From 3c4e6212379a4321ee9904dbb9dd2f57bad32caa Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 18 Oct 2021 17:38:30 -0700 Subject: [PATCH] power: supply: qti_battery_charger: Add support for thermal-mitigation-step Currently, thermal mitigation is supported with "qcom,thermal-mitigation" property where different fast charging current(FCC) levels can be specified as an array. This would be applied when thermal SW votes for a mitigation level through CHARGE_CONTROL_LIMIT property. For some boards, the number of levels can be simply obtained by specifying a fixed FCC tep as the maximum FCC supported is already obtained from the charger FW. Add Support for this via "qcom,thermal-mitigation-step" property. With this, we don't have to override "qcom,thermal-mitigation" property for battery type variation (1S vs 2S). Change-Id: I16af90545924d8880a6c49d02935b4d21a86c417 Signed-off-by: Anjelique Melendez --- drivers/power/supply/qti_battery_charger.c | 93 ++++++++++++++-------- 1 file changed, 61 insertions(+), 32 deletions(-) diff --git a/drivers/power/supply/qti_battery_charger.c b/drivers/power/supply/qti_battery_charger.c index 421d11e93dbd..cb82d08dc909 100644 --- a/drivers/power/supply/qti_battery_charger.c +++ b/drivers/power/supply/qti_battery_charger.c @@ -245,6 +245,7 @@ struct battery_chg_dev { u32 restrict_fcc_ua; u32 last_fcc_ua; u32 usb_icl_ua; + u32 thermal_fcc_step; bool restrict_chg_en; /* To track the driver initialization status */ bool initialized; @@ -1056,7 +1057,12 @@ static int battery_psy_set_charge_current(struct battery_chg_dev *bcdev, if (val < 0 || val > bcdev->num_thermal_levels) return -EINVAL; - fcc_ua = bcdev->thermal_levels[val]; + if (bcdev->thermal_fcc_step == 0) + fcc_ua = bcdev->thermal_levels[val]; + else + fcc_ua = bcdev->psy_list[PSY_TYPE_BATTERY].prop[BATT_CHG_CTRL_LIM_MAX] + - (bcdev->thermal_fcc_step * val); + prev_fcc_ua = bcdev->thermal_fcc_ua; bcdev->thermal_fcc_ua = fcc_ua; @@ -1851,12 +1857,6 @@ static int battery_chg_parse_dt(struct battery_chg_dev *bcdev) of_property_read_u32(node, "qcom,shutdown-voltage", &bcdev->shutdown_volt_mv); - rc = of_property_count_elems_of_size(node, "qcom,thermal-mitigation", - sizeof(u32)); - if (rc <= 0) - return 0; - - len = rc; rc = read_property_id(bcdev, pst, BATT_CHG_CTRL_LIM_MAX); if (rc < 0) { @@ -1865,41 +1865,70 @@ static int battery_chg_parse_dt(struct battery_chg_dev *bcdev) return rc; } - prev = pst->prop[BATT_CHG_CTRL_LIM_MAX]; + rc = of_property_count_elems_of_size(node, "qcom,thermal-mitigation", + sizeof(u32)); + if (rc <= 0) { + + rc = of_property_read_u32(node, "qcom,thermal-mitigation-step", + &val); - for (i = 0; i < len; i++) { - rc = of_property_read_u32_index(node, "qcom,thermal-mitigation", - i, &val); if (rc < 0) - return rc; - - if (val > prev) { - pr_err("Thermal levels should be in descending order\n"); - bcdev->num_thermal_levels = -EINVAL; return 0; + + if (val < 500000 || val >= pst->prop[BATT_CHG_CTRL_LIM_MAX]) { + pr_err("thermal_fcc_step %d is invalid\n", val); + return -EINVAL; } - prev = val; - } + bcdev->thermal_fcc_step = val; + len = pst->prop[BATT_CHG_CTRL_LIM_MAX] / bcdev->thermal_fcc_step; - bcdev->thermal_levels = devm_kcalloc(bcdev->dev, len + 1, - sizeof(*bcdev->thermal_levels), - GFP_KERNEL); - if (!bcdev->thermal_levels) - return -ENOMEM; + /* + * FCC values must be above 500mA. + * Since len is truncated when calculated, check and adjust len so + * that the above requirement is met. + */ + if (pst->prop[BATT_CHG_CTRL_LIM_MAX] - (bcdev->thermal_fcc_step * len) < 500000) + len = len - 1; + } else { + bcdev->thermal_fcc_step = 0; + len = rc; + prev = pst->prop[BATT_CHG_CTRL_LIM_MAX]; - /* - * Element 0 is for normal charging current. Elements from index 1 - * onwards is for thermal mitigation charging currents. - */ + for (i = 0; i < len; i++) { + rc = of_property_read_u32_index(node, "qcom,thermal-mitigation", + i, &val); + if (rc < 0) + return rc; - bcdev->thermal_levels[0] = pst->prop[BATT_CHG_CTRL_LIM_MAX]; + if (val > prev) { + pr_err("Thermal levels should be in descending order\n"); + bcdev->num_thermal_levels = -EINVAL; + return 0; + } - rc = of_property_read_u32_array(node, "qcom,thermal-mitigation", + prev = val; + } + + bcdev->thermal_levels = devm_kcalloc(bcdev->dev, len + 1, + sizeof(*bcdev->thermal_levels), + GFP_KERNEL); + if (!bcdev->thermal_levels) + return -ENOMEM; + + /* + * Element 0 is for normal charging current. Elements from index 1 + * onwards is for thermal mitigation charging currents. + */ + + bcdev->thermal_levels[0] = pst->prop[BATT_CHG_CTRL_LIM_MAX]; + + rc = of_property_read_u32_array(node, "qcom,thermal-mitigation", &bcdev->thermal_levels[1], len); - if (rc < 0) { - pr_err("Error in reading qcom,thermal-mitigation, rc=%d\n", rc); - return rc; + if (rc < 0) { + pr_err("Error in reading qcom,thermal-mitigation, rc=%d\n", rc); + return rc; + } } bcdev->num_thermal_levels = len;