[PATCH 06/22] ARM: dtsi: axp22x: add AXP22X ADC subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 05/22] ARM: dtsi: axp209: add AXP209 ADC subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 07/22] dt-bindings: power: supply: add AXP20X/AXP22X AC power supply

2017-01-02 Thread Quentin Schulz
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 
---
 .../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 000..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



[PATCH 08/22] power: supply: add AC power supply driver for AXP20X and AXP22X PMICs

2017-01-02 Thread Quentin Schulz
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 
---
 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 000..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 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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, ®);
+   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, ®);
+   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, ®);
+   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 m

[PATCH 10/22] ARM: dtsi: axp209: add AC power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 09/22] mfd: axp20x: add AC power supply cells for AXP22X PMICs

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 02/22] mfd: axp20x: add ADC data regs to volatile regs for AXP22X

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 11/22] ARM: dtsi: axp22x: add AC power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 12/22] ARM: dts: sun8i: sina33: enable ACIN power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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";
+};
+
 ®_aldo1 {
regulator-always-on;
regulator-min-microvolt = <300>;
-- 
2.9.3



[PATCH 13/22] ARM: sun5i: chip: enable ACIN power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 00/22] add support for AXP20X and AXP22X power supply drivers

2017-01-02 Thread Quentin Schulz
ws 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



[PATCH 14/22] dt-bindings: power: supply: add AXP20X/AXP22X battery DT binding

2017-01-02 Thread Quentin Schulz
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 
---
 .../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 000..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



[PATCH 01/22] dt-bindings: iio: adc: add AXP20X/AXP22X ADC DT binding

2017-01-02 Thread Quentin Schulz
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 
---
 .../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 000..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



[PATCH 22/22] ARM: sun5i: chip: enable battery power supply subnode

2017-01-02 Thread Quentin Schulz
The NextThing Co. CHIP has an AXP209 PMIC with battery connector.

This enables the battery power supply subnode.

Signed-off-by: Quentin Schulz 
---
 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



[PATCH 21/22] ARM: dts: sun8i: sina33: enable battery power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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";
+};
+
 ®_aldo1 {
regulator-always-on;
regulator-min-microvolt = <300>;
-- 
2.9.3



[PATCH 20/22] ARM: dtsi: axp22x: add battery power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 18/22] mfd: axp20x: add MFD cells for AXP20X and AXP22X battery driver

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 19/22] ARM: dtsi: axp209: add battery power supply subnode

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 17/22] power: supply: add battery driver for AXP20X and AXP22X PMICs

2017-01-02 Thread Quentin Schulz
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 
---
 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 000..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 
+ *
+ * This driver is based on a previous upstreaming attempt by:
+ * Bruno Prémont 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#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_VALIDBIT(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_15VBIT(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_22VBIT(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, ®);
+   if (ret)
+   return ret;
+
+   switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
+   case AXP20X_CHRG_CTRL1_TGT_4_1V:
+   *val = 410;
+   break;
+   case AXP20X_CHRG_CTRL1_TGT_4_15V:
+   *val = 415;
+   break;
+   case AXP20X_CHRG_CTRL1_TGT_4_2V:
+   *val = 420;
+   break;
+   case AXP20X_CHRG_CTRL1_TGT_4_36V:
+   *val = 436;
+   break;
+   default:
+   

[PATCH 16/22] mfd: axp20x: add V_OFF to writeable regs for AXP20X and AXP22X

2017-01-02 Thread Quentin Schulz
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 
---
 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



[PATCH 15/22] mfd: axp20x: add CHRG_CTRL1 to writeable regs for AXP20X/AXP22X

2017-01-02 Thread Quentin Schulz
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 
---
 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



Re: [PATCH 1/7] Documentation: DT: bindings: iio: adc: add documentation for Allwinner SoCs' GPADC driver

2016-12-20 Thread Quentin Schulz
Hi,

On 20/12/2016 15:25, Maxime Ripard wrote:
> Hi,
> 
> On Tue, Dec 20, 2016 at 11:27:03AM +0100, Quentin Schulz wrote:
[...]
>> +Currently, the touchscreen controller does not have a driver using this ADC
>> +driver. The touchscreen controller is currently driven only by
>> +input/touchscreen/sun4i-ts.c which is absolutely incompatible with this 
>> driver.
>> +
>> +The Allwinner A10, A13 and A31 SoCs already have a DT binding for the
>> +aforementioned input driver, thus an MFD driver matches the existing DT 
>> binding
>> +(mfd/sun4i-gpadc.c) and replaces the input driver. No DT binding is 
>> required for
>> +these SoCs' ADC, everything is handled by the MFD which is matching the 
>> existing
>> +DT binding for input/touchscreen/sun4i-ts.c.
>> +
>> +The Allwinner A33 GPADC only have a thermal sensor and have a proper DT 
>> binding
>> +for this driver unlike the previously mentioned SoCs.
> 
> The DT bindings should be agnostic from the OS. You can remove all
> mention of the implementations details in Linux.
> 
> (and you should wrap at 72 characters).
> 
> But we already have a binding document for that controller, so you
> shouldn't create a new one, reuse the old one that is already there.
> 

ACK.

>> +Required properties:
>> + - compatible: "allwinner,sun8i-a33-gpadc-iio"
> 
> IIO is an implementation detail. The IP is called GPADC.
> You're also missing reg.
> 

ACK.

>> +
>> +Optional properties:
>> +(for use with thermal framework for CPU thermal throttling for example, 
>> and/or
>> + IIO consumers)
>> + - #thermal-sensor-cells = <0>; (see
>> +Documentation/devicetree/bindings/thermal/thermal.txt)
>> + - #io-channel-cells = <0>; (see
>> +Documentation/devicetree/bindings/iio/iio-bindings.txt)
> 
> I wouldn't list that as optional.
> 

In what sense? Do you mean you wouldn't put them here at all or you
would require them?

Thanks,
Quentin

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


Re: [PATCH 3/7] iio: adc: sun4i-gpadc-iio: add support for A33 thermal sensor

2016-12-20 Thread Quentin Schulz
Hi,

On 20/12/2016 15:44, Maxime Ripard wrote:
> On Tue, Dec 20, 2016 at 11:27:05AM +0100, Quentin Schulz wrote:
>> This adds support for the Allwinner A33 thermal sensor.
>>
>> Unlike the A10, A13 and A31, the Allwinner A33 only has one channel
>> which is dedicated to the thermal sensor. Moreover, its thermal sensor
>> does not generate interruptions, thus we only need to directly read the
>> register storing the temperature value.
>>
>> The MFD used by the A10, A13 and A31, was created to avoid breaking the
>> DT binding, but since the nodes for the ADC weren't there for the A33,
>> it is not needed.
>>
>> Signed-off-by: Quentin Schulz 
>> ---
>>  drivers/iio/adc/Kconfig   |  21 ++--
>>  drivers/iio/adc/sun4i-gpadc-iio.c | 204 
>> --
>>  include/linux/mfd/sun4i-gpadc.h   |   4 +
>>  3 files changed, 172 insertions(+), 57 deletions(-)
>>
>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>> index 6a6d369..06041ff 100644
>> --- a/drivers/iio/adc/Kconfig
>> +++ b/drivers/iio/adc/Kconfig
>> @@ -437,17 +437,24 @@ config STX104
>>  config SUN4I_GPADC
>>  tristate "Support for the Allwinner SoCs GPADC"
>>  depends on IIO
>> -depends on MFD_SUN4I_GPADC
>> -help
>> -  Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
>> -  GPADC. This ADC provides 4 channels which can be used as an ADC or as
>> -  a touchscreen input and one channel for thermal sensor.
>> -
>> -  The thermal sensor slows down ADC readings and can be disabled by
>> +# MFD_SUN4I_GPADC is needed for sun4i, sun5i and sun6i but not for sun8i
> 
> The indentation is wrong here, and I wouldn't list all the families
> there, this is just going to be always amended, for no particular
> reason.
> 

ACK.

>> +select MFD_SUN4I_GPADC if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I
> 
> Why did you change the depends on to a select?
> 

The "depends on" does not have an if condition but "select" has. See:
https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt

> And isn't that redundant with the comment just above?
> 
>> +# THERMAL_OF can be disabled on sun4i, sun5i and sun6i to quicken ADC 
>> readings
> 
> I'm not sure this is worth adding either. Any option can be added with
> any number of side effects, I'm not sure we want to list all of them.
> 

ACK.

>> +depends on THERMAL_OF || MACH_SUN4I || MACH_SUN5I || MACH_SUN6I
> 
> So you can't disable THERMAL_OF on MACH_SUN8I?
> 

Not in the current state. devm_thermal_zone_of_sensor_register from
sun4i_gpadc_probe_dt returns an error if THERMAL_OF is disabled and
thus, the probe fails. Maybe it should rather fail silently and let the
user choose whether (s)he wants the thermal framework to be able to read
data from this driver?

>> +depends on !TOUCHSCREEN_SUN4I
> 
> This should be a different patch.
> 
>> +help
>> +  Say yes here to build support for Allwinner (A10, A13, A31 and A33)
>> +  SoCs GPADC.
>> +
>> +  The ADC on A10, A13 and A31 provides 4 channels which can be used as
>> +  an ADC or as a touchscreen input and one channel for thermal sensor.
>> +  Their thermal sensor slows down ADC readings and can be disabled by
> 
> Again, I'm not sure putting all those details in the Kconfig help
> really helps. This is only going to grow with more and more cases, and
> this isn't something really helpful anyway.
> 

Are you suggesting to remove completely the paragraph on why it is
possible to disable CONFIG_THERMAL_OF for the A10, A13 and A31 or only
to remove the mention to SoCs?

>>disabling CONFIG_THERMAL_OF. However, the thermal sensor should be
>>enabled by default since the SoC temperature is usually more critical
>>than ADC readings.
>>  
>> +  The ADC on A33 provides one channel for thermal sensor.
>> +
>>To compile this driver as a module, choose M here: the module will be
>>called sun4i-gpadc-iio.
>>  
>> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
>> b/drivers/iio/adc/sun4i-gpadc-iio.c
>> index a8e134f..8be694e 100644
>> --- a/drivers/iio/adc/sun4i-gpadc-iio.c
>> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c
>> @@ -1,4 +1,4 @@
>> -/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
>> +/* ADC driver for sunxi platforms' (A10, A13, A31 and A33) GPADC
>>   *
>>   * Copyright (c) 2016 Quentin Schulz 
>>   *
>> @@ -8

[PATCH 4/7] ARM: dts: sun8i-a33-sinlinx-sina33: add cpu-supply

2016-12-20 Thread Quentin Schulz
This adds the cpu-supply DT property to the cpu0 DT node needed by
the board to adapt the regulator voltage depending on the currently used
OPP.

Signed-off-by: Quentin Schulz 
---
 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 fef6abc..0901c57 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -63,6 +63,10 @@
};
 };
 
+&cpu0 {
+   cpu-supply = <®_dcdc3>;
+};
+
 &ehci0 {
status = "okay";
 };
-- 
2.9.3



[PATCH 6/7] ARM: dtsi: sun8i-a33: add A33 thermal sensor

2016-12-20 Thread Quentin Schulz
This adds the DT node for the thermal sensor present in the Allwinner
A33 GPADC.

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/sun8i-a33.dtsi | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index 2878a77..1fcae81 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -151,6 +151,13 @@
reset-names = "ahb";
};
 
+   rtp: rtp@01c25000 {
+   compatible = "allwinner,sun8i-a33-gpadc-iio";
+   reg = <0x01c25000 0x100>;
+   #thermal-sensor-cells = <0>;
+   #io-channel-cells = <0>;
+   };
+
fe0: display-frontend@01e0 {
compatible = "allwinner,sun8i-a33-display-frontend";
reg = <0x01e0 0x2>;
@@ -261,6 +268,11 @@
};
};
};
+
+   iio-hwmon {
+   compatible = "iio-hwmon";
+   io-channels = <&rtp>;
+   };
 };
 
 &ccu {
-- 
2.9.3



[PATCH 7/7] ARM: dtsi: sun8i-a33: add CPU thermal throttling

2016-12-20 Thread Quentin Schulz
This adds CPU thermal throttling for the Allwinner A33. It uses the
thermal sensor present in the SoC's GPADC.

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/sun8i-a33.dtsi | 47 
 1 file changed, 47 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index 1fcae81..735ebea 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -43,6 +43,7 @@
  */
 
 #include "sun8i-a23-a33.dtsi"
+#include 
 
 / {
cpu0_opp_table: opp_table0 {
@@ -79,6 +80,9 @@
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
+   cooling-min-level = <0>;
+   cooling-max-level = <3>;
+   #cooling-cells = <2>;
};
 
cpu@2 {
@@ -100,6 +104,49 @@
status = "disabled";
};
 
+   thermal-zones {
+   cpu_thermal {
+   /* milliseconds */
+   polling-delay-passive = <250>;
+   polling-delay = <1000>;
+   thermal-sensors = <&rtp>;
+
+   cooling-maps {
+   map0 {
+   trip = <&cpu_alert0>;
+   cooling-device = <&cpu0 
THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+   };
+   map1 {
+   trip = <&cpu_alert1>;
+   cooling-device = <&cpu0 
THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+   };
+   };
+
+   trips {
+   cpu_alert0: cpu_alert0 {
+   /* milliCelsius */
+   temperature = <75000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   cpu_alert1: cpu_alert1 {
+   /* milliCelsius */
+   temperature = <9>;
+   hysteresis = <2000>;
+   type = "hot";
+   };
+
+   cpu_crit: cpu_crit {
+   /* milliCelsius */
+   temperature = <11>;
+   hysteresis = <2000>;
+   type = "critical";
+   };
+   };
+   };
+   };
+
memory {
reg = <0x4000 0x8000>;
};
-- 
2.9.3



[PATCH 3/7] iio: adc: sun4i-gpadc-iio: add support for A33 thermal sensor

2016-12-20 Thread Quentin Schulz
This adds support for the Allwinner A33 thermal sensor.

Unlike the A10, A13 and A31, the Allwinner A33 only has one channel
which is dedicated to the thermal sensor. Moreover, its thermal sensor
does not generate interruptions, thus we only need to directly read the
register storing the temperature value.

The MFD used by the A10, A13 and A31, was created to avoid breaking the
DT binding, but since the nodes for the ADC weren't there for the A33,
it is not needed.

Signed-off-by: Quentin Schulz 
---
 drivers/iio/adc/Kconfig   |  21 ++--
 drivers/iio/adc/sun4i-gpadc-iio.c | 204 --
 include/linux/mfd/sun4i-gpadc.h   |   4 +
 3 files changed, 172 insertions(+), 57 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 6a6d369..06041ff 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -437,17 +437,24 @@ config STX104
 config SUN4I_GPADC
tristate "Support for the Allwinner SoCs GPADC"
depends on IIO
-   depends on MFD_SUN4I_GPADC
-   help
- Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
- GPADC. This ADC provides 4 channels which can be used as an ADC or as
- a touchscreen input and one channel for thermal sensor.
-
- The thermal sensor slows down ADC readings and can be disabled by
+# MFD_SUN4I_GPADC is needed for sun4i, sun5i and sun6i but not for sun8i
+   select MFD_SUN4I_GPADC if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I
+# THERMAL_OF can be disabled on sun4i, sun5i and sun6i to quicken ADC readings
+   depends on THERMAL_OF || MACH_SUN4I || MACH_SUN5I || MACH_SUN6I
+   depends on !TOUCHSCREEN_SUN4I
+   help
+ Say yes here to build support for Allwinner (A10, A13, A31 and A33)
+ SoCs GPADC.
+
+ The ADC on A10, A13 and A31 provides 4 channels which can be used as
+ an ADC or as a touchscreen input and one channel for thermal sensor.
+ Their thermal sensor slows down ADC readings and can be disabled by
  disabling CONFIG_THERMAL_OF. However, the thermal sensor should be
  enabled by default since the SoC temperature is usually more critical
  than ADC readings.
 
+ The ADC on A33 provides one channel for thermal sensor.
+
  To compile this driver as a module, choose M here: the module will be
  called sun4i-gpadc-iio.
 
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index a8e134f..8be694e 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -1,4 +1,4 @@
-/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
+/* ADC driver for sunxi platforms' (A10, A13, A31 and A33) GPADC
  *
  * Copyright (c) 2016 Quentin Schulz 
  *
@@ -85,6 +85,12 @@ static const struct gpadc_data sun6i_gpadc_data = {
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
 };
 
+static const struct gpadc_data sun8i_gpadc_data = {
+   .temp_offset = -1662,
+   .temp_scale = 162,
+   .tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
+};
+
 struct sun4i_gpadc_iio {
struct iio_dev  *indio_dev;
struct completion   completion;
@@ -96,6 +102,7 @@ struct sun4i_gpadc_iio {
unsigned inttemp_data_irq;
atomic_tignore_temp_data_irq;
const struct gpadc_data *data;
+   booluse_dt;
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
 };
@@ -138,6 +145,23 @@ static const struct iio_chan_spec 
sun4i_gpadc_channels_no_temp[] = {
SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
 };
 
+static const struct iio_chan_spec sun8i_gpadc_channels[] = {
+   {
+   .type = IIO_TEMP,
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_OFFSET),
+   .datasheet_name = "temp_adc",
+   },
+};
+
+static const struct regmap_config sun4i_gpadc_regmap_config = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = 4,
+   .fast_io = true,
+};
+
 static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
 unsigned int irq)
 {
@@ -231,7 +255,6 @@ static int sun4i_gpadc_read(struct iio_dev *indio_dev, int 
channel, int *val,
 err:
pm_runtime_put_autosuspend(indio_dev->dev.parent);
mutex_unlock(&info->mutex);
-
return ret;
 }
 
@@ -246,6 +269,19 @@ static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, 
int channel,
 static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
 {
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
+   int ret;
+
+   if (info->use_dt) {

[PATCH 0/7] add CPU thermal throttling to Allwinner A33 SoC

2016-12-20 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used
either for the ADC or the touchscreen and the fifth channel is used for
the thermal sensor. We currently have a driver for the two latter
functions in drivers/input/touchscreen/sun4i-ts.c but we don't have
access to the ADC feature at all. It is meant to replace the current
driver by using MFD and subdrivers.

The Allwinner A33 only has a thermal sensor present in the GPADC. In
addition, there is not an existing DT binding for the GPADC. Thus, we do
not need the sun4i-gpadc MFD driver which was made to keep DT compatibility
and probe subdrivers without the need to add DT subnodes.

This series of patch adds the CPU thermal sensor for the A33 and CPU thermal
throttling. It also adds DT binding documentation for the IIO and MFD GPADC
drivers. Finally, it adds the cpu-supply property to the CPU node needed by
the Sinlinx SinA33 and Olinuxino A33 to adapt their CPU regulator voltage
depending on the currently used OPP. The other A33 boards all have their
cpu-supply property set.

This patch *HAS NOT* been tested on the Olinuxino A33.
 @Stefan (or anyone owning an Olinuxino A33), could you test this patch
 series on your board, test CPUfreq and tell us if it works in a stable
 manner? Thanks!

This series of patch is based on this[1] and this[2][3] series of patch.

[1] https://lkml.org/lkml/2016/12/13/298 : "[PATCH v9] add support for Allwinner
SoCs ADC"
[2] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473962.html
: "[PATCH] Allwinner A33 CPU frequency scaling support" without PATCH 4/6
[3] https://lkml.org/lkml/2016/12/19/72 : "[PATCH v2] ARM: dts: sun8i: add
opp-v2 table for A33"

Quentin Schulz (7):
  Documentation: DT: bindings: iio: adc: add documentation for Allwinner
SoCs' GPADC driver
  Documentation: DT: bindings: mfd: add documentation for Allwinner
SoCs' GPADC MFD driver
  iio: adc: sun4i-gpadc-iio: add support for A33 thermal sensor
  ARM: dts: sun8i-a33-sinlinx-sina33: add cpu-supply
  ARM: dts: sun8i-a33-olinuxino: add cpu-supply
  ARM: dtsi: sun8i-a33: add A33 thermal sensor
  ARM: dtsi: sun8i-a33: add CPU thermal throttling

 .../bindings/iio/adc/sun4i-gpadc-iio.txt   |  57 ++
 .../devicetree/bindings/mfd/sun4i-gpadc.txt|  47 +
 arch/arm/boot/dts/sun8i-a33-olinuxino.dts  |   4 +
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts |   4 +
 arch/arm/boot/dts/sun8i-a33.dtsi   |  59 ++
 drivers/iio/adc/Kconfig|  21 ++-
 drivers/iio/adc/sun4i-gpadc-iio.c  | 204 -
 include/linux/mfd/sun4i-gpadc.h|   4 +
 8 files changed, 343 insertions(+), 57 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/iio/adc/sun4i-gpadc-iio.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt

-- 
2.9.3



[PATCH 2/7] Documentation: DT: bindings: mfd: add documentation for Allwinner SoCs' GPADC MFD driver

2016-12-20 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a thermal sensor
and sometimes as a touchscreen controller. If there is a touchscreen
controller, the first four channels can be used either for the ADC or
the touchscreen and the fifth channel is used for the thermal sensor.
If there is not a touchscreen controller, the one and only channel is
used for the thermal sensor.

The Allwinner SoCs already have an existing DT binding for the
touchscreen controller and thermal sensor for the sun4i-ts input driver
which does let the user use the ADC. To keep backward compatibility,
this MFD driver re-uses the same bindings as the sun4i-ts input driver
and will probe the required drivers to make the ADC and thermal sensor
work.

This patch adds the binding documentation for the MFD driver of the
Allwinner SoCs' GPADC.

Signed-off-by: Quentin Schulz 
---
 .../devicetree/bindings/mfd/sun4i-gpadc.txt| 47 ++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt

diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt 
b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
new file mode 100644
index 000..bc4b4f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
@@ -0,0 +1,47 @@
+Allwinner SoCs' GPADC Device Tree bindings
+--
+
+The Allwinner SoCs all have an ADC that can also act as a thermal sensor and
+sometimes as a touchscreen controller. If there is a touchscreen controller, 
the
+first four channels can be used either for the ADC or the touchscreen and the
+fifth channel is used for the thermal sensor.
+If there is not a touchscreen controller, the one and only channel is used for
+the thermal sensor.
+
+Currently, the touchscreen controller does not have a driver using this ADC
+driver. The touchscreen controller is currently driven only by
+input/touchscreen/sun4i-ts.c which is absolutely incompatible with this driver.
+
+The Allwinner A10, A13 and A31 SoCs already have a DT binding for the
+aforementioned input driver, thus this MFD driver matches the existing DT
+binding (mfd/sun4i-gpadc.c).
+To keep DT binding compatibility, the MFD replaces the sun4i-ts input driver 
and
+probes required drivers (IIO GPADC driver (iio/adc/sun4i-gpadc-iio.c),
+iio-hwmon and soon the touchscreen driver) without the need for a DT binding 
for
+each driver.
+
+Required properties:
+ - compatible: one of:
+   - "allwinner,sun4i-a10-ts",
+   - "allwinner,sun5i-a13-ts",
+   - "allwinner,sun6i-a31-ts"
+ - #thermal-sensor-cells = <0>;
+
+Example:
+
+thermal-zones {
+   cpu_thermal {
+   thermal-sensors = <&rtp>;
+   [...]
+   };
+};
+
+soc@01c0 {
+   [...]
+   rtp: rtp@01c25000 {
+   compatible = "allwinner,sun6i-a31-ts";
+   reg = <0x01c25000 0x100>;
+   interrupts = ;
+   #thermal-sensor-cells = <0>;
+   };
+};
-- 
2.9.3



[PATCH 1/7] Documentation: DT: bindings: iio: adc: add documentation for Allwinner SoCs' GPADC driver

2016-12-20 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a thermal sensor
and sometimes as a touchscreen controller. If there is a touchscreen
controller, the first four channels can be used either for the ADC or
the touchscreen and the fifth channel is used for the thermal sensor.
If there is not a touchscreen controller, the one and only channel is
used for the thermal sensor.

This patch adds the documentation for the driver of the Allwinner SoCs'
GPADC.

Signed-off-by: Quentin Schulz 
---
 .../bindings/iio/adc/sun4i-gpadc-iio.txt   | 57 ++
 1 file changed, 57 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/iio/adc/sun4i-gpadc-iio.txt

diff --git a/Documentation/devicetree/bindings/iio/adc/sun4i-gpadc-iio.txt 
b/Documentation/devicetree/bindings/iio/adc/sun4i-gpadc-iio.txt
new file mode 100644
index 000..aab768d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/sun4i-gpadc-iio.txt
@@ -0,0 +1,57 @@
+Allwinner SoCs' GPADC Device Tree bindings
+--
+
+The Allwinner SoCs all have an ADC that can also act as a thermal sensor and
+sometimes as a touchscreen controller. If there is a touchscreen controller, 
the
+first four channels can be used either for the ADC or the touchscreen and the
+fifth channel is used for the thermal sensor.
+If there is not a touchscreen controller, the one and only channel is used for
+the thermal sensor.
+
+Currently, the touchscreen controller does not have a driver using this ADC
+driver. The touchscreen controller is currently driven only by
+input/touchscreen/sun4i-ts.c which is absolutely incompatible with this driver.
+
+The Allwinner A10, A13 and A31 SoCs already have a DT binding for the
+aforementioned input driver, thus an MFD driver matches the existing DT binding
+(mfd/sun4i-gpadc.c) and replaces the input driver. No DT binding is required 
for
+these SoCs' ADC, everything is handled by the MFD which is matching the 
existing
+DT binding for input/touchscreen/sun4i-ts.c.
+
+The Allwinner A33 GPADC only have a thermal sensor and have a proper DT binding
+for this driver unlike the previously mentioned SoCs.
+
+Required properties:
+ - compatible: "allwinner,sun8i-a33-gpadc-iio"
+
+Optional properties:
+(for use with thermal framework for CPU thermal throttling for example, and/or
+ IIO consumers)
+ - #thermal-sensor-cells = <0>; (see
+Documentation/devicetree/bindings/thermal/thermal.txt)
+ - #io-channel-cells = <0>; (see
+Documentation/devicetree/bindings/iio/iio-bindings.txt)
+
+Example:
+
+thermal-zones {
+   cpu_thermal {
+   thermal-sensors = <&rtp>;
+   [...]
+   };
+};
+
+soc@01c0 {
+   [...]
+   rtp: rtp@01c25000 {
+   compatible = "allwinner,sun8i-a33-gpadc-iio";
+   reg = <0x01c25000 0x100>;
+   #thermal-sensor-cells = <0>;
+   #io-channel-cells = <0>;
+   };
+}
+
+iio_hwmon {
+   compatible = "iio-hwmon";
+   io-channels = <&rtp>;
+};
-- 
2.9.3



[PATCH 5/7] ARM: dts: sun8i-a33-olinuxino: add cpu-supply

2016-12-20 Thread Quentin Schulz
This adds the cpu-supply DT property to the cpu0 DT node needed by
the board to adapt the regulator voltage depending on the currently use
OPP.

Signed-off-by: Quentin Schulz 
---

This hasn't been tested on the board but it is what I understand from the
schematics[1] of the board.

Stefan (or anyone owning this board), could you test this series of patch on the
Olinuxino A33, test CPUfreq on it and tell us if it works? Thanks!

[1] 
https://github.com/OLIMEX/OLINUXINO/raw/master/HARDWARE/A33/A33-OLinuXino_Rev_B1.pdf

 arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts 
b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
index 9ea637e..df55f54 100644
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
@@ -72,6 +72,10 @@
};
 };
 
+&cpu0 {
+   cpu-supply = <®_dcdc3>;
+};
+
 &ehci0 {
status = "okay";
 };
-- 
2.9.3



Re: [PATCH v2] ARM: dts: sun8i: add opp-v2 table for A33

2016-12-19 Thread Quentin Schulz
On 19/12/2016 15:06, Icenowy Zheng wrote:
> 
> 
> 19.12.2016, 16:54, "Chen-Yu Tsai" :
>> On Mon, Dec 19, 2016 at 4:46 PM, Maxime Ripard
>>  wrote:
>>>  On Fri, Dec 16, 2016 at 02:27:54AM +0800, Icenowy Zheng wrote:
>>>>  An operating point table is needed for the cpu frequency adjusting to
>>>>  work.
>>>>
>>>>  The operating point table is converted from the common value in
>>>>  extracted script.fex from many A33 board/tablets.
>>>>
>>>>  Signed-off-by: Icenowy Zheng 
>>>>  ---
>>>>  Changes since v1:
>>>>  - Fix format problem (blank lines).
>>>>  - Removed the 1.344GHz operating point, as it's overvoltage and 
>>>> overclocked.
>>>>
>>>>  This patch depends on the following patchset:
>>>>
>>>>  
>>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473962.html
>>>>
>>>>  It's the v2 of the [PATCH 4/6] in this patchset.
>>>>
>>>>  I think this operating point table may also apply to A23, as there's no
>>>>  difference except the points over 1.2GHz between A23 and A33's stock dvfs 
>>>> table.
>>>>
>>>>  But as A23 CCU may not have the necessary fixes, I won't add the table to 
>>>> A23
>>>>  now.
>>>>
>>>>  Chen-Yu, could you test the CCU fixes I described in the patchset above 
>>>> on A23,
>>>>  then test this operating points table?
>>>>
>>>>  If it's necessary, you can send out the CCU fixes and add one more patch 
>>>> that
>>>>  moves this opp-v2 table to sun8i-a23-a33.dtsi .
>>>>
>>>>   arch/arm/boot/dts/sun8i-a33.dtsi | 35 +++
>>>>   1 file changed, 35 insertions(+)
>>>>
>>>>  diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi 
>>>> b/arch/arm/boot/dts/sun8i-a33.dtsi
>>>>  index 504996cbee29..0f5b2af72981 100644
>>>>  --- a/arch/arm/boot/dts/sun8i-a33.dtsi
>>>>  +++ b/arch/arm/boot/dts/sun8i-a33.dtsi
>>>>  @@ -46,7 +46,42 @@
>>>>   #include 
>>>>
>>>>   / {
>>>>  + cpu0_opp_table: opp_table0 {
>>>>  + compatible = "operating-points-v2";
>>>>  + opp-shared;
>>>>  +
>>>>  + opp@64800 {
>>>>  + opp-hz = /bits/ 64 <64800>;
>>>>  + opp-microvolt = <104>;
>>>>  + clock-latency-ns = <244144>; /* 8 32k periods */
>>>>  + };
>>>>  +
>>>>  + opp@81600 {
>>>>  + opp-hz = /bits/ 64 <81600>;
>>>>  + opp-microvolt = <110>;
>>>>  + clock-latency-ns = <244144>; /* 8 32k periods */
>>>>  + };
>>>>  +
>>>>  + opp@100800 {
>>>>  + opp-hz = /bits/ 64 <100800>;
>>>>  + opp-microvolt = <120>;
>>>>  + clock-latency-ns = <244144>; /* 8 32k periods */
>>>>  + };
>>>>  +
>>>>  + opp@12 {
>>>>  + opp-hz = /bits/ 64 <12>;
>>>>  + opp-microvolt = <132>;
>>>>  + clock-latency-ns = <244144>; /* 8 32k periods */
>>>>  + };
>>>>  + };
>>>>  +

