power: qpnp-bms: add a taper charging notification

SMB chip only has a 20-30mV accuracy for VDDMAX. Since it never
meets the 10mV accuracy that BMS expects, taper charging detection
will fail. Fix this by implementing the notification from SMB
driver to BMS driver.

Change-Id: I1936aecec2c281dc98173b80db105871e6869a1d
Signed-off-by: Zhenhua Huang <zhenhuah@codeaurora.org>
This commit is contained in:
Zhenhua Huang 2014-03-31 18:09:45 +08:00
parent f22e88a13c
commit 01a74380fb
3 changed files with 37 additions and 2 deletions

View file

@ -282,6 +282,7 @@ struct qpnp_bms_chip {
u8 charge_increase;
int fcc_resolution;
bool battery_removed;
bool in_taper_charge;
struct bms_irq sw_cc_thr_irq;
struct bms_irq ocv_thr_irq;
struct qpnp_vadc_chip *vadc_dev;
@ -772,6 +773,30 @@ static int get_battery_status(struct qpnp_bms_chip *chip)
return POWER_SUPPLY_STATUS_UNKNOWN;
}
static int get_battery_charge_type(struct qpnp_bms_chip *chip)
{
union power_supply_propval ret = {0,};
int rc;
if (chip->batt_psy == NULL)
chip->batt_psy = power_supply_get_by_name("battery");
if (chip->batt_psy) {
/* if battery has been registered, use the type property */
rc = chip->batt_psy->get_property(chip->batt_psy,
POWER_SUPPLY_PROP_CHARGE_TYPE, &ret);
if (rc) {
pr_debug("Battery does not export charge type: %d\n"
, rc);
return POWER_SUPPLY_CHARGE_TYPE_NONE;
}
return ret.intval;
}
/* Default to false if the battery power supply is not registered. */
pr_debug("battery power supply is not registered\n");
return POWER_SUPPLY_CHARGE_TYPE_NONE;
}
static bool is_battery_charging(struct qpnp_bms_chip *chip)
{
return get_battery_status(chip) == POWER_SUPPLY_STATUS_CHARGING;
@ -1918,7 +1943,8 @@ static int charging_adjustments(struct qpnp_bms_chip *chip,
batt_terminal_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
if (chip->soc_at_cv == -EINVAL) {
if (batt_terminal_uv >= chip->max_voltage_uv - VDD_MAX_ERR) {
if (batt_terminal_uv >= chip->max_voltage_uv - VDD_MAX_ERR ||
chip->in_taper_charge) {
chip->soc_at_cv = soc;
chip->prev_chg_soc = soc;
chip->ibat_at_cv_ua = params->iavg_ua;
@ -3237,6 +3263,7 @@ static void charging_ended(struct qpnp_bms_chip *chip)
mutex_lock(&chip->last_ocv_uv_mutex);
chip->soc_at_cv = -EINVAL;
chip->prev_chg_soc = -EINVAL;
chip->in_taper_charge = false;
/* update the chargecycles */
if (chip->end_soc > chip->start_soc) {
@ -3368,6 +3395,11 @@ static void qpnp_bms_external_power_changed(struct power_supply *psy)
battery_insertion_check(chip);
batfet_status_check(chip);
battery_status_check(chip);
if (POWER_SUPPLY_CHARGE_TYPE_TAPER == get_battery_charge_type(chip))
chip->in_taper_charge = true;
else
chip->in_taper_charge = false;
}
static int qpnp_bms_power_get_property(struct power_supply *psy,

View file

@ -849,8 +849,10 @@ static int smb358_get_prop_charge_type(struct smb358_charger *chip)
reg &= STATUS_C_CHARGING_MASK;
if (reg == STATUS_C_FAST_CHARGING || reg == STATUS_C_TAPER_CHARGING)
if (reg == STATUS_C_FAST_CHARGING)
return POWER_SUPPLY_CHARGE_TYPE_FAST;
else if (reg == STATUS_C_TAPER_CHARGING)
return POWER_SUPPLY_CHARGE_TYPE_TAPER;
else if (reg == STATUS_C_PRE_CHARGING)
return POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
else

View file

@ -44,6 +44,7 @@ enum {
POWER_SUPPLY_CHARGE_TYPE_NONE,
POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
POWER_SUPPLY_CHARGE_TYPE_FAST,
POWER_SUPPLY_CHARGE_TYPE_TAPER,
};
enum {