diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c index a368d32161ee..d04318af7939 100644 --- a/drivers/power/qpnp-bms.c +++ b/drivers/power/qpnp-bms.c @@ -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, diff --git a/drivers/power/smb358-charger.c b/drivers/power/smb358-charger.c index be97c66b09e8..6d241a020693 100644 --- a/drivers/power/smb358-charger.c +++ b/drivers/power/smb358-charger.c @@ -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 diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 597dadf8d63a..9010ddb20771 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -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 {