Also, there are a lot more operating points for the A33, see:
https://github.com/QSchulz/linux/blob/v4.9-rc4_adc_a31_v7/cpufreq_a33/arch/arm/boot/dts/sun8i-a33.dtsi#L323-L340

They are present in the Allwinner Linux source code and in the fex of
all A33-based boards.

Is there a reason for not adding all opp?

Quentin

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


Re: [PATCH v2] ARM: dts: sun8i: add opp-v2 table for A33

2016-12-19 Thread Quentin Schulz
Hi,

On 19/12/2016 15:06, Icenowy Zheng wrote:
> 
> After proper testing of A23 ccu, the operating points can also apply to A23.
> (According to A23 devices' fex)
> 

I disagree. I've looked into using the same operating points for A23 and
A33 for CPUfreq and I came to the conclusion that not all A23-based
boards share the same operating points. You can find the fex files for
the different boards here:
https://github.com/linux-sunxi/sunxi-boards/tree/master/sys_config/a23

After gathering all supported frequencies/voltages for each A23-based
boards, I found that only the following frequencies and voltages are
supported by all A23-based boards:

 - 1008 MHz, 1220 mV
 - 816 MHz, 1120 mV
 - 600 MHz, 1040 mV

Quentin

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


Re: [PATCH v2 02/11] mfd: axp20x: add volatile and writeable reg ranges for VBUS power supply driver

2016-12-19 Thread Quentin Schulz
Hi Chen-Yu,

On 14/12/2016 16:43, Chen-Yu Tsai wrote:
> On Fri, Dec 9, 2016 at 7:04 PM, Quentin Schulz
>  wrote:
>> The X-Powers AXP20X and AXP22X PMICs allow to choose the maximum voltage
>> and minimum current delivered by the VBUS power supply.
>>
>> This adds the register used by the VBUS power supply driver to the range
>> of volatile and writeable regs ranges.
>>
>> Signed-off-by: Quentin Schulz 
>> ---
>>
>> added in v2
>>
>>  drivers/mfd/axp20x.c | 4 
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>> index ba130be..6ee2cc6 100644
>> --- a/drivers/mfd/axp20x.c
>> +++ b/drivers/mfd/axp20x.c
>> @@ -65,12 +65,14 @@ 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),
> 
> This is already covered by the previous entry.
> 
>> regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
>> regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
>>  };
>>
>>  static const struct regmap_range axp20x_volatile_ranges[] = {
>> regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
>> +   regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT, AXP20X_VBUS_IPSOUT_MGMT),
> 
> And I'm not sure why you specify it as volatile? The PMIC doesn't change any
> of the bits in this register on its own.
> 

I got things mixed up between the work on the battery driver I'll soon
send (which actually needs updated reg ranges) and this VBUS driver.
Sorry for that.

> Same for the AXP22x bits. So basically I think you don't need this patch.
> 

Indeed. Should I send a v3 to remove this patch or is it fine for you to
ignore this one?

Thanks!
Quentin

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


[PATCH v9 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-12-13 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. This patch adds the ADC driver which is
based on the MFD for the same SoCs ADC.

This also registers the thermal adc channel in the iio map array so
iio_hwmon could use it without modifying the Device Tree. This registers
the driver in the thermal framework.

The thermal sensor requires the IP to be in touchscreen mode to return
correct values. Therefore, if the user is continuously reading the ADC
channel(s), the thermal framework in which the thermal sensor is
registered will switch the IP in touchscreen mode to get a temperature
value and requires a delay of 100ms (because of the mode switching),
then the ADC will switch back to ADC mode and requires also a delay of
100ms. If the ADC readings are critical to user and the SoC temperature
is not, this driver is capable of not registering the thermal sensor in
the thermal framework and thus, "quicken" the ADC readings.

This driver probes on three different platform_device_id to take into
account slight differences (registers bit and temperature computation)
between Allwinner SoCs ADCs.

Signed-off-by: Quentin Schulz 
Acked-by: Maxime Ripard 
Acked-by: Jonathan Cameron 
Acked-for-MFD-by: Lee Jones 
---

v9:
 - clarify comment on why we have to use the parent node as node for
 registering in thermal framework, (backward compatibility)
 - clarify comment on why we can disable CONFIG_THERMAL_OF,
 - clarify Kconfig help to say that CONFIG_THERMAL_OF can be disabled
 but should not in most cases,
 - make return value of devm_thermal_zone_of_sensor_register a local
 variable of the condition block,
 - correct scale from _PLUS_MICRO to _PLUS_NANO for ADC raw readings
 scale,

v8:
 - remove Kconfig depends on !TOUCHSCREEN_SUN4I (moved to
MFD_SUN4I_GPADC),
 - fix return values of regmap_irq_get_virq and platform_get_irq_byname
stored in an unsigned int and then check if negative,
 - fix uninitialized ret value when an error occurs while registering
the thermal sensor in the framework,

v7:
 - add Kconfig depends on !TOUCHSCREEN_SUN4I,
 - remove Kconfig selects THERMAL_OF,
 - do not register thermal sensor if CONFIG_THERMAL_OF is disabled,
 - disable irq in irq_handler rather than in read_raw,
 - add delay when switching the IP's mode or channel (delay empirically found),
 - quicken thermal sensor interrupt period,
 - add masks for channel bits,
 - fix deadlock in sun4i_gpadc_read if regmap_read/write fails,
 - move some logic from sun4i_gpadc_read to sun4i_prepare_for_irq,
 - mark last busy for runtime_pm only on success in sun4i_gpadc_read,
 - remove cached values,
 - increase wait_for_completion_timeout timeout to 1s to be sure to not miss the
 thermal interrupt,
 - add voltage scale,
 - use devm_iio_device_register,

v6:
 - remove "-mfd" from filenames and variables inside MFD driver,
 - use DEFINE_RES_IRQ_NAMED instead of setting resources manually,
 - cosmetic changes,
 - use IDs and switch over ID to get cells specific to an architecture, instead
 of using cells direclty, in of_device_id.data,
 - compute size of mfd_cells array instead of hardcoded one,

v5:
 - correct mail address,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - rename defines from SUNXI_* to SUN4I_* or SUN6I_*,
 - remove TP in defines name,
 - rename SUNXI_IRQ_* to SUN4I_GPADC_IRQ_* for consistency,
 - use devm functions for regmap_add_irq_chip and mfd_add_devices,
 - remove remove functions (now empty thanks to devm functions),

v3:
 - use defines in regmap_irq instead of hard coded BITs,
 - use of_device_id data field to chose which MFD cells to add considering
   the compatible responsible of the MFD probe,
 - remove useless initializations,
 - disable all interrupts before adding them to regmap_irqchip,
 - add goto error label in probe,
 - correct wrapping in header license,
 - move defines from IIO driver to header,
 - use GENMASK to limit the size of the variable passed to a macro,
 - prefix register BIT defines with the name of the register,
 - reorder defines,

v2:
 - add license headers,
 - reorder alphabetically includes,
 - add SUNXI_GPADC_ prefixes for defines,

 drivers/iio/adc/Kconfig   |  17 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 613 ++
 include/linux/mfd/sun4i-gpadc.h   |   2 +
 4 files changed, 633 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 99c0514..6a6d369 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -434,6 +434,23 @@ config STX104
  The base port addresses for the devices may be configured via the base
  array module parameter.
 
+config SUN4I_GPADC
+   tristate "Support for the Allwinner SoCs GPADC"
+   depends on IIO
+   depends on MFD_SUN4I_GPADC
+   help
+ Say yes here to bu

[PATCH v9 2/3] mfd: Kconfig: MFD_SUN4I_GPADC depends on !TOUCHSCREN_SUN4I_GPADC

2016-12-13 Thread Quentin Schulz
MFD_SUN4I_GPADC and TOUCHSCREEN_SUN4I are incompatible (both are drivers
for Allwinner SoCs' ADC). This makes sure TOUCHSCREEN_SUN4I isn't
enabled while MFD_SUN4I_GPADC is enabled.

Signed-off-by: Quentin Schulz 
---

added in v8. I wrongly put the XOR dependance for SUN4I_GPADC and
TOUCHSCREEN_SUN4I instead of for MFD_SUN4I_GPADC and TOUCHSCREEN_SUN4I.

 drivers/mfd/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 443ee50..e803884 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -45,6 +45,7 @@ config MFD_SUN4I_GPADC
select MFD_CORE
select REGMAP_MMIO
depends on ARCH_SUNXI || COMPILE_TEST
+   depends on !TOUCHSCREEN_SUN4I
help
  Select this to get support for Allwinner SoCs (A10, A13 and A31) ADC.
  This driver will only map the hardware interrupt and registers, you
-- 
2.9.3



[PATCH v9 0/3] add support for Allwinner SoCs ADC

2016-12-13 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used
either for the ADC or the touchscreen and the fifth channel is used for
the thermal sensor. We currently have a driver for the two latter
functions in drivers/input/touchscreen/sun4i-ts.c but we don't have
access to the ADC feature at all. It is meant to replace the current
driver by using MFD and subdrivers.

This adds initial support for Allwinner SoCs ADC with all features. Yet,
the touchscreen is not implemented but will be added later. To switch
between touchscreen and ADC modes, you need to poke a few bits in
registers and (de)activate an interrupt (pen-up).

When changing modes or channels, the IP is in inconsistent mode and has
no register or interrupt to notify the kernel when it's stable and ready
to return correct values. Therefore, we add a delay of 100ms when
changing modes and 10ms when changing channels. These values have been
found empirically.

An MFD is provided to let the input driver activate the pen-up interrupt
through a virtual interrupt, poke a few bits via regmap and read data
from the ADC driver while both (and iio_hwmon) are probed by the MFD.

The thermal sensor requires the IP to be in touchscreen mode to return
correct values. Therefore, if the user is continuously reading the ADC
channel(s), the thermal framework in which the thermal sensor is
registered will switch the IP in touchscreen mode to get a temperature
value and requires a delay of 100ms (because of the mode switching),
then the ADC will switch back to ADC mode and requires also a delay of
100ms. If the ADC readings are critical to user and the SoC temperature
is not, this driver is capable of not registering the thermal sensor in
the thermal framework and thus, "quicken" the ADC readings. In most use
cases, the SoC temperature is more critical (for cpu throttling for
example or activating cooling devices) than ADC readings, thus it is
enabled by default in multi_v7_defconfig and in sunxi_defconfig (default
being added in this patch series).

There are slight variations between the different SoCs ADC like the
address of some registers and the scale and offset to apply to raw
thermal sensor values. These variations are handled by using different
platform_device_id, passed to the sub-drivers when they are probed by
the MFD.



Removal of proposed patch for iio_hwmon's iio channel's label in v3. The
patch induces irreversible ABI changes and will be handled as a separate
patch since I think it is not absolutely necessary to have labels yet in
iio_hwmon.

Removal of proposed patch for reattaching of_node of the MFD to the MFD
cell device structure in v3. As Lee Jones said, this patch might cause
"unintended side-effects for existing drivers.". Moreover, this patch
introduced a bug of multiple probe of this MFD driver I haven't
identified yet. This patch aimed at allowing the ADC driver (which is a
child of the MFD and not present in the DT) to register in the thermal
framework. The thermal driver has a phandle to the MFD node which is
used to match against the MFD of_node but since the ADC driver has no
node in the DT, could not register in the thermal framework. The other
solution is to "impersonate" the MFD when registering in the thermal
framework since the device is only used to match the phandle and the
of_node, an other structure passed by parameter being used to compute
temperatures.

(in the ADC driver, probed by the MFD driver) instead of:
tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info,
   &sun4i_ts_tz_ops);
we now have:
tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, info,
   &sun4i_ts_tz_ops);

Removal of proposed patch to use late_initcall for iio_hwmon probe
deferring.

Removal of patch for iio_hwmon probe deferring due to being applied to
 -next by Guenter Roeck.

This patch series requires this[1] patch which has already been merged
by Lee Jones.

[1] https://patchwork.kernel.org/patch/9333547/

Quentin Schulz (3):
  ARM: sunxi_defconfig: Add CONFIG_THERMAL_OF
  mfd: Kconfig: MFD_SUN4I_GPADC depends on !TOUCHSCREN_SUN4I_GPADC
  iio: adc: add support for Allwinner SoCs ADC

 arch/arm/configs/sunxi_defconfig  |   1 +
 drivers/iio/adc/Kconfig   |  17 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 613 ++
 drivers/mfd/Kconfig   |   1 +
 include/linux/mfd/sun4i-gpadc.h   |   2 +
 6 files changed, 635 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

-- 
2.9.3



[PATCH v9 1/3] ARM: sunxi_defconfig: Add CONFIG_THERMAL_OF

2016-12-13 Thread Quentin Schulz
This enables CONFIG_THERMAL_OF by default for sunxi_defconfig. It is
required to get Allwinner SoCs' temperature from the GPADC driver.

The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used
either for the ADC or the touchscreen and the fifth channel is used for
the thermal sensor.

The thermal sensor requires the IP to be in touchscreen mode to return
correct values. Therefore, if the user is continuously reading the ADC
channel(s), the thermal framework in which the thermal sensor is
registered will switch the IP in touchscreen mode to get a temperature
value and requires a delay of 100ms (because of the mode switching),
then the ADC will switch back to ADC mode and requires also a delay of
100ms. If the ADC readings are critical to user and the SoC temperature
is not, the GPADC driver is capable of not registering the thermal
sensor in the thermal framework and thus, "quicken" the ADC readings. In
most use cases, the SoC temperature is more critical (for cpu throttling
for example or activating cooling devices) than ADC readings, thus it is
now enabled by default.

Signed-off-by: Quentin Schulz 
---

v8:
 - more explanatory commit log,

added in v7

 arch/arm/configs/sunxi_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 714da33..8aaeae3 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -83,6 +83,7 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_AXP20X_POWER=y
 CONFIG_THERMAL=y
+CONFIG_THERMAL_OF=y
 CONFIG_CPU_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
-- 
2.9.3



Re: [PATCH v2 00/11] add support for VBUS max current and min voltage limits AXP20X and AXP22X PMICs

2016-12-12 Thread Quentin Schulz
Hi all,

I forgot to add a question to my cover letter so here it is:

The X-Powers AXP209 and AXP223 PMICs allow to not limit the maximal
current for the VBUS power supply.[1]
(If a Chinese-speaking person could check it's the same for the AXP221
that would be great also[2]).

In the get_property (axp20x_usb_power_get_property) of the power supply
driver, I see that we use -1 as value for "no limit". Should we use the
same (-1) value for the set_property (axp20x_usb_power_set_property) to
disable max current limit?

[1] http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf page 33,
REG 30H, BITS 0 & 1
[2]
http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
page 33, REG 30H, BITS 0 & 1 => 不限流 is written for when the BIT(1) is
set.

Thanks,
Quentin

On 09/12/2016 12:04, Quentin Schulz wrote:
> The X-Powers AXP209 and AXP20X PMICs are able to set a limit for the
> VBUS power supply for both max current and min voltage supplied. This
> series of patch adds the possibility to set these limits from sysfs.
> 
> Also, the AXP223 PMIC shares most of its behaviour with the AXP221 but
> the former can set the VBUS power supply max current to 100mA, unlike
> the latter. The AXP223 VBUS power supply driver used to probe on the
> AXP221 compatible. This series of patch introduces a new compatible for
> the AXP223 to be able to set the current max limit to 100mA.
> 
> With that new compatible, boards having the AXP223 see their DT updated
> to use the VBUS power supply driver with the correct compatible.
> 
> This series of patch also migrates from of_device_is_compatible function
> to the data field of of_device_id to identify the compatible used to
> probe. This improves the code readability.
> 
> Mostly cosmetic changes in v2 and adding volatile and writeable regs to
> AXP20X and AXP22X MFD cells for the VBUS power supply driver.
> 
> Quentin Schulz (11):
>   power: supply: axp20x_usb_power: use of_device_id data field instead
> of device_is_compatible
>   mfd: axp20x: add volatile and writeable reg ranges for VBUS power
> supply driver
>   power: supply: axp20x_usb_power: set min voltage and max current from
> sysfs
>   Documentation: DT: binding: axp20x_usb_power: add axp223 compatible
>   power: supply: axp20x_usb_power: add 100mA max current limit for
> AXP223
>   mfd: axp20x: add separate MFD cell for AXP223
>   ARM: dtsi: add DTSI for AXP223
>   ARM: dts: sun8i-a33-olinuxino: use AXP223 DTSI
>   ARM: dts: sun8i-a33-sinlinx-sina33: use AXP223 DTSI
>   ARM: dts: sun8i-r16-parrot: use AXP223 DTSI
>   ARM: dtsi: sun8i-reference-design-tablet: use AXP223 DTSI
> 
>  .../bindings/power/supply/axp20x_usb_power.txt |   5 +
>  arch/arm/boot/dts/axp223.dtsi  |  58 +++
>  arch/arm/boot/dts/sun8i-a33-olinuxino.dts  |   2 +-
>  arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts |   2 +-
>  arch/arm/boot/dts/sun8i-r16-parrot.dts |   2 +-
>  .../boot/dts/sun8i-reference-design-tablet.dtsi|   2 +-
>  drivers/mfd/axp20x.c   |  32 +-
>  drivers/power/supply/axp20x_usb_power.c    | 116 
> ++---
>  8 files changed, 197 insertions(+), 22 deletions(-)
>  create mode 100644 arch/arm/boot/dts/axp223.dtsi
> 

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


Re: [PATCH v8 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-12-11 Thread Quentin Schulz
Hi Maxime,

On 10/12/2016 10:44, Maxime Ripard wrote:
> Hi,
> 
> Just some minor comments.
> 
> On Fri, Dec 09, 2016 at 11:22:36AM +0100, Quentin Schulz wrote:
>> +/*
>> + * Since the thermal sensor needs the IP to be in touchscreen mode and
>> + * there is no register to know if the IP has finished its transition
>> + * between the two modes, a delay is required when switching modes. This
>> + * slows down ADC readings while the latter are critical data to the
> 
> The latter between what and what?
> 
>> + * user. Disabling CONFIG_THERMAL_OF in kernel configuration allows the
>> + * user to avoid registering the thermal sensor (thus unavailable) and
> 
> Isn't it obvious that it's not going to be available if you do not
> register it?
> 
>> + * does not switch between modes thus "quicken" the ADC readings.
>> + * The thermal sensor should be enabled by default since the SoC
>> + * temperature is usually more critical than ADC readings.
> 
> This last sentence should be in the Kconfig help. You cannot expect
> that all your users will read all the source code they want to compile
> :)
> 
> Overall, I think this comment is kind of missing the point, maybe
> something like:
> 
> /*
>  * Since the controller needs to be in touchscreen mode for its
>  * thermal sensor to operate properly, and that switching between the
>  * two modes needs a delay, always registering in the thermal
>  * framework will significantly slow down the conversion rate of the
>  * ADCs.
>  *
>  * Therefore, instead of depending on THERMAL_OF in Kconfig, we only
>  * register the sensor if that option is enabled, eventually leaving
>  * that choice to the user.
>  */
> 
> Would be much clearer.
> 
>> + */
>> +
>> +if (IS_ENABLED(CONFIG_THERMAL_OF)) {
>> +/*
>> + * This driver is a child of an MFD which has a node in the DT but not
>> + * its children. Therefore, the resulting devices of this driver do not
> 
> Wrong indentation for the comment, and saying why the MFD children
> don't have a node in the DT (backward compatibility) would be nice.
> 

Thanks for the comments, that's indeed much clearer.

>> + * have an of_node variable.
>> + * However, its parent (the MFD driver) has an of_node variable and
>> + * since devm_thermal_zone_of_sensor_register uses its first argument to
>> + * match the phandle defined in the node of the thermal driver with the
>> + * of_node of the device passed as first argument and the third argument
>> + * to call ops from thermal_zone_of_device_ops, the solution is to use
>> + * the parent device as first argument to match the phandle with its
>> + * of_node, and the device from this driver as third argument to return
>> + * the temperature.
>> + */
>> +tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0,
>> +   info,
>> +   &sun4i_ts_tz_ops);
> 
> I don't think tzd is used anywhere else in your function, it can be
> made local to this block.
> 

ACK.

Thanks,
Quentin

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



signature.asc
Description: OpenPGP digital signature


[PATCH v2 01/11] power: supply: axp20x_usb_power: use of_device_id data field instead of device_is_compatible

2016-12-09 Thread Quentin Schulz
This replaces calls to of_device_is_compatible to check data field of
of_device_id matched when probing the driver.

Signed-off-by: Quentin Schulz 
---
 drivers/power/supply/axp20x_usb_power.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/power/supply/axp20x_usb_power.c 
b/drivers/power/supply/axp20x_usb_power.c
index 6af6feb..8985646 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -45,6 +46,7 @@ struct axp20x_usb_power {
struct device_node *np;
struct regmap *regmap;
struct power_supply *supply;
+   int axp20x_id;
 };
 
 static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
@@ -86,8 +88,7 @@ static int axp20x_usb_power_get_property(struct power_supply 
*psy,
 
switch (v & AXP20X_VBUS_CLIMIT_MASK) {
case AXP20X_VBUC_CLIMIT_100mA:
-   if (of_device_is_compatible(power->np,
-   "x-powers,axp202-usb-power-supply")) {
+   if (power->axp20x_id == AXP202_ID) {
val->intval = 10;
} else {
val->intval = -1; /* No 100mA limit */
@@ -130,8 +131,7 @@ static int axp20x_usb_power_get_property(struct 
power_supply *psy,
 
val->intval = POWER_SUPPLY_HEALTH_GOOD;
 
-   if (of_device_is_compatible(power->np,
-   "x-powers,axp202-usb-power-supply")) {
+   if (power->axp20x_id == AXP202_ID) {
ret = regmap_read(power->regmap,
  AXP20X_USB_OTG_STATUS, &v);
if (ret)
@@ -214,11 +214,12 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
if (!power)
return -ENOMEM;
 
+   power->axp20x_id = (int)of_device_get_match_data(&pdev->dev);
+
power->np = pdev->dev.of_node;
power->regmap = axp20x->regmap;
 
-   if (of_device_is_compatible(power->np,
-   "x-powers,axp202-usb-power-supply")) {
+   if (power->axp20x_id == AXP202_ID) {
/* Enable vbus valid checking */
ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
 AXP20X_VBUS_MON_VBUS_VALID,
@@ -235,8 +236,7 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
 
usb_power_desc = &axp20x_usb_power_desc;
irq_names = axp20x_irq_names;
-   } else if (of_device_is_compatible(power->np,
-   "x-powers,axp221-usb-power-supply")) {
+   } else if (power->axp20x_id == AXP221_ID) {
usb_power_desc = &axp22x_usb_power_desc;
irq_names = axp22x_irq_names;
} else {
@@ -273,9 +273,13 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
 }
 
 static const struct of_device_id axp20x_usb_power_match[] = {
-   { .compatible = "x-powers,axp202-usb-power-supply" },
-   { .compatible = "x-powers,axp221-usb-power-supply" },
-   { }
+   {
+   .compatible = "x-powers,axp202-usb-power-supply",
+   .data = (void *)AXP202_ID,
+   }, {
+   .compatible = "x-powers,axp221-usb-power-supply",
+   .data = (void *)AXP221_ID,
+   }, { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
 
-- 
2.9.3



[PATCH v2 10/11] ARM: dts: sun8i-r16-parrot: use AXP223 DTSI

2016-12-09 Thread Quentin Schulz
Previously, the Allwinner Parrot R16 used everything declared in AXP221
DTSI while it has an AXP223 PMIC.

This corrects that so the Allwinner Parrot R16 can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-r16-parrot.dts 
b/arch/arm/boot/dts/sun8i-r16-parrot.dts
index 47553e5..6afdba3 100644
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -209,7 +209,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH v2 08/11] ARM: dts: sun8i-a33-olinuxino: use AXP223 DTSI

2016-12-09 Thread Quentin Schulz
Previously, the Olimex A33-OlinuXino used everything declared in AXP221
DTSI while it has an AXP223 PMIC.

This corrects that so the Olimex A33-OlinuXino can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts 
b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
index 9ea637e..3e8f2ec 100644
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
@@ -126,7 +126,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH v2 11/11] ARM: dtsi: sun8i-reference-design-tablet: use AXP223 DTSI

2016-12-09 Thread Quentin Schulz
Previously, the sun8i tablets used everything declared in AXP221 DTSI
while they have an AXP223 PMIC.

This corrects that so the sun8i tablets can get some features the AXP223
has (at the moment, ability to have 100mA as maximal current on VBUS
power supply).

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi 
b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index 08cd001..ea79c33 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -136,7 +136,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH v2 09/11] ARM: dts: sun8i-a33-sinlinx-sina33: use AXP223 DTSI

2016-12-09 Thread Quentin Schulz
Previously, the Sinlinx SinA33 used everything declared in AXP221 DTSI
while it has an AXP223 PMIC.

This corrects that so the Sinlinx SinA33 can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts 
b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index fef6abc..1fc459c 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -145,7 +145,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH v2 06/11] mfd: axp20x: add separate MFD cell for AXP223

2016-12-09 Thread Quentin Schulz
The AXP223 shares most of its logic with the AXP221 but has some
differences for the VBUS power supply driver. Thus, to probe the driver
with the correct compatible, the AXP221 and the AXP223 now have separate
MFD cells.

AXP221 MFD cells are renamed from axp22x_cells to axp221_cells to avoid
confusion.

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---

v2:
 - correct indentation,
 - renaming axp22x_cells to axp221_cells to avoid confusion between axp22x,
axp221 and axp223

 drivers/mfd/axp20x.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 6ee2cc6..b31f123 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -591,7 +591,22 @@ static struct mfd_cell axp20x_cells[] = {
},
 };
 
-static struct mfd_cell axp22x_cells[] = {
+static struct mfd_cell axp221_cells[] = {
+   {
+   .name   = "axp20x-pek",
+   .num_resources  = ARRAY_SIZE(axp22x_pek_resources),
+   .resources  = axp22x_pek_resources,
+   }, {
+   .name   = "axp20x-regulator",
+   }, {
+   .name   = "axp20x-usb-power-supply",
+   .of_compatible  = "x-powers,axp221-usb-power-supply",
+   .num_resources  = ARRAY_SIZE(axp22x_usb_power_supply_resources),
+   .resources  = axp22x_usb_power_supply_resources,
+   },
+};
+
+static struct mfd_cell axp223_cells[] = {
{
.name   = "axp20x-pek",
.num_resources  = ARRAY_SIZE(axp22x_pek_resources),
@@ -600,7 +615,7 @@ static struct mfd_cell axp22x_cells[] = {
.name   = "axp20x-regulator",
}, {
.name   = "axp20x-usb-power-supply",
-   .of_compatible  = "x-powers,axp221-usb-power-supply",
+   .of_compatible  = "x-powers,axp223-usb-power-supply",
.num_resources  = ARRAY_SIZE(axp22x_usb_power_supply_resources),
.resources  = axp22x_usb_power_supply_resources,
},
@@ -793,9 +808,14 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
break;
case AXP221_ID:
+   axp20x->nr_cells = ARRAY_SIZE(axp221_cells);
+   axp20x->cells = axp221_cells;
+   axp20x->regmap_cfg = &axp22x_regmap_config;
+   axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
+   break;
case AXP223_ID:
-   axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
-   axp20x->cells = axp22x_cells;
+   axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
+   axp20x->cells = axp223_cells;
axp20x->regmap_cfg = &axp22x_regmap_config;
axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
break;
-- 
2.9.3



[PATCH v2 00/11] add support for VBUS max current and min voltage limits AXP20X and AXP22X PMICs

2016-12-09 Thread Quentin Schulz
The X-Powers AXP209 and AXP20X PMICs are able to set a limit for the
VBUS power supply for both max current and min voltage supplied. This
series of patch adds the possibility to set these limits from sysfs.

Also, the AXP223 PMIC shares most of its behaviour with the AXP221 but
the former can set the VBUS power supply max current to 100mA, unlike
the latter. The AXP223 VBUS power supply driver used to probe on the
AXP221 compatible. This series of patch introduces a new compatible for
the AXP223 to be able to set the current max limit to 100mA.

With that new compatible, boards having the AXP223 see their DT updated
to use the VBUS power supply driver with the correct compatible.

This series of patch also migrates from of_device_is_compatible function
to the data field of of_device_id to identify the compatible used to
probe. This improves the code readability.

Mostly cosmetic changes in v2 and adding volatile and writeable regs to
AXP20X and AXP22X MFD cells for the VBUS power supply driver.

Quentin Schulz (11):
  power: supply: axp20x_usb_power: use of_device_id data field instead
of device_is_compatible
  mfd: axp20x: add volatile and writeable reg ranges for VBUS power
supply driver
  power: supply: axp20x_usb_power: set min voltage and max current from
sysfs
  Documentation: DT: binding: axp20x_usb_power: add axp223 compatible
  power: supply: axp20x_usb_power: add 100mA max current limit for
AXP223
  mfd: axp20x: add separate MFD cell for AXP223
  ARM: dtsi: add DTSI for AXP223
  ARM: dts: sun8i-a33-olinuxino: use AXP223 DTSI
  ARM: dts: sun8i-a33-sinlinx-sina33: use AXP223 DTSI
  ARM: dts: sun8i-r16-parrot: use AXP223 DTSI
  ARM: dtsi: sun8i-reference-design-tablet: use AXP223 DTSI

 .../bindings/power/supply/axp20x_usb_power.txt |   5 +
 arch/arm/boot/dts/axp223.dtsi  |  58 +++
 arch/arm/boot/dts/sun8i-a33-olinuxino.dts  |   2 +-
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts |   2 +-
 arch/arm/boot/dts/sun8i-r16-parrot.dts |   2 +-
 .../boot/dts/sun8i-reference-design-tablet.dtsi|   2 +-
 drivers/mfd/axp20x.c   |  32 +-
 drivers/power/supply/axp20x_usb_power.c| 116 ++---
 8 files changed, 197 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm/boot/dts/axp223.dtsi

-- 
2.9.3



[PATCH v2 02/11] mfd: axp20x: add volatile and writeable reg ranges for VBUS power supply driver

2016-12-09 Thread Quentin Schulz
The X-Powers AXP20X and AXP22X PMICs allow to choose the maximum voltage
and minimum current delivered by the VBUS power supply.

This adds the register used by the VBUS power supply driver to the range
of volatile and writeable regs ranges.

Signed-off-by: Quentin Schulz 
---

added in v2

 drivers/mfd/axp20x.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index ba130be..6ee2cc6 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -65,12 +65,14 @@ 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_DCDC_MODE, AXP20X_FG_RES),
regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
 };
 
 static const struct regmap_range axp20x_volatile_ranges[] = {
regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
+   regmap_reg_range(AXP20X_VBUS_IPSOUT_MGMT, AXP20X_VBUS_IPSOUT_MGMT),
regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
@@ -91,11 +93,13 @@ 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_DCDC_MODE, AXP22X_BATLOW_THRES1),
 };
 
 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(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
-- 
2.9.3



[PATCH v2 04/11] Documentation: DT: binding: axp20x_usb_power: add axp223 compatible

2016-12-09 Thread Quentin Schulz
This adds the "x-powers,axp223-usb-power-supply" to the list of
compatibles for AXP20X VBUS power supply driver.

Signed-off-by: Quentin Schulz 
---

v2:
 - adding small explanation on AXP223 variation compared to the AXP221,

 Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt | 5 +
 1 file changed, 5 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt 
b/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
index f1d7bee..ba8d35f 100644
--- a/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
+++ b/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
@@ -3,6 +3,11 @@ AXP20x USB power supply
 Required Properties:
 -compatible: One of: "x-powers,axp202-usb-power-supply"
  "x-powers,axp221-usb-power-supply"
+ "x-powers,axp223-usb-power-supply"
+
+The AXP223 PMIC shares most of its behaviour with the AXP221 but has slight
+variations such as the former being able to set the VBUS power supply max
+current to 100mA, unlike the latter.
 
 This node is a subnode of the axp20x PMIC.
 
-- 
2.9.3



[PATCH v2 05/11] power: supply: axp20x_usb_power: add 100mA max current limit for AXP223

2016-12-09 Thread Quentin Schulz
The X-Powers AXP223 shares most of its behaviour with the AXP221 PMIC
but allows the VBUS power supply max current to be set to 100mA (like
the AXP209 PMIC).

This basically adds a new compatible to the VBUS power supply driver and
adds a check on the compatible when setting current max limit.

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---
 drivers/power/supply/axp20x_usb_power.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/power/supply/axp20x_usb_power.c 
b/drivers/power/supply/axp20x_usb_power.c
index 9e3f4ae..1bcb025 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -90,11 +90,10 @@ static int axp20x_usb_power_get_property(struct 
power_supply *psy,
 
switch (v & AXP20X_VBUS_CLIMIT_MASK) {
case AXP20X_VBUC_CLIMIT_100mA:
-   if (power->axp20x_id == AXP202_ID) {
-   val->intval = 10;
-   } else {
+   if (power->axp20x_id == AXP221_ID)
val->intval = -1; /* No 100mA limit */
-   }
+   else
+   val->intval = 10;
break;
case AXP20X_VBUC_CLIMIT_500mA:
val->intval = 50;
@@ -317,7 +316,8 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
 
usb_power_desc = &axp20x_usb_power_desc;
irq_names = axp20x_irq_names;
-   } else if (power->axp20x_id == AXP221_ID) {
+   } else if (power->axp20x_id == AXP221_ID ||
+  power->axp20x_id == AXP223_ID) {
usb_power_desc = &axp22x_usb_power_desc;
irq_names = axp22x_irq_names;
} else {
@@ -360,6 +360,9 @@ static const struct of_device_id axp20x_usb_power_match[] = 
{
}, {
.compatible = "x-powers,axp221-usb-power-supply",
.data = (void *)AXP221_ID,
+   }, {
+   .compatible = "x-powers,axp223-usb-power-supply",
+   .data = (void *)AXP223_ID,
}, { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
-- 
2.9.3



[PATCH v2 07/11] ARM: dtsi: add DTSI for AXP223

2016-12-09 Thread Quentin Schulz
The AXP223 shares most of its logic with the AXP221 but it has some
differences for the VBUS driver.

Signed-off-by: Quentin Schulz 
Acked-by: Chen-Yu Tsai 
---

v2:
 - adding small explanation of AXP223 variation compared to AXP221,

 arch/arm/boot/dts/axp223.dtsi | 58 +++
 1 file changed, 58 insertions(+)
 create mode 100644 arch/arm/boot/dts/axp223.dtsi

diff --git a/arch/arm/boot/dts/axp223.dtsi b/arch/arm/boot/dts/axp223.dtsi
new file mode 100644
index 000..b91b6c1
--- /dev/null
+++ b/arch/arm/boot/dts/axp223.dtsi
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 Free Electrons
+ *
+ * Quentin Schulz 
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * AXP223 Integrated Power Management Chip
+ * http://www.x-powers.com/product/AXP22X.php
+ * http://dl.linux-sunxi.org/AXP/AXP223-en.pdf
+ *
+ * The AXP223 shares most of its logic with the AXP221 but it has some
+ * differences, for the VBUS driver for example.
+ */
+
+#include "axp22x.dtsi"
+
+&usb_power_supply {
+   compatible = "x-powers,axp223-usb-power-supply";
+};
-- 
2.9.3



[PATCH v2 03/11] power: supply: axp20x_usb_power: set min voltage and max current from sysfs

2016-12-09 Thread Quentin Schulz
AXP20X and AXP22X PMICs allow setting the min voltage and max current of
VBUS power supply. This adds entries in sysfs to allow to do so.

Signed-off-by: Quentin Schulz 
---

v2:
 - moving defines from header mfd/axp20x.h to the driver,
 - adding two functions to reduce indentation in axp20x_usb_power_set_property,
 - adding new define for VBUS register VHOLD bits offset,
 - switching return values in case of invalid value from 0 to -EINVAL,

 drivers/power/supply/axp20x_usb_power.c | 81 +
 1 file changed, 81 insertions(+)

diff --git a/drivers/power/supply/axp20x_usb_power.c 
b/drivers/power/supply/axp20x_usb_power.c
index 8985646..9e3f4ae 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -31,6 +31,8 @@
 #define AXP20X_USB_STATUS_VBUS_VALID   BIT(2)
 
 #define AXP20X_VBUS_VHOLD_uV(b)(400 + (((b) >> 3) & 7) * 
10)
+#define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
+#define AXP20X_VBUS_VHOLD_OFFSET   3
 #define AXP20X_VBUS_CLIMIT_MASK3
 #define AXP20X_VBUC_CLIMIT_900mA   0
 #define AXP20X_VBUC_CLIMIT_500mA   1
@@ -155,6 +157,81 @@ static int axp20x_usb_power_get_property(struct 
power_supply *psy,
return 0;
 }
 
+static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
+   int intval)
+{
+   int val;
+
+   switch (intval) {
+   case 400:
+   case 410:
+   case 420:
+   case 430:
+   case 440:
+   case 450:
+   case 460:
+   case 470:
+   val = (intval - 400) / 10;
+   return regmap_update_bits(power->regmap,
+ AXP20X_VBUS_IPSOUT_MGMT,
+ AXP20X_VBUS_VHOLD_MASK,
+ val << AXP20X_VBUS_VHOLD_OFFSET);
+   default:
+   return -EINVAL;
+   }
+
+   return -EINVAL;
+}
+
+static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power,
+   int intval)
+{
+   int val;
+
+   switch (intval) {
+   case 10:
+   if (power->axp20x_id == AXP221_ID)
+   return -EINVAL;
+   case 50:
+   case 90:
+   val = (90 - intval) / 40;
+   return regmap_update_bits(power->regmap,
+ AXP20X_VBUS_IPSOUT_MGMT,
+ AXP20X_VBUS_CLIMIT_MASK, val);
+   default:
+   return -EINVAL;
+   }
+
+   return -EINVAL;
+}
+
+static int axp20x_usb_power_set_property(struct power_supply *psy,
+enum power_supply_property psp,
+const union power_supply_propval *val)
+{
+   struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
+
+   switch (psp) {
+   case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+   return axp20x_usb_power_set_voltage_min(power, val->intval);
+
+   case POWER_SUPPLY_PROP_CURRENT_MAX:
+   return axp20x_usb_power_set_current_max(power, val->intval);
+
+   default:
+   return -EINVAL;
+   }
+
+   return -EINVAL;
+}
+
+static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
+  enum power_supply_property psp)
+{
+   return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
+  psp == POWER_SUPPLY_PROP_CURRENT_MAX;
+}
+
 static enum power_supply_property axp20x_usb_power_properties[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
@@ -178,7 +255,9 @@ static const struct power_supply_desc axp20x_usb_power_desc 
= {
.type = POWER_SUPPLY_TYPE_USB,
.properties = axp20x_usb_power_properties,
.num_properties = ARRAY_SIZE(axp20x_usb_power_properties),
+   .property_is_writeable = axp20x_usb_power_prop_writeable,
.get_property = axp20x_usb_power_get_property,
+   .set_property = axp20x_usb_power_set_property,
 };
 
 static const struct power_supply_desc axp22x_usb_power_desc = {
@@ -186,7 +265,9 @@ static const struct power_supply_desc axp22x_usb_power_desc 
= {
.type = POWER_SUPPLY_TYPE_USB,
.properties = axp22x_usb_power_properties,
.num_properties = ARRAY_SIZE(axp22x_usb_power_properties),
+   .property_is_writeable = axp20x_usb_power_prop_writeable,
.get_property = axp20x_usb_power_get_property,
+   .set_property = axp20x_usb_power_set_property,
 };
 
 static int axp20x_usb_power_probe(struct platform_device *pdev)
-- 
2.9.3



[PATCH v8 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-12-09 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. This patch adds the ADC driver which is
based on the MFD for the same SoCs ADC.

This also registers the thermal adc channel in the iio map array so
iio_hwmon could use it without modifying the Device Tree. This registers
the driver in the thermal framework.

The thermal sensor requires the IP to be in touchscreen mode to return
correct values. Therefore, if the user is continuously reading the ADC
channel(s), the thermal framework in which the thermal sensor is
registered will switch the IP in touchscreen mode to get a temperature
value and requires a delay of 100ms (because of the mode switching),
then the ADC will switch back to ADC mode and requires also a delay of
100ms. If the ADC readings are critical to user and the SoC temperature
is not, this driver is capable of not registering the thermal sensor in
the thermal framework and thus, "quicken" the ADC readings.

This driver probes on three different platform_device_id to take into
account slight differences (registers bit and temperature computation)
between Allwinner SoCs ADCs.

Signed-off-by: Quentin Schulz 
Acked-by: Maxime Ripard 
Acked-by: Jonathan Cameron 
Acked-for-MFD-by: Lee Jones 
---

v8:
 - remove Kconfig depends on !TOUCHSCREEN_SUN4I (moved to
MFD_SUN4I_GPADC),
 - fix return values of regmap_irq_get_virq and platform_get_irq_byname
stored in an unsigned int and then check if negative,
 - fix uninitialized ret value when an error occurs while registering
the thermal sensor in the framework,

v7:
 - add Kconfig depends on !TOUCHSCREEN_SUN4I,
 - remove Kconfig selects THERMAL_OF,
 - do not register thermal sensor if CONFIG_THERMAL_OF is disabled,
 - disable irq in irq_handler rather than in read_raw,
 - add delay when switching the IP's mode or channel (delay empirically found),
 - quicken thermal sensor interrupt period,
 - add masks for channel bits,
 - fix deadlock in sun4i_gpadc_read if regmap_read/write fails,
 - move some logic from sun4i_gpadc_read to sun4i_prepare_for_irq,
 - mark last busy for runtime_pm only on success in sun4i_gpadc_read,
 - remove cached values,
 - increase wait_for_completion_timeout timeout to 1s to be sure to not miss the
 thermal interrupt,
 - add voltage scale,
 - use devm_iio_device_register,

v6:
 - remove "-mfd" from filenames and variables inside MFD driver,
 - use DEFINE_RES_IRQ_NAMED instead of setting resources manually,
 - cosmetic changes,
 - use IDs and switch over ID to get cells specific to an architecture, instead
 of using cells direclty, in of_device_id.data,
 - compute size of mfd_cells array instead of hardcoded one,

v5:
 - correct mail address,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - rename defines from SUNXI_* to SUN4I_* or SUN6I_*,
 - remove TP in defines name,
 - rename SUNXI_IRQ_* to SUN4I_GPADC_IRQ_* for consistency,
 - use devm functions for regmap_add_irq_chip and mfd_add_devices,
 - remove remove functions (now empty thanks to devm functions),

v3:
 - use defines in regmap_irq instead of hard coded BITs,
 - use of_device_id data field to chose which MFD cells to add considering
   the compatible responsible of the MFD probe,
 - remove useless initializations,
 - disable all interrupts before adding them to regmap_irqchip,
 - add goto error label in probe,
 - correct wrapping in header license,
 - move defines from IIO driver to header,
 - use GENMASK to limit the size of the variable passed to a macro,
 - prefix register BIT defines with the name of the register,
 - reorder defines,

v2:
 - add license headers,
 - reorder alphabetically includes,
 - add SUNXI_GPADC_ prefixes for defines,

 drivers/iio/adc/Kconfig   |  16 +
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 612 ++
 include/linux/mfd/sun4i-gpadc.h   |   2 +
 4 files changed, 631 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 99c0514..67ed278 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -434,6 +434,22 @@ config STX104
  The base port addresses for the devices may be configured via the base
  array module parameter.
 
+config SUN4I_GPADC
+   tristate "Support for the Allwinner SoCs GPADC"
+   depends on IIO
+   depends on MFD_SUN4I_GPADC
+   help
+ Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
+ GPADC. This ADC provides 4 channels which can be used as an ADC or as
+ a touchscreen input and one channel for thermal sensor.
+
+ The thermal sensor is activated by default but slows down ADC
+ readings. You can disable CONFIG_THERMAL_OF to disable the CPU thermal
+ sensor if you want faster ADC readings.
+
+ To compile this driver as a module, choose M here: the module w

[PATCH v8 1/3] ARM: sunxi_defconfig: Add CONFIG_THERMAL_OF

2016-12-09 Thread Quentin Schulz
This enables CONFIG_THERMAL_OF by default for sunxi_defconfig. It is
required to get Allwinner SoCs' temperature from the GPADC driver.

The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used
either for the ADC or the touchscreen and the fifth channel is used for
the thermal sensor.

The thermal sensor requires the IP to be in touchscreen mode to return
correct values. Therefore, if the user is continuously reading the ADC
channel(s), the thermal framework in which the thermal sensor is
registered will switch the IP in touchscreen mode to get a temperature
value and requires a delay of 100ms (because of the mode switching),
then the ADC will switch back to ADC mode and requires also a delay of
100ms. If the ADC readings are critical to user and the SoC temperature
is not, the GPADC driver is capable of not registering the thermal
sensor in the thermal framework and thus, "quicken" the ADC readings. In
most use cases, the SoC temperature is more critical (for cpu throttling
for example or activating cooling devices) than ADC readings, thus it is
now enabled by default.

Signed-off-by: Quentin Schulz 
---

v8:
 - more explanatory commit log,

added in v7

 arch/arm/configs/sunxi_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 714da33..8aaeae3 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -83,6 +83,7 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_AXP20X_POWER=y
 CONFIG_THERMAL=y
+CONFIG_THERMAL_OF=y
 CONFIG_CPU_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
-- 
2.9.3



[PATCH v8 2/3] mfd: Kconfig: MFD_SUN4I_GPADC depends on !TOUCHSCREN_SUN4I_GPADC

2016-12-09 Thread Quentin Schulz
MFD_SUN4I_GPADC and TOUCHSCREEN_SUN4I are incompatible (both are drivers
for Allwinner SoCs' ADC). This makes sure TOUCHSCREEN_SUN4I isn't
enabled while MFD_SUN4I_GPADC is enabled.

Signed-off-by: Quentin Schulz 
---

added in v8. I wrongly put the XOR dependance for SUN4I_GPADC and
TOUCHSCREEN_SUN4I instead of for MFD_SUN4I_GPADC and TOUCHSCREEN_SUN4I.

 drivers/mfd/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 443ee50..e803884 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -45,6 +45,7 @@ config MFD_SUN4I_GPADC
select MFD_CORE
select REGMAP_MMIO
depends on ARCH_SUNXI || COMPILE_TEST
+   depends on !TOUCHSCREEN_SUN4I
help
  Select this to get support for Allwinner SoCs (A10, A13 and A31) ADC.
  This driver will only map the hardware interrupt and registers, you
-- 
2.9.3



[PATCH v8 0/3] add support for Allwinner SoCs ADC

2016-12-09 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used
either for the ADC or the touchscreen and the fifth channel is used for
the thermal sensor. We currently have a driver for the two latter
functions in drivers/input/touchscreen/sun4i-ts.c but we don't have
access to the ADC feature at all. It is meant to replace the current
driver by using MFD and subdrivers.

This adds initial support for Allwinner SoCs ADC with all features. Yet,
the touchscreen is not implemented but will be added later. To switch
between touchscreen and ADC modes, you need to poke a few bits in
registers and (de)activate an interrupt (pen-up).

When changing modes or channels, the IP is in inconsistent mode and has
no register or interrupt to notify the kernel when it's stable and ready
to return correct values. Therefore, we add a delay of 100ms when
changing modes and 10ms when changing channels. These values have been
found empirically.

An MFD is provided to let the input driver activate the pen-up interrupt
through a virtual interrupt, poke a few bits via regmap and read data
from the ADC driver while both (and iio_hwmon) are probed by the MFD.

The thermal sensor requires the IP to be in touchscreen mode to return
correct values. Therefore, if the user is continuously reading the ADC
channel(s), the thermal framework in which the thermal sensor is
registered will switch the IP in touchscreen mode to get a temperature
value and requires a delay of 100ms (because of the mode switching),
then the ADC will switch back to ADC mode and requires also a delay of
100ms. If the ADC readings are critical to user and the SoC temperature
is not, this driver is capable of not registering the thermal sensor in
the thermal framework and thus, "quicken" the ADC readings. In most use
cases, the SoC temperature is more critical (for cpu throttling for
example or activating cooling devices) than ADC readings, thus it is
enabled by default in multi_v7_defconfig and in sunxi_defconfig (default
being added in this patch series).

There are slight variations between the different SoCs ADC like the
address of some registers and the scale and offset to apply to raw
thermal sensor values. These variations are handled by using different
platform_device_id, passed to the sub-drivers when they are probed by
the MFD.



Removal of proposed patch for iio_hwmon's iio channel's label in v3. The
patch induces irreversible ABI changes and will be handled as a separate
patch since I think it is not absolutely necessary to have labels yet in
iio_hwmon.

Removal of proposed patch for reattaching of_node of the MFD to the MFD
cell device structure in v3. As Lee Jones said, this patch might cause
"unintended side-effects for existing drivers.". Moreover, this patch
introduced a bug of multiple probe of this MFD driver I haven't
identified yet. This patch aimed at allowing the ADC driver (which is a
child of the MFD and not present in the DT) to register in the thermal
framework. The thermal driver has a phandle to the MFD node which is
used to match against the MFD of_node but since the ADC driver has no
node in the DT, could not register in the thermal framework. The other
solution is to "impersonate" the MFD when registering in the thermal
framework since the device is only used to match the phandle and the
of_node, an other structure passed by parameter being used to compute
temperatures.

(in the ADC driver, probed by the MFD driver) instead of:
tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info,
   &sun4i_ts_tz_ops);
we now have:
tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, info,
   &sun4i_ts_tz_ops);

Removal of proposed patch to use late_initcall for iio_hwmon probe
deferring.

Removal of patch for iio_hwmon probe deferring due to being applied to
 -next by Guenter Roeck.

This patch series requires this[1] patch which has already been merged
by Lee Jones.

[1] https://patchwork.kernel.org/patch/9333547/

Quentin Schulz (3):
  ARM: sunxi_defconfig: Add CONFIG_THERMAL_OF
  mfd: Kconfig: MFD_SUN4I_GPADC depends on !TOUCHSCREN_SUN4I_GPADC
  iio: adc: add support for Allwinner SoCs ADC

 arch/arm/configs/sunxi_defconfig  |   1 +
 drivers/iio/adc/Kconfig   |  16 +
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 612 ++
 drivers/mfd/Kconfig   |   1 +
 include/linux/mfd/sun4i-gpadc.h   |   2 +
 6 files changed, 633 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

-- 
2.9.3



Re: [PATCH RESEND 2/2] gpio: axp209: add pinctrl support

2016-11-29 Thread Quentin Schulz
Hi Linus,

On 24/11/2016 15:17, Linus Walleij wrote:
> On Wed, Nov 23, 2016 at 3:11 PM, Quentin Schulz
>  wrote:
> 
>> The GPIOs present in the AXP209 PMIC have multiple functions. They
>> typically allow a pin to be used as GPIO input or output and can also be
>> used as ADC or regulator for example.[1]
>>
>> This adds the possibility to use all functions of the GPIOs present in
>> the AXP209 PMIC thanks to pinctrl subsystem.
>>
>> [1] see registers 90H, 92H and 93H at
>> http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf
>>
>> Signed-off-by: Quentin Schulz 
> 
> I need Maxime's review on this patch.
> 
>>  .../devicetree/bindings/gpio/gpio-axp209.txt   |  28 +-
> 
> Also move the bindings to pinctrl/pinctrl-axp209.txt
> 
>>  drivers/gpio/gpio-axp209.c | 551 
>> ++---
> 
> Combined drivers should be in drivers/pinctrl/*.
> 
> Make a separate patch moving the driver to
> drivers/pinctrl/pinctrl-axp209.c (remember -M to git format-patch)
> augment Kconfig and Makefile in both subsystems and make
> these patches on top of that.
> 

So basically:

 - first patch for adding pinctrl to the existing driver
 - second patch for moving the driver and binding from gpio to pinctrl
subsystem
 - third patch for both removing Kconfig entry and Makefile rule from
gpio subsystem, and adding a Kconfig entry and a Makefile rule in
pinctrl subsystem

Is that what you want?

Thanks,
Quentin

> I will deal with cross-merging the result between the GPIO
> and pin control trees.
> 
> Yours,
> Linus Walleij
> 

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


[PATCH v2] phy: phy-sun4i-usb: Add log when probing

2016-11-29 Thread Quentin Schulz
When phy-sun4i-usb's probing fails, it does not print the reason in
kernel log, forcing the developer to edit this driver to add info logs.
This commit makes the kernel print the reason of phy-sun4i-usb's probing
failure or a success message.

Signed-off-by: Quentin Schulz 
---
Sorry for the delay, I completely forgot to send a v2.

v2:
 - removing (from v1) debug message when devm_ioremap_resource fails,
 - changing dev_info to dev_dbg when driver is successfully loaded,

 drivers/phy/phy-sun4i-usb.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index fec34f5..f1b2848 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -632,19 +632,25 @@ static int sun4i_usb_phy_probe(struct platform_device 
*pdev)
 
data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
GPIOD_IN);
-   if (IS_ERR(data->id_det_gpio))
+   if (IS_ERR(data->id_det_gpio)) {
+   dev_err(dev, "Couldn't request ID GPIO\n");
return PTR_ERR(data->id_det_gpio);
+   }
 
data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
  GPIOD_IN);
-   if (IS_ERR(data->vbus_det_gpio))
+   if (IS_ERR(data->vbus_det_gpio)) {
+   dev_err(dev, "Couldn't request VBUS detect GPIO\n");
return PTR_ERR(data->vbus_det_gpio);
+   }
 
if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
 "usb0_vbus_power-supply");
-   if (IS_ERR(data->vbus_power_supply))
+   if (IS_ERR(data->vbus_power_supply)) {
+   dev_err(dev, "Couldn't get the VBUS power supply\n");
return PTR_ERR(data->vbus_power_supply);
+   }
 
if (!data->vbus_power_supply)
return -EPROBE_DEFER;
@@ -653,8 +659,10 @@ static int sun4i_usb_phy_probe(struct platform_device 
*pdev)
data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0);
 
data->extcon = devm_extcon_dev_allocate(dev, sun4i_usb_phy0_cable);
-   if (IS_ERR(data->extcon))
+   if (IS_ERR(data->extcon)) {
+   dev_err(dev, "Couldn't allocate our extcon device\n");
return PTR_ERR(data->extcon);
+   }
 
ret = devm_extcon_dev_register(dev, data->extcon);
if (ret) {
@@ -669,8 +677,13 @@ static int sun4i_usb_phy_probe(struct platform_device 
*pdev)
snprintf(name, sizeof(name), "usb%d_vbus", i);
phy->vbus = devm_regulator_get_optional(dev, name);
if (IS_ERR(phy->vbus)) {
-   if (PTR_ERR(phy->vbus) == -EPROBE_DEFER)
+   if (PTR_ERR(phy->vbus) == -EPROBE_DEFER) {
+   dev_err(dev,
+   "Couldn't get regulator %s... Deferring 
probe\n",
+   name);
return -EPROBE_DEFER;
+   }
+
phy->vbus = NULL;
}
 
@@ -754,6 +767,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return PTR_ERR(phy_provider);
}
 
+   dev_dbg(dev, "successfully loaded\n");
+
return 0;
 }
 
-- 
2.9.3



[PATCH 03/10] Documentation: DT: binding: axp20x_usb_power: add axp223 compatible

2016-11-25 Thread Quentin Schulz
This adds the "x-powers,axp223-usb-power-supply" to the list of
compatibles for AXP20X VBUS power supply driver.

Signed-off-by: Quentin Schulz 
---
 Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt 
b/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
index f1d7bee..bf3953c 100644
--- a/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
+++ b/Documentation/devicetree/bindings/power/supply/axp20x_usb_power.txt
@@ -3,6 +3,7 @@ AXP20x USB power supply
 Required Properties:
 -compatible: One of: "x-powers,axp202-usb-power-supply"
  "x-powers,axp221-usb-power-supply"
+ "x-powers,axp223-usb-power-supply"
 
 This node is a subnode of the axp20x PMIC.
 
-- 
2.9.3



[PATCH 09/10] ARM: dts: sun8i-r16-parrot: use AXP223 DTSI

2016-11-25 Thread Quentin Schulz
Previously, the Allwinner Parrot R16 used everything declared in AXP221
DTSI while it has an AXP223 PMIC.

This corrects that so the Allwinner Parrot R16 can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-r16-parrot.dts 
b/arch/arm/boot/dts/sun8i-r16-parrot.dts
index 47553e5..6afdba3 100644
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -209,7 +209,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH 07/10] ARM: dts: sun8i-a33-olinuxino: use AXP223 DTSI

2016-11-25 Thread Quentin Schulz
Previously, the Olimex A33-OlinuXino used everything declared in AXP221
DTSI while it has an AXP223 PMIC.

This corrects that so the Olimex A33-OlinuXino can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts 
b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
index 9ea637e..3e8f2ec 100644
--- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
+++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts
@@ -126,7 +126,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH 05/10] mfd: axp20x: add separate MFD cell for AXP223

2016-11-25 Thread Quentin Schulz
The AXP223 shares most of its logic with the AXP221 but has some
differences for the VBUS power supply driver. Thus, to probe the driver
with the correct compatible, the AXP221 and the AXP223 now have separate
MFD cells.

Signed-off-by: Quentin Schulz 
---
 drivers/mfd/axp20x.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index ba130be..989d568 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -602,6 +602,21 @@ static struct mfd_cell axp22x_cells[] = {
},
 };
 
+static struct mfd_cell axp223_cells[] = {
+   {
+   .name   = "axp20x-pek",
+   .num_resources  = ARRAY_SIZE(axp22x_pek_resources),
+   .resources  = axp22x_pek_resources,
+   }, {
+   .name   = "axp20x-regulator",
+   }, {
+   .name   = "axp20x-usb-power-supply",
+   .of_compatible  = "x-powers,axp223-usb-power-supply",
+   .num_resources  = ARRAY_SIZE(axp22x_usb_power_supply_resources),
+   .resources  = axp22x_usb_power_supply_resources,
+   },
+};
+
 static struct mfd_cell axp152_cells[] = {
{
.name   = "axp20x-pek",
@@ -789,12 +804,17 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
break;
case AXP221_ID:
-   case AXP223_ID:
axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
axp20x->cells = axp22x_cells;
axp20x->regmap_cfg = &axp22x_regmap_config;
axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
break;
+   case AXP223_ID:
+   axp20x->nr_cells = ARRAY_SIZE(axp223_cells);
+   axp20x->cells = axp223_cells;
+   axp20x->regmap_cfg = &axp22x_regmap_config;
+   axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
+   break;
case AXP288_ID:
axp20x->cells = axp288_cells;
axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
-- 
2.9.3



[PATCH 00/10] add support for VBUS max current and min voltage limits AXP20X and AXP22X PMICs

2016-11-25 Thread Quentin Schulz
The X-Powers AXP209 and AXP20X PMICs are able to set a limit for the VBUS power
supply for both max current and min voltage supplied. This series of patch adds
the possibility to set these limits from sysfs.

Also, the AXP223 PMIC shares most of its behaviour with the AXP221 but the
former can set the VBUS power supply max current to 100mA, unlike the latter.
The AXP223 VBUS power supply driver used to probe on the AXP221 compatible. This
series of patch introduces a new compatible for the AXP223 to be able to set the
current max limit to 100mA.

With that new compatible, boards having the AXP223 see their DT updated to use
the VBUS power supply driver with the correct compatible.

This series of patch also migrates from of_device_is_compatible function to the
data field of of_device_id to identify the compatible used to probe. This
improves the code readability.

Quentin Schulz (10):
  power: supply: axp20x_usb_power: use of_device_id data field instead
of device_is_compatible
  power: supply: axp20x_usb_power: set min voltage and max current from
sysfs
  Documentation: DT: binding: axp20x_usb_power: add axp223 compatible
  power: supply: axp20x_usb_power: add 100mA max current limit for
AXP223
  mfd: axp20x: add separate MFD cell for AXP223
  ARM: dtsi: add DTSI for AXP223
  ARM: dts: sun8i-a33-olinuxino: use AXP223 DTSI
  ARM: dts: sun8i-a33-sinlinx-sina33: use AXP223 DTSI
  ARM: dts: sun8i-r16-parrot: use AXP223 DTSI
  ARM: dtsi: sun8i-reference-design-tablet: use AXP223 DTSI

 .../bindings/power/supply/axp20x_usb_power.txt |   1 +
 arch/arm/boot/dts/axp223.dtsi  |  55 ++
 arch/arm/boot/dts/sun8i-a33-olinuxino.dts  |   2 +-
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts |   2 +-
 arch/arm/boot/dts/sun8i-r16-parrot.dts |   2 +-
 .../boot/dts/sun8i-reference-design-tablet.dtsi|   2 +-
 drivers/mfd/axp20x.c   |  22 +++-
 drivers/power/supply/axp20x_usb_power.c| 120 +
 include/linux/mfd/axp20x.h |   3 +
 9 files changed, 186 insertions(+), 23 deletions(-)
 create mode 100644 arch/arm/boot/dts/axp223.dtsi

-- 
2.9.3



[PATCH 02/10] power: supply: axp20x_usb_power: set min voltage and max current from sysfs

2016-11-25 Thread Quentin Schulz
AXP20X and AXP22X PMICs allow setting the min voltage and max current of
VBUS power supply. This adds entries in sysfs to allow to do so.

Signed-off-by: Quentin Schulz 
---
 drivers/power/supply/axp20x_usb_power.c | 72 +
 include/linux/mfd/axp20x.h  |  3 ++
 2 files changed, 75 insertions(+)

diff --git a/drivers/power/supply/axp20x_usb_power.c 
b/drivers/power/supply/axp20x_usb_power.c
index b19754e..638cb52 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -155,6 +155,74 @@ static int axp20x_usb_power_get_property(struct 
power_supply *psy,
return 0;
 }
 
+static int axp20x_usb_power_set_property(struct power_supply *psy,
+enum power_supply_property psp,
+const union power_supply_propval *val)
+{
+   struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
+   int ret, val1;
+
+   switch (psp) {
+   case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+   switch (val->intval) {
+   case 400:
+   case 410:
+   case 420:
+   case 430:
+   case 440:
+   case 450:
+   case 460:
+   case 470:
+   val1 = (val->intval - 400) / 10;
+   ret = regmap_update_bits(power->regmap,
+AXP20X_VBUS_IPSOUT_MGMT,
+AXP20X_VBUS_VHOLD_MASK,
+val1 << 3);
+   if (ret)
+   return ret;
+
+   return 0;
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+
+   case POWER_SUPPLY_PROP_CURRENT_MAX:
+   switch (val->intval) {
+   case 10:
+   if (power->axp20x_id == AXP221_ID)
+   return -EINVAL;
+   case 50:
+   case 90:
+   val1 = (90 - val->intval) / 40;
+   ret = regmap_update_bits(power->regmap,
+AXP20X_VBUS_IPSOUT_MGMT,
+AXP20X_VBUS_CLIMIT_MASK, val1);
+   if (ret)
+   return ret;
+
+   return 0;
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
+  enum power_supply_property psp)
+{
+   return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
+  psp == POWER_SUPPLY_PROP_CURRENT_MAX;
+}
+
 static enum power_supply_property axp20x_usb_power_properties[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
@@ -178,7 +246,9 @@ static const struct power_supply_desc axp20x_usb_power_desc 
= {
.type = POWER_SUPPLY_TYPE_USB,
.properties = axp20x_usb_power_properties,
.num_properties = ARRAY_SIZE(axp20x_usb_power_properties),
+   .property_is_writeable = axp20x_usb_power_prop_writeable,
.get_property = axp20x_usb_power_get_property,
+   .set_property = axp20x_usb_power_set_property,
 };
 
 static const struct power_supply_desc axp22x_usb_power_desc = {
@@ -186,7 +256,9 @@ static const struct power_supply_desc axp22x_usb_power_desc 
= {
.type = POWER_SUPPLY_TYPE_USB,
.properties = axp22x_usb_power_properties,
.num_properties = ARRAY_SIZE(axp22x_usb_power_properties),
+   .property_is_writeable = axp20x_usb_power_prop_writeable,
.get_property = axp20x_usb_power_get_property,
+   .set_property = axp20x_usb_power_set_property,
 };
 
 static const struct of_device_id axp20x_usb_power_match[] = {
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index fec597f..8883595 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -56,6 +56,9 @@ enum {
 #define AXP20X_LDO24_V_OUT 0x28
 #define AXP20X_LDO3_V_OUT  0x29
 #define AXP20X_VBUS_IPSOUT_MGMT0x30
+
+#define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
+
 #define AXP20X_V_OFF   0x31
 #define AXP20X_OFF_CTRL0x32
 #define AXP20X_CHRG_CTRL1  0x33
-- 
2.9.3



[PATCH 10/10] ARM: dtsi: sun8i-reference-design-tablet: use AXP223 DTSI

2016-11-25 Thread Quentin Schulz
Previously, the sun8i tablets used everything declared in AXP221 DTSI
while they have an AXP223 PMIC.

This corrects that so the sun8i tablets can get some features the AXP223
has (at the moment, ability to have 100mA as maximal current on VBUS
power supply).

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi 
b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index 08cd001..ea79c33 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -136,7 +136,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH 04/10] power: supply: axp20x_usb_power: add 100mA max current limit for AXP223

2016-11-25 Thread Quentin Schulz
The X-Powers AXP223 shares most of its behaviour with the AXP221 PMIC
but allows the VBUS power supply max current to be set to 100mA (like
the AXP209 PMIC).

This basically adds a new compatible to the VBUS power supply driver and
adds a check on the compatible when setting current max limit.

Signed-off-by: Quentin Schulz 
---
 drivers/power/supply/axp20x_usb_power.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/power/supply/axp20x_usb_power.c 
b/drivers/power/supply/axp20x_usb_power.c
index 638cb52..6d5d451 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -88,11 +88,10 @@ static int axp20x_usb_power_get_property(struct 
power_supply *psy,
 
switch (v & AXP20X_VBUS_CLIMIT_MASK) {
case AXP20X_VBUC_CLIMIT_100mA:
-   if (power->axp20x_id == AXP202_ID) {
-   val->intval = 10;
-   } else {
+   if (power->axp20x_id == AXP221_ID)
val->intval = -1; /* No 100mA limit */
-   }
+   else
+   val->intval = 10;
break;
case AXP20X_VBUC_CLIMIT_500mA:
val->intval = 50;
@@ -268,6 +267,9 @@ static const struct of_device_id axp20x_usb_power_match[] = 
{
}, {
.compatible = "x-powers,axp221-usb-power-supply",
.data = (void *)AXP221_ID,
+   }, {
+   .compatible = "x-powers,axp223-usb-power-supply",
+   .data = (void *)AXP223_ID,
}, { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
@@ -324,7 +326,8 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
 
usb_power_desc = &axp20x_usb_power_desc;
irq_names = axp20x_irq_names;
-   } else if (power->axp20x_id == AXP221_ID) {
+   } else if (power->axp20x_id == AXP221_ID ||
+  power->axp20x_id == AXP223_ID) {
usb_power_desc = &axp22x_usb_power_desc;
irq_names = axp22x_irq_names;
} else {
-- 
2.9.3



[PATCH 01/10] power: supply: axp20x_usb_power: use of_device_id data field instead of device_is_compatible

2016-11-25 Thread Quentin Schulz
This replaces calls to of_device_is_compatible to check data field of
of_device_id matched when probing the driver.

Signed-off-by: Quentin Schulz 
---
 drivers/power/supply/axp20x_usb_power.c | 39 -
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/power/supply/axp20x_usb_power.c 
b/drivers/power/supply/axp20x_usb_power.c
index 6af6feb..b19754e 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -45,6 +46,7 @@ struct axp20x_usb_power {
struct device_node *np;
struct regmap *regmap;
struct power_supply *supply;
+   int axp20x_id;
 };
 
 static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
@@ -86,8 +88,7 @@ static int axp20x_usb_power_get_property(struct power_supply 
*psy,
 
switch (v & AXP20X_VBUS_CLIMIT_MASK) {
case AXP20X_VBUC_CLIMIT_100mA:
-   if (of_device_is_compatible(power->np,
-   "x-powers,axp202-usb-power-supply")) {
+   if (power->axp20x_id == AXP202_ID) {
val->intval = 10;
} else {
val->intval = -1; /* No 100mA limit */
@@ -130,8 +131,7 @@ static int axp20x_usb_power_get_property(struct 
power_supply *psy,
 
val->intval = POWER_SUPPLY_HEALTH_GOOD;
 
-   if (of_device_is_compatible(power->np,
-   "x-powers,axp202-usb-power-supply")) {
+   if (power->axp20x_id == AXP202_ID) {
ret = regmap_read(power->regmap,
  AXP20X_USB_OTG_STATUS, &v);
if (ret)
@@ -189,6 +189,17 @@ static const struct power_supply_desc 
axp22x_usb_power_desc = {
.get_property = axp20x_usb_power_get_property,
 };
 
+static const struct of_device_id axp20x_usb_power_match[] = {
+   {
+   .compatible = "x-powers,axp202-usb-power-supply",
+   .data = (void *)AXP202_ID,
+   }, {
+   .compatible = "x-powers,axp221-usb-power-supply",
+   .data = (void *)AXP221_ID,
+   }, { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
+
 static int axp20x_usb_power_probe(struct platform_device *pdev)
 {
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
@@ -200,11 +211,16 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
"VBUS_PLUGIN", "VBUS_REMOVAL", NULL };
static const char * const *irq_names;
const struct power_supply_desc *usb_power_desc;
+   const struct of_device_id *of_id;
int i, irq, ret;
 
if (!of_device_is_available(pdev->dev.of_node))
return -ENODEV;
 
+   of_id = of_match_device(axp20x_usb_power_match, &pdev->dev);
+   if (!of_id)
+   return -ENODEV;
+
if (!axp20x) {
dev_err(&pdev->dev, "Parent drvdata not set\n");
return -EINVAL;
@@ -214,11 +230,12 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
if (!power)
return -ENOMEM;
 
+   power->axp20x_id = (int)of_id->data;
+
power->np = pdev->dev.of_node;
power->regmap = axp20x->regmap;
 
-   if (of_device_is_compatible(power->np,
-   "x-powers,axp202-usb-power-supply")) {
+   if (power->axp20x_id == AXP202_ID) {
/* Enable vbus valid checking */
ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
 AXP20X_VBUS_MON_VBUS_VALID,
@@ -235,8 +252,7 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
 
usb_power_desc = &axp20x_usb_power_desc;
irq_names = axp20x_irq_names;
-   } else if (of_device_is_compatible(power->np,
-   "x-powers,axp221-usb-power-supply")) {
+   } else if (power->axp20x_id == AXP221_ID) {
usb_power_desc = &axp22x_usb_power_desc;
irq_names = axp22x_irq_names;
} else {
@@ -272,13 +288,6 @@ static int axp20x_usb_power_probe(struct platform_device 
*pdev)
return 0;
 }
 
-static const struct of_device_id axp20x_usb_power_match[] = {
-   { .compatible = "x-powers,axp202-usb-power-supply" },
-   { .compatible = "x-powers,axp221-usb-power-supply" },
-   { }
-};
-MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
-
 static struct platform_driver axp20x_usb_power_driver = {
.probe = axp20x_usb_power_probe,
.driver = {
-- 
2.9.3



[PATCH 08/10] ARM: dts: sun8i-a33-sinlinx-sina33: use AXP223 DTSI

2016-11-25 Thread Quentin Schulz
Previously, the Sinlinx SinA33 used everything declared in AXP221 DTSI
while it has an AXP223 PMIC.

This corrects that so the Sinlinx SinA33 can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts 
b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index 573aa2c..3373164 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -161,7 +161,7 @@
};
 };
 
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
 
 ®_aldo1 {
regulator-always-on;
-- 
2.9.3



[PATCH 06/10] ARM: dtsi: add DTSI for AXP223

2016-11-25 Thread Quentin Schulz
The AXP223 shares most of its logic with the AXP221 but it has some
differences for the VBUS driver.

Signed-off-by: Quentin Schulz 
---
 arch/arm/boot/dts/axp223.dtsi | 55 +++
 1 file changed, 55 insertions(+)
 create mode 100644 arch/arm/boot/dts/axp223.dtsi

diff --git a/arch/arm/boot/dts/axp223.dtsi b/arch/arm/boot/dts/axp223.dtsi
new file mode 100644
index 000..f8ce55c
--- /dev/null
+++ b/arch/arm/boot/dts/axp223.dtsi
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016 Free Electrons
+ *
+ * Quentin Schulz 
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ * This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * AXP223 Integrated Power Management Chip
+ * http://www.x-powers.com/product/AXP22X.php
+ * http://dl.linux-sunxi.org/AXP/AXP223-en.pdf
+ */
+
+#include "axp22x.dtsi"
+
+&usb_power_supply {
+   compatible = "x-powers,axp223-usb-power-supply";
+};
-- 
2.9.3



[PATCH RESEND 1/2] gpio: axp209: use correct register for GPIO input status

2016-11-23 Thread Quentin Schulz
The GPIO input status was read from control register
(AXP20X_GPIO[210]_CTRL) instead of status register (AXP20X_GPIO20_SS).

Signed-off-by: Quentin Schulz 
---
 drivers/gpio/gpio-axp209.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c
index d9c2a51..4a346b7 100644
--- a/drivers/gpio/gpio-axp209.c
+++ b/drivers/gpio/gpio-axp209.c
@@ -64,13 +64,9 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned 
offset)
 {
struct axp20x_gpio *gpio = gpiochip_get_data(chip);
unsigned int val;
-   int reg, ret;
-
-   reg = axp20x_gpio_get_reg(offset);
-   if (reg < 0)
-   return reg;
+   int ret;
 
-   ret = regmap_read(gpio->regmap, reg, &val);
+   ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val);
if (ret)
return ret;
 
-- 
2.9.3



[PATCH RESEND 0/2] add support for AXP209 GPIOs functions

2016-11-23 Thread Quentin Schulz
The AXP209 PMIC has three GPIOs. Two of them can be muxed in other modes
(namely adc or regulator)[1] which cannot be used while the pin is in one
of GPIO modes.

This adds the possibility to use all functions of the GPIOs present in
the AXP209 PMIC thanks to the pinctrl subsystem.

An upcoming ADC driver for the AXP209 PMIC will make use of this pinctrl to
read ADC values of GPIO0 and GPIO1. At the moment, no driver is pinctrling
these GPIOs.

This patch also corrects the register used to read GPIO input status.

[1] see registers 90H, 92H and 93H at
http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf

Quentin Schulz (2):
  gpio: axp209: use correct register for GPIO input status
  gpio: axp209: add pinctrl support

 .../devicetree/bindings/gpio/gpio-axp209.txt   |  28 +-
 drivers/gpio/gpio-axp209.c | 557 ++---
 2 files changed, 504 insertions(+), 81 deletions(-)

-- 

Adding Maxime Ripard (original driver author) and LKML to mail recipients.
2.9.3



[PATCH RESEND 2/2] gpio: axp209: add pinctrl support

2016-11-23 Thread Quentin Schulz
The GPIOs present in the AXP209 PMIC have multiple functions. They
typically allow a pin to be used as GPIO input or output and can also be
used as ADC or regulator for example.[1]

This adds the possibility to use all functions of the GPIOs present in
the AXP209 PMIC thanks to pinctrl subsystem.

[1] see registers 90H, 92H and 93H at
http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf

Signed-off-by: Quentin Schulz 
---
 .../devicetree/bindings/gpio/gpio-axp209.txt   |  28 +-
 drivers/gpio/gpio-axp209.c | 551 ++---
 2 files changed, 503 insertions(+), 76 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt 
b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
index a661130..a5bfe87 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
@@ -1,4 +1,4 @@
-AXP209 GPIO controller
+AXP209 GPIO & pinctrl controller
 
 This driver follows the usual GPIO bindings found in
 Documentation/devicetree/bindings/gpio/gpio.txt
@@ -28,3 +28,29 @@ axp209: pmic@34 {
#gpio-cells = <2>;
};
 };
+
+The GPIOs can be muxed to other functions and therefore, must be a subnode of
+axp_gpio.
+
+Example:
+
+&axp_gpio {
+   gpio0_adc: gpio0_adc {
+   pin = "GPIO0";
+   function = "adc";
+   };
+};
+
+&example_node {
+   pinctrl-names = "default";
+   pinctrl-0 = <&gpio0_adc>;
+};
+
+GPIOs and their functions
+-
+
+GPIO   |   Functions
+
+GPIO0  |   gpio_in, gpio_out, ldo, adc
+GPIO1  |   gpio_in, gpio_out, ldo, adc
+GPIO2  |   gpio_in, gpio_out
diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c
index 4a346b7..0a64cfc 100644
--- a/drivers/gpio/gpio-axp209.c
+++ b/drivers/gpio/gpio-axp209.c
@@ -1,7 +1,8 @@
 /*
- * AXP20x GPIO driver
+ * AXP20x Pin control driver
  *
  * Copyright (C) 2016 Maxime Ripard 
+ * Copyright (C) 2016 Quentin Schulz 
  *
  * 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
@@ -21,52 +22,103 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define AXP20X_GPIO_FUNCTIONS  0x7
 #define AXP20X_GPIO_FUNCTION_OUT_LOW   0
 #define AXP20X_GPIO_FUNCTION_OUT_HIGH  1
 #define AXP20X_GPIO_FUNCTION_INPUT 2
 
-struct axp20x_gpio {
-   struct gpio_chipchip;
-   struct regmap   *regmap;
-};
+#define AXP20X_PINCTRL_PIN(_pin_num, _pin, _regs)  \
+   {   \
+   .number = _pin_num, \
+   .name = _pin,   \
+   .drv_data = _regs,  \
+   }
 
-static int axp20x_gpio_get_reg(unsigned offset)
-{
-   switch (offset) {
-   case 0:
-   return AXP20X_GPIO0_CTRL;
-   case 1:
-   return AXP20X_GPIO1_CTRL;
-   case 2:
-   return AXP20X_GPIO2_CTRL;
+#define AXP20X_PIN(_pin, ...)  \
+   {   \
+   .pin = _pin,\
+   .functions = (struct axp20x_desc_function[]) {  \
+ __VA_ARGS__, { } },   \
}
 
-   return -EINVAL;
-}
+#define AXP20X_FUNCTION(_val, _name)   \
+   {   \
+   .name = _name,  \
+   .muxval = _val, \
+   }
 
-static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset)
-{
-   struct axp20x_gpio *gpio = gpiochip_get_data(chip);
-   int reg;
+struct axp20x_desc_function {
+   const char  *name;
+   u8  muxval;
+};
 
-   reg = axp20x_gpio_get_reg(offset);
-   if (reg < 0)
-   return reg;
+struct axp20x_desc_pin {
+   struct pinctrl_pin_desc pin;
+   struct axp20x_desc_function *functions;
+};
 
-   return regmap_update_bits(gpio->regmap, reg,
- AXP20X_GPIO_FUNCTIONS,
- AXP20X_GPIO_FUNCTION_INPUT);
-}
+struct axp20x_pinctrl_desc {
+   const struct axp20x_desc_pin*pins;
+   int npins;
+   unsigned intpin_base;
+};
+
+struct axp20x_pinctrl_function {
+   const char  *name;
+   const char  **groups;
+   unsigned intngroups;
+};
+
+struct axp20x_pinctrl_group {
+   const char  *name;
+   unsigned long   config;
+   unsigned intpin;
+};
+
+struct axp20x_pctl {
+   s

[PATCH 2/2] gpio: axp209: add pinctrl support

2016-11-23 Thread Quentin Schulz
The GPIOs present in the AXP209 PMIC have multiple functions. They
typically allow a pin to be used as GPIO input or output and can also be
used as ADC or regulator for example.[1]

This adds the possibility to use all functions of the GPIOs present in
the AXP209 PMIC thanks to pinctrl subsystem.

[1] see registers 90H, 92H and 93H at
http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf

Signed-off-by: Quentin Schulz 
---
 .../devicetree/bindings/gpio/gpio-axp209.txt   |  28 +-
 drivers/gpio/gpio-axp209.c | 551 ++---
 2 files changed, 503 insertions(+), 76 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt 
b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
index a661130..a5bfe87 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
@@ -1,4 +1,4 @@
-AXP209 GPIO controller
+AXP209 GPIO & pinctrl controller
 
 This driver follows the usual GPIO bindings found in
 Documentation/devicetree/bindings/gpio/gpio.txt
@@ -28,3 +28,29 @@ axp209: pmic@34 {
#gpio-cells = <2>;
};
 };
+
+The GPIOs can be muxed to other functions and therefore, must be a subnode of
+axp_gpio.
+
+Example:
+
+&axp_gpio {
+   gpio0_adc: gpio0_adc {
+   pin = "GPIO0";
+   function = "adc";
+   };
+};
+
+&example_node {
+   pinctrl-names = "default";
+   pinctrl-0 = <&gpio0_adc>;
+};
+
+GPIOs and their functions
+-
+
+GPIO   |   Functions
+
+GPIO0  |   gpio_in, gpio_out, ldo, adc
+GPIO1  |   gpio_in, gpio_out, ldo, adc
+GPIO2  |   gpio_in, gpio_out
diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c
index 4a346b7..0a64cfc 100644
--- a/drivers/gpio/gpio-axp209.c
+++ b/drivers/gpio/gpio-axp209.c
@@ -1,7 +1,8 @@
 /*
- * AXP20x GPIO driver
+ * AXP20x Pin control driver
  *
  * Copyright (C) 2016 Maxime Ripard 
+ * Copyright (C) 2016 Quentin Schulz 
  *
  * 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
@@ -21,52 +22,103 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #define AXP20X_GPIO_FUNCTIONS  0x7
 #define AXP20X_GPIO_FUNCTION_OUT_LOW   0
 #define AXP20X_GPIO_FUNCTION_OUT_HIGH  1
 #define AXP20X_GPIO_FUNCTION_INPUT 2
 
-struct axp20x_gpio {
-   struct gpio_chipchip;
-   struct regmap   *regmap;
-};
+#define AXP20X_PINCTRL_PIN(_pin_num, _pin, _regs)  \
+   {   \
+   .number = _pin_num, \
+   .name = _pin,   \
+   .drv_data = _regs,  \
+   }
 
-static int axp20x_gpio_get_reg(unsigned offset)
-{
-   switch (offset) {
-   case 0:
-   return AXP20X_GPIO0_CTRL;
-   case 1:
-   return AXP20X_GPIO1_CTRL;
-   case 2:
-   return AXP20X_GPIO2_CTRL;
+#define AXP20X_PIN(_pin, ...)  \
+   {   \
+   .pin = _pin,\
+   .functions = (struct axp20x_desc_function[]) {  \
+ __VA_ARGS__, { } },   \
}
 
-   return -EINVAL;
-}
+#define AXP20X_FUNCTION(_val, _name)   \
+   {   \
+   .name = _name,  \
+   .muxval = _val, \
+   }
 
-static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset)
-{
-   struct axp20x_gpio *gpio = gpiochip_get_data(chip);
-   int reg;
+struct axp20x_desc_function {
+   const char  *name;
+   u8  muxval;
+};
 
-   reg = axp20x_gpio_get_reg(offset);
-   if (reg < 0)
-   return reg;
+struct axp20x_desc_pin {
+   struct pinctrl_pin_desc pin;
+   struct axp20x_desc_function *functions;
+};
 
-   return regmap_update_bits(gpio->regmap, reg,
- AXP20X_GPIO_FUNCTIONS,
- AXP20X_GPIO_FUNCTION_INPUT);
-}
+struct axp20x_pinctrl_desc {
+   const struct axp20x_desc_pin*pins;
+   int npins;
+   unsigned intpin_base;
+};
+
+struct axp20x_pinctrl_function {
+   const char  *name;
+   const char  **groups;
+   unsigned intngroups;
+};
+
+struct axp20x_pinctrl_group {
+   const char  *name;
+   unsigned long   config;
+   unsigned intpin;
+};
+
+struct axp20x_pctl {
+   s

[PATCH 0/2] add support for AXP209 GPIOs functions

2016-11-23 Thread Quentin Schulz
The AXP209 PMIC has three GPIOs. Two of them can be muxed in other modes
(namely adc or regulator)[1] which cannot be used while the pin is in one
of GPIO modes.

This adds the possibility to use all functions of the GPIOs present in
the AXP209 PMIC thanks to the pinctrl subsystem.

An upcoming ADC driver for the AXP209 PMIC will make use of this pinctrl to
read ADC values of GPIO0 and GPIO1. At the moment, no driver is pinctrling
these GPIOs.

This patch also corrects the register used to read GPIO input status.

[1] see registers 90H, 92H and 93H at
http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf

Quentin Schulz (2):
  gpio: axp209: use correct register for GPIO input status
  gpio: axp209: add pinctrl support

 .../devicetree/bindings/gpio/gpio-axp209.txt   |  28 +-
 drivers/gpio/gpio-axp209.c | 557 ++---
 2 files changed, 504 insertions(+), 81 deletions(-)

-- 
2.9.3


[PATCH 1/2] gpio: axp209: use correct register for GPIO input status

2016-11-23 Thread Quentin Schulz
The GPIO input status was read from control register
(AXP20X_GPIO[210]_CTRL) instead of status register (AXP20X_GPIO20_SS).

Signed-off-by: Quentin Schulz 
---
 drivers/gpio/gpio-axp209.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c
index d9c2a51..4a346b7 100644
--- a/drivers/gpio/gpio-axp209.c
+++ b/drivers/gpio/gpio-axp209.c
@@ -64,13 +64,9 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned 
offset)
 {
struct axp20x_gpio *gpio = gpiochip_get_data(chip);
unsigned int val;
-   int reg, ret;
-
-   reg = axp20x_gpio_get_reg(offset);
-   if (reg < 0)
-   return reg;
+   int ret;
 
-   ret = regmap_read(gpio->regmap, reg, &val);
+   ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val);
if (ret)
return ret;
 
-- 
2.9.3



Re: [PATCH 2/2] clk: sunxi-ng: fix up PLL_CPUX adjusting for A23/A33

2016-11-06 Thread Quentin Schulz
Hi Icenowy,

This patch (2/2) should be before the first one.

The first patch allows adjusting of the PLL and the second fixes a
problem with the adjustment of the PLL.

You should fix the problem before allowing the adjustment of the PLL.
That way, if someone builds the kernel between your two patches, the
kernel is supposed to be working.

Tested in correct order on A33.

Thanks!

Quentin

On 06/11/2016 18:29, Icenowy Zheng wrote:
> When adjusting PLL_CPUX on A23/A33, the PLL is driven too high, and the
> system stucks.
> 
> Add a notifier to avoid this situation.
> 
> The code is ported from ccu-sun6i-a31.c.
> 
> Signed-off-by: Icenowy Zheng 
> ---
> Patch 4.9-rc too.
>  drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 10 ++
>  drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 10 ++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c 
> b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
> index 44c4775..41a8594 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
> @@ -709,6 +709,13 @@ static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = {
>   .num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets),
>  };
>  
> +static struct ccu_mux_nb sun8i_a23_cpu_nb = {
> + .common = &cpux_clk.common,
> + .cm = &cpux_clk.mux,
> + .delay_us   = 1, /* > 8 clock cycles at 24 MHz */
> + .bypass_index   = 1, /* index of 24 MHz oscillator */
> +};
> +
>  static void __init sun8i_a23_ccu_setup(struct device_node *node)
>  {
>   void __iomem *reg;
> @@ -732,6 +739,9 @@ static void __init sun8i_a23_ccu_setup(struct device_node 
> *node)
>   writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
>  
>   sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
> +
> + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
> +   &sun8i_a23_cpu_nb);
>  }
>  CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
>  sun8i_a23_ccu_setup);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c 
> b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
> index 59cfdc8..3efbb6e 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
> @@ -752,6 +752,13 @@ static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = {
>   .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets),
>  };
>  
> +static struct ccu_mux_nb sun8i_a33_cpu_nb = {
> + .common = &cpux_clk.common,
> + .cm = &cpux_clk.mux,
> + .delay_us   = 1, /* > 8 clock cycles at 24 MHz */
> + .bypass_index   = 1, /* index of 24 MHz oscillator */
> +};
> +
>  static void __init sun8i_a33_ccu_setup(struct device_node *node)
>  {
>   void __iomem *reg;
> @@ -775,6 +782,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node 
> *node)
>   writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
>  
>   sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
> +
> + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
> +   &sun8i_a33_cpu_nb);
>  }
>  CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
>  sun8i_a33_ccu_setup);
> 

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


[PATCH v7 1/3] input: touchscreen: TOUCHSCREEN_SUN4I depends on !SUN4I_GPADC

2016-11-03 Thread Quentin Schulz
SUN4I_GPADC and TOUCHSCREEN_SUN4I are incompatible (both are drivers
for Allwinner SoCs' ADC). This makes sure TOUCHSCREEN_SUN4I isn't
enabled while SUN4I_GPADC is enabled.

Signed-off-by: Quentin Schulz 
---

added in v7

 drivers/input/touchscreen/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index efca013..c618cb9 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1120,6 +1120,7 @@ config TOUCHSCREEN_SUN4I
depends on ARCH_SUNXI || COMPILE_TEST
depends on HWMON
depends on THERMAL || !THERMAL_OF
+   depends on !SUN4I_GPADC
help
  This selects support for the resistive touchscreen controller
  found on Allwinner sunxi SoCs.
-- 
2.9.3



[PATCH v7 0/3] add support for Allwinner SoCs ADC

2016-11-03 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used either
for the ADC or the touchscreen and the fifth channel is used for the
thermal sensor. We currently have a driver for the two latter functions in
drivers/input/touchscreen/sun4i-ts.c but we don't have access to the ADC
feature at all. It is meant to replace the current driver by using MFD and
subdrivers.

This adds initial support for Allwinner SoCs ADC with all features. Yet,
the touchscreen is not implemented but will be added later. To switch
between touchscreen and ADC modes, you need to poke a few bits in registers
and (de)activate an interrupt (pen-up).

When changing modes or channels, the IP is in inconsistent mode and has no
register or interrupt to notify the kernel when it's stable and ready to return
correct values. Therefore, we add a delay of 100ms when changing modes and 10ms
when changing channels. These values have been found empirically.

An MFD is provided to let the input driver activate the pen-up interrupt
through a virtual interrupt, poke a few bits via regmap and read data from
the ADC driver while both (and iio_hwmon) are probed by the MFD.

The thermal sensor requires the IP to be in touchscreen mode to return correct
values. Therefore, if the user is continuously reading the ADC channel(s), the
thermal framework in which the thermal sensor is registered will switch the IP
in touchscreen mode to get a temperature value and requires a delay of 100ms
(because of the mode switching), then the ADC will switch back to ADC mode and
requires also a delay of 100ms. If the ADC readings are critical to user and the
SoC temperature is not, this driver is capable of not registering the thermal
sensor in the thermal framework and thus, "quicken" the ADC readings. In most
use cases, the SoC temperature is more critical (for cpu throttling for example
or activating cooling devices) than ADC readings, thus it is enabled by default
in multi_v7_defconfig and in sunxi_defconfig (default being added in this patch
series).

There are slight variations between the different SoCs ADC like the address
of some registers and the scale and offset to apply to raw thermal sensor
values. These variations are handled by using different platform_device_id,
passed to the sub-drivers when they are probed by the MFD.



Removal of proposed patch for iio_hwmon's iio channel's label in v3. The
patch induces irreversible ABI changes and will be handled as a separate
patch since I think it is not absolutely necessary to have labels yet in
iio_hwmon.

Removal of proposed patch for reattaching of_node of the MFD to the MFD
cell device structure in v3. As Lee Jones said, this patch might cause
"unintended side-effects for existing drivers.". Moreover, this patch
introduced a bug of multiple probe of this MFD driver I haven't identified
yet. This patch aimed at allowing the ADC driver (which is a child of the
MFD and not present in the DT) to register in the thermal framework. The
thermal driver has a phandle to the MFD node which is used to match against
the MFD of_node but since the ADC driver has no node in the DT, could not
register in the thermal framework. The other solution is to "impersonate"
the MFD when registering in the thermal framework since the device is only
used to match the phandle and the of_node, an other structure passed by
parameter being used to compute temperatures.

(in the ADC driver, probed by the MFD driver) instead of:
tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info,
   &sun4i_ts_tz_ops);
we now have:
tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, info,
   &sun4i_ts_tz_ops);

Removal of proposed patch to use late_initcall for iio_hwmon probe deferring.

Removal of patch for iio_hwmon probe deferring due to being applied to -next by
Guenter Roeck.

This patch series requires this[1] patch which has already been merged by Lee
Jones.

[1] https://patchwork.kernel.org/patch/9333547/

Quentin Schulz (3):
  input: touchscreen: TOUCHSCREEN_SUN4I depends on !SUN4I_GPADC
  ARM: sunxi_defconfig: Add CONFIG_THERMAL_OF
  iio: adc: add support for Allwinner SoCs ADC

 arch/arm/configs/sunxi_defconfig  |   1 +
 drivers/iio/adc/Kconfig   |  17 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 605 ++
 drivers/input/touchscreen/Kconfig |   1 +
 include/linux/mfd/sun4i-gpadc.h   |   2 +
 6 files changed, 627 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

-- 
2.9.3



[PATCH v7 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-11-03 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. This patch adds the ADC driver which is
based on the MFD for the same SoCs ADC.

This also registers the thermal adc channel in the iio map array so
iio_hwmon could use it without modifying the Device Tree. This registers
the driver in the thermal framework.

The thermal sensor requires the IP to be in touchscreen mode to return correct
values. Therefore, if the user is continuously reading the ADC channel(s), the
thermal framework in which the thermal sensor is registered will switch the IP
in touchscreen mode to get a temperature value and requires a delay of 100ms
(because of the mode switching), then the ADC will switch back to ADC mode and
requires also a delay of 100ms. If the ADC readings are critical to user and the
SoC temperature is not, this driver is capable of not registering the thermal
sensor in the thermal framework and thus, "quicken" the ADC readings.

This driver probes on three different platform_device_id to take into
account slight differences (registers bit and temperature computation)
between Allwinner SoCs ADCs.

Signed-off-by: Quentin Schulz 
Acked-by: Maxime Ripard 
Acked-by: Jonathan Cameron 
---

v7:
 - add Kconfig depends on !TOUCHSCREEN_SUN4I,
 - remove Kconfig selects THERMAL_OF,
 - do not register thermal sensor if CONFIG_THERMAL_OF is disabled,
 - disable irq in irq_handler rather than in read_raw,
 - add delay when switching the IP's mode or channel (delay empirically found),
 - quicken thermal sensor interrupt period,
 - add masks for channel bits,
 - fix deadlock in sun4i_gpadc_read if regmap_read/write fails,
 - move some logic from sun4i_gpadc_read to sun4i_prepare_for_irq,
 - mark last busy for runtime_pm only on success in sun4i_gpadc_read,
 - remove cached values,
 - increase wait_for_completion_timeout timeout to 1s to be sure to not miss the
 thermal interrupt,
 - add voltage scale,
 - use devm_iio_device_register,

v6:
 - remove "-mfd" from filenames and variables inside MFD driver,
 - use DEFINE_RES_IRQ_NAMED instead of setting resources manually,
 - cosmetic changes,
 - use IDs and switch over ID to get cells specific to an architecture, instead
 of using cells direclty, in of_device_id.data,
 - compute size of mfd_cells array instead of hardcoded one,

v5:
 - correct mail address,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - rename defines from SUNXI_* to SUN4I_* or SUN6I_*,
 - remove TP in defines name,
 - rename SUNXI_IRQ_* to SUN4I_GPADC_IRQ_* for consistency,
 - use devm functions for regmap_add_irq_chip and mfd_add_devices,
 - remove remove functions (now empty thanks to devm functions),

v3:
 - use defines in regmap_irq instead of hard coded BITs,
 - use of_device_id data field to chose which MFD cells to add considering
   the compatible responsible of the MFD probe,
 - remove useless initializations,
 - disable all interrupts before adding them to regmap_irqchip,
 - add goto error label in probe,
 - correct wrapping in header license,
 - move defines from IIO driver to header,
 - use GENMASK to limit the size of the variable passed to a macro,
 - prefix register BIT defines with the name of the register,
 - reorder defines,

v2:
 - add license headers,
 - reorder alphabetically includes,
 - add SUNXI_GPADC_ prefixes for defines,

 drivers/iio/adc/Kconfig   |  17 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 605 ++
 include/linux/mfd/sun4i-gpadc.h   |   2 +
 4 files changed, 625 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 7edcf32..9aa3c945 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -434,6 +434,23 @@ config STX104
  The base port addresses for the devices may be configured via the base
  array module parameter.
 
+config SUN4I_GPADC
+   tristate "Support for the Allwinner SoCs GPADC"
+   depends on IIO
+   depends on MFD_SUN4I_GPADC
+   depends on !TOUCHSCREEN_SUN4I
+   help
+ Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
+ GPADC. This ADC provides 4 channels which can be used as an ADC or as
+ a touchscreen input and one channel for thermal sensor.
+
+ The thermal sensor is activated by default but slows down ADC
+ readings. You can disable CONFIG_THERMAL_OF to disable the CPU thermal
+ sensor if you want faster ADC readings.
+
+ To compile this driver as a module, choose M here: the module will be
+ called sun4i-gpadc-iio.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 7a40c04..18ce8d6 100644
--- a/drivers/iio/adc/Makefile
+++ b/d

[PATCH v7 2/3] ARM: sunxi_defconfig: Add CONFIG_THERMAL_OF

2016-11-03 Thread Quentin Schulz
This enables CONFIG_THERMAL_OF by default for sunxi_defconfig.

Signed-off-by: Quentin Schulz 
---

added in v7

 arch/arm/configs/sunxi_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 714da33..8aaeae3 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -83,6 +83,7 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_AXP20X_POWER=y
 CONFIG_THERMAL=y
+CONFIG_THERMAL_OF=y
 CONFIG_CPU_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=y
-- 
2.9.3



Re: [PATCH v6 2/2] iio: adc: add support for Allwinner SoCs ADC

2016-10-31 Thread Quentin Schulz
Hi Jonathan and Lee,

On 30/10/2016 17:59, Jonathan Cameron wrote:
> On 15/09/16 13:44, Quentin Schulz wrote:
>> The Allwinner SoCs all have an ADC that can also act as a touchscreen
>> controller and a thermal sensor. This patch adds the ADC driver which is
>> based on the MFD for the same SoCs ADC.
>>
>> This also registers the thermal adc channel in the iio map array so
>> iio_hwmon could use it without modifying the Device Tree. This registers
>> the driver in the thermal framework.
>>
>> This driver probes on three different platform_device_id to take into
>> account slight differences (registers bit and temperature computation)
>> between Allwinner SoCs ADCs.
>>
>> Signed-off-by: Quentin Schulz 
>> Acked-by: Maxime Ripard 
>> Acked-by: Jonathan Cameron 
> Hi Lee,
> 
> As you applied the MFD part of this series, could you pick this up as well?
> 

Someone reported some bugs on the CHIP (sun5i-r8). I'm investigating that.

Also, it misses a scale for voltage (not that critical but still).

And also, Thomas Petazzoni just found a deadlock in sun4i_gpadc_read. If
a regmap_write fails after getting the mutex, it is never released.

Is there some sort of deadline you want for a v7 since the mfd patch has
been merged?

Thanks,
Quentin

> Thanks,
> 
> Jonathan
>> ---
>>
>> v6:
>>  - remove useless member (regs) from sun4i_gpadc_dev structure,
>>  - rename sun4i_gpadc_dev structure to sun4i_gpadc_iio,
>>  - remove regmap_update_bits used to disable hardware interrupts, it is 
>> already
>>  handled by devm functions,
>>
>> v5:
>>  - correct mail address,
>>  - correct several typos,
>>  - move from const to static for sunxi_gpadc_chan_select functions,
>>  - rename soc_specific struct to gpadc_data,
>>  - rename soc_specific field to data in sun4i_gpadc_dev,
>>  - return error code from regmap_write in case of failure in read_raws,
>>  - share if condition in IIO_CHAN_INFO_RAW case,
>>  - add comment on why we use parent device for registering in thermal,
>>  - reordering remove function,
>>
>> v4:
>>  - rename files and variables from sunxi* to sun4i*,
>>  - shorten sunxi_gpadc_soc_specific structure to soc_specific,
>>  - factorize sysfs ADC and temp read_raws,
>>  - use cached values when read_raw times out (except before a first value
>>is gotten),
>>  - remove mutex locks and unlocks from runtime_pm functions,
>>  - factorize irq initializations,
>>  - initialize temp_data and fifo_data values to -1 (error value),
>>  - "impersonate" MFD to register in thermal framework,
>>  - deactivate hardware interrupts one by one when probe fails or when
>>removing driver instead of blindly deactivating all hardware interrupts,
>>  - selects THERMAL_OF in Kconfig,
>>
>> v3:
>>  - correct wrapping,
>>  - add comment about thermal sensor inner working,
>>  - move defines in mfd header,
>>  - use structure to define SoC specific registers or behaviour,
>>  - attach this structure to the device according to of_device_id of the
>>platform device,
>>  - use new mutex instead of iio_dev mutex,
>>  - use atomic flags to avoid race between request_irq and disable_irq in
>>probe,
>>  - switch from processed value to raw, offset and scale values for
>>temperature ADC channel,
>>  - remove faulty sentinel in iio_chan_spec array,
>>  - add pm_runtime support,
>>  - register thermal sensor in thermal framework (forgotten since the
>>beginning whereas it is present in current sun4i-ts driver),
>>  - remove useless ret variables to store return value of regmap_reads,
>>  - move comments on thermal sensor acquisition period in code instead of
>>header,
>>  - adding goto label to unregister iio_map_array when failing to register
>>iio_dev,
>>
>> v2:
>>  - add SUNXI_GPADC_ prefixes for defines,
>>  - correct typo in Kconfig,
>>  - reorder alphabetically includes, makefile,
>>  - add license header,
>>  - fix architecture variations not being handled in interrupt handlers or
>>read raw functions,
>>  - fix unability to return negative values from thermal sensor,
>>  - add gotos to reduce code repetition,
>>  - fix irq variable being unsigned int instead of int,
>>  - remove useless dev_err and dev_info,
>>  - deactivate all interrupts if probe fails,
>>  - fix iio_device_register on NULL variable,
>>  - deactivate ADC in the IP when probe fails or when removing driver,
>>
>>  drivers/iio/adc/Kconfig   |  13 +
>>  drivers/iio/ad

Re: [PATCH 3/5] iio: adc: sunxi-gpadc-iio: enable iio_buffers

2016-09-25 Thread Quentin Schulz
On 25/09/2016 11:10, Jonathan Cameron wrote:
> On 24/09/16 18:40, Quentin Schulz wrote:
>> Hi Jonathan,
>>
>> Sorry for the (long) delay, I did not have time to work on it. I'll
>> mainly work in my free time now.
>>
>> Keep in mind this patch was proposed based on the v2 of the ADC patches.
>> Since then, substantial changes have been made and I'm working on
>> rebasing this series of patches on the v6, so comments here might
>> include references to code parts added later in the ADC patch series.
>>
>> On 24/07/2016 13:03, Jonathan Cameron wrote:
>>> On 20/07/16 09:29, Quentin Schulz wrote:
>>>> This enables the use of buffers on ADC channels of sunxi-gpadc-iio driver.
>>>> It also prepares the code which will be used by the touchscreen driver
>>>> named sunxi-gpadc-ts.
>>>>
>>>> The GPADC on Allwinner SoCs (A10, A13 and A31) has a 12 bits register for
>>>> conversion's data. The GPADC uses the same ADC channels for the ADC and the
>>>> touchscreen therefore exposes these channels to the sunxi-gpadc-ts iio
>>>> consumer which will be in charge of reading data from these channels for
>>>> the input framework.
>>>>
>>>> The temperature can only be read when in touchscreen mode. This means if
>>>> the buffers are being used for the ADC, the temperature sensor cannot be
>>>> read.
>>> That may be the bizarest hardware restriction I've heard of in a while! :)
>>>>
>>>> When a FIFO_DATA_PENDING irq occurs, its handler will read the entire FIFO
>>>> and fill a buffer before sending it to the consumers which registered in
>>>> IIO for the ADC channels.
>>>>
>>>> When a consumer starts buffering ADC channels,
>>>> sunxi_gpadc_buffer_postenable is called and will enable FIFO_DATA_PENDING
>>>> irq and select the mode in which the GPADC should run (ADC or touchscreen)
>>>> depending on a property of the DT ("allwinner,ts-attached").
>>>> When the consumer stops buffering, it disables the same irq.
>>> Hmm. Might be possible to distinguish which consumer caused the start.
>>> Thus, if the touchscreen is there we would know purely based on the
>>> driver being the requester that we need to be in touchscreen mode.
>>>
>>
>> As of yet, can't see in which way I can retrieve the consumer in
>> provider code. Maybe I'm missing something, I don't know?
> I don't think we have a current way of doing this... Might be possible
> to add one, but it would be a rather odd bit of reverse looking up.
[...]
>>>> @@ -101,19 +104,43 @@ struct sunxi_gpadc_dev {
>>>>unsigned intfifo_data_irq;
>>>>unsigned inttemp_data_irq;
>>>>unsigned intflags;
>>>> +  struct iio_dev  *indio_dev;
>>> I was suprised to see this as normally it is cleaner to structure
>>> the whole code to go in one direction through the structures (which is
>>> why we don't provide a generic iio_device_from_priv bit of pointer magic).
>>>
>>> Anyhow, don't htink you are actually using it ;)
>>>
>>
>> I'm using to push to buffers from the irq handler since I pass the local
>> structure (sunxi_gpadc_dev) to the irq handler when registering it. But
>> I guess I can pass the iio_dev instead and remove this from the local
>> structure.
> I'd prefer passing the iio_dev and keep all lookups in one direction.

ACK.

>>
>> [...]
>>>>  static int sunxi_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
>>>>int *val)
>>>>  {
>>>>struct sunxi_gpadc_dev *info = iio_priv(indio_dev);
>>>> +  bool buffered = info->buffered;
>>> Not worth the local version...
>>>>int ret = 0;
>>>> +  unsigned int reg;
>>>>  
>>>>mutex_lock(&indio_dev->mlock);
>>>>  
>>>>reinit_completion(&info->completion);
>>>> +
>>>> +  reg = SUNXI_GPADC_TP_FIFO_TRIG_LEVEL(1) | SUNXI_GPADC_TP_FIFO_FLUSH;
>>>> +  regmap_update_bits(info->regmap, SUNXI_GPADC_TP_INT_FIFOC, reg, reg);
>>> I'd put it in directly rahter than having a reg local variable.  To mind
>>> mind that would be slightly easier to understand.
>>>> +
>>>>if (info->flags & SUNXI_GPADC_ARCH_SUN6I)
>>>>r

Re: [PATCH 4/5] input: touchscreen: support Allwinner SoCs' touchscreen

2016-09-25 Thread Quentin Schulz
On 24/07/2016 13:24, Jonathan Cameron wrote:
> On 20/07/16 09:29, Quentin Schulz wrote:
>> This adds support for Allwinner SoCs' (A10, A13 and A31) resistive
>> touchscreen. This driver is probed by the MFD sunxi-gpadc-mfd.
>>
>> This driver uses ADC channels exposed through the IIO framework by
>> sunxi-gpadc-iio to get its data. When opening this input device, it will
>> start buffering in the ADC driver and enable a TP_UP_PENDING irq. The ADC
>> driver will fill in a buffer with all data and call the callback the input
>> device associated with this buffer. The input device will then read the
>> buffer two by two and send X and Y coordinates to the input framework based
>> on what it received from the ADC's buffer. When closing this input device,
>> the buffering is stopped.
>>
>> Note that locations in the first received buffer after an TP_UP_PENDING irq
>> occurred are unreliable, thus dropped.
>>
> I think I now understand what you are doing.
> 
> The channel grab is grabbing 4 channels, when there are only two real
> ones (x and y) then you are abusing the callback interface from IIO.

Actually, I need an IIO channel only for registering the callback from
the consumer but I never use the IIO channel in an other way from
consumer side (everything's done in the provider by reading the FIFO
register and sending data to the callback via iio_buffer).

> That transmits only one scan (e.g. here (x,y)) per call. Because you
> have added a sideband route for the buffer size what you have wil work.
> 
> However, it is not how the interface should be used.  Please fix that.
> Using it correctly is not a big issue.
> 
> On the channels front, I'd be tempted to do this as follows:
> 
> 6 Channels, not 4.
> 
> First 4 are standard ADC channels
> Next 2 are the touch screen channels with appropriate descriptions
> (guessing these are actually differential channels across the various
> wires of the first two?)
> 

Yes they are differential channels.

However, I think there is actually no sense in using several channels
for the touchscreen as everything is handled by the hardware. You only
select the touchscreen mode by setting a register and then X and Y
coordinates will be added to the FIFO register when touching the
touchscreen. I would not mind not having IIO channel at all since we do
not read from the consumer. But I need a way to register a callback to
get data from the provider. I don't know if I make myself clear enough?

> Then you set the map up to apply to the last two channels only.
> By setting available_scan_masks to the relevant options in the IIO driver
> you'll be able to automatically lock the device when ever the
> touch screeen driver is loaded.
> 
> That map will be something like (in binary
> 00
> 11
> 000100
> 001000
> 01
> 10
> 001100
> 010100
> 011000
> 100100
> 101000
> 11
> 011100
> 101100
> 110100
> 111000
> 00
> 
> thus any combination of the ADC channels, but always all or none of the
> touchscreen (none when ever the ADC channels are on) the order above
> ensures we always turn on the minimum possible for a given requirement.
> 
> Hence whenever the touch screen is there it'll lock out the ADC usage.
> Your postenable can look at what is there and put it in the right mode.
> 

I'll dive more into that.

> After that, break your fifo read up into individual pairs of readings
> and push those out.
> 
> That way we end up using the interface in the standard fashion.
> 
> You'll also need fix the usage of the fifo for ADC mode which suffers
> from the same problem.  There all sorts of nasty crashes might occur
> or you might just loose data
> 
[...]
>> +/*
>> + * This function will be called by iio_push_to_buffers from another driver
>> + * (namely sunxi-gpadc-iio). It will be passed the buffer filled with input
>> + * values (X value then Y value) and the sunxi_gpadc_ts structure 
>> representing
>> + * the device.
>> + */
>> +static int sunxi_gpadc_ts_callback(const void *data, void *private)
>> +{
>> +const struct sunxi_gpadc_buffer *buffer = data;
>> +struct sunxi_gpadc_ts *info = private;
>> +int i = 0;
>> +
>> +/* Locations in the first buffer after an up event are unreliable */
>> +if (info->ignore_fifo_data) {
>> +info->ignore_fifo_data = false;
>> +return 0;
>> +}
>> +
> It doesn't work like this at all. You'll get one scan only on each call of
> this function.  As I said in the previous driver, if there is a true reason
> to do this (and I'm unconvinced a

Re: [PATCH 4/5] input: touchscreen: support Allwinner SoCs' touchscreen

2016-09-24 Thread Quentin Schulz
Hi Dimitry,

Sorry for the (long) delay, I did not have time to work on it. I'll
mainly work in my free time now.

On 20/07/2016 19:25, Dmitry Torokhov wrote:
> Hi Quentin,
> 
> On Wed, Jul 20, 2016 at 10:29:10AM +0200, Quentin Schulz wrote:
>> This adds support for Allwinner SoCs' (A10, A13 and A31) resistive
>> touchscreen. This driver is probed by the MFD sunxi-gpadc-mfd.
>>
>> This driver uses ADC channels exposed through the IIO framework by
>> sunxi-gpadc-iio to get its data. When opening this input device, it will
>> start buffering in the ADC driver and enable a TP_UP_PENDING irq. The ADC
>> driver will fill in a buffer with all data and call the callback the input
>> device associated with this buffer. The input device will then read the
>> buffer two by two and send X and Y coordinates to the input framework based
>> on what it received from the ADC's buffer. When closing this input device,
>> the buffering is stopped.
>>
>> Note that locations in the first received buffer after an TP_UP_PENDING irq
>> occurred are unreliable, thus dropped.
>>
>> Signed-off-by: Quentin Schulz 
>> ---
[...]
>> +info->buffer = iio_channel_get_all_cb(&pdev->dev,
>> +  &sunxi_gpadc_ts_callback,
>> +  (void *)info);
> 
> Any chance we could introduce devm-variant here? If you do not want to
> wait for IIO to add it you can temporarily add call
> devm_add_action_or_reset() after getting channels and remove it when IIO
> API catches up.
> 

Something like:

release_iio_channels(void* data)
{
struct sunxi_gpadc_ts *info = data;
iio_channel_release_all_cb(info->buffer);
}

[...]
info->buffer = iio_channel_get_all_cb(&pdev->dev,
  &sunxi_gpadc_ts_callback,
  (void *)info);
ret = devm_add_action_or_reset(&pdev->dev,
   release_iio_channels,
   (void *)info);
if (ret)
return ret;

?

May I know why you prefer that way instead of explicit removing in
remove function of the platform device? I understand for devm-variant
already in the framework but I am curious for this one.

[...]
>> +static int sunxi_gpadc_ts_remove(struct platform_device *pdev)
>> +{
>> +struct sunxi_gpadc_ts *info = platform_get_drvdata(pdev);
>> +
>> +iio_channel_stop_all_cb(info->buffer);
>> +iio_channel_release_all_cb(info->buffer);
>> +
>> +disable_irq(info->tp_up_irq);
> 
> You are mixing devm and non-devm so your unwind order is completely out
> of wack. If input device is opened while you are unloading (or
> unbinding) the dirver, then you'll release channels, then input device's
> close() will be called, which will try to stop the IIO channels again
> and disable IRQ yet again.
> 

Do you mean that I should be using exclusively devm or non-devm functions?
Do you mean input device's close will always be called when
unloading/unbinding the driver?

[...]
Thanks,
Quentin

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


Re: [PATCH 3/5] iio: adc: sunxi-gpadc-iio: enable iio_buffers

2016-09-24 Thread Quentin Schulz
Hi Jonathan,

Sorry for the (long) delay, I did not have time to work on it. I'll
mainly work in my free time now.

Keep in mind this patch was proposed based on the v2 of the ADC patches.
Since then, substantial changes have been made and I'm working on
rebasing this series of patches on the v6, so comments here might
include references to code parts added later in the ADC patch series.

On 24/07/2016 13:03, Jonathan Cameron wrote:
> On 20/07/16 09:29, Quentin Schulz wrote:
>> This enables the use of buffers on ADC channels of sunxi-gpadc-iio driver.
>> It also prepares the code which will be used by the touchscreen driver
>> named sunxi-gpadc-ts.
>>
>> The GPADC on Allwinner SoCs (A10, A13 and A31) has a 12 bits register for
>> conversion's data. The GPADC uses the same ADC channels for the ADC and the
>> touchscreen therefore exposes these channels to the sunxi-gpadc-ts iio
>> consumer which will be in charge of reading data from these channels for
>> the input framework.
>>
>> The temperature can only be read when in touchscreen mode. This means if
>> the buffers are being used for the ADC, the temperature sensor cannot be
>> read.
> That may be the bizarest hardware restriction I've heard of in a while! :)
>>
>> When a FIFO_DATA_PENDING irq occurs, its handler will read the entire FIFO
>> and fill a buffer before sending it to the consumers which registered in
>> IIO for the ADC channels.
>>
>> When a consumer starts buffering ADC channels,
>> sunxi_gpadc_buffer_postenable is called and will enable FIFO_DATA_PENDING
>> irq and select the mode in which the GPADC should run (ADC or touchscreen)
>> depending on a property of the DT ("allwinner,ts-attached").
>> When the consumer stops buffering, it disables the same irq.
> Hmm. Might be possible to distinguish which consumer caused the start.
> Thus, if the touchscreen is there we would know purely based on the
> driver being the requester that we need to be in touchscreen mode.
> 

As of yet, can't see in which way I can retrieve the consumer in
provider code. Maybe I'm missing something, I don't know?

>>
>> Signed-off-by: Quentin Schulz 
> You are moving fast on this - I'd have been tempted to do a mega
> series with the updated version of the basic support and this on top
> rather than a new unconnected series.
> 
> (I'd forgotten that was still under review so got confused when I
> went to look something up in the files you are modifying!).
>> ---
>>  drivers/iio/adc/Kconfig   |   1 +
>>  drivers/iio/adc/sunxi-gpadc-iio.c | 153 
>> ++
>>  2 files changed, 138 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>> index 184856f..15e3b08 100644
>> --- a/drivers/iio/adc/Kconfig
>> +++ b/drivers/iio/adc/Kconfig
>> @@ -342,6 +342,7 @@ config SUNXI_ADC
>>  tristate "ADC driver for sunxi platforms"
>>  depends on IIO
>>  depends on MFD_SUNXI_ADC
>> +depends on IIO_BUFFER_CB
>>  help
>>Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
>>ADC. This ADC provides 4 channels which can be used as an ADC or as a
>> diff --git a/drivers/iio/adc/sunxi-gpadc-iio.c 
>> b/drivers/iio/adc/sunxi-gpadc-iio.c
>> index 87cc913..2e44ca7 100644
>> --- a/drivers/iio/adc/sunxi-gpadc-iio.c
>> +++ b/drivers/iio/adc/sunxi-gpadc-iio.c
>> @@ -16,8 +16,9 @@
>>  #include 
>>  #include 
>>  
>> -#include 
>> +#include 
>>  #include 
>> +#include 
> Can't say I'm a particular fan of reordering headers to be in alphabetical
> order, but I suppose it doesn't really matter if you want to do it.
> (to my mind there is a tree structure implicit in these headers with iio.h
> at the top for generic support, then the various sub elements below).
> 
>>  #include 
>>  #include 
>>  
>> @@ -71,6 +72,7 @@
>>  #define SUNXI_GPADC_TP_DATA_XY_CHANGE   BIT(13)
>>  #define SUNXI_GPADC_TP_FIFO_TRIG_LEVEL(x)   ((x) << 8)  /* 5 bits */
>>  #define SUNXI_GPADC_TP_DATA_DRQ_EN  BIT(7)
>> +/* Be careful, flushing FIFO spawns SUNXI_GPADC_FIFO_DATA_PENDING 
>> interrupts */
> Sounds like you learned that one the hard way ;)
>>  #define SUNXI_GPADC_TP_FIFO_FLUSH   BIT(4)
>>  #define SUNXI_GPADC_TP_UP_IRQ_ENBIT(1)
>>  #define SUNXI_GPADC_TP_DOWN_IRQ_EN  BIT(0)
>> @@ -79,6 +81,7 @@
>>  #define SUNXI_GPADC_TEMP_DATA_PENDING   BIT(18)
>>  #define SUNXI_G

[PATCH v6 2/2] iio: adc: add support for Allwinner SoCs ADC

2016-09-15 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. This patch adds the ADC driver which is
based on the MFD for the same SoCs ADC.

This also registers the thermal adc channel in the iio map array so
iio_hwmon could use it without modifying the Device Tree. This registers
the driver in the thermal framework.

This driver probes on three different platform_device_id to take into
account slight differences (registers bit and temperature computation)
between Allwinner SoCs ADCs.

Signed-off-by: Quentin Schulz 
Acked-by: Maxime Ripard 
Acked-by: Jonathan Cameron 
---

v6:
 - remove useless member (regs) from sun4i_gpadc_dev structure,
 - rename sun4i_gpadc_dev structure to sun4i_gpadc_iio,
 - remove regmap_update_bits used to disable hardware interrupts, it is already
 handled by devm functions,

v5:
 - correct mail address,
 - correct several typos,
 - move from const to static for sunxi_gpadc_chan_select functions,
 - rename soc_specific struct to gpadc_data,
 - rename soc_specific field to data in sun4i_gpadc_dev,
 - return error code from regmap_write in case of failure in read_raws,
 - share if condition in IIO_CHAN_INFO_RAW case,
 - add comment on why we use parent device for registering in thermal,
 - reordering remove function,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - shorten sunxi_gpadc_soc_specific structure to soc_specific,
 - factorize sysfs ADC and temp read_raws,
 - use cached values when read_raw times out (except before a first value
   is gotten),
 - remove mutex locks and unlocks from runtime_pm functions,
 - factorize irq initializations,
 - initialize temp_data and fifo_data values to -1 (error value),
 - "impersonate" MFD to register in thermal framework,
 - deactivate hardware interrupts one by one when probe fails or when
   removing driver instead of blindly deactivating all hardware interrupts,
 - selects THERMAL_OF in Kconfig,

v3:
 - correct wrapping,
 - add comment about thermal sensor inner working,
 - move defines in mfd header,
 - use structure to define SoC specific registers or behaviour,
 - attach this structure to the device according to of_device_id of the
   platform device,
 - use new mutex instead of iio_dev mutex,
 - use atomic flags to avoid race between request_irq and disable_irq in
   probe,
 - switch from processed value to raw, offset and scale values for
   temperature ADC channel,
 - remove faulty sentinel in iio_chan_spec array,
 - add pm_runtime support,
 - register thermal sensor in thermal framework (forgotten since the
   beginning whereas it is present in current sun4i-ts driver),
 - remove useless ret variables to store return value of regmap_reads,
 - move comments on thermal sensor acquisition period in code instead of
   header,
 - adding goto label to unregister iio_map_array when failing to register
   iio_dev,

v2:
 - add SUNXI_GPADC_ prefixes for defines,
 - correct typo in Kconfig,
 - reorder alphabetically includes, makefile,
 - add license header,
 - fix architecture variations not being handled in interrupt handlers or
   read raw functions,
 - fix unability to return negative values from thermal sensor,
 - add gotos to reduce code repetition,
 - fix irq variable being unsigned int instead of int,
 - remove useless dev_err and dev_info,
 - deactivate all interrupts if probe fails,
 - fix iio_device_register on NULL variable,
 - deactivate ADC in the IP when probe fails or when removing driver,

 drivers/iio/adc/Kconfig   |  13 +
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 522 ++
 3 files changed, 536 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 25378c5..ea36a4f 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -384,6 +384,19 @@ config ROCKCHIP_SARADC
  To compile this driver as a module, choose M here: the
  module will be called rockchip_saradc.
 
+config SUN4I_GPADC
+   tristate "Support for the Allwinner SoCs GPADC"
+   depends on IIO
+   depends on MFD_SUN4I_GPADC
+   select THERMAL_OF
+   help
+ Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
+ GPADC. This ADC provides 4 channels which can be used as an ADC or as
+ a touchscreen input and one channel for thermal sensor.
+
+ To compile this driver as a module, choose M here: the module will be
+ called sun4i-gpadc-iio.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 38638d4..204372d 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
 obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
 obj-$(CONFI

[PATCH v6 0/2] add support for Allwinner SoCs ADC

2016-09-15 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used either
for the ADC or the touchscreen and the fifth channel is used for the
thermal sensor. We currently have a driver for the two latter functions in
drivers/input/touchscreen/sun4i-ts.c but we don't have access to the ADC
feature at all. It is meant to replace the current driver by using MFD and
subdrivers.

This adds initial support for Allwinner SoCs ADC with all features. Yet,
the touchscreen is not implemented but will be added later. To switch
between touchscreen and ADC modes, you need to poke a few bits in registers
and (de)activate an interrupt (pen-up).
An MFD is provided to let the input driver activate the pen-up interrupt
through a virtual interrupt, poke a few bits via regmap and read data from
the ADC driver while both (and iio_hwmon) are probed by the MFD.

There are slight variations between the different SoCs ADC like the address
of some registers and the scale and offset to apply to raw thermal sensor
values. These variations are handled by using different platform_device_id,
passed to the sub-drivers when they are probed by the MFD.

Removal of proposed patch for iio_hwmon's iio channel's label in v3. The
patch induces irreversible ABI changes and will be handled as a separate
patch since I think it is not absolutely necessary to have labels yet in
iio_hwmon.

Removal of proposed patch for reattaching of_node of the MFD to the MFD
cell device structure in v3. As Lee Jones said, this patch might cause
"unintended side-effects for existing drivers.". Moreover, this patch
introduced a bug of multiple probe of this MFD driver I haven't identified
yet. This patch aimed at allowing the ADC driver (which is a child of the
MFD and not present in the DT) to register in the thermal framework. The
thermal driver has a phandle to the MFD node which is used to match against
the MFD of_node but since the ADC driver has no node in the DT, could not
register in the thermal framework. The other solution is to "impersonate"
the MFD when registering in the thermal framework since the device is only
used to match the phandle and the of_node, an other structure passed by
parameter being used to compute temperatures.

(in the ADC driver, probed by the MFD driver) instead of:
tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info,
   &sun4i_ts_tz_ops);
we now have:
tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, info,
   &sun4i_ts_tz_ops);

Removal of proposed patch to use late_initcall for iio_hwmon probe deferring.

Removal of patch for iio_hwmon probe deferring due to being applied to -next by
Guenter Roeck.

Quentin Schulz (2):
  mfd: add support for Allwinner SoCs ADC
  iio: adc: add support for Allwinner SoCs ADC

 drivers/iio/adc/Kconfig   |  13 +
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 522 ++
 drivers/mfd/Kconfig   |  15 ++
 drivers/mfd/Makefile  |   2 +
 drivers/mfd/sun4i-gpadc.c | 181 +
 include/linux/mfd/sun4i-gpadc.h   |  94 +++
 7 files changed, 828 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c
 create mode 100644 drivers/mfd/sun4i-gpadc.c
 create mode 100644 include/linux/mfd/sun4i-gpadc.h

-- 
2.5.0



[PATCH v6 1/2] mfd: add support for Allwinner SoCs ADC

2016-09-15 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. For now, only the ADC and the thermal
sensor drivers are probed by the MFD, the touchscreen controller support
will be added later.

Signed-off-by: Quentin Schulz 
Acked-by: Maxime Ripard 
Acked-by: Jonathan Cameron 
---

v6:
 - remove "-mfd" from filenames and variables inside MFD driver,
 - use DEFINE_RES_IRQ_NAMED instead of setting resources manually,
 - cosmetic changes,
 - use IDs and switch over ID to get cells specific to an architecture, instead
 of using cells direclty, in of_device_id.data,
 - compute size of mfd_cells array instead of hardcoded one,

v5:
 - correct mail address,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - rename defines from SUNXI_* to SUN4I_* or SUN6I_*,
 - remove TP in defines name,
 - rename SUNXI_IRQ_* to SUN4I_GPADC_IRQ_* for consistency,
 - use devm functions for regmap_add_irq_chip and mfd_add_devices,
 - remove remove functions (now empty thanks to devm functions),

v3:
 - use defines in regmap_irq instead of hard coded BITs,
 - use of_device_id data field to chose which MFD cells to add considering
   the compatible responsible of the MFD probe,
 - remove useless initializations,
 - disable all interrupts before adding them to regmap_irqchip,
 - add goto error label in probe,
 - correct wrapping in header license,
 - move defines from IIO driver to header,
 - use GENMASK to limit the size of the variable passed to a macro,
 - prefix register BIT defines with the name of the register,
 - reorder defines,

v2:
 - add license headers,
 - reorder alphabetically includes,
 - add SUNXI_GPADC_ prefixes for defines,

 drivers/mfd/Kconfig |  15 
 drivers/mfd/Makefile|   2 +
 drivers/mfd/sun4i-gpadc.c   | 181 
 include/linux/mfd/sun4i-gpadc.h |  94 +
 4 files changed, 292 insertions(+)
 create mode 100644 drivers/mfd/sun4i-gpadc.c
 create mode 100644 include/linux/mfd/sun4i-gpadc.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 1bcf601..45db3f4 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -29,6 +29,21 @@ config MFD_ACT8945A
  linear regulators, along with a complete ActivePath battery
  charger.
 
+config MFD_SUN4I_GPADC
+   tristate "Allwinner sunxi platforms' GPADC MFD driver"
+   select MFD_CORE
+   select REGMAP_MMIO
+   depends on ARCH_SUNXI || COMPILE_TEST
+   help
+ Select this to get support for Allwinner SoCs (A10, A13 and A31) ADC.
+ This driver will only map the hardware interrupt and registers, you
+ have to select individual drivers based on this MFD to be able to use
+ the ADC or the thermal sensor. This will try to probe the ADC driver
+ sun4i-gpadc-iio and the hwmon driver iio_hwmon.
+
+ To compile this driver as a module, choose M here: the module will be
+ called sun4i-gpadc.
+
 config MFD_AS3711
bool "AMS AS3711"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 42a66e1..12c49af 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -205,3 +205,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o 
intel_soc_pmic_crc.o
 intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)   += intel-soc-pmic.o
 obj-$(CONFIG_MFD_MT6397)   += mt6397-core.o
+
+obj-$(CONFIG_MFD_SUN4I_GPADC)  += sun4i-gpadc.o
diff --git a/drivers/mfd/sun4i-gpadc.c b/drivers/mfd/sun4i-gpadc.c
new file mode 100644
index 000..276a1f4
--- /dev/null
+++ b/drivers/mfd/sun4i-gpadc.c
@@ -0,0 +1,181 @@
+/* ADC MFD core driver for sunxi platforms
+ *
+ * Copyright (c) 2016 Quentin Schulz 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define ARCH_SUN4I_A10 0
+#define ARCH_SUN5I_A13 1
+#define ARCH_SUN6I_A31 2
+
+static struct resource adc_resources[] = {
+   DEFINE_RES_IRQ_NAMED(SUN4I_GPADC_IRQ_FIFO_DATA, "FIFO_DATA_PENDING"),
+   DEFINE_RES_IRQ_NAMED(SUN4I_GPADC_IRQ_TEMP_DATA, "TEMP_DATA_PENDING"),
+};
+
+static const struct regmap_irq sun4i_gpadc_regmap_irq[] = {
+   REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_FIFO_DATA, 0,
+  SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN),
+   REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_TEMP_DATA, 0,
+  SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN),
+};
+
+static const struct regmap_irq_chip sun4i_gpadc_regmap_irq_chip = {
+   .name = "sun4i_gpadc_irq_chip",
+   .status_base = SUN4I_GPADC_INT_FIFOS,
+   .ack_base = SUN4I_GPADC_INT_FIFOS,
+   .mask_base = SUN4I_GPADC_INT_FIFOC,
+   .i

Re: [PATCH v5 2/3] mfd: add support for Allwinner SoCs ADC

2016-09-13 Thread Quentin Schulz
On 12/09/2016 15:56, Lee Jones wrote:
> On Mon, 12 Sep 2016, Quentin Schulz wrote:
>> On 12/09/2016 11:59, Lee Jones wrote:
>>> On Mon, 12 Sep 2016, Quentin Schulz wrote:
>>>
>>>> On 12/09/2016 11:18, Lee Jones wrote:
>>>>> On Thu, 08 Sep 2016, Quentin Schulz wrote:
>>>>> [...]
>>>>>> +
>>>>>> +MODULE_DEVICE_TABLE(of, sun4i_gpadc_mfd_of_match);
>>>>>
>>>>> Place this directly under the table.
>>>>>
>>>>>> +static struct platform_driver sun4i_gpadc_mfd_driver = {
>>>>>> +.driver = {
>>>>>> +.name = "sun4i-adc-mfd",
>>>>>> +.of_match_table = 
>>>>>> of_match_ptr(sun4i_gpadc_mfd_of_match),
>>>>>> +},
>>>>>> +.probe = sun4i_gpadc_mfd_probe,
>>>>>
>>>>> No .remove?
>>>>>
>>>>
>>>> No, everything in probe is handled with devm functions.
>>>
>>> Don't you need to undo the register write you did?
>>>
>>
>> The regmap_write I use is there to disable all interrupts on hardware
>> side before the irq_chip handles all interrupts by itself. The
>> interrupts are not used in the MFD driver.
>>
>> Thus, I chose to disable the hardware interrupts in the remove function
>> of drivers using the interrupts (only the IIO yet but the touchscreen
>> driver later also which will be using a third interrupt). When the MFD
>> driver is removed, the MFD cells will all be removed, thus calling their
>> own remove functions, thus disabling hardware interrupts used in each
>> driver. So the hardware interrupts disabling would be called twice.
> 
> This does send some little alarm bells ringing.  I'd normally expect
> the .remove function to undo everything you did in .probe.  So, if you
> are disabling the IRQs from within the leaf drivers, shouldn't you be
> initialising them in the leaf driver's respective .probes?
> 

I use the regmap_write in the MFD driver's probe to disable all
interrupts before requesting irq_chip to guarantee the interrupts are in
a known state, being disabled. It is to insure no interrupt will occur
unwittingly before we want the leaf drivers to handle them.

The disabling of irqs in the remove is handled rather by
devm_regmap_del_irq_chip than by an explicit regmap_write in the
driver's removal function. It performs the exact same thing.

I always use devm functions for requesting either an irq_chip or the
irqs themselves. In that case, when the device is removed, the irqs are
freed on leaf drivers' (where the irqs are requested) removal while the
removal of irq_chip in the MFD driver will also free all irqs mapped to
this irq_chip thanks to devm_regmap_del_irq_chip. Therefore, the
interrupts are disabled by devm functions.

The regmap_update_bits in probe and removal of the ADC driver to disable
irqs are actually redundant because the devm functions already handle
the irqs disabling.

Thanks,
Quentin


Re: [PATCH v5 2/3] mfd: add support for Allwinner SoCs ADC

2016-09-12 Thread Quentin Schulz


On 12/09/2016 11:59, Lee Jones wrote:
> On Mon, 12 Sep 2016, Quentin Schulz wrote:
> 
>> On 12/09/2016 11:18, Lee Jones wrote:
>>> On Thu, 08 Sep 2016, Quentin Schulz wrote:
>>>
>> [...]
> 
> [...]
> 
>>>> +++ b/drivers/mfd/sun4i-gpadc-mfd.c
> 
> [...]
> 
>>>> +static struct mfd_cell sun4i_gpadc_mfd_cells[] = {
>>>> +  {
>>>> +  .name   = "sun4i-a10-gpadc-iio",
>>>> +  .resources = adc_resources,
>>>> +  .num_resources = ARRAY_SIZE(adc_resources),
>>>> +  }, {
>>>> +  .name = "iio_hwmon",
>>>> +  }
>>>
>>> Single line please
>>>
>>> { .name = "iio_hwmon" }
>>>
>>
>> +{
>> +.name   = "sun4i-a10-gpadc-iio",
>> +.resources = adc_resources,
>> +.num_resources = ARRAY_SIZE(adc_resources),
>> +}, { .name = "iio_hwmon" }
>>
>> or
>>
>> +{
>> +.name   = "sun4i-a10-gpadc-iio",
>> +.resources = adc_resources,
>> +.num_resources = ARRAY_SIZE(adc_resources),
>> +},
>> +{ .name = "iio_hwmon" }
>>
>> ?
> 
> The latter.
> 
> [...]
> 
>>>> +static const struct of_device_id sun4i_gpadc_mfd_of_match[] = {
>>>> +  {
>>>> +  .compatible = "allwinner,sun4i-a10-ts",
>>>> +  .data = &sun4i_gpadc_mfd_cells,
>>>> +  }, {
>>>> +  .compatible = "allwinner,sun5i-a13-ts",
>>>> +  .data = &sun5i_gpadc_mfd_cells,
>>>> +  }, {
>>>> +  .compatible = "allwinner,sun6i-a31-ts",
>>>> +  .data = &sun6i_gpadc_mfd_cells,
>>>> +  }, { /* sentinel */ }
>>>> +};
>>>
>>> Don't mix OF and MFD functionality.
>>>
>>> Why don't you create a node for "iio_hwmon" and have
>>> platform_of_populate() do your bidding?
>>>
>>
>> We are using a stable binding which we cannot modify. This means, the DT
>> in its current state can only be modified to add features, which is not
>> the case of this driver (it is a rewriting of an existing driver which
>> uses the rtp node).
> 
> Then use .data =  and set up a switch() in .probe().
> 
>>>> +static int sun4i_gpadc_mfd_probe(struct platform_device *pdev)
>>>
>>> Remove all mention of "mfd" from this file.
>>>
>>> (Accept the calls to the MFD API of course).
>>>
>> [...]
>>>> +
>>>> +MODULE_DEVICE_TABLE(of, sun4i_gpadc_mfd_of_match);
>>>
>>> Place this directly under the table.
>>>
>>>> +static struct platform_driver sun4i_gpadc_mfd_driver = {
>>>> +  .driver = {
>>>> +  .name = "sun4i-adc-mfd",
>>>> +  .of_match_table = of_match_ptr(sun4i_gpadc_mfd_of_match),
>>>> +  },
>>>> +  .probe = sun4i_gpadc_mfd_probe,
>>>
>>> No .remove?
>>>
>>
>> No, everything in probe is handled with devm functions.
> 
> Don't you need to undo the register write you did?
> 

The regmap_write I use is there to disable all interrupts on hardware
side before the irq_chip handles all interrupts by itself. The
interrupts are not used in the MFD driver.

Thus, I chose to disable the hardware interrupts in the remove function
of drivers using the interrupts (only the IIO yet but the touchscreen
driver later also which will be using a third interrupt). When the MFD
driver is removed, the MFD cells will all be removed, thus calling their
own remove functions, thus disabling hardware interrupts used in each
driver. So the hardware interrupts disabling would be called twice.

Quentin



signature.asc
Description: OpenPGP digital signature


Re: [PATCH v5 2/3] mfd: add support for Allwinner SoCs ADC

2016-09-12 Thread Quentin Schulz
On 12/09/2016 12:49, Lee Jones wrote:
> On Mon, 12 Sep 2016, Maxime Ripard wrote:
> 
>> On Mon, Sep 12, 2016 at 10:59:23AM +0100, Lee Jones wrote:
>> +static const struct of_device_id sun4i_gpadc_mfd_of_match[] = {
>> +{
>> +.compatible = "allwinner,sun4i-a10-ts",
>> +.data = &sun4i_gpadc_mfd_cells,
>> +}, {
>> +.compatible = "allwinner,sun5i-a13-ts",
>> +.data = &sun5i_gpadc_mfd_cells,
>> +}, {
>> +.compatible = "allwinner,sun6i-a31-ts",
>> +.data = &sun6i_gpadc_mfd_cells,
>> +}, { /* sentinel */ }
>> +};
>
> Don't mix OF and MFD functionality.
>
> Why don't you create a node for "iio_hwmon" and have
> platform_of_populate() do your bidding?
>

 We are using a stable binding which we cannot modify. This means, the DT
 in its current state can only be modified to add features, which is not
 the case of this driver (it is a rewriting of an existing driver which
 uses the rtp node).
>>>
>>> Then use .data =  and set up a switch() in .probe().
>>
>> Uh? Why? It just adds a non-standard indirection, while using
>> of_match_device is very standard, and used extensively in Linux.
> 
> You still use of_match_device() to obtain the ID.
> 
> The "don't mix DT with the MFD API" is there to prevent some of the
> nasty hacks I've seen previously.  This particular example doesn't
> seem so bad, but it's a gateway to ridiculous hackery!
> 

How am I supposed to get the .data without of_match_node then?
What's more hackish in using .data field for specific data for each
compatible than in using a random ID in .data and switching on it? The
result is exactly the same, the switching case being more verbose and
adding complexity to something that can be done in a straightforward manner.

Quentin


Re: [PATCH v5 2/3] mfd: add support for Allwinner SoCs ADC

2016-09-12 Thread Quentin Schulz
On 12/09/2016 11:18, Lee Jones wrote:
> On Thu, 08 Sep 2016, Quentin Schulz wrote:
> 
[...]
>> +  To compile this driver as a module, choose M here: the module will be
>> +  called sun4i-gpadc-mfd.
> 
> Drop the -mfd.
> 
>>  config MFD_AS3711
>>  bool "AMS AS3711"
>>  select MFD_CORE
>> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
>> index 42a66e1..3b964d7 100644
>> --- a/drivers/mfd/Makefile
>> +++ b/drivers/mfd/Makefile
>> @@ -205,3 +205,5 @@ intel-soc-pmic-objs  := 
>> intel_soc_pmic_core.o intel_soc_pmic_crc.o
>>  intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC)  += intel_soc_pmic_bxtwc.o
>>  obj-$(CONFIG_INTEL_SOC_PMIC)+= intel-soc-pmic.o
>>  obj-$(CONFIG_MFD_MT6397)+= mt6397-core.o
>> +
>> +obj-$(CONFIG_MFD_SUN4I_GPADC)   += sun4i-gpadc-mfd.o
>> diff --git a/drivers/mfd/sun4i-gpadc-mfd.c b/drivers/mfd/sun4i-gpadc-mfd.c
>> new file mode 100644
>> index 000..b499545
>> --- /dev/null
>> +++ b/drivers/mfd/sun4i-gpadc-mfd.c
> 
> Drop the -mfd.
> 
>> @@ -0,0 +1,174 @@
>> +/* ADC MFD core driver for sunxi platforms
>> + *
>> + * Copyright (c) 2016 Quentin Schulz 
>> + *
>> + * 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 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +
>> +static struct resource adc_resources[] = {
>> +{
>> +.name   = "FIFO_DATA_PENDING",
>> +.start  = SUN4I_GPADC_IRQ_FIFO_DATA,
>> +.end= SUN4I_GPADC_IRQ_FIFO_DATA,
>> +.flags  = IORESOURCE_IRQ,
>> +}, {
>> +.name   = "TEMP_DATA_PENDING",
>> +.start  = SUN4I_GPADC_IRQ_TEMP_DATA,
>> +.end= SUN4I_GPADC_IRQ_TEMP_DATA,
>> +.flags  = IORESOURCE_IRQ,
>> +},
>> +};
> 
> Use the RES_IRQ_* defines.
> 
>> +static const struct regmap_irq sun4i_gpadc_mfd_regmap_irq[] = {
>> +REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_FIFO_DATA, 0,
>> +   SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN),
>> +REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_TEMP_DATA, 0,
>> +   SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN),
>> +};
>> +
>> +static const struct regmap_irq_chip sun4i_gpadc_mfd_regmap_irq_chip = {
>> +.name = "sun4i_gpadc_mfd_irq_chip",
>> +.status_base = SUN4I_GPADC_INT_FIFOS,
>> +.ack_base = SUN4I_GPADC_INT_FIFOS,
>> +.mask_base = SUN4I_GPADC_INT_FIFOC,
>> +.init_ack_masked = true,
>> +.mask_invert = true,
>> +.irqs = sun4i_gpadc_mfd_regmap_irq,
>> +.num_irqs = ARRAY_SIZE(sun4i_gpadc_mfd_regmap_irq),
>> +.num_regs = 1,
>> +};
>> +
>> +static struct mfd_cell sun4i_gpadc_mfd_cells[] = {
>> +{
>> +.name   = "sun4i-a10-gpadc-iio",
>> +.resources = adc_resources,
>> +.num_resources = ARRAY_SIZE(adc_resources),
>> +}, {
>> +.name = "iio_hwmon",
>> +}
> 
> Single line please
> 
> { .name = "iio_hwmon" }
>

+   {
+   .name   = "sun4i-a10-gpadc-iio",
+   .resources = adc_resources,
+   .num_resources = ARRAY_SIZE(adc_resources),
+   }, { .name = "iio_hwmon" }

or

+   {
+   .name   = "sun4i-a10-gpadc-iio",
+   .resources = adc_resources,
+   .num_resources = ARRAY_SIZE(adc_resources),
+   },
+   { .name = "iio_hwmon" }

?
>> +};
>> +
>> +static struct mfd_cell sun5i_gpadc_mfd_cells[] = {
>> +{
>> +.name   = "sun5i-a13-gpadc-iio",
>> +.resources = adc_resources,
>> +.num_resources = ARRAY_SIZE(adc_resources),
>> +}, {
>> +.name = "iio_hwmon",
>> +},
>> +};
> 
> As above.
> 
>> +static struct mfd_cell sun6i_gpadc_mfd_cells[] = {
>> +{
>> +.name   = "sun6i-a31-gpadc-iio",
>> +.resources = adc_resources,
>> +.num_resources = ARRAY_SIZE(adc_resources),
>> +}, {
>> +.name = "iio_hwmon",
>> +},
>> +};
> 
> As above.
> 
>> +static const struct regmap_config sun4i

[PATCH v5 0/3] add support for Allwinner SoCs ADC

2016-09-08 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. The first four channels can be used either
for the ADC or the touchscreen and the fifth channel is used for the
thermal sensor. We currently have a driver for the two latter functions in
drivers/input/touchscreen/sun4i-ts.c but we don't have access to the ADC
feature at all. It is meant to replace the current driver by using MFD and
subdrivers.

This adds initial support for Allwinner SoCs ADC with all features. Yet,
the touchscreen is not implemented but will be added later. To switch
between touchscreen and ADC modes, you need to poke a few bits in registers
and (de)activate an interrupt (pen-up).
An MFD is provided to let the input driver activate the pen-up interrupt
through a virtual interrupt, poke a few bits via regmap and read data from
the ADC driver while both (and iio_hwmon) are probed by the MFD.

There are slight variations between the different SoCs ADC like the address
of some registers and the scale and offset to apply to raw thermal sensor
values. These variations are handled by using different platform_device_id,
passed to the sub-drivers when they are probed by the MFD.

This also modifies iio-hwmon to allow probe deferring when no iio channel
is found. Currently when no iio channel is found, the probing of iio-hwmon
fails. This is problematic when iio-hwmon probes before the iio driver
could register iio channels to share.

Removal of proposed patch for iio_hwmon's iio channel's label in v3. The
patch induces irreversible ABI changes and will be handled as a separate
patch since I think it is not absolutely necessary to have labels yet in
iio_hwmon.

Removal of proposed patch for reattaching of_node of the MFD to the MFD
cell device structure in v3. As Lee Jones said, this patch might cause
"unintended side-effects for existing drivers.". Moreover, this patch
introduced a bug of multiple probe of this MFD driver I haven't identified
yet. This patch aimed at allowing the ADC driver (which is a child of the
MFD and not present in the DT) to register in the thermal framework. The
thermal driver has a phandle to the MFD node which is used to match against
the MFD of_node but since the ADC driver has no node in the DT, could not
register in the thermal framework. The other solution is to "impersonate"
the MFD when registering in the thermal framework since the device is only
used to match the phandle and the of_node, an other structure passed by
parameter being used to compute temperatures.

(in the ADC driver, probed by the MFD driver) instead of:
tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, info,
   &sun4i_ts_tz_ops);
we now have:
tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, info,
   &sun4i_ts_tz_ops);

Removal of proposed patch to use late_initcall for iio_hwmon probe deferring.

Quentin Schulz (3):
  hwmon: iio_hwmon: defer probe when no channel is found
  mfd: add support for Allwinner SoCs ADC
  iio: adc: add support for Allwinner SoCs ADC

 drivers/hwmon/iio_hwmon.c   |   5 +-
 drivers/iio/adc/Kconfig |  13 +
 drivers/iio/adc/Makefile|   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c   | 543 
 drivers/mfd/Kconfig |  15 +
 drivers/mfd/Makefile|   2 +
 drivers/mfd/sun4i-gpadc-mfd.c   | 174 
 include/linux/mfd/sun4i-gpadc-mfd.h |  94 +++
 8 files changed, 846 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c
 create mode 100644 drivers/mfd/sun4i-gpadc-mfd.c
 create mode 100644 include/linux/mfd/sun4i-gpadc-mfd.h

-- 
2.5.0



[PATCH v5 1/3] hwmon: iio_hwmon: defer probe when no channel is found

2016-09-08 Thread Quentin Schulz
iio_channel_get_all returns -ENODEV when it cannot find either phandles and
properties in the Device Tree or channels whose consumer_dev_name matches
iio_hwmon in iio_map_list. The iio_map_list is filled in by iio drivers
which might be probed after iio_hwmon.

It is better to defer the probe of iio_hwmon if such error is returned by
iio_channel_get_all in order to let a chance to iio drivers to expose
channels in iio_map_list.

Signed-off-by: Quentin Schulz 
---

v5:
 - patch re-inserted,

v3:
 - patch removed,

 drivers/hwmon/iio_hwmon.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c
index b550ba5..c0da4d9 100644
--- a/drivers/hwmon/iio_hwmon.c
+++ b/drivers/hwmon/iio_hwmon.c
@@ -73,8 +73,11 @@ static int iio_hwmon_probe(struct platform_device *pdev)
name = dev->of_node->name;
 
channels = iio_channel_get_all(dev);
-   if (IS_ERR(channels))
+   if (IS_ERR(channels)) {
+   if (PTR_ERR(channels) == -ENODEV)
+   return -EPROBE_DEFER;
return PTR_ERR(channels);
+   }
 
st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
if (st == NULL) {
-- 
2.5.0



[PATCH v5 2/3] mfd: add support for Allwinner SoCs ADC

2016-09-08 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. For now, only the ADC and the thermal
sensor drivers are probed by the MFD, the touchscreen controller support
will be added later.

Signed-off-by: Quentin Schulz 
---

v5:
 - correct mail address,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - rename defines from SUNXI_* to SUN4I_* or SUN6I_*,
 - remove TP in defines name,
 - rename SUNXI_IRQ_* to SUN4I_GPADC_IRQ_* for consistency,
 - use devm functions for regmap_add_irq_chip and mfd_add_devices,
 - remove remove functions (now empty thanks to devm functions),

v3:
 - use defines in regmap_irq instead of hard coded BITs,
 - use of_device_id data field to chose which MFD cells to add considering
   the compatible responsible of the MFD probe,
 - remove useless initializations,
 - disable all interrupts before adding them to regmap_irqchip,
 - add goto error label in probe,
 - correct wrapping in header license,
 - move defines from IIO driver to header,
 - use GENMASK to limit the size of the variable passed to a macro,
 - prefix register BIT defines with the name of the register,
 - reorder defines,

v2:
 - add license headers,
 - reorder alphabetically includes,
 - add SUNXI_GPADC_ prefixes for defines,

 drivers/mfd/Kconfig |  15 
 drivers/mfd/Makefile|   2 +
 drivers/mfd/sun4i-gpadc-mfd.c   | 174 
 include/linux/mfd/sun4i-gpadc-mfd.h |  94 +++
 4 files changed, 285 insertions(+)
 create mode 100644 drivers/mfd/sun4i-gpadc-mfd.c
 create mode 100644 include/linux/mfd/sun4i-gpadc-mfd.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 1bcf601..95b3c3e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -29,6 +29,21 @@ config MFD_ACT8945A
  linear regulators, along with a complete ActivePath battery
  charger.
 
+config MFD_SUN4I_GPADC
+   tristate "Allwinner sunxi platforms' GPADC MFD driver"
+   select MFD_CORE
+   select REGMAP_MMIO
+   depends on ARCH_SUNXI || COMPILE_TEST
+   help
+ Select this to get support for Allwinner SoCs (A10, A13 and A31) ADC.
+ This driver will only map the hardware interrupt and registers, you
+ have to select individual drivers based on this MFD to be able to use
+ the ADC or the thermal sensor. This will try to probe the ADC driver
+ sun4i-gpadc-iio and the hwmon driver iio_hwmon.
+
+ To compile this driver as a module, choose M here: the module will be
+ called sun4i-gpadc-mfd.
+
 config MFD_AS3711
bool "AMS AS3711"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 42a66e1..3b964d7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -205,3 +205,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o 
intel_soc_pmic_crc.o
 intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)   += intel-soc-pmic.o
 obj-$(CONFIG_MFD_MT6397)   += mt6397-core.o
+
+obj-$(CONFIG_MFD_SUN4I_GPADC)  += sun4i-gpadc-mfd.o
diff --git a/drivers/mfd/sun4i-gpadc-mfd.c b/drivers/mfd/sun4i-gpadc-mfd.c
new file mode 100644
index 000..b499545
--- /dev/null
+++ b/drivers/mfd/sun4i-gpadc-mfd.c
@@ -0,0 +1,174 @@
+/* ADC MFD core driver for sunxi platforms
+ *
+ * Copyright (c) 2016 Quentin Schulz 
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static struct resource adc_resources[] = {
+   {
+   .name   = "FIFO_DATA_PENDING",
+   .start  = SUN4I_GPADC_IRQ_FIFO_DATA,
+   .end= SUN4I_GPADC_IRQ_FIFO_DATA,
+   .flags  = IORESOURCE_IRQ,
+   }, {
+   .name   = "TEMP_DATA_PENDING",
+   .start  = SUN4I_GPADC_IRQ_TEMP_DATA,
+   .end= SUN4I_GPADC_IRQ_TEMP_DATA,
+   .flags  = IORESOURCE_IRQ,
+   },
+};
+
+static const struct regmap_irq sun4i_gpadc_mfd_regmap_irq[] = {
+   REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_FIFO_DATA, 0,
+  SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN),
+   REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_TEMP_DATA, 0,
+  SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN),
+};
+
+static const struct regmap_irq_chip sun4i_gpadc_mfd_regmap_irq_chip = {
+   .name = "sun4i_gpadc_mfd_irq_chip",
+   .status_base = SUN4I_GPADC_INT_FIFOS,
+   .ack_base = SUN4I_GPADC_INT_FIFOS,
+   .mask_base = SUN4I_GPADC_INT_FIFOC,
+   .init_ack_masked = true,
+   .mask_invert = true,
+   .irqs = sun4i_gpadc_mfd_regmap_irq,
+   .num_irqs = ARRAY_SIZE(sun4i_gpadc_mfd_regmap_irq),
+   .num_regs =

[PATCH v5 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-09-08 Thread Quentin Schulz
The Allwinner SoCs all have an ADC that can also act as a touchscreen
controller and a thermal sensor. This patch adds the ADC driver which is
based on the MFD for the same SoCs ADC.

This also registers the thermal adc channel in the iio map array so
iio_hwmon could use it without modifying the Device Tree. This registers
the driver in the thermal framework.

This driver probes on three different platform_device_id to take into
account slight differences (registers bit and temperature computation)
between Allwinner SoCs ADCs.

Signed-off-by: Quentin Schulz 
---

v5:
 - correct mail address,
 - correct several typos,
 - move from const to static for sunxi_gpadc_chan_select functions,
 - rename soc_specific struct to gpadc_data,
 - rename soc_specific field to data in sun4i_gpadc_dev,
 - return error code from regmap_write in case of failure in read_raws,
 - share if condition in IIO_CHAN_INFO_RAW case,
 - add comment on why we use parent device for registering in thermal,
 - reordering remove function,

v4:
 - rename files and variables from sunxi* to sun4i*,
 - shorten sunxi_gpadc_soc_specific structure to soc_specific,
 - factorize sysfs ADC and temp read_raws,
 - use cached values when read_raw times out (except before a first value
   is gotten),
 - remove mutex locks and unlocks from runtime_pm functions,
 - factorize irq initializations,
 - initialize temp_data and fifo_data values to -1 (error value),
 - "impersonate" MFD to register in thermal framework,
 - deactivate hardware interrupts one by one when probe fails or when
   removing driver instead of blindly deactivating all hardware interrupts,
 - selects THERMAL_OF in Kconfig,

v3:
 - correct wrapping,
 - add comment about thermal sensor inner working,
 - move defines in mfd header,
 - use structure to define SoC specific registers or behaviour,
 - attach this structure to the device according to of_device_id of the
   platform device,
 - use new mutex instead of iio_dev mutex,
 - use atomic flags to avoid race between request_irq and disable_irq in
   probe,
 - switch from processed value to raw, offset and scale values for
   temperature ADC channel,
 - remove faulty sentinel in iio_chan_spec array,
 - add pm_runtime support,
 - register thermal sensor in thermal framework (forgotten since the
   beginning whereas it is present in current sun4i-ts driver),
 - remove useless ret variables to store return value of regmap_reads,
 - move comments on thermal sensor acquisition period in code instead of
   header,
 - adding goto label to unregister iio_map_array when failing to register
   iio_dev,

v2:
 - add SUNXI_GPADC_ prefixes for defines,
 - correct typo in Kconfig,
 - reorder alphabetically includes, makefile,
 - add license header,
 - fix architecture variations not being handled in interrupt handlers or
   read raw functions,
 - fix unability to return negative values from thermal sensor,
 - add gotos to reduce code repetition,
 - fix irq variable being unsigned int instead of int,
 - remove useless dev_err and dev_info,
 - deactivate all interrupts if probe fails,
 - fix iio_device_register on NULL variable,
 - deactivate ADC in the IP when probe fails or when removing driver,

 drivers/iio/adc/Kconfig   |  13 +
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c | 543 ++
 3 files changed, 557 insertions(+)
 create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 25378c5..ea36a4f 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -384,6 +384,19 @@ config ROCKCHIP_SARADC
  To compile this driver as a module, choose M here: the
  module will be called rockchip_saradc.
 
+config SUN4I_GPADC
+   tristate "Support for the Allwinner SoCs GPADC"
+   depends on IIO
+   depends on MFD_SUN4I_GPADC
+   select THERMAL_OF
+   help
+ Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
+ GPADC. This ADC provides 4 channels which can be used as an ADC or as
+ a touchscreen input and one channel for thermal sensor.
+
+ To compile this driver as a module, choose M here: the module will be
+ called sun4i-gpadc-iio.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 38638d4..204372d 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
 obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
 obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
 obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
+obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
 obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
diff --git a/dri

Re: [PATCH v4 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-09-07 Thread Quentin Schulz
On 04/09/2016 16:35, Jonathan Cameron wrote:
> On 01/09/16 15:05, Quentin Schulz wrote:
>> The Allwinner SoCs all have an ADC that can also act as a touchscreen
>> controller and a thermal sensor. This patch adds the ADC driver which is
>> based on the MFD for the same SoCs ADC.
>>
>> This also registers the thermal adc channel in the iio map array so
>> iio_hwmon could use it without modifying the Device Tree. This registers
>> the driver in the thermal framework.
>>
>> This driver probes on three different platform_device_id to take into
>> account slight differences (registers bit and temperature computation)
>> between Allwinner SoCs ADCs.
>>
>> Signed-off-by: Quentin Schulz 
> One utterly trivial point about unrolling code ordering inline.
> 
> Other than the bit about patch 1 I'm basically happy with this..

ACK. Will revert this patch in v5. Thanks.

> However I would like some input (i.e. an Ack) from thermal given this
> sets up a thermal zone.
> 
> Zhang or Eduardo, could you take a quick look at this and confirm you
> are happy with it?
> 
> Thanks,
> 
> Jonathan
[...]
>> +
>> +err_map:
>> +iio_map_array_unregister(indio_dev);
>> +
>> +err_fifo_irq:
>> +/* Disable FIFO_DATA_PENDING interrupt on hardware side. */
>> +regmap_update_bits(info->regmap, SUN4I_GPADC_INT_FIFOC,
>> +   SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN,
>> +   0);
>> +
>> +err_temp_irq:
>> +/* Disable TEMP_DATA_PENDING interrupt on hardware side. */
>> +regmap_update_bits(info->regmap, SUN4I_GPADC_INT_FIFOC,
>> +   SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN,
>> +   0);
>> +
>> +err:
>> +pm_runtime_put(&pdev->dev);
>> +pm_runtime_disable(&pdev->dev);
>> +
>> +return ret;
>> +}
>> +
>> +static int sun4i_gpadc_remove(struct platform_device *pdev)
>> +{
>> +struct sun4i_gpadc_dev *info;
>> +struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>> +
>> +info = iio_priv(indio_dev);
>> +iio_device_unregister(indio_dev);
>> +iio_map_array_unregister(indio_dev);
>> +pm_runtime_put(&pdev->dev);
>> +pm_runtime_disable(&pdev->dev);
> Its really minor but in the interests of 'obviously correct' making
> review easy I'd rather everything in the remove was in the reverse order
> of probe (and hence the same as the error path in probe for most of it).
> 
> That would put the pm_runtime stuff last I think..
> 
> If you weren't rerolling anyway over patch 1 I'd probably have just let
> this go, but might as well make this trivial change as well.
> 

I'm going with the following order:
pm_runtime_put
pm_runtime_disable
regmap_update_bits
iio_map_array_unregister
iio_device_unregister

Is that okay? (I don't really know which one of iio_map_array_unregister
or iio_device_unregister to put first, if it matters in any way).

Thanks!
Quentin
> 
>> +/*
>> + * Disable TEMP_DATA_PENDING and FIFO_DATA_PENDING interrupts on
>> + * hardware side.
>> + */
>> +regmap_update_bits(info->regmap, SUN4I_GPADC_INT_FIFOC,
>> +   SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN |
>> +SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN,
>> +   0);
>> +
>> +return 0;
>> +}
>> +
>> +static const struct platform_device_id sun4i_gpadc_id[] = {
>> +{ "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_soc_specific },
>> +{ "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_soc_specific },
>> +    { "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_soc_specific },
>> +{ /* sentinel */ },
>> +};
>> +
>> +static struct platform_driver sun4i_gpadc_driver = {
>> +.driver = {
>> +.name = "sun4i-gpadc-iio",
>> +.pm = &sun4i_gpadc_pm_ops,
>> +},
>> +.id_table = sun4i_gpadc_id,
>> +.probe = sun4i_gpadc_probe,
>> +.remove = sun4i_gpadc_remove,
>> +};
>> +
>> +module_platform_driver(sun4i_gpadc_driver);
>> +
>> +MODULE_DESCRIPTION("ADC driver for sunxi platforms");
>> +MODULE_AUTHOR("Quentin Schulz ");
>> +MODULE_LICENSE("GPL v2");
>>
> 



Re: [PATCH v4 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-09-07 Thread Quentin Schulz
On 04/09/2016 18:12, Peter Meerwald-Stadler wrote:
> 
>> The Allwinner SoCs all have an ADC that can also act as a touchscreen
>> controller and a thermal sensor. This patch adds the ADC driver which is
>> based on the MFD for the same SoCs ADC.
> 
> nitpicking ahead
>  
[...]
>> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
>> b/drivers/iio/adc/sun4i-gpadc-iio.c
>> new file mode 100644
>> index 000..a93d36d
>> --- /dev/null
>> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c
>> @@ -0,0 +1,525 @@
>> +/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
>> + *
>> + * Copyright (c) 2016 Quentin Schulz 
> 
> email address is incomplete
> 

As in my other patches, thanks!

>> + *
>> + * 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.
>> + *
>> + * The Allwinner SoCs all have an ADC that can also act as a touchscreen
>> + * controller and a thermal sensor.
>> + * The thermal sensor works only when the ADC acts as a touchscreen 
>> controller
>> + * and is configured to throw an interrupt every fixed periods of time (let 
>> say
>> + * every X seconds).
>> + * One would be tempted to disable the IP on the hardware side rather than
>> + * disabling interrupts to save some power but that reset the internal 
>> clock of
> 
> resets
> 
>> + * the IP, resulting in having to wait X seconds every time we want to read 
>> the
>> + * value of the thermal sensor.
>> + * This is also the reason of using autosuspend in pm_runtime. If there 
>> were no
> 
> there was no
> 
[...]
>> +
>> +const unsigned int sun4i_gpadc_chan_select(unsigned int chan)
> 
> static instead of const?
> 

static const then?

>> +{
>> +return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
>> +}
>> +
>> +const unsigned int sun6i_gpadc_chan_select(unsigned int chan)
> 
> static instead of const?
> 

static const then?

>> +{
>> +return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
>> +}
>> +
>> +struct soc_specific {
>> +const int   temp_offset;
> 
> wondering why you constify every member?
> 

Because they're supposed to be fixed values? It won't change in runtime.
Is there any reason why I shouldn't do that?

>> +const int   temp_scale;
>> +const unsigned int  tp_mode_en;
>> +const unsigned int  tp_adc_select;
>> +const unsigned int  (*adc_chan_select)(unsigned int chan);
>> +};
[...]
>> +static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int 
>> *val,
>> +unsigned int irq)
>> +{
>> +struct sun4i_gpadc_dev *info = iio_priv(indio_dev);
>> +int ret = 0;
>> +
>> +pm_runtime_get_sync(indio_dev->dev.parent);
>> +mutex_lock(&info->mutex);
>> +
>> +reinit_completion(&info->completion);
>> +
>> +regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC,
>> + SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
>> + SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
> 
> check retval? here and elsewhere for regmap_write()
> 

ACK. What should I do with the retval then?

There are some in:
- sun4i_gpadc_read called for read_raws => return which error code (or
-ret only?)?
- sun4i_gpadc_runtime_suspend => return value of ret, but that would
cancel the suspend right?
- sun4i_gpadc_runtime_resume => return value of ret, but that would
cancel resume right?
- sun4i_gpadc_probe in the error gotos => probe already failing so do we
actually care if regmap_update_bits fails? If yes, what's the expected
behaviour?
- sun4i_gpadc_remove => return value of ret, but that would mean the
remove failed right?

[...]
>> +static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
>> +struct iio_chan_spec const *chan, int *val,
>> +int *val2, long mask)
>> +{
>> +int ret;
>> +
>> +switch (mask) {
>> +case IIO_CHAN_INFO_OFFSET:
>> +ret = sun4i_gpadc_temp_offset(indio_dev, val);
>> +if (ret)
>> +return ret;
>> +
>> +return IIO_VAL_INT;
>> +case IIO_CHAN_INFO_RAW:
>> +if (chan->type == IIO_VOLTAGE) {
>> +ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
>> +

Re: [PATCH v4 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-09-05 Thread Quentin Schulz
On 05/09/2016 10:07, Peter Meerwald-Stadler wrote:
> 
 The Allwinner SoCs all have an ADC that can also act as a touchscreen
 controller and a thermal sensor. This patch adds the ADC driver which is
 based on the MFD for the same SoCs ADC.
>>>
>>> nitpicking ahead
> 
>> [...]
 +
 +const unsigned int sun4i_gpadc_chan_select(unsigned int chan)
>>>
>>> static instead of const?
> 
>> static const then?
> 
> no, the const is redundant and ignored
> -Wignored-qualifiers gives a warning
> 
> just static, no const
> 
> see
> http://stackoverflow.com/questions/12052468/type-qualifiers-on-function-return-type
> 

ACK. Thanks.

 +{
 +  return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
 +}
 +
 +struct soc_specific {
 +  const int   temp_offset;
>>>
>>> wondering why you constify every member?
>>>
>>
>> Because they're supposed to be fixed values? It won't change in runtime.
>> Is there any reason why I shouldn't do that?
> 
> yes, but using the entire struct as const has the same effect;
> constifying individual members makes more sense if there are also 
> non-const members
> 
> nothing wrong, just unusual
> 

So I would let all members non-const and then when using the struct
soc_specific as a member in a struct or as a variable I would prefix it
with const? That's what you mean by using the entire struct as const?

[...]

Thanks,
Quentin


Re: [PATCH v4 3/3] iio: adc: add support for Allwinner SoCs ADC

2016-09-05 Thread Quentin Schulz
On 05/09/2016 09:07, Maxime Ripard wrote:
> Hi,
> 
> Nitpicks ahead.
> 
> On Thu, Sep 01, 2016 at 04:05:05PM +0200, Quentin Schulz wrote:
>> +info->soc_specific = (struct soc_specific 
>> *)platform_get_device_id(pdev)->driver_data;
> 
> This line is still rather long. How about calling the field "data" and
> the structure gpadc_data?
> 

driver_data is coming from the platform_device_id
(http://lxr.free-electrons.com/source/include/linux/mod_devicetable.h#L498)
so can't really change that.
I could change the structure to gpadc_data, that would save me 2
characters, still 13 characters above the 80 characters limit however.

>> +
>> +tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0, info,
>> +   &sun4i_ts_tz_ops);
> 
> A comment on why you put the parent device structure and not the
> device itself like you're doing on all the other calls in that probe
> would be nice.
> 

Indeed.

Thanks,
Quentin

> Thanks!
> Maxime
> 



signature.asc
Description: OpenPGP digital signature


<    1   2   3   4   5   6   7   >