Message ID | 20240530-max77693-charger-extcon-v1-5-dc2a9e5bdf30@gmail.com |
---|---|
State | New |
Headers | show |
Series | power: supply: max77693: Toggle charging/OTG based on extcon status | expand |
On 30/05/2024 10:55, Artur Weber wrote: > There are two charger current limit registers: > > - Fast charge current limit (which controls current going from the > charger to the battery); > - CHGIN input current limit (which controls current going into the > charger through the cable, and is managed by the CHARGER regulator). > > + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: > + ret = max77693_get_input_current_limit(chg, &val->intval); > + break; > + case POWER_SUPPLY_PROP_CURRENT_MAX: > + ret = max77693_get_fast_charge_current(regmap, &val->intval); > + break; > case POWER_SUPPLY_PROP_MODEL_NAME: > val->strval = max77693_charger_model; > break; > @@ -680,6 +727,11 @@ static int max77693_charger_probe(struct platform_device *pdev) > chg->dev = &pdev->dev; > chg->max77693 = max77693; > > + chg->regu = devm_regulator_get(chg->dev, "CHARGER"); > + if (IS_ERR(chg->regu)) > + return dev_err_probe(&pdev->dev, PTR_ERR(chg->regu), > + "failed to get charger regulator\n");\ This breaks users... and where is the binding? Best regards, Krzysztof
On 31.05.2024 11:38, Krzysztof Kozlowski wrote: > On 30/05/2024 10:55, Artur Weber wrote: >> There are two charger current limit registers: >> >> - Fast charge current limit (which controls current going from the >> charger to the battery); >> - CHGIN input current limit (which controls current going into the >> charger through the cable, and is managed by the CHARGER regulator). >> > > > >> + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: >> + ret = max77693_get_input_current_limit(chg, &val->intval); >> + break; >> + case POWER_SUPPLY_PROP_CURRENT_MAX: >> + ret = max77693_get_fast_charge_current(regmap, &val->intval); >> + break; >> case POWER_SUPPLY_PROP_MODEL_NAME: >> val->strval = max77693_charger_model; >> break; >> @@ -680,6 +727,11 @@ static int max77693_charger_probe(struct platform_device *pdev) >> chg->dev = &pdev->dev; >> chg->max77693 = max77693; >> >> + chg->regu = devm_regulator_get(chg->dev, "CHARGER"); >> + if (IS_ERR(chg->regu)) >> + return dev_err_probe(&pdev->dev, PTR_ERR(chg->regu), >> + "failed to get charger regulator\n");\ > > This breaks users... and where is the binding? Assuming "this" means "erroring out if the CHARGER regulator is not found": The way it works here is that the CHARGER regulator is fetched directly from the parent max77693 device (it's defined in the regulator subnode in DT). I suppose we could add a DT property for it, in the charger node (like we do for the USB connector), though I don't know if anyone would use any other regulator here than the CHARGER regulator of the max77693 regulator device. (And after all, we're using it here to modify charger registers... maybe another point to my argument that we should be handling all of this directly in the charger driver instead of deferring it to a regulator.) Best regards Artur [1] https://lore.kernel.org/all/20160927081344.GC4394@kozik-lap/ [2] https://lore.kernel.org/all/298d81d5-fe41-e2d1-32a7-d3dc35b0fe25@kernel.org/
diff --git a/drivers/power/supply/max77693_charger.c b/drivers/power/supply/max77693_charger.c index 2001e12c9f7d..894c35b750b3 100644 --- a/drivers/power/supply/max77693_charger.c +++ b/drivers/power/supply/max77693_charger.c @@ -9,6 +9,7 @@ #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/mfd/max77693.h> #include <linux/mfd/max77693-common.h> #include <linux/mfd/max77693-private.h> @@ -21,6 +22,7 @@ struct max77693_charger { struct device *dev; struct max77693_dev *max77693; struct power_supply *charger; + struct regulator *regu; u32 constant_volt; u32 min_system_volt; @@ -197,12 +199,51 @@ static int max77693_get_online(struct regmap *regmap, int *val) return 0; } +/* + * There are *two* current limit registers: + * - CHGIN limit, which limits the input current from the external charger; + * - Fast charge current limit, which limits the current going to the battery. + */ + +static int max77693_get_input_current_limit(struct max77693_charger *chg, + int *val) +{ + int ret; + + ret = regulator_get_current_limit(chg->regu); + if (ret < 0) + return ret; + + *val = ret; + + return 0; +} + +static int max77693_get_fast_charge_current(struct regmap *regmap, int *val) +{ + unsigned int data; + int ret; + + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_02, &data); + if (ret < 0) + return ret; + + data &= CHG_CNFG_02_CC_MASK; + data >>= CHG_CNFG_02_CC_SHIFT; + + *val = (data * 333 / 10) * 1000; /* 3 steps/0.1A */ + + return 0; +} + static enum power_supply_property max77693_charger_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, + POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, }; @@ -231,6 +272,12 @@ static int max77693_charger_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_ONLINE: ret = max77693_get_online(regmap, &val->intval); break; + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + ret = max77693_get_input_current_limit(chg, &val->intval); + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + ret = max77693_get_fast_charge_current(regmap, &val->intval); + break; case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = max77693_charger_model; break; @@ -680,6 +727,11 @@ static int max77693_charger_probe(struct platform_device *pdev) chg->dev = &pdev->dev; chg->max77693 = max77693; + chg->regu = devm_regulator_get(chg->dev, "CHARGER"); + if (IS_ERR(chg->regu)) + return dev_err_probe(&pdev->dev, PTR_ERR(chg->regu), + "failed to get charger regulator\n"); + ret = max77693_dt_init(&pdev->dev, chg); if (ret) return ret;
There are two charger current limit registers: - Fast charge current limit (which controls current going from the charger to the battery); - CHGIN input current limit (which controls current going into the charger through the cable, and is managed by the CHARGER regulator). Add the necessary functions to retrieve the CHGIN input limit (from CHARGER regulator) and maximum fast charge current values, and expose them as power supply properties. Signed-off-by: Artur Weber <aweber.kernel@gmail.com> --- drivers/power/supply/max77693_charger.c | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)