All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/4] mfd: axp20x: add adc volatile ranges for axp22x
@ 2016-10-09  6:27 ` Icenowy Zheng
  0 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: Rob Herring, Chen-Yu Tsai, Maxime Ripard, Lee Jones,
	Bruno Prémont, Michael Haas
  Cc: Mark Rutland, devicetree, linux-pm, linux-kernel, Russell King,
	Icenowy Zheng, Sebastian Reichel, linux-arm-kernel

AXP22x has also some different register map than axp20x, they're also
added here.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Nothing.

 drivers/mfd/axp20x.c       | 1 +
 include/linux/mfd/axp20x.h | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index fd80b09..17877b2 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -97,6 +97,7 @@ static const struct regmap_range axp22x_volatile_ranges[] = {
 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
 	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),
 	regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
 };
 
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 0be4982..ad3d9c7 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -201,6 +201,10 @@ enum {
 #define AXP20X_OCV_MAX			0xf
 
 /* AXP22X specific registers */
+#define AXP22X_PMIC_ADC_H		0x56
+#define AXP22X_PMIC_ADC_L		0x57
+#define AXP22X_TS_ADC_H			0x58
+#define AXP22X_TS_ADC_L			0x59
 #define AXP22X_BATLOW_THRES1		0xe6
 
 /* AXP288 specific registers */
-- 
2.10.0

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

* [PATCH v2 1/4] mfd: axp20x: add adc volatile ranges for axp22x
@ 2016-10-09  6:27 ` Icenowy Zheng
  0 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: linux-arm-kernel

AXP22x has also some different register map than axp20x, they're also
added here.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Nothing.

 drivers/mfd/axp20x.c       | 1 +
 include/linux/mfd/axp20x.h | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index fd80b09..17877b2 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -97,6 +97,7 @@ static const struct regmap_range axp22x_volatile_ranges[] = {
 	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
 	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),
 	regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
 };
 
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 0be4982..ad3d9c7 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -201,6 +201,10 @@ enum {
 #define AXP20X_OCV_MAX			0xf
 
 /* AXP22X specific registers */
+#define AXP22X_PMIC_ADC_H		0x56
+#define AXP22X_PMIC_ADC_L		0x57
+#define AXP22X_TS_ADC_H			0x58
+#define AXP22X_TS_ADC_L			0x59
 #define AXP22X_BATLOW_THRES1		0xe6
 
 /* AXP288 specific registers */
-- 
2.10.0

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

* [PATCH v2 2/4] power: add axp20x-battery driver
  2016-10-09  6:27 ` Icenowy Zheng
@ 2016-10-09  6:27   ` Icenowy Zheng
  -1 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: Rob Herring, Chen-Yu Tsai, Maxime Ripard, Lee Jones,
	Bruno Prémont, Michael Haas
  Cc: Mark Rutland, devicetree, linux-pm, linux-kernel, Russell King,
	Icenowy Zheng, Sebastian Reichel, linux-arm-kernel

This driver is the battery power supply driver of axp20x PMIC.

This driver currently contains only capacity and current properties (for
axp20x only capacity is supported now) , however it's easy to implement more
properties.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Add initial support for AXP20x.

 drivers/mfd/axp20x.c                  |  28 ++++
 drivers/power/supply/Makefile         |   1 +
 drivers/power/supply/axp20x_battery.c | 277 ++++++++++++++++++++++++++++++++++
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/power/supply/axp20x_battery.c

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 17877b2..ebccb22 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -141,6 +141,15 @@ static struct resource axp20x_ac_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
 };
 
+static struct resource axp20x_battery_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_PLUGIN, "BATT_PLUGIN"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_REMOVAL, "BATT_REMOVAL"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_ENT_ACT_MODE, "BATT_ENT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_EXIT_ACT_MODE, "BATT_EXIT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_CHARG, "CHARG"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_CHARG_DONE, "CHARG_DONE"),
+};
+
 static struct resource axp20x_pek_resources[] = {
 	{
 		.name	= "PEK_DBR",
@@ -162,6 +171,15 @@ static struct resource axp20x_usb_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
 };
 
+static struct resource axp22x_battery_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_PLUGIN, "BATT_PLUGIN"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_REMOVAL, "BATT_REMOVAL"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_ENT_ACT_MODE, "BATT_ENT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_EXIT_ACT_MODE, "BATT_EXIT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_CHARG, "CHARG"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_CHARG_DONE, "CHARG_DONE"),
+};
+
 static struct resource axp22x_usb_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
@@ -520,6 +538,11 @@ static struct mfd_cell axp20x_cells[] = {
 		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
 		.resources	= axp20x_ac_power_supply_resources,
 	}, {
+		.name		= "axp20x-battery",
+		.of_compatible	= "x-powers,axp202-battery",
+		.num_resources	= ARRAY_SIZE(axp20x_battery_resources),
+		.resources	= axp20x_battery_resources,
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp202-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
@@ -535,6 +558,11 @@ static struct mfd_cell axp22x_cells[] = {
 	}, {
 		.name			= "axp20x-regulator",
 	}, {
+		.name		= "axp20x-battery",
+		.of_compatible	= "x-powers,axp221-battery",
+		.num_resources	= ARRAY_SIZE(axp22x_battery_resources),
+		.resources	= axp22x_battery_resources,
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp221-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 36c599d..01271d3 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_GENERIC_ADC_BATTERY)	+= generic-adc-battery.o
 
 obj-$(CONFIG_PDA_POWER)		+= pda_power.o
 obj-$(CONFIG_APM_POWER)		+= apm_power.o
+obj-$(CONFIG_AXP20X_POWER)	+= axp20x_battery.o
 obj-$(CONFIG_AXP20X_POWER)	+= axp20x_usb_power.o
 obj-$(CONFIG_MAX8925_POWER)	+= max8925_power.o
 obj-$(CONFIG_WM831X_BACKUP)	+= wm831x_backup.o
diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
new file mode 100644
index 0000000..67ee58f
--- /dev/null
+++ b/drivers/power/supply/axp20x_battery.c
@@ -0,0 +1,277 @@
+/*
+ * AXP20x PMIC battery status driver
+ *
+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
+ * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (C) 2014 Bruno Prémont <bonbons@linux-vserver.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DRVNAME "axp20x-battery"
+
+#define AXP20X_PWR_STATUS_ACIN_USED BIT(6)
+#define AXP20X_PWR_STATUS_VBUS_USED BIT(4)
+#define AXP20X_PWR_STATUS_BAT_DIRECTION BIT(2)
+
+#define AXP20X_OP_MODE_CHARGING BIT(6)
+#define AXP20X_OP_MODE_BATTERY_PRESENT BIT(5)
+#define AXP20X_OP_MODE_BATTERY_ACTIVE BIT(3)
+
+#define AXP20X_CAPACITY_CORRECT BIT(7)
+
+struct axp20x_battery {
+	struct axp20x_dev *axp20x;
+	struct regmap *regmap;
+	struct power_supply *supply;
+};
+
+static irqreturn_t axp20x_battery_irq(int irq, void *devid)
+{
+	struct axp20x_battery *power = devid;
+
+	power_supply_changed(power->supply);
+
+	return IRQ_HANDLED;
+}
+
+static int axp20x_battery_get_property(struct power_supply *psy,
+	enum power_supply_property psp, union power_supply_propval *val)
+{
+	struct axp20x_battery *power = power_supply_get_drvdata(psy);
+	unsigned int input, op_mode, capacity, dh, dl;
+	int ret, ext;
+
+	/* All the properties below need the input-status reg value */
+	ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(power->regmap, AXP20X_PWR_OP_MODE, &op_mode);
+	if (ret)
+		return ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_HEALTH:
+		if (!(op_mode & AXP20X_OP_MODE_BATTERY_PRESENT)) {
+			val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+			break;
+		}
+
+		val->intval = POWER_SUPPLY_HEALTH_GOOD;
+
+		if (op_mode & AXP20X_OP_MODE_BATTERY_ACTIVE) {
+			/* AXP20X is now trying to re-activate the battery */
+			val->intval = POWER_SUPPLY_HEALTH_DEAD;
+			break;
+		}
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = !!(op_mode & AXP20X_OP_MODE_BATTERY_PRESENT);
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		ret = regmap_read(power->regmap, AXP20X_FG_RES, &capacity);
+		if (ret)
+			return ret;
+		if (capacity & AXP20X_CAPACITY_CORRECT)
+			val->intval = capacity & (~AXP20X_CAPACITY_CORRECT);
+		else
+			return -EIO;
+		/* from axp_capchange function of Allwinner 3.4 driver */
+		if (val->intval == 127)
+			val->intval = 100;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		if (!(op_mode & AXP20X_OP_MODE_BATTERY_PRESENT)) {
+			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+			break;
+		}
+
+		ret = regmap_read(power->regmap, AXP20X_FG_RES, &capacity);
+		if (ret)
+			return ret;
+
+		ext = (input & AXP20X_PWR_STATUS_ACIN_USED) ||
+		      (input & AXP20X_PWR_STATUS_VBUS_USED);
+
+		if (op_mode & AXP20X_OP_MODE_CHARGING)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else if (!(input & AXP20X_PWR_STATUS_BAT_DIRECTION) && !ext)
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		else if (capacity == (100 | AXP20X_CAPACITY_CORRECT) ||
+			 capacity == (127 | AXP20X_CAPACITY_CORRECT))
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		else
+			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
+		if (ret)
+			return ret;
+		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
+		if (ret)
+			return ret;
+		/* it's a 12 bit integer, high 8-bit is stored in dh */
+		val->intval = dh << 4 | dl >> 4;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
+		if (ret)
+			return ret;
+		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
+		if (ret)
+			return ret;
+		/* it's a 12 bit integer, high 8-bit is stored in dh */
+		val->intval = dh << 4 | dl >> 4;
+		/* The formula below is from axp22_vbat_to_mV function
+		 * of Allwinner 3.4 kernel.
+		 */
+		val->intval = val->intval * 1100 / 1000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum power_supply_property axp20x_battery_properties[] = {
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
+static const struct power_supply_desc axp20x_battery_desc = {
+	.name = "axp20x-battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.properties = axp20x_battery_properties,
+	.num_properties = ARRAY_SIZE(axp20x_battery_properties),
+	.get_property = axp20x_battery_get_property,
+};
+
+static enum power_supply_property axp22x_battery_properties[] = {
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static const struct power_supply_desc axp22x_battery_desc = {
+	.name = "axp20x-battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.properties = axp22x_battery_properties,
+	.num_properties = ARRAY_SIZE(axp22x_battery_properties),
+	.get_property = axp20x_battery_get_property,
+};
+
+static int axp20x_battery_probe(struct platform_device *pdev)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct power_supply_config psy_cfg = {};
+	struct axp20x_battery *power;
+	static const char * const axp20x_irq_names[] = {
+		"BATT_PLUGIN", "BATT_REMOVAL", "BATT_ENT_ACT_MODE",
+		"BATT_EXIT_ACT_MODE", "CHARG", "CHARG_DONE", NULL };
+	static const char * const axp22x_irq_names[] = {
+		"BATT_PLUGIN", "BATT_REMOVAL", "BATT_ENT_ACT_MODE",
+		"BATT_EXIT_ACT_MODE", "CHARG", "CHARG_DONE", NULL };
+	static const char * const *irq_names;
+	const struct power_supply_desc *battery_desc;
+	int i, irq, ret;
+
+	if (!of_device_is_available(pdev->dev.of_node))
+		return -ENODEV;
+
+	if (!axp20x) {
+		dev_err(&pdev->dev, "Parent drvdata not set\n");
+		return -EINVAL;
+	}
+
+	power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL);
+	if (!power)
+		return -ENOMEM;
+
+	power->axp20x = axp20x;
+	power->regmap = axp20x->regmap;
+
+	switch (power->axp20x->variant) {
+	case AXP202_ID:
+	case AXP209_ID:
+		battery_desc = &axp20x_battery_desc;
+		irq_names = axp20x_irq_names;
+		break;
+	case AXP221_ID:
+	case AXP223_ID:
+		battery_desc = &axp22x_battery_desc;
+		irq_names = axp22x_irq_names;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
+			axp20x->variant);
+		return -EINVAL;
+	}
+
+	psy_cfg.of_node = pdev->dev.of_node;
+	psy_cfg.drv_data = power;
+
+	power->supply = devm_power_supply_register(&pdev->dev, battery_desc,
+						   &psy_cfg);
+	if (IS_ERR(power->supply))
+		return PTR_ERR(power->supply);
+
+	/* Request irqs after registering, as irqs may trigger immediately */
+	for (i = 0; irq_names[i]; i++) {
+		irq = platform_get_irq_byname(pdev, irq_names[i]);
+		if (irq < 0) {
+			dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
+				 irq_names[i], irq);
+			continue;
+		}
+		irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
+		ret = devm_request_any_context_irq(&pdev->dev, irq,
+				axp20x_battery_irq, 0, DRVNAME, power);
+		if (ret < 0)
+			dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
+				 irq_names[i], ret);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id axp20x_battery_match[] = {
+	{ .compatible = "x-powers,axp202-battery" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, axp20x_battery_match);
+
+static struct platform_driver axp20x_battery_driver = {
+	.probe = axp20x_battery_probe,
+	.driver = {
+		.name = DRVNAME,
+		.of_match_table = axp20x_battery_match,
+	},
+};
+
+module_platform_driver(axp20x_battery_driver);
+
+MODULE_AUTHOR("Icenowy Zheng <icenowy@aosc.xyz>");
+MODULE_DESCRIPTION("AXP20x PMIC battery status driver");
+MODULE_LICENSE("GPL");
-- 
2.10.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 2/4] power: add axp20x-battery driver
@ 2016-10-09  6:27   ` Icenowy Zheng
  0 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: linux-arm-kernel

This driver is the battery power supply driver of axp20x PMIC.

This driver currently contains only capacity and current properties (for
axp20x only capacity is supported now) , however it's easy to implement more
properties.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Add initial support for AXP20x.

 drivers/mfd/axp20x.c                  |  28 ++++
 drivers/power/supply/Makefile         |   1 +
 drivers/power/supply/axp20x_battery.c | 277 ++++++++++++++++++++++++++++++++++
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/power/supply/axp20x_battery.c

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 17877b2..ebccb22 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -141,6 +141,15 @@ static struct resource axp20x_ac_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
 };
 
+static struct resource axp20x_battery_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_PLUGIN, "BATT_PLUGIN"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_REMOVAL, "BATT_REMOVAL"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_ENT_ACT_MODE, "BATT_ENT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_BATT_EXIT_ACT_MODE, "BATT_EXIT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_CHARG, "CHARG"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_CHARG_DONE, "CHARG_DONE"),
+};
+
 static struct resource axp20x_pek_resources[] = {
 	{
 		.name	= "PEK_DBR",
@@ -162,6 +171,15 @@ static struct resource axp20x_usb_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
 };
 
+static struct resource axp22x_battery_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_PLUGIN, "BATT_PLUGIN"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_REMOVAL, "BATT_REMOVAL"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_ENT_ACT_MODE, "BATT_ENT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_BATT_EXIT_ACT_MODE, "BATT_EXIT_ACT_MODE"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_CHARG, "CHARG"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_CHARG_DONE, "CHARG_DONE"),
+};
+
 static struct resource axp22x_usb_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
@@ -520,6 +538,11 @@ static struct mfd_cell axp20x_cells[] = {
 		.num_resources	= ARRAY_SIZE(axp20x_ac_power_supply_resources),
 		.resources	= axp20x_ac_power_supply_resources,
 	}, {
+		.name		= "axp20x-battery",
+		.of_compatible	= "x-powers,axp202-battery",
+		.num_resources	= ARRAY_SIZE(axp20x_battery_resources),
+		.resources	= axp20x_battery_resources,
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp202-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
@@ -535,6 +558,11 @@ static struct mfd_cell axp22x_cells[] = {
 	}, {
 		.name			= "axp20x-regulator",
 	}, {
+		.name		= "axp20x-battery",
+		.of_compatible	= "x-powers,axp221-battery",
+		.num_resources	= ARRAY_SIZE(axp22x_battery_resources),
+		.resources	= axp22x_battery_resources,
+	}, {
 		.name		= "axp20x-usb-power-supply",
 		.of_compatible	= "x-powers,axp221-usb-power-supply",
 		.num_resources	= ARRAY_SIZE(axp22x_usb_power_supply_resources),
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 36c599d..01271d3 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_GENERIC_ADC_BATTERY)	+= generic-adc-battery.o
 
 obj-$(CONFIG_PDA_POWER)		+= pda_power.o
 obj-$(CONFIG_APM_POWER)		+= apm_power.o
+obj-$(CONFIG_AXP20X_POWER)	+= axp20x_battery.o
 obj-$(CONFIG_AXP20X_POWER)	+= axp20x_usb_power.o
 obj-$(CONFIG_MAX8925_POWER)	+= max8925_power.o
 obj-$(CONFIG_WM831X_BACKUP)	+= wm831x_backup.o
diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
new file mode 100644
index 0000000..67ee58f
--- /dev/null
+++ b/drivers/power/supply/axp20x_battery.c
@@ -0,0 +1,277 @@
+/*
+ * AXP20x PMIC battery status driver
+ *
+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
+ * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (C) 2014 Bruno Pr?mont <bonbons@linux-vserver.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DRVNAME "axp20x-battery"
+
+#define AXP20X_PWR_STATUS_ACIN_USED BIT(6)
+#define AXP20X_PWR_STATUS_VBUS_USED BIT(4)
+#define AXP20X_PWR_STATUS_BAT_DIRECTION BIT(2)
+
+#define AXP20X_OP_MODE_CHARGING BIT(6)
+#define AXP20X_OP_MODE_BATTERY_PRESENT BIT(5)
+#define AXP20X_OP_MODE_BATTERY_ACTIVE BIT(3)
+
+#define AXP20X_CAPACITY_CORRECT BIT(7)
+
+struct axp20x_battery {
+	struct axp20x_dev *axp20x;
+	struct regmap *regmap;
+	struct power_supply *supply;
+};
+
+static irqreturn_t axp20x_battery_irq(int irq, void *devid)
+{
+	struct axp20x_battery *power = devid;
+
+	power_supply_changed(power->supply);
+
+	return IRQ_HANDLED;
+}
+
+static int axp20x_battery_get_property(struct power_supply *psy,
+	enum power_supply_property psp, union power_supply_propval *val)
+{
+	struct axp20x_battery *power = power_supply_get_drvdata(psy);
+	unsigned int input, op_mode, capacity, dh, dl;
+	int ret, ext;
+
+	/* All the properties below need the input-status reg value */
+	ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
+	if (ret)
+		return ret;
+
+	ret = regmap_read(power->regmap, AXP20X_PWR_OP_MODE, &op_mode);
+	if (ret)
+		return ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_HEALTH:
+		if (!(op_mode & AXP20X_OP_MODE_BATTERY_PRESENT)) {
+			val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+			break;
+		}
+
+		val->intval = POWER_SUPPLY_HEALTH_GOOD;
+
+		if (op_mode & AXP20X_OP_MODE_BATTERY_ACTIVE) {
+			/* AXP20X is now trying to re-activate the battery */
+			val->intval = POWER_SUPPLY_HEALTH_DEAD;
+			break;
+		}
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = !!(op_mode & AXP20X_OP_MODE_BATTERY_PRESENT);
+		break;
+	case POWER_SUPPLY_PROP_CAPACITY:
+		ret = regmap_read(power->regmap, AXP20X_FG_RES, &capacity);
+		if (ret)
+			return ret;
+		if (capacity & AXP20X_CAPACITY_CORRECT)
+			val->intval = capacity & (~AXP20X_CAPACITY_CORRECT);
+		else
+			return -EIO;
+		/* from axp_capchange function of Allwinner 3.4 driver */
+		if (val->intval == 127)
+			val->intval = 100;
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		if (!(op_mode & AXP20X_OP_MODE_BATTERY_PRESENT)) {
+			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+			break;
+		}
+
+		ret = regmap_read(power->regmap, AXP20X_FG_RES, &capacity);
+		if (ret)
+			return ret;
+
+		ext = (input & AXP20X_PWR_STATUS_ACIN_USED) ||
+		      (input & AXP20X_PWR_STATUS_VBUS_USED);
+
+		if (op_mode & AXP20X_OP_MODE_CHARGING)
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+		else if (!(input & AXP20X_PWR_STATUS_BAT_DIRECTION) && !ext)
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		else if (capacity == (100 | AXP20X_CAPACITY_CORRECT) ||
+			 capacity == (127 | AXP20X_CAPACITY_CORRECT))
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+		else
+			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
+		if (ret)
+			return ret;
+		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
+		if (ret)
+			return ret;
+		/* it's a 12 bit integer, high 8-bit is stored in dh */
+		val->intval = dh << 4 | dl >> 4;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
+		if (ret)
+			return ret;
+		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
+		if (ret)
+			return ret;
+		/* it's a 12 bit integer, high 8-bit is stored in dh */
+		val->intval = dh << 4 | dl >> 4;
+		/* The formula below is from axp22_vbat_to_mV function
+		 * of Allwinner 3.4 kernel.
+		 */
+		val->intval = val->intval * 1100 / 1000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum power_supply_property axp20x_battery_properties[] = {
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_STATUS,
+};
+
+static const struct power_supply_desc axp20x_battery_desc = {
+	.name = "axp20x-battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.properties = axp20x_battery_properties,
+	.num_properties = ARRAY_SIZE(axp20x_battery_properties),
+	.get_property = axp20x_battery_get_property,
+};
+
+static enum power_supply_property axp22x_battery_properties[] = {
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+};
+
+static const struct power_supply_desc axp22x_battery_desc = {
+	.name = "axp20x-battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.properties = axp22x_battery_properties,
+	.num_properties = ARRAY_SIZE(axp22x_battery_properties),
+	.get_property = axp20x_battery_get_property,
+};
+
+static int axp20x_battery_probe(struct platform_device *pdev)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct power_supply_config psy_cfg = {};
+	struct axp20x_battery *power;
+	static const char * const axp20x_irq_names[] = {
+		"BATT_PLUGIN", "BATT_REMOVAL", "BATT_ENT_ACT_MODE",
+		"BATT_EXIT_ACT_MODE", "CHARG", "CHARG_DONE", NULL };
+	static const char * const axp22x_irq_names[] = {
+		"BATT_PLUGIN", "BATT_REMOVAL", "BATT_ENT_ACT_MODE",
+		"BATT_EXIT_ACT_MODE", "CHARG", "CHARG_DONE", NULL };
+	static const char * const *irq_names;
+	const struct power_supply_desc *battery_desc;
+	int i, irq, ret;
+
+	if (!of_device_is_available(pdev->dev.of_node))
+		return -ENODEV;
+
+	if (!axp20x) {
+		dev_err(&pdev->dev, "Parent drvdata not set\n");
+		return -EINVAL;
+	}
+
+	power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL);
+	if (!power)
+		return -ENOMEM;
+
+	power->axp20x = axp20x;
+	power->regmap = axp20x->regmap;
+
+	switch (power->axp20x->variant) {
+	case AXP202_ID:
+	case AXP209_ID:
+		battery_desc = &axp20x_battery_desc;
+		irq_names = axp20x_irq_names;
+		break;
+	case AXP221_ID:
+	case AXP223_ID:
+		battery_desc = &axp22x_battery_desc;
+		irq_names = axp22x_irq_names;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
+			axp20x->variant);
+		return -EINVAL;
+	}
+
+	psy_cfg.of_node = pdev->dev.of_node;
+	psy_cfg.drv_data = power;
+
+	power->supply = devm_power_supply_register(&pdev->dev, battery_desc,
+						   &psy_cfg);
+	if (IS_ERR(power->supply))
+		return PTR_ERR(power->supply);
+
+	/* Request irqs after registering, as irqs may trigger immediately */
+	for (i = 0; irq_names[i]; i++) {
+		irq = platform_get_irq_byname(pdev, irq_names[i]);
+		if (irq < 0) {
+			dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
+				 irq_names[i], irq);
+			continue;
+		}
+		irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
+		ret = devm_request_any_context_irq(&pdev->dev, irq,
+				axp20x_battery_irq, 0, DRVNAME, power);
+		if (ret < 0)
+			dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
+				 irq_names[i], ret);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id axp20x_battery_match[] = {
+	{ .compatible = "x-powers,axp202-battery" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, axp20x_battery_match);
+
+static struct platform_driver axp20x_battery_driver = {
+	.probe = axp20x_battery_probe,
+	.driver = {
+		.name = DRVNAME,
+		.of_match_table = axp20x_battery_match,
+	},
+};
+
+module_platform_driver(axp20x_battery_driver);
+
+MODULE_AUTHOR("Icenowy Zheng <icenowy@aosc.xyz>");
+MODULE_DESCRIPTION("AXP20x PMIC battery status driver");
+MODULE_LICENSE("GPL");
-- 
2.10.0

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

* [PATCH v2 3/4] ARM: dts: add battery node for axp20x/axp22x dtsi
  2016-10-09  6:27 ` Icenowy Zheng
@ 2016-10-09  6:27   ` Icenowy Zheng
  -1 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: Rob Herring, Chen-Yu Tsai, Maxime Ripard, Lee Jones,
	Bruno Prémont, Michael Haas
  Cc: Mark Rutland, devicetree, linux-pm, linux-kernel, Russell King,
	Icenowy Zheng, Sebastian Reichel, linux-arm-kernel

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Add support for AXP20x.

 arch/arm/boot/dts/axp209.dtsi | 5 +++++
 arch/arm/boot/dts/axp22x.dtsi | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index afbe89c..1602987 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -91,6 +91,11 @@
 		};
 	};
 
+	battery: battery {
+		compatible = "x-powers,axp202-battery";
+		status = "disabled";
+	};
+
 	usb_power_supply: usb_power_supply {
 		compatible = "x-powers,axp202-usb-power-supply";
 		status = "disabled";
diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
index 458b668..a09ba3f 100644
--- a/arch/arm/boot/dts/axp22x.dtsi
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -148,6 +148,11 @@
 		};
 	};
 
+	battery: battery {
+		compatible = "x-powers,axp221-battery";
+		status = "disabled";
+	};
+
 	usb_power_supply: usb_power_supply {
 		compatible = "x-powers,axp221-usb-power-supply";
 		status = "disabled";
-- 
2.10.0

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

* [PATCH v2 3/4] ARM: dts: add battery node for axp20x/axp22x dtsi
@ 2016-10-09  6:27   ` Icenowy Zheng
  0 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Add support for AXP20x.

 arch/arm/boot/dts/axp209.dtsi | 5 +++++
 arch/arm/boot/dts/axp22x.dtsi | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/axp209.dtsi b/arch/arm/boot/dts/axp209.dtsi
index afbe89c..1602987 100644
--- a/arch/arm/boot/dts/axp209.dtsi
+++ b/arch/arm/boot/dts/axp209.dtsi
@@ -91,6 +91,11 @@
 		};
 	};
 
+	battery: battery {
+		compatible = "x-powers,axp202-battery";
+		status = "disabled";
+	};
+
 	usb_power_supply: usb_power_supply {
 		compatible = "x-powers,axp202-usb-power-supply";
 		status = "disabled";
diff --git a/arch/arm/boot/dts/axp22x.dtsi b/arch/arm/boot/dts/axp22x.dtsi
index 458b668..a09ba3f 100644
--- a/arch/arm/boot/dts/axp22x.dtsi
+++ b/arch/arm/boot/dts/axp22x.dtsi
@@ -148,6 +148,11 @@
 		};
 	};
 
+	battery: battery {
+		compatible = "x-powers,axp221-battery";
+		status = "disabled";
+	};
+
 	usb_power_supply: usb_power_supply {
 		compatible = "x-powers,axp221-usb-power-supply";
 		status = "disabled";
-- 
2.10.0

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

* [PATCH v2 4/4] ARM: sunxi: enable battery on reference design tablets
  2016-10-09  6:27 ` Icenowy Zheng
@ 2016-10-09  6:27   ` Icenowy Zheng
  -1 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: Rob Herring, Chen-Yu Tsai, Maxime Ripard, Lee Jones,
	Bruno Prémont, Michael Haas
  Cc: Mark Rutland, devicetree, linux-pm, linux-kernel, Russell King,
	Icenowy Zheng, Sebastian Reichel, linux-arm-kernel

Since battery is one part of the reference design of Allwinner tablets,
enable the battery node of reference design tablets.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Applied to reference design tablet, not Q8 only now.
- Add support for sun5i reference design tablet.

 arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi | 4 ++++
 arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
index 20cc940..9e17b46 100644
--- a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
@@ -92,6 +92,10 @@
 
 #include "axp209.dtsi"
 
+&battery {
+	status = "okay";
+};
+
 &lradc {
 	vref-supply = <&reg_ldo2>;
 };
diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index 9d90361..74517ab 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -112,6 +112,10 @@
 
 #include "axp22x.dtsi"
 
+&battery {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-always-on;
 	regulator-min-microvolt = <3000000>;
-- 
2.10.0

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

* [PATCH v2 4/4] ARM: sunxi: enable battery on reference design tablets
@ 2016-10-09  6:27   ` Icenowy Zheng
  0 siblings, 0 replies; 14+ messages in thread
From: Icenowy Zheng @ 2016-10-09  6:27 UTC (permalink / raw)
  To: linux-arm-kernel

Since battery is one part of the reference design of Allwinner tablets,
enable the battery node of reference design tablets.

Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
---
Changes since v1:
- Applied to reference design tablet, not Q8 only now.
- Add support for sun5i reference design tablet.

 arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi | 4 ++++
 arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
index 20cc940..9e17b46 100644
--- a/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun5i-reference-design-tablet.dtsi
@@ -92,6 +92,10 @@
 
 #include "axp209.dtsi"
 
+&battery {
+	status = "okay";
+};
+
 &lradc {
 	vref-supply = <&reg_ldo2>;
 };
diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index 9d90361..74517ab 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -112,6 +112,10 @@
 
 #include "axp22x.dtsi"
 
+&battery {
+	status = "okay";
+};
+
 &reg_aldo1 {
 	regulator-always-on;
 	regulator-min-microvolt = <3000000>;
-- 
2.10.0

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

* Re: [PATCH v2 2/4] power: add axp20x-battery driver
  2016-10-09  6:27   ` Icenowy Zheng
  (?)
@ 2016-10-10 12:57     ` Maxime Ripard
  -1 siblings, 0 replies; 14+ messages in thread
From: Maxime Ripard @ 2016-10-10 12:57 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Lee Jones, Bruno Prémont,
	Michael Haas, Mark Rutland, Russell King, Sebastian Reichel,
	devicetree, linux-arm-kernel, linux-kernel, linux-pm, quentin

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

Hi Icenowy,

On Sun, Oct 09, 2016 at 02:27:12PM +0800, Icenowy Zheng wrote:
> +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
> +		if (ret)
> +			return ret;
> +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
> +		if (ret)
> +			return ret;
> +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> +		val->intval = dh << 4 | dl >> 4;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
> +		if (ret)
> +			return ret;
> +		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
> +		if (ret)
> +			return ret;
> +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> +		val->intval = dh << 4 | dl >> 4;
> +		/* The formula below is from axp22_vbat_to_mV function
> +		 * of Allwinner 3.4 kernel.
> +		 */
> +		val->intval = val->intval * 1100 / 1000;
> +		break;

I really feel that this should be implemented through a IIO driver
(like the AXP288). This is especially true for the AXP209 and its
multiple GPIOs that can be muxed to a general purpose ADC, but it's
also true for the AXP221 / 223 TS pin that can also be used as an ADC.

Quentin has been working on this lately for the AXP209, feel free to
sync with him to support the AXP22*

Maxime

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

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

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

* Re: [PATCH v2 2/4] power: add axp20x-battery driver
@ 2016-10-10 12:57     ` Maxime Ripard
  0 siblings, 0 replies; 14+ messages in thread
From: Maxime Ripard @ 2016-10-10 12:57 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Mark Rutland, devicetree, linux-pm, linux-kernel, Michael Haas,
	Russell King, quentin, Chen-Yu Tsai, Rob Herring,
	Sebastian Reichel, Bruno Prémont, Lee Jones,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1442 bytes --]

Hi Icenowy,

On Sun, Oct 09, 2016 at 02:27:12PM +0800, Icenowy Zheng wrote:
> +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
> +		if (ret)
> +			return ret;
> +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
> +		if (ret)
> +			return ret;
> +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> +		val->intval = dh << 4 | dl >> 4;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
> +		if (ret)
> +			return ret;
> +		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
> +		if (ret)
> +			return ret;
> +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> +		val->intval = dh << 4 | dl >> 4;
> +		/* The formula below is from axp22_vbat_to_mV function
> +		 * of Allwinner 3.4 kernel.
> +		 */
> +		val->intval = val->intval * 1100 / 1000;
> +		break;

I really feel that this should be implemented through a IIO driver
(like the AXP288). This is especially true for the AXP209 and its
multiple GPIOs that can be muxed to a general purpose ADC, but it's
also true for the AXP221 / 223 TS pin that can also be used as an ADC.

Quentin has been working on this lately for the AXP209, feel free to
sync with him to support the AXP22*

Maxime

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

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 2/4] power: add axp20x-battery driver
@ 2016-10-10 12:57     ` Maxime Ripard
  0 siblings, 0 replies; 14+ messages in thread
From: Maxime Ripard @ 2016-10-10 12:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Icenowy,

On Sun, Oct 09, 2016 at 02:27:12PM +0800, Icenowy Zheng wrote:
> +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
> +		if (ret)
> +			return ret;
> +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
> +		if (ret)
> +			return ret;
> +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> +		val->intval = dh << 4 | dl >> 4;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
> +		if (ret)
> +			return ret;
> +		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
> +		if (ret)
> +			return ret;
> +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> +		val->intval = dh << 4 | dl >> 4;
> +		/* The formula below is from axp22_vbat_to_mV function
> +		 * of Allwinner 3.4 kernel.
> +		 */
> +		val->intval = val->intval * 1100 / 1000;
> +		break;

I really feel that this should be implemented through a IIO driver
(like the AXP288). This is especially true for the AXP209 and its
multiple GPIOs that can be muxed to a general purpose ADC, but it's
also true for the AXP221 / 223 TS pin that can also be used as an ADC.

Quentin has been working on this lately for the AXP209, feel free to
sync with him to support the AXP22*

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161010/f2256077/attachment.sig>

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

* Re: [PATCH v2 2/4] power: add axp20x-battery driver
  2016-10-10 12:57     ` Maxime Ripard
  (?)
