linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers
@ 2017-01-02 16:37 Quentin Schulz
  2017-01-02 16:37 ` [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding Quentin Schulz
                   ` (21 more replies)
  0 siblings, 22 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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.

[RFC]
I want to take this series of patch as an opportunity to ask what we should
do with the OCV curves.

A battery voltage does not decrease linearly but decreases slowly near
maximum and minimal voltage and quickly most of the time.
By taking raw values without an OCV curve, the battery percentage (or
often wrongly named "capacity") is computed by approximating by a linear
function. This results in battery percentage not lasting the same
depending if the battery is full, almost empty or within those two
states. For example, a decrease of 40 points could take as much time as
a decrease of 5 points when in low battery. Without an OCV curve, the
battery percentage returned by the battery driver (as it is done today)
is absolute non-sense.
When an OCV curve is provided, the percentage is approximated by this
OCV curve and battery percentage are very more likely to last the same
time and thus, being trustworthy.

While I understand the kernel has absolutely nothing to do with OCV
computation, the AXP20X/AXP22X PMICs raise a question due to their
ability to compute the approximated battery percentage if we give them
the OCV curve of the battery in some of their registers. No computing
has to be done in the kernel, we just have to give them the OCV curve of
the battery and the PMIC will return the approximated percentage.

The question is how to do it? IMHO, two different approaches are possible:

 - give the OCV curve points in the Device Tree,
   This allows the OCV curve to be fixed for boards with a non-removable
   battery. However, it also avoids changing batteries without
   recompiling the DT, which is definitely not end-user friendly.
   The DT is here for hardware definition and battery is hardware
   definition I guess, so it makes sense in a way, but it does not work
   for removable batteries.

 - give the OCV curve points via the POWER_SUPPLY_PROP_VOLTAGE_OCV sysfs
 entry in the Power Supply framework,
   This allows the OCV curve to be changed when a user switches the
   batteries, but it also means that the OCV curve will always have to
   be submitted by a small boot script which means it is
   rootfs-dependent. Not really cool for a hardware component which in
   embedded systems is more than likely not to change (IMHO).

Maybe, the best would be the two approaches at the same time: the
OCV curve of the default battery in the DT and the possibility to modify
the OCV curve via the POWER_SUPPLY_PROP_VOLTAGE_OCV sysfs entry?

Thanks,
Quentin

Quentin Schulz (22):
  dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
  mfd: axp20x: add ADC data regs to volatile regs for AXP22X
  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
  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 to writeable regs for AXP20X/AXP22X
  mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X
  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     |  24 +
 .../bindings/power/supply/axp20x_ac_power.txt      |  27 ++
 .../bindings/power/supply/axp20x_battery.txt       |  24 +
 arch/arm/boot/dts/axp209.dtsi                      |  19 +
 arch/arm/boot/dts/axp22x.dtsi                      |  17 +
 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                       | 490 +++++++++++++++++++++
 drivers/mfd/axp20x.c                               |  35 +-
 drivers/power/supply/Kconfig                       |  24 +
 drivers/power/supply/Makefile                      |   2 +
 drivers/power/supply/axp20x_ac_power.c             | 251 +++++++++++
 drivers/power/supply/axp20x_battery.c              | 458 +++++++++++++++++++
 include/linux/mfd/axp20x.h                         |   4 +
 16 files changed, 1400 insertions(+), 2 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

^ permalink raw reply	[flat|nested] 72+ messages in thread

* [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-03 23:20   ` Rob Herring
  2017-01-05 16:40   ` Maxime Ripard
  2017-01-02 16:37 ` [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X Quentin Schulz
                   ` (20 subsequent siblings)
  21 siblings, 2 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 .../devicetree/bindings/iio/adc/axp20x_adc.txt     | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt b/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
new file mode 100644
index 0000000..1b60065
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
@@ -0,0 +1,24 @@
+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"
+ - #io-channel-cells = <1>;
+
+This is a subnode of the AXP20X PMIC.
+
+Example:
+
+&axp209 {
+	axp209_adc: axp209_adc {
+		compatible = "x-powers,axp209-adc";
+		#io-channel-cells = <1>;
+	};
+};
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
  2017-01-02 16:37 ` [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 11:55   ` Lee Jones
  2017-01-05  4:12   ` Chen-Yu Tsai
  2017-01-02 16:37 ` [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs Quentin Schulz
                   ` (19 subsequent siblings)
  21 siblings, 2 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

The AXP22X PMICs have multiple ADCs, each one exposing data from the
different power supplies connected to the PMIC.

This adds the different ADC data registers to the volatile registers of
the AXP22X PMIC.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
 drivers/mfd/axp20x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 619a83e..a33db5e 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -100,6 +100,7 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
 static const struct regmap_range axp22x_volatile_ranges[] = {
 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
 	regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT, AXP20X_VBUS_IPSOUT_MGMT),
+	regmap_reg_range(AXP22X_TEMP_ADC_H, AXP20X_BATT_DISCHRG_I_L),
 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
 	regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
 	regmap_reg_range(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
  2017-01-02 16:37 ` [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding Quentin Schulz
  2017-01-02 16:37 ` [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-05  5:42   ` Chen-Yu Tsai
                     ` (2 more replies)
  2017-01-02 16:37 ` [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs Quentin Schulz
                   ` (18 subsequent siblings)
  21 siblings, 3 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 drivers/iio/adc/Kconfig      |  10 +
 drivers/iio/adc/Makefile     |   1 +
 drivers/iio/adc/axp20x_adc.c | 490 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h   |   4 +
 4 files changed, 505 insertions(+)
 create mode 100644 drivers/iio/adc/axp20x_adc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 38bc319..5c5b51f 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -154,6 +154,16 @@ config AT91_SAMA5D2_ADC
 	  To compile this driver as a module, choose M here: the module will be
 	  called at91-sama5d2_adc.
 
+config AXP20X_ADC
+	tristate "X-Powers AXP20X and AXP22X ADC driver"
+	depends on MFD_AXP20X
+	help
+	  Say yes here to have support for X-Powers power management IC (PMIC)
+	  AXP20X and AXP22X ADC devices.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called axp20x_adc.
+
 config AXP288_ADC
 	tristate "X-Powers AXP288 ADC driver"
 	depends on MFD_AXP20X
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index d36c4be..f5c28a5 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
 obj-$(CONFIG_AD799X) += ad799x.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
+obj-$(CONFIG_AXP20X_ADC) += axp20x_adc.o
 obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
 obj-$(CONFIG_BCM_IPROC_ADC) += bcm_iproc_adc.o
 obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c
new file mode 100644
index 0000000..8df972a
--- /dev/null
+++ b/drivers/iio/adc/axp20x_adc.c
@@ -0,0 +1,490 @@
+/* ADC driver for AXP20X and AXP22X PMICs
+ *
+ * Copyright (c) 2016 Free Electrons NextThing Co.
+ *	Quentin Schulz <quentin.schulz@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ *
+ */
+
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/thermal.h>
+
+#include <linux/iio/iio.h>
+#include <linux/mfd/axp20x.h>
+
+#define AXP20X_ADC_EN1_MASK			GENMASK(7, 0)
+
+#define AXP20X_ADC_EN2_MASK			(GENMASK(3, 2) | BIT(7))
+#define AXP22X_ADC_EN1_MASK			(GENMASK(7, 5) | BIT(0))
+#define AXP20X_ADC_EN2_TEMP_ADC			BIT(7)
+#define AXP20X_ADC_EN2_GPIO0_ADC		BIT(3)
+#define AXP20X_ADC_EN2_GPIO1_ADC		BIT(2)
+
+#define AXP20X_GPIO10_IN_RANGE_GPIO0		BIT(0)
+#define AXP20X_GPIO10_IN_RANGE_GPIO1		BIT(1)
+#define AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(x)	((x) & BIT(0))
+#define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x)	(((x) & BIT(0)) << 1)
+
+#define AXP20X_ADC_RATE_MASK			(3 << 6)
+#define AXP20X_ADC_RATE_25HZ			(0 << 6)
+#define AXP20X_ADC_RATE_50HZ			BIT(6)
+#define AXP20X_ADC_RATE_100HZ			(2 << 6)
+#define AXP20X_ADC_RATE_200HZ			(3 << 6)
+
+#define AXP22X_ADC_RATE_100HZ			(0 << 6)
+#define AXP22X_ADC_RATE_200HZ			BIT(6)
+#define AXP22X_ADC_RATE_400HZ			(2 << 6)
+#define AXP22X_ADC_RATE_800HZ			(3 << 6)
+
+#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)	\
+	{							\
+		.type = _type,					\
+		.indexed = 1,					\
+		.channel = _channel,				\
+		.address = _reg,				\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
+				      BIT(IIO_CHAN_INFO_SCALE),	\
+		.datasheet_name = _name,			\
+	}
+
+#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
+	{							\
+		.type = _type,					\
+		.indexed = 1,					\
+		.channel = _channel,				\
+		.address = _reg,				\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
+				      BIT(IIO_CHAN_INFO_SCALE) |\
+				      BIT(IIO_CHAN_INFO_OFFSET),\
+		.datasheet_name = _name,			\
+	}
+
+struct axp20x_adc_iio {
+	struct iio_dev		*indio_dev;
+	struct regmap		*regmap;
+};
+
+enum axp20x_adc_channel {
+	AXP20X_ACIN_V = 0,
+	AXP20X_ACIN_I,
+	AXP20X_VBUS_V,
+	AXP20X_VBUS_I,
+	AXP20X_TEMP_ADC,
+	AXP20X_GPIO0_V,
+	AXP20X_GPIO1_V,
+	AXP20X_BATT_V,
+	AXP20X_BATT_CHRG_I,
+	AXP20X_BATT_DISCHRG_I,
+	AXP20X_IPSOUT_V,
+};
+
+enum axp22x_adc_channel {
+	AXP22X_TEMP_ADC = 0,
+	AXP22X_BATT_V,
+	AXP22X_BATT_CHRG_I,
+	AXP22X_BATT_DISCHRG_I,
+};
+
+static const struct iio_chan_spec axp20x_adc_channels[] = {
+	AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,
+			   AXP20X_ACIN_V_ADC_H),
+	AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,
+			   AXP20X_ACIN_I_ADC_H),
+	AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,
+			   AXP20X_VBUS_V_ADC_H),
+	AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,
+			   AXP20X_VBUS_I_ADC_H),
+	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_TEMP_ADC, "temp_adc", IIO_TEMP,
+				  AXP20X_TEMP_ADC_H),
+	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
+				  AXP20X_GPIO0_V_ADC_H),
+	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,
+				  AXP20X_GPIO1_V_ADC_H),
+	AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,
+			   AXP20X_BATT_V_H),
+	AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
+			   AXP20X_BATT_CHRG_I_H),
+	AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
+			   AXP20X_BATT_DISCHRG_I_H),
+	AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
+			   AXP20X_IPSOUT_V_HIGH_H),
+};
+
+static const struct iio_chan_spec axp22x_adc_channels[] = {
+	AXP20X_ADC_CHANNEL_OFFSET(AXP22X_TEMP_ADC, "temp_adc", IIO_TEMP,
+				  AXP22X_TEMP_ADC_H),
+	AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,
+			   AXP20X_BATT_V_H),
+	AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
+			   AXP20X_BATT_CHRG_I_H),
+	AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
+			   AXP20X_BATT_DISCHRG_I_H),
+};
+
+static int axp20x_adc_read_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *channel, int *val,
+			       int *val2)
+{
+	struct axp20x_adc_iio *info = iio_priv(indio_dev);
+	int size = 12, ret;
+
+	switch (channel->channel) {
+	case AXP20X_BATT_DISCHRG_I:
+		size = 13;
+	case AXP20X_ACIN_V:
+	case AXP20X_ACIN_I:
+	case AXP20X_VBUS_V:
+	case AXP20X_VBUS_I:
+	case AXP20X_TEMP_ADC:
+	case AXP20X_BATT_V:
+	case AXP20X_BATT_CHRG_I:
+	case AXP20X_IPSOUT_V:
+	case AXP20X_GPIO0_V:
+	case AXP20X_GPIO1_V:
+		ret = axp20x_read_variable_width(info->regmap, channel->address,
+						 size);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *channel, int *val,
+			       int *val2)
+{
+	struct axp20x_adc_iio *info = iio_priv(indio_dev);
+	int size = 12, ret;
+
+	switch (channel->channel) {
+	case AXP22X_BATT_DISCHRG_I:
+		size = 13;
+	case AXP22X_TEMP_ADC:
+	case AXP22X_BATT_V:
+	case AXP22X_BATT_CHRG_I:
+		ret = axp20x_read_variable_width(info->regmap, channel->address,
+						 size);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp20x_adc_scale(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_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_TEMP_ADC:
+		*val = 100;
+		return IIO_VAL_INT;
+
+	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_BATT_DISCHRG_I:
+	case AXP20X_BATT_CHRG_I:
+		*val = 0;
+		*val2 = 500000;
+		return IIO_VAL_INT_PLUS_MICRO;
+
+	case AXP20X_IPSOUT_V:
+		*val = 1;
+		*val2 = 400000;
+		return IIO_VAL_INT_PLUS_MICRO;
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp22x_adc_scale(int channel, int *val, int *val2)
+{
+	switch (channel) {
+	case AXP22X_TEMP_ADC:
+		*val = 100;
+		return IIO_VAL_INT;
+
+	case AXP22X_BATT_V:
+		*val = 1;
+		*val2 = 100000;
+		return IIO_VAL_INT_PLUS_MICRO;
+
+	case AXP22X_BATT_DISCHRG_I:
+	case AXP22X_BATT_CHRG_I:
+		*val = 0;
+		*val2 = 500000;
+		return IIO_VAL_INT_PLUS_MICRO;
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp20x_adc_offset(struct iio_dev *indio_dev, int channel, int *val)
+{
+	struct axp20x_adc_iio *info = iio_priv(indio_dev);
+	int ret, reg;
+
+	switch (channel) {
+	case AXP20X_TEMP_ADC:
+		*val = -1447;
+		return IIO_VAL_INT;
+
+	case AXP20X_GPIO0_V:
+	case AXP20X_GPIO1_V:
+		ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, &reg);
+		if (ret < 0)
+			return ret;
+
+		if (channel == AXP20X_GPIO0_V)
+			*val = reg & AXP20X_GPIO10_IN_RANGE_GPIO0;
+		else
+			*val = reg & AXP20X_GPIO10_IN_RANGE_GPIO1;
+
+		*val = !!(*val) * 700000;
+
+		return IIO_VAL_INT;
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp20x_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan, int *val,
+			   int *val2, long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_OFFSET:
+		return axp20x_adc_offset(indio_dev, chan->channel, val);
+
+	case IIO_CHAN_INFO_SCALE:
+		return axp20x_adc_scale(chan->channel, val, val2);
+
+	case IIO_CHAN_INFO_RAW:
+		return axp20x_adc_read_raw(indio_dev, chan, val, val2);
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp22x_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan, int *val,
+			   int *val2, long mask)
+{
+	switch (mask) {
+	case IIO_CHAN_INFO_OFFSET:
+		*val = -2667;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		return axp22x_adc_scale(chan->channel, val, val2);
+
+	case IIO_CHAN_INFO_RAW:
+		return axp22x_adc_read_raw(indio_dev, chan, val, val2);
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int axp20x_write_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan, int val, int val2,
+			    long mask)
+{
+	struct axp20x_adc_iio *info = iio_priv(indio_dev);
+
+	/*
+	 * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets
+	 * for (independently) GPIO0 and GPIO1 when in ADC mode.
+	 */
+	if (mask != IIO_CHAN_INFO_OFFSET)
+		return -EINVAL;
+
+	if (chan->channel != AXP20X_GPIO0_V && chan->channel != AXP20X_GPIO1_V)
+		return -EINVAL;
+
+	if (val != 0 && val != 700000)
+		return -EINVAL;
+
+	if (chan->channel == AXP20X_GPIO0_V)
+		return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
+					  AXP20X_GPIO10_IN_RANGE_GPIO0,
+					  AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val));
+
+	return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
+				  AXP20X_GPIO10_IN_RANGE_GPIO1,
+				  AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val));
+}
+
+static const struct iio_info axp20x_adc_iio_info = {
+	.read_raw = axp20x_read_raw,
+	.write_raw = axp20x_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info axp22x_adc_iio_info = {
+	.read_raw = axp22x_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct of_device_id axp20x_adc_of_match[] = {
+	{ .compatible = "x-powers,axp209-adc", .data = (void *)AXP209_ID, },
+	{ .compatible = "x-powers,axp221-adc", .data = (void *)AXP221_ID, },
+	{ /* sentinel */ },
+};
+
+static int axp20x_probe(struct platform_device *pdev)
+{
+	struct axp20x_adc_iio *info;
+	struct iio_dev *indio_dev;
+	struct axp20x_dev *axp20x_dev;
+	int ret, axp20x_id;
+
+	axp20x_dev = dev_get_drvdata(pdev->dev.parent);
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	info = iio_priv(indio_dev);
+	platform_set_drvdata(pdev, indio_dev);
+
+	info->regmap = axp20x_dev->regmap;
+	info->indio_dev = indio_dev;
+	indio_dev->name = dev_name(&pdev->dev);
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->dev.of_node = pdev->dev.of_node;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	axp20x_id = (int)of_device_get_match_data(&pdev->dev);
+
+	switch (axp20x_id) {
+	case AXP209_ID:
+		indio_dev->info = &axp20x_adc_iio_info;
+		indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
+		indio_dev->channels = axp20x_adc_channels;
+
+		/* Enable the ADCs on IP */
+		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
+
+		/* Enable GPIO0/1 and internal temperature ADCs */
+		regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
+				   AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
+
+		/* Configure ADCs rate */
+		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
+				   AXP20X_ADC_RATE_MASK, AXP20X_ADC_RATE_50HZ);
+		break;
+
+	case AXP221_ID:
+		indio_dev->info = &axp22x_adc_iio_info;
+		indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
+		indio_dev->channels = axp22x_adc_channels;
+
+		/* Enable the ADCs on IP */
+		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
+
+		/* Configure ADCs rate */
+		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
+				   AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	ret = devm_iio_device_register(&pdev->dev, indio_dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "could not register the device\n");
+		regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
+		regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int axp20x_remove(struct platform_device *pdev)
+{
+	struct axp20x_adc_iio *info;
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+
+	info = iio_priv(indio_dev);
+	regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
+	regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
+
+	return 0;
+}
+
+static struct platform_driver axp20x_adc_driver = {
+	.driver = {
+		.name = "axp20x-adc",
+		.of_match_table = axp20x_adc_of_match,
+	},
+	.probe = axp20x_probe,
+	.remove = axp20x_remove,
+};
+
+module_platform_driver(axp20x_adc_driver);
+
+MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
+MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index a4860bc..650c6f6 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -150,6 +150,10 @@ enum {
 #define AXP20X_VBUS_I_ADC_L		0x5d
 #define AXP20X_TEMP_ADC_H		0x5e
 #define AXP20X_TEMP_ADC_L		0x5f
+
+#define AXP22X_TEMP_ADC_H		0x56
+#define AXP22X_TEMP_ADC_L		0x57
+
 #define AXP20X_TS_IN_H			0x62
 #define AXP20X_TS_IN_L			0x63
 #define AXP20X_GPIO0_V_ADC_H		0x64
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (2 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 11:56   ` Lee Jones
  2017-01-02 16:37 ` [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode Quentin Schulz
                   ` (17 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

This adds the AXP20X/AXP22x ADCs driver to the mfd cells of the AXP209,
AXP221 and AXP223 MFD.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
 drivers/mfd/axp20x.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index a33db5e..31a84d81 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -582,6 +582,9 @@ static struct mfd_cell axp20x_cells[] = {
 	}, {
 		.name		= "axp20x-regulator",
 	}, {
+		.name		= "axp20x-adc",
+		.of_compatible	= "x-powers,axp209-adc",
+	}, {
 		.name		= "axp20x-ac-power-supply",
 		.of_compatible	= "x-powers,axp202-ac-power-supply",
 		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
@@ -602,6 +605,9 @@ static struct mfd_cell axp221_cells[] = {
 	}, {
 		.name		= "axp20x-regulator",
 	}, {
+		.name		= "axp20x-adc",
+		.of_compatible	= "x-powers,axp221-adc"
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp221-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
@@ -615,6 +621,9 @@ static struct mfd_cell axp223_cells[] = {
 		.num_resources		= ARRAY_SIZE(axp22x_pek_resources),
 		.resources		= axp22x_pek_resources,
 	}, {
+		.name		= "axp20x-adc",
+		.of_compatible	= "x-powers,axp221-adc"
+	}, {
 		.name			= "axp20x-regulator",
 	}, {
 		.name		= "axp20x-usb-power-supply",
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (3 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-05  5:51   ` Chen-Yu Tsai
  2017-01-02 16:37 ` [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X " Quentin Schulz
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/axp209.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index 675bb0f..2a4e8ee 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -53,6 +53,11 @@
 	interrupt-controller;
 	#interrupt-cells = <1>;
 
+	axp209_adc: axp209_adc {
+		compatible = "x-powers,axp209-adc";
+		#io-channel-cells = <1>;
+	};
+
 	axp_gpio: gpio {
 		compatible = "x-powers,axp209-gpio";
 		gpio-controller;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X ADC subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (4 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-05  5:52   ` Chen-Yu Tsai
  2017-01-02 16:37 ` [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply Quentin Schulz
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/axp22x.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
index 458b668..a2c4401 100644
--- a/arch/arm/boot/dts/axp22x.dtsi
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -52,6 +52,11 @@
 	interrupt-controller;
 	#interrupt-cells = <1>;
 
+	axp221_adc: axp221_adc {
+		compatible = "x-powers,axp221-adc";
+		#io-channel-cells = <1>;
+	};
+
 	regulators {
 		/* Default work frequency for buck regulators */
 		x-powers,dcdc-freq = <3000>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (5 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 13:14   ` Rob Herring
  2017-01-02 16:37 ` [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs Quentin Schulz
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 .../bindings/power/supply/axp20x_ac_power.txt      | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt

diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
new file mode 100644
index 0000000..16d0de4
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
@@ -0,0 +1,28 @@
+AXP20X and AXP22X PMICs' AC power supply
+
+Required Properties:
+ - compatible: One of:
+			"x-powers,axp202-ac-power-supply"
+			"x-powers,axp221-ac-power-supply"
+
+More Required Properties for AXP20X PMICs:
+ - io-channels: phandles to ACIN voltage and current ADC channels
+ - io-channel-names = "acin_v", "acin_i";
+
+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";
+		io-channels = <&axp209_adc 0>, <&axp209_adc 1>;
+		io-channel-names = "acin_v", "acin_i";
+	};
+};
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (6 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-07 19:31   ` Jonathan Cameron
  2017-01-17  3:00   ` Sebastian Reichel
  2017-01-02 16:37 ` [PATCH 09/22] mfd: axp20x: add AC power supply cells for " Quentin Schulz
                   ` (13 subsequent siblings)
  21 siblings, 2 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 drivers/power/supply/Kconfig           |  12 ++
 drivers/power/supply/Makefile          |   1 +
 drivers/power/supply/axp20x_ac_power.c | 251 +++++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+)
 create mode 100644 drivers/power/supply/axp20x_ac_power.c

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 76806a0..c552b4b 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -214,6 +214,18 @@ config BATTERY_DA9150
 	  This driver can also be built as a module. If so, the module will be
 	  called da9150-fg.
 
+config CHARGER_AXP20X
+	tristate "X-Powers AXP20X and AXP22X AC power supply driver"
+	depends on MFD_AXP20X
+	depends on AXP20X_ADC
+	depends on IIO
+	help
+	  Say Y here to enable support for X-Powers AXP20X and AXP22X PMICs' AC
+	  power supply.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called axp20x_ac_power.
+
 config AXP288_CHARGER
 	tristate "X-Powers AXP288 Charger"
 	depends on MFD_AXP20X && EXTCON_AXP288
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 36c599d..7d22417 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_TEST_POWER)	+= test_power.o
 
 obj-$(CONFIG_BATTERY_88PM860X)	+= 88pm860x_battery.o
 obj-$(CONFIG_BATTERY_ACT8945A)	+= act8945a_charger.o
+obj-$(CONFIG_CHARGER_AXP20X)	+= axp20x_ac_power.o
 obj-$(CONFIG_BATTERY_DS2760)	+= ds2760_battery.o
 obj-$(CONFIG_BATTERY_DS2780)	+= ds2780_battery.o
 obj-$(CONFIG_BATTERY_DS2781)	+= ds2781_battery.o
diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
new file mode 100644
index 0000000..d7bc25c
--- /dev/null
+++ b/drivers/power/supply/axp20x_ac_power.c
@@ -0,0 +1,251 @@
+/*
+ * AXP20X and AXP22X PMICs' ACIN power supply driver
+ *
+ * Copyright (C) 2016 Free Electrons
+ *	Quentin Schulz <quentin.schulz@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#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"
+
+struct axp20x_ac_power {
+	struct device_node *np;
+	struct regmap *regmap;
+	struct power_supply *supply;
+	int axp20x_id;
+	struct iio_channel *acin_v;
+	struct iio_channel *acin_i;
+};
+
+static irqreturn_t axp20x_ac_power_irq(int irq, void *devid)
+{
+	struct axp20x_ac_power *power = devid;
+
+	power_supply_changed(power->supply);
+
+	return IRQ_HANDLED;
+}
+
+static int axp20x_ac_power_get_property(struct power_supply *psy,
+					enum power_supply_property psp,
+					union power_supply_propval *val)
+{
+	struct axp20x_ac_power *power = power_supply_get_drvdata(psy);
+	int ret, reg;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_HEALTH:
+		ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &reg);
+		if (ret)
+			return ret;
+
+		if (reg & AXP20X_PWR_STATUS_ACIN_PRESENT) {
+			val->intval = POWER_SUPPLY_HEALTH_GOOD;
+			return 0;
+		}
+
+		val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+		return 0;
+
+	case POWER_SUPPLY_PROP_PRESENT:
+		ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &reg);
+		if (ret)
+			return ret;
+
+		val->intval = !!(reg & AXP20X_PWR_STATUS_ACIN_PRESENT);
+		return 0;
+
+	case POWER_SUPPLY_PROP_ONLINE:
+		ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &reg);
+		if (ret)
+			return ret;
+
+		val->intval = !!(reg & AXP20X_PWR_STATUS_ACIN_AVAIL);
+		return 0;
+
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = iio_read_channel_processed(power->acin_v, &val->intval);
+		if (ret)
+			return ret;
+
+		/*
+		 * IIO framework gives mV but Power Supply framework gives µV.
+		 */
+		val->intval *= 1000;
+
+		return 0;
+
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		ret = iio_read_channel_processed(power->acin_i, &val->intval);
+		if (ret)
+			return ret;
+
+		/*
+		 * IIO framework gives mV but Power Supply framework gives µV.
+		 */
+		val->intval *= 1000;
+
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static enum power_supply_property axp20x_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,
+};
+
+static enum power_supply_property axp22x_ac_power_properties[] = {
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+static const struct power_supply_desc axp20x_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,
+};
+
+static const struct power_supply_desc axp22x_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,
+};
+
+static int axp20x_ac_power_probe(struct platform_device *pdev)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct power_supply_config psy_cfg = {};
+	struct axp20x_ac_power *power;
+	static const char * const axp20x_irq_names[] = { "ACIN_PLUGIN",
+		"ACIN_REMOVAL", NULL };
+	static const char * const *irq_names;
+	const struct power_supply_desc *ac_power_desc;
+	int i, 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;
+
+	power->axp20x_id = (int)of_device_get_match_data(&pdev->dev);
+
+	irq_names = axp20x_irq_names;
+
+	if (power->axp20x_id == AXP202_ID) {
+		ac_power_desc = &axp20x_ac_power_desc;
+
+		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;
+			return PTR_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;
+			return PTR_ERR(power->acin_i);
+		}
+	} else {
+		ac_power_desc = &axp22x_ac_power_desc;
+	}
+
+	power->np = pdev->dev.of_node;
+	power->regmap = axp20x->regmap;
+
+	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, ac_power_desc,
+						   &psy_cfg);
+	if (IS_ERR(power->supply))
+		return PTR_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);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id axp20x_ac_power_match[] = {
+	{
+		.compatible = "x-powers,axp202-ac-power-supply",
+		.data = (void *)AXP202_ID,
+	}, {
+		.compatible = "x-powers,axp221-ac-power-supply",
+		.data = (void *)AXP221_ID,
+	}, { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, axp20x_ac_power_match);
+
+static struct platform_driver axp20x_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");
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 09/22] mfd: axp20x: add AC power supply cells for AXP22X PMICs
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (7 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 11:57   ` Lee Jones
  2017-01-02 16:37 ` [PATCH 10/22] ARM: dtsi: axp209: add AC power supply subnode Quentin Schulz
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 drivers/mfd/axp20x.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 31a84d81..65c57d0 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -608,6 +608,11 @@ static struct mfd_cell axp221_cells[] = {
 		.name		= "axp20x-adc",
 		.of_compatible	= "x-powers,axp221-adc"
 	}, {
+		.name		= "axp20x-ac-power-supply",
+		.of_compatible	= "x-powers,axp221-ac-power-supply",
+		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
+		.resources	= axp20x_ac_power_supply_resources,
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp221-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
@@ -626,6 +631,11 @@ static struct mfd_cell axp223_cells[] = {
 	}, {
 		.name			= "axp20x-regulator",
 	}, {
+		.name		= "axp20x-ac-power-supply",
+		.of_compatible	= "x-powers,axp221-ac-power-supply",
+		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
+		.resources	= axp20x_ac_power_supply_resources,
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp223-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 10/22] ARM: dtsi: axp209: add AC power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (8 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 09/22] mfd: axp20x: add AC power supply cells for " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 11/22] ARM: dtsi: axp22x: " Quentin Schulz
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/axp209.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index 2a4e8ee..1bfdc85 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -53,6 +53,13 @@
 	interrupt-controller;
 	#interrupt-cells = <1>;
 
+	ac_power_supply: ac_power_supply {
+		compatible = "x-powers,axp202-ac-power-supply";
+		io-channels = <&axp209_adc 0>, <&axp209_adc 1>;
+		io-channel-names = "acin_v", "acin_i";
+		status = "disabled";
+	};
+
 	axp209_adc: axp209_adc {
 		compatible = "x-powers,axp209-adc";
 		#io-channel-cells = <1>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 11/22] ARM: dtsi: axp22x: add AC power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (9 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 10/22] ARM: dtsi: axp209: add AC power supply subnode Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 12/22] ARM: dts: sun8i: sina33: enable ACIN " Quentin Schulz
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/axp22x.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
index a2c4401..aba7fde 100644
--- a/arch/arm/boot/dts/axp22x.dtsi
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -52,6 +52,11 @@
 	interrupt-controller;
 	#interrupt-cells = <1>;
 
+	ac_power_supply: ac_power_supply {
+		compatible = "x-powers,axp221-ac-power-supply";
+		status = "disabled";
+	};
+
 	axp221_adc: axp221_adc {
 		compatible = "x-powers,axp221-adc";
 		#io-channel-cells = <1>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 12/22] ARM: dts: sun8i: sina33: enable ACIN power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (10 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 11/22] ARM: dtsi: axp22x: " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 13/22] ARM: sun5i: chip: " Quentin Schulz
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index 28c58c5..bf53408 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -147,6 +147,10 @@
 
 #include "axp223.dtsi"
 
+&ac_power_supply {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-always-on;
 	regulator-min-microvolt = <3000000>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 13/22] ARM: sun5i: chip: enable ACIN power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (11 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 12/22] ARM: dts: sun8i: sina33: enable ACIN " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding Quentin Schulz
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/sun5i-r8-chip.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
index c6da5ad..6011757 100644
--- a/arch/arm/boot/dts/sun5i-r8-chip.dts
+++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
@@ -128,6 +128,10 @@
 
 #include "axp209.dtsi"
 
+&ac_power_supply {
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c1_pins_a>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (12 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 13/22] ARM: sun5i: chip: " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 13:21   ` Rob Herring
  2017-01-02 16:37 ` [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X Quentin Schulz
                   ` (7 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 .../bindings/power/supply/axp20x_battery.txt       | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt

diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
new file mode 100644
index 0000000..5489d0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
@@ -0,0 +1,27 @@
+AXP20x and AXP22x battery power supply
+
+Required Properties:
+ - compatible, one of:
+			"x-powers,axp209-battery-power-supply"
+			"x-powers,axp221-battery-power-supply"
+ - io-channels: phandles to battery voltage, charge and discharge
+ currents ADC channels
+ - io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
+
+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";
+		io-channels = <&axp209_adc 7>, <&axp209_adc 8>,
+			<&axp209_adc 9>;
+		io-channel-names = "batt_v", "batt_chrg_i",
+			"batt_dischrg_i";
+	}
+};
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (13 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 11:57   ` Lee Jones
  2017-01-05  6:10   ` Chen-Yu Tsai
  2017-01-02 16:37 ` [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X Quentin Schulz
                   ` (6 subsequent siblings)
  21 siblings, 2 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

The CHR_CTRL1 register is made of 7 read-write bits with one being used
to set the target voltage for battery charging.

This adds the CHRG_CTRL1 register to the list of writeable registers for
AXP20X and AXP22X PMICs.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
 drivers/mfd/axp20x.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 65c57d0..19bdba3 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -66,6 +66,7 @@ static const struct regmap_access_table axp152_volatile_table = {
 static const struct regmap_range axp20x_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_CHRG_CTRL1, AXP20X_CHRG_CTRL1),
 	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
 	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
 };
@@ -94,6 +95,7 @@ static const struct regmap_access_table axp20x_volatile_table = {
 static const struct regmap_range axp22x_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_CHRG_CTRL1, AXP20X_CHRG_CTRL1),
 	regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
 };
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (14 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 11:57   ` Lee Jones
  2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 drivers/mfd/axp20x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 19bdba3..7f0f05f 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -65,7 +65,7 @@ static const struct regmap_access_table axp152_volatile_table = {
 
 static const struct regmap_range axp20x_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, AXP20X_CHRG_CTRL1),
 	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
 	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
@@ -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 */
 static const struct regmap_range axp22x_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, AXP20X_CHRG_CTRL1),
 	regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
 };
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (15 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-05 17:02   ` Maxime Ripard
                     ` (3 more replies)
  2017-01-02 16:37 ` [PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver Quentin Schulz
                   ` (4 subsequent siblings)
  21 siblings, 4 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 drivers/power/supply/Kconfig          |  12 +
 drivers/power/supply/Makefile         |   1 +
 drivers/power/supply/axp20x_battery.c | 458 ++++++++++++++++++++++++++++++++++
 3 files changed, 471 insertions(+)
 create mode 100644 drivers/power/supply/axp20x_battery.c

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index c552b4b..48619de 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -226,6 +226,18 @@ config CHARGER_AXP20X
 	  This driver can also be built as a module. If so, the module will be
 	  called axp20x_ac_power.
 
+config BATTERY_AXP20X
+	tristate "X-Powers AXP20X battery driver"
+	depends on MFD_AXP20X
+	depends on AXP20X_ADC
+	depends on IIO
+	help
+	  Say Y here to enable support for X-Powers AXP20X PMICs' battery power
+	  supply.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called axp20x_battery.
+
 config AXP288_CHARGER
 	tristate "X-Powers AXP288 Charger"
 	depends on MFD_AXP20X && EXTCON_AXP288
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 7d22417..5a217b2 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_TEST_POWER)	+= test_power.o
 
 obj-$(CONFIG_BATTERY_88PM860X)	+= 88pm860x_battery.o
 obj-$(CONFIG_BATTERY_ACT8945A)	+= act8945a_charger.o
+obj-$(CONFIG_BATTERY_AXP20X)	+= axp20x_battery.o
 obj-$(CONFIG_CHARGER_AXP20X)	+= axp20x_ac_power.o
 obj-$(CONFIG_BATTERY_DS2760)	+= ds2760_battery.o
 obj-$(CONFIG_BATTERY_DS2780)	+= ds2780_battery.o
diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
new file mode 100644
index 0000000..e1d7b5f
--- /dev/null
+++ b/drivers/power/supply/axp20x_battery.c
@@ -0,0 +1,458 @@
+/*
+ * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs
+ *
+ * Copyright 2016 Free Electrons NextThing Co.
+ *	Quentin Schulz <quentin.schulz@free-electrons.com>
+ *
+ * This driver is based on a previous upstreaming attempt by:
+ *	Bruno Prémont <bonbons@linux-vserver.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.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/time.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/consumer.h>
+#include <linux/mfd/axp20x.h>
+
+#define AXP20X_PWR_STATUS_BAT_CHARGING	BIT(2)
+
+#define AXP20X_PWR_OP_BATT_PRESENT	BIT(5)
+#define AXP20X_PWR_OP_BATT_ACTIVATED	BIT(3)
+
+#define AXP209_FG_PERCENT		GENMASK(6, 0)
+#define AXP22X_FG_VALID			BIT(7)
+
+#define AXP20X_CHRG_CTRL1_TGT_VOLT	GENMASK(6, 5)
+#define AXP20X_CHRG_CTRL1_TGT_4_1V	(0 << 5)
+#define AXP20X_CHRG_CTRL1_TGT_4_15V	BIT(5)
+#define AXP20X_CHRG_CTRL1_TGT_4_2V	(2 << 5)
+#define AXP20X_CHRG_CTRL1_TGT_4_36V	(3 << 5)
+#define AXP20X_CHRG_CTRL1_TGT_CURR	GENMASK(3, 0)
+
+#define AXP22X_CHRG_CTRL1_TGT_4_22V	BIT(5)
+#define AXP22X_CHRG_CTRL1_TGT_4_24V	(3 << 5)
+
+#define AXP20X_V_OFF_MASK		GENMASK(2, 0)
+
+struct axp20x_batt_ps {
+	struct regmap *regmap;
+	struct power_supply *batt;
+	struct axp20x_dev *axp20x;
+	struct iio_channel *batt_chrg_i;
+	struct iio_channel *batt_dischrg_i;
+	struct iio_channel *batt_v;
+	u8 axp_id;
+};
+
+static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
+					  int *val)
+{
+	int ret, reg;
+
+	ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
+	if (ret)
+		return ret;
+
+	switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
+	case AXP20X_CHRG_CTRL1_TGT_4_1V:
+		*val = 4100000;
+		break;
+	case AXP20X_CHRG_CTRL1_TGT_4_15V:
+		*val = 4150000;
+		break;
+	case AXP20X_CHRG_CTRL1_TGT_4_2V:
+		*val = 4200000;
+		break;
+	case AXP20X_CHRG_CTRL1_TGT_4_36V:
+		*val = 4360000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
+					  int *val)
+{
+	int ret, reg;
+
+	ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
+	if (ret)
+		return ret;
+
+	switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
+	case AXP20X_CHRG_CTRL1_TGT_4_1V:
+		*val = 4100000;
+		break;
+	case AXP20X_CHRG_CTRL1_TGT_4_2V:
+		*val = 4200000;
+		break;
+	case AXP22X_CHRG_CTRL1_TGT_4_22V:
+		*val = 4220000;
+		break;
+	case AXP22X_CHRG_CTRL1_TGT_4_24V:
+		*val = 4240000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int axp20x_battery_get_prop(struct power_supply *psy,
+				   enum power_supply_property psp,
+				   union power_supply_propval *val)
+{
+	struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
+	struct iio_channel *chan;
+	int ret = 0, reg, val1;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+	case POWER_SUPPLY_PROP_ONLINE:
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
+				  &reg);
+		if (ret)
+			return ret;
+
+		val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT);
+		break;
+
+	case POWER_SUPPLY_PROP_STATUS:
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
+				  &reg);
+		if (ret)
+			return ret;
+
+		if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+			return 0;
+		}
+
+		ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i,
+						 &val1);
+		if (ret)
+			return ret;
+
+		if (val1) {
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+			return 0;
+		}
+
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1);
+		if (ret)
+			return ret;
+
+		/*
+		 * Fuel Gauge data takes 7 bits but the stored value seems to be
+		 * directly the raw percentage without any scaling to 7 bits.
+		 */
+		if ((val1 & AXP209_FG_PERCENT) == 100)
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		else
+			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		break;
+
+	case POWER_SUPPLY_PROP_HEALTH:
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
+				  &val1);
+		if (ret)
+			return ret;
+
+		if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) {
+			val->intval = POWER_SUPPLY_HEALTH_DEAD;
+			return 0;
+		}
+
+		val->intval = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
+		if (ret)
+			return ret;
+
+		reg &= AXP20X_CHRG_CTRL1_TGT_CURR;
+		val->intval = reg * 100000 + 300000;
+		break;
+
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
+				  &reg);
+		if (ret)
+			return ret;
+
+		if (reg & AXP20X_PWR_STATUS_BAT_CHARGING)
+			chan = axp20x_batt->batt_chrg_i;
+		else
+			chan = axp20x_batt->batt_dischrg_i;
+
+		ret = iio_read_channel_processed(chan, &val->intval);
+		if (ret)
+			return ret;
+
+		/*
+		 * IIO framework gives mV but Power Supply framework gives µV.
+		 */
+		val->intval *= 1000;
+		break;
+
+	case POWER_SUPPLY_PROP_CAPACITY:
+		/* When no battery is present, return capacity is 100% */
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
+				  &reg);
+		if (ret)
+			return ret;
+
+		if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
+			val->intval = 100;
+			return 0;
+		}
+
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &reg);
+		if (ret)
+			return ret;
+
+		if (axp20x_batt->axp_id == AXP221_ID &&
+		    !(reg & AXP22X_FG_VALID))
+			return -EINVAL;
+
+		/*
+		 * Fuel Gauge data takes 7 bits but the stored value seems to be
+		 * directly the raw percentage without any scaling to 7 bits.
+		 */
+		val->intval = reg & AXP209_FG_PERCENT;
+		break;
+
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		if (axp20x_batt->axp_id == AXP209_ID)
+			return axp20x_battery_get_max_voltage(axp20x_batt,
+							      &val->intval);
+		return axp22x_battery_get_max_voltage(axp20x_batt,
+						      &val->intval);
+
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg);
+		if (ret)
+			return ret;
+
+		val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
+		break;
+
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = iio_read_channel_processed(axp20x_batt->batt_v,
+						 &val->intval);
+		if (ret)
+			return ret;
+
+		/*
+		 * IIO framework gives mV but Power Supply framework gives µV.
+		 */
+		val->intval *= 1000;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
+					  int val)
+{
+	switch (val) {
+	case 4100000:
+		return regmap_update_bits(axp20x_batt->regmap,
+					  AXP20X_CHRG_CTRL1,
+					  AXP20X_CHRG_CTRL1_TGT_VOLT,
+					  AXP20X_CHRG_CTRL1_TGT_4_1V);
+	case 4150000:
+		if (axp20x_batt->axp_id == AXP221_ID)
+			return -EINVAL;
+
+		return regmap_update_bits(axp20x_batt->regmap,
+					  AXP20X_CHRG_CTRL1,
+					  AXP20X_CHRG_CTRL1_TGT_VOLT,
+					  AXP20X_CHRG_CTRL1_TGT_4_15V);
+	case 4200000:
+		return regmap_update_bits(axp20x_batt->regmap,
+					  AXP20X_CHRG_CTRL1,
+					  AXP20X_CHRG_CTRL1_TGT_VOLT,
+					  AXP20X_CHRG_CTRL1_TGT_4_2V);
+	default:
+		/*
+		 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
+		 * can be set to 4.22V and 4.24V, but these voltages are too
+		 * high for Lithium based batteries (AXP PMICs are supposed to
+		 * be used with these kinds of battery).
+		 */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int axp20x_battery_set_prop(struct power_supply *psy,
+				   enum power_supply_property psp,
+				   const union power_supply_propval *val)
+{
+	struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
+	int ret = 0, val1;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val1 = (val->intval - 2600000) / 100000;
+		if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
+			return -EINVAL;
+
+		return regmap_update_bits(axp20x_batt->regmap, AXP20X_V_OFF,
+					  AXP20X_V_OFF_MASK, val1);
+
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		return axp20x_battery_set_max_voltage(axp20x_batt, val->intval);
+
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		if (axp20x_batt->axp_id == AXP209_ID)
+			val1 = (val->intval - 300000) / 100000;
+		else
+			val1 = (val->intval - 300000) / 150000;
+
+		if (val1 > AXP20X_CHRG_CTRL1_TGT_CURR || val1 < 0)
+			return -EINVAL;
+
+		return regmap_update_bits(axp20x_batt->regmap,
+					  AXP20X_CHRG_CTRL1,
+					  AXP20X_CHRG_CTRL1_TGT_CURR, val1);
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum power_supply_property axp20x_battery_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_CAPACITY,
+};
+
+static int axp20x_battery_prop_writeable(struct power_supply *psy,
+					 enum power_supply_property psp)
+{
+	return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN ||
+	       psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ||
+	       psp == POWER_SUPPLY_PROP_CURRENT_MAX;
+}
+
+static const struct power_supply_desc axp20x_batt_ps_desc = {
+	.name = "axp20x-battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.properties = axp20x_battery_props,
+	.num_properties = ARRAY_SIZE(axp20x_battery_props),
+	.property_is_writeable = axp20x_battery_prop_writeable,
+	.get_property = axp20x_battery_get_prop,
+	.set_property = axp20x_battery_set_prop,
+};
+
+static const struct of_device_id axp20x_battery_ps_id[] = {
+	{
+		.compatible = "x-powers,axp209-battery-power-supply",
+		.data = (void *)AXP209_ID,
+	}, {
+		.compatible = "x-powers,axp221-battery-power-supply",
+		.data = (void *)AXP221_ID,
+	}, { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
+
+static int axp20x_power_probe(struct platform_device *pdev)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct axp20x_batt_ps *axp20x_batt;
+	struct power_supply_config psy_cfg = {};
+
+	axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
+				   GFP_KERNEL);
+	if (!axp20x_batt)
+		return -ENOMEM;
+
+	axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
+	if (IS_ERR(axp20x_batt->batt_v)) {
+		if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV)
+			return -EPROBE_DEFER;
+		return PTR_ERR(axp20x_batt->batt_v);
+	}
+
+	axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
+							"batt_chrg_i");
+	if (IS_ERR(axp20x_batt->batt_chrg_i)) {
+		if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV)
+			return -EPROBE_DEFER;
+		return PTR_ERR(axp20x_batt->batt_chrg_i);
+	}
+
+	axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
+							   "batt_dischrg_i");
+	if (IS_ERR(axp20x_batt->batt_dischrg_i)) {
+		if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV)
+			return -EPROBE_DEFER;
+		return PTR_ERR(axp20x_batt->batt_dischrg_i);
+	}
+
+	axp20x_batt->regmap = axp20x->regmap;
+	platform_set_drvdata(pdev, axp20x_batt);
+
+	psy_cfg.drv_data = axp20x_batt;
+	psy_cfg.of_node = pdev->dev.of_node;
+
+	axp20x_batt->axp_id = (int)of_device_get_match_data(&pdev->dev);
+
+	axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
+						       &axp20x_batt_ps_desc,
+						       &psy_cfg);
+	return PTR_ERR_OR_ZERO(axp20x_batt->batt);
+}
+
+static struct platform_driver axp20x_batt_driver = {
+	.probe    = axp20x_power_probe,
+	.driver   = {
+		.name  = "axp20x-battery-power-supply",
+		.of_match_table = axp20x_battery_ps_id,
+	},
+};
+
+module_platform_driver(axp20x_batt_driver);
+
+MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
+MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
+MODULE_LICENSE("GPL");
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (16 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-04 11:57   ` Lee Jones
  2017-01-02 16:37 ` [PATCH 19/22] ARM: dtsi: axp209: add battery power supply subnode Quentin Schulz
                   ` (3 subsequent siblings)
  21 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 drivers/mfd/axp20x.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 7f0f05f..8730fc2 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -587,6 +587,9 @@ static struct mfd_cell axp20x_cells[] = {
 		.name		= "axp20x-adc",
 		.of_compatible	= "x-powers,axp209-adc",
 	}, {
+		.name		= "axp20x-battery-power-supply",
+		.of_compatible	= "x-powers,axp209-battery-power-supply",
+	}, {
 		.name		= "axp20x-ac-power-supply",
 		.of_compatible	= "x-powers,axp202-ac-power-supply",
 		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
@@ -615,6 +618,9 @@ static struct mfd_cell axp221_cells[] = {
 		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
 		.resources	= axp20x_ac_power_supply_resources,
 	}, {
+		.name		= "axp20x-battery-power-supply",
+		.of_compatible	= "x-powers,axp221-battery-power-supply",
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp221-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
@@ -631,6 +637,9 @@ static struct mfd_cell axp223_cells[] = {
 		.name		= "axp20x-adc",
 		.of_compatible	= "x-powers,axp221-adc"
 	}, {
+		.name		= "axp20x-battery-power-supply",
+		.of_compatible	= "x-powers,axp221-battery-power-supply",
+	}, {
 		.name			= "axp20x-regulator",
 	}, {
 		.name		= "axp20x-ac-power-supply",
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 19/22] ARM: dtsi: axp209: add battery power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (17 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 20/22] ARM: dtsi: axp22x: " Quentin Schulz
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/axp209.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index 1bfdc85..9ed2dd2 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -71,6 +71,13 @@
 		#gpio-cells = <2>;
 	};
 
+	battery_power_supply: battery_power_supply {
+		compatible = "x-powers,axp209-battery-power-supply";
+		io-channels = <&axp209_adc 7>, <&axp209_adc 8>, <&axp209_adc 9>;
+		io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
+		status = "disabled";
+	};
+
 	regulators {
 		/* Default work frequency for buck regulators */
 		x-powers,dcdc-freq = <1500>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 20/22] ARM: dtsi: axp22x: add battery power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (18 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 19/22] ARM: dtsi: axp209: add battery power supply subnode Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 21/22] ARM: dts: sun8i: sina33: enable " Quentin Schulz
  2017-01-02 16:37 ` [PATCH 22/22] ARM: sun5i: chip: " Quentin Schulz
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/axp22x.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
index aba7fde..c4a64a5 100644
--- a/arch/arm/boot/dts/axp22x.dtsi
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -62,6 +62,13 @@
 		#io-channel-cells = <1>;
 	};
 
+	battery_power_supply: battery_power_supply {
+		compatible = "x-powers,axp221-battery-power-supply";
+		io-channels = <&axp221_adc 1>, <&axp221_adc 2>, <&axp221_adc 3>;
+		io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
+		status = "disabled";
+	};
+
 	regulators {
 		/* Default work frequency for buck regulators */
 		x-powers,dcdc-freq = <3000>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 21/22] ARM: dts: sun8i: sina33: enable battery power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (19 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 20/22] ARM: dtsi: axp22x: " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  2017-01-02 16:37 ` [PATCH 22/22] ARM: sun5i: chip: " Quentin Schulz
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

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 <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index bf53408..2fe9299 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -151,6 +151,10 @@
 	status = "okay";
 };
 
+&battery_power_supply {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-always-on;
 	regulator-min-microvolt = <3000000>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* [PATCH 22/22] ARM: sun5i: chip: enable battery power supply subnode
  2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
                   ` (20 preceding siblings ...)
  2017-01-02 16:37 ` [PATCH 21/22] ARM: dts: sun8i: sina33: enable " Quentin Schulz
@ 2017-01-02 16:37 ` Quentin Schulz
  21 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-02 16:37 UTC (permalink / raw)
  To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, lee.jones
  Cc: Quentin Schulz, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

The NextThing Co. CHIP has an AXP209 PMIC with battery connector.

This enables the battery power supply subnode.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
 arch/arm/boot/dts/sun5i-r8-chip.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
index 6011757..d4332b1 100644
--- a/arch/arm/boot/dts/sun5i-r8-chip.dts
+++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
@@ -132,6 +132,10 @@
 	status = "okay";
 };
 
+&battery_power_supply {
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c1_pins_a>;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
  2017-01-02 16:37 ` [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding Quentin Schulz
@ 2017-01-03 23:20   ` Rob Herring
  2017-01-05  4:05     ` Chen-Yu Tsai
  2017-01-05 16:40   ` Maxime Ripard
  1 sibling, 1 reply; 72+ messages in thread
From: Rob Herring @ 2017-01-03 23:20 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, mark.rutland, wens, sre, linux,
	maxime.ripard, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, Jan 02, 2017 at 05:37:01PM +0100, 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 the device tree binding documentation for the X-Powers AXP20X
> and AXP22X PMICs ADCs.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  .../devicetree/bindings/iio/adc/axp20x_adc.txt     | 24 ++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt b/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
> new file mode 100644
> index 0000000..1b60065
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
> @@ -0,0 +1,24 @@
> +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"
> + - #io-channel-cells = <1>;
> +
> +This is a subnode of the AXP20X PMIC.
> +
> +Example:
> +
> +&axp209 {
> +	axp209_adc: axp209_adc {

Use 'adc' for node name:

With that,

Acked-by: Rob Herring <robh@kernel.org>

> +		compatible = "x-powers,axp209-adc";
> +		#io-channel-cells = <1>;
> +	};
> +};
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X
  2017-01-02 16:37 ` [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X Quentin Schulz
@ 2017-01-04 11:55   ` Lee Jones
  2017-01-05  4:12   ` Chen-Yu Tsai
  1 sibling, 0 replies; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:55 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, 02 Jan 2017, Quentin Schulz wrote:

> The AXP22X PMICs have multiple ADCs, each one exposing data from the
> different power supplies connected to the PMIC.
> 
> This adds the different ADC data registers to the volatile registers of
> the AXP22X PMIC.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
  
> ---
>  drivers/mfd/axp20x.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 619a83e..a33db5e 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -100,6 +100,7 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
>  static const struct regmap_range axp22x_volatile_ranges[] = {
>  	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
>  	regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT, AXP20X_VBUS_IPSOUT_MGMT),
> +	regmap_reg_range(AXP22X_TEMP_ADC_H, AXP20X_BATT_DISCHRG_I_L),
>  	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
>  	regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
>  	regmap_reg_range(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L),

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs Quentin Schulz
@ 2017-01-04 11:56   ` Lee Jones
  2017-01-04 11:56     ` Lee Jones
  0 siblings, 1 reply; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:56 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, 02 Jan 2017, Quentin Schulz wrote:

> This adds the AXP20X/AXP22x ADCs driver to the mfd cells of the AXP209,
> AXP221 and AXP223 MFD.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 9 +++++++++
>  1 file changed, 9 insertions(+)

Applied, thanks.

> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index a33db5e..31a84d81 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -582,6 +582,9 @@ static struct mfd_cell axp20x_cells[] = {
>  	}, {
>  		.name		= "axp20x-regulator",
>  	}, {
> +		.name		= "axp20x-adc",
> +		.of_compatible	= "x-powers,axp209-adc",
> +	}, {
>  		.name		= "axp20x-ac-power-supply",
>  		.of_compatible	= "x-powers,axp202-ac-power-supply",
>  		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
> @@ -602,6 +605,9 @@ static struct mfd_cell axp221_cells[] = {
>  	}, {
>  		.name		= "axp20x-regulator",
>  	}, {
> +		.name		= "axp20x-adc",
> +		.of_compatible	= "x-powers,axp221-adc"
> +	}, {
>  		.name		= "axp20x-usb-power-supply",
>  		.of_compatible	= "x-powers,axp221-usb-power-supply",
>  		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
> @@ -615,6 +621,9 @@ static struct mfd_cell axp223_cells[] = {
>  		.num_resources		= ARRAY_SIZE(axp22x_pek_resources),
>  		.resources		= axp22x_pek_resources,
>  	}, {
> +		.name		= "axp20x-adc",
> +		.of_compatible	= "x-powers,axp221-adc"
> +	}, {
>  		.name			= "axp20x-regulator",
>  	}, {
>  		.name		= "axp20x-usb-power-supply",

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs
  2017-01-04 11:56   ` Lee Jones
@ 2017-01-04 11:56     ` Lee Jones
  2017-01-05  5:51       ` Chen-Yu Tsai
  0 siblings, 1 reply; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:56 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Wed, 04 Jan 2017, Lee Jones wrote:

> On Mon, 02 Jan 2017, Quentin Schulz wrote:
> 
> > This adds the AXP20X/AXP22x ADCs driver to the mfd cells of the AXP209,
> > AXP221 and AXP223 MFD.
> > 
> > Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> > ---
> >  drivers/mfd/axp20x.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> 
> Applied, thanks.

Whoops, wrong key combo!  Should have been:

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

> > diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> > index a33db5e..31a84d81 100644
> > --- a/drivers/mfd/axp20x.c
> > +++ b/drivers/mfd/axp20x.c
> > @@ -582,6 +582,9 @@ static struct mfd_cell axp20x_cells[] = {
> >  	}, {
> >  		.name		= "axp20x-regulator",
> >  	}, {
> > +		.name		= "axp20x-adc",
> > +		.of_compatible	= "x-powers,axp209-adc",
> > +	}, {
> >  		.name		= "axp20x-ac-power-supply",
> >  		.of_compatible	= "x-powers,axp202-ac-power-supply",
> >  		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
> > @@ -602,6 +605,9 @@ static struct mfd_cell axp221_cells[] = {
> >  	}, {
> >  		.name		= "axp20x-regulator",
> >  	}, {
> > +		.name		= "axp20x-adc",
> > +		.of_compatible	= "x-powers,axp221-adc"
> > +	}, {
> >  		.name		= "axp20x-usb-power-supply",
> >  		.of_compatible	= "x-powers,axp221-usb-power-supply",
> >  		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
> > @@ -615,6 +621,9 @@ static struct mfd_cell axp223_cells[] = {
> >  		.num_resources		= ARRAY_SIZE(axp22x_pek_resources),
> >  		.resources		= axp22x_pek_resources,
> >  	}, {
> > +		.name		= "axp20x-adc",
> > +		.of_compatible	= "x-powers,axp221-adc"
> > +	}, {
> >  		.name			= "axp20x-regulator",
> >  	}, {
> >  		.name		= "axp20x-usb-power-supply",
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 09/22] mfd: axp20x: add AC power supply cells for AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 09/22] mfd: axp20x: add AC power supply cells for " Quentin Schulz
@ 2017-01-04 11:57   ` Lee Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:57 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, 02 Jan 2017, 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 <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
  
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 31a84d81..65c57d0 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -608,6 +608,11 @@ static struct mfd_cell axp221_cells[] = {
>  		.name		= "axp20x-adc",
>  		.of_compatible	= "x-powers,axp221-adc"
>  	}, {
> +		.name		= "axp20x-ac-power-supply",
> +		.of_compatible	= "x-powers,axp221-ac-power-supply",
> +		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
> +		.resources	= axp20x_ac_power_supply_resources,
> +	}, {
>  		.name		= "axp20x-usb-power-supply",
>  		.of_compatible	= "x-powers,axp221-usb-power-supply",
>  		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
> @@ -626,6 +631,11 @@ static struct mfd_cell axp223_cells[] = {
>  	}, {
>  		.name			= "axp20x-regulator",
>  	}, {
> +		.name		= "axp20x-ac-power-supply",
> +		.of_compatible	= "x-powers,axp221-ac-power-supply",
> +		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
> +		.resources	= axp20x_ac_power_supply_resources,
> +	}, {
>  		.name		= "axp20x-usb-power-supply",
>  		.of_compatible	= "x-powers,axp223-usb-power-supply",
>  		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X
  2017-01-02 16:37 ` [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X Quentin Schulz
@ 2017-01-04 11:57   ` Lee Jones
  2017-01-05  6:10   ` Chen-Yu Tsai
  1 sibling, 0 replies; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:57 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, 02 Jan 2017, Quentin Schulz wrote:

> The CHR_CTRL1 register is made of 7 read-write bits with one being used
> to set the target voltage for battery charging.
> 
> This adds the CHRG_CTRL1 register to the list of writeable registers for
> AXP20X and AXP22X PMICs.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 2 ++
>  1 file changed, 2 insertions(+)

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
  
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 65c57d0..19bdba3 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -66,6 +66,7 @@ static const struct regmap_access_table axp152_volatile_table = {
>  static const struct regmap_range axp20x_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_CHRG_CTRL1, AXP20X_CHRG_CTRL1),
>  	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
>  	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
>  };
> @@ -94,6 +95,7 @@ static const struct regmap_access_table axp20x_volatile_table = {
>  static const struct regmap_range axp22x_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_CHRG_CTRL1, AXP20X_CHRG_CTRL1),
>  	regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
>  };
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X
  2017-01-02 16:37 ` [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X Quentin Schulz
@ 2017-01-04 11:57   ` Lee Jones
  2017-01-05  6:02     ` Chen-Yu Tsai
  0 siblings, 1 reply; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:57 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, 02 Jan 2017, Quentin Schulz wrote:

> 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 <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
  
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 19bdba3..7f0f05f 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -65,7 +65,7 @@ static const struct regmap_access_table axp152_volatile_table = {
>  
>  static const struct regmap_range axp20x_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, AXP20X_CHRG_CTRL1),
>  	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
>  	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
> @@ -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 */
>  static const struct regmap_range axp22x_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, AXP20X_CHRG_CTRL1),
>  	regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver
  2017-01-02 16:37 ` [PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver Quentin Schulz
@ 2017-01-04 11:57   ` Lee Jones
  0 siblings, 0 replies; 72+ messages in thread
From: Lee Jones @ 2017-01-04 11:57 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, maxime.ripard, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, 02 Jan 2017, Quentin Schulz wrote:

> 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 <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 9 +++++++++
>  1 file changed, 9 insertions(+)

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
  
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 7f0f05f..8730fc2 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -587,6 +587,9 @@ static struct mfd_cell axp20x_cells[] = {
>  		.name		= "axp20x-adc",
>  		.of_compatible	= "x-powers,axp209-adc",
>  	}, {
> +		.name		= "axp20x-battery-power-supply",
> +		.of_compatible	= "x-powers,axp209-battery-power-supply",
> +	}, {
>  		.name		= "axp20x-ac-power-supply",
>  		.of_compatible	= "x-powers,axp202-ac-power-supply",
>  		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
> @@ -615,6 +618,9 @@ static struct mfd_cell axp221_cells[] = {
>  		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
>  		.resources	= axp20x_ac_power_supply_resources,
>  	}, {
> +		.name		= "axp20x-battery-power-supply",
> +		.of_compatible	= "x-powers,axp221-battery-power-supply",
> +	}, {
>  		.name		= "axp20x-usb-power-supply",
>  		.of_compatible	= "x-powers,axp221-usb-power-supply",
>  		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
> @@ -631,6 +637,9 @@ static struct mfd_cell axp223_cells[] = {
>  		.name		= "axp20x-adc",
>  		.of_compatible	= "x-powers,axp221-adc"
>  	}, {
> +		.name		= "axp20x-battery-power-supply",
> +		.of_compatible	= "x-powers,axp221-battery-power-supply",
> +	}, {
>  		.name			= "axp20x-regulator",
>  	}, {
>  		.name		= "axp20x-ac-power-supply",

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply
  2017-01-02 16:37 ` [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply Quentin Schulz
@ 2017-01-04 13:14   ` Rob Herring
  2017-01-05  6:17     ` Chen-Yu Tsai
  0 siblings, 1 reply; 72+ messages in thread
From: Rob Herring @ 2017-01-04 13:14 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, mark.rutland, wens, sre, linux,
	maxime.ripard, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, Jan 02, 2017 at 05:37:07PM +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 <quentin.schulz@free-electrons.com>
> ---
>  .../bindings/power/supply/axp20x_ac_power.txt      | 28 ++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
> new file mode 100644
> index 0000000..16d0de4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
> @@ -0,0 +1,28 @@
> +AXP20X and AXP22X PMICs' AC power supply
> +
> +Required Properties:
> + - compatible: One of:
> +			"x-powers,axp202-ac-power-supply"
> +			"x-powers,axp221-ac-power-supply"
> +
> +More Required Properties for AXP20X PMICs:
> + - io-channels: phandles to ACIN voltage and current ADC channels
> + - io-channel-names = "acin_v", "acin_i";
> +
> +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 {

power-supply {

> +		compatible = "x-powers,axp202-ac-power-supply";
> +		io-channels = <&axp209_adc 0>, <&axp209_adc 1>;

Is this assignment fixed? If so, then it doesn't need to be in DT.

> +		io-channel-names = "acin_v", "acin_i";
> +	};
> +};
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding
  2017-01-02 16:37 ` [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding Quentin Schulz
@ 2017-01-04 13:21   ` Rob Herring
  2017-01-07 19:33     ` Jonathan Cameron
  0 siblings, 1 reply; 72+ messages in thread
From: Rob Herring @ 2017-01-04 13:21 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, mark.rutland, wens, sre, linux,
	maxime.ripard, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On Mon, Jan 02, 2017 at 05:37:14PM +0100, Quentin Schulz wrote:
> 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 <quentin.schulz@free-electrons.com>
> ---
>  .../bindings/power/supply/axp20x_battery.txt       | 27 ++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
> new file mode 100644
> index 0000000..5489d0d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
> @@ -0,0 +1,27 @@
> +AXP20x and AXP22x battery power supply
> +
> +Required Properties:
> + - compatible, one of:
> +			"x-powers,axp209-battery-power-supply"
> +			"x-powers,axp221-battery-power-supply"
> + - io-channels: phandles to battery voltage, charge and discharge
> + currents ADC channels
> + - io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
> +
> +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 {

Humm, I guess you power-supply is not sufficient, so 
'battery-power-supply' and similar for ac.

> +		compatible = "x-powers,axp209-battery-power-supply";
> +		io-channels = <&axp209_adc 7>, <&axp209_adc 8>,
> +			<&axp209_adc 9>;
> +		io-channel-names = "batt_v", "batt_chrg_i",
> +			"batt_dischrg_i";
> +	}
> +};
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
  2017-01-03 23:20   ` Rob Herring
@ 2017-01-05  4:05     ` Chen-Yu Tsai
  0 siblings, 0 replies; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  4:05 UTC (permalink / raw)
  To: Rob Herring
  Cc: Quentin Schulz, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Wed, Jan 4, 2017 at 7:20 AM, Rob Herring <robh@kernel.org> wrote:
> On Mon, Jan 02, 2017 at 05:37:01PM +0100, 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 the device tree binding documentation for the X-Powers AXP20X
>> and AXP22X PMICs ADCs.
>>
>> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
>> ---
>>  .../devicetree/bindings/iio/adc/axp20x_adc.txt     | 24 ++++++++++++++++++++++
>>  1 file changed, 24 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt b/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
>> new file mode 100644
>> index 0000000..1b60065
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
>> @@ -0,0 +1,24 @@
>> +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"
>> + - #io-channel-cells = <1>;
>> +
>> +This is a subnode of the AXP20X PMIC.
>> +
>> +Example:
>> +
>> +&axp209 {
>> +     axp209_adc: axp209_adc {
>
> Use 'adc' for node name:
>
> With that,
>
> Acked-by: Rob Herring <robh@kernel.org>

Same comments as Rob.

Acked-by: Chen-Yu Tsai <wens@csie.org>

>
>> +             compatible = "x-powers,axp209-adc";
>> +             #io-channel-cells = <1>;
>> +     };
>> +};
>> --
>> 2.9.3
>>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X
  2017-01-02 16:37 ` [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X Quentin Schulz
  2017-01-04 11:55   ` Lee Jones
@ 2017-01-05  4:12   ` Chen-Yu Tsai
  1 sibling, 0 replies; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  4:12 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> The AXP22X PMICs have multiple ADCs, each one exposing data from the
> different power supplies connected to the PMIC.
>
> This adds the different ADC data registers to the volatile registers of
> the AXP22X PMIC.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 619a83e..a33db5e 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -100,6 +100,7 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
>  static const struct regmap_range axp22x_volatile_ranges[] = {
>         regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
>         regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT, AXP20X_VBUS_IPSOUT_MGMT),
> +       regmap_reg_range(AXP22X_TEMP_ADC_H, AXP20X_BATT_DISCHRG_I_L),

You added this macro in the next patch. Please move that hunk to this patch.

ChenYu

>         regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
>         regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
>         regmap_reg_range(AXP22X_PMIC_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-02 16:37 ` [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs Quentin Schulz
@ 2017-01-05  5:42   ` Chen-Yu Tsai
  2017-01-05  8:06     ` Quentin Schulz
  2017-01-05 16:51   ` Maxime Ripard
  2017-01-07 19:13   ` Jonathan Cameron
  2 siblings, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  5:42 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> 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 <quentin.schulz@free-electrons.com>
> ---
>  drivers/iio/adc/Kconfig      |  10 +
>  drivers/iio/adc/Makefile     |   1 +
>  drivers/iio/adc/axp20x_adc.c | 490 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/axp20x.h   |   4 +
>  4 files changed, 505 insertions(+)
>  create mode 100644 drivers/iio/adc/axp20x_adc.c
>
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 38bc319..5c5b51f 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -154,6 +154,16 @@ config AT91_SAMA5D2_ADC
>           To compile this driver as a module, choose M here: the module will be
>           called at91-sama5d2_adc.
>
> +config AXP20X_ADC
> +       tristate "X-Powers AXP20X and AXP22X ADC driver"
> +       depends on MFD_AXP20X
> +       help
> +         Say yes here to have support for X-Powers power management IC (PMIC)
> +         AXP20X and AXP22X ADC devices.
> +
> +         To compile this driver as a module, choose M here: the module will be
> +         called axp20x_adc.
> +
>  config AXP288_ADC
>         tristate "X-Powers AXP288 ADC driver"
>         depends on MFD_AXP20X
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index d36c4be..f5c28a5 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
>  obj-$(CONFIG_AD799X) += ad799x.o
>  obj-$(CONFIG_AT91_ADC) += at91_adc.o
>  obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
> +obj-$(CONFIG_AXP20X_ADC) += axp20x_adc.o
>  obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
>  obj-$(CONFIG_BCM_IPROC_ADC) += bcm_iproc_adc.o
>  obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
> diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c
> new file mode 100644
> index 0000000..8df972a
> --- /dev/null
> +++ b/drivers/iio/adc/axp20x_adc.c
> @@ -0,0 +1,490 @@
> +/* ADC driver for AXP20X and AXP22X PMICs
> + *
> + * Copyright (c) 2016 Free Electrons NextThing Co.
> + *     Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + *
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/thermal.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/mfd/axp20x.h>
> +
> +#define AXP20X_ADC_EN1_MASK                    GENMASK(7, 0)
> +
> +#define AXP20X_ADC_EN2_MASK                    (GENMASK(3, 2) | BIT(7))
> +#define AXP22X_ADC_EN1_MASK                    (GENMASK(7, 5) | BIT(0))
> +#define AXP20X_ADC_EN2_TEMP_ADC                        BIT(7)
> +#define AXP20X_ADC_EN2_GPIO0_ADC               BIT(3)
> +#define AXP20X_ADC_EN2_GPIO1_ADC               BIT(2)

The latter 3 individual bits aren't used anywhere.
Please remove them for now.

> +
> +#define AXP20X_GPIO10_IN_RANGE_GPIO0           BIT(0)
> +#define AXP20X_GPIO10_IN_RANGE_GPIO1           BIT(1)
> +#define AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(x)    ((x) & BIT(0))
> +#define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x)    (((x) & BIT(0)) << 1)
> +
> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)

Please be consistent with the format.

> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
> +
> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)

These are power-of-2 multiples of some base rate. May I suggest
a formula macro instead. Either way, you seem to be using only
one value. Will this be made configurable in the future?

> +
> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
> +       {                                                       \
> +               .type = _type,                                  \
> +               .indexed = 1,                                   \
> +               .channel = _channel,                            \
> +               .address = _reg,                                \
> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
> +                                     BIT(IIO_CHAN_INFO_SCALE), \
> +               .datasheet_name = _name,                        \
> +       }
> +
> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
> +       {                                                       \
> +               .type = _type,                                  \
> +               .indexed = 1,                                   \
> +               .channel = _channel,                            \
> +               .address = _reg,                                \
> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
> +               .datasheet_name = _name,                        \
> +       }
> +
> +struct axp20x_adc_iio {
> +       struct iio_dev          *indio_dev;
> +       struct regmap           *regmap;
> +};
> +
> +enum axp20x_adc_channel {
> +       AXP20X_ACIN_V = 0,
> +       AXP20X_ACIN_I,
> +       AXP20X_VBUS_V,
> +       AXP20X_VBUS_I,
> +       AXP20X_TEMP_ADC,

PMIC_TEMP would be better. And please save a slot for TS input.

> +       AXP20X_GPIO0_V,
> +       AXP20X_GPIO1_V,

Please skip a slot for "battery instantaneous power".

> +       AXP20X_BATT_V,
> +       AXP20X_BATT_CHRG_I,
> +       AXP20X_BATT_DISCHRG_I,
> +       AXP20X_IPSOUT_V,
> +};
> +
> +enum axp22x_adc_channel {
> +       AXP22X_TEMP_ADC = 0,

Same comments as AXP20X_TEMP_ADC.

> +       AXP22X_BATT_V,
> +       AXP22X_BATT_CHRG_I,
> +       AXP22X_BATT_DISCHRG_I,
> +};

Shouldn't these channel numbers be exported as part of the device tree
bindings? At the very least, they shouldn't be changed.

Also please add a comment saying that the channels are numbered
in the order of their respective registers, and not the table
describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
and 9.5 E-Gauge for AXP221).

> +
> +static const struct iio_chan_spec axp20x_adc_channels[] = {
> +       AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,
> +                          AXP20X_ACIN_V_ADC_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,
> +                          AXP20X_ACIN_I_ADC_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,
> +                          AXP20X_VBUS_V_ADC_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,
> +                          AXP20X_VBUS_I_ADC_H),
> +       AXP20X_ADC_CHANNEL_OFFSET(AXP20X_TEMP_ADC, "temp_adc", IIO_TEMP,
> +                                 AXP20X_TEMP_ADC_H),
> +       AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
> +                                 AXP20X_GPIO0_V_ADC_H),
> +       AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,
> +                                 AXP20X_GPIO1_V_ADC_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,
> +                          AXP20X_BATT_V_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
> +                          AXP20X_BATT_CHRG_I_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
> +                          AXP20X_BATT_DISCHRG_I_H),
> +       AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
> +                          AXP20X_IPSOUT_V_HIGH_H),
> +};
> +
> +static const struct iio_chan_spec axp22x_adc_channels[] = {
> +       AXP20X_ADC_CHANNEL_OFFSET(AXP22X_TEMP_ADC, "temp_adc", IIO_TEMP,
> +                                 AXP22X_TEMP_ADC_H),
> +       AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,
> +                          AXP20X_BATT_V_H),
> +       AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
> +                          AXP20X_BATT_CHRG_I_H),
> +       AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
> +                          AXP20X_BATT_DISCHRG_I_H),
> +};
> +
> +static int axp20x_adc_read_raw(struct iio_dev *indio_dev,
> +                              struct iio_chan_spec const *channel, int *val,
> +                              int *val2)
> +{
> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +       int size = 12, ret;
> +
> +       switch (channel->channel) {
> +       case AXP20X_BATT_DISCHRG_I:
> +               size = 13;
> +       case AXP20X_ACIN_V:
> +       case AXP20X_ACIN_I:
> +       case AXP20X_VBUS_V:
> +       case AXP20X_VBUS_I:
> +       case AXP20X_TEMP_ADC:
> +       case AXP20X_BATT_V:
> +       case AXP20X_BATT_CHRG_I:
> +       case AXP20X_IPSOUT_V:
> +       case AXP20X_GPIO0_V:
> +       case AXP20X_GPIO1_V:
> +               ret = axp20x_read_variable_width(info->regmap, channel->address,
> +                                                size);
> +               if (ret < 0)
> +                       return ret;
> +               *val = ret;
> +               return IIO_VAL_INT;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
> +                              struct iio_chan_spec const *channel, int *val,
> +                              int *val2)
> +{
> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +       int size = 12, ret;
> +
> +       switch (channel->channel) {
> +       case AXP22X_BATT_DISCHRG_I:
> +               size = 13;
> +       case AXP22X_TEMP_ADC:
> +       case AXP22X_BATT_V:
> +       case AXP22X_BATT_CHRG_I:

According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.

> +               ret = axp20x_read_variable_width(info->regmap, channel->address,
> +                                                size);
> +               if (ret < 0)
> +                       return ret;
> +               *val = ret;
> +               return IIO_VAL_INT;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp20x_adc_scale(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_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_TEMP_ADC:
> +               *val = 100;
> +               return IIO_VAL_INT;
> +
> +       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_BATT_DISCHRG_I:
> +       case AXP20X_BATT_CHRG_I:
> +               *val = 0;
> +               *val2 = 500000;
> +               return IIO_VAL_INT_PLUS_MICRO;
> +
> +       case AXP20X_IPSOUT_V:
> +               *val = 1;
> +               *val2 = 400000;
> +               return IIO_VAL_INT_PLUS_MICRO;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp22x_adc_scale(int channel, int *val, int *val2)
> +{
> +       switch (channel) {
> +       case AXP22X_TEMP_ADC:
> +               *val = 100;
> +               return IIO_VAL_INT;
> +
> +       case AXP22X_BATT_V:
> +               *val = 1;
> +               *val2 = 100000;
> +               return IIO_VAL_INT_PLUS_MICRO;
> +
> +       case AXP22X_BATT_DISCHRG_I:
> +       case AXP22X_BATT_CHRG_I:
> +               *val = 0;
> +               *val2 = 500000;
> +               return IIO_VAL_INT_PLUS_MICRO;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp20x_adc_offset(struct iio_dev *indio_dev, int channel, int *val)
> +{
> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +       int ret, reg;
> +
> +       switch (channel) {
> +       case AXP20X_TEMP_ADC:
> +               *val = -1447;
> +               return IIO_VAL_INT;
> +
> +       case AXP20X_GPIO0_V:
> +       case AXP20X_GPIO1_V:
> +               ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, &reg);
> +               if (ret < 0)
> +                       return ret;
> +
> +               if (channel == AXP20X_GPIO0_V)
> +                       *val = reg & AXP20X_GPIO10_IN_RANGE_GPIO0;
> +               else
> +                       *val = reg & AXP20X_GPIO10_IN_RANGE_GPIO1;
> +
> +               *val = !!(*val) * 700000;
> +
> +               return IIO_VAL_INT;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp20x_read_raw(struct iio_dev *indio_dev,
> +                          struct iio_chan_spec const *chan, int *val,
> +                          int *val2, long mask)
> +{
> +       switch (mask) {
> +       case IIO_CHAN_INFO_OFFSET:
> +               return axp20x_adc_offset(indio_dev, chan->channel, val);
> +
> +       case IIO_CHAN_INFO_SCALE:
> +               return axp20x_adc_scale(chan->channel, val, val2);
> +
> +       case IIO_CHAN_INFO_RAW:
> +               return axp20x_adc_read_raw(indio_dev, chan, val, val2);
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp22x_read_raw(struct iio_dev *indio_dev,
> +                          struct iio_chan_spec const *chan, int *val,
> +                          int *val2, long mask)
> +{
> +       switch (mask) {
> +       case IIO_CHAN_INFO_OFFSET:
> +               *val = -2667;

Datasheet says -267.7 C, or -2677 here.

> +               return IIO_VAL_INT;
> +
> +       case IIO_CHAN_INFO_SCALE:
> +               return axp22x_adc_scale(chan->channel, val, val2);
> +
> +       case IIO_CHAN_INFO_RAW:
> +               return axp22x_adc_read_raw(indio_dev, chan, val, val2);
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int axp20x_write_raw(struct iio_dev *indio_dev,
> +                           struct iio_chan_spec const *chan, int val, int val2,
> +                           long mask)
> +{
> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +
> +       /*
> +        * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets
> +        * for (independently) GPIO0 and GPIO1 when in ADC mode.
> +        */
> +       if (mask != IIO_CHAN_INFO_OFFSET)
> +               return -EINVAL;
> +
> +       if (chan->channel != AXP20X_GPIO0_V && chan->channel != AXP20X_GPIO1_V)
> +               return -EINVAL;
> +
> +       if (val != 0 && val != 700000)
> +               return -EINVAL;
> +
> +       if (chan->channel == AXP20X_GPIO0_V)
> +               return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
> +                                         AXP20X_GPIO10_IN_RANGE_GPIO0,
> +                                         AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val));
> +
> +       return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
> +                                 AXP20X_GPIO10_IN_RANGE_GPIO1,
> +                                 AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val));
> +}
> +
> +static const struct iio_info axp20x_adc_iio_info = {
> +       .read_raw = axp20x_read_raw,
> +       .write_raw = axp20x_write_raw,
> +       .driver_module = THIS_MODULE,
> +};
> +
> +static const struct iio_info axp22x_adc_iio_info = {
> +       .read_raw = axp22x_read_raw,
> +       .driver_module = THIS_MODULE,
> +};
> +
> +static const struct of_device_id axp20x_adc_of_match[] = {
> +       { .compatible = "x-powers,axp209-adc", .data = (void *)AXP209_ID, },
> +       { .compatible = "x-powers,axp221-adc", .data = (void *)AXP221_ID, },
> +       { /* sentinel */ },
> +};
> +
> +static int axp20x_probe(struct platform_device *pdev)
> +{
> +       struct axp20x_adc_iio *info;
> +       struct iio_dev *indio_dev;
> +       struct axp20x_dev *axp20x_dev;
> +       int ret, axp20x_id;
> +
> +       axp20x_dev = dev_get_drvdata(pdev->dev.parent);
> +
> +       indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
> +       if (!indio_dev)
> +               return -ENOMEM;
> +
> +       info = iio_priv(indio_dev);
> +       platform_set_drvdata(pdev, indio_dev);
> +
> +       info->regmap = axp20x_dev->regmap;
> +       info->indio_dev = indio_dev;
> +       indio_dev->name = dev_name(&pdev->dev);
> +       indio_dev->dev.parent = &pdev->dev;
> +       indio_dev->dev.of_node = pdev->dev.of_node;
> +       indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +       axp20x_id = (int)of_device_get_match_data(&pdev->dev);
> +
> +       switch (axp20x_id) {
> +       case AXP209_ID:
> +               indio_dev->info = &axp20x_adc_iio_info;
> +               indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
> +               indio_dev->channels = axp20x_adc_channels;
> +
> +               /* Enable the ADCs on IP */
> +               regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
> +
> +               /* Enable GPIO0/1 and internal temperature ADCs */
> +               regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
> +                                  AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
> +
> +               /* Configure ADCs rate */
> +               regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +                                  AXP20X_ADC_RATE_MASK, AXP20X_ADC_RATE_50HZ);
> +               break;
> +
> +       case AXP221_ID:
> +               indio_dev->info = &axp22x_adc_iio_info;
> +               indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
> +               indio_dev->channels = axp22x_adc_channels;
> +
> +               /* Enable the ADCs on IP */
> +               regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
> +
> +               /* Configure ADCs rate */
> +               regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +                                  AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
> +               break;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       ret = devm_iio_device_register(&pdev->dev, indio_dev);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "could not register the device\n");
> +               regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> +               regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_remove(struct platform_device *pdev)
> +{
> +       struct axp20x_adc_iio *info;
> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +       info = iio_priv(indio_dev);

Nit: you could just reverse the 2 declarations above and join this
line after struct axp20x_adc_iio *info;

> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);

The existing VBUS power supply driver enables the VBUS ADC bits itself,
and does not check them later on. This means if one were to remove this
axp20x-adc module, the voltage/current readings in the VBUS power supply
would be invalid. Some sort of workaround would be needed here in this
driver of the VBUS driver.

> +
> +       return 0;
> +}
> +
> +static struct platform_driver axp20x_adc_driver = {
> +       .driver = {
> +               .name = "axp20x-adc",
> +               .of_match_table = axp20x_adc_of_match,
> +       },
> +       .probe = axp20x_probe,
> +       .remove = axp20x_remove,
> +};
> +
> +module_platform_driver(axp20x_adc_driver);
> +
> +MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index a4860bc..650c6f6 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -150,6 +150,10 @@ enum {
>  #define AXP20X_VBUS_I_ADC_L            0x5d
>  #define AXP20X_TEMP_ADC_H              0x5e
>  #define AXP20X_TEMP_ADC_L              0x5f
> +
> +#define AXP22X_TEMP_ADC_H              0x56
> +#define AXP22X_TEMP_ADC_L              0x57
> +

This is in the wrong patch. Also we already have

/* AXP22X specific registers */
#define AXP22X_PMIC_ADC_H               0x56
#define AXP22X_PMIC_ADC_L               0x57
#define AXP22X_TS_ADC_H                 0x58
#define AXP22X_TS_ADC_L                 0x59

If you want, you could just rename them to be consistent.

Regards
ChenYu

>  #define AXP20X_TS_IN_H                 0x62
>  #define AXP20X_TS_IN_L                 0x63
>  #define AXP20X_GPIO0_V_ADC_H           0x64
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs
  2017-01-04 11:56     ` Lee Jones
@ 2017-01-05  5:51       ` Chen-Yu Tsai
  0 siblings, 0 replies; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  5:51 UTC (permalink / raw)
  To: Lee Jones
  Cc: Quentin Schulz, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, linux-iio,
	devicetree, linux-kernel, open list:THERMAL, linux-arm-kernel,
	Thomas Petazzoni, Icenowy Zheng, Bruno Prémont

On Wed, Jan 4, 2017 at 7:56 PM, Lee Jones <lee.jones@linaro.org> wrote:
> On Wed, 04 Jan 2017, Lee Jones wrote:
>
>> On Mon, 02 Jan 2017, Quentin Schulz wrote:
>>
>> > This adds the AXP20X/AXP22x ADCs driver to the mfd cells of the AXP209,
>> > AXP221 and AXP223 MFD.
>> >
>> > Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
>> > ---
>> >  drivers/mfd/axp20x.c | 9 +++++++++
>> >  1 file changed, 9 insertions(+)
>>
>> Applied, thanks.
>
> Whoops, wrong key combo!  Should have been:
>
> For my own reference:
>   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

Acked-by: Chen-Yu Tsai <wens@csie.org>

>
>> > diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>> > index a33db5e..31a84d81 100644
>> > --- a/drivers/mfd/axp20x.c
>> > +++ b/drivers/mfd/axp20x.c
>> > @@ -582,6 +582,9 @@ static struct mfd_cell axp20x_cells[] = {
>> >     }, {
>> >             .name           = "axp20x-regulator",
>> >     }, {
>> > +           .name           = "axp20x-adc",
>> > +           .of_compatible  = "x-powers,axp209-adc",
>> > +   }, {
>> >             .name           = "axp20x-ac-power-supply",
>> >             .of_compatible  = "x-powers,axp202-ac-power-supply",
>> >             .num_resources  = ARRAY_SIZE(axp20x_ac_power_supply_resources),
>> > @@ -602,6 +605,9 @@ static struct mfd_cell axp221_cells[] = {
>> >     }, {
>> >             .name           = "axp20x-regulator",
>> >     }, {
>> > +           .name           = "axp20x-adc",
>> > +           .of_compatible  = "x-powers,axp221-adc"
>> > +   }, {
>> >             .name           = "axp20x-usb-power-supply",
>> >             .of_compatible  = "x-powers,axp221-usb-power-supply",
>> >             .num_resources  = ARRAY_SIZE(axp22x_usb_power_supply_resources),
>> > @@ -615,6 +621,9 @@ static struct mfd_cell axp223_cells[] = {
>> >             .num_resources          = ARRAY_SIZE(axp22x_pek_resources),
>> >             .resources              = axp22x_pek_resources,
>> >     }, {
>> > +           .name           = "axp20x-adc",
>> > +           .of_compatible  = "x-powers,axp221-adc"
>> > +   }, {
>> >             .name                   = "axp20x-regulator",
>> >     }, {
>> >             .name           = "axp20x-usb-power-supply",
>>
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode
  2017-01-02 16:37 ` [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode Quentin Schulz
@ 2017-01-05  5:51   ` Chen-Yu Tsai
  2017-01-05  8:08     ` Quentin Schulz
  0 siblings, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  5:51 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> 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 <quentin.schulz@free-electrons.com>
> ---
>  arch/arm/boot/dts/axp209.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
> index 675bb0f..2a4e8ee 100644
> --- a/arch/arm/boot/dts/axp209.dtsi
> +++ b/arch/arm/boot/dts/axp209.dtsi
> @@ -53,6 +53,11 @@
>         interrupt-controller;
>         #interrupt-cells = <1>;
>
> +       axp209_adc: axp209_adc {

Node name should be generic. Please change it to "adc".

ChenYu

> +               compatible = "x-powers,axp209-adc";
> +               #io-channel-cells = <1>;
> +       };
> +
>         axp_gpio: gpio {
>                 compatible = "x-powers,axp209-gpio";
>                 gpio-controller;
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X ADC subnode
  2017-01-02 16:37 ` [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X " Quentin Schulz
@ 2017-01-05  5:52   ` Chen-Yu Tsai
  0 siblings, 0 replies; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  5:52 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> 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 <quentin.schulz@free-electrons.com>
> ---
>  arch/arm/boot/dts/axp22x.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
> index 458b668..a2c4401 100644
> --- a/arch/arm/boot/dts/axp22x.dtsi
> +++ b/arch/arm/boot/dts/axp22x.dtsi
> @@ -52,6 +52,11 @@
>         interrupt-controller;
>         #interrupt-cells = <1>;
>
> +       axp221_adc: axp221_adc {

Same as the last patch. Please change to "adc".

ChenYu

> +               compatible = "x-powers,axp221-adc";
> +               #io-channel-cells = <1>;
> +       };
> +
>         regulators {
>                 /* Default work frequency for buck regulators */
>                 x-powers,dcdc-freq = <3000>;
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X
  2017-01-04 11:57   ` Lee Jones
@ 2017-01-05  6:02     ` Chen-Yu Tsai
  0 siblings, 0 replies; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  6:02 UTC (permalink / raw)
  To: Lee Jones
  Cc: Quentin Schulz, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, linux-iio,
	devicetree, linux-kernel, open list:THERMAL, linux-arm-kernel,
	Thomas Petazzoni, Icenowy Zheng, Bruno Prémont

On Wed, Jan 4, 2017 at 7:57 PM, Lee Jones <lee.jones@linaro.org> wrote:
> On Mon, 02 Jan 2017, Quentin Schulz wrote:
>
>> 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 <quentin.schulz@free-electrons.com>
>> ---
>>  drivers/mfd/axp20x.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> For my own reference:
>   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

Acked-by: Chen-Yu Tsai <wens@csie.org>

>
>> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>> index 19bdba3..7f0f05f 100644
>> --- a/drivers/mfd/axp20x.c
>> +++ b/drivers/mfd/axp20x.c
>> @@ -65,7 +65,7 @@ static const struct regmap_access_table axp152_volatile_table = {
>>
>>  static const struct regmap_range axp20x_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, AXP20X_CHRG_CTRL1),
>>       regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
>>       regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
>> @@ -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 */
>>  static const struct regmap_range axp22x_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, AXP20X_CHRG_CTRL1),
>>       regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
>>  };
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X
  2017-01-02 16:37 ` [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X Quentin Schulz
  2017-01-04 11:57   ` Lee Jones
@ 2017-01-05  6:10   ` Chen-Yu Tsai
  2017-01-05  8:10     ` Quentin Schulz
  1 sibling, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  6:10 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> The CHR_CTRL1 register is made of 7 read-write bits with one being used
> to set the target voltage for battery charging.

The description is incorrect.

All 8 bits are read-write:

  - The highest bit enables the charger module
  - Bits [6:5] set the target voltage
  - Bits [4:3] set when the charge cycle ends, based on percentage
    of charge current
  - Bits [2:0] set the charge current

Feel free to use the above in the commit message.

>
> This adds the CHRG_CTRL1 register to the list of writeable registers for
> AXP20X and AXP22X PMICs.

You might want to add up to CHRG_CTRL3 for the AXP22x and CHRG_CTRL2
for the AXP20x. These control additional aspects of the charger.

AXP20X_CHRG_BAK_CTRL controls the charger for the RTC battery. You
could add this now, or let the person doing the RTC battery driver
add it.

Regards
ChenYu

>
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> ---
>  drivers/mfd/axp20x.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 65c57d0..19bdba3 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -66,6 +66,7 @@ static const struct regmap_access_table axp152_volatile_table = {
>  static const struct regmap_range axp20x_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_CHRG_CTRL1, AXP20X_CHRG_CTRL1),
>         regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
>         regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
>  };
> @@ -94,6 +95,7 @@ static const struct regmap_access_table axp20x_volatile_table = {
>  static const struct regmap_range axp22x_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_CHRG_CTRL1, AXP20X_CHRG_CTRL1),
>         regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
>  };
>
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply
  2017-01-04 13:14   ` Rob Herring
@ 2017-01-05  6:17     ` Chen-Yu Tsai
  2017-01-07 19:26       ` Jonathan Cameron
  0 siblings, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  6:17 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Rob Herring, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

Hi Quentin,

On Wed, Jan 4, 2017 at 9:14 PM, Rob Herring <robh@kernel.org> wrote:
> On Mon, Jan 02, 2017 at 05:37:07PM +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 <quentin.schulz@free-electrons.com>
>> ---
>>  .../bindings/power/supply/axp20x_ac_power.txt      | 28 ++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
>>
>> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
>> new file mode 100644
>> index 0000000..16d0de4
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
>> @@ -0,0 +1,28 @@
>> +AXP20X and AXP22X PMICs' AC power supply
>> +
>> +Required Properties:
>> + - compatible: One of:
>> +                     "x-powers,axp202-ac-power-supply"
>> +                     "x-powers,axp221-ac-power-supply"
>> +
>> +More Required Properties for AXP20X PMICs:
>> + - io-channels: phandles to ACIN voltage and current ADC channels
>> + - io-channel-names = "acin_v", "acin_i";
>> +
>> +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 {
>
> power-supply {
>
>> +             compatible = "x-powers,axp202-ac-power-supply";
>> +             io-channels = <&axp209_adc 0>, <&axp209_adc 1>;
>
> Is this assignment fixed? If so, then it doesn't need to be in DT.

Is there any case that we actually need to use the IIO channels
from the device tree? Seems to me its limited to the other AXP
sub-devices.

If so you could use struct iio_map to map the channels to other
devices by name. See axp288_adc for an example.

Regards
ChenYu

>> +             io-channel-names = "acin_v", "acin_i";
>> +     };
>> +};
>> --
>> 2.9.3
>>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05  5:42   ` Chen-Yu Tsai
@ 2017-01-05  8:06     ` Quentin Schulz
  2017-01-05  8:27       ` Chen-Yu Tsai
  0 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-05  8:06 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

Hi Chen-Yu,

On 05/01/2017 06:42, Chen-Yu Tsai wrote:
> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
> <quentin.schulz@free-electrons.com> wrote:
[...]
>> +
>> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
>> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
>> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)
> 
> Please be consistent with the format.
> 
>> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
>> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
>> +
>> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
>> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
>> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
>> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)
> 
> These are power-of-2 multiples of some base rate. May I suggest
> a formula macro instead. Either way, you seem to be using only
> one value. Will this be made configurable in the future?
> 

Yes, I could use a formula macro instead. No plan to make it
configurable, should I make it configurable?

>> +
>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
>> +       {                                                       \
>> +               .type = _type,                                  \
>> +               .indexed = 1,                                   \
>> +               .channel = _channel,                            \
>> +               .address = _reg,                                \
>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>> +                                     BIT(IIO_CHAN_INFO_SCALE), \
>> +               .datasheet_name = _name,                        \
>> +       }
>> +
>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>> +       {                                                       \
>> +               .type = _type,                                  \
>> +               .indexed = 1,                                   \
>> +               .channel = _channel,                            \
>> +               .address = _reg,                                \
>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
>> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
>> +               .datasheet_name = _name,                        \
>> +       }
>> +
>> +struct axp20x_adc_iio {
>> +       struct iio_dev          *indio_dev;
>> +       struct regmap           *regmap;
>> +};
>> +
>> +enum axp20x_adc_channel {
>> +       AXP20X_ACIN_V = 0,
>> +       AXP20X_ACIN_I,
>> +       AXP20X_VBUS_V,
>> +       AXP20X_VBUS_I,
>> +       AXP20X_TEMP_ADC,
> 
> PMIC_TEMP would be better. And please save a slot for TS input.
> 

ACK.

Hum.. I'm wondering what should be the IIO type of the TS input channel
then? The TS Pin can be used in two modes: either to monitor the
temperature of the battery or as an external ADC, at least that's what I
understand from the datasheet.

>> +       AXP20X_GPIO0_V,
>> +       AXP20X_GPIO1_V,
> 
> Please skip a slot for "battery instantaneous power".
> 
>> +       AXP20X_BATT_V,
>> +       AXP20X_BATT_CHRG_I,
>> +       AXP20X_BATT_DISCHRG_I,
>> +       AXP20X_IPSOUT_V,
>> +};
>> +
>> +enum axp22x_adc_channel {
>> +       AXP22X_TEMP_ADC = 0,
> 
> Same comments as AXP20X_TEMP_ADC.
> 
>> +       AXP22X_BATT_V,
>> +       AXP22X_BATT_CHRG_I,
>> +       AXP22X_BATT_DISCHRG_I,
>> +};
> 
> Shouldn't these channel numbers be exported as part of the device tree
> bindings? At the very least, they shouldn't be changed.
> 

I don't understand what you mean by that. Do you mean you want a
consistent numbering between the AXP20X and the AXP22X, so that
AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?

Could you explain a bit more your thoughts on the channel numbers being
exported as part of the device tree bindings?

> Also please add a comment saying that the channels are numbered
> in the order of their respective registers, and not the table
> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
> and 9.5 E-Gauge for AXP221).
> 

Yes I can.

What about Rob wanting channel numbers to start at zero for each
different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
exported as in_current1_raw whereas he wants in_current0_raw).
[...]
>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>> +                              struct iio_chan_spec const *channel, int *val,
>> +                              int *val2)
>> +{
>> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
>> +       int size = 12, ret;
>> +
>> +       switch (channel->channel) {
>> +       case AXP22X_BATT_DISCHRG_I:
>> +               size = 13;
>> +       case AXP22X_TEMP_ADC:
>> +       case AXP22X_BATT_V:
>> +       case AXP22X_BATT_CHRG_I:
> 
> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
> 

Where did you get that?

Also, the datasheet is inconsistent:
 - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
value at 0xfff for all channels, that's 12 bits.
 - 10.1.4 ADC Data => all channels except battery discharge current are
on 12 bits (8 high, 4 low).

[...]
>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>> +                          struct iio_chan_spec const *chan, int *val,
>> +                          int *val2, long mask)
>> +{
>> +       switch (mask) {
>> +       case IIO_CHAN_INFO_OFFSET:
>> +               *val = -2667;
> 
> Datasheet says -267.7 C, or -2677 here.
> 

The formula in the datasheet is (in milli Celsius):
 processed = raw * 100 - 266700;

while the IIO framework asks for a scale and an offset which are then
applied as:
 processed = (raw + offset) * scale;

Thus by factorizing, we get:
 processed = (raw - 2667) * 100;

[...]
>> +static int axp20x_remove(struct platform_device *pdev)
>> +{
>> +       struct axp20x_adc_iio *info;
>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>> +
>> +       info = iio_priv(indio_dev);
> 
> Nit: you could just reverse the 2 declarations above and join this
> line after struct axp20x_adc_iio *info;
> 
>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> 
> The existing VBUS power supply driver enables the VBUS ADC bits itself,
> and does not check them later on. This means if one were to remove this
> axp20x-adc module, the voltage/current readings in the VBUS power supply
> would be invalid. Some sort of workaround would be needed here in this
> driver of the VBUS driver.
> 

That would be one reason to migrate the VBUS driver to use the IIO
channels, wouldn't it?

But ACK, I'll think about something to work around this issue.

>> +
>> +       return 0;
>> +}
>> +
>> +static struct platform_driver axp20x_adc_driver = {
>> +       .driver = {
>> +               .name = "axp20x-adc",
>> +               .of_match_table = axp20x_adc_of_match,
>> +       },
>> +       .probe = axp20x_probe,
>> +       .remove = axp20x_remove,
>> +};
>> +
>> +module_platform_driver(axp20x_adc_driver);
>> +
>> +MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
>> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
>> index a4860bc..650c6f6 100644
>> --- a/include/linux/mfd/axp20x.h
>> +++ b/include/linux/mfd/axp20x.h
>> @@ -150,6 +150,10 @@ enum {
>>  #define AXP20X_VBUS_I_ADC_L            0x5d
>>  #define AXP20X_TEMP_ADC_H              0x5e
>>  #define AXP20X_TEMP_ADC_L              0x5f
>> +
>> +#define AXP22X_TEMP_ADC_H              0x56
>> +#define AXP22X_TEMP_ADC_L              0x57
>> +
> 
> This is in the wrong patch. Also we already have
> 
> /* AXP22X specific registers */
> #define AXP22X_PMIC_ADC_H               0x56
> #define AXP22X_PMIC_ADC_L               0x57
> #define AXP22X_TS_ADC_H                 0x58
> #define AXP22X_TS_ADC_L                 0x59
> 
> If you want, you could just rename them to be consistent.
> 

ACK.

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode
  2017-01-05  5:51   ` Chen-Yu Tsai
@ 2017-01-05  8:08     ` Quentin Schulz
  2017-01-05  8:16       ` Chen-Yu Tsai
  0 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-05  8:08 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On 05/01/2017 06:51, Chen-Yu Tsai wrote:
> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
> <quentin.schulz@free-electrons.com> 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 <quentin.schulz@free-electrons.com>
>> ---
>>  arch/arm/boot/dts/axp209.dtsi | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
>> index 675bb0f..2a4e8ee 100644
>> --- a/arch/arm/boot/dts/axp209.dtsi
>> +++ b/arch/arm/boot/dts/axp209.dtsi
>> @@ -53,6 +53,11 @@
>>         interrupt-controller;
>>         #interrupt-cells = <1>;
>>
>> +       axp209_adc: axp209_adc {
> 
> Node name should be generic. Please change it to "adc".
> 

OK, do I keep the label as is?

axp209_adc: adc {

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X
  2017-01-05  6:10   ` Chen-Yu Tsai
@ 2017-01-05  8:10     ` Quentin Schulz
  0 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-05  8:10 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On 05/01/2017 07:10, Chen-Yu Tsai wrote:
> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
> <quentin.schulz@free-electrons.com> wrote:
>> The CHR_CTRL1 register is made of 7 read-write bits with one being used
>> to set the target voltage for battery charging.
> 
> The description is incorrect.
> 
> All 8 bits are read-write:
> 
>   - The highest bit enables the charger module
>   - Bits [6:5] set the target voltage
>   - Bits [4:3] set when the charge cycle ends, based on percentage
>     of charge current
>   - Bits [2:0] set the charge current
> 
> Feel free to use the above in the commit message.
> 

Thanks for the correction.

>>
>> This adds the CHRG_CTRL1 register to the list of writeable registers for
>> AXP20X and AXP22X PMICs.
> 
> You might want to add up to CHRG_CTRL3 for the AXP22x and CHRG_CTRL2
> for the AXP20x. These control additional aspects of the charger.
> 

ACK.

> AXP20X_CHRG_BAK_CTRL controls the charger for the RTC battery. You
> could add this now, or let the person doing the RTC battery driver
> add it.

I'll let the person adding the RTC battery driver add it.

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode
  2017-01-05  8:08     ` Quentin Schulz
@ 2017-01-05  8:16       ` Chen-Yu Tsai
  0 siblings, 0 replies; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  8:16 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Chen-Yu Tsai, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Thu, Jan 5, 2017 at 4:08 PM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> On 05/01/2017 06:51, Chen-Yu Tsai wrote:
>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>> <quentin.schulz@free-electrons.com> 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 <quentin.schulz@free-electrons.com>
>>> ---
>>>  arch/arm/boot/dts/axp209.dtsi | 5 +++++
>>>  1 file changed, 5 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
>>> index 675bb0f..2a4e8ee 100644
>>> --- a/arch/arm/boot/dts/axp209.dtsi
>>> +++ b/arch/arm/boot/dts/axp209.dtsi
>>> @@ -53,6 +53,11 @@
>>>         interrupt-controller;
>>>         #interrupt-cells = <1>;
>>>
>>> +       axp209_adc: axp209_adc {
>>
>> Node name should be generic. Please change it to "adc".
>>
>
> OK, do I keep the label as is?
>
> axp209_adc: adc {

Yup. The label is for dereferencing and stuff, and exists in a global scope.
You wouldn't want 2 label names clashing.

ChenYu

>
> Thanks,
> Quentin
>
> --
> Quentin Schulz, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05  8:06     ` Quentin Schulz
@ 2017-01-05  8:27       ` Chen-Yu Tsai
  2017-01-05  9:50         ` Quentin Schulz
  0 siblings, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05  8:27 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Chen-Yu Tsai, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Thu, Jan 5, 2017 at 4:06 PM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> Hi Chen-Yu,
>
> On 05/01/2017 06:42, Chen-Yu Tsai wrote:
>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>> <quentin.schulz@free-electrons.com> wrote:
> [...]
>>> +
>>> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
>>> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
>>> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)
>>
>> Please be consistent with the format.
>>
>>> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
>>> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
>>> +
>>> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
>>> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
>>> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
>>> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)
>>
>> These are power-of-2 multiples of some base rate. May I suggest
>> a formula macro instead. Either way, you seem to be using only
>> one value. Will this be made configurable in the future?
>>
>
> Yes, I could use a formula macro instead. No plan to make it
> configurable, should I make it configurable?

I don't see a use case for that atm.

>>> +
>>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
>>> +       {                                                       \
>>> +               .type = _type,                                  \
>>> +               .indexed = 1,                                   \
>>> +               .channel = _channel,                            \
>>> +               .address = _reg,                                \
>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>> +                                     BIT(IIO_CHAN_INFO_SCALE), \
>>> +               .datasheet_name = _name,                        \
>>> +       }
>>> +
>>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>>> +       {                                                       \
>>> +               .type = _type,                                  \
>>> +               .indexed = 1,                                   \
>>> +               .channel = _channel,                            \
>>> +               .address = _reg,                                \
>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
>>> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
>>> +               .datasheet_name = _name,                        \
>>> +       }
>>> +
>>> +struct axp20x_adc_iio {
>>> +       struct iio_dev          *indio_dev;
>>> +       struct regmap           *regmap;
>>> +};
>>> +
>>> +enum axp20x_adc_channel {
>>> +       AXP20X_ACIN_V = 0,
>>> +       AXP20X_ACIN_I,
>>> +       AXP20X_VBUS_V,
>>> +       AXP20X_VBUS_I,
>>> +       AXP20X_TEMP_ADC,
>>
>> PMIC_TEMP would be better. And please save a slot for TS input.
>>
>
> ACK.
>
> Hum.. I'm wondering what should be the IIO type of the TS input channel
> then? The TS Pin can be used in two modes: either to monitor the
> temperature of the battery or as an external ADC, at least that's what I
> understand from the datasheet.

AFAIK the battery charge/discharge high/low temperature threshold
registers take values in terms of voltage, not actual temperature.
And the temperature readout kind of depends on the thermoresistor
one is using. So I think "voltage" would be the proper type.

>
>>> +       AXP20X_GPIO0_V,
>>> +       AXP20X_GPIO1_V,
>>
>> Please skip a slot for "battery instantaneous power".
>>
>>> +       AXP20X_BATT_V,
>>> +       AXP20X_BATT_CHRG_I,
>>> +       AXP20X_BATT_DISCHRG_I,
>>> +       AXP20X_IPSOUT_V,
>>> +};
>>> +
>>> +enum axp22x_adc_channel {
>>> +       AXP22X_TEMP_ADC = 0,
>>
>> Same comments as AXP20X_TEMP_ADC.
>>
>>> +       AXP22X_BATT_V,
>>> +       AXP22X_BATT_CHRG_I,
>>> +       AXP22X_BATT_DISCHRG_I,
>>> +};
>>
>> Shouldn't these channel numbers be exported as part of the device tree
>> bindings? At the very least, they shouldn't be changed.
>>
>
> I don't understand what you mean by that. Do you mean you want a
> consistent numbering between the AXP20X and the AXP22X, so that
> AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?
>
> Could you explain a bit more your thoughts on the channel numbers being
> exported as part of the device tree bindings?

What I meant was that, since you are referencing the channels in the
device tree, the numbering scheme would be part of the device tree
binding, and should never be changed. So either these would be macros
in include/dt-bindings/, or a big warning should be put before it.

But see my reply on patch 7, about do we actually need to expose this
in the device tree.

>> Also please add a comment saying that the channels are numbered
>> in the order of their respective registers, and not the table
>> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
>> and 9.5 E-Gauge for AXP221).
>>
>
> Yes I can.
>
> What about Rob wanting channel numbers to start at zero for each
> different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
> exported as in_current1_raw whereas he wants in_current0_raw).

Hmm... I missed this. Are you talking about IIO or hwmon? IIRC
hwmon numbers things starting at 1.

> [...]
>>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>>> +                              struct iio_chan_spec const *channel, int *val,
>>> +                              int *val2)
>>> +{
>>> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
>>> +       int size = 12, ret;
>>> +
>>> +       switch (channel->channel) {
>>> +       case AXP22X_BATT_DISCHRG_I:
>>> +               size = 13;
>>> +       case AXP22X_TEMP_ADC:
>>> +       case AXP22X_BATT_V:
>>> +       case AXP22X_BATT_CHRG_I:
>>
>> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
>>
>
> Where did you get that?
>
> Also, the datasheet is inconsistent:
>  - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
> value at 0xfff for all channels, that's 12 bits.
>  - 10.1.4 ADC Data => all channels except battery discharge current are
> on 12 bits (8 high, 4 low).

My datasheets (AXP221 v1.6, AXP221s v1.2, AXP223 v1.1, all Chinese) say
in 10.1.4:

  - 7A: battery charge current high 5 bits
  - 7B: battery charge current low 8 bits
  - 7C: battery discharge current high 5 bits
  - 7D: battery discharge current low 8 bits

>
> [...]
>>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>>> +                          struct iio_chan_spec const *chan, int *val,
>>> +                          int *val2, long mask)
>>> +{
>>> +       switch (mask) {
>>> +       case IIO_CHAN_INFO_OFFSET:
>>> +               *val = -2667;
>>
>> Datasheet says -267.7 C, or -2677 here.
>>
>
> The formula in the datasheet is (in milli Celsius):
>  processed = raw * 100 - 266700;
>
> while the IIO framework asks for a scale and an offset which are then
> applied as:
>  processed = (raw + offset) * scale;
>
> Thus by factorizing, we get:
>  processed = (raw - 2667) * 100;

What I meant was that your lower end value is off by one degree,
-266.7 in your code vs -267.7 in the datasheet.

>
> [...]
>>> +static int axp20x_remove(struct platform_device *pdev)
>>> +{
>>> +       struct axp20x_adc_iio *info;
>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>> +
>>> +       info = iio_priv(indio_dev);
>>
>> Nit: you could just reverse the 2 declarations above and join this
>> line after struct axp20x_adc_iio *info;
>>
>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
>>
>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
>> and does not check them later on. This means if one were to remove this
>> axp20x-adc module, the voltage/current readings in the VBUS power supply
>> would be invalid. Some sort of workaround would be needed here in this
>> driver of the VBUS driver.
>>
>
> That would be one reason to migrate the VBUS driver to use the IIO
> channels, wouldn't it?

It is, preferably without changing the device tree.

Regards
ChenYu

>
> But ACK, I'll think about something to work around this issue.
>
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static struct platform_driver axp20x_adc_driver = {
>>> +       .driver = {
>>> +               .name = "axp20x-adc",
>>> +               .of_match_table = axp20x_adc_of_match,
>>> +       },
>>> +       .probe = axp20x_probe,
>>> +       .remove = axp20x_remove,
>>> +};
>>> +
>>> +module_platform_driver(axp20x_adc_driver);
>>> +
>>> +MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
>>> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
>>> +MODULE_LICENSE("GPL");
>>> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
>>> index a4860bc..650c6f6 100644
>>> --- a/include/linux/mfd/axp20x.h
>>> +++ b/include/linux/mfd/axp20x.h
>>> @@ -150,6 +150,10 @@ enum {
>>>  #define AXP20X_VBUS_I_ADC_L            0x5d
>>>  #define AXP20X_TEMP_ADC_H              0x5e
>>>  #define AXP20X_TEMP_ADC_L              0x5f
>>> +
>>> +#define AXP22X_TEMP_ADC_H              0x56
>>> +#define AXP22X_TEMP_ADC_L              0x57
>>> +
>>
>> This is in the wrong patch. Also we already have
>>
>> /* AXP22X specific registers */
>> #define AXP22X_PMIC_ADC_H               0x56
>> #define AXP22X_PMIC_ADC_L               0x57
>> #define AXP22X_TS_ADC_H                 0x58
>> #define AXP22X_TS_ADC_L                 0x59
>>
>> If you want, you could just rename them to be consistent.
>>
>
> ACK.
>
> Thanks,
> Quentin
>
> --
> Quentin Schulz, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05  8:27       ` Chen-Yu Tsai
@ 2017-01-05  9:50         ` Quentin Schulz
  2017-01-05 10:28           ` Chen-Yu Tsai
                             ` (2 more replies)
  0 siblings, 3 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-05  9:50 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On 05/01/2017 09:27, Chen-Yu Tsai wrote:
> On Thu, Jan 5, 2017 at 4:06 PM, Quentin Schulz
> <quentin.schulz@free-electrons.com> wrote:
>> Hi Chen-Yu,
>>
>> On 05/01/2017 06:42, Chen-Yu Tsai wrote:
>>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>>> <quentin.schulz@free-electrons.com> wrote:
>> [...]
>>>> +
>>>> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
>>>> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
>>>> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)
>>>
>>> Please be consistent with the format.
>>>
>>>> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
>>>> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
>>>> +
>>>> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
>>>> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
>>>> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
>>>> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)
>>>
>>> These are power-of-2 multiples of some base rate. May I suggest
>>> a formula macro instead. Either way, you seem to be using only
>>> one value. Will this be made configurable in the future?
>>>
>>
>> Yes, I could use a formula macro instead. No plan to make it
>> configurable, should I make it configurable?
> 
> I don't see a use case for that atm.
> 
>>>> +
>>>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
>>>> +       {                                                       \
>>>> +               .type = _type,                                  \
>>>> +               .indexed = 1,                                   \
>>>> +               .channel = _channel,                            \
>>>> +               .address = _reg,                                \
>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>> +                                     BIT(IIO_CHAN_INFO_SCALE), \
>>>> +               .datasheet_name = _name,                        \
>>>> +       }
>>>> +
>>>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>>>> +       {                                                       \
>>>> +               .type = _type,                                  \
>>>> +               .indexed = 1,                                   \
>>>> +               .channel = _channel,                            \
>>>> +               .address = _reg,                                \
>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
>>>> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
>>>> +               .datasheet_name = _name,                        \
>>>> +       }
>>>> +
>>>> +struct axp20x_adc_iio {
>>>> +       struct iio_dev          *indio_dev;
>>>> +       struct regmap           *regmap;
>>>> +};
>>>> +
>>>> +enum axp20x_adc_channel {
>>>> +       AXP20X_ACIN_V = 0,
>>>> +       AXP20X_ACIN_I,
>>>> +       AXP20X_VBUS_V,
>>>> +       AXP20X_VBUS_I,
>>>> +       AXP20X_TEMP_ADC,
>>>
>>> PMIC_TEMP would be better. And please save a slot for TS input.
>>>
>>
>> ACK.
>>
>> Hum.. I'm wondering what should be the IIO type of the TS input channel
>> then? The TS Pin can be used in two modes: either to monitor the
>> temperature of the battery or as an external ADC, at least that's what I
>> understand from the datasheet.
> 
> AFAIK the battery charge/discharge high/low temperature threshold
> registers take values in terms of voltage, not actual temperature.
> And the temperature readout kind of depends on the thermoresistor
> one is using. So I think "voltage" would be the proper type.
> 

ACK. Should I just add TS_IN in axp20x_adc_channel enum but not add it
in the exposed IIO channels ("saving" the slot but not using it)?

>>
>>>> +       AXP20X_GPIO0_V,
>>>> +       AXP20X_GPIO1_V,
>>>
>>> Please skip a slot for "battery instantaneous power".
>>>
>>>> +       AXP20X_BATT_V,
>>>> +       AXP20X_BATT_CHRG_I,
>>>> +       AXP20X_BATT_DISCHRG_I,
>>>> +       AXP20X_IPSOUT_V,
>>>> +};
>>>> +
>>>> +enum axp22x_adc_channel {
>>>> +       AXP22X_TEMP_ADC = 0,
>>>
>>> Same comments as AXP20X_TEMP_ADC.
>>>
>>>> +       AXP22X_BATT_V,
>>>> +       AXP22X_BATT_CHRG_I,
>>>> +       AXP22X_BATT_DISCHRG_I,
>>>> +};
>>>
>>> Shouldn't these channel numbers be exported as part of the device tree
>>> bindings? At the very least, they shouldn't be changed.
>>>
>>
>> I don't understand what you mean by that. Do you mean you want a
>> consistent numbering between the AXP20X and the AXP22X, so that
>> AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?
>>
>> Could you explain a bit more your thoughts on the channel numbers being
>> exported as part of the device tree bindings?
> 
> What I meant was that, since you are referencing the channels in the
> device tree, the numbering scheme would be part of the device tree
> binding, and should never be changed. So either these would be macros
> in include/dt-bindings/, or a big warning should be put before it.
> 

ACK.

> But see my reply on patch 7, about do we actually need to expose this
> in the device tree.
> 

I don't know what's the best.

>>> Also please add a comment saying that the channels are numbered
>>> in the order of their respective registers, and not the table
>>> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
>>> and 9.5 E-Gauge for AXP221).
>>>
>>
>> Yes I can.
>>
>> What about Rob wanting channel numbers to start at zero for each
>> different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
>> exported as in_current1_raw whereas he wants in_current0_raw).
> 
> Hmm... I missed this. Are you talking about IIO or hwmon? IIRC
> hwmon numbers things starting at 1.
> 

About IIO.

Today, we have exposed:
in_voltage0_raw for acin_v
in_current1_raw for acin_i
in_voltage2_raw for vbus_v
in_current3_raw for vbus_i
in_temp4_raw for adc_temp
in_voltage5_raw for gpio0_v
in_voltage6_raw for gpio1_v
in_voltage7_raw for batt_v
in_current8_raw for batt_chrg_i
in_current9_raw for batt_dischrg_i
in_voltage10_raw for ipsout_v

but I think what Rob wants is:

in_voltage0_raw acin_v
in_current0_raw for acin_i
in_voltage1_raw for vbus_v
in_current1_raw for vbus_i
in_temp_raw for adc_temp
in_voltage2_raw for gpio0_v
in_voltage3_raw for gpio1_v
in_voltage4_raw for batt_v
in_current2_raw for batt_chrg_i
in_current3_raw for batt_dischrg_i
in_voltage5_raw for ipsout_v

>> [...]
>>>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>>>> +                              struct iio_chan_spec const *channel, int *val,
>>>> +                              int *val2)
>>>> +{
>>>> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
>>>> +       int size = 12, ret;
>>>> +
>>>> +       switch (channel->channel) {
>>>> +       case AXP22X_BATT_DISCHRG_I:
>>>> +               size = 13;
>>>> +       case AXP22X_TEMP_ADC:
>>>> +       case AXP22X_BATT_V:
>>>> +       case AXP22X_BATT_CHRG_I:
>>>
>>> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
>>>
>>
>> Where did you get that?
>>
>> Also, the datasheet is inconsistent:
>>  - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
>> value at 0xfff for all channels, that's 12 bits.
>>  - 10.1.4 ADC Data => all channels except battery discharge current are
>> on 12 bits (8 high, 4 low).
> 
> My datasheets (AXP221 v1.6, AXP221s v1.2, AXP223 v1.1, all Chinese) say
> in 10.1.4:
> 
>   - 7A: battery charge current high 5 bits
>   - 7B: battery charge current low 8 bits
>   - 7C: battery discharge current high 5 bits
>   - 7D: battery discharge current low 8 bits
> 

AXP223 v1.1 in English in 10.1.4[1]:
    - 7A: battery charge current high 8 bits
    - 7B: battery charge current low 4 bits
    - 7C: battery discharge current high 8 bits
    - 7D: battery discharge current low 5 bits

Note that it's 8 bits for high and 4/5 bits for low while you wrote 4/5
bits high and low 8 bits (typos or actually what's written in the
datasheet?).

Hum.. from the reg reading function[2] I would say that the correct
formula is high on 8 bits and low on 4/5 bits.

So hum.. what do we do?

[1] http://dl.linux-sunxi.org/AXP/AXP223-en.pdf
[2] http://lxr.free-electrons.com/source/include/linux/mfd/axp20x.h#L564

>>
>> [...]
>>>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>>>> +                          struct iio_chan_spec const *chan, int *val,
>>>> +                          int *val2, long mask)
>>>> +{
>>>> +       switch (mask) {
>>>> +       case IIO_CHAN_INFO_OFFSET:
>>>> +               *val = -2667;
>>>
>>> Datasheet says -267.7 C, or -2677 here.
>>>
>>
>> The formula in the datasheet is (in milli Celsius):
>>  processed = raw * 100 - 266700;
>>
>> while the IIO framework asks for a scale and an offset which are then
>> applied as:
>>  processed = (raw + offset) * scale;
>>
>> Thus by factorizing, we get:
>>  processed = (raw - 2667) * 100;
> 
> What I meant was that your lower end value is off by one degree,
> -266.7 in your code vs -267.7 in the datasheet.
> 

Indeed. Thanks.

>>
>> [...]
>>>> +static int axp20x_remove(struct platform_device *pdev)
>>>> +{
>>>> +       struct axp20x_adc_iio *info;
>>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>>> +
>>>> +       info = iio_priv(indio_dev);
>>>
>>> Nit: you could just reverse the 2 declarations above and join this
>>> line after struct axp20x_adc_iio *info;
>>>
>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
>>>
>>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
>>> and does not check them later on. This means if one were to remove this
>>> axp20x-adc module, the voltage/current readings in the VBUS power supply
>>> would be invalid. Some sort of workaround would be needed here in this
>>> driver of the VBUS driver.
>>>
>>
>> That would be one reason to migrate the VBUS driver to use the IIO
>> channels, wouldn't it?
> 
> It is, preferably without changing the device tree.
> 

Yes, of course.

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05  9:50         ` Quentin Schulz
@ 2017-01-05 10:28           ` Chen-Yu Tsai
  2017-01-07 19:23             ` Jonathan Cameron
  2017-01-05 16:46           ` Maxime Ripard
  2017-01-07 19:20           ` Jonathan Cameron
  2 siblings, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-05 10:28 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Chen-Yu Tsai, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

On Thu, Jan 5, 2017 at 5:50 PM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> On 05/01/2017 09:27, Chen-Yu Tsai wrote:
>> On Thu, Jan 5, 2017 at 4:06 PM, Quentin Schulz
>> <quentin.schulz@free-electrons.com> wrote:
>>> Hi Chen-Yu,
>>>
>>> On 05/01/2017 06:42, Chen-Yu Tsai wrote:
>>>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>>>> <quentin.schulz@free-electrons.com> wrote:
>>> [...]
>>>>> +
>>>>> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
>>>>> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
>>>>> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)
>>>>
>>>> Please be consistent with the format.
>>>>
>>>>> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
>>>>> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
>>>>> +
>>>>> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
>>>>> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
>>>>> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
>>>>> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)
>>>>
>>>> These are power-of-2 multiples of some base rate. May I suggest
>>>> a formula macro instead. Either way, you seem to be using only
>>>> one value. Will this be made configurable in the future?
>>>>
>>>
>>> Yes, I could use a formula macro instead. No plan to make it
>>> configurable, should I make it configurable?
>>
>> I don't see a use case for that atm.
>>
>>>>> +
>>>>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
>>>>> +       {                                                       \
>>>>> +               .type = _type,                                  \
>>>>> +               .indexed = 1,                                   \
>>>>> +               .channel = _channel,                            \
>>>>> +               .address = _reg,                                \
>>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>>> +                                     BIT(IIO_CHAN_INFO_SCALE), \
>>>>> +               .datasheet_name = _name,                        \
>>>>> +       }
>>>>> +
>>>>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>>>>> +       {                                                       \
>>>>> +               .type = _type,                                  \
>>>>> +               .indexed = 1,                                   \
>>>>> +               .channel = _channel,                            \
>>>>> +               .address = _reg,                                \
>>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>>> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
>>>>> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
>>>>> +               .datasheet_name = _name,                        \
>>>>> +       }
>>>>> +
>>>>> +struct axp20x_adc_iio {
>>>>> +       struct iio_dev          *indio_dev;
>>>>> +       struct regmap           *regmap;
>>>>> +};
>>>>> +
>>>>> +enum axp20x_adc_channel {
>>>>> +       AXP20X_ACIN_V = 0,
>>>>> +       AXP20X_ACIN_I,
>>>>> +       AXP20X_VBUS_V,
>>>>> +       AXP20X_VBUS_I,
>>>>> +       AXP20X_TEMP_ADC,
>>>>
>>>> PMIC_TEMP would be better. And please save a slot for TS input.
>>>>
>>>
>>> ACK.
>>>
>>> Hum.. I'm wondering what should be the IIO type of the TS input channel
>>> then? The TS Pin can be used in two modes: either to monitor the
>>> temperature of the battery or as an external ADC, at least that's what I
>>> understand from the datasheet.
>>
>> AFAIK the battery charge/discharge high/low temperature threshold
>> registers take values in terms of voltage, not actual temperature.
>> And the temperature readout kind of depends on the thermoresistor
>> one is using. So I think "voltage" would be the proper type.
>>
>
> ACK. Should I just add TS_IN in axp20x_adc_channel enum but not add it
> in the exposed IIO channels ("saving" the slot but not using it)?

Sure. Or you could skip the number with

    AXP20X_GPIO0_V = 6,

>>>
>>>>> +       AXP20X_GPIO0_V,
>>>>> +       AXP20X_GPIO1_V,
>>>>
>>>> Please skip a slot for "battery instantaneous power".
>>>>
>>>>> +       AXP20X_BATT_V,
>>>>> +       AXP20X_BATT_CHRG_I,
>>>>> +       AXP20X_BATT_DISCHRG_I,
>>>>> +       AXP20X_IPSOUT_V,
>>>>> +};
>>>>> +
>>>>> +enum axp22x_adc_channel {
>>>>> +       AXP22X_TEMP_ADC = 0,
>>>>
>>>> Same comments as AXP20X_TEMP_ADC.
>>>>
>>>>> +       AXP22X_BATT_V,
>>>>> +       AXP22X_BATT_CHRG_I,
>>>>> +       AXP22X_BATT_DISCHRG_I,
>>>>> +};
>>>>
>>>> Shouldn't these channel numbers be exported as part of the device tree
>>>> bindings? At the very least, they shouldn't be changed.
>>>>
>>>
>>> I don't understand what you mean by that. Do you mean you want a
>>> consistent numbering between the AXP20X and the AXP22X, so that
>>> AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?
>>>
>>> Could you explain a bit more your thoughts on the channel numbers being
>>> exported as part of the device tree bindings?
>>
>> What I meant was that, since you are referencing the channels in the
>> device tree, the numbering scheme would be part of the device tree
>> binding, and should never be changed. So either these would be macros
>> in include/dt-bindings/, or a big warning should be put before it.
>>
>
> ACK.
>
>> But see my reply on patch 7, about do we actually need to expose this
>> in the device tree.
>>
>
> I don't know what's the best.

Then let's not expose it in the device tree for now. It's easier to
add it later than to remove it.

>
>>>> Also please add a comment saying that the channels are numbered
>>>> in the order of their respective registers, and not the table
>>>> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
>>>> and 9.5 E-Gauge for AXP221).
>>>>
>>>
>>> Yes I can.
>>>
>>> What about Rob wanting channel numbers to start at zero for each
>>> different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
>>> exported as in_current1_raw whereas he wants in_current0_raw).
>>
>> Hmm... I missed this. Are you talking about IIO or hwmon? IIRC
>> hwmon numbers things starting at 1.
>>
>
> About IIO.
>
> Today, we have exposed:
> in_voltage0_raw for acin_v
> in_current1_raw for acin_i
> in_voltage2_raw for vbus_v
> in_current3_raw for vbus_i
> in_temp4_raw for adc_temp
> in_voltage5_raw for gpio0_v
> in_voltage6_raw for gpio1_v
> in_voltage7_raw for batt_v
> in_current8_raw for batt_chrg_i
> in_current9_raw for batt_dischrg_i
> in_voltage10_raw for ipsout_v
>
> but I think what Rob wants is:
>
> in_voltage0_raw acin_v
> in_current0_raw for acin_i
> in_voltage1_raw for vbus_v
> in_current1_raw for vbus_i
> in_temp_raw for adc_temp
> in_voltage2_raw for gpio0_v
> in_voltage3_raw for gpio1_v
> in_voltage4_raw for batt_v
> in_current2_raw for batt_chrg_i
> in_current3_raw for batt_dischrg_i
> in_voltage5_raw for ipsout_v

I think that's doable. If I understand IIO code correctly, the channel
number is not used anywhere in the core code for dereferencing. It's
used for sysfs entries (when .indexed is set) and events. However
the twl4030 and twl6030 drivers use our current exposed scheme.
I suppose its best to get some input from the IIO maintainer.

So if we want, we could have the following channel mapping:

  0 -> acin
  1 -> vbus
  2 -> pmic
  3 -> gpio0
  4 -> gpio1
  5 -> ipsout
  6 -> battery

Each channel could have mulitple entries in axp20x_adc_channels[],
one for each type of reading. You might need multiple channels for
the battery to cover charge and discharge currents.

Your callback functions would get a bit messier though.

>
>>> [...]
>>>>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>>>>> +                              struct iio_chan_spec const *channel, int *val,
>>>>> +                              int *val2)
>>>>> +{
>>>>> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
>>>>> +       int size = 12, ret;
>>>>> +
>>>>> +       switch (channel->channel) {
>>>>> +       case AXP22X_BATT_DISCHRG_I:
>>>>> +               size = 13;
>>>>> +       case AXP22X_TEMP_ADC:
>>>>> +       case AXP22X_BATT_V:
>>>>> +       case AXP22X_BATT_CHRG_I:
>>>>
>>>> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
>>>>
>>>
>>> Where did you get that?
>>>
>>> Also, the datasheet is inconsistent:
>>>  - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
>>> value at 0xfff for all channels, that's 12 bits.
>>>  - 10.1.4 ADC Data => all channels except battery discharge current are
>>> on 12 bits (8 high, 4 low).
>>
>> My datasheets (AXP221 v1.6, AXP221s v1.2, AXP223 v1.1, all Chinese) say
>> in 10.1.4:
>>
>>   - 7A: battery charge current high 5 bits
>>   - 7B: battery charge current low 8 bits
>>   - 7C: battery discharge current high 5 bits
>>   - 7D: battery discharge current low 8 bits
>>
>
> AXP223 v1.1 in English in 10.1.4[1]:
>     - 7A: battery charge current high 8 bits
>     - 7B: battery charge current low 4 bits
>     - 7C: battery discharge current high 8 bits
>     - 7D: battery discharge current low 5 bits
>
> Note that it's 8 bits for high and 4/5 bits for low while you wrote 4/5
> bits high and low 8 bits (typos or actually what's written in the
> datasheet?).

Typo on my end, sorry. It's high 8bits and low 5/4 bits.

Apart from that, the Chinese and English versions don't match for the
battery charge current. :(

Would it be possible for you to test this? As in, have the module running,
and charging a battery, and have a multimeter in series with the battery
to verify the readings.

Regards
ChenYu

>
> Hum.. from the reg reading function[2] I would say that the correct
> formula is high on 8 bits and low on 4/5 bits.
>
> So hum.. what do we do?
>
> [1] http://dl.linux-sunxi.org/AXP/AXP223-en.pdf
> [2] http://lxr.free-electrons.com/source/include/linux/mfd/axp20x.h#L564
>
>>>
>>> [...]
>>>>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>>>>> +                          struct iio_chan_spec const *chan, int *val,
>>>>> +                          int *val2, long mask)
>>>>> +{
>>>>> +       switch (mask) {
>>>>> +       case IIO_CHAN_INFO_OFFSET:
>>>>> +               *val = -2667;
>>>>
>>>> Datasheet says -267.7 C, or -2677 here.
>>>>
>>>
>>> The formula in the datasheet is (in milli Celsius):
>>>  processed = raw * 100 - 266700;
>>>
>>> while the IIO framework asks for a scale and an offset which are then
>>> applied as:
>>>  processed = (raw + offset) * scale;
>>>
>>> Thus by factorizing, we get:
>>>  processed = (raw - 2667) * 100;
>>
>> What I meant was that your lower end value is off by one degree,
>> -266.7 in your code vs -267.7 in the datasheet.
>>
>
> Indeed. Thanks.
>
>>>
>>> [...]
>>>>> +static int axp20x_remove(struct platform_device *pdev)
>>>>> +{
>>>>> +       struct axp20x_adc_iio *info;
>>>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>>>> +
>>>>> +       info = iio_priv(indio_dev);
>>>>
>>>> Nit: you could just reverse the 2 declarations above and join this
>>>> line after struct axp20x_adc_iio *info;
>>>>
>>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
>>>>
>>>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
>>>> and does not check them later on. This means if one were to remove this
>>>> axp20x-adc module, the voltage/current readings in the VBUS power supply
>>>> would be invalid. Some sort of workaround would be needed here in this
>>>> driver of the VBUS driver.
>>>>
>>>
>>> That would be one reason to migrate the VBUS driver to use the IIO
>>> channels, wouldn't it?
>>
>> It is, preferably without changing the device tree.
>>
>
> Yes, of course.
>
> Thanks,
> Quentin
>
> --
> Quentin Schulz, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding
  2017-01-02 16:37 ` [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding Quentin Schulz
  2017-01-03 23:20   ` Rob Herring
@ 2017-01-05 16:40   ` Maxime Ripard
  1 sibling, 0 replies; 72+ messages in thread
From: Maxime Ripard @ 2017-01-05 16:40 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, lee.jones, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 654 bytes --]

On Mon, Jan 02, 2017 at 05:37:01PM +0100, 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 the device tree binding documentation for the X-Powers AXP20X
> and AXP22X PMICs ADCs.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>

Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05  9:50         ` Quentin Schulz
  2017-01-05 10:28           ` Chen-Yu Tsai
@ 2017-01-05 16:46           ` Maxime Ripard
  2017-01-07 19:20           ` Jonathan Cameron
  2 siblings, 0 replies; 72+ messages in thread
From: Maxime Ripard @ 2017-01-05 16:46 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Chen-Yu Tsai, Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Lee Jones, linux-iio,
	devicetree, linux-kernel, open list:THERMAL, linux-arm-kernel,
	Thomas Petazzoni, Icenowy Zheng, Bruno Prémont

[-- Attachment #1: Type: text/plain, Size: 1415 bytes --]

On Thu, Jan 05, 2017 at 10:50:33AM +0100, Quentin Schulz wrote:
> >>>> +static int axp20x_remove(struct platform_device *pdev)
> >>>> +{
> >>>> +       struct axp20x_adc_iio *info;
> >>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >>>> +
> >>>> +       info = iio_priv(indio_dev);
> >>>
> >>> Nit: you could just reverse the 2 declarations above and join this
> >>> line after struct axp20x_adc_iio *info;
> >>>
> >>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> >>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> >>>
> >>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
> >>> and does not check them later on. This means if one were to remove this
> >>> axp20x-adc module, the voltage/current readings in the VBUS power supply
> >>> would be invalid. Some sort of workaround would be needed here in this
> >>> driver of the VBUS driver.
> >>>
> >>
> >> That would be one reason to migrate the VBUS driver to use the IIO
> >> channels, wouldn't it?
> > 
> > It is, preferably without changing the device tree.
> > 
> 
> Yes, of course.

Note that you can have something like a test for the iio channel
property in the VBUS driver, and keep the old behaviour in the case
where we wouldn't have it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-02 16:37 ` [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs Quentin Schulz
  2017-01-05  5:42   ` Chen-Yu Tsai
@ 2017-01-05 16:51   ` Maxime Ripard
  2017-01-07 19:13   ` Jonathan Cameron
  2 siblings, 0 replies; 72+ messages in thread
From: Maxime Ripard @ 2017-01-05 16:51 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, lee.jones, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 1575 bytes --]

On Mon, Jan 02, 2017 at 05:37:03PM +0100, Quentin Schulz wrote:
> +	switch (axp20x_id) {
> +	case AXP209_ID:
> +		indio_dev->info = &axp20x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
> +		indio_dev->channels = axp20x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
> +
> +		/* Enable GPIO0/1 and internal temperature ADCs */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
> +				   AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP20X_ADC_RATE_50HZ);
> +		break;
> +
> +	case AXP221_ID:
> +		indio_dev->info = &axp22x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
> +		indio_dev->channels = axp22x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}

I'm not a big fan of those IDs. It always ends up with a ever
increasing list of cases without any consolidation.

In this case, the only thing you need is a list of pointers and values
that can definitely be stored in a structure.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
@ 2017-01-05 17:02   ` Maxime Ripard
  2017-01-05 17:34   ` Ezequiel Garcia
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 72+ messages in thread
From: Maxime Ripard @ 2017-01-05 17:02 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens, sre,
	linux, lee.jones, linux-iio, devicetree, linux-kernel, linux-pm,
	linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 1726 bytes --]

On Mon, Jan 02, 2017 at 05:37:17PM +0100, Quentin Schulz wrote:
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives µV.
> +		 */
> +		val->intval *= 1000;

s/gives/wants/ ?

> +static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +					  int val)
> +{
> +	switch (val) {
> +	case 4100000:
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_1V);
> +	case 4150000:
> +		if (axp20x_batt->axp_id == AXP221_ID)
> +			return -EINVAL;
> +
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_15V);
> +	case 4200000:
> +		return regmap_update_bits(axp20x_batt->regmap,
> +					  AXP20X_CHRG_CTRL1,
> +					  AXP20X_CHRG_CTRL1_TGT_VOLT,
> +					  AXP20X_CHRG_CTRL1_TGT_4_2V);
> +	default:
> +		/*
> +		 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
> +		 * can be set to 4.22V and 4.24V, but these voltages are too
> +		 * high for Lithium based batteries (AXP PMICs are supposed to
> +		 * be used with these kinds of battery).
> +		 */
> +		return -EINVAL;
> +	}

Since all your calls to regmap are the same, something like:

case 4100000:
	val = AXP20X_CHRG_CTRL1_TGT_4_1V;
	break;

case 4150000:
	val = AXP20X_CHRG_CTRL1_TGT_4_15V;
	break;

regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
		   AXP20X_CHRG_CTRL1_TGT_VOLT, val);


It would also get rid of your warnings in checkpatch.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
  2017-01-05 17:02   ` Maxime Ripard
@ 2017-01-05 17:34   ` Ezequiel Garcia
  2017-01-06  2:46     ` Sebastian Reichel
  2017-01-06  3:39   ` Chen-Yu Tsai
  2017-01-17  3:46   ` Sebastian Reichel
  3 siblings, 1 reply; 72+ messages in thread
From: Ezequiel Garcia @ 2017-01-05 17:34 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, Rob Herring, Mark Rutland,
	Chen-Yu Tsai, sre, linux, Maxime Ripard, Lee Jones,
	Thomas Petazzoni, devicetree, linux-pm, linux-iio, linux-kernel,
	bonbons, icenowy, linux-arm-kernel

On 2 January 2017 at 13:37, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
[...]
> +
> +#define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2)
> +
> +#define AXP20X_PWR_OP_BATT_PRESENT     BIT(5)
> +#define AXP20X_PWR_OP_BATT_ACTIVATED   BIT(3)
> +
> +#define AXP209_FG_PERCENT              GENMASK(6, 0)
> +#define AXP22X_FG_VALID                        BIT(7)
> +
> +#define AXP20X_CHRG_CTRL1_TGT_VOLT     GENMASK(6, 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_1V     (0 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_15V    BIT(5)

This is just a silly nit, but I would put (1 << 5) here
for readability.

> +#define AXP20X_CHRG_CTRL1_TGT_4_2V     (2 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_36V    (3 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_CURR     GENMASK(3, 0)
> +
> +#define AXP22X_CHRG_CTRL1_TGT_4_22V    BIT(5)

Ditto.

> +#define AXP22X_CHRG_CTRL1_TGT_4_24V    (3 << 5)
> +
> +#define AXP20X_V_OFF_MASK              GENMASK(2, 0)
> +
> +struct axp20x_batt_ps {
> +       struct regmap *regmap;
> +       struct power_supply *batt;
> +       struct axp20x_dev *axp20x;
> +       struct iio_channel *batt_chrg_i;
> +       struct iio_channel *batt_dischrg_i;
> +       struct iio_channel *batt_v;
> +       u8 axp_id;
> +};
> +
[..]
> +static int axp20x_power_probe(struct platform_device *pdev)
> +{
> +       struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +       struct axp20x_batt_ps *axp20x_batt;
> +       struct power_supply_config psy_cfg = {};
> +

To be consistent with the AC power supply and USB power supply,
you might want to call of_device_is_available() here.
Otherwise, the device probes even if "disabled" in the DTS.

> +       axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
> +                                  GFP_KERNEL);
> +       if (!axp20x_batt)
> +               return -ENOMEM;
> +

Thanks for the good work,
-- 
Ezequiel García, VanguardiaSur
www.vanguardiasur.com.ar

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-05 17:34   ` Ezequiel Garcia
@ 2017-01-06  2:46     ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2017-01-06  2:46 UTC (permalink / raw)
  To: Ezequiel Garcia
  Cc: Quentin Schulz, jic23, knaack.h, lars, pmeerw, Rob Herring,
	Mark Rutland, Chen-Yu Tsai, linux, Maxime Ripard, Lee Jones,
	Thomas Petazzoni, devicetree, linux-pm, linux-iio, linux-kernel,
	bonbons, icenowy, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 652 bytes --]

Hi,

On Thu, Jan 05, 2017 at 02:34:48PM -0300, Ezequiel Garcia wrote:
> > +static int axp20x_power_probe(struct platform_device *pdev)
> > +{
> > +       struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> > +       struct axp20x_batt_ps *axp20x_batt;
> > +       struct power_supply_config psy_cfg = {};
> > +
> 
> To be consistent with the AC power supply and USB power supply,
> you might want to call of_device_is_available() here.
> Otherwise, the device probes even if "disabled" in the DTS.

I would expect that check in the mfd code. Probe should not be
called at all if the sub-device is disabled.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
  2017-01-05 17:02   ` Maxime Ripard
  2017-01-05 17:34   ` Ezequiel Garcia
@ 2017-01-06  3:39   ` Chen-Yu Tsai
  2017-01-06  8:29     ` Quentin Schulz
  2017-01-17  3:46   ` Sebastian Reichel
  3 siblings, 1 reply; 72+ messages in thread
From: Chen-Yu Tsai @ 2017-01-06  3:39 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland, Chen-Yu Tsai,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

 Hi,

On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
<quentin.schulz@free-electrons.com> 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 <quentin.schulz@free-electrons.com>
> ---
>  drivers/power/supply/Kconfig          |  12 +
>  drivers/power/supply/Makefile         |   1 +
>  drivers/power/supply/axp20x_battery.c | 458 ++++++++++++++++++++++++++++++++++
>  3 files changed, 471 insertions(+)
>  create mode 100644 drivers/power/supply/axp20x_battery.c
>
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index c552b4b..48619de 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -226,6 +226,18 @@ config CHARGER_AXP20X
>           This driver can also be built as a module. If so, the module will be
>           called axp20x_ac_power.
>
> +config BATTERY_AXP20X
> +       tristate "X-Powers AXP20X battery driver"
> +       depends on MFD_AXP20X
> +       depends on AXP20X_ADC
> +       depends on IIO
> +       help
> +         Say Y here to enable support for X-Powers AXP20X PMICs' battery power
> +         supply.
> +
> +         This driver can also be built as a module. If so, the module will be
> +         called axp20x_battery.
> +
>  config AXP288_CHARGER
>         tristate "X-Powers AXP288 Charger"
>         depends on MFD_AXP20X && EXTCON_AXP288
> diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> index 7d22417..5a217b2 100644
> --- a/drivers/power/supply/Makefile
> +++ b/drivers/power/supply/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_TEST_POWER)      += test_power.o
>
>  obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
>  obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
> +obj-$(CONFIG_BATTERY_AXP20X)   += axp20x_battery.o
>  obj-$(CONFIG_CHARGER_AXP20X)   += axp20x_ac_power.o
>  obj-$(CONFIG_BATTERY_DS2760)   += ds2760_battery.o
>  obj-$(CONFIG_BATTERY_DS2780)   += ds2780_battery.o
> diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
> new file mode 100644
> index 0000000..e1d7b5f
> --- /dev/null
> +++ b/drivers/power/supply/axp20x_battery.c
> @@ -0,0 +1,458 @@
> +/*
> + * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs
> + *
> + * Copyright 2016 Free Electrons NextThing Co.
> + *     Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This driver is based on a previous upstreaming attempt by:
> + *     Bruno Prémont <bonbons@linux-vserver.org>
> + *
> + * This file is subject to the terms and conditions of the GNU General
> + * Public License. See the file "COPYING" in the main directory of this
> + * archive for more details.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.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/time.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/mfd/axp20x.h>
> +
> +#define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2)
> +
> +#define AXP20X_PWR_OP_BATT_PRESENT     BIT(5)
> +#define AXP20X_PWR_OP_BATT_ACTIVATED   BIT(3)
> +
> +#define AXP209_FG_PERCENT              GENMASK(6, 0)
> +#define AXP22X_FG_VALID                        BIT(7)
> +
> +#define AXP20X_CHRG_CTRL1_TGT_VOLT     GENMASK(6, 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_1V     (0 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_15V    BIT(5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_2V     (2 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_4_36V    (3 << 5)
> +#define AXP20X_CHRG_CTRL1_TGT_CURR     GENMASK(3, 0)
> +
> +#define AXP22X_CHRG_CTRL1_TGT_4_22V    BIT(5)
> +#define AXP22X_CHRG_CTRL1_TGT_4_24V    (3 << 5)
> +
> +#define AXP20X_V_OFF_MASK              GENMASK(2, 0)
> +
> +struct axp20x_batt_ps {
> +       struct regmap *regmap;
> +       struct power_supply *batt;
> +       struct axp20x_dev *axp20x;
> +       struct iio_channel *batt_chrg_i;
> +       struct iio_channel *batt_dischrg_i;
> +       struct iio_channel *batt_v;
> +       u8 axp_id;
> +};
> +
> +static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +                                         int *val)
> +{
> +       int ret, reg;
> +
> +       ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
> +       if (ret)
> +               return ret;
> +
> +       switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
> +       case AXP20X_CHRG_CTRL1_TGT_4_1V:
> +               *val = 4100000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_15V:
> +               *val = 4150000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_2V:
> +               *val = 4200000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_36V:
> +               *val = 4360000;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +                                         int *val)
> +{
> +       int ret, reg;
> +
> +       ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
> +       if (ret)
> +               return ret;
> +
> +       switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
> +       case AXP20X_CHRG_CTRL1_TGT_4_1V:
> +               *val = 4100000;
> +               break;
> +       case AXP20X_CHRG_CTRL1_TGT_4_2V:
> +               *val = 4200000;
> +               break;
> +       case AXP22X_CHRG_CTRL1_TGT_4_22V:
> +               *val = 4220000;
> +               break;
> +       case AXP22X_CHRG_CTRL1_TGT_4_24V:
> +               *val = 4240000;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_battery_get_prop(struct power_supply *psy,
> +                                  enum power_supply_property psp,
> +                                  union power_supply_propval *val)
> +{
> +       struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
> +       struct iio_channel *chan;
> +       int ret = 0, reg, val1;
> +
> +       switch (psp) {
> +       case POWER_SUPPLY_PROP_PRESENT:
> +       case POWER_SUPPLY_PROP_ONLINE:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT);
> +               break;
> +
> +       case POWER_SUPPLY_PROP_STATUS:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
> +                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
> +                       return 0;
> +               }
> +
> +               ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i,
> +                                                &val1);
> +               if (ret)
> +                       return ret;
> +
> +               if (val1) {
> +                       val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +                       return 0;
> +               }
> +
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1);
> +               if (ret)
> +                       return ret;
> +
> +               /*
> +                * Fuel Gauge data takes 7 bits but the stored value seems to be
> +                * directly the raw percentage without any scaling to 7 bits.
> +                */
> +               if ((val1 & AXP209_FG_PERCENT) == 100)
> +                       val->intval = POWER_SUPPLY_STATUS_FULL;
> +               else
> +                       val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_HEALTH:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
> +                                 &val1);
> +               if (ret)
> +                       return ret;
> +
> +               if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) {
> +                       val->intval = POWER_SUPPLY_HEALTH_DEAD;
> +                       return 0;
> +               }
> +
> +               val->intval = POWER_SUPPLY_HEALTH_GOOD;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_CURRENT_MAX:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
> +               if (ret)
> +                       return ret;
> +
> +               reg &= AXP20X_CHRG_CTRL1_TGT_CURR;
> +               val->intval = reg * 100000 + 300000;
> +               break;


This controls the charge current. I believe the correct property to use
is CONSTANT_CHARGE_CURRENT. And you should add CONSTANT_CHARGE_CURRENT_MAX
which returns the highest possible setting.

Also letting the user control this might not always be a good idea.
IIUC, LiPo batteries can only be charged at 1C, where C is the
rated capacity (X mAh).

> +
> +       case POWER_SUPPLY_PROP_CURRENT_NOW:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (reg & AXP20X_PWR_STATUS_BAT_CHARGING)
> +                       chan = axp20x_batt->batt_chrg_i;
> +               else
> +                       chan = axp20x_batt->batt_dischrg_i;
> +
> +               ret = iio_read_channel_processed(chan, &val->intval);
> +               if (ret)
> +                       return ret;
> +
> +               /*
> +                * IIO framework gives mV but Power Supply framework gives µV.
> +                */
> +               val->intval *= 1000;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_CAPACITY:
> +               /* When no battery is present, return capacity is 100% */
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
> +                                 &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
> +                       val->intval = 100;
> +                       return 0;
> +               }
> +
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &reg);
> +               if (ret)
> +                       return ret;
> +
> +               if (axp20x_batt->axp_id == AXP221_ID &&
> +                   !(reg & AXP22X_FG_VALID))
> +                       return -EINVAL;
> +
> +               /*
> +                * Fuel Gauge data takes 7 bits but the stored value seems to be
> +                * directly the raw percentage without any scaling to 7 bits.
> +                */
> +               val->intval = reg & AXP209_FG_PERCENT;
> +               break;
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> +               if (axp20x_batt->axp_id == AXP209_ID)
> +                       return axp20x_battery_get_max_voltage(axp20x_batt,
> +                                                             &val->intval);
> +               return axp22x_battery_get_max_voltage(axp20x_batt,
> +                                                     &val->intval);
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg);
> +               if (ret)
> +                       return ret;
> +
> +               val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
> +               break;
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +               ret = iio_read_channel_processed(axp20x_batt->batt_v,
> +                                                &val->intval);
> +               if (ret)
> +                       return ret;
> +
> +               /*
> +                * IIO framework gives mV but Power Supply framework gives µV.
> +                */
> +               val->intval *= 1000;
> +               break;
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
> +                                         int val)
> +{
> +       switch (val) {
> +       case 4100000:
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_VOLT,
> +                                         AXP20X_CHRG_CTRL1_TGT_4_1V);
> +       case 4150000:
> +               if (axp20x_batt->axp_id == AXP221_ID)
> +                       return -EINVAL;
> +
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_VOLT,
> +                                         AXP20X_CHRG_CTRL1_TGT_4_15V);
> +       case 4200000:
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_VOLT,
> +                                         AXP20X_CHRG_CTRL1_TGT_4_2V);
> +       default:
> +               /*
> +                * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
> +                * can be set to 4.22V and 4.24V, but these voltages are too
> +                * high for Lithium based batteries (AXP PMICs are supposed to
> +                * be used with these kinds of battery).
> +                */
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int axp20x_battery_set_prop(struct power_supply *psy,
> +                                  enum power_supply_property psp,
> +                                  const union power_supply_propval *val)
> +{
> +       struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
> +       int ret = 0, val1;
> +
> +       switch (psp) {
> +       case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +               val1 = (val->intval - 2600000) / 100000;
> +               if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
> +                       return -EINVAL;
> +
> +               return regmap_update_bits(axp20x_batt->regmap, AXP20X_V_OFF,
> +                                         AXP20X_V_OFF_MASK, val1);
> +
> +       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> +               return axp20x_battery_set_max_voltage(axp20x_batt, val->intval);
> +
> +       case POWER_SUPPLY_PROP_CURRENT_MAX:
> +               if (axp20x_batt->axp_id == AXP209_ID)
> +                       val1 = (val->intval - 300000) / 100000;
> +               else
> +                       val1 = (val->intval - 300000) / 150000;
> +
> +               if (val1 > AXP20X_CHRG_CTRL1_TGT_CURR || val1 < 0)
> +                       return -EINVAL;
> +
> +               return regmap_update_bits(axp20x_batt->regmap,
> +                                         AXP20X_CHRG_CTRL1,
> +                                         AXP20X_CHRG_CTRL1_TGT_CURR, val1);
> +
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static enum power_supply_property axp20x_battery_props[] = {
> +       POWER_SUPPLY_PROP_PRESENT,
> +       POWER_SUPPLY_PROP_ONLINE,
> +       POWER_SUPPLY_PROP_STATUS,
> +       POWER_SUPPLY_PROP_VOLTAGE_NOW,
> +       POWER_SUPPLY_PROP_CURRENT_NOW,
> +       POWER_SUPPLY_PROP_CURRENT_MAX,
> +       POWER_SUPPLY_PROP_HEALTH,
> +       POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
> +       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
> +       POWER_SUPPLY_PROP_CAPACITY,

You can also add POWER_SUPPLY_PROP_TECHNOLOGY, which would return
POWER_SUPPLY_TECHNOLOGY_LIPO.

It is also possible to do POWER_SUPPLY_PROP_CHARGE_TYPE. According
to the manual, if the battery is charging, it is in constant current
mode (POWER_SUPPLY_CHARGE_TYPE_FAST) when V_battery < V_target.
When V_battery == V_target, it is in constant voltage mode, though
I don't think this is the same as POWER_SUPPLY_CHARGE_TYPE_TRICKLE.
When it is not charging, you can return POWER_SUPPLY_CHARGE_TYPE_NONE.

Regards
ChenYu

> +};
> +
> +static int axp20x_battery_prop_writeable(struct power_supply *psy,
> +                                        enum power_supply_property psp)
> +{
> +       return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN ||
> +              psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ||
> +              psp == POWER_SUPPLY_PROP_CURRENT_MAX;
> +}
> +
> +static const struct power_supply_desc axp20x_batt_ps_desc = {
> +       .name = "axp20x-battery",
> +       .type = POWER_SUPPLY_TYPE_BATTERY,
> +       .properties = axp20x_battery_props,
> +       .num_properties = ARRAY_SIZE(axp20x_battery_props),
> +       .property_is_writeable = axp20x_battery_prop_writeable,
> +       .get_property = axp20x_battery_get_prop,
> +       .set_property = axp20x_battery_set_prop,
> +};
> +
> +static const struct of_device_id axp20x_battery_ps_id[] = {
> +       {
> +               .compatible = "x-powers,axp209-battery-power-supply",
> +               .data = (void *)AXP209_ID,
> +       }, {
> +               .compatible = "x-powers,axp221-battery-power-supply",
> +               .data = (void *)AXP221_ID,
> +       }, { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
> +
> +static int axp20x_power_probe(struct platform_device *pdev)
> +{
> +       struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +       struct axp20x_batt_ps *axp20x_batt;
> +       struct power_supply_config psy_cfg = {};
> +
> +       axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
> +                                  GFP_KERNEL);
> +       if (!axp20x_batt)
> +               return -ENOMEM;
> +
> +       axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
> +       if (IS_ERR(axp20x_batt->batt_v)) {
> +               if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV)
> +                       return -EPROBE_DEFER;
> +               return PTR_ERR(axp20x_batt->batt_v);
> +       }
> +
> +       axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
> +                                                       "batt_chrg_i");
> +       if (IS_ERR(axp20x_batt->batt_chrg_i)) {
> +               if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV)
> +                       return -EPROBE_DEFER;
> +               return PTR_ERR(axp20x_batt->batt_chrg_i);
> +       }
> +
> +       axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
> +                                                          "batt_dischrg_i");
> +       if (IS_ERR(axp20x_batt->batt_dischrg_i)) {
> +               if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV)
> +                       return -EPROBE_DEFER;
> +               return PTR_ERR(axp20x_batt->batt_dischrg_i);
> +       }
> +
> +       axp20x_batt->regmap = axp20x->regmap;
> +       platform_set_drvdata(pdev, axp20x_batt);
> +
> +       psy_cfg.drv_data = axp20x_batt;
> +       psy_cfg.of_node = pdev->dev.of_node;
> +
> +       axp20x_batt->axp_id = (int)of_device_get_match_data(&pdev->dev);
> +
> +       axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
> +                                                      &axp20x_batt_ps_desc,
> +                                                      &psy_cfg);
> +       return PTR_ERR_OR_ZERO(axp20x_batt->batt);
> +}
> +
> +static struct platform_driver axp20x_batt_driver = {
> +       .probe    = axp20x_power_probe,
> +       .driver   = {
> +               .name  = "axp20x-battery-power-supply",
> +               .of_match_table = axp20x_battery_ps_id,
> +       },
> +};
> +
> +module_platform_driver(axp20x_batt_driver);
> +
> +MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> --
> 2.9.3
>

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-06  3:39   ` Chen-Yu Tsai
@ 2017-01-06  8:29     ` Quentin Schulz
  0 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-06  8:29 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Jonathan Cameron, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Rob Herring, Mark Rutland,
	Sebastian Reichel, Russell King, Maxime Ripard, Lee Jones,
	linux-iio, devicetree, linux-kernel, open list:THERMAL,
	linux-arm-kernel, Thomas Petazzoni, Icenowy Zheng,
	Bruno Prémont

Hi,

On 06/01/2017 04:39, Chen-Yu Tsai wrote:
>  Hi,
> 
> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
> <quentin.schulz@free-electrons.com> wrote:
[...]
>> +       case POWER_SUPPLY_PROP_CURRENT_MAX:
>> +               ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
>> +               if (ret)
>> +                       return ret;
>> +
>> +               reg &= AXP20X_CHRG_CTRL1_TGT_CURR;
>> +               val->intval = reg * 100000 + 300000;
>> +               break;
> 
> 
> This controls the charge current. I believe the correct property to use
> is CONSTANT_CHARGE_CURRENT. And you should add CONSTANT_CHARGE_CURRENT_MAX
> which returns the highest possible setting.
> 

ACK.

> Also letting the user control this might not always be a good idea.
> IIUC, LiPo batteries can only be charged at 1C, where C is the
> rated capacity (X mAh).
> 

OK. Should I get the charge current from a DT property then?

Like "x-powers,charge-current = <300000>;"
It's close to what has been done in bq24257_charger for example.

[...]
>> +static enum power_supply_property axp20x_battery_props[] = {
>> +       POWER_SUPPLY_PROP_PRESENT,
>> +       POWER_SUPPLY_PROP_ONLINE,
>> +       POWER_SUPPLY_PROP_STATUS,
>> +       POWER_SUPPLY_PROP_VOLTAGE_NOW,
>> +       POWER_SUPPLY_PROP_CURRENT_NOW,
>> +       POWER_SUPPLY_PROP_CURRENT_MAX,
>> +       POWER_SUPPLY_PROP_HEALTH,
>> +       POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
>> +       POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
>> +       POWER_SUPPLY_PROP_CAPACITY,
> 
> You can also add POWER_SUPPLY_PROP_TECHNOLOGY, which would return
> POWER_SUPPLY_TECHNOLOGY_LIPO.
> 

Hum.. There are also POWER_SUPPLY_TECHNOLOGY_LION,
POWER_SUPPLY_TECHNOLOGY_LiFe and POWER_SUPPLY_TECHNOLOGY_LiMn which are
all Lithium-based batteries. From the datasheet, it can take a "single
cell Li-battery (Li-Ion/Polymer)". So I guess it's either
POWER_SUPPLY_TECHNOLOGY_LION or POWER_SUPPLY_TECHNOLOGY_LIPO.

> It is also possible to do POWER_SUPPLY_PROP_CHARGE_TYPE. According
> to the manual, if the battery is charging, it is in constant current
> mode (POWER_SUPPLY_CHARGE_TYPE_FAST) when V_battery < V_target.
> When V_battery == V_target, it is in constant voltage mode, though
> I don't think this is the same as POWER_SUPPLY_CHARGE_TYPE_TRICKLE.
> When it is not charging, you can return POWER_SUPPLY_CHARGE_TYPE_NONE.
> 

ACK, I'll look into that.

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-02 16:37 ` [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs Quentin Schulz
  2017-01-05  5:42   ` Chen-Yu Tsai
  2017-01-05 16:51   ` Maxime Ripard
@ 2017-01-07 19:13   ` Jonathan Cameron
  2 siblings, 0 replies; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-07 19:13 UTC (permalink / raw)
  To: Quentin Schulz, knaack.h, lars, pmeerw, robh+dt, mark.rutland,
	wens, sre, linux, maxime.ripard, lee.jones
  Cc: linux-iio, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	thomas.petazzoni, icenowy, bonbons

On 02/01/17 11:37, 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 <quentin.schulz@free-electrons.com>
Couple of little bits from me. Peter got the bigger stuff.

Jonathan
> ---
>  drivers/iio/adc/Kconfig      |  10 +
>  drivers/iio/adc/Makefile     |   1 +
>  drivers/iio/adc/axp20x_adc.c | 490 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/axp20x.h   |   4 +
>  4 files changed, 505 insertions(+)
>  create mode 100644 drivers/iio/adc/axp20x_adc.c
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 38bc319..5c5b51f 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -154,6 +154,16 @@ config AT91_SAMA5D2_ADC
>  	  To compile this driver as a module, choose M here: the module will be
>  	  called at91-sama5d2_adc.
>  
> +config AXP20X_ADC
> +	tristate "X-Powers AXP20X and AXP22X ADC driver"
> +	depends on MFD_AXP20X
> +	help
> +	  Say yes here to have support for X-Powers power management IC (PMIC)
> +	  AXP20X and AXP22X ADC devices.
> +
> +	  To compile this driver as a module, choose M here: the module will be
> +	  called axp20x_adc.
> +
>  config AXP288_ADC
>  	tristate "X-Powers AXP288 ADC driver"
>  	depends on MFD_AXP20X
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index d36c4be..f5c28a5 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
>  obj-$(CONFIG_AD799X) += ad799x.o
>  obj-$(CONFIG_AT91_ADC) += at91_adc.o
>  obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
> +obj-$(CONFIG_AXP20X_ADC) += axp20x_adc.o
>  obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
>  obj-$(CONFIG_BCM_IPROC_ADC) += bcm_iproc_adc.o
>  obj-$(CONFIG_BERLIN2_ADC) += berlin2-adc.o
> diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c
> new file mode 100644
> index 0000000..8df972a
> --- /dev/null
> +++ b/drivers/iio/adc/axp20x_adc.c
> @@ -0,0 +1,490 @@
> +/* ADC driver for AXP20X and AXP22X PMICs
> + *
> + * Copyright (c) 2016 Free Electrons NextThing Co.
> + *	Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + *
Pet hate : why a blank line here? ;) I'm grumpy - my flight home is delayed.
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/thermal.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/mfd/axp20x.h>
> +
> +#define AXP20X_ADC_EN1_MASK			GENMASK(7, 0)
> +
> +#define AXP20X_ADC_EN2_MASK			(GENMASK(3, 2) | BIT(7))
> +#define AXP22X_ADC_EN1_MASK			(GENMASK(7, 5) | BIT(0))
> +#define AXP20X_ADC_EN2_TEMP_ADC			BIT(7)
> +#define AXP20X_ADC_EN2_GPIO0_ADC		BIT(3)
> +#define AXP20X_ADC_EN2_GPIO1_ADC		BIT(2)
> +
> +#define AXP20X_GPIO10_IN_RANGE_GPIO0		BIT(0)
> +#define AXP20X_GPIO10_IN_RANGE_GPIO1		BIT(1)
> +#define AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(x)	((x) & BIT(0))
> +#define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x)	(((x) & BIT(0)) << 1)
> +
> +#define AXP20X_ADC_RATE_MASK			(3 << 6)
> +#define AXP20X_ADC_RATE_25HZ			(0 << 6)
> +#define AXP20X_ADC_RATE_50HZ			BIT(6)
> +#define AXP20X_ADC_RATE_100HZ			(2 << 6)
> +#define AXP20X_ADC_RATE_200HZ			(3 << 6)
> +
> +#define AXP22X_ADC_RATE_100HZ			(0 << 6)
> +#define AXP22X_ADC_RATE_200HZ			BIT(6)
> +#define AXP22X_ADC_RATE_400HZ			(2 << 6)
> +#define AXP22X_ADC_RATE_800HZ			(3 << 6)
> +
> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)	\
> +	{							\
> +		.type = _type,					\
> +		.indexed = 1,					\
> +		.channel = _channel,				\
> +		.address = _reg,				\
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
> +				      BIT(IIO_CHAN_INFO_SCALE),	\
> +		.datasheet_name = _name,			\
> +	}
> +
> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
> +	{							\
> +		.type = _type,					\
> +		.indexed = 1,					\
> +		.channel = _channel,				\
> +		.address = _reg,				\
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
> +				      BIT(IIO_CHAN_INFO_SCALE) |\
> +				      BIT(IIO_CHAN_INFO_OFFSET),\
> +		.datasheet_name = _name,			\
> +	}
> +
> +struct axp20x_adc_iio {
Why?  I'm not seeing this used anywhere.
> +	struct iio_dev		*indio_dev;
> +	struct regmap		*regmap;
> +};
> +
> +enum axp20x_adc_channel {
> +	AXP20X_ACIN_V = 0,
> +	AXP20X_ACIN_I,
> +	AXP20X_VBUS_V,
> +	AXP20X_VBUS_I,
> +	AXP20X_TEMP_ADC,
> +	AXP20X_GPIO0_V,
> +	AXP20X_GPIO1_V,
> +	AXP20X_BATT_V,
> +	AXP20X_BATT_CHRG_I,
> +	AXP20X_BATT_DISCHRG_I,
> +	AXP20X_IPSOUT_V,
> +};
> +
> +enum axp22x_adc_channel {
> +	AXP22X_TEMP_ADC = 0,
> +	AXP22X_BATT_V,
> +	AXP22X_BATT_CHRG_I,
> +	AXP22X_BATT_DISCHRG_I,
> +};
> +
> +static const struct iio_chan_spec axp20x_adc_channels[] = {
> +	AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,
> +			   AXP20X_ACIN_V_ADC_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,
> +			   AXP20X_ACIN_I_ADC_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,
> +			   AXP20X_VBUS_V_ADC_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,
> +			   AXP20X_VBUS_I_ADC_H),
> +	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_TEMP_ADC, "temp_adc", IIO_TEMP,
> +				  AXP20X_TEMP_ADC_H),
> +	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,
> +				  AXP20X_GPIO0_V_ADC_H),
> +	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,
> +				  AXP20X_GPIO1_V_ADC_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,
> +			   AXP20X_BATT_V_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
> +			   AXP20X_BATT_CHRG_I_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
> +			   AXP20X_BATT_DISCHRG_I_H),
> +	AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,
> +			   AXP20X_IPSOUT_V_HIGH_H),
> +};
> +
> +static const struct iio_chan_spec axp22x_adc_channels[] = {
> +	AXP20X_ADC_CHANNEL_OFFSET(AXP22X_TEMP_ADC, "temp_adc", IIO_TEMP,
> +				  AXP22X_TEMP_ADC_H),
> +	AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,
> +			   AXP20X_BATT_V_H),
> +	AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,
> +			   AXP20X_BATT_CHRG_I_H),
> +	AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,
> +			   AXP20X_BATT_DISCHRG_I_H),
> +};
> +
> +static int axp20x_adc_read_raw(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *channel, int *val,
> +			       int *val2)
> +{
> +	struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +	int size = 12, ret;
> +
> +	switch (channel->channel) {
> +	case AXP20X_BATT_DISCHRG_I:
> +		size = 13;
> +	case AXP20X_ACIN_V:
> +	case AXP20X_ACIN_I:
> +	case AXP20X_VBUS_V:
> +	case AXP20X_VBUS_I:
> +	case AXP20X_TEMP_ADC:
> +	case AXP20X_BATT_V:
> +	case AXP20X_BATT_CHRG_I:
> +	case AXP20X_IPSOUT_V:
> +	case AXP20X_GPIO0_V:
> +	case AXP20X_GPIO1_V:
> +		ret = axp20x_read_variable_width(info->regmap, channel->address,
> +						 size);
> +		if (ret < 0)
> +			return ret;
> +		*val = ret;
> +		return IIO_VAL_INT;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *channel, int *val,
> +			       int *val2)
> +{
> +	struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +	int size = 12, ret;
> +
> +	switch (channel->channel) {
> +	case AXP22X_BATT_DISCHRG_I:
> +		size = 13;
> +	case AXP22X_TEMP_ADC:
> +	case AXP22X_BATT_V:
> +	case AXP22X_BATT_CHRG_I:
> +		ret = axp20x_read_variable_width(info->regmap, channel->address,
> +						 size);
> +		if (ret < 0)
> +			return ret;
> +		*val = ret;
> +		return IIO_VAL_INT;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp20x_adc_scale(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_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_TEMP_ADC:
> +		*val = 100;
> +		return IIO_VAL_INT;
> +
> +	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_BATT_DISCHRG_I:
> +	case AXP20X_BATT_CHRG_I:
> +		*val = 0;
> +		*val2 = 500000;
> +		return IIO_VAL_INT_PLUS_MICRO;
> +
> +	case AXP20X_IPSOUT_V:
> +		*val = 1;
> +		*val2 = 400000;
> +		return IIO_VAL_INT_PLUS_MICRO;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp22x_adc_scale(int channel, int *val, int *val2)
> +{
> +	switch (channel) {
> +	case AXP22X_TEMP_ADC:
> +		*val = 100;
> +		return IIO_VAL_INT;
> +
> +	case AXP22X_BATT_V:
> +		*val = 1;
> +		*val2 = 100000;
> +		return IIO_VAL_INT_PLUS_MICRO;
> +
> +	case AXP22X_BATT_DISCHRG_I:
> +	case AXP22X_BATT_CHRG_I:
> +		*val = 0;
> +		*val2 = 500000;
> +		return IIO_VAL_INT_PLUS_MICRO;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp20x_adc_offset(struct iio_dev *indio_dev, int channel, int *val)
> +{
> +	struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +	int ret, reg;
> +
> +	switch (channel) {
> +	case AXP20X_TEMP_ADC:
> +		*val = -1447;
> +		return IIO_VAL_INT;
> +
> +	case AXP20X_GPIO0_V:
> +	case AXP20X_GPIO1_V:
> +		ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, &reg);
> +		if (ret < 0)
> +			return ret;
> +
> +		if (channel == AXP20X_GPIO0_V)
> +			*val = reg & AXP20X_GPIO10_IN_RANGE_GPIO0;
> +		else
> +			*val = reg & AXP20X_GPIO10_IN_RANGE_GPIO1;
> +
> +		*val = !!(*val) * 700000;
> +
> +		return IIO_VAL_INT;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp20x_read_raw(struct iio_dev *indio_dev,
> +			   struct iio_chan_spec const *chan, int *val,
> +			   int *val2, long mask)
> +{
> +	switch (mask) {
> +	case IIO_CHAN_INFO_OFFSET:
> +		return axp20x_adc_offset(indio_dev, chan->channel, val);
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		return axp20x_adc_scale(chan->channel, val, val2);
> +
> +	case IIO_CHAN_INFO_RAW:
> +		return axp20x_adc_read_raw(indio_dev, chan, val, val2);
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp22x_read_raw(struct iio_dev *indio_dev,
> +			   struct iio_chan_spec const *chan, int *val,
> +			   int *val2, long mask)
> +{
> +	switch (mask) {
> +	case IIO_CHAN_INFO_OFFSET:
> +		*val = -2667;
> +		return IIO_VAL_INT;
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		return axp22x_adc_scale(chan->channel, val, val2);
> +
> +	case IIO_CHAN_INFO_RAW:
> +		return axp22x_adc_read_raw(indio_dev, chan, val, val2);
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int axp20x_write_raw(struct iio_dev *indio_dev,
> +			    struct iio_chan_spec const *chan, int val, int val2,
> +			    long mask)
> +{
> +	struct axp20x_adc_iio *info = iio_priv(indio_dev);
> +
> +	/*
> +	 * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets
> +	 * for (independently) GPIO0 and GPIO1 when in ADC mode.
> +	 */
> +	if (mask != IIO_CHAN_INFO_OFFSET)
> +		return -EINVAL;
> +
> +	if (chan->channel != AXP20X_GPIO0_V && chan->channel != AXP20X_GPIO1_V)
> +		return -EINVAL;
> +
> +	if (val != 0 && val != 700000)
> +		return -EINVAL;
> +
> +	if (chan->channel == AXP20X_GPIO0_V)
> +		return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
> +					  AXP20X_GPIO10_IN_RANGE_GPIO0,
> +					  AXP20X_GPIO10_IN_RANGE_GPIO0_VAL(!!val));
> +
> +	return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE,
> +				  AXP20X_GPIO10_IN_RANGE_GPIO1,
> +				  AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(!!val));
> +}
> +
> +static const struct iio_info axp20x_adc_iio_info = {
> +	.read_raw = axp20x_read_raw,
> +	.write_raw = axp20x_write_raw,
> +	.driver_module = THIS_MODULE,
> +};
> +
> +static const struct iio_info axp22x_adc_iio_info = {
> +	.read_raw = axp22x_read_raw,
> +	.driver_module = THIS_MODULE,
> +};
> +
> +static const struct of_device_id axp20x_adc_of_match[] = {
> +	{ .compatible = "x-powers,axp209-adc", .data = (void *)AXP209_ID, },
> +	{ .compatible = "x-powers,axp221-adc", .data = (void *)AXP221_ID, },
> +	{ /* sentinel */ },
> +};
> +
> +static int axp20x_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_adc_iio *info;
> +	struct iio_dev *indio_dev;
> +	struct axp20x_dev *axp20x_dev;
> +	int ret, axp20x_id;
> +
> +	axp20x_dev = dev_get_drvdata(pdev->dev.parent);
> +
> +	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	info = iio_priv(indio_dev);
> +	platform_set_drvdata(pdev, indio_dev);
> +
> +	info->regmap = axp20x_dev->regmap;
> +	info->indio_dev = indio_dev;
> +	indio_dev->name = dev_name(&pdev->dev);
> +	indio_dev->dev.parent = &pdev->dev;
> +	indio_dev->dev.of_node = pdev->dev.of_node;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	axp20x_id = (int)of_device_get_match_data(&pdev->dev);
> +
> +	switch (axp20x_id) {
> +	case AXP209_ID:
> +		indio_dev->info = &axp20x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp20x_adc_channels);
> +		indio_dev->channels = axp20x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP20X_ADC_EN1_MASK);
> +
> +		/* Enable GPIO0/1 and internal temperature ADCs */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_EN2,
> +				   AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP20X_ADC_RATE_50HZ);
> +		break;
> +
> +	case AXP221_ID:
> +		indio_dev->info = &axp22x_adc_iio_info;
> +		indio_dev->num_channels = ARRAY_SIZE(axp22x_adc_channels);
> +		indio_dev->channels = axp22x_adc_channels;
> +
> +		/* Enable the ADCs on IP */
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, AXP22X_ADC_EN1_MASK);
> +
> +		/* Configure ADCs rate */
> +		regmap_update_bits(info->regmap, AXP20X_ADC_RATE,
> +				   AXP20X_ADC_RATE_MASK, AXP22X_ADC_RATE_200HZ);
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	ret = devm_iio_device_register(&pdev->dev, indio_dev);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "could not register the device\n");
> +		regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> +		regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int axp20x_remove(struct platform_device *pdev)
> +{
> +	struct axp20x_adc_iio *info;
> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +	info = iio_priv(indio_dev);
> +	regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
> +	regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver axp20x_adc_driver = {
> +	.driver = {
> +		.name = "axp20x-adc",
> +		.of_match_table = axp20x_adc_of_match,
> +	},
> +	.probe = axp20x_probe,
> +	.remove = axp20x_remove,
> +};
> +
> +module_platform_driver(axp20x_adc_driver);
> +
> +MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index a4860bc..650c6f6 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -150,6 +150,10 @@ enum {
>  #define AXP20X_VBUS_I_ADC_L		0x5d
>  #define AXP20X_TEMP_ADC_H		0x5e
>  #define AXP20X_TEMP_ADC_L		0x5f
> +
> +#define AXP22X_TEMP_ADC_H		0x56
> +#define AXP22X_TEMP_ADC_L		0x57
> +
>  #define AXP20X_TS_IN_H			0x62
>  #define AXP20X_TS_IN_L			0x63
>  #define AXP20X_GPIO0_V_ADC_H		0x64
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05  9:50         ` Quentin Schulz
  2017-01-05 10:28           ` Chen-Yu Tsai
  2017-01-05 16:46           ` Maxime Ripard
@ 2017-01-07 19:20           ` Jonathan Cameron
  2 siblings, 0 replies; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-07 19:20 UTC (permalink / raw)
  To: Quentin Schulz, Chen-Yu Tsai
  Cc: knaack.h, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Rob Herring, Mark Rutland, Sebastian Reichel, Russell King,
	Maxime Ripard, Lee Jones, linux-iio, devicetree, linux-kernel,
	open list:THERMAL, linux-arm-kernel, Thomas Petazzoni,
	Icenowy Zheng, Bruno Prémont

On 05/01/17 04:50, Quentin Schulz wrote:
> On 05/01/2017 09:27, Chen-Yu Tsai wrote:
>> On Thu, Jan 5, 2017 at 4:06 PM, Quentin Schulz
>> <quentin.schulz@free-electrons.com> wrote:
>>> Hi Chen-Yu,
>>>
>>> On 05/01/2017 06:42, Chen-Yu Tsai wrote:
>>>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>>>> <quentin.schulz@free-electrons.com> wrote:
>>> [...]
>>>>> +
>>>>> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
>>>>> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
>>>>> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)
>>>>
>>>> Please be consistent with the format.
>>>>
>>>>> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
>>>>> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
>>>>> +
>>>>> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
>>>>> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
>>>>> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
>>>>> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)
>>>>
>>>> These are power-of-2 multiples of some base rate. May I suggest
>>>> a formula macro instead. Either way, you seem to be using only
>>>> one value. Will this be made configurable in the future?
>>>>
>>>
>>> Yes, I could use a formula macro instead. No plan to make it
>>> configurable, should I make it configurable?
>>
>> I don't see a use case for that atm.
>>
>>>>> +
>>>>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
>>>>> +       {                                                       \
>>>>> +               .type = _type,                                  \
>>>>> +               .indexed = 1,                                   \
>>>>> +               .channel = _channel,                            \
>>>>> +               .address = _reg,                                \
>>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>>> +                                     BIT(IIO_CHAN_INFO_SCALE), \
>>>>> +               .datasheet_name = _name,                        \
>>>>> +       }
>>>>> +
>>>>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>>>>> +       {                                                       \
>>>>> +               .type = _type,                                  \
>>>>> +               .indexed = 1,                                   \
>>>>> +               .channel = _channel,                            \
>>>>> +               .address = _reg,                                \
>>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>>> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
>>>>> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
>>>>> +               .datasheet_name = _name,                        \
>>>>> +       }
>>>>> +
>>>>> +struct axp20x_adc_iio {
>>>>> +       struct iio_dev          *indio_dev;
>>>>> +       struct regmap           *regmap;
>>>>> +};
>>>>> +
>>>>> +enum axp20x_adc_channel {
>>>>> +       AXP20X_ACIN_V = 0,
>>>>> +       AXP20X_ACIN_I,
>>>>> +       AXP20X_VBUS_V,
>>>>> +       AXP20X_VBUS_I,
>>>>> +       AXP20X_TEMP_ADC,
>>>>
>>>> PMIC_TEMP would be better. And please save a slot for TS input.
>>>>
>>>
>>> ACK.
>>>
>>> Hum.. I'm wondering what should be the IIO type of the TS input channel
>>> then? The TS Pin can be used in two modes: either to monitor the
>>> temperature of the battery or as an external ADC, at least that's what I
>>> understand from the datasheet.
>>
>> AFAIK the battery charge/discharge high/low temperature threshold
>> registers take values in terms of voltage, not actual temperature.
>> And the temperature readout kind of depends on the thermoresistor
>> one is using. So I think "voltage" would be the proper type.
>>
> 
> ACK. Should I just add TS_IN in axp20x_adc_channel enum but not add it
> in the exposed IIO channels ("saving" the slot but not using it)?
Ideally we'd put an IIO consumer driver on the channel that handles the
thermoresistor explicitly.  Would need consumer support for events
though to be much use.
> 
>>>
>>>>> +       AXP20X_GPIO0_V,
>>>>> +       AXP20X_GPIO1_V,
>>>>
>>>> Please skip a slot for "battery instantaneous power".
>>>>
>>>>> +       AXP20X_BATT_V,
>>>>> +       AXP20X_BATT_CHRG_I,
>>>>> +       AXP20X_BATT_DISCHRG_I,
>>>>> +       AXP20X_IPSOUT_V,
>>>>> +};
>>>>> +
>>>>> +enum axp22x_adc_channel {
>>>>> +       AXP22X_TEMP_ADC = 0,
>>>>
>>>> Same comments as AXP20X_TEMP_ADC.
>>>>
>>>>> +       AXP22X_BATT_V,
>>>>> +       AXP22X_BATT_CHRG_I,
>>>>> +       AXP22X_BATT_DISCHRG_I,
>>>>> +};
>>>>
>>>> Shouldn't these channel numbers be exported as part of the device tree
>>>> bindings? At the very least, they shouldn't be changed.
>>>>
>>>
>>> I don't understand what you mean by that. Do you mean you want a
>>> consistent numbering between the AXP20X and the AXP22X, so that
>>> AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?
>>>
>>> Could you explain a bit more your thoughts on the channel numbers being
>>> exported as part of the device tree bindings?
>>
>> What I meant was that, since you are referencing the channels in the
>> device tree, the numbering scheme would be part of the device tree
>> binding, and should never be changed. So either these would be macros
>> in include/dt-bindings/, or a big warning should be put before it.
>>
> 
> ACK.
> 
>> But see my reply on patch 7, about do we actually need to expose this
>> in the device tree.
>>
> 
> I don't know what's the best.
> 
>>>> Also please add a comment saying that the channels are numbered
>>>> in the order of their respective registers, and not the table
>>>> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
>>>> and 9.5 E-Gauge for AXP221).
>>>>
>>>
>>> Yes I can.
>>>
>>> What about Rob wanting channel numbers to start at zero for each
>>> different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
>>> exported as in_current1_raw whereas he wants in_current0_raw).
>>
>> Hmm... I missed this. Are you talking about IIO or hwmon? IIRC
>> hwmon numbers things starting at 1.
>>
> 
> About IIO.
> 
> Today, we have exposed:
> in_voltage0_raw for acin_v
> in_current1_raw for acin_i
> in_voltage2_raw for vbus_v
> in_current3_raw for vbus_i
> in_temp4_raw for adc_temp
> in_voltage5_raw for gpio0_v
> in_voltage6_raw for gpio1_v
> in_voltage7_raw for batt_v
> in_current8_raw for batt_chrg_i
> in_current9_raw for batt_dischrg_i
> in_voltage10_raw for ipsout_v
> 
> but I think what Rob wants is:
> 
> in_voltage0_raw acin_v
> in_current0_raw for acin_i
> in_voltage1_raw for vbus_v
> in_current1_raw for vbus_i
> in_temp_raw for adc_temp
> in_voltage2_raw for gpio0_v
> in_voltage3_raw for gpio1_v
> in_voltage4_raw for batt_v
> in_current2_raw for batt_chrg_i
> in_current3_raw for batt_dischrg_i
> in_voltage5_raw for ipsout_v
That would be standard choice.  It's not disastrous to skip numbers but
it tends to not be what userspace expects.
> 
>>> [...]
>>>>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>>>>> +                              struct iio_chan_spec const *channel, int *val,
>>>>> +                              int *val2)
>>>>> +{
>>>>> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
>>>>> +       int size = 12, ret;
>>>>> +
>>>>> +       switch (channel->channel) {
>>>>> +       case AXP22X_BATT_DISCHRG_I:
>>>>> +               size = 13;
>>>>> +       case AXP22X_TEMP_ADC:
>>>>> +       case AXP22X_BATT_V:
>>>>> +       case AXP22X_BATT_CHRG_I:
>>>>
>>>> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
>>>>
>>>
>>> Where did you get that?
>>>
>>> Also, the datasheet is inconsistent:
>>>  - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
>>> value at 0xfff for all channels, that's 12 bits.
>>>  - 10.1.4 ADC Data => all channels except battery discharge current are
>>> on 12 bits (8 high, 4 low).
>>
>> My datasheets (AXP221 v1.6, AXP221s v1.2, AXP223 v1.1, all Chinese) say
>> in 10.1.4:
>>
>>   - 7A: battery charge current high 5 bits
>>   - 7B: battery charge current low 8 bits
>>   - 7C: battery discharge current high 5 bits
>>   - 7D: battery discharge current low 8 bits
>>
> 
> AXP223 v1.1 in English in 10.1.4[1]:
>     - 7A: battery charge current high 8 bits
>     - 7B: battery charge current low 4 bits
>     - 7C: battery discharge current high 8 bits
>     - 7D: battery discharge current low 5 bits
> 
> Note that it's 8 bits for high and 4/5 bits for low while you wrote 4/5
> bits high and low 8 bits (typos or actually what's written in the
> datasheet?).
> 
> Hum.. from the reg reading function[2] I would say that the correct
> formula is high on 8 bits and low on 4/5 bits.
> 
> So hum.. what do we do?
> 
> [1] http://dl.linux-sunxi.org/AXP/AXP223-en.pdf
> [2] http://lxr.free-electrons.com/source/include/linux/mfd/axp20x.h#L564
> 
>>>
>>> [...]
>>>>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>>>>> +                          struct iio_chan_spec const *chan, int *val,
>>>>> +                          int *val2, long mask)
>>>>> +{
>>>>> +       switch (mask) {
>>>>> +       case IIO_CHAN_INFO_OFFSET:
>>>>> +               *val = -2667;
>>>>
>>>> Datasheet says -267.7 C, or -2677 here.
>>>>
>>>
>>> The formula in the datasheet is (in milli Celsius):
>>>  processed = raw * 100 - 266700;
>>>
>>> while the IIO framework asks for a scale and an offset which are then
>>> applied as:
>>>  processed = (raw + offset) * scale;
>>>
>>> Thus by factorizing, we get:
>>>  processed = (raw - 2667) * 100;
>>
>> What I meant was that your lower end value is off by one degree,
>> -266.7 in your code vs -267.7 in the datasheet.
>>
> 
> Indeed. Thanks.
> 
>>>
>>> [...]
>>>>> +static int axp20x_remove(struct platform_device *pdev)
>>>>> +{
>>>>> +       struct axp20x_adc_iio *info;
>>>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>>>> +
>>>>> +       info = iio_priv(indio_dev);
>>>>
>>>> Nit: you could just reverse the 2 declarations above and join this
>>>> line after struct axp20x_adc_iio *info;
>>>>
>>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
>>>>
>>>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
>>>> and does not check them later on. This means if one were to remove this
>>>> axp20x-adc module, the voltage/current readings in the VBUS power supply
>>>> would be invalid. Some sort of workaround would be needed here in this
>>>> driver of the VBUS driver.
>>>>
>>>
>>> That would be one reason to migrate the VBUS driver to use the IIO
>>> channels, wouldn't it?
>>
>> It is, preferably without changing the device tree.
>>
> 
> Yes, of course.
> 
> Thanks,
> Quentin
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
  2017-01-05 10:28           ` Chen-Yu Tsai
@ 2017-01-07 19:23             ` Jonathan Cameron
  0 siblings, 0 replies; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-07 19:23 UTC (permalink / raw)
  To: Chen-Yu Tsai, Quentin Schulz
  Cc: knaack.h, Lars-Peter Clausen, Peter Meerwald-Stadler,
	Rob Herring, Mark Rutland, Sebastian Reichel, Russell King,
	Maxime Ripard, Lee Jones, linux-iio, devicetree, linux-kernel,
	open list:THERMAL, linux-arm-kernel, Thomas Petazzoni,
	Icenowy Zheng, Bruno Prémont

On 05/01/17 05:28, Chen-Yu Tsai wrote:
> On Thu, Jan 5, 2017 at 5:50 PM, Quentin Schulz
> <quentin.schulz@free-electrons.com> wrote:
>> On 05/01/2017 09:27, Chen-Yu Tsai wrote:
>>> On Thu, Jan 5, 2017 at 4:06 PM, Quentin Schulz
>>> <quentin.schulz@free-electrons.com> wrote:
>>>> Hi Chen-Yu,
>>>>
>>>> On 05/01/2017 06:42, Chen-Yu Tsai wrote:
>>>>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>>>>> <quentin.schulz@free-electrons.com> wrote:
>>>> [...]
>>>>>> +
>>>>>> +#define AXP20X_ADC_RATE_MASK                   (3 << 6)
>>>>>> +#define AXP20X_ADC_RATE_25HZ                   (0 << 6)
>>>>>> +#define AXP20X_ADC_RATE_50HZ                   BIT(6)
>>>>>
>>>>> Please be consistent with the format.
>>>>>
>>>>>> +#define AXP20X_ADC_RATE_100HZ                  (2 << 6)
>>>>>> +#define AXP20X_ADC_RATE_200HZ                  (3 << 6)
>>>>>> +
>>>>>> +#define AXP22X_ADC_RATE_100HZ                  (0 << 6)
>>>>>> +#define AXP22X_ADC_RATE_200HZ                  BIT(6)
>>>>>> +#define AXP22X_ADC_RATE_400HZ                  (2 << 6)
>>>>>> +#define AXP22X_ADC_RATE_800HZ                  (3 << 6)
>>>>>
>>>>> These are power-of-2 multiples of some base rate. May I suggest
>>>>> a formula macro instead. Either way, you seem to be using only
>>>>> one value. Will this be made configurable in the future?
>>>>>
>>>>
>>>> Yes, I could use a formula macro instead. No plan to make it
>>>> configurable, should I make it configurable?
>>>
>>> I don't see a use case for that atm.
>>>
>>>>>> +
>>>>>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)       \
>>>>>> +       {                                                       \
>>>>>> +               .type = _type,                                  \
>>>>>> +               .indexed = 1,                                   \
>>>>>> +               .channel = _channel,                            \
>>>>>> +               .address = _reg,                                \
>>>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>>>> +                                     BIT(IIO_CHAN_INFO_SCALE), \
>>>>>> +               .datasheet_name = _name,                        \
>>>>>> +       }
>>>>>> +
>>>>>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>>>>>> +       {                                                       \
>>>>>> +               .type = _type,                                  \
>>>>>> +               .indexed = 1,                                   \
>>>>>> +               .channel = _channel,                            \
>>>>>> +               .address = _reg,                                \
>>>>>> +               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
>>>>>> +                                     BIT(IIO_CHAN_INFO_SCALE) |\
>>>>>> +                                     BIT(IIO_CHAN_INFO_OFFSET),\
>>>>>> +               .datasheet_name = _name,                        \
>>>>>> +       }
>>>>>> +
>>>>>> +struct axp20x_adc_iio {
>>>>>> +       struct iio_dev          *indio_dev;
>>>>>> +       struct regmap           *regmap;
>>>>>> +};
>>>>>> +
>>>>>> +enum axp20x_adc_channel {
>>>>>> +       AXP20X_ACIN_V = 0,
>>>>>> +       AXP20X_ACIN_I,
>>>>>> +       AXP20X_VBUS_V,
>>>>>> +       AXP20X_VBUS_I,
>>>>>> +       AXP20X_TEMP_ADC,
>>>>>
>>>>> PMIC_TEMP would be better. And please save a slot for TS input.
>>>>>
>>>>
>>>> ACK.
>>>>
>>>> Hum.. I'm wondering what should be the IIO type of the TS input channel
>>>> then? The TS Pin can be used in two modes: either to monitor the
>>>> temperature of the battery or as an external ADC, at least that's what I
>>>> understand from the datasheet.
>>>
>>> AFAIK the battery charge/discharge high/low temperature threshold
>>> registers take values in terms of voltage, not actual temperature.
>>> And the temperature readout kind of depends on the thermoresistor
>>> one is using. So I think "voltage" would be the proper type.
>>>
>>
>> ACK. Should I just add TS_IN in axp20x_adc_channel enum but not add it
>> in the exposed IIO channels ("saving" the slot but not using it)?
> 
> Sure. Or you could skip the number with
> 
>     AXP20X_GPIO0_V = 6,
> 
>>>>
>>>>>> +       AXP20X_GPIO0_V,
>>>>>> +       AXP20X_GPIO1_V,
>>>>>
>>>>> Please skip a slot for "battery instantaneous power".
>>>>>
>>>>>> +       AXP20X_BATT_V,
>>>>>> +       AXP20X_BATT_CHRG_I,
>>>>>> +       AXP20X_BATT_DISCHRG_I,
>>>>>> +       AXP20X_IPSOUT_V,
>>>>>> +};
>>>>>> +
>>>>>> +enum axp22x_adc_channel {
>>>>>> +       AXP22X_TEMP_ADC = 0,
>>>>>
>>>>> Same comments as AXP20X_TEMP_ADC.
>>>>>
>>>>>> +       AXP22X_BATT_V,
>>>>>> +       AXP22X_BATT_CHRG_I,
>>>>>> +       AXP22X_BATT_DISCHRG_I,
>>>>>> +};
>>>>>
>>>>> Shouldn't these channel numbers be exported as part of the device tree
>>>>> bindings? At the very least, they shouldn't be changed.
>>>>>
>>>>
>>>> I don't understand what you mean by that. Do you mean you want a
>>>> consistent numbering between the AXP20X and the AXP22X, so that
>>>> AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?
>>>>
>>>> Could you explain a bit more your thoughts on the channel numbers being
>>>> exported as part of the device tree bindings?
>>>
>>> What I meant was that, since you are referencing the channels in the
>>> device tree, the numbering scheme would be part of the device tree
>>> binding, and should never be changed. So either these would be macros
>>> in include/dt-bindings/, or a big warning should be put before it.
>>>
>>
>> ACK.
>>
>>> But see my reply on patch 7, about do we actually need to expose this
>>> in the device tree.
>>>
>>
>> I don't know what's the best.
> 
> Then let's not expose it in the device tree for now. It's easier to
> add it later than to remove it.
> 
>>
>>>>> Also please add a comment saying that the channels are numbered
>>>>> in the order of their respective registers, and not the table
>>>>> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
>>>>> and 9.5 E-Gauge for AXP221).
>>>>>
>>>>
>>>> Yes I can.
>>>>
>>>> What about Rob wanting channel numbers to start at zero for each
>>>> different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
>>>> exported as in_current1_raw whereas he wants in_current0_raw).
>>>
>>> Hmm... I missed this. Are you talking about IIO or hwmon? IIRC
>>> hwmon numbers things starting at 1.
>>>
>>
>> About IIO.
>>
>> Today, we have exposed:
>> in_voltage0_raw for acin_v
>> in_current1_raw for acin_i
>> in_voltage2_raw for vbus_v
>> in_current3_raw for vbus_i
>> in_temp4_raw for adc_temp
>> in_voltage5_raw for gpio0_v
>> in_voltage6_raw for gpio1_v
>> in_voltage7_raw for batt_v
>> in_current8_raw for batt_chrg_i
>> in_current9_raw for batt_dischrg_i
>> in_voltage10_raw for ipsout_v
>>
>> but I think what Rob wants is:
>>
>> in_voltage0_raw acin_v
>> in_current0_raw for acin_i
>> in_voltage1_raw for vbus_v
>> in_current1_raw for vbus_i
>> in_temp_raw for adc_temp
>> in_voltage2_raw for gpio0_v
>> in_voltage3_raw for gpio1_v
>> in_voltage4_raw for batt_v
>> in_current2_raw for batt_chrg_i
>> in_current3_raw for batt_dischrg_i
>> in_voltage5_raw for ipsout_v
> 
> I think that's doable. If I understand IIO code correctly, the channel
> number is not used anywhere in the core code for dereferencing. It's
> used for sysfs entries (when .indexed is set) and events. However
> the twl4030 and twl6030 drivers use our current exposed scheme.
> I suppose its best to get some input from the IIO maintainer.
If we are doing it to superficially group channels that are measuring
different things about the same physical system then I'm fine with
mappings with holes in them.

It's not actually specified anywhere that we can't allow this and
IIRC there are a few drivers doing exactly this.
> 
> So if we want, we could have the following channel mapping:
> 
>   0 -> acin
>   1 -> vbus
>   2 -> pmic
>   3 -> gpio0
>   4 -> gpio1
>   5 -> ipsout
>   6 -> battery
> 
> Each channel could have mulitple entries in axp20x_adc_channels[],
> one for each type of reading. You might need multiple channels for
> the battery to cover charge and discharge currents.
> 
> Your callback functions would get a bit messier though.
> 
>>
>>>> [...]
>>>>>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>>>>>> +                              struct iio_chan_spec const *channel, int *val,
>>>>>> +                              int *val2)
>>>>>> +{
>>>>>> +       struct axp20x_adc_iio *info = iio_priv(indio_dev);
>>>>>> +       int size = 12, ret;
>>>>>> +
>>>>>> +       switch (channel->channel) {
>>>>>> +       case AXP22X_BATT_DISCHRG_I:
>>>>>> +               size = 13;
>>>>>> +       case AXP22X_TEMP_ADC:
>>>>>> +       case AXP22X_BATT_V:
>>>>>> +       case AXP22X_BATT_CHRG_I:
>>>>>
>>>>> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
>>>>>
>>>>
>>>> Where did you get that?
>>>>
>>>> Also, the datasheet is inconsistent:
>>>>  - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
>>>> value at 0xfff for all channels, that's 12 bits.
>>>>  - 10.1.4 ADC Data => all channels except battery discharge current are
>>>> on 12 bits (8 high, 4 low).
>>>
>>> My datasheets (AXP221 v1.6, AXP221s v1.2, AXP223 v1.1, all Chinese) say
>>> in 10.1.4:
>>>
>>>   - 7A: battery charge current high 5 bits
>>>   - 7B: battery charge current low 8 bits
>>>   - 7C: battery discharge current high 5 bits
>>>   - 7D: battery discharge current low 8 bits
>>>
>>
>> AXP223 v1.1 in English in 10.1.4[1]:
>>     - 7A: battery charge current high 8 bits
>>     - 7B: battery charge current low 4 bits
>>     - 7C: battery discharge current high 8 bits
>>     - 7D: battery discharge current low 5 bits
>>
>> Note that it's 8 bits for high and 4/5 bits for low while you wrote 4/5
>> bits high and low 8 bits (typos or actually what's written in the
>> datasheet?).
> 
> Typo on my end, sorry. It's high 8bits and low 5/4 bits.
> 
> Apart from that, the Chinese and English versions don't match for the
> battery charge current. :(
> 
> Would it be possible for you to test this? As in, have the module running,
> and charging a battery, and have a multimeter in series with the battery
> to verify the readings.
> 
> Regards
> ChenYu
> 
>>
>> Hum.. from the reg reading function[2] I would say that the correct
>> formula is high on 8 bits and low on 4/5 bits.
>>
>> So hum.. what do we do?
>>
>> [1] http://dl.linux-sunxi.org/AXP/AXP223-en.pdf
>> [2] http://lxr.free-electrons.com/source/include/linux/mfd/axp20x.h#L564
>>
>>>>
>>>> [...]
>>>>>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>>>>>> +                          struct iio_chan_spec const *chan, int *val,
>>>>>> +                          int *val2, long mask)
>>>>>> +{
>>>>>> +       switch (mask) {
>>>>>> +       case IIO_CHAN_INFO_OFFSET:
>>>>>> +               *val = -2667;
>>>>>
>>>>> Datasheet says -267.7 C, or -2677 here.
>>>>>
>>>>
>>>> The formula in the datasheet is (in milli Celsius):
>>>>  processed = raw * 100 - 266700;
>>>>
>>>> while the IIO framework asks for a scale and an offset which are then
>>>> applied as:
>>>>  processed = (raw + offset) * scale;
>>>>
>>>> Thus by factorizing, we get:
>>>>  processed = (raw - 2667) * 100;
>>>
>>> What I meant was that your lower end value is off by one degree,
>>> -266.7 in your code vs -267.7 in the datasheet.
>>>
>>
>> Indeed. Thanks.
>>
>>>>
>>>> [...]
>>>>>> +static int axp20x_remove(struct platform_device *pdev)
>>>>>> +{
>>>>>> +       struct axp20x_adc_iio *info;
>>>>>> +       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>>>>> +
>>>>>> +       info = iio_priv(indio_dev);
>>>>>
>>>>> Nit: you could just reverse the 2 declarations above and join this
>>>>> line after struct axp20x_adc_iio *info;
>>>>>
>>>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>>>>>> +       regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
>>>>>
>>>>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
>>>>> and does not check them later on. This means if one were to remove this
>>>>> axp20x-adc module, the voltage/current readings in the VBUS power supply
>>>>> would be invalid. Some sort of workaround would be needed here in this
>>>>> driver of the VBUS driver.
>>>>>
>>>>
>>>> That would be one reason to migrate the VBUS driver to use the IIO
>>>> channels, wouldn't it?
>>>
>>> It is, preferably without changing the device tree.
>>>
>>
>> Yes, of course.
>>
>> Thanks,
>> Quentin
>>
>> --
>> Quentin Schulz, Free Electrons
>> Embedded Linux and Kernel engineering
>> http://free-electrons.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply
  2017-01-05  6:17     ` Chen-Yu Tsai
@ 2017-01-07 19:26       ` Jonathan Cameron
  0 siblings, 0 replies; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-07 19:26 UTC (permalink / raw)
  To: Chen-Yu Tsai, Quentin Schulz
  Cc: Rob Herring, knaack.h, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Mark Rutland, Sebastian Reichel,
	Russell King, Maxime Ripard, Lee Jones, linux-iio, devicetree,
	linux-kernel, open list:THERMAL, linux-arm-kernel,
	Thomas Petazzoni, Icenowy Zheng, Bruno Prémont

On 05/01/17 01:17, Chen-Yu Tsai wrote:
> Hi Quentin,
> 
> On Wed, Jan 4, 2017 at 9:14 PM, Rob Herring <robh@kernel.org> wrote:
>> On Mon, Jan 02, 2017 at 05:37:07PM +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 <quentin.schulz@free-electrons.com>
>>> ---
>>>  .../bindings/power/supply/axp20x_ac_power.txt      | 28 ++++++++++++++++++++++
>>>  1 file changed, 28 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
>>> new file mode 100644
>>> index 0000000..16d0de4
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
>>> @@ -0,0 +1,28 @@
>>> +AXP20X and AXP22X PMICs' AC power supply
>>> +
>>> +Required Properties:
>>> + - compatible: One of:
>>> +                     "x-powers,axp202-ac-power-supply"
>>> +                     "x-powers,axp221-ac-power-supply"
>>> +
>>> +More Required Properties for AXP20X PMICs:
>>> + - io-channels: phandles to ACIN voltage and current ADC channels
>>> + - io-channel-names = "acin_v", "acin_i";
>>> +
>>> +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 {
>>
>> power-supply {
>>
>>> +             compatible = "x-powers,axp202-ac-power-supply";
>>> +             io-channels = <&axp209_adc 0>, <&axp209_adc 1>;
>>
>> Is this assignment fixed? If so, then it doesn't need to be in DT.
> 
> Is there any case that we actually need to use the IIO channels
> from the device tree? Seems to me its limited to the other AXP
> sub-devices.
> 
> If so you could use struct iio_map to map the channels to other
> devices by name. See axp288_adc for an example.
Agreed. When we are within a device (so it's not flexible) that
is the way to go.
> 
> Regards
> ChenYu
> 
>>> +             io-channel-names = "acin_v", "acin_i";
>>> +     };
>>> +};
>>> --
>>> 2.9.3
>>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs Quentin Schulz
@ 2017-01-07 19:31   ` Jonathan Cameron
  2017-01-08 10:41     ` Quentin Schulz
  2017-01-17  3:00   ` Sebastian Reichel
  1 sibling, 1 reply; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-07 19:31 UTC (permalink / raw)
  To: Quentin Schulz, knaack.h, lars, pmeerw, robh+dt, mark.rutland,
	wens, sre, linux, maxime.ripard, lee.jones
  Cc: linux-iio, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	thomas.petazzoni, icenowy, bonbons

On 02/01/17 11:37, 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 <quentin.schulz@free-electrons.com>
For the IIO bits
Acked-by: Jonathan Cameron <jic23@kernel.org>

Trivial comment inline.
> ---
>  drivers/power/supply/Kconfig           |  12 ++
>  drivers/power/supply/Makefile          |   1 +
>  drivers/power/supply/axp20x_ac_power.c | 251 +++++++++++++++++++++++++++++++++
>  3 files changed, 264 insertions(+)
>  create mode 100644 drivers/power/supply/axp20x_ac_power.c
> 
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index 76806a0..c552b4b 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -214,6 +214,18 @@ config BATTERY_DA9150
>  	  This driver can also be built as a module. If so, the module will be
>  	  called da9150-fg.
>  
> +config CHARGER_AXP20X
> +	tristate "X-Powers AXP20X and AXP22X AC power supply driver"
> +	depends on MFD_AXP20X
> +	depends on AXP20X_ADC
> +	depends on IIO
> +	help
> +	  Say Y here to enable support for X-Powers AXP20X and AXP22X PMICs' AC
> +	  power supply.
> +
> +	  This driver can also be built as a module. If so, the module will be
> +	  called axp20x_ac_power.
> +
>  config AXP288_CHARGER
>  	tristate "X-Powers AXP288 Charger"
>  	depends on MFD_AXP20X && EXTCON_AXP288
> diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> index 36c599d..7d22417 100644
> --- a/drivers/power/supply/Makefile
> +++ b/drivers/power/supply/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_TEST_POWER)	+= test_power.o
>  
>  obj-$(CONFIG_BATTERY_88PM860X)	+= 88pm860x_battery.o
>  obj-$(CONFIG_BATTERY_ACT8945A)	+= act8945a_charger.o
> +obj-$(CONFIG_CHARGER_AXP20X)	+= axp20x_ac_power.o
>  obj-$(CONFIG_BATTERY_DS2760)	+= ds2760_battery.o
>  obj-$(CONFIG_BATTERY_DS2780)	+= ds2780_battery.o
>  obj-$(CONFIG_BATTERY_DS2781)	+= ds2781_battery.o
> diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
> new file mode 100644
> index 0000000..d7bc25c
> --- /dev/null
> +++ b/drivers/power/supply/axp20x_ac_power.c
> @@ -0,0 +1,251 @@
> +/*
> + * AXP20X and AXP22X PMICs' ACIN power supply driver
> + *
> + * Copyright (C) 2016 Free Electrons
> + *	Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under  the terms of the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the License, or (at your
> + * option) any later version.
> + */
> +
> +#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"
> +
> +struct axp20x_ac_power {
> +	struct device_node *np;
> +	struct regmap *regmap;
> +	struct power_supply *supply;
> +	int axp20x_id;
> +	struct iio_channel *acin_v;
> +	struct iio_channel *acin_i;
> +};
> +
> +static irqreturn_t axp20x_ac_power_irq(int irq, void *devid)
> +{
> +	struct axp20x_ac_power *power = devid;
> +
> +	power_supply_changed(power->supply);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int axp20x_ac_power_get_property(struct power_supply *psy,
> +					enum power_supply_property psp,
> +					union power_supply_propval *val)
> +{
> +	struct axp20x_ac_power *power = power_supply_get_drvdata(psy);
> +	int ret, reg;
> +
> +	switch (psp) {
> +	case POWER_SUPPLY_PROP_HEALTH:
> +		ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &reg);
> +		if (ret)
> +			return ret;
> +
> +		if (reg & AXP20X_PWR_STATUS_ACIN_PRESENT) {
> +			val->intval = POWER_SUPPLY_HEALTH_GOOD;
> +			return 0;
> +		}
> +
> +		val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
> +		return 0;
> +
> +	case POWER_SUPPLY_PROP_PRESENT:
> +		ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &reg);
> +		if (ret)
> +			return ret;
> +
> +		val->intval = !!(reg & AXP20X_PWR_STATUS_ACIN_PRESENT);
> +		return 0;
> +
> +	case POWER_SUPPLY_PROP_ONLINE:
> +		ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &reg);
> +		if (ret)
> +			return ret;
> +
> +		val->intval = !!(reg & AXP20X_PWR_STATUS_ACIN_AVAIL);
> +		return 0;
> +
> +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +		ret = iio_read_channel_processed(power->acin_v, &val->intval);
> +		if (ret)
> +			return ret;
> +
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives µV.
> +		 */
single line comment syntax throughout or we'll have to face a patch 'fixing' it.
> +		val->intval *= 1000;
> +
> +		return 0;
> +
> +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> +		ret = iio_read_channel_processed(power->acin_i, &val->intval);
> +		if (ret)
> +			return ret;
> +
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives µV.
> +		 */
> +		val->intval *= 1000;
> +
> +		return 0;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static enum power_supply_property axp20x_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,
> +};
> +
> +static enum power_supply_property axp22x_ac_power_properties[] = {
> +	POWER_SUPPLY_PROP_HEALTH,
> +	POWER_SUPPLY_PROP_PRESENT,
> +	POWER_SUPPLY_PROP_ONLINE,
> +};
> +
> +static const struct power_supply_desc axp20x_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,
> +};
> +
> +static const struct power_supply_desc axp22x_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,
> +};
> +
> +static int axp20x_ac_power_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +	struct power_supply_config psy_cfg = {};
> +	struct axp20x_ac_power *power;
> +	static const char * const axp20x_irq_names[] = { "ACIN_PLUGIN",
> +		"ACIN_REMOVAL", NULL };
> +	static const char * const *irq_names;
> +	const struct power_supply_desc *ac_power_desc;
> +	int i, 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;
> +
> +	power->axp20x_id = (int)of_device_get_match_data(&pdev->dev);
> +
> +	irq_names = axp20x_irq_names;
> +
> +	if (power->axp20x_id == AXP202_ID) {
> +		ac_power_desc = &axp20x_ac_power_desc;
> +
> +		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;
> +			return PTR_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;
> +			return PTR_ERR(power->acin_i);
> +		}
> +	} else {
> +		ac_power_desc = &axp22x_ac_power_desc;
> +	}
> +
> +	power->np = pdev->dev.of_node;
> +	power->regmap = axp20x->regmap;
> +
> +	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, ac_power_desc,
> +						   &psy_cfg);
> +	if (IS_ERR(power->supply))
> +		return PTR_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);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id axp20x_ac_power_match[] = {
> +	{
> +		.compatible = "x-powers,axp202-ac-power-supply",
> +		.data = (void *)AXP202_ID,
> +	}, {
> +		.compatible = "x-powers,axp221-ac-power-supply",
> +		.data = (void *)AXP221_ID,
> +	}, { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, axp20x_ac_power_match);
> +
> +static struct platform_driver axp20x_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");
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding
  2017-01-04 13:21   ` Rob Herring
@ 2017-01-07 19:33     ` Jonathan Cameron
  2017-01-08 10:48       ` Quentin Schulz
  0 siblings, 1 reply; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-07 19:33 UTC (permalink / raw)
  To: Rob Herring, Quentin Schulz
  Cc: knaack.h, lars, pmeerw, mark.rutland, wens, sre, linux,
	maxime.ripard, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On 04/01/17 08:21, Rob Herring wrote:
> On Mon, Jan 02, 2017 at 05:37:14PM +0100, Quentin Schulz wrote:
>> 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 <quentin.schulz@free-electrons.com>
>> ---
>>  .../bindings/power/supply/axp20x_battery.txt       | 27 ++++++++++++++++++++++
>>  1 file changed, 27 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>
>> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>> new file mode 100644
>> index 0000000..5489d0d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>> @@ -0,0 +1,27 @@
>> +AXP20x and AXP22x battery power supply
>> +
>> +Required Properties:
>> + - compatible, one of:
>> +			"x-powers,axp209-battery-power-supply"
>> +			"x-powers,axp221-battery-power-supply"
>> + - io-channels: phandles to battery voltage, charge and discharge
>> + currents ADC channels
>> + - io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
>> +
>> +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 {
> 
> Humm, I guess you power-supply is not sufficient, so 
> 'battery-power-supply' and similar for ac.
> 
>> +		compatible = "x-powers,axp209-battery-power-supply";
>> +		io-channels = <&axp209_adc 7>, <&axp209_adc 8>,
>> +			<&axp209_adc 9>;
>> +		io-channel-names = "batt_v", "batt_chrg_i",
>> +			"batt_dischrg_i";
Is this stuff fixed for the device?
>> +	}
>> +};
>> -- 
>> 2.9.3
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-07 19:31   ` Jonathan Cameron
@ 2017-01-08 10:41     ` Quentin Schulz
  0 siblings, 0 replies; 72+ messages in thread
From: Quentin Schulz @ 2017-01-08 10:41 UTC (permalink / raw)
  To: Jonathan Cameron, knaack.h, lars, pmeerw, robh+dt, mark.rutland,
	wens, sre, linux, maxime.ripard, lee.jones
  Cc: linux-iio, devicetree, linux-kernel, linux-pm, linux-arm-kernel,
	thomas.petazzoni, icenowy, bonbons

Hi Jonathan,

On 07/01/2017 20:31, Jonathan Cameron wrote:
> On 02/01/17 11:37, Quentin Schulz wrote:
[...]
>> +		/*
>> +		 * IIO framework gives mV but Power Supply framework gives µV.
>> +		 */
> single line comment syntax throughout or we'll have to face a patch 'fixing' it.

I actually had to make it a multiple lines comment to make checkpatch
happy. Maybe there is something with the encoding of the µ symbol? I'll
retry with a u instead and let you know.

[...]

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding
  2017-01-07 19:33     ` Jonathan Cameron
@ 2017-01-08 10:48       ` Quentin Schulz
  2017-01-08 10:59         ` Jonathan Cameron
  0 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-08 10:48 UTC (permalink / raw)
  To: Jonathan Cameron, Rob Herring
  Cc: knaack.h, lars, pmeerw, mark.rutland, wens, sre, linux,
	maxime.ripard, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

Hi Jonathan,

On 07/01/2017 20:33, Jonathan Cameron wrote:
> On 04/01/17 08:21, Rob Herring wrote:
>> On Mon, Jan 02, 2017 at 05:37:14PM +0100, Quentin Schulz wrote:
>>> 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 <quentin.schulz@free-electrons.com>
>>> ---
>>>  .../bindings/power/supply/axp20x_battery.txt       | 27 ++++++++++++++++++++++
>>>  1 file changed, 27 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>> new file mode 100644
>>> index 0000000..5489d0d
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>> @@ -0,0 +1,27 @@
>>> +AXP20x and AXP22x battery power supply
>>> +
>>> +Required Properties:
>>> + - compatible, one of:
>>> +			"x-powers,axp209-battery-power-supply"
>>> +			"x-powers,axp221-battery-power-supply"
>>> + - io-channels: phandles to battery voltage, charge and discharge
>>> + currents ADC channels
>>> + - io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
>>> +
>>> +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 {
>>
>> Humm, I guess you power-supply is not sufficient, so 
>> 'battery-power-supply' and similar for ac.
>>
>>> +		compatible = "x-powers,axp209-battery-power-supply";
>>> +		io-channels = <&axp209_adc 7>, <&axp209_adc 8>,
>>> +			<&axp209_adc 9>;
>>> +		io-channel-names = "batt_v", "batt_chrg_i",
>>> +			"batt_dischrg_i";
> Is this stuff fixed for the device?

If we don't mix the IIO channels order, it is. This driver only requires
batt_v, batt_chrg_i and batt_dischrg_i so we've to keep them at that
place in the list of IIO channels. Or as suggested by Rob and Chen-Yu, I
can move all this inside the driver with iio_map and don't care anymore
about the order.

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding
  2017-01-08 10:48       ` Quentin Schulz
@ 2017-01-08 10:59         ` Jonathan Cameron
  0 siblings, 0 replies; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-08 10:59 UTC (permalink / raw)
  To: Quentin Schulz, Rob Herring
  Cc: knaack.h, lars, pmeerw, mark.rutland, wens, sre, linux,
	maxime.ripard, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On 08/01/17 10:48, Quentin Schulz wrote:
> Hi Jonathan,
> 
> On 07/01/2017 20:33, Jonathan Cameron wrote:
>> On 04/01/17 08:21, Rob Herring wrote:
>>> On Mon, Jan 02, 2017 at 05:37:14PM +0100, Quentin Schulz wrote:
>>>> 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 <quentin.schulz@free-electrons.com>
>>>> ---
>>>>  .../bindings/power/supply/axp20x_battery.txt       | 27 ++++++++++++++++++++++
>>>>  1 file changed, 27 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>>> new file mode 100644
>>>> index 0000000..5489d0d
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_battery.txt
>>>> @@ -0,0 +1,27 @@
>>>> +AXP20x and AXP22x battery power supply
>>>> +
>>>> +Required Properties:
>>>> + - compatible, one of:
>>>> +			"x-powers,axp209-battery-power-supply"
>>>> +			"x-powers,axp221-battery-power-supply"
>>>> + - io-channels: phandles to battery voltage, charge and discharge
>>>> + currents ADC channels
>>>> + - io-channel-names = "batt_v", "batt_chrg_i", "batt_dischrg_i";
>>>> +
>>>> +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 {
>>>
>>> Humm, I guess you power-supply is not sufficient, so 
>>> 'battery-power-supply' and similar for ac.
>>>
>>>> +		compatible = "x-powers,axp209-battery-power-supply";
>>>> +		io-channels = <&axp209_adc 7>, <&axp209_adc 8>,
>>>> +			<&axp209_adc 9>;
>>>> +		io-channel-names = "batt_v", "batt_chrg_i",
>>>> +			"batt_dischrg_i";
>> Is this stuff fixed for the device?
> 
> If we don't mix the IIO channels order, it is. This driver only requires
> batt_v, batt_chrg_i and batt_dischrg_i so we've to keep them at that
> place in the list of IIO channels. Or as suggested by Rob and Chen-Yu, I
> can move all this inside the driver with iio_map and don't care anymore
> about the order.
> 
I'd do that. Makes life easier to represented fixed things as fixed!
> Thanks,
> Quentin
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs Quentin Schulz
  2017-01-07 19:31   ` Jonathan Cameron
@ 2017-01-17  3:00   ` Sebastian Reichel
  2017-01-26 13:32     ` Quentin Schulz
  1 sibling, 1 reply; 72+ messages in thread
From: Sebastian Reichel @ 2017-01-17  3:00 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens,
	linux, maxime.ripard, lee.jones, linux-iio, devicetree,
	linux-kernel, linux-pm, linux-arm-kernel, thomas.petazzoni,
	icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 1695 bytes --]

Hi Quentin,

The driver looks mostly fine. I do have a two comments, though.

On Mon, Jan 02, 2017 at 05:37:08PM +0100, Quentin Schulz wrote:
> [...]
>
> +static int axp20x_ac_power_probe(struct platform_device *pdev)
> +{
> +	static const char * const axp20x_irq_names[] = { "ACIN_PLUGIN",
> +		"ACIN_REMOVAL", NULL };
>
> +	static const char * const *irq_names;
> +	const struct power_supply_desc *ac_power_desc;
> +	int i, 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;
> +	}

axp20x will no longer be needed after implementing below
comments.

> [...]
> +	irq_names = axp20x_irq_names;

Just rename axp20x_irq_names into irq_names, since its only used
here.

> [...]
>
> +	power->np = pdev->dev.of_node;

This can be dropped, it's not used at all.

> +	power->regmap = axp20x->regmap;

power->regmap = dev_get_regmap(pdev->dev.parent, NULL);

> [...]
> +	/* 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);

The mapping should actually happen in the mfd driver, so that
the platform resource contains a valid 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);
> +	}

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs
  2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
                     ` (2 preceding siblings ...)
  2017-01-06  3:39   ` Chen-Yu Tsai
@ 2017-01-17  3:46   ` Sebastian Reichel
  3 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2017-01-17  3:46 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens,
	linux, maxime.ripard, lee.jones, linux-iio, devicetree,
	linux-kernel, linux-pm, linux-arm-kernel, thomas.petazzoni,
	icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 2347 bytes --]

Hi Quentin,

Just a couple of small things in this patch.

On Mon, Jan 02, 2017 at 05:37:17PM +0100, Quentin Schulz wrote:
> [...]
> +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> +		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
> +				  &reg);
> +		if (ret)
> +			return ret;
> +
> +		if (reg & AXP20X_PWR_STATUS_BAT_CHARGING)
> +			chan = axp20x_batt->batt_chrg_i;
> +		else
> +			chan = axp20x_batt->batt_dischrg_i;
> +
> +		ret = iio_read_channel_processed(chan, &val->intval);
> +		if (ret)
> +			return ret;
> +
> +		/*
> +		 * IIO framework gives mV but Power Supply framework gives µV.
> +		 */

Nit: Volt -> Ampere

> +		val->intval *= 1000;
> +		break;
>
> [...]
>
> +static int axp20x_power_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +	struct axp20x_batt_ps *axp20x_batt;
> +	struct power_supply_config psy_cfg = {};
> +
> +	axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
> +				   GFP_KERNEL);
> +	if (!axp20x_batt)
> +		return -ENOMEM;
> +
> +	axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
> +	if (IS_ERR(axp20x_batt->batt_v)) {
> +		if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV)
> +			return -EPROBE_DEFER;
> +		return PTR_ERR(axp20x_batt->batt_v);
> +	}
> +
> +	axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
> +							"batt_chrg_i");
> +	if (IS_ERR(axp20x_batt->batt_chrg_i)) {
> +		if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV)
> +			return -EPROBE_DEFER;
> +		return PTR_ERR(axp20x_batt->batt_chrg_i);
> +	}
> +
> +	axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
> +							   "batt_dischrg_i");
> +	if (IS_ERR(axp20x_batt->batt_dischrg_i)) {
> +		if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV)
> +			return -EPROBE_DEFER;
> +		return PTR_ERR(axp20x_batt->batt_dischrg_i);
> +	}
> +
> +	axp20x_batt->regmap = axp20x->regmap;
> +	platform_set_drvdata(pdev, axp20x_batt);

Please use drv_get_regmap(pdev->dev.parent, NULL) instead (and drop
axp20x).

> +	psy_cfg.drv_data = axp20x_batt;
> +	psy_cfg.of_node = pdev->dev.of_node;
> +
> +	axp20x_batt->axp_id = (int)of_device_get_match_data(&pdev->dev);

use (uintptr_t) to avoid compiler warnings on systems with sizeof
int != sizeof ptr.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-17  3:00   ` Sebastian Reichel
@ 2017-01-26 13:32     ` Quentin Schulz
  2017-01-27  8:20       ` Maxime Ripard
  0 siblings, 1 reply; 72+ messages in thread
From: Quentin Schulz @ 2017-01-26 13:32 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, wens,
	linux, maxime.ripard, lee.jones, linux-iio, devicetree,
	linux-kernel, linux-pm, linux-arm-kernel, thomas.petazzoni,
	icenowy, bonbons

Hi Sebastian,

On 17/01/2017 04:00, Sebastian Reichel wrote:
> Hi Quentin,
> 
> The driver looks mostly fine. I do have a two comments, though.
> 
> On Mon, Jan 02, 2017 at 05:37:08PM +0100, Quentin Schulz wrote:
>> [...]
>>
>> +static int axp20x_ac_power_probe(struct platform_device *pdev)
>> +{
>> +	static const char * const axp20x_irq_names[] = { "ACIN_PLUGIN",
>> +		"ACIN_REMOVAL", NULL };
>>
>> +	static const char * const *irq_names;
>> +	const struct power_supply_desc *ac_power_desc;
>> +	int i, 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;
>> +	}
> 
> axp20x will no longer be needed after implementing below
> comments.
> 
>> [...]
>> +	irq_names = axp20x_irq_names;
> 
> Just rename axp20x_irq_names into irq_names, since its only used
> here.
> 
>> [...]
>>
>> +	power->np = pdev->dev.of_node;
> 
> This can be dropped, it's not used at all.
> 
>> +	power->regmap = axp20x->regmap;
> 
> power->regmap = dev_get_regmap(pdev->dev.parent, NULL);
> 

ACK on everything above.

>> [...]
>> +	/* 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);
> 
> The mapping should actually happen in the mfd driver, so that
> the platform resource contains a valid irq.
> 

I've come with this solution:

------------------------------------------------------------------------
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 012c064..117eacb 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -882,7 +882,7 @@ EXPORT_SYMBOL(axp20x_match_device);

 int axp20x_device_probe(struct axp20x_dev *axp20x)
 {
-	int ret;
+	int ret, irq_base;

 	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
 				  IRQF_ONESHOT | IRQF_SHARED, -1,
@@ -893,8 +893,9 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
 		return ret;
 	}

+	irq_base = regmap_irq_chip_get_base(axp20x->regmap_irqc);
 	ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
-			      axp20x->nr_cells, NULL, 0, NULL);
+			      axp20x->nr_cells, NULL, irq_base, NULL);

 	if (ret) {
 		dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
------------------------------------------------------------------------

However, this implies that all cells added by the mfd driver which are
requesting irqs will need to be changed in the same commit to remove the
regmap_irq_get_virq calls. If we don't modify the drivers, they will
purely fail to request the irqs.

The impacted drivers are the following:

 - drivers/extcon/extcon-axp288.c
 - drivers/input/misc/axp20x-pek.c
 - drivers/power/supply/axp20x_usb_power.c
 - drivers/power/supply/axp288_charger.c
 - drivers/power/supply/axp288_fuel_gauge.c

Is it really worth to do such a cleanup? I'm assuming that impacting
four different subsystems at the same time might require a bit of time
to make the patch into the kernel. I don't see also another way than
doing one single patch for all changes since the changes in the mfd
driver will break all aforementioned drivers.

Thanks,
Quentin

-- 
Quentin Schulz, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply related	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-26 13:32     ` Quentin Schulz
@ 2017-01-27  8:20       ` Maxime Ripard
  2017-01-28 14:30         ` Jonathan Cameron
  0 siblings, 1 reply; 72+ messages in thread
From: Maxime Ripard @ 2017-01-27  8:20 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Sebastian Reichel, jic23, knaack.h, lars, pmeerw, robh+dt,
	mark.rutland, wens, linux, lee.jones, linux-iio, devicetree,
	linux-kernel, linux-pm, linux-arm-kernel, thomas.petazzoni,
	icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 2391 bytes --]

On Thu, Jan 26, 2017 at 02:32:21PM +0100, Quentin Schulz wrote:
> I've come with this solution:
> 
> ------------------------------------------------------------------------
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 012c064..117eacb 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -882,7 +882,7 @@ EXPORT_SYMBOL(axp20x_match_device);
> 
>  int axp20x_device_probe(struct axp20x_dev *axp20x)
>  {
> -	int ret;
> +	int ret, irq_base;
> 
>  	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
>  				  IRQF_ONESHOT | IRQF_SHARED, -1,
> @@ -893,8 +893,9 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
>  		return ret;
>  	}
> 
> +	irq_base = regmap_irq_chip_get_base(axp20x->regmap_irqc);
>  	ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
> -			      axp20x->nr_cells, NULL, 0, NULL);
> +			      axp20x->nr_cells, NULL, irq_base, NULL);
> 
>  	if (ret) {
>  		dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
> ------------------------------------------------------------------------
> 
> However, this implies that all cells added by the mfd driver which are
> requesting irqs will need to be changed in the same commit to remove the
> regmap_irq_get_virq calls. If we don't modify the drivers, they will
> purely fail to request the irqs.
> 
> The impacted drivers are the following:
> 
>  - drivers/extcon/extcon-axp288.c
>  - drivers/input/misc/axp20x-pek.c
>  - drivers/power/supply/axp20x_usb_power.c
>  - drivers/power/supply/axp288_charger.c
>  - drivers/power/supply/axp288_fuel_gauge.c
> 
> Is it really worth to do such a cleanup?

Yes. The current behaviour goes against what everyone is expecting
from the API.

> I'm assuming that impacting four different subsystems at the same
> time might require a bit of time to make the patch into the
> kernel. I don't see also another way than doing one single patch for
> all changes since the changes in the mfd driver will break all
> aforementioned drivers.

However, I think that can be fixed in a later, independant serie. This
serie is quite big already and this has been long overdue, so I'd
really like not to delay it once again because of a dependency on a
cross-tree cleanup.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-27  8:20       ` Maxime Ripard
@ 2017-01-28 14:30         ` Jonathan Cameron
  2017-01-29 15:16           ` Sebastian Reichel
  0 siblings, 1 reply; 72+ messages in thread
From: Jonathan Cameron @ 2017-01-28 14:30 UTC (permalink / raw)
  To: Maxime Ripard, Quentin Schulz
  Cc: Sebastian Reichel, knaack.h, lars, pmeerw, robh+dt, mark.rutland,
	wens, linux, lee.jones, linux-iio, devicetree, linux-kernel,
	linux-pm, linux-arm-kernel, thomas.petazzoni, icenowy, bonbons

On 27/01/17 08:20, Maxime Ripard wrote:
> On Thu, Jan 26, 2017 at 02:32:21PM +0100, Quentin Schulz wrote:
>> I've come with this solution:
>>
>> ------------------------------------------------------------------------
>> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>> index 012c064..117eacb 100644
>> --- a/drivers/mfd/axp20x.c
>> +++ b/drivers/mfd/axp20x.c
>> @@ -882,7 +882,7 @@ EXPORT_SYMBOL(axp20x_match_device);
>>
>>  int axp20x_device_probe(struct axp20x_dev *axp20x)
>>  {
>> -	int ret;
>> +	int ret, irq_base;
>>
>>  	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
>>  				  IRQF_ONESHOT | IRQF_SHARED, -1,
>> @@ -893,8 +893,9 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
>>  		return ret;
>>  	}
>>
>> +	irq_base = regmap_irq_chip_get_base(axp20x->regmap_irqc);
>>  	ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
>> -			      axp20x->nr_cells, NULL, 0, NULL);
>> +			      axp20x->nr_cells, NULL, irq_base, NULL);
>>
>>  	if (ret) {
>>  		dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
>> ------------------------------------------------------------------------
>>
>> However, this implies that all cells added by the mfd driver which are
>> requesting irqs will need to be changed in the same commit to remove the
>> regmap_irq_get_virq calls. If we don't modify the drivers, they will
>> purely fail to request the irqs.
>>
>> The impacted drivers are the following:
>>
>>  - drivers/extcon/extcon-axp288.c
>>  - drivers/input/misc/axp20x-pek.c
>>  - drivers/power/supply/axp20x_usb_power.c
>>  - drivers/power/supply/axp288_charger.c
>>  - drivers/power/supply/axp288_fuel_gauge.c
>>
>> Is it really worth to do such a cleanup?
> 
> Yes. The current behaviour goes against what everyone is expecting
> from the API.
> 
>> I'm assuming that impacting four different subsystems at the same
>> time might require a bit of time to make the patch into the
>> kernel. I don't see also another way than doing one single patch for
>> all changes since the changes in the mfd driver will break all
>> aforementioned drivers.
> 
> However, I think that can be fixed in a later, independant serie. This
> serie is quite big already and this has been long overdue, so I'd
> really like not to delay it once again because of a dependency on a
> cross-tree cleanup.
It's not that cross tree really. Lining up this level of change to
go through an immutable branch pulled into each of the relevant trees
isn't too hard to arrange.

Jonathan
> 
> Maxime
> 

^ permalink raw reply	[flat|nested] 72+ messages in thread

* Re: [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs
  2017-01-28 14:30         ` Jonathan Cameron
@ 2017-01-29 15:16           ` Sebastian Reichel
  0 siblings, 0 replies; 72+ messages in thread
From: Sebastian Reichel @ 2017-01-29 15:16 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Maxime Ripard, Quentin Schulz, knaack.h, lars, pmeerw, robh+dt,
	mark.rutland, wens, linux, lee.jones, linux-iio, devicetree,
	linux-kernel, linux-pm, linux-arm-kernel, thomas.petazzoni,
	icenowy, bonbons

[-- Attachment #1: Type: text/plain, Size: 3059 bytes --]

Hi,

On Sat, Jan 28, 2017 at 02:30:22PM +0000, Jonathan Cameron wrote:
> On 27/01/17 08:20, Maxime Ripard wrote:
> > On Thu, Jan 26, 2017 at 02:32:21PM +0100, Quentin Schulz wrote:
> >> I've come with this solution:
> >>
> >> ------------------------------------------------------------------------
> >> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> >> index 012c064..117eacb 100644
> >> --- a/drivers/mfd/axp20x.c
> >> +++ b/drivers/mfd/axp20x.c
> >> @@ -882,7 +882,7 @@ EXPORT_SYMBOL(axp20x_match_device);
> >>
> >>  int axp20x_device_probe(struct axp20x_dev *axp20x)
> >>  {
> >> -	int ret;
> >> +	int ret, irq_base;
> >>
> >>  	ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
> >>  				  IRQF_ONESHOT | IRQF_SHARED, -1,
> >> @@ -893,8 +893,9 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
> >>  		return ret;
> >>  	}
> >>
> >> +	irq_base = regmap_irq_chip_get_base(axp20x->regmap_irqc);
> >>  	ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells,
> >> -			      axp20x->nr_cells, NULL, 0, NULL);
> >> +			      axp20x->nr_cells, NULL, irq_base, NULL);
> >>
> >>  	if (ret) {
> >>  		dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
> >> ------------------------------------------------------------------------
> >>
> >> However, this implies that all cells added by the mfd driver which are
> >> requesting irqs will need to be changed in the same commit to remove the
> >> regmap_irq_get_virq calls. If we don't modify the drivers, they will
> >> purely fail to request the irqs.
> >>
> >> The impacted drivers are the following:
> >>
> >>  - drivers/extcon/extcon-axp288.c
> >>  - drivers/input/misc/axp20x-pek.c
> >>  - drivers/power/supply/axp20x_usb_power.c
> >>  - drivers/power/supply/axp288_charger.c
> >>  - drivers/power/supply/axp288_fuel_gauge.c

So mostly power-supply, which is affected by this series anyways.
Only input & extcon are added.

> >> Is it really worth to do such a cleanup?
> > 
> > Yes. The current behaviour goes against what everyone is expecting
> > from the API.
> >
> >> I'm assuming that impacting four different subsystems at the same
> >> time might require a bit of time to make the patch into the
> >> kernel. I don't see also another way than doing one single patch for
> >> all changes since the changes in the mfd driver will break all
> >> aforementioned drivers.
> > 
> > However, I think that can be fixed in a later, independant serie. This
> > serie is quite big already and this has been long overdue, so I'd
> > really like not to delay it once again because of a dependency on a
> > cross-tree cleanup.
>
> It's not that cross tree really. Lining up this level of change to
> go through an immutable branch pulled into each of the relevant trees
> isn't too hard to arrange.

I'm fine with doing this as a separate series, if it follows
directly behind this one. Mainlined drivers tend to be used as
template for new ones and this invalid IRQ resources are a bad
example.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2017-01-29 15:17 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-02 16:37 [PATCH 00/22] add support for AXP20X and AXP22X power supply drivers Quentin Schulz
2017-01-02 16:37 ` [PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding Quentin Schulz
2017-01-03 23:20   ` Rob Herring
2017-01-05  4:05     ` Chen-Yu Tsai
2017-01-05 16:40   ` Maxime Ripard
2017-01-02 16:37 ` [PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X Quentin Schulz
2017-01-04 11:55   ` Lee Jones
2017-01-05  4:12   ` Chen-Yu Tsai
2017-01-02 16:37 ` [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs Quentin Schulz
2017-01-05  5:42   ` Chen-Yu Tsai
2017-01-05  8:06     ` Quentin Schulz
2017-01-05  8:27       ` Chen-Yu Tsai
2017-01-05  9:50         ` Quentin Schulz
2017-01-05 10:28           ` Chen-Yu Tsai
2017-01-07 19:23             ` Jonathan Cameron
2017-01-05 16:46           ` Maxime Ripard
2017-01-07 19:20           ` Jonathan Cameron
2017-01-05 16:51   ` Maxime Ripard
2017-01-07 19:13   ` Jonathan Cameron
2017-01-02 16:37 ` [PATCH 04/22] mfd: axp20x: add ADC cells for AXP20X and AXP22X PMICs Quentin Schulz
2017-01-04 11:56   ` Lee Jones
2017-01-04 11:56     ` Lee Jones
2017-01-05  5:51       ` Chen-Yu Tsai
2017-01-02 16:37 ` [PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode Quentin Schulz
2017-01-05  5:51   ` Chen-Yu Tsai
2017-01-05  8:08     ` Quentin Schulz
2017-01-05  8:16       ` Chen-Yu Tsai
2017-01-02 16:37 ` [PATCH 06/22] ARM: dtsi: axp22x: add AXP22X " Quentin Schulz
2017-01-05  5:52   ` Chen-Yu Tsai
2017-01-02 16:37 ` [PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply Quentin Schulz
2017-01-04 13:14   ` Rob Herring
2017-01-05  6:17     ` Chen-Yu Tsai
2017-01-07 19:26       ` Jonathan Cameron
2017-01-02 16:37 ` [PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs Quentin Schulz
2017-01-07 19:31   ` Jonathan Cameron
2017-01-08 10:41     ` Quentin Schulz
2017-01-17  3:00   ` Sebastian Reichel
2017-01-26 13:32     ` Quentin Schulz
2017-01-27  8:20       ` Maxime Ripard
2017-01-28 14:30         ` Jonathan Cameron
2017-01-29 15:16           ` Sebastian Reichel
2017-01-02 16:37 ` [PATCH 09/22] mfd: axp20x: add AC power supply cells for " Quentin Schulz
2017-01-04 11:57   ` Lee Jones
2017-01-02 16:37 ` [PATCH 10/22] ARM: dtsi: axp209: add AC power supply subnode Quentin Schulz
2017-01-02 16:37 ` [PATCH 11/22] ARM: dtsi: axp22x: " Quentin Schulz
2017-01-02 16:37 ` [PATCH 12/22] ARM: dts: sun8i: sina33: enable ACIN " Quentin Schulz
2017-01-02 16:37 ` [PATCH 13/22] ARM: sun5i: chip: " Quentin Schulz
2017-01-02 16:37 ` [PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding Quentin Schulz
2017-01-04 13:21   ` Rob Herring
2017-01-07 19:33     ` Jonathan Cameron
2017-01-08 10:48       ` Quentin Schulz
2017-01-08 10:59         ` Jonathan Cameron
2017-01-02 16:37 ` [PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X Quentin Schulz
2017-01-04 11:57   ` Lee Jones
2017-01-05  6:10   ` Chen-Yu Tsai
2017-01-05  8:10     ` Quentin Schulz
2017-01-02 16:37 ` [PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X Quentin Schulz
2017-01-04 11:57   ` Lee Jones
2017-01-05  6:02     ` Chen-Yu Tsai
2017-01-02 16:37 ` [PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs Quentin Schulz
2017-01-05 17:02   ` Maxime Ripard
2017-01-05 17:34   ` Ezequiel Garcia
2017-01-06  2:46     ` Sebastian Reichel
2017-01-06  3:39   ` Chen-Yu Tsai
2017-01-06  8:29     ` Quentin Schulz
2017-01-17  3:46   ` Sebastian Reichel
2017-01-02 16:37 ` [PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver Quentin Schulz
2017-01-04 11:57   ` Lee Jones
2017-01-02 16:37 ` [PATCH 19/22] ARM: dtsi: axp209: add battery power supply subnode Quentin Schulz
2017-01-02 16:37 ` [PATCH 20/22] ARM: dtsi: axp22x: " Quentin Schulz
2017-01-02 16:37 ` [PATCH 21/22] ARM: dts: sun8i: sina33: enable " Quentin Schulz
2017-01-02 16:37 ` [PATCH 22/22] ARM: sun5i: chip: " Quentin Schulz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).