/** * smb347_charging_status - returns status of charging * @smb: pointer to smb347 charger instance * * Function returns charging status. %0 means no charging is in progress, * %1 means pre-charging, %2 fast-charging and %3 taper-charging. */ static int smb347_charging_status(struct smb347_charger *smb) { int ret; if (!smb347_is_online(smb)) return 0; ret = smb347_read(smb, STAT_C); if (ret < 0) return 0; return (ret & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT; }
static int smb347_update_online(struct smb347_charger *smb) { int ret; if (smb347_is_online(smb)) { ret = smb347_charging_enable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to enable charging\n"); } else { ret = smb347_charging_disable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to disable charging\n"); } return ret; }
static int smb347_update_online(struct smb347_charger *smb) { int ret; /* * Depending on whether valid power source is connected or not, we * disable or enable the charging. We do it manually because it * depends on how the platform has configured the valid inputs. */ if (smb347_is_online(smb)) { ret = smb347_charging_enable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to enable charging\n"); } else { ret = smb347_charging_disable(smb); if (ret < 0) dev_err(&smb->client->dev, "failed to disable charging\n"); } return ret; }
static int smb347_battery_get_property(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) { struct smb347_charger *smb = container_of(psy, struct smb347_charger, battery); const struct smb347_charger_platform_data *pdata = smb->pdata; int ret; ret = smb347_update_status(smb); if (ret < 0) return ret; if (ret > 0) { smb347_update_online(smb); power_supply_changed(&smb->mains); power_supply_changed(&smb->usb); } switch (prop) { case POWER_SUPPLY_PROP_STATUS: if (!smb347_is_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_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_VOLTAGE_NOW: if (!smb347_is_online(smb)) return -ENODATA; ret = smb347_read(smb, STAT_A); if (ret < 0) return ret; ret &= STAT_A_FLOAT_VOLTAGE_MASK; if (ret > 0x3d) ret = 0x3d; val->intval = 3500000 + ret * 20000; break; case POWER_SUPPLY_PROP_CURRENT_NOW: if (!smb347_is_online(smb)) return -ENODATA; ret = smb347_read(smb, STAT_B); if (ret < 0) return ret; /* * The current value is composition of FCC and PCC values * and we can detect which table to use from bit 5. */ if (ret & 0x20) { val->intval = hw_to_current(fcc_tbl, ARRAY_SIZE(fcc_tbl), ret & 7); } else { ret >>= 3; val->intval = hw_to_current(pcc_tbl, ARRAY_SIZE(pcc_tbl), ret & 7); } 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; }