AXP813 AC power supply support with input current and
voltage limiting support.
AXP803 AC and battery power supply support.
Changes in v4:
* Change order of axp20x-gpio in axp20x.c
* Fix indentation and spaces to tabs in axp20x.c
Changes in v3:
* Reorder ac_power_supply DT node
* Rename axp20x_ac_power_set_property function
* Split mfd commit
Changes in v2:
* Reuse axp813 compatibles for axp803
* Refactor axp20x_ac_power.c
Oskari Lemmela (7):
dt-bindings: power: supply: axp20x: add AXP813 AC power DT binding
ARM: dts: axp81x: add AC power supply subnode
arm64: dts: allwinner: axp803: add AC and battery power supplies
arm64: dts: allwinner: a64: sopine: enable power supplies
power: supply: add AC power supply driver for AXP813
mfd: axp20x: Add AC power supply cell for AXP813
mfd: axp20x: Add supported cells for AXP803
.../bindings/power/supply/axp20x_ac_power.txt | 3 +
arch/arm/boot/dts/axp81x.dtsi | 5 +
arch/arm64/boot/dts/allwinner/axp803.dtsi | 31 +++++++
.../allwinner/sun50i-a64-sopine-baseboard.dts | 8 ++
drivers/mfd/axp20x.c | 20 ++++
drivers/power/supply/axp20x_ac_power.c | 92 +++++++++++++++++++
include/linux/mfd/axp20x.h | 1 +
7 files changed, 160 insertions(+)
--
2.17.1
The AXP803/AXP813 AC power supply can limit input current and voltage.
Signed-off-by: Oskari Lemmela <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
Reviewed-by: Quentin Schulz <[email protected]>
---
.../devicetree/bindings/power/supply/axp20x_ac_power.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
index 826e8a879121..7a1fb532abe5 100644
--- a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
+++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
@@ -4,6 +4,7 @@ Required Properties:
- compatible: One of:
"x-powers,axp202-ac-power-supply"
"x-powers,axp221-ac-power-supply"
+ "x-powers,axp813-ac-power-supply"
This node is a subnode of the axp20x PMIC.
@@ -13,6 +14,8 @@ reading ADC channels from the AXP20X ADC.
The AXP22X is only able to tell if an AC power supply is present and
usable.
+AXP813/AXP803 are able to limit current and supply voltage
+
Example:
&axp209 {
--
2.17.1
AXP803 is compatible with AXP813.
Adding cells for GPIO, ADC, AC and battery power supplies.
Signed-off-by: Oskari Lemmela <[email protected]>
---
drivers/mfd/axp20x.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index dfc3cff1d08b..e415b967d38c 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -728,11 +728,26 @@ static const struct mfd_cell axp288_cells[] = {
static const struct mfd_cell axp803_cells[] = {
{
+ .name = "axp20x-gpio",
+ .of_compatible = "x-powers,axp813-gpio",
+ }, {
.name = "axp221-pek",
.num_resources = ARRAY_SIZE(axp803_pek_resources),
.resources = axp803_pek_resources,
},
{ .name = "axp20x-regulator" },
+ {
+ .name = "axp813-adc",
+ .of_compatible = "x-powers,axp813-adc",
+ }, {
+ .name = "axp20x-battery-power-supply",
+ .of_compatible = "x-powers,axp813-battery-power-supply",
+ }, {
+ .name = "axp20x-ac-power-supply",
+ .of_compatible = "x-powers,axp813-ac-power-supply",
+ .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
+ .resources = axp20x_ac_power_supply_resources,
+ },
};
static const struct mfd_cell axp806_self_working_cells[] = {
--
2.17.1
AXP803 is compatible with AXP813. Add DT nodes ADC, GPIO,
AC and battery power supplies.
Signed-off-by: Oskari Lemmela <[email protected]>
Reviewed-by: Quentin Schulz <[email protected]>
---
arch/arm64/boot/dts/allwinner/axp803.dtsi | 31 +++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/axp803.dtsi b/arch/arm64/boot/dts/allwinner/axp803.dtsi
index e5eae8bafc42..128177178615 100644
--- a/arch/arm64/boot/dts/allwinner/axp803.dtsi
+++ b/arch/arm64/boot/dts/allwinner/axp803.dtsi
@@ -49,6 +49,37 @@
interrupt-controller;
#interrupt-cells = <1>;
+ ac_power_supply: ac-power-supply {
+ compatible = "x-powers,axp813-ac-power-supply";
+ status = "disabled";
+ };
+
+ axp_adc: adc {
+ compatible = "x-powers,axp813-adc";
+ #io-channel-cells = <1>;
+ };
+
+ axp_gpio: gpio {
+ compatible = "x-powers,axp813-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio0_ldo: gpio0-ldo {
+ pins = "GPIO0";
+ function = "ldo";
+ };
+
+ gpio1_ldo: gpio1-ldo {
+ pins = "GPIO1";
+ function = "ldo";
+ };
+ };
+
+ battery_power_supply: battery-power-supply {
+ compatible = "x-powers,axp813-battery-power-supply";
+ status = "disabled";
+ };
+
regulators {
/* Default work frequency for buck regulators */
x-powers,dcdc-freq = <3000>;
--
2.17.1
AXP813 and AXP803 PMICs can control input current and
minimum voltage.
Both of these values are configurable.
Signed-off-by: Oskari Lemmela <[email protected]>
Reviewed-by: Quentin Schulz <[email protected]>
---
drivers/power/supply/axp20x_ac_power.c | 92 ++++++++++++++++++++++++++
include/linux/mfd/axp20x.h | 1 +
2 files changed, 93 insertions(+)
diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
index 0771f951b11f..059a97d6e14c 100644
--- a/drivers/power/supply/axp20x_ac_power.c
+++ b/drivers/power/supply/axp20x_ac_power.c
@@ -27,6 +27,16 @@
#define AXP20X_PWR_STATUS_ACIN_PRESENT BIT(7)
#define AXP20X_PWR_STATUS_ACIN_AVAIL BIT(6)
+#define AXP813_VHOLD_MASK GENMASK(5, 3)
+#define AXP813_VHOLD_UV_TO_BIT(x) ((((x) / 100000) - 40) << 3)
+#define AXP813_VHOLD_REG_TO_UV(x) \
+ (((((x) & AXP813_VHOLD_MASK) >> 3) + 40) * 100000)
+
+#define AXP813_CURR_LIMIT_MASK GENMASK(2, 0)
+#define AXP813_CURR_LIMIT_UA_TO_BIT(x) (((x) / 500000) - 3)
+#define AXP813_CURR_LIMIT_REG_TO_UA(x) \
+ ((((x) & AXP813_CURR_LIMIT_MASK) + 3) * 500000)
+
#define DRVNAME "axp20x-ac-power-supply"
struct axp20x_ac_power {
@@ -102,6 +112,55 @@ static int axp20x_ac_power_get_property(struct power_supply *psy,
return 0;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+ ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®);
+ if (ret)
+ return ret;
+
+ val->intval = AXP813_VHOLD_REG_TO_UV(reg);
+
+ return 0;
+
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+ ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®);
+ if (ret)
+ return ret;
+
+ val->intval = AXP813_CURR_LIMIT_REG_TO_UA(reg);
+
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
+
+static int axp813_ac_power_set_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct axp20x_ac_power *power = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+ if (val->intval < 4000000 || val->intval > 4700000)
+ return -EINVAL;
+
+ return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL,
+ AXP813_VHOLD_MASK,
+ AXP813_VHOLD_UV_TO_BIT(val->intval));
+
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+ if (val->intval < 1500000 || val->intval > 4000000)
+ return -EINVAL;
+
+ return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL,
+ AXP813_CURR_LIMIT_MASK,
+ AXP813_CURR_LIMIT_UA_TO_BIT
+ (val->intval));
+
default:
return -EINVAL;
}
@@ -109,6 +168,13 @@ static int axp20x_ac_power_get_property(struct power_supply *psy,
return -EINVAL;
}
+static int axp813_ac_power_prop_writeable(struct power_supply *psy,
+ enum power_supply_property psp)
+{
+ return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
+ psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
+}
+
static enum power_supply_property axp20x_ac_power_properties[] = {
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
@@ -123,6 +189,14 @@ static enum power_supply_property axp22x_ac_power_properties[] = {
POWER_SUPPLY_PROP_ONLINE,
};
+static enum power_supply_property axp813_ac_power_properties[] = {
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN,
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
+};
+
static const struct power_supply_desc axp20x_ac_power_desc = {
.name = "axp20x-ac",
.type = POWER_SUPPLY_TYPE_MAINS,
@@ -139,6 +213,16 @@ static const struct power_supply_desc axp22x_ac_power_desc = {
.get_property = axp20x_ac_power_get_property,
};
+static const struct power_supply_desc axp813_ac_power_desc = {
+ .name = "axp813-ac",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .properties = axp813_ac_power_properties,
+ .num_properties = ARRAY_SIZE(axp813_ac_power_properties),
+ .property_is_writeable = axp813_ac_power_prop_writeable,
+ .get_property = axp20x_ac_power_get_property,
+ .set_property = axp813_ac_power_set_property,
+};
+
struct axp_data {
const struct power_supply_desc *power_desc;
bool acin_adc;
@@ -154,6 +238,11 @@ static const struct axp_data axp22x_data = {
.acin_adc = false,
};
+static const struct axp_data axp813_data = {
+ .power_desc = &axp813_ac_power_desc,
+ .acin_adc = false,
+};
+
static int axp20x_ac_power_probe(struct platform_device *pdev)
{
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
@@ -234,6 +323,9 @@ static const struct of_device_id axp20x_ac_power_match[] = {
}, {
.compatible = "x-powers,axp221-ac-power-supply",
.data = &axp22x_data,
+ }, {
+ .compatible = "x-powers,axp813-ac-power-supply",
+ .data = &axp813_data,
}, { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, axp20x_ac_power_match);
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 517e60eecbcb..2302b620d238 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -266,6 +266,7 @@ enum axp20x_variants {
#define AXP288_RT_BATT_V_H 0xa0
#define AXP288_RT_BATT_V_L 0xa1
+#define AXP813_ACIN_PATH_CTRL 0x3a
#define AXP813_ADC_RATE 0x85
/* Fuel Gauge */
--
2.17.1
As axp20x-ac-power-supply now supports AXP813, add a cell for it.
Signed-off-by: Oskari Lemmela <[email protected]>
Reviewed-by: Quentin Schulz <[email protected]>
---
drivers/mfd/axp20x.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 0be511dd93d0..dfc3cff1d08b 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -778,6 +778,11 @@ static const struct mfd_cell axp813_cells[] = {
}, {
.name = "axp20x-battery-power-supply",
.of_compatible = "x-powers,axp813-battery-power-supply",
+ }, {
+ .name = "axp20x-ac-power-supply",
+ .of_compatible = "x-powers,axp813-ac-power-supply",
+ .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
+ .resources = axp20x_ac_power_supply_resources,
},
};
--
2.17.1
Sopine baseboard have ACIN and battery connectors.
Signed-off-by: Oskari Lemmela <[email protected]>
Reviewed-by: Quentin Schulz <[email protected]>
---
.../boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index c21f2331add6..335cf2263d19 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -69,6 +69,14 @@
};
};
+&ac_power_supply {
+ status = "okay";
+};
+
+&battery_power_supply {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
--
2.17.1
Add AC power supply subnode for AXP81X PMIC.
Signed-off-by: Oskari Lemmela <[email protected]>
Reviewed-by: Quentin Schulz <[email protected]>
---
arch/arm/boot/dts/axp81x.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi
index 043c717dcef1..bd83962d3627 100644
--- a/arch/arm/boot/dts/axp81x.dtsi
+++ b/arch/arm/boot/dts/axp81x.dtsi
@@ -48,6 +48,11 @@
interrupt-controller;
#interrupt-cells = <1>;
+ ac_power_supply: ac-power-supply {
+ compatible = "x-powers,axp813-ac-power-supply";
+ status = "disabled";
+ };
+
axp_adc: adc {
compatible = "x-powers,axp813-adc";
#io-channel-cells = <1>;
--
2.17.1
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> Add AC power supply subnode for AXP81X PMIC.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
Reviewed-by: Chen-Yu Tsai <[email protected]>
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> The AXP803/AXP813 AC power supply can limit input current and voltage.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
Reviewed-by: Chen-Yu Tsai <[email protected]>
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> AXP803 is compatible with AXP813. Add DT nodes ADC, GPIO,
> AC and battery power supplies.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
> ---
> arch/arm64/boot/dts/allwinner/axp803.dtsi | 31 +++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/axp803.dtsi b/arch/arm64/boot/dts/allwinner/axp803.dtsi
> index e5eae8bafc42..128177178615 100644
> --- a/arch/arm64/boot/dts/allwinner/axp803.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/axp803.dtsi
> @@ -49,6 +49,37 @@
> interrupt-controller;
> #interrupt-cells = <1>;
>
> + ac_power_supply: ac-power-supply {
> + compatible = "x-powers,axp813-ac-power-supply";
Even though they seem to be compatible, please add a model specific
compatible string in front for all the new nodes just in case. In
this case it would be "x-powers,axp803-ac-power-supply".
ChenYu
> + status = "disabled";
> + };
> +
> + axp_adc: adc {
> + compatible = "x-powers,axp813-adc";
> + #io-channel-cells = <1>;
> + };
> +
> + axp_gpio: gpio {
> + compatible = "x-powers,axp813-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> +
> + gpio0_ldo: gpio0-ldo {
> + pins = "GPIO0";
> + function = "ldo";
> + };
> +
> + gpio1_ldo: gpio1-ldo {
> + pins = "GPIO1";
> + function = "ldo";
> + };
> + };
> +
> + battery_power_supply: battery-power-supply {
> + compatible = "x-powers,axp813-battery-power-supply";
> + status = "disabled";
> + };
> +
> regulators {
> /* Default work frequency for buck regulators */
> x-powers,dcdc-freq = <3000>;
> --
> 2.17.1
>
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> Sopine baseboard have ACIN and battery connectors.
The commit message should be more specific, like how the two connections
from the PMIC are routed. In this case ACIN is routed from the SOM to
the DC jack on the baseboard, while the battery pins are routed to a 3-pin
connector next to the USB connectors.
ChenYu
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
> ---
> .../boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
> index c21f2331add6..335cf2263d19 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
> @@ -69,6 +69,14 @@
> };
> };
>
> +&ac_power_supply {
> + status = "okay";
> +};
> +
> +&battery_power_supply {
> + status = "okay";
> +};
> +
> &ehci0 {
> status = "okay";
> };
> --
> 2.17.1
>
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> AXP803 is compatible with AXP813.
> Adding cells for GPIO, ADC, AC and battery power supplies.
They are not _completely_ compatible. A better way to phrase this would be:
Parts of the AXP803 are compatible with their counterparts on the AXP813.
These include the GPIO, ADC, AC and battery power supplies.
> Signed-off-by: Oskari Lemmela <[email protected]>
Otherwise,
Reviewed-by: Chen-Yu Tsai <[email protected]>
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> As axp20x-ac-power-supply now supports AXP813, add a cell for it.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
Reviewed-by: Chen-Yu Tsai <[email protected]>
On Sat, Oct 13, 2018 at 4:09 PM Oskari Lemmela <[email protected]> wrote:
>
> AXP813 and AXP803 PMICs can control input current and
> minimum voltage.
>
> Both of these values are configurable.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
> ---
> drivers/power/supply/axp20x_ac_power.c | 92 ++++++++++++++++++++++++++
> include/linux/mfd/axp20x.h | 1 +
> 2 files changed, 93 insertions(+)
>
> diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
> index 0771f951b11f..059a97d6e14c 100644
> --- a/drivers/power/supply/axp20x_ac_power.c
> +++ b/drivers/power/supply/axp20x_ac_power.c
> @@ -27,6 +27,16 @@
> #define AXP20X_PWR_STATUS_ACIN_PRESENT BIT(7)
> #define AXP20X_PWR_STATUS_ACIN_AVAIL BIT(6)
>
> +#define AXP813_VHOLD_MASK GENMASK(5, 3)
> +#define AXP813_VHOLD_UV_TO_BIT(x) ((((x) / 100000) - 40) << 3)
> +#define AXP813_VHOLD_REG_TO_UV(x) \
> + (((((x) & AXP813_VHOLD_MASK) >> 3) + 40) * 100000)
> +
> +#define AXP813_CURR_LIMIT_MASK GENMASK(2, 0)
> +#define AXP813_CURR_LIMIT_UA_TO_BIT(x) (((x) / 500000) - 3)
> +#define AXP813_CURR_LIMIT_REG_TO_UA(x) \
> + ((((x) & AXP813_CURR_LIMIT_MASK) + 3) * 500000)
> +
> #define DRVNAME "axp20x-ac-power-supply"
>
> struct axp20x_ac_power {
> @@ -102,6 +112,55 @@ static int axp20x_ac_power_get_property(struct power_supply *psy,
>
> return 0;
>
> + case POWER_SUPPLY_PROP_VOLTAGE_MIN:
> + ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®);
> + if (ret)
> + return ret;
> +
> + val->intval = AXP813_VHOLD_REG_TO_UV(reg);
> +
> + return 0;
> +
> + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
> + ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®);
> + if (ret)
> + return ret;
> +
> + val->intval = AXP813_CURR_LIMIT_REG_TO_UA(reg);
This doesn't handle the case where the register value is set to 0x6 or 0x7,
which should still mean 4000 mA.
> +
> + return 0;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int axp813_ac_power_set_property(struct power_supply *psy,
> + enum power_supply_property psp,
> + const union power_supply_propval *val)
> +{
> + struct axp20x_ac_power *power = power_supply_get_drvdata(psy);
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_VOLTAGE_MIN:
> + if (val->intval < 4000000 || val->intval > 4700000)
> + return -EINVAL;
> +
> + return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL,
> + AXP813_VHOLD_MASK,
> + AXP813_VHOLD_UV_TO_BIT(val->intval));
> +
> + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
> + if (val->intval < 1500000 || val->intval > 4000000)
> + return -EINVAL;
> +
> + return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL,
> + AXP813_CURR_LIMIT_MASK,
> + AXP813_CURR_LIMIT_UA_TO_BIT
> + (val->intval));
Nit, don't wrap this part. Even if it exceeds the 80 character limit, it's
still easier to read that way.
ChenYu
> +
> default:
> return -EINVAL;
> }
> @@ -109,6 +168,13 @@ static int axp20x_ac_power_get_property(struct power_supply *psy,
> return -EINVAL;
> }
>
> +static int axp813_ac_power_prop_writeable(struct power_supply *psy,
> + enum power_supply_property psp)
> +{
> + return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
> + psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
> +}
> +
> static enum power_supply_property axp20x_ac_power_properties[] = {
> POWER_SUPPLY_PROP_HEALTH,
> POWER_SUPPLY_PROP_PRESENT,
> @@ -123,6 +189,14 @@ static enum power_supply_property axp22x_ac_power_properties[] = {
> POWER_SUPPLY_PROP_ONLINE,
> };
>
> +static enum power_supply_property axp813_ac_power_properties[] = {
> + POWER_SUPPLY_PROP_HEALTH,
> + POWER_SUPPLY_PROP_PRESENT,
> + POWER_SUPPLY_PROP_ONLINE,
> + POWER_SUPPLY_PROP_VOLTAGE_MIN,
> + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
> +};
> +
> static const struct power_supply_desc axp20x_ac_power_desc = {
> .name = "axp20x-ac",
> .type = POWER_SUPPLY_TYPE_MAINS,
> @@ -139,6 +213,16 @@ static const struct power_supply_desc axp22x_ac_power_desc = {
> .get_property = axp20x_ac_power_get_property,
> };
>
> +static const struct power_supply_desc axp813_ac_power_desc = {
> + .name = "axp813-ac",
> + .type = POWER_SUPPLY_TYPE_MAINS,
> + .properties = axp813_ac_power_properties,
> + .num_properties = ARRAY_SIZE(axp813_ac_power_properties),
> + .property_is_writeable = axp813_ac_power_prop_writeable,
> + .get_property = axp20x_ac_power_get_property,
> + .set_property = axp813_ac_power_set_property,
> +};
> +
> struct axp_data {
> const struct power_supply_desc *power_desc;
> bool acin_adc;
> @@ -154,6 +238,11 @@ static const struct axp_data axp22x_data = {
> .acin_adc = false,
> };
>
> +static const struct axp_data axp813_data = {
> + .power_desc = &axp813_ac_power_desc,
> + .acin_adc = false,
> +};
> +
> static int axp20x_ac_power_probe(struct platform_device *pdev)
> {
> struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> @@ -234,6 +323,9 @@ static const struct of_device_id axp20x_ac_power_match[] = {
> }, {
> .compatible = "x-powers,axp221-ac-power-supply",
> .data = &axp22x_data,
> + }, {
> + .compatible = "x-powers,axp813-ac-power-supply",
> + .data = &axp813_data,
> }, { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, axp20x_ac_power_match);
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index 517e60eecbcb..2302b620d238 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -266,6 +266,7 @@ enum axp20x_variants {
> #define AXP288_RT_BATT_V_H 0xa0
> #define AXP288_RT_BATT_V_L 0xa1
>
> +#define AXP813_ACIN_PATH_CTRL 0x3a
> #define AXP813_ADC_RATE 0x85
>
> /* Fuel Gauge */
> --
> 2.17.1
>
On Saturday, October 13, 2018 1:08:41 AM PDT Oskari Lemmela wrote:
> AXP813 AC power supply support with input current and
> voltage limiting support.
>
> AXP803 AC and battery power supply support.
>
> Changes in v4:
> * Change order of axp20x-gpio in axp20x.c
> * Fix indentation and spaces to tabs in axp20x.c
>
> Changes in v3:
> * Reorder ac_power_supply DT node
> * Rename axp20x_ac_power_set_property function
> * Split mfd commit
>
> Changes in v2:
> * Reuse axp813 compatibles for axp803
> * Refactor axp20x_ac_power.c
Patches 1-3, 5-7:
Tested-by: Vasily Khoruzhick <[email protected]>
> Oskari Lemmela (7):
> dt-bindings: power: supply: axp20x: add AXP813 AC power DT binding
> ARM: dts: axp81x: add AC power supply subnode
> arm64: dts: allwinner: axp803: add AC and battery power supplies
> arm64: dts: allwinner: a64: sopine: enable power supplies
> power: supply: add AC power supply driver for AXP813
> mfd: axp20x: Add AC power supply cell for AXP813
> mfd: axp20x: Add supported cells for AXP803
>
> .../bindings/power/supply/axp20x_ac_power.txt | 3 +
> arch/arm/boot/dts/axp81x.dtsi | 5 +
> arch/arm64/boot/dts/allwinner/axp803.dtsi | 31 +++++++
> .../allwinner/sun50i-a64-sopine-baseboard.dts | 8 ++
> drivers/mfd/axp20x.c | 20 ++++
> drivers/power/supply/axp20x_ac_power.c | 92 +++++++++++++++++++
> include/linux/mfd/axp20x.h | 1 +
> 7 files changed, 160 insertions(+)
Hi,
On Sat, Oct 13, 2018 at 11:08:46AM +0300, Oskari Lemmela wrote:
> AXP813 and AXP803 PMICs can control input current and
> minimum voltage.
>
> Both of these values are configurable.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
> ---
Looks good to me apart from Chen-Yu Tsai's comments.
-- Sebastian
> drivers/power/supply/axp20x_ac_power.c | 92 ++++++++++++++++++++++++++
> include/linux/mfd/axp20x.h | 1 +
> 2 files changed, 93 insertions(+)
>
> diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
> index 0771f951b11f..059a97d6e14c 100644
> --- a/drivers/power/supply/axp20x_ac_power.c
> +++ b/drivers/power/supply/axp20x_ac_power.c
> @@ -27,6 +27,16 @@
> #define AXP20X_PWR_STATUS_ACIN_PRESENT BIT(7)
> #define AXP20X_PWR_STATUS_ACIN_AVAIL BIT(6)
>
> +#define AXP813_VHOLD_MASK GENMASK(5, 3)
> +#define AXP813_VHOLD_UV_TO_BIT(x) ((((x) / 100000) - 40) << 3)
> +#define AXP813_VHOLD_REG_TO_UV(x) \
> + (((((x) & AXP813_VHOLD_MASK) >> 3) + 40) * 100000)
> +
> +#define AXP813_CURR_LIMIT_MASK GENMASK(2, 0)
> +#define AXP813_CURR_LIMIT_UA_TO_BIT(x) (((x) / 500000) - 3)
> +#define AXP813_CURR_LIMIT_REG_TO_UA(x) \
> + ((((x) & AXP813_CURR_LIMIT_MASK) + 3) * 500000)
> +
> #define DRVNAME "axp20x-ac-power-supply"
>
> struct axp20x_ac_power {
> @@ -102,6 +112,55 @@ static int axp20x_ac_power_get_property(struct power_supply *psy,
>
> return 0;
>
> + case POWER_SUPPLY_PROP_VOLTAGE_MIN:
> + ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®);
> + if (ret)
> + return ret;
> +
> + val->intval = AXP813_VHOLD_REG_TO_UV(reg);
> +
> + return 0;
> +
> + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
> + ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®);
> + if (ret)
> + return ret;
> +
> + val->intval = AXP813_CURR_LIMIT_REG_TO_UA(reg);
> +
> + return 0;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int axp813_ac_power_set_property(struct power_supply *psy,
> + enum power_supply_property psp,
> + const union power_supply_propval *val)
> +{
> + struct axp20x_ac_power *power = power_supply_get_drvdata(psy);
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_VOLTAGE_MIN:
> + if (val->intval < 4000000 || val->intval > 4700000)
> + return -EINVAL;
> +
> + return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL,
> + AXP813_VHOLD_MASK,
> + AXP813_VHOLD_UV_TO_BIT(val->intval));
> +
> + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
> + if (val->intval < 1500000 || val->intval > 4000000)
> + return -EINVAL;
> +
> + return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL,
> + AXP813_CURR_LIMIT_MASK,
> + AXP813_CURR_LIMIT_UA_TO_BIT
> + (val->intval));
> +
> default:
> return -EINVAL;
> }
> @@ -109,6 +168,13 @@ static int axp20x_ac_power_get_property(struct power_supply *psy,
> return -EINVAL;
> }
>
> +static int axp813_ac_power_prop_writeable(struct power_supply *psy,
> + enum power_supply_property psp)
> +{
> + return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
> + psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
> +}
> +
> static enum power_supply_property axp20x_ac_power_properties[] = {
> POWER_SUPPLY_PROP_HEALTH,
> POWER_SUPPLY_PROP_PRESENT,
> @@ -123,6 +189,14 @@ static enum power_supply_property axp22x_ac_power_properties[] = {
> POWER_SUPPLY_PROP_ONLINE,
> };
>
> +static enum power_supply_property axp813_ac_power_properties[] = {
> + POWER_SUPPLY_PROP_HEALTH,
> + POWER_SUPPLY_PROP_PRESENT,
> + POWER_SUPPLY_PROP_ONLINE,
> + POWER_SUPPLY_PROP_VOLTAGE_MIN,
> + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
> +};
> +
> static const struct power_supply_desc axp20x_ac_power_desc = {
> .name = "axp20x-ac",
> .type = POWER_SUPPLY_TYPE_MAINS,
> @@ -139,6 +213,16 @@ static const struct power_supply_desc axp22x_ac_power_desc = {
> .get_property = axp20x_ac_power_get_property,
> };
>
> +static const struct power_supply_desc axp813_ac_power_desc = {
> + .name = "axp813-ac",
> + .type = POWER_SUPPLY_TYPE_MAINS,
> + .properties = axp813_ac_power_properties,
> + .num_properties = ARRAY_SIZE(axp813_ac_power_properties),
> + .property_is_writeable = axp813_ac_power_prop_writeable,
> + .get_property = axp20x_ac_power_get_property,
> + .set_property = axp813_ac_power_set_property,
> +};
> +
> struct axp_data {
> const struct power_supply_desc *power_desc;
> bool acin_adc;
> @@ -154,6 +238,11 @@ static const struct axp_data axp22x_data = {
> .acin_adc = false,
> };
>
> +static const struct axp_data axp813_data = {
> + .power_desc = &axp813_ac_power_desc,
> + .acin_adc = false,
> +};
> +
> static int axp20x_ac_power_probe(struct platform_device *pdev)
> {
> struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> @@ -234,6 +323,9 @@ static const struct of_device_id axp20x_ac_power_match[] = {
> }, {
> .compatible = "x-powers,axp221-ac-power-supply",
> .data = &axp22x_data,
> + }, {
> + .compatible = "x-powers,axp813-ac-power-supply",
> + .data = &axp813_data,
> }, { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, axp20x_ac_power_match);
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index 517e60eecbcb..2302b620d238 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -266,6 +266,7 @@ enum axp20x_variants {
> #define AXP288_RT_BATT_V_H 0xa0
> #define AXP288_RT_BATT_V_L 0xa1
>
> +#define AXP813_ACIN_PATH_CTRL 0x3a
> #define AXP813_ADC_RATE 0x85
>
> /* Fuel Gauge */
> --
> 2.17.1
>
Hi,
On Sat, Oct 13, 2018 at 11:08:42AM +0300, Oskari Lemmela wrote:
> The AXP803/AXP813 AC power supply can limit input current and voltage.
>
> Signed-off-by: Oskari Lemmela <[email protected]>
> Reviewed-by: Rob Herring <[email protected]>
> Reviewed-by: Quentin Schulz <[email protected]>
> ---
Reviewed-by: Sebastian Reichel <[email protected]>
-- Sebastian
> .../devicetree/bindings/power/supply/axp20x_ac_power.txt | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
> index 826e8a879121..7a1fb532abe5 100644
> --- a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
> +++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt
> @@ -4,6 +4,7 @@ Required Properties:
> - compatible: One of:
> "x-powers,axp202-ac-power-supply"
> "x-powers,axp221-ac-power-supply"
> + "x-powers,axp813-ac-power-supply"
>
> This node is a subnode of the axp20x PMIC.
>
> @@ -13,6 +14,8 @@ reading ADC channels from the AXP20X ADC.
> The AXP22X is only able to tell if an AC power supply is present and
> usable.
>
> +AXP813/AXP803 are able to limit current and supply voltage
> +
> Example:
>
> &axp209 {
> --
> 2.17.1
>