This patch adds the support to use power supply attributes registration mechanism for battery properties. This will be useful if the platform has a main/primary battery and it relies on smb347 driver to get some critical battery attributes.
Anton, I have to rework on this patch once we get an agreement on the power supply attribute sources registration. Signed-off-by: Ramakrishna Pallala <ramakrishna.pall...@intel.com> --- drivers/power/smb347-charger.c | 124 +++++++++++++++++++++++++++++----- include/linux/power/smb347-charger.h | 1 + 2 files changed, 108 insertions(+), 17 deletions(-) diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c index 332dd01..b232453 100644 --- a/drivers/power/smb347-charger.c +++ b/drivers/power/smb347-charger.c @@ -136,6 +136,7 @@ struct smb347_charger { struct power_supply mains; struct power_supply usb; struct power_supply battery; + struct power_supply_attr_source battery_attr; bool mains_online; bool usb_online; bool charging_enabled; @@ -731,7 +732,8 @@ static irqreturn_t smb347_interrupt(int irq, void *data) dev_err(smb->dev, "error in charger, disabling charging\n"); smb347_charging_disable(smb); - power_supply_changed(&smb->battery); + if (smb->pdata->use_battery) + power_supply_changed(&smb->battery); handled = true; } @@ -741,7 +743,8 @@ static irqreturn_t smb347_interrupt(int irq, void *data) * disabled by the hardware. */ if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { - if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) + if ((irqstat_c & IRQSTAT_C_TERMINATION_STAT) && + smb->pdata->use_battery) power_supply_changed(&smb->battery); handled = true; } @@ -1061,6 +1064,80 @@ static int smb347_battery_get_property(struct power_supply *psy, return 0; } +static int smb347_battery_get_attr_property( + struct power_supply_attr_source *psy_attr, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct smb347_charger *smb = container_of(psy_attr, + struct smb347_charger, battery_attr); + const struct smb347_charger_platform_data *pdata = smb->pdata; + int ret; + + ret = smb347_update_ps_status(smb); + if (ret < 0) + return ret; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + if (!smb347_is_ps_online(smb)) { + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + break; + } + if (smb347_charging_status(smb)) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else + val->intval = POWER_SUPPLY_STATUS_FULL; + break; + + case POWER_SUPPLY_PROP_CHARGE_TYPE: + if (!smb347_is_ps_online(smb)) + return -ENODATA; + + /* + * We handle trickle and pre-charging the same, and taper + * and none the same. + */ + switch (smb347_charging_status(smb)) { + case 1: + val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; + break; + case 2: + val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; + break; + default: + val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; + break; + } + break; + + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = pdata->battery_info.technology; + break; + + case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: + val->intval = pdata->battery_info.voltage_min_design; + break; + + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + val->intval = pdata->battery_info.voltage_max_design; + break; + + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = pdata->battery_info.charge_full_design; + break; + + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = pdata->battery_info.name; + break; + + default: + return -EINVAL; + } + + return 0; +} + static enum power_supply_property smb347_battery_properties[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_CHARGE_TYPE, @@ -1184,20 +1261,30 @@ static int smb347_probe(struct i2c_client *client, } } - smb->battery.name = "smb347-battery"; - smb->battery.type = POWER_SUPPLY_TYPE_BATTERY; - smb->battery.get_property = smb347_battery_get_property; - smb->battery.properties = smb347_battery_properties; - smb->battery.num_properties = ARRAY_SIZE(smb347_battery_properties); - - - ret = power_supply_register(dev, &smb->battery); - if (ret < 0) { - if (smb->pdata->use_usb) - power_supply_unregister(&smb->usb); - if (smb->pdata->use_mains) - power_supply_unregister(&smb->mains); - return ret; + if (smb->pdata->use_battery) { + smb->battery.name = "smb347-battery"; + smb->battery.type = POWER_SUPPLY_TYPE_BATTERY; + smb->battery.get_property = smb347_battery_get_property; + smb->battery.properties = smb347_battery_properties; + smb->battery.num_properties = + ARRAY_SIZE(smb347_battery_properties); + ret = power_supply_register(dev, &smb->battery); + if (ret < 0) { + if (smb->pdata->use_usb) + power_supply_unregister(&smb->usb); + if (smb->pdata->use_mains) + power_supply_unregister(&smb->mains); + return ret; + } + } else { + smb->battery_attr.name = "smb347-battery"; + smb->battery_attr.type = POWER_SUPPLY_TYPE_BATTERY; + smb->battery_attr.get_property = + smb347_battery_get_attr_property; + ret = power_supply_attributes_register(dev, &smb->battery_attr); + if (ret < 0) + dev_warn(dev, + "power supply attr register failed: %d\n", ret); } /* @@ -1227,7 +1314,10 @@ static int smb347_remove(struct i2c_client *client) gpio_free(smb->pdata->irq_gpio); } - power_supply_unregister(&smb->battery); + if (smb->pdata->use_battery) + power_supply_unregister(&smb->battery); + else + power_supply_attributes_unregister(&smb->battery_attr); if (smb->pdata->use_usb) power_supply_unregister(&smb->usb); if (smb->pdata->use_mains) diff --git a/include/linux/power/smb347-charger.h b/include/linux/power/smb347-charger.h index b3cb20d..4bccd01 100644 --- a/include/linux/power/smb347-charger.h +++ b/include/linux/power/smb347-charger.h @@ -109,6 +109,7 @@ struct smb347_charger_platform_data { unsigned int charge_current_compensation; bool use_mains; bool use_usb; + bool use_battery; bool use_usb_otg; int irq_gpio; enum smb347_chg_enable enable_control; -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/