Loading drivers/power/supply/qcom/qpnp-fg-gen4.c +75 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/of_batterydata.h> #include <linux/platform_device.h> #include <linux/iio/consumer.h> #include <linux/qpnp/qpnp-pbs.h> #include <linux/qpnp/qpnp-revid.h> #include <linux/thermal.h> #include "fg-core.h" Loading Loading @@ -263,6 +264,7 @@ struct fg_gen4_chip { struct cycle_counter *counter; struct cap_learning *cl; struct ttf *ttf; struct device_node *pbs_dev; struct nvmem_device *fg_nvmem; struct votable *delta_esr_irq_en_votable; struct votable *pl_disable_votable; Loading Loading @@ -298,6 +300,7 @@ struct fg_gen4_chip { int vbatt_res; int scale_timer; int current_now; int calib_level; bool first_profile_load; bool ki_coeff_dischg_en; bool slope_limit_en; Loading Loading @@ -1124,6 +1127,61 @@ static int fg_gen4_get_prop_soc_scale(struct fg_gen4_chip *chip) return rc; } #define SDAM1_MEM_124_REG 0xB0BC static int fg_gen4_set_calibrate_level(struct fg_gen4_chip *chip, int val) { struct fg_dev *fg = &chip->fg; int rc; u8 buf; if (!chip->pbs_dev) return -ENODEV; if (val < 0 || val > 0x83) { pr_err("Incorrect calibration level %d\n", val); return -EINVAL; } if (val == chip->calib_level) return 0; buf = (u8)val; rc = fg_write(fg, SDAM1_MEM_124_REG, &buf, 1); if (rc < 0) { pr_err("Error in writing to 0x%04X, rc=%d\n", SDAM1_MEM_124_REG, rc); return rc; } buf = 0x1; rc = qpnp_pbs_trigger_event(chip->pbs_dev, buf); if (rc < 0) { pr_err("Error in triggering PBS rc=%d\n", rc); return rc; } rc = fg_read(fg, SDAM1_MEM_124_REG, &buf, 1); if (rc < 0) { pr_err("Error in reading from 0x%04X, rc=%d\n", SDAM1_MEM_124_REG, rc); return rc; } if (buf) { pr_err("Incorrect return value: %x\n", buf); return -EINVAL; } if (is_parallel_charger_available(fg)) { cancel_work_sync(&chip->pl_current_en_work); schedule_work(&chip->pl_current_en_work); } chip->calib_level = val; fg_dbg(fg, FG_POWER_SUPPLY, "Set calib_level to %x\n", val); return 0; } /* ALG callback functions below */ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) Loading Loading @@ -4387,6 +4445,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_POWER_AVG: rc = fg_gen4_get_power(chip, &pval->intval, true); break; case POWER_SUPPLY_PROP_CALIBRATE: pval->intval = chip->calib_level; break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; Loading Loading @@ -4476,6 +4537,9 @@ static int fg_psy_set_property(struct power_supply *psy, chip->batt_age_level = pval->intval; schedule_delayed_work(&fg->profile_load_work, 0); break; case POWER_SUPPLY_PROP_CALIBRATE: rc = fg_gen4_set_calibrate_level(chip, pval->intval); break; default: break; } Loading @@ -4495,6 +4559,7 @@ static int fg_property_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_SOH: case POWER_SUPPLY_PROP_CLEAR_SOH: case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: case POWER_SUPPLY_PROP_CALIBRATE: return 1; default: break; Loading Loading @@ -4539,6 +4604,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, POWER_SUPPLY_PROP_SCALE_MODE_EN, POWER_SUPPLY_PROP_CALIBRATE, }; static const struct power_supply_desc fg_psy_desc = { Loading Loading @@ -5735,6 +5801,14 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) if (rc < 0) return rc; if (of_find_property(node, "qcom,pmic-pbs", NULL)) { chip->pbs_dev = of_parse_phandle(node, "qcom,pmic-pbs", 0); if (!chip->pbs_dev) { pr_err("Missing qcom,pmic-pbs property\n"); return -ENODEV; } } rc = fg_gen4_parse_nvmem_dt(chip); if (rc < 0) return rc; Loading Loading @@ -5944,6 +6018,7 @@ static int fg_gen4_probe(struct platform_device *pdev) chip->ki_coeff_full_soc[0] = -EINVAL; chip->ki_coeff_full_soc[1] = -EINVAL; chip->esr_soh_cycle_count = -EINVAL; chip->calib_level = -EINVAL; fg->regmap = dev_get_regmap(fg->dev->parent, NULL); if (!fg->regmap) { dev_err(fg->dev, "Parent regmap is unavailable\n"); Loading Loading
drivers/power/supply/qcom/qpnp-fg-gen4.c +75 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/of_batterydata.h> #include <linux/platform_device.h> #include <linux/iio/consumer.h> #include <linux/qpnp/qpnp-pbs.h> #include <linux/qpnp/qpnp-revid.h> #include <linux/thermal.h> #include "fg-core.h" Loading Loading @@ -263,6 +264,7 @@ struct fg_gen4_chip { struct cycle_counter *counter; struct cap_learning *cl; struct ttf *ttf; struct device_node *pbs_dev; struct nvmem_device *fg_nvmem; struct votable *delta_esr_irq_en_votable; struct votable *pl_disable_votable; Loading Loading @@ -298,6 +300,7 @@ struct fg_gen4_chip { int vbatt_res; int scale_timer; int current_now; int calib_level; bool first_profile_load; bool ki_coeff_dischg_en; bool slope_limit_en; Loading Loading @@ -1124,6 +1127,61 @@ static int fg_gen4_get_prop_soc_scale(struct fg_gen4_chip *chip) return rc; } #define SDAM1_MEM_124_REG 0xB0BC static int fg_gen4_set_calibrate_level(struct fg_gen4_chip *chip, int val) { struct fg_dev *fg = &chip->fg; int rc; u8 buf; if (!chip->pbs_dev) return -ENODEV; if (val < 0 || val > 0x83) { pr_err("Incorrect calibration level %d\n", val); return -EINVAL; } if (val == chip->calib_level) return 0; buf = (u8)val; rc = fg_write(fg, SDAM1_MEM_124_REG, &buf, 1); if (rc < 0) { pr_err("Error in writing to 0x%04X, rc=%d\n", SDAM1_MEM_124_REG, rc); return rc; } buf = 0x1; rc = qpnp_pbs_trigger_event(chip->pbs_dev, buf); if (rc < 0) { pr_err("Error in triggering PBS rc=%d\n", rc); return rc; } rc = fg_read(fg, SDAM1_MEM_124_REG, &buf, 1); if (rc < 0) { pr_err("Error in reading from 0x%04X, rc=%d\n", SDAM1_MEM_124_REG, rc); return rc; } if (buf) { pr_err("Incorrect return value: %x\n", buf); return -EINVAL; } if (is_parallel_charger_available(fg)) { cancel_work_sync(&chip->pl_current_en_work); schedule_work(&chip->pl_current_en_work); } chip->calib_level = val; fg_dbg(fg, FG_POWER_SUPPLY, "Set calib_level to %x\n", val); return 0; } /* ALG callback functions below */ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) Loading Loading @@ -4387,6 +4445,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_POWER_AVG: rc = fg_gen4_get_power(chip, &pval->intval, true); break; case POWER_SUPPLY_PROP_CALIBRATE: pval->intval = chip->calib_level; break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; Loading Loading @@ -4476,6 +4537,9 @@ static int fg_psy_set_property(struct power_supply *psy, chip->batt_age_level = pval->intval; schedule_delayed_work(&fg->profile_load_work, 0); break; case POWER_SUPPLY_PROP_CALIBRATE: rc = fg_gen4_set_calibrate_level(chip, pval->intval); break; default: break; } Loading @@ -4495,6 +4559,7 @@ static int fg_property_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_SOH: case POWER_SUPPLY_PROP_CLEAR_SOH: case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: case POWER_SUPPLY_PROP_CALIBRATE: return 1; default: break; Loading Loading @@ -4539,6 +4604,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, POWER_SUPPLY_PROP_SCALE_MODE_EN, POWER_SUPPLY_PROP_CALIBRATE, }; static const struct power_supply_desc fg_psy_desc = { Loading Loading @@ -5735,6 +5801,14 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip) if (rc < 0) return rc; if (of_find_property(node, "qcom,pmic-pbs", NULL)) { chip->pbs_dev = of_parse_phandle(node, "qcom,pmic-pbs", 0); if (!chip->pbs_dev) { pr_err("Missing qcom,pmic-pbs property\n"); return -ENODEV; } } rc = fg_gen4_parse_nvmem_dt(chip); if (rc < 0) return rc; Loading Loading @@ -5944,6 +6018,7 @@ static int fg_gen4_probe(struct platform_device *pdev) chip->ki_coeff_full_soc[0] = -EINVAL; chip->ki_coeff_full_soc[1] = -EINVAL; chip->esr_soh_cycle_count = -EINVAL; chip->calib_level = -EINVAL; fg->regmap = dev_get_regmap(fg->dev->parent, NULL); if (!fg->regmap) { dev_err(fg->dev, "Parent regmap is unavailable\n"); Loading