[PATCH v2 1/1] power: supply: gpio-charger: Support to disable charger

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Stefan Raufhake <s.raufhake@xxxxxxxxxxx>

Some GPIO-controlled power supplies can be turned off (charging disabled).
Support changing the charging state by setting charge_type to
POWER_SUPPLY_CHARGE_TYPE_STANDARD and disabling charging by setting
charge_type to POWER_SUPPLY_CHARGE_TYPE_NONE. One potential use case for
this is disabling battery backup on a UPS.

Signed-off-by: Stefan Raufhake <s.raufhake@xxxxxxxxxxx>
---
 .../bindings/power/supply/gpio-charger.yaml   |  6 +++
 drivers/power/supply/gpio-charger.c           | 43 +++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/supply/gpio-charger.yaml b/Documentation/devicetree/bindings/power/supply/gpio-charger.yaml
index 89f8e2bcb2d7..084520bfc040 100644
--- a/Documentation/devicetree/bindings/power/supply/gpio-charger.yaml
+++ b/Documentation/devicetree/bindings/power/supply/gpio-charger.yaml
@@ -44,6 +44,10 @@ properties:
     maxItems: 32
     description: GPIOs used for current limiting
 
+  enable-gpios:
+    maxItems: 1
+    description: GPIO is used to enable/disable the charger
+
   charge-current-limit-mapping:
     description: List of tuples with current in uA and a GPIO bitmap (in
       this order). The tuples must be provided in descending order of the
@@ -68,6 +72,8 @@ anyOf:
       - charge-status-gpios
   - required:
       - charge-current-limit-gpios
+  - required:
+      - enable-gpios
 
 dependencies:
   charge-current-limit-gpios: [ charge-current-limit-mapping ]
diff --git a/drivers/power/supply/gpio-charger.c b/drivers/power/supply/gpio-charger.c
index 68212b39785b..461fec34904d 100644
--- a/drivers/power/supply/gpio-charger.c
+++ b/drivers/power/supply/gpio-charger.c
@@ -32,6 +32,7 @@ struct gpio_charger {
 	struct power_supply_desc charger_desc;
 	struct gpio_desc *gpiod;
 	struct gpio_desc *charge_status;
+	struct gpio_desc *charge_type;
 
 	struct gpio_descs *current_limit_gpios;
 	struct gpio_mapping *current_limit_map;
@@ -82,6 +83,26 @@ static int set_charge_current_limit(struct gpio_charger *gpio_charger, int val)
 	return 0;
 }
 
+static int gpio_charger_set_charge_type(struct gpio_desc *gpio_charger, int type)
+{
+	int chg_config = 0;
+
+	switch (type) {
+	case POWER_SUPPLY_CHARGE_TYPE_STANDARD:
+		chg_config = 1;
+		break;
+	case POWER_SUPPLY_CHARGE_TYPE_NONE:
+		chg_config = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	gpiod_set_value_cansleep(gpio_charger, chg_config);
+
+	return 0;
+}
+
 static int gpio_charger_get_property(struct power_supply *psy,
 		enum power_supply_property psp, union power_supply_propval *val)
 {
@@ -100,6 +121,13 @@ static int gpio_charger_get_property(struct power_supply *psy,
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 		val->intval = gpio_charger->charge_current_limit;
 		break;
+	case POWER_SUPPLY_PROP_CHARGE_TYPE:
+		if (gpiod_get_value_cansleep(gpio_charger->charge_type))
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
+		else
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+		break;
+
 	default:
 		return -EINVAL;
 	}
@@ -115,6 +143,9 @@ static int gpio_charger_set_property(struct power_supply *psy,
 	switch (psp) {
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 		return set_charge_current_limit(gpio_charger, val->intval);
+	case POWER_SUPPLY_PROP_CHARGE_TYPE:
+		return gpio_charger_set_charge_type(gpio_charger->charge_type, val->intval);
+	break;
 	default:
 		return -EINVAL;
 	}
@@ -126,6 +157,7 @@ static int gpio_charger_property_is_writeable(struct power_supply *psy,
 					      enum power_supply_property psp)
 {
 	switch (psp) {
+	case POWER_SUPPLY_PROP_CHARGE_TYPE:
 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
 		return 1;
 	default:
@@ -246,6 +278,7 @@ static enum power_supply_property gpio_charger_properties[] = {
 	POWER_SUPPLY_PROP_ONLINE,
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+	POWER_SUPPLY_PROP_CHARGE_TYPE,
 };
 
 static int gpio_charger_probe(struct platform_device *pdev)
@@ -256,6 +289,7 @@ static int gpio_charger_probe(struct platform_device *pdev)
 	struct gpio_charger *gpio_charger;
 	struct power_supply_desc *charger_desc;
 	struct gpio_desc *charge_status;
+	struct gpio_desc *charge_type;
 	int charge_status_irq;
 	int ret;
 	int num_props = 0;
@@ -304,6 +338,15 @@ static int gpio_charger_probe(struct platform_device *pdev)
 		num_props++;
 	}
 
+	charge_type = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
+	if (IS_ERR(charge_type))
+		return PTR_ERR(charge_type);
+	if (charge_type) {
+		gpio_charger->charge_type = charge_type;
+		gpio_charger_properties[num_props] = POWER_SUPPLY_PROP_CHARGE_TYPE;
+		num_props++;
+	}
+
 	charger_desc = &gpio_charger->charger_desc;
 	charger_desc->properties = gpio_charger_properties;
 	charger_desc->num_properties = num_props;
-- 
2.25.1





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux