power: android-battery: Add USB and AC battery power supplies
authorhongmin.son <hongmin.son@samsung.com>
Thu, 23 Aug 2012 20:11:30 +0000 (13:11 -0700)
committerArve Hjønnevåg <arve@android.com>
Mon, 1 Jul 2013 21:16:05 +0000 (14:16 -0700)
For reflecting board-level decisions on whether USB or AC charger
is connected, which may differ from charger power supply notion
of USB input path (which may be connected to an AC charger) vs.
AC input path.

Change-Id: I9d2eb446db8b4d9496ba7ce1472d0e7a4d4e24ef
[toddpoynor@google.com: refactoring]
Signed-off-by: hongmin.son <hongmin.son@samsung.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
drivers/power/android_battery.c

index cc8e62887ffbc135d33c35c8de4a6b2334029f73..39f45930388288957bde05065fdb1be433c92340 100644 (file)
@@ -46,6 +46,8 @@ struct android_bat_data {
        struct device           *dev;
 
        struct power_supply     psy_bat;
+       struct power_supply     psy_usb;
+       struct power_supply     psy_ac;
 
        struct wake_lock        monitor_wake_lock;
        struct wake_lock        charger_wake_lock;
@@ -69,6 +71,10 @@ struct android_bat_data {
        struct dentry           *debugfs_entry;
 };
 
+static char *supply_list[] = {
+       "android-battery",
+};
+
 static enum power_supply_property android_battery_props[] = {
        POWER_SUPPLY_PROP_STATUS,
        POWER_SUPPLY_PROP_HEALTH,
@@ -81,6 +87,10 @@ static enum power_supply_property android_battery_props[] = {
        POWER_SUPPLY_PROP_CURRENT_NOW,
 };
 
+static enum power_supply_property android_power_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
 static void android_bat_update_data(struct android_bat_data *battery);
 
 static char *charge_source_str(int charge_source)
@@ -146,6 +156,36 @@ static int android_bat_get_property(struct power_supply *ps,
        return 0;
 }
 
+static int android_usb_get_property(struct power_supply *ps,
+               enum power_supply_property psp,
+               union power_supply_propval *val)
+{
+       struct android_bat_data *battery = container_of(ps,
+                               struct android_bat_data, psy_usb);
+
+       if (psp != POWER_SUPPLY_PROP_ONLINE)
+               return -EINVAL;
+
+       val->intval = (battery->charge_source == CHARGE_SOURCE_USB);
+
+       return 0;
+}
+
+static int android_ac_get_property(struct power_supply *ps,
+               enum power_supply_property psp,
+               union power_supply_propval *val)
+{
+       struct android_bat_data *battery = container_of(ps,
+                               struct android_bat_data, psy_ac);
+
+       if (psp != POWER_SUPPLY_PROP_ONLINE)
+               return -EINVAL;
+
+       val->intval = (battery->charge_source == CHARGE_SOURCE_AC);
+
+       return 0;
+}
+
 static void android_bat_get_temp(struct android_bat_data *battery)
 {
        int batt_temp = 42000; /* 4.2C */
@@ -271,6 +311,9 @@ static void android_bat_charger_work(struct work_struct *work)
                break;
        }
 
+       power_supply_changed(&battery->psy_ac);
+       power_supply_changed(&battery->psy_usb);
+
        wake_lock_timeout(&battery->charger_wake_lock, HZ * 2);
 }
 
@@ -409,6 +452,22 @@ static int android_bat_probe(struct platform_device *pdev)
        battery->psy_bat.num_properties = ARRAY_SIZE(android_battery_props),
        battery->psy_bat.get_property = android_bat_get_property,
 
+       battery->psy_usb.name = "android-usb",
+       battery->psy_usb.type = POWER_SUPPLY_TYPE_USB,
+       battery->psy_usb.supplied_to = supply_list,
+       battery->psy_usb.num_supplicants = ARRAY_SIZE(supply_list),
+       battery->psy_usb.properties = android_power_props,
+       battery->psy_usb.num_properties = ARRAY_SIZE(android_power_props),
+       battery->psy_usb.get_property = android_usb_get_property,
+
+       battery->psy_ac.name = "android-ac",
+       battery->psy_ac.type = POWER_SUPPLY_TYPE_MAINS,
+       battery->psy_ac.supplied_to = supply_list,
+       battery->psy_ac.num_supplicants = ARRAY_SIZE(supply_list),
+       battery->psy_ac.properties = android_power_props,
+       battery->psy_ac.num_properties = ARRAY_SIZE(android_power_props),
+       battery->psy_ac.get_property = android_ac_get_property;
+
        battery->batt_vcell = -1;
        battery->batt_soc = -1;
 
@@ -421,7 +480,21 @@ static int android_bat_probe(struct platform_device *pdev)
        if (ret) {
                dev_err(battery->dev, "%s: failed to register psy_bat\n",
                        __func__);
-               goto err_psy_reg;
+               goto err_psy_bat_reg;
+       }
+
+       ret = power_supply_register(&pdev->dev, &battery->psy_usb);
+       if (ret) {
+               dev_err(battery->dev, "%s: failed to register psy_usb\n",
+                               __func__);
+               goto err_psy_usb_reg;
+       }
+
+       ret = power_supply_register(&pdev->dev, &battery->psy_ac);
+       if (ret) {
+               dev_err(battery->dev, "%s: failed to register psy_ac\n",
+                               __func__);
+               goto err_psy_ac_reg;
        }
 
        battery->monitor_wqueue =
@@ -462,8 +535,12 @@ static int android_bat_probe(struct platform_device *pdev)
        return 0;
 
 err_wq:
+       power_supply_unregister(&battery->psy_ac);
+err_psy_ac_reg:
+       power_supply_unregister(&battery->psy_usb);
+err_psy_usb_reg:
        power_supply_unregister(&battery->psy_bat);
-err_psy_reg:
+err_psy_bat_reg:
        wake_lock_destroy(&battery->monitor_wake_lock);
        wake_lock_destroy(&battery->charger_wake_lock);
 err_pdata: