Loading drivers/power/supply/qcom/qg-core.h +2 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ struct qpnp_qg { u32 esr_last; ktime_t last_user_update_time; ktime_t last_fifo_update_time; unsigned long last_maint_soc_update_time; /* soc params */ int catch_up_soc; Loading @@ -145,6 +146,7 @@ struct qpnp_qg { int full_soc; int sys_soc; int last_adj_ssoc; int recharge_soc; struct alarm alarm_timer; u32 sdam_data[SDAM_MAX]; Loading drivers/power/supply/qcom/qg-soc.c +40 −7 Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ module_param_named( soc_cold_interval_ms, qg_delta_soc_cold_interval_ms, int, 0600 ); static int qg_maint_soc_update_ms = 120000; module_param_named( maint_soc_update_ms, qg_maint_soc_update_ms, int, 0600 ); int qg_adjust_sys_soc(struct qpnp_qg *chip) { int soc, vbat_uv, rc; Loading Loading @@ -93,10 +98,11 @@ static void get_next_update_time(struct qpnp_qg *chip) /* Lower the delta soc interval by half at cold */ rc = qg_get_battery_temp(chip, &batt_temp); if (rc < 0) pr_err("Failed to read battery temperature rc=%d\n", rc); else if (batt_temp < chip->dt.cold_temp_threshold) if (!rc && batt_temp < chip->dt.cold_temp_threshold) min_delta_soc_interval_ms = qg_delta_soc_cold_interval_ms; else if (chip->maint_soc > 0 && chip->maint_soc >= chip->recharge_soc) /* if in maintenance mode scale slower */ min_delta_soc_interval_ms = qg_maint_soc_update_ms; if (!min_delta_soc_interval_ms) min_delta_soc_interval_ms = 1000; /* 1 second */ Loading Loading @@ -135,9 +141,34 @@ static bool is_scaling_required(struct qpnp_qg *chip) return true; } static bool maint_soc_timeout(struct qpnp_qg *chip) { unsigned long now; int rc; if (chip->maint_soc < 0) return false; rc = get_rtc_time(&now); if (rc < 0) return true; /* Do not scale if we have dropped below recharge-soc */ if (chip->maint_soc < chip->recharge_soc) return true; if ((now - chip->last_maint_soc_update_time) >= (qg_maint_soc_update_ms / 1000)) { chip->last_maint_soc_update_time = now; return true; } return false; } static void update_msoc(struct qpnp_qg *chip) { int rc = 0, batt_temp = 0, batt_soc_32bit = 0; int rc = 0, sdam_soc, batt_temp = 0, batt_soc_32bit = 0; bool usb_present = is_usb_present(chip); if (chip->catch_up_soc > chip->msoc) { Loading @@ -150,7 +181,8 @@ static void update_msoc(struct qpnp_qg *chip) } chip->msoc = CAP(0, 100, chip->msoc); if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc) { if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc && maint_soc_timeout(chip)) { chip->maint_soc -= chip->dt.delta_soc; chip->maint_soc = CAP(0, 100, chip->maint_soc); } Loading @@ -165,8 +197,9 @@ static void update_msoc(struct qpnp_qg *chip) pr_err("Failed to update MSOC register rc=%d\n", rc); /* update SDAM with the new MSOC */ chip->sdam_data[SDAM_SOC] = chip->msoc; rc = qg_sdam_write(SDAM_SOC, chip->msoc); sdam_soc = (chip->maint_soc > 0) ? chip->maint_soc : chip->msoc; chip->sdam_data[SDAM_SOC] = sdam_soc; rc = qg_sdam_write(SDAM_SOC, sdam_soc); if (rc < 0) pr_err("Failed to update SDAM with MSOC rc=%d\n", rc); Loading drivers/power/supply/qcom/qpnp-qg.c +36 −16 Original line number Diff line number Diff line Loading @@ -1858,9 +1858,11 @@ static int qg_charge_full_update(struct qpnp_qg *chip) recharge_soc = DEFAULT_RECHARGE_SOC; } recharge_soc = prop.intval; chip->recharge_soc = recharge_soc; qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d\n", chip->msoc, health, chip->charge_full); qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d charge_done=%d\n", chip->msoc, health, chip->charge_full, chip->charge_done); if (chip->charge_done && !chip->charge_full) { if (chip->msoc >= 99 && health == POWER_SUPPLY_HEALTH_GOOD) { chip->charge_full = true; Loading @@ -1871,10 +1873,18 @@ static int qg_charge_full_update(struct qpnp_qg *chip) qg_dbg(chip, QG_DEBUG_STATUS, "Terminated charging @ msoc=%d\n", chip->msoc); } } else if ((!chip->charge_done || chip->msoc < recharge_soc) } else if ((!chip->charge_done || chip->msoc <= recharge_soc) && chip->charge_full) { if (chip->wa_flags & QG_RECHARGE_SOC_WA) { bool usb_present = is_usb_present(chip); /* * force a recharge only if SOC <= recharge SOC and * we have not started charging. */ if ((chip->wa_flags & QG_RECHARGE_SOC_WA) && usb_present && chip->msoc <= recharge_soc && chip->charge_status != POWER_SUPPLY_STATUS_CHARGING) { /* Force recharge */ prop.intval = 0; rc = power_supply_set_property(chip->batt_psy, Loading @@ -1882,23 +1892,33 @@ static int qg_charge_full_update(struct qpnp_qg *chip) if (rc < 0) pr_err("Failed to force recharge rc=%d\n", rc); else qg_dbg(chip, QG_DEBUG_STATUS, "Forced recharge\n"); qg_dbg(chip, QG_DEBUG_STATUS, "Forced recharge\n"); } if (chip->charge_done) return 0; /* wait for recharge */ /* * If recharge or discharge has started and * if linearize soc dtsi property defined * scale msoc from 100% for better UX. * If SOC has indeed dropped below recharge-SOC or * the USB is removed, if linearize-soc is set scale * msoc from 100% for better UX. */ if (chip->dt.linearize_soc && chip->msoc < 99) { if (chip->msoc < recharge_soc || !usb_present) { if (chip->dt.linearize_soc) { get_rtc_time(&chip->last_maint_soc_update_time); chip->maint_soc = FULL_SOC; qg_scale_soc(chip, false); } chip->charge_full = false; qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full (1->0)\n", chip->msoc, recharge_soc); chip->charge_full = false; } else { /* continue with charge_full state */ qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full=%d usb_present=%d\n", chip->msoc, recharge_soc, chip->charge_full, usb_present); } } out: return 0; Loading Loading
drivers/power/supply/qcom/qg-core.h +2 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ struct qpnp_qg { u32 esr_last; ktime_t last_user_update_time; ktime_t last_fifo_update_time; unsigned long last_maint_soc_update_time; /* soc params */ int catch_up_soc; Loading @@ -145,6 +146,7 @@ struct qpnp_qg { int full_soc; int sys_soc; int last_adj_ssoc; int recharge_soc; struct alarm alarm_timer; u32 sdam_data[SDAM_MAX]; Loading
drivers/power/supply/qcom/qg-soc.c +40 −7 Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ module_param_named( soc_cold_interval_ms, qg_delta_soc_cold_interval_ms, int, 0600 ); static int qg_maint_soc_update_ms = 120000; module_param_named( maint_soc_update_ms, qg_maint_soc_update_ms, int, 0600 ); int qg_adjust_sys_soc(struct qpnp_qg *chip) { int soc, vbat_uv, rc; Loading Loading @@ -93,10 +98,11 @@ static void get_next_update_time(struct qpnp_qg *chip) /* Lower the delta soc interval by half at cold */ rc = qg_get_battery_temp(chip, &batt_temp); if (rc < 0) pr_err("Failed to read battery temperature rc=%d\n", rc); else if (batt_temp < chip->dt.cold_temp_threshold) if (!rc && batt_temp < chip->dt.cold_temp_threshold) min_delta_soc_interval_ms = qg_delta_soc_cold_interval_ms; else if (chip->maint_soc > 0 && chip->maint_soc >= chip->recharge_soc) /* if in maintenance mode scale slower */ min_delta_soc_interval_ms = qg_maint_soc_update_ms; if (!min_delta_soc_interval_ms) min_delta_soc_interval_ms = 1000; /* 1 second */ Loading Loading @@ -135,9 +141,34 @@ static bool is_scaling_required(struct qpnp_qg *chip) return true; } static bool maint_soc_timeout(struct qpnp_qg *chip) { unsigned long now; int rc; if (chip->maint_soc < 0) return false; rc = get_rtc_time(&now); if (rc < 0) return true; /* Do not scale if we have dropped below recharge-soc */ if (chip->maint_soc < chip->recharge_soc) return true; if ((now - chip->last_maint_soc_update_time) >= (qg_maint_soc_update_ms / 1000)) { chip->last_maint_soc_update_time = now; return true; } return false; } static void update_msoc(struct qpnp_qg *chip) { int rc = 0, batt_temp = 0, batt_soc_32bit = 0; int rc = 0, sdam_soc, batt_temp = 0, batt_soc_32bit = 0; bool usb_present = is_usb_present(chip); if (chip->catch_up_soc > chip->msoc) { Loading @@ -150,7 +181,8 @@ static void update_msoc(struct qpnp_qg *chip) } chip->msoc = CAP(0, 100, chip->msoc); if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc) { if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc && maint_soc_timeout(chip)) { chip->maint_soc -= chip->dt.delta_soc; chip->maint_soc = CAP(0, 100, chip->maint_soc); } Loading @@ -165,8 +197,9 @@ static void update_msoc(struct qpnp_qg *chip) pr_err("Failed to update MSOC register rc=%d\n", rc); /* update SDAM with the new MSOC */ chip->sdam_data[SDAM_SOC] = chip->msoc; rc = qg_sdam_write(SDAM_SOC, chip->msoc); sdam_soc = (chip->maint_soc > 0) ? chip->maint_soc : chip->msoc; chip->sdam_data[SDAM_SOC] = sdam_soc; rc = qg_sdam_write(SDAM_SOC, sdam_soc); if (rc < 0) pr_err("Failed to update SDAM with MSOC rc=%d\n", rc); Loading
drivers/power/supply/qcom/qpnp-qg.c +36 −16 Original line number Diff line number Diff line Loading @@ -1858,9 +1858,11 @@ static int qg_charge_full_update(struct qpnp_qg *chip) recharge_soc = DEFAULT_RECHARGE_SOC; } recharge_soc = prop.intval; chip->recharge_soc = recharge_soc; qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d\n", chip->msoc, health, chip->charge_full); qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d charge_done=%d\n", chip->msoc, health, chip->charge_full, chip->charge_done); if (chip->charge_done && !chip->charge_full) { if (chip->msoc >= 99 && health == POWER_SUPPLY_HEALTH_GOOD) { chip->charge_full = true; Loading @@ -1871,10 +1873,18 @@ static int qg_charge_full_update(struct qpnp_qg *chip) qg_dbg(chip, QG_DEBUG_STATUS, "Terminated charging @ msoc=%d\n", chip->msoc); } } else if ((!chip->charge_done || chip->msoc < recharge_soc) } else if ((!chip->charge_done || chip->msoc <= recharge_soc) && chip->charge_full) { if (chip->wa_flags & QG_RECHARGE_SOC_WA) { bool usb_present = is_usb_present(chip); /* * force a recharge only if SOC <= recharge SOC and * we have not started charging. */ if ((chip->wa_flags & QG_RECHARGE_SOC_WA) && usb_present && chip->msoc <= recharge_soc && chip->charge_status != POWER_SUPPLY_STATUS_CHARGING) { /* Force recharge */ prop.intval = 0; rc = power_supply_set_property(chip->batt_psy, Loading @@ -1882,23 +1892,33 @@ static int qg_charge_full_update(struct qpnp_qg *chip) if (rc < 0) pr_err("Failed to force recharge rc=%d\n", rc); else qg_dbg(chip, QG_DEBUG_STATUS, "Forced recharge\n"); qg_dbg(chip, QG_DEBUG_STATUS, "Forced recharge\n"); } if (chip->charge_done) return 0; /* wait for recharge */ /* * If recharge or discharge has started and * if linearize soc dtsi property defined * scale msoc from 100% for better UX. * If SOC has indeed dropped below recharge-SOC or * the USB is removed, if linearize-soc is set scale * msoc from 100% for better UX. */ if (chip->dt.linearize_soc && chip->msoc < 99) { if (chip->msoc < recharge_soc || !usb_present) { if (chip->dt.linearize_soc) { get_rtc_time(&chip->last_maint_soc_update_time); chip->maint_soc = FULL_SOC; qg_scale_soc(chip, false); } chip->charge_full = false; qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full (1->0)\n", chip->msoc, recharge_soc); chip->charge_full = false; } else { /* continue with charge_full state */ qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full=%d usb_present=%d\n", chip->msoc, recharge_soc, chip->charge_full, usb_present); } } out: return 0; Loading