@ 2016-10-10 13:12       ` Maxime Ripard
  -1 siblings, 0 replies; 14+ messages in thread
From: Maxime Ripard @ 2016-10-10 13:12 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Rob Herring, Chen-Yu Tsai, Lee Jones, Bruno Prémont,
	Michael Haas, Mark Rutland, Russell King, Sebastian Reichel,
	devicetree, linux-arm-kernel, linux-kernel, linux-pm, quentin

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

Adding the real Quentin address

On Mon, Oct 10, 2016 at 02:57:26PM +0200, Maxime Ripard wrote:
> Hi Icenowy,
> 
> On Sun, Oct 09, 2016 at 02:27:12PM +0800, Icenowy Zheng wrote:
> > +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
> > +		if (ret)
> > +			return ret;
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
> > +		if (ret)
> > +			return ret;
> > +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> > +		val->intval = dh << 4 | dl >> 4;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
> > +		if (ret)
> > +			return ret;
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
> > +		if (ret)
> > +			return ret;
> > +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> > +		val->intval = dh << 4 | dl >> 4;
> > +		/* The formula below is from axp22_vbat_to_mV function
> > +		 * of Allwinner 3.4 kernel.
> > +		 */
> > +		val->intval = val->intval * 1100 / 1000;
> > +		break;
> 
> I really feel that this should be implemented through a IIO driver
> (like the AXP288). This is especially true for the AXP209 and its
> multiple GPIOs that can be muxed to a general purpose ADC, but it's
> also true for the AXP221 / 223 TS pin that can also be used as an ADC.
> 
> Quentin has been working on this lately for the AXP209, feel free to
> sync with him to support the AXP22*
> 
> Maxime
> 
> -- 
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com



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

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

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

* Re: [PATCH v2 2/4] power: add axp20x-battery driver
@ 2016-10-10 13:12       ` Maxime Ripard
  0 siblings, 0 replies; 14+ messages in thread
From: Maxime Ripard @ 2016-10-10 13:12 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Mark Rutland, devicetree, quentin, linux-pm, linux-kernel,
	Michael Haas, Russell King, Chen-Yu Tsai, Rob Herring,
	Sebastian Reichel, Bruno Prémont, Lee Jones,
	linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1733 bytes --]

Adding the real Quentin address

On Mon, Oct 10, 2016 at 02:57:26PM +0200, Maxime Ripard wrote:
> Hi Icenowy,
> 
> On Sun, Oct 09, 2016 at 02:27:12PM +0800, Icenowy Zheng wrote:
> > +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
> > +		if (ret)
> > +			return ret;
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
> > +		if (ret)
> > +			return ret;
> > +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> > +		val->intval = dh << 4 | dl >> 4;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
> > +		if (ret)
> > +			return ret;
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
> > +		if (ret)
> > +			return ret;
> > +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> > +		val->intval = dh << 4 | dl >> 4;
> > +		/* The formula below is from axp22_vbat_to_mV function
> > +		 * of Allwinner 3.4 kernel.
> > +		 */
> > +		val->intval = val->intval * 1100 / 1000;
> > +		break;
> 
> I really feel that this should be implemented through a IIO driver
> (like the AXP288). This is especially true for the AXP209 and its
> multiple GPIOs that can be muxed to a general purpose ADC, but it's
> also true for the AXP221 / 223 TS pin that can also be used as an ADC.
> 
> Quentin has been working on this lately for the AXP209, feel free to
> sync with him to support the AXP22*
> 
> Maxime
> 
> -- 
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com



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

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

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v2 2/4] power: add axp20x-battery driver
@ 2016-10-10 13:12       ` Maxime Ripard
  0 siblings, 0 replies; 14+ messages in thread
From: Maxime Ripard @ 2016-10-10 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

Adding the real Quentin address

On Mon, Oct 10, 2016 at 02:57:26PM +0200, Maxime Ripard wrote:
> Hi Icenowy,
> 
> On Sun, Oct 09, 2016 at 02:27:12PM +0800, Icenowy Zheng wrote:
> > +	case POWER_SUPPLY_PROP_CURRENT_NOW:
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_H, &dh);
> > +		if (ret)
> > +			return ret;
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_DISCHRG_I_L, &dl);
> > +		if (ret)
> > +			return ret;
> > +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> > +		val->intval = dh << 4 | dl >> 4;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_V_H, &dh);
> > +		if (ret)
> > +			return ret;
> > +		ret = regmap_read(power->regmap, AXP20X_BATT_V_L, &dl);
> > +		if (ret)
> > +			return ret;
> > +		/* it's a 12 bit integer, high 8-bit is stored in dh */
> > +		val->intval = dh << 4 | dl >> 4;
> > +		/* The formula below is from axp22_vbat_to_mV function
> > +		 * of Allwinner 3.4 kernel.
> > +		 */
> > +		val->intval = val->intval * 1100 / 1000;
> > +		break;
> 
> I really feel that this should be implemented through a IIO driver
> (like the AXP288). This is especially true for the AXP209 and its
> multiple GPIOs that can be muxed to a general purpose ADC, but it's
> also true for the AXP221 / 223 TS pin that can also be used as an ADC.
> 
> Quentin has been working on this lately for the AXP209, feel free to
> sync with him to support the AXP22*
> 
> Maxime
> 
> -- 
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com



-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161010/ff37d435/attachment.sig>

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

end of thread, other threads:[~2016-10-10 13:14 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-09  6:27 [PATCH v2 1/4] mfd: axp20x: add adc volatile ranges for axp22x Icenowy Zheng
2016-10-09  6:27 ` Icenowy Zheng
2016-10-09  6:27 ` [PATCH v2 2/4] power: add axp20x-battery driver Icenowy Zheng
2016-10-09  6:27   ` Icenowy Zheng
2016-10-10 12:57   ` Maxime Ripard
2016-10-10 12:57     ` Maxime Ripard
2016-10-10 12:57     ` Maxime Ripard
2016-10-10 13:12     ` Maxime Ripard
2016-10-10 13:12       ` Maxime Ripard
2016-10-10 13:12       ` Maxime Ripard
2016-10-09  6:27 ` [PATCH v2 3/4] ARM: dts: add battery node for axp20x/axp22x dtsi Icenowy Zheng
2016-10-09  6:27   ` Icenowy Zheng
2016-10-09  6:27 ` [PATCH v2 4/4] ARM: sunxi: enable battery on reference design tablets Icenowy Zheng
2016-10-09  6:27   ` Icenowy Zheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.