Hi Pavel, On 15/06/2020 16:05, Pavel Machek wrote: > Hi! > > Droid 4 has same problem as N900: it is often neccessary to manually > tweak current draw from USB, for example when using thin charging cable. > > N900 creates unique attribute by hand, but I believe > POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT looks suitable. (Should N900 be > converted?) > > Comments? Would the patch be acceptable after fixing whitespace? I'm not very knowledgeable on batteries - but the patch looks good to me. Could you perhaps explain what exactly this fixes? I've seen some interesting behaviour when plugging a Droid 4 into a PC (or wall charger, really): the led blinks for a few seconds until it stabilises. And then there's the issue where, once the battery is full, it will switch between charging and discharging every few seconds/minutes. Cheers, Merlijn > > Best regards, > Pavel > > Signed-off-by: Pavel Machek <pavel@xxxxxx> > > diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c > index b16848cfb58c..39a00716372f 100644 > --- a/drivers/power/supply/cpcap-battery.c > +++ b/drivers/power/supply/cpcap-battery.c > @@ -3,7 +3,7 @@ > * > * Copyright (C) 2017 Tony Lindgren <tony@xxxxxxxxxxx> > * > - * Some parts of the code based on earlie Motorola mapphone Linux kernel > + * Some parts of the code based on earlier Motorola mapphone Linux kernel > * drivers: > * > * Copyright (C) 2009-2010 Motorola, Inc. > diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c > index cf1e05b511d9..292d7a31c663 100644 > --- a/drivers/power/supply/cpcap-charger.c > +++ b/drivers/power/supply/cpcap-charger.c > @@ -89,6 +89,8 @@ > * CPCAP_REG_CRM charge currents. These seem to match MC13783UG.pdf > * values in "Table 8-3. Charge Path Regulator Current Limit > * Characteristics" for the nominal values. > + * > + * Except 70mA and 1.596A and unlimited, these are simply 88.7mA / step. > */ > #define CPCAP_REG_CRM_ICHRG(val) (((val) & 0xf) << 0) > #define CPCAP_REG_CRM_ICHRG_0A000 CPCAP_REG_CRM_ICHRG(0x0) > @@ -147,6 +149,8 @@ struct cpcap_charger_ddata { > int status; > int state; > int voltage; > + int limit_current; > + > int last_current; > int last_current_retries; > }; > @@ -175,6 +179,7 @@ static enum power_supply_property cpcap_charger_props[] = { > POWER_SUPPLY_PROP_STATUS, > POWER_SUPPLY_PROP_ONLINE, > POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, > + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, > POWER_SUPPLY_PROP_VOLTAGE_NOW, > POWER_SUPPLY_PROP_CURRENT_NOW, > }; > @@ -238,6 +243,9 @@ static int cpcap_charger_get_property(struct power_supply *psy, > case POWER_SUPPLY_PROP_STATUS: > val->intval = ddata->status; > break; > + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: > + val->intval = ddata->limit_current; > + break; > case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: > val->intval = ddata->voltage; > break; > @@ -308,6 +316,25 @@ cpcap_charger_get_bat_const_charge_voltage(struct cpcap_charger_ddata *ddata) > return voltage; > } > > +static int cpcap_charger_current_to_regval(int microamp) > +{ > + int miliamp = microamp/1000; > + int res; > + if (miliamp < 0) > + return -EINVAL; > + if (miliamp < 70) > + return CPCAP_REG_CRM_ICHRG(0x0); > + if (miliamp < 177) > + return CPCAP_REG_CRM_ICHRG(0x1); > + if (miliamp > 1596) > + return CPCAP_REG_CRM_ICHRG(0xe); > + > + res = microamp / 88666; > + if (res > 0xd) > + res = 0xd; > + return CPCAP_REG_CRM_ICHRG(res); > +} > + > static int cpcap_charger_set_property(struct power_supply *psy, > enum power_supply_property psp, > const union power_supply_propval *val) > @@ -316,6 +343,12 @@ static int cpcap_charger_set_property(struct power_supply *psy, > int voltage, batvolt; > > switch (psp) { > + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: > + if (cpcap_charger_current_to_regval(val->intval) < 0) > + return -EINVAL; > + ddata->limit_current = val->intval; > + schedule_delayed_work(&ddata->detect_work, 0); > + break; > case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: > voltage = cpcap_charger_match_voltage(val->intval); > batvolt = cpcap_charger_get_bat_const_charge_voltage(ddata); > @@ -335,6 +368,7 @@ static int cpcap_charger_property_is_writeable(struct power_supply *psy, > enum power_supply_property psp) > { > switch (psp) { > + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: > case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: > return 1; > default: > @@ -657,23 +691,21 @@ static void cpcap_usb_detect(struct work_struct *work) > > if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) && > s.chrgcurr1) { > - int max_current; > - int vchrg; > + int max_current = 532000; > + int vchrg, ichrg; > > if (cpcap_charger_battery_found(ddata)) > - max_current = CPCAP_REG_CRM_ICHRG_1A596; > - else > - max_current = CPCAP_REG_CRM_ICHRG_0A532; > + max_current = 1596000; > > switch (ddata->state) { > case CPCAP_CHARGER_DETECTING: > ddata->last_current_retries = 0; > break; > case CPCAP_CHARGER_DISCONNECTED: > - if (ddata->last_current > CPCAP_REG_CRM_ICHRG_0A532) { > + if (ddata->last_current > 532000) { > /* Attempt current 3 times before lowering */ > if (ddata->last_current_retries++ >= 3) { > - ddata->last_current--; > + ddata->last_current -= 100000; > ddata->last_current_retries = 0; > /* Wait a bit for voltage to ramp up */ > usleep_range(40000, 50000); > @@ -688,11 +720,16 @@ static void cpcap_usb_detect(struct work_struct *work) > break; > } > > + if (max_current > ddata->limit_current) > + max_current = ddata->limit_current; > + > ddata->last_current = max_current; > + > + ichrg = cpcap_charger_current_to_regval(max_current); > vchrg = cpcap_charger_voltage_to_regval(ddata->voltage); > error = cpcap_charger_set_state(ddata, > CPCAP_REG_CRM_VCHRG(vchrg), > - max_current, 0); > + ichrg, 0); > if (error) > goto out_err; > cpcap_charger_update_state(ddata, CPCAP_CHARGER_CHARGING); > @@ -864,6 +901,7 @@ static int cpcap_charger_probe(struct platform_device *pdev) > > ddata->dev = &pdev->dev; > ddata->voltage = 4200000; > + ddata->limit_current = 532000; > > ddata->reg = dev_get_regmap(ddata->dev->parent, NULL); > if (!ddata->reg) >
Attachment:
signature.asc
Description: OpenPGP digital signature