The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose
information and data of the various power supplies they support such as
ACIN, battery and VBUS. For example, they expose the current battery
voltage, charge or discharge, as well as ACIN and VBUS current voltages
and currents, internal PMIC temperature and ADC on 2 different GPIOs
when in the right mode (for the AXP209 only).
The ACIN power supply driver is added by this patch. The AXP20X and
AXP22X can both read the status and the "usability" of the power supply
but only the AXP209 will be able to tell the current current and voltage
of the power supply by reading ADC channels. It is simply not supported
by the AXP22X PMICs.
The battery power supply driver is also added by this patch. The AXP20X
and AXP22X share most of their behaviour but have slight variations. The
allowed target voltages for battery charging are not the same, the
AXP22X PMIC are able to tell if the battery percentage computed by the
PMIC is trustworthy and they have different formulas for computing max
current for battery power supply. The driver is able to give the current
voltage and current of the battery (be it charging or discharging), the
maximal and minimal voltage and maximal current allowed for the battery,
whether the battery is present and usable and its capacity. It will get
the battery current current and voltage by reading the ADC channels. The
PMIC allows maximal voltages (4.36V for AXP20X and 4.22V and 4.24V for
AXP22X) that should not be used with Lithium-based batteries and since
this PMIC is supposed to be used with Lithium-based batteries, they have
been disabled. The values returned by the ADC driver are multipled by
1000 to scale from the mV returned by the ADC to the uV expected by the
power supply framework.
This series of patch adds DT bindings for ACIN power supply, ADC and
battery power supply drivers for AXP20X and AXP22X PMICs and their
documentation. It also enables the supported power supplies for the
Nextthing Co. CHIP and Sinlinx SinA33 boards.
The different drivers are also added to the MFD cells of the AXP20X and
AXP22X cells and the writeable and volatile regs updated to work with
the newly added drivers.
VBUS driver has intentionally not been modified to use the ADC channels
because a DT binding already exists for this driver. Migrating the
driver would mean to add an iio_map to map the ADC channels to the VBUS
driver (so we can use iio_channel_get and iio_read_channel_processed
functions). This slightly complexifies the VBUS driver only for
"cosmetic" changes. Feel free to give your two cents on the matter.
This series of patch is based on a previous upstreaming attempt done by
Bruno Pr?mont few months ago. It differs in three points: the ADC
driver does not tell the battery temperature (TS_IN) as I do not have a
board to test it with, it does not tell the instantaneous battery power
as it returns crazy values for me and finally no support for OCV curves
for the battery.
You can test these patches from this repo and branch:
https://github.com/QSchulz/linux/tree/axp2xx_adc_batt_ac_v2
v2:
- Some registers' name have been changed to better reflect their
purpose,
- Make VBUS power supply driver use IIO channels when AXP ADC driver is
enabled, but fall back on previous behavior when disabled. This is made
to avoid the ADC driver overwritting registers for VBUS power supply
ADC when removed,
- Removed useless adding of data registers to volatile registers,
- Reordered IIO channels, now grouped by same part of the PMIC (e.g.
voltage and current of the battery have the same index in different
IIO types),
- Added structures for specific data instead of matching on IDs,
- Switched from DT IIO channels mapping to iio_map structures IIO
channels mapping,
Quentin
Quentin Schulz (25):
dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
mfd: axp20x: correct name of temperature data ADC registers
power: supply: axp20x_usb_power: use IIO channels when available
iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs
ARM: dtsi: axp209: add AXP209 ADC subnode
ARM: dtsi: axp22x: add AXP22X ADC subnode
dt-bindings: power: supply: add AXP20X/AXP22X AC power supply
iio: adc: axp20x_adc: map acin_i and acin_v
power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
mfd: axp20x: add AC power supply cells for AXP22X PMICs
ARM: dtsi: axp209: add AC power supply subnode
ARM: dtsi: axp22x: add AC power supply subnode
ARM: dts: sun8i: sina33: enable ACIN power supply subnode
ARM: sun5i: chip: enable ACIN power supply subnode
dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding
mfd: axp20x: add CHRG_CTRL1/2/3 to writeable regs for AXP20X/AXP22X
mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X
iio: adc: axp20x_adc: map battery IIO channels
power: supply: add battery driver for AXP20X and AXP22X PMICs
mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver
ARM: dtsi: axp209: add battery power supply subnode
ARM: dtsi: axp22x: add battery power supply subnode
ARM: dts: sun8i: sina33: enable battery power supply subnode
ARM: sun5i: chip: enable battery power supply subnode
.../devicetree/bindings/iio/adc/axp20x_adc.txt | 22 +
.../bindings/power/supply/axp20x_ac_power.txt | 22 +
.../bindings/power/supply/axp20x_battery.txt | 25 +
arch/arm/boot/dts/axp209.dtsi | 14 +
arch/arm/boot/dts/axp22x.dtsi | 14 +
arch/arm/boot/dts/sun5i-r8-chip.dts | 8 +
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 8 +
drivers/iio/adc/Kconfig | 10 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/axp20x_adc.c | 609 +++++++++++++++++++++
drivers/mfd/axp20x.c | 36 +-
drivers/power/supply/Kconfig | 24 +
drivers/power/supply/Makefile | 2 +
drivers/power/supply/axp20x_ac_power.c | 250 +++++++++
drivers/power/supply/axp20x_battery.c | 477 ++++++++++++++++
drivers/power/supply/axp20x_usb_power.c | 70 ++-
include/linux/mfd/axp20x.h | 4 +-
17 files changed, 1587 insertions(+), 9 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
create mode 100644 drivers/iio/adc/axp20x_adc.c
create mode 100644 drivers/power/supply/axp20x_ac_power.c
create mode 100644 drivers/power/supply/axp20x_battery.c
--
2.9.3
The X-Powers AXP20X and AXP22X PMICs can have a battery as power supply.
This patch adds the battery power supply driver to get various data from
the PMIC, such as the battery status (charging, discharging, full,
dead), current max limit, current current, battery capacity (in
percentage), voltage max and min limits, current voltage and battery
capacity (in Ah).
This battery driver uses the AXP20X/AXP22X ADC driver as PMIC data
provider.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- changed BIT(x) to 1 << x when describing bits purpose for which 2 <<
x or 3 << x exists, to be consistent,
- switched from POWER_SUPPLY_PROP_CURRENT_MAX to
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
- added POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX to the list of
readable properties,
- replaced ? character by a common u for micro units to make checkpatch
happy,
- factorized code in axp20x_battery_set_max_voltage,
- added a axp20x_set_constant_charge_current function to be used when
setting the value from sysfs and from the DT,
- removed some dead code,
- added a DT property to set constant current charge of the battery
(x-powers,constant-charge-current),
- migrated to dev_get_regmap instead of manually looking for the regmap
in the drvdata of the parent,
- switched from int to uintptr_t cast to make sure the cast is always
for the same size type (make build on 64bits platforms happy mainly),
drivers/power/supply/Kconfig | 12 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/axp20x_battery.c | 477 ++++++++++++++++++++++++++++++++++
3 files changed, 490 insertions(+)
create mode 100644 drivers/power/supply/axp20x_battery.c
The NextThing Co. CHIP has an AXP209 PMIC and can be power-supplied by
ACIN via the CHG-IN pin.
This enables the ACIN power supply subnode in the DT.
Signed-off-by: Quentin Schulz <redacted>
---
arch/arm/boot/dts/sun5i-r8-chip.dts | 4 ++++
1 file changed, 4 insertions(+)
The X-Powers AXP209 PMIC exposes battery supply various data such as
the battery status (charging, discharging, full, dead), current max
limit, current current, battery capacity (in percentage), voltage max
and min limits, current voltage, and battery capacity (in Ah).
This adds the battery power supply subnode for AXP20X PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- changed DT node name from battery_power_supply to
battery-power-supply,
- removed io-channels and io-channel-names from DT (the IIO mapping is
done in the IIO ADC driver now),
arch/arm/boot/dts/axp209.dtsi | 5 +++++
1 file changed, 5 insertions(+)
@@ -68,6 +68,11 @@#gpio-cells=<2>;};+battery_power_supply:battery-power-supply{+compatible="x-powers,axp209-battery-power-supply";+status="disabled";+};+regulators{/* Default work frequency for buck regulators */x-powers,dcdc-freq=<1500>;
The Sinlinx SinA33 has an AXP223 PMIC and a battery connector, thus, we
enable the battery power supply subnode in its Device Tree.
Signed-off-by: Quentin Schulz <redacted>
---
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 4 ++++
1 file changed, 4 insertions(+)
The NextThing Co. CHIP has an AXP209 PMIC with battery connector.
This enables the battery power supply subnode.
Signed-off-by: Quentin Schulz <redacted>
---
arch/arm/boot/dts/sun5i-r8-chip.dts | 4 ++++
1 file changed, 4 insertions(+)
The V_OFF register has its first 3 read-write bits for the minimal
voltage (Voff) of the battery before the system is automatically shut
down due to the power being too low.
This adds V_OFF register to the writeable registers of AXP20X and AXP22X
PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
Acked-by: Chen-Yu Tsai <redacted>
---
drivers/mfd/axp20x.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -94,7 +94,7 @@ static const struct regmap_access_table axp20x_volatile_table = {/* AXP22x ranges are shared with the AXP809, as they cover the same range */staticconststructregmap_rangeaxp22x_writeable_ranges[]={regmap_reg_range(AXP20X_DATACACHE(0),AXP20X_IRQ5_STATE),-regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT,AXP20X_VBUS_IPSOUT_MGMT),+regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT,AXP20X_V_OFF),regmap_reg_range(AXP20X_CHRG_CTRL1,AXP22X_CHRG_CTRL3),regmap_reg_range(AXP20X_DCDC_MODE,AXP22X_BATLOW_THRES1),};
This maps the IIO channels batt_v, batt_chrg_i and batt_dischrg_i
(respectively exposing the current charging and discharging currents and
current voltage measures of the battery power supply) to the battery
power supply driver.
Signed-off-by: Quentin Schulz <redacted>
---
added in v2
drivers/iio/adc/axp20x_adc.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
The X-Powers AXP20X and AXP22X PMICs can have a battery as power supply.
This patch adds the AXP20X/AXP22X battery driver to the MFD cells of the
AXP209, AXP221 and AXP223 MFD.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
---
drivers/mfd/axp20x.c | 9 +++++++++
1 file changed, 9 insertions(+)
The X-Powers AXP22X PMIC exposes battery supply various data such as
the battery status (charging, discharging, full, dead), current max
limit, current current, battery capacity (in percentage), voltage max
limit, current voltage, and battery capacity (in Ah).
This adds the battery power supply subnode for AXP22X PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- changed DT node name from battery_power_supply to
battery-power-supply,
- removed io-channels and io-channel-names from DT (the IIO mapping is
done in the IIO ADC driver now),
arch/arm/boot/dts/axp22x.dtsi | 5 +++++
1 file changed, 5 insertions(+)
@@ -61,6 +61,11 @@compatible="x-powers,axp221-adc";};+battery_power_supply:battery-power-supply{+compatible="x-powers,axp221-battery-power-supply";+status="disabled";+};+regulators{/* Default work frequency for buck regulators */x-powers,dcdc-freq=<3000>;
The CHRG_CTRL1 and CHRG_CTRL2 registers are made for controlling
different battery charging settings such as the constant current charge
value.
The AXP22X also have a third register CHRG_CTRL3 which has settings for
battery charging too.
This adds the CHRG_CTRL1, CHRG_CTRL2 and CHRG_CTRL3 registers to the
list of writeable registers for AXP20X and AXP22X PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
---
v2:
- added AXP20X_CHRG_CTRL2 and AXP20X_CHRG_CTRL3 to the writeable
registers table,
- removed added reg range for ADC data in volatile regs range,
drivers/mfd/axp20x.c | 2 ++
1 file changed, 2 insertions(+)
The X-Powers AXP20X and AXP22X PMICs can have a battery as power supply.
This patch adds the DT binding documentation for the battery power
supply which gets various data from the PMIC, such as the battery status
(charging, discharging, full, dead), current max limit, current current,
battery capacity (in percentage), voltage max and min limits, current
voltage and battery capacity (in Ah).
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- changed DT node name from ac_power_supply to ac-power-supply,
- removed io-channels and io-channel-names from DT (the IIO mapping is
done in the IIO ADC driver now),
- added x-powers,constant-charge-current property to set the maximal
default constant current charge of the battery,
.../bindings/power/supply/axp20x_battery.txt | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
@@ -0,0 +1,25 @@+AXP20x and AXP22x battery power supply++Required Properties:+ - compatible, one of:+ "x-powers,axp209-battery-power-supply"+ "x-powers,axp221-battery-power-supply"++Optional properties:+ - x-powers,constant-charge-current: its value in uA gives the PMIC the default+ maximal allowed value for the constant charge current of the battery.++This node is a subnode of the axp20x/axp22x PMIC.++The AXP20X and AXP22X can read the battery voltage, charge and discharge+currents of the battery by reading ADC channels from the AXP20X/AXP22X+ADC.++Example:++&axp209 {+ battery_power_supply: battery-power-supply {+ compatible = "x-powers,axp209-battery-power-supply";+ x-powers,constant-charge-current = <600000>;+ }+};
The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
battery voltage, battery charge and discharge currents, AC-in and VBUS
voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
This adds support for most of AXP20X and AXP22X ADCs.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- removed unused defines,
- changed BIT(x) to 1 << x when describing bits purpose for which 2 <<
x or 3 << x exists, to be consistent,
- changed ADC rate defines to macro formulas,
- reordered IIO channels, now different measures (current/voltage) of
the same part of the PMIC (e.g. battery), have the same IIO channel in
their respective IIO type. When a part of the PMIC have only one
measure, a number is jumped,
- left IIO channel mapping in DT to use iio_map structure,
- removed indexing of ADC internal temperature,
- removed unused iio_dev structure in axp20x_adc_iio,
- added a structure for data specific to AXP20X or AXP22X PMICs instead
of using an ID and an if condition when needing to separate the
behaviour of both,
- added a comment on batt_chrg_i really being on 12bits rather than
what the Chinese datasheets say (13 bits),
- corrected the offset for AXP22X PMIC temperature,
- set the ADC rate to a value (100Hz) shared by the AXP20X and AXP22X,
- created macro formulas to compute the ADC rate for each,
- added a condition on presence of ADC_EN2 reg before setting/resetting
it,
- switched from devm_iio_device_unregister to the non-devm function
because of the need for a remove function,
- removed some dead code,
drivers/iio/adc/Kconfig | 10 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/axp20x_adc.c | 572 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 583 insertions(+)
create mode 100644 drivers/iio/adc/axp20x_adc.c
The X-Powers AXP20X PMIC exposes the current current and voltage
measures via an internal ADC.
This adds the possibility to read IIO channels directly for processed
values rather than reading the registers and computing the value.
For backward compatibility purpose, if the IIO driver is not compiled,
this driver will fall back on previous behaviour which is direct
register readings.
Signed-off-by: Quentin Schulz <redacted>
---
added in v2
drivers/power/supply/axp20x_usb_power.c | 70 +++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 4 deletions(-)
@@ -76,6 +79,20 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,val->intval=AXP20X_VBUS_VHOLD_uV(v);return0;casePOWER_SUPPLY_PROP_VOLTAGE_NOW:+if(IS_ENABLED(CONFIG_AXP20X_ADC)){+ret=iio_read_channel_processed(power->vbus_v,+&val->intval);+if(ret)+returnret;++/*+*IIOframeworkgivesmVbutPowerSupplyframework+*givesuV.+*/+val->intval*=1000;+return0;+}+ret=axp20x_read_variable_width(power->regmap,AXP20X_VBUS_V_ADC_H,12);if(ret<0)
@@ -107,6 +124,20 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,}return0;casePOWER_SUPPLY_PROP_CURRENT_NOW:+if(IS_ENABLED(CONFIG_AXP20X_ADC)){+ret=iio_read_channel_processed(power->vbus_i,+&val->intval);+if(ret)+returnret;++/*+*IIOframeworkgivesmAbutPowerSupplyframework+*givesuA.+*/+val->intval*=1000;+return0;+}+ret=axp20x_read_variable_width(power->regmap,AXP20X_VBUS_I_ADC_H,12);if(ret<0)
@@ -269,6 +300,36 @@ static const struct power_supply_desc axp22x_usb_power_desc = {.set_property=axp20x_usb_power_set_property,};+staticintconfigure_iio_channels(structplatform_device*pdev,+structaxp20x_usb_power*power)+{+power->vbus_v=devm_iio_channel_get(&pdev->dev,"vbus_v");+if(IS_ERR(power->vbus_v)){+if(PTR_ERR(power->vbus_v)==-ENODEV)+return-EPROBE_DEFER;+returnPTR_ERR(power->vbus_v);+}++power->vbus_i=devm_iio_channel_get(&pdev->dev,"vbus_i");+if(IS_ERR(power->vbus_i)){+if(PTR_ERR(power->vbus_i)==-ENODEV)+return-EPROBE_DEFER;+returnPTR_ERR(power->vbus_i);+}++return0;+}++staticintconfigure_adc_registers(structaxp20x_usb_power*power)+{+/* Enable vbus voltage and current measurement */+returnregmap_update_bits(power->regmap,AXP20X_ADC_EN1,+AXP20X_ADC_EN1_VBUS_CURR|+AXP20X_ADC_EN1_VBUS_VOLT,+AXP20X_ADC_EN1_VBUS_CURR|+AXP20X_ADC_EN1_VBUS_VOLT);+}+staticintaxp20x_usb_power_probe(structplatform_device*pdev){structaxp20x_dev*axp20x=dev_get_drvdata(pdev->dev.parent);
@@ -307,10 +368,11 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)if(ret)returnret;-/* Enable vbus voltage and current measurement */-ret=regmap_update_bits(power->regmap,AXP20X_ADC_EN1,-AXP20X_ADC_EN1_VBUS_CURR|AXP20X_ADC_EN1_VBUS_VOLT,-AXP20X_ADC_EN1_VBUS_CURR|AXP20X_ADC_EN1_VBUS_VOLT);+if(IS_ENABLED(CONFIG_AXP20X_ADC))+ret=configure_iio_channels(pdev,power);+else+ret=configure_adc_registers(power);+if(ret)returnret;
The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
battery voltage, battery charge and discharge currents, AC-in and VBUS
voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
This adds the device tree binding documentation for the X-Powers AXP20X
and AXP22X PMICs ADCs.
Signed-off-by: Quentin Schulz <redacted>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Chen-Yu Tsai <redacted>
Acked-by: Maxime Ripard <redacted>
---
v2:
- removing io-channels from required properties,
- update AXP ADC DT node name from axp209_adc to simply adc,
.../devicetree/bindings/iio/adc/axp20x_adc.txt | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
@@ -0,0 +1,22 @@+X-Powers AXP20X and AXP22X PMIC Analog to Digital Converter (ADC)++The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the+battery voltage, battery charge and discharge currents, AC-in and VBUS+voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.++The AXP22X PMICs do not have all ADCs of the AXP20X though.++Required properties:+ - compatible, one of:+ "x-powers,axp209-adc"+ "x-powers,axp221-adc"++This is a subnode of the AXP20X PMIC.++Example:++&axp209 {+ axp209_adc: adc {+ compatible = "x-powers,axp209-adc";+ };+};
The registers 0x56 and 0x57 of AXP22X PMIC store the value of the
internal temperature of the PMIC.
This patch modifies the name of these registers from AXP22X_PMIC_ADC_H/L
to AXP22X_PMIC_TEMP_H/L so their purpose is clearer.
Signed-off-by: Quentin Schulz <redacted>
---
added in v2
drivers/mfd/axp20x.c | 2 +-
include/linux/mfd/axp20x.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
The X-Powers AXP20X and AXP22X PMICs expose the status of AC power
supply.
Moreover, the AXP20X can also expose the current current and voltage
values of the AC power supply.
This adds the driver which exposes the status of the AC power supply of
the AXP20X and AXP22X PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-by: Jonathan Cameron <jic23@kernel.org>
---
v2:
- replaced ? character by a common u for micro units to make checkpatch
happy,
- use of structure for specific data instead of an ID and if
condiftions,
- use dev_get_regmap instead of manually looking for it in the parent
drvdata,
drivers/power/supply/Kconfig | 12 ++
drivers/power/supply/Makefile | 1 +
drivers/power/supply/axp20x_ac_power.c | 250 +++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+)
create mode 100644 drivers/power/supply/axp20x_ac_power.c
@@ -0,0 +1,250 @@+/*+*AXP20XandAXP22XPMICs'ACINpowersupplydriver+*+*Copyright(C)2016FreeElectrons+*QuentinSchulz<quentin.schulz@free-electrons.com>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseaspublishedbythe+*FreeSoftwareFoundation;eitherversion2oftheLicense,or(atyour+*option)anylaterversion.+*/++#include<linux/device.h>+#include<linux/init.h>+#include<linux/interrupt.h>+#include<linux/kernel.h>+#include<linux/mfd/axp20x.h>+#include<linux/module.h>+#include<linux/of.h>+#include<linux/of_device.h>+#include<linux/platform_device.h>+#include<linux/power_supply.h>+#include<linux/regmap.h>+#include<linux/slab.h>+#include<linux/iio/consumer.h>++#define AXP20X_PWR_STATUS_ACIN_PRESENT BIT(7)+#define AXP20X_PWR_STATUS_ACIN_AVAIL BIT(6)++#define DRVNAME "axp20x-ac-power-supply"++structaxp20x_ac_power{+structdevice_node*np;+structregmap*regmap;+structpower_supply*supply;+intaxp20x_id;+structiio_channel*acin_v;+structiio_channel*acin_i;+};++staticirqreturn_taxp20x_ac_power_irq(intirq,void*devid)+{+structaxp20x_ac_power*power=devid;++power_supply_changed(power->supply);++returnIRQ_HANDLED;+}++staticintaxp20x_ac_power_get_property(structpower_supply*psy,+enumpower_supply_propertypsp,+unionpower_supply_propval*val)+{+structaxp20x_ac_power*power=power_supply_get_drvdata(psy);+intret,reg;++switch(psp){+casePOWER_SUPPLY_PROP_HEALTH:+ret=regmap_read(power->regmap,AXP20X_PWR_INPUT_STATUS,®);+if(ret)+returnret;++if(reg&AXP20X_PWR_STATUS_ACIN_PRESENT){+val->intval=POWER_SUPPLY_HEALTH_GOOD;+return0;+}++val->intval=POWER_SUPPLY_HEALTH_UNKNOWN;+return0;++casePOWER_SUPPLY_PROP_PRESENT:+ret=regmap_read(power->regmap,AXP20X_PWR_INPUT_STATUS,®);+if(ret)+returnret;++val->intval=!!(reg&AXP20X_PWR_STATUS_ACIN_PRESENT);+return0;++casePOWER_SUPPLY_PROP_ONLINE:+ret=regmap_read(power->regmap,AXP20X_PWR_INPUT_STATUS,®);+if(ret)+returnret;++val->intval=!!(reg&AXP20X_PWR_STATUS_ACIN_AVAIL);+return0;++casePOWER_SUPPLY_PROP_VOLTAGE_NOW:+ret=iio_read_channel_processed(power->acin_v,&val->intval);+if(ret)+returnret;++/* IIO framework gives mV but Power Supply framework gives uV */+val->intval*=1000;++return0;++casePOWER_SUPPLY_PROP_CURRENT_NOW:+ret=iio_read_channel_processed(power->acin_i,&val->intval);+if(ret)+returnret;++/* IIO framework gives mA but Power Supply framework gives uA */+val->intval*=1000;++return0;++default:+return-EINVAL;+}++return-EINVAL;+}++staticenumpower_supply_propertyaxp20x_ac_power_properties[]={+POWER_SUPPLY_PROP_HEALTH,+POWER_SUPPLY_PROP_PRESENT,+POWER_SUPPLY_PROP_ONLINE,+POWER_SUPPLY_PROP_VOLTAGE_NOW,+POWER_SUPPLY_PROP_CURRENT_NOW,+};++staticenumpower_supply_propertyaxp22x_ac_power_properties[]={+POWER_SUPPLY_PROP_HEALTH,+POWER_SUPPLY_PROP_PRESENT,+POWER_SUPPLY_PROP_ONLINE,+};++staticconststructpower_supply_descaxp20x_ac_power_desc={+.name="axp20x-ac",+.type=POWER_SUPPLY_TYPE_MAINS,+.properties=axp20x_ac_power_properties,+.num_properties=ARRAY_SIZE(axp20x_ac_power_properties),+.get_property=axp20x_ac_power_get_property,+};++staticconststructpower_supply_descaxp22x_ac_power_desc={+.name="axp22x-ac",+.type=POWER_SUPPLY_TYPE_MAINS,+.properties=axp22x_ac_power_properties,+.num_properties=ARRAY_SIZE(axp22x_ac_power_properties),+.get_property=axp20x_ac_power_get_property,+};++structaxp_data{+conststructpower_supply_desc*power_desc;+boolacin_adc;+};++staticconststructaxp_dataaxp20x_data={+.power_desc=&axp20x_ac_power_desc,+.acin_adc=true,+};++staticconststructaxp_dataaxp22x_data={+.power_desc=&axp22x_ac_power_desc,+.acin_adc=false,+};++staticintaxp20x_ac_power_probe(structplatform_device*pdev)+{+structaxp20x_dev*axp20x=dev_get_drvdata(pdev->dev.parent);+structpower_supply_configpsy_cfg={};+structaxp20x_ac_power*power;+structaxp_data*axp_data;+staticconstchar*constirq_names[]={"ACIN_PLUGIN","ACIN_REMOVAL",+NULL};+inti,irq,ret;++if(!of_device_is_available(pdev->dev.of_node))+return-ENODEV;++if(!axp20x){+dev_err(&pdev->dev,"Parent drvdata not set\n");+return-EINVAL;+}++power=devm_kzalloc(&pdev->dev,sizeof(*power),GFP_KERNEL);+if(!power)+return-ENOMEM;++axp_data=(structaxp_data*)of_device_get_match_data(&pdev->dev);++if(axp_data->acin_adc){+power->acin_v=devm_iio_channel_get(&pdev->dev,"acin_v");+if(IS_ERR(power->acin_v)){+if(PTR_ERR(power->acin_v)==-ENODEV)+return-EPROBE_DEFER;+returnPTR_ERR(power->acin_v);+}++power->acin_i=devm_iio_channel_get(&pdev->dev,"acin_i");+if(IS_ERR(power->acin_i)){+if(PTR_ERR(power->acin_i)==-ENODEV)+return-EPROBE_DEFER;+returnPTR_ERR(power->acin_i);+}+}++power->regmap=dev_get_regmap(pdev->dev.parent,NULL);++platform_set_drvdata(pdev,power);++psy_cfg.of_node=pdev->dev.of_node;+psy_cfg.drv_data=power;++power->supply=devm_power_supply_register(&pdev->dev,+axp_data->power_desc,+&psy_cfg);+if(IS_ERR(power->supply))+returnPTR_ERR(power->supply);++/* Request irqs after registering, as irqs may trigger immediately */+for(i=0;irq_names[i];i++){+irq=platform_get_irq_byname(pdev,irq_names[i]);+if(irq<0){+dev_warn(&pdev->dev,"No IRQ for %s: %d\n",+irq_names[i],irq);+continue;+}+irq=regmap_irq_get_virq(axp20x->regmap_irqc,irq);+ret=devm_request_any_context_irq(&pdev->dev,irq,+axp20x_ac_power_irq,0,+DRVNAME,power);+if(ret<0)+dev_warn(&pdev->dev,"Error requesting %s IRQ: %d\n",+irq_names[i],ret);+}++return0;+}++staticconststructof_device_idaxp20x_ac_power_match[]={+{+.compatible="x-powers,axp202-ac-power-supply",+.data=(void*)&axp20x_data,+},{+.compatible="x-powers,axp221-ac-power-supply",+.data=(void*)&axp22x_data,+},{/* sentinel */}+};+MODULE_DEVICE_TABLE(of,axp20x_ac_power_match);++staticstructplatform_driveraxp20x_ac_power_driver={+.probe=axp20x_ac_power_probe,+.driver={+.name=DRVNAME,+.of_match_table=axp20x_ac_power_match,+},+};++module_platform_driver(axp20x_ac_power_driver);++MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");+MODULE_DESCRIPTION("AXP20X and AXP22X PMICs' AC power supply driver");+MODULE_LICENSE("GPL");
This maps the IIO channels acin_i and acin_v (respectively exposing the
current current and voltage measures of the AC power supply) to the AC
power supply driver.
Only the AXP20X PMICs have these ADC channels and thus they are only
mapped for this version of the PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
added in v2
drivers/iio/adc/axp20x_adc.c | 8 ++++++++
1 file changed, 8 insertions(+)
This adds the AXP20X/AXP22x ADCs driver to the mfd cells of the AXP209,
AXP221 and AXP223 MFD.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
Acked-by: Chen-Yu Tsai <redacted>
---
drivers/mfd/axp20x.c | 9 +++++++++
1 file changed, 9 insertions(+)
The X-Powers AXP20X PMIC exposes the status of AC power supply, the
current current and voltage supplied to the board by the AC power
supply.
This adds the AC power supply subnode for AXP20X PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- changed DT node name from ac_power_supply to ac-power-supply,
- removed io-channels and io-channel-names from DT (the IIO mapping is
done in the IIO ADC driver now),
arch/arm/boot/dts/axp209.dtsi | 5 +++++
1 file changed, 5 insertions(+)
The Sinlinx SinA33 has an AXP223 PMIC and an ACIN connector, thus, we
enable the ACIN power supply in its Device Tree.
Signed-off-by: Quentin Schulz <redacted>
---
arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 4 ++++
1 file changed, 4 insertions(+)
From: Maxime Ripard <hidden> Date: 2017-01-27 09:20:35
On Fri, Jan 27, 2017 at 09:54:33AM +0100, Quentin Schulz wrote:
The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose
information and data of the various power supplies they support such as
ACIN, battery and VBUS. For example, they expose the current battery
voltage, charge or discharge, as well as ACIN and VBUS current voltages
and currents, internal PMIC temperature and ADC on 2 different GPIOs
when in the right mode (for the AXP209 only).
The ACIN power supply driver is added by this patch. The AXP20X and
AXP22X can both read the status and the "usability" of the power supply
but only the AXP209 will be able to tell the current current and voltage
of the power supply by reading ADC channels. It is simply not supported
by the AXP22X PMICs.
The battery power supply driver is also added by this patch. The AXP20X
and AXP22X share most of their behaviour but have slight variations. The
allowed target voltages for battery charging are not the same, the
AXP22X PMIC are able to tell if the battery percentage computed by the
PMIC is trustworthy and they have different formulas for computing max
current for battery power supply. The driver is able to give the current
voltage and current of the battery (be it charging or discharging), the
maximal and minimal voltage and maximal current allowed for the battery,
whether the battery is present and usable and its capacity. It will get
the battery current current and voltage by reading the ADC channels. The
PMIC allows maximal voltages (4.36V for AXP20X and 4.22V and 4.24V for
AXP22X) that should not be used with Lithium-based batteries and since
this PMIC is supposed to be used with Lithium-based batteries, they have
been disabled. The values returned by the ADC driver are multipled by
1000 to scale from the mV returned by the ADC to the uV expected by the
power supply framework.
This series of patch adds DT bindings for ACIN power supply, ADC and
battery power supply drivers for AXP20X and AXP22X PMICs and their
documentation. It also enables the supported power supplies for the
Nextthing Co. CHIP and Sinlinx SinA33 boards.
The different drivers are also added to the MFD cells of the AXP20X and
AXP22X cells and the writeable and volatile regs updated to work with
the newly added drivers.
VBUS driver has intentionally not been modified to use the ADC channels
because a DT binding already exists for this driver. Migrating the
driver would mean to add an iio_map to map the ADC channels to the VBUS
driver (so we can use iio_channel_get and iio_read_channel_processed
functions). This slightly complexifies the VBUS driver only for
"cosmetic" changes. Feel free to give your two cents on the matter.
This series of patch is based on a previous upstreaming attempt done by
Bruno Pr?mont few months ago. It differs in three points: the ADC
driver does not tell the battery temperature (TS_IN) as I do not have a
board to test it with, it does not tell the instantaneous battery power
as it returns crazy values for me and finally no support for OCV curves
for the battery.
You can test these patches from this repo and branch:
https://github.com/QSchulz/linux/tree/axp2xx_adc_batt_ac_v2
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
The registers 0x56 and 0x57 of AXP22X PMIC store the value of the
internal temperature of the PMIC.
This patch modifies the name of these registers from AXP22X_PMIC_ADC_H/L
to AXP22X_PMIC_TEMP_H/L so their purpose is clearer.
Signed-off-by: Quentin Schulz <redacted>
The X-Powers AXP20X and AXP22X PMICs expose the status of AC power
supply.
This adds the AC power supply driver to the MFD cells of the AXP22X
PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
---
drivers/mfd/axp20x.c | 10 ++++++++++
1 file changed, 10 insertions(+)
The X-Powers AXP20X and AXP22X PMICs have an AC entry to supply power to
the board. They have a few registers dedicated to the status of the AC
power supply.
This adds the DT binding documentation for the AC power supply for
AXP20X and AXP22X PMICs.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- removed #io-channels property,
.../bindings/power/supply/axp20x_ac_power.txt | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
@@ -0,0 +1,22 @@+AXP20X and AXP22X PMICs' AC power supply++Required Properties:+ - compatible: One of:+ "x-powers,axp202-ac-power-supply"+ "x-powers,axp221-ac-power-supply"++This node is a subnode of the axp20x PMIC.++The AXP20X can read the current current and voltage supplied by AC by+reading ADC channels from the AXP20X ADC.++The AXP22X is only able to tell if an AC power supply is present and+usable.++Example:++&axp209 {+ ac_power_supply: ac-power-supply {+ compatible = "x-powers,axp202-ac-power-supply";+ };+};
The X-Powers AXP22X PMIC exposes the status of AC power supply.
This adds the AC power supply subnode for the AXP22X PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- changed DT node name from ac_power_supply to ac-power-supply,
- removed io-channels and io-channel-names from DT (the IIO mapping is
done in the IIO ADC driver now),
arch/arm/boot/dts/axp22x.dtsi | 5 +++++
1 file changed, 5 insertions(+)
X-Powers AXP209 PMIC has multiple ADCs, each one exposing data from the
different power supplies connected to the PMIC.
This adds the ADC subnode for AXP20X PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- removed #io-channels property (the IIO channels mapping is done by
using iio_map structure in the ADC driver),
arch/arm/boot/dts/axp209.dtsi | 4 ++++
1 file changed, 4 insertions(+)
X-Powers AXP22X PMIC has multiple ADCs, each one exposing data from the
different power supplies connected to the PMIC.
This adds the ADC subnode for AXP22X PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
v2:
- removed #io-channels property (the IIO channels mapping is done by
using iio_map structure in the ADC driver),
arch/arm/boot/dts/axp22x.dtsi | 4 ++++
1 file changed, 4 insertions(+)
@@ -52,6 +52,10 @@interrupt-controller;#interrupt-cells=<1>;+axp221_adc:adc{+compatible="x-powers,axp221-adc";+};+regulators{/* Default work frequency for buck regulators */x-powers,dcdc-freq=<3000>;
From: Jonathan Cameron <jic23@kernel.org> Date: 2017-01-28 14:45:23
On 27/01/17 08:54, Quentin Schulz wrote:
The X-Powers AXP20X PMIC exposes the current current and voltage
measures via an internal ADC.
This adds the possibility to read IIO channels directly for processed
values rather than reading the registers and computing the value.
For backward compatibility purpose, if the IIO driver is not compiled,
this driver will fall back on previous behaviour which is direct
register readings.
Signed-off-by: Quentin Schulz <redacted>
Acked-by: Jonathan Cameron <jic23@kernel.org>
I (or someone else) really needs to find time to deal with deferred probing
properly in the IIO core. It's a mess as we need to revisit how the
channel map stuff works to make sure it's always there...
Anyhow, it's still on the todo list and we can tidy this up if it ever
happens!
Jonathan
@@ -76,6 +79,20 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,val->intval=AXP20X_VBUS_VHOLD_uV(v);return0;casePOWER_SUPPLY_PROP_VOLTAGE_NOW:+if(IS_ENABLED(CONFIG_AXP20X_ADC)){+ret=iio_read_channel_processed(power->vbus_v,+&val->intval);+if(ret)+returnret;++/*+*IIOframeworkgivesmVbutPowerSupplyframework+*givesuV.+*/+val->intval*=1000;+return0;+}+ret=axp20x_read_variable_width(power->regmap,AXP20X_VBUS_V_ADC_H,12);if(ret<0)
@@ -107,6 +124,20 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,}return0;casePOWER_SUPPLY_PROP_CURRENT_NOW:+if(IS_ENABLED(CONFIG_AXP20X_ADC)){+ret=iio_read_channel_processed(power->vbus_i,+&val->intval);+if(ret)+returnret;++/*+*IIOframeworkgivesmAbutPowerSupplyframework+*givesuA.+*/+val->intval*=1000;+return0;+}+ret=axp20x_read_variable_width(power->regmap,AXP20X_VBUS_I_ADC_H,12);if(ret<0)
@@ -269,6 +300,36 @@ static const struct power_supply_desc axp22x_usb_power_desc = {.set_property=axp20x_usb_power_set_property,};+staticintconfigure_iio_channels(structplatform_device*pdev,+structaxp20x_usb_power*power)+{+power->vbus_v=devm_iio_channel_get(&pdev->dev,"vbus_v");+if(IS_ERR(power->vbus_v)){+if(PTR_ERR(power->vbus_v)==-ENODEV)+return-EPROBE_DEFER;+returnPTR_ERR(power->vbus_v);+}++power->vbus_i=devm_iio_channel_get(&pdev->dev,"vbus_i");+if(IS_ERR(power->vbus_i)){+if(PTR_ERR(power->vbus_i)==-ENODEV)+return-EPROBE_DEFER;+returnPTR_ERR(power->vbus_i);+}++return0;+}++staticintconfigure_adc_registers(structaxp20x_usb_power*power)+{+/* Enable vbus voltage and current measurement */+returnregmap_update_bits(power->regmap,AXP20X_ADC_EN1,+AXP20X_ADC_EN1_VBUS_CURR|+AXP20X_ADC_EN1_VBUS_VOLT,+AXP20X_ADC_EN1_VBUS_CURR|+AXP20X_ADC_EN1_VBUS_VOLT);+}+staticintaxp20x_usb_power_probe(structplatform_device*pdev){structaxp20x_dev*axp20x=dev_get_drvdata(pdev->dev.parent);
@@ -307,10 +368,11 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)if(ret)returnret;-/* Enable vbus voltage and current measurement */-ret=regmap_update_bits(power->regmap,AXP20X_ADC_EN1,-AXP20X_ADC_EN1_VBUS_CURR|AXP20X_ADC_EN1_VBUS_VOLT,-AXP20X_ADC_EN1_VBUS_CURR|AXP20X_ADC_EN1_VBUS_VOLT);+if(IS_ENABLED(CONFIG_AXP20X_ADC))+ret=configure_iio_channels(pdev,power);+else+ret=configure_adc_registers(power);+if(ret)returnret;
From: Jonathan Cameron <jic23@kernel.org> Date: 2017-01-28 14:51:49
On 27/01/17 08:54, Quentin Schulz wrote:
This maps the IIO channels acin_i and acin_v (respectively exposing the
current current and voltage measures of the AC power supply) to the AC
power supply driver.
Only the AXP20X PMICs have these ADC channels and thus they are only
mapped for this version of the PMIC.
Signed-off-by: Quentin Schulz <redacted>
From: Jonathan Cameron <jic23@kernel.org> Date: 2017-01-28 14:51:50
On 27/01/17 08:54, Quentin Schulz wrote:
The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
battery voltage, battery charge and discharge currents, AC-in and VBUS
voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
This adds support for most of AXP20X and AXP22X ADCs.
Signed-off-by: Quentin Schulz <redacted>
Pretty good, but not everything seems to be cleaned up on error paths
in probe.
A few other suggestions / questions inline.
Jonathan
quoted hunk
---
v2:
- removed unused defines,
- changed BIT(x) to 1 << x when describing bits purpose for which 2 <<
x or 3 << x exists, to be consistent,
- changed ADC rate defines to macro formulas,
- reordered IIO channels, now different measures (current/voltage) of
the same part of the PMIC (e.g. battery), have the same IIO channel in
their respective IIO type. When a part of the PMIC have only one
measure, a number is jumped,
- left IIO channel mapping in DT to use iio_map structure,
- removed indexing of ADC internal temperature,
- removed unused iio_dev structure in axp20x_adc_iio,
- added a structure for data specific to AXP20X or AXP22X PMICs instead
of using an ID and an if condition when needing to separate the
behaviour of both,
- added a comment on batt_chrg_i really being on 12bits rather than
what the Chinese datasheets say (13 bits),
- corrected the offset for AXP22X PMIC temperature,
- set the ADC rate to a value (100Hz) shared by the AXP20X and AXP22X,
- created macro formulas to compute the ADC rate for each,
- added a condition on presence of ADC_EN2 reg before setting/resetting
it,
- switched from devm_iio_device_unregister to the non-devm function
because of the need for a remove function,
- removed some dead code,
drivers/iio/adc/Kconfig | 10 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/axp20x_adc.c | 572 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 583 insertions(+)
create mode 100644 drivers/iio/adc/axp20x_adc.c
Given I don't think you can get here without it being current, voltage or temp;
couldn't this be done more cleanly with
if ((chan->type == IIO_CURRENT) && (chan->channel == AXP20X_BAT_DISCHRG_I))
size = 13;
and have the rest in the normal code flow?
+ case IIO_VOLTAGE:
+ case IIO_TEMP:
+ *val = axp20x_read_variable_width(info->regmap, chan->address,
+ size);
+ if (*val < 0)
+ return *val;
+
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int axp22x_adc_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val)
+{
+ struct axp20x_adc_iio *info = iio_priv(indio_dev);
+ int size = 12;
+
+ switch (chan->type) {
+ case IIO_CURRENT:
+ /*
+ * Unlike the Chinese datasheets tell, the charging current is
+ * stored on 12 bits, not 13 bits.
+ */
+ if (chan->channel == AXP22X_BATT_DISCHRG_I)
+ size = 13;
+ case IIO_VOLTAGE:
+ case IIO_TEMP:
+ *val = axp20x_read_variable_width(info->regmap, chan->address,
+ size);
+ if (*val < 0)
+ return *val;
+
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int axp20x_adc_scale_voltage(int channel, int *val, int *val2)
+{
+ switch (channel) {
+ case AXP20X_ACIN_V:
+ case AXP20X_VBUS_V:
+ *val = 1;
+ *val2 = 700000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case AXP20X_GPIO0_V:
+ case AXP20X_GPIO1_V:
+ *val = 0;
+ *val2 = 500000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case AXP20X_BATT_V:
+ *val = 1;
+ *val2 = 100000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case AXP20X_IPSOUT_V:
+ *val = 1;
+ *val2 = 400000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int axp20x_adc_scale_current(int channel, int *val, int *val2)
+{
+ switch (channel) {
+ case AXP20X_ACIN_I:
+ *val = 0;
+ *val2 = 625000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case AXP20X_VBUS_I:
+ *val = 0;
+ *val2 = 375000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ case AXP20X_BATT_DISCHRG_I:
+ case AXP20X_BATT_CHRG_I:
+ *val = 0;
+ *val2 = 500000;
+ return IIO_VAL_INT_PLUS_MICRO;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int axp20x_adc_scale(struct iio_chan_spec const *chan, int *val,
+ int *val2)
+{
+ switch (chan->type) {
+ case IIO_VOLTAGE:
+ return axp20x_adc_scale_voltage(chan->channel, val, val2);
+
+ case IIO_CURRENT:
+ return axp20x_adc_scale_current(chan->channel, val, val2);
+
+ case IIO_TEMP:
+ *val = 100;
+ return IIO_VAL_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,
+ int *val2)
+{
+ switch (chan->type) {
+ case IIO_VOLTAGE:
+ if (chan->channel != AXP22X_BATT_V)
+ return -EINVAL;
+
+ *val = 1;
+ *val2 = 100000;
+ return IIO_VAL_INT_PLUS_MICRO;
Not sure on this name - what does end up as? Expected to be
a description of the part so in this case something like axp209-adc.
I've been lax at picking up on this in the past and it's led to some
crazy naming that is no use at all to userspace. Basically this
name just provides a convenient user readable name for userspace apps to
use.
+ return ret;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not register the device\n");
+ regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
+
+ if (info->data->adc_en2)
+ regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
I'd expect to see a complete unwind of what has been done earlier in probe
including iio_map_array_unregister.
The traditional goto error* approach is probably worth having here to
make sure the unwind makes sense.
From: Jonathan Cameron <jic23@kernel.org> Date: 2017-01-28 14:59:57
On 27/01/17 08:54, Quentin Schulz wrote:
This maps the IIO channels batt_v, batt_chrg_i and batt_dischrg_i
(respectively exposing the current charging and discharging currents and
current voltage measures of the battery power supply) to the battery
power supply driver.
Signed-off-by: Quentin Schulz <redacted>
From: Jonathan Cameron <jic23@kernel.org> Date: 2017-01-28 15:20:08
On 27/01/17 08:54, Quentin Schulz wrote:
The X-Powers AXP20X and AXP22X PMICs can have a battery as power supply.
This patch adds the battery power supply driver to get various data from
the PMIC, such as the battery status (charging, discharging, full,
dead), current max limit, current current, battery capacity (in
percentage), voltage max and min limits, current voltage and battery
capacity (in Ah).
This battery driver uses the AXP20X/AXP22X ADC driver as PMIC data
provider.
Signed-off-by: Quentin Schulz <redacted>
For IIO bits
Acked-by: Jonathan Cameron <jic23@kernel.org>
quoted hunk
---
v2:
- changed BIT(x) to 1 << x when describing bits purpose for which 2 <<
x or 3 << x exists, to be consistent,
- switched from POWER_SUPPLY_PROP_CURRENT_MAX to
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
- added POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX to the list of
readable properties,
- replaced ? character by a common u for micro units to make checkpatch
happy,
- factorized code in axp20x_battery_set_max_voltage,
- added a axp20x_set_constant_charge_current function to be used when
setting the value from sysfs and from the DT,
- removed some dead code,
- added a DT property to set constant current charge of the battery
(x-powers,constant-charge-current),
- migrated to dev_get_regmap instead of manually looking for the regmap
in the drvdata of the parent,
- switched from int to uintptr_t cast to make sure the cast is always
for the same size type (make build on 64bits platforms happy mainly),
drivers/power/supply/Kconfig | 12 +
drivers/power/supply/Makefile | 1 +
drivers/power/supply/axp20x_battery.c | 477 ++++++++++++++++++++++++++++++++++
3 files changed, 490 insertions(+)
create mode 100644 drivers/power/supply/axp20x_battery.c
Hi Jonathan
On 28/01/2017 15:49, Jonathan Cameron wrote:
On 27/01/17 08:54, Quentin Schulz wrote:
quoted
The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
battery voltage, battery charge and discharge currents, AC-in and VBUS
voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
This adds support for most of AXP20X and AXP22X ADCs.
Signed-off-by: Quentin Schulz <redacted>
Pretty good, but not everything seems to be cleaned up on error paths
in probe.
A few other suggestions / questions inline.
Jonathan
quoted
---
[...]
quoted
+static int axp20x_adc_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val)
+{
+ struct axp20x_adc_iio *info = iio_priv(indio_dev);
+ int size = 12;
+
+ switch (chan->type) {
+ case IIO_CURRENT:
+ /*
+ * Unlike the Chinese datasheets tell, the charging current is
+ * stored on 12 bits, not 13 bits.
+ */
+ if (chan->channel == AXP20X_BATT_DISCHRG_I)
+ size = 13;
Given I don't think you can get here without it being current, voltage or temp;
couldn't this be done more cleanly with
if ((chan->type == IIO_CURRENT) && (chan->channel == AXP20X_BAT_DISCHRG_I))
size = 13;
and have the rest in the normal code flow?
Not sure on this name - what does end up as? Expected to be
a description of the part so in this case something like axp209-adc.
I've been lax at picking up on this in the past and it's led to some
crazy naming that is no use at all to userspace. Basically this
name just provides a convenient user readable name for userspace apps to
use.
ACK. Should we have a different name for AXP20X and AXP22X PMICs?
You mean disabling ADCs as it is done in the remove? If so, indeed.
quoted
+ return ret;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not register the device\n");
+ regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
+
+ if (info->data->adc_en2)
+ regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
I'd expect to see a complete unwind of what has been done earlier in probe
including iio_map_array_unregister.
The traditional goto error* approach is probably worth having here to
make sure the unwind makes sense.
Yes. I see iio_device_unregister already disable all buffers, why not
unregistering the map array as well in this function?
[...]
Thanks,
Quentin
--
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
From: Jonathan Cameron <jic23@kernel.org> Date: 2017-01-28 15:35:28
On 28/01/17 15:12, Quentin Schulz wrote:
Hi Jonathan
On 28/01/2017 15:49, Jonathan Cameron wrote:
quoted
On 27/01/17 08:54, Quentin Schulz wrote:
quoted
The X-Powers AXP20X and AXP22X PMICs have multiple ADCs. They expose the
battery voltage, battery charge and discharge currents, AC-in and VBUS
voltages and currents, 2 GPIOs muxable in ADC mode and PMIC temperature.
This adds support for most of AXP20X and AXP22X ADCs.
Signed-off-by: Quentin Schulz <redacted>
Pretty good, but not everything seems to be cleaned up on error paths
in probe.
A few other suggestions / questions inline.
Jonathan
quoted
---
[...]
quoted
quoted
+static int axp20x_adc_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val)
+{
+ struct axp20x_adc_iio *info = iio_priv(indio_dev);
+ int size = 12;
+
+ switch (chan->type) {
+ case IIO_CURRENT:
+ /*
+ * Unlike the Chinese datasheets tell, the charging current is
+ * stored on 12 bits, not 13 bits.
+ */
+ if (chan->channel == AXP20X_BATT_DISCHRG_I)
+ size = 13;
Given I don't think you can get here without it being current, voltage or temp;
couldn't this be done more cleanly with
if ((chan->type == IIO_CURRENT) && (chan->channel == AXP20X_BAT_DISCHRG_I))
size = 13;
and have the rest in the normal code flow?
Not sure on this name - what does end up as? Expected to be
a description of the part so in this case something like axp209-adc.
I've been lax at picking up on this in the past and it's led to some
crazy naming that is no use at all to userspace. Basically this
name just provides a convenient user readable name for userspace apps to
use.
ACK. Should we have a different name for AXP20X and AXP22X PMICs?
You mean disabling ADCs as it is done in the remove? If so, indeed.
yes.
quoted
quoted
+ return ret;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "could not register the device\n");
+ regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
+
+ if (info->data->adc_en2)
+ regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
I'd expect to see a complete unwind of what has been done earlier in probe
including iio_map_array_unregister.
The traditional goto error* approach is probably worth having here to
make sure the unwind makes sense.
From: Sebastian Reichel <sre@kernel.org> Date: 2017-01-29 16:22:02
Hi,
On Fri, Jan 27, 2017 at 09:54:36AM +0100, Quentin Schulz wrote:
The X-Powers AXP20X PMIC exposes the current current and voltage
measures via an internal ADC.
This adds the possibility to read IIO channels directly for processed
values rather than reading the registers and computing the value.
For backward compatibility purpose, if the IIO driver is not compiled,
this driver will fall back on previous behaviour which is direct
register readings.
Signed-off-by: Quentin Schulz <redacted>
From: Sebastian Reichel <sre@kernel.org> Date: 2017-01-29 16:25:20
Hi,
On Fri, Jan 27, 2017 at 09:54:41AM +0100, Quentin Schulz wrote:
The X-Powers AXP20X and AXP22X PMICs have an AC entry to supply power to
the board. They have a few registers dedicated to the status of the AC
power supply.
This adds the DT binding documentation for the AC power supply for
AXP20X and AXP22X PMICs.
Signed-off-by: Quentin Schulz <redacted>
From: Sebastian Reichel <sre@kernel.org> Date: 2017-01-29 16:26:59
Hi,
On Fri, Jan 27, 2017 at 09:54:43AM +0100, Quentin Schulz wrote:
The X-Powers AXP20X and AXP22X PMICs expose the status of AC power
supply.
Moreover, the AXP20X can also expose the current current and voltage
values of the AC power supply.
This adds the driver which exposes the status of the AC power supply of
the AXP20X and AXP22X PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Thanks, I queued this into power-supply's for-next branch. I
removed "struct device_node *np" and "int axp20x_id" from
"struct axp20x_ac_power", since they were unused.
-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170129/23e6f0db/attachment.sig>
From: Sebastian Reichel <sre@kernel.org> Date: 2017-01-29 16:32:03
Hi,
On Fri, Jan 27, 2017 at 09:54:42AM +0100, Quentin Schulz wrote:
quoted hunk
This maps the IIO channels acin_i and acin_v (respectively exposing the
current current and voltage measures of the AC power supply) to the AC
power supply driver.
Only the AXP20X PMICs have these ADC channels and thus they are only
mapped for this version of the PMIC.
Signed-off-by: Quentin Schulz <redacted>
---
added in v2
drivers/iio/adc/axp20x_adc.c | 8 ++++++++
1 file changed, 8 insertions(+)
From: Sebastian Reichel <sre@kernel.org> Date: 2017-01-29 16:38:32
Hi,
On Fri, Jan 27, 2017 at 09:54:44AM +0100, Quentin Schulz wrote:
The X-Powers AXP20X and AXP22X PMICs expose the status of AC power
supply.
This adds the AC power supply driver to the MFD cells of the AXP22X
PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
X-Powers AXP209 PMIC has multiple ADCs, each one exposing data from the
different power supplies connected to the PMIC.
This adds the ADC subnode for AXP20X PMIC.
Signed-off-by: Quentin Schulz <redacted>
Given the device node no longer exports anything, we might
as well drop it from the device tree.
On Mon, Jan 30, 2017 at 12:35 AM, Sebastian Reichel [off-list ref] wrote:
Hi,
On Fri, Jan 27, 2017 at 09:54:44AM +0100, Quentin Schulz wrote:
quoted
The X-Powers AXP20X and AXP22X PMICs expose the status of AC power
supply.
This adds the AC power supply driver to the MFD cells of the AXP22X
PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
The X-Powers AXP22X PMIC exposes the status of AC power supply.
This adds the AC power supply subnode for the AXP22X PMIC.
Signed-off-by: Quentin Schulz <redacted>
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
The X-Powers AXP20X PMIC exposes the status of AC power supply, the
current current and voltage supplied to the board by the AC power
supply.
This adds the AC power supply subnode for AXP20X PMIC.
Signed-off-by: Quentin Schulz <redacted>
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
The Sinlinx SinA33 has an AXP223 PMIC and an ACIN connector, thus, we
enable the ACIN power supply in its Device Tree.
Signed-off-by: Quentin Schulz <redacted>
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
The NextThing Co. CHIP has an AXP209 PMIC and can be power-supplied by
ACIN via the CHG-IN pin.
This enables the ACIN power supply subnode in the DT.
Signed-off-by: Quentin Schulz <redacted>
On Sat, Jan 28, 2017 at 10:52 PM, Jonathan Cameron [off-list ref] wrote:
On 27/01/17 08:54, Quentin Schulz wrote:
quoted
This maps the IIO channels batt_v, batt_chrg_i and batt_dischrg_i
(respectively exposing the current charging and discharging currents and
current voltage measures of the battery power supply) to the battery
power supply driver.
Signed-off-by: Quentin Schulz <redacted>
On Fri, Jan 27, 2017 at 4:54 PM, Quentin Schulz
[off-list ref] wrote:
The CHRG_CTRL1 and CHRG_CTRL2 registers are made for controlling
different battery charging settings such as the constant current charge
value.
The AXP22X also have a third register CHRG_CTRL3 which has settings for
battery charging too.
This adds the CHRG_CTRL1, CHRG_CTRL2 and CHRG_CTRL3 registers to the
list of writeable registers for AXP20X and AXP22X PMICs.
Signed-off-by: Quentin Schulz <redacted>
Acked-for-MFD-by: Lee Jones [off-list ref]
Hi,
On Fri, Jan 27, 2017 at 09:54:49AM +0100, Quentin Schulz wrote:
quoted
- added x-powers,constant-charge-current property to set the
maximal default constant current charge of the battery,
Since this is information about the battery and not the fuel-gauge,
it should use the WIP "framework" for information about batteries.
Have a look at the following patchset:
http://marc.info/?l=linux-pm&m=148411561025684&w=2
OK. So what you propose is to have a fourth property in this new
structure named design-max-constant-charge-current that gives the
maximal input amperage the battery can receive?
Then, I set the charger to output a maximum of this amperage by default
and let the user the possibility to choose between the minimum allowed
by the PMIC and the maximum allowed by the battery from sysfs. That
makes more sense than what I do here in the way that I didn't protect a
possible over-amperage of the battery, thing that Chen-Yu was afraid
some users would do.
I've a comment on the linked patches however. Though the three
properties are listed as optional in the binding-dt, the implementation
is saying the opposite:
http://marc.info/?l=linux-pm&m=148411561725693&w=2
If I'm not mistaken, if `nominal-microvolt' or `design-microwatt-hours'
is not a property of the DT node, power_supply_get_battery_info will
return without parsing the other properties and even return a negative
error.
Thanks,
Quentin
--
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170131/746ba7b8/attachment-0001.sig>
From: Lee Jones <hidden> Date: 2017-02-08 09:27:38
On Fri, 27 Jan 2017, Quentin Schulz wrote:
The registers 0x56 and 0x57 of AXP22X PMIC store the value of the
internal temperature of the PMIC.
This patch modifies the name of these registers from AXP22X_PMIC_ADC_H/L
to AXP22X_PMIC_TEMP_H/L so their purpose is clearer.
Signed-off-by: Quentin Schulz <redacted>
---
added in v2
drivers/mfd/axp20x.c | 2 +-
include/linux/mfd/axp20x.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
For my own reference:
Acked-for-MFD-by: Lee Jones [off-list ref]