Message ID | 20190917215253.17880-4-tony@atomide.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | cpcap charger and battery changes to deal with dropped voltage | expand |
On Tue 2019-09-17 14:52:53, Tony Lindgren wrote: > When debugging why higher than 500 mA charge current does not work, I > noticed that we start getting lots of chrgcurr1 interrupts if we attempt > to charge at rates higher than the charger can provide. > > We can take advantage of the chrgcurr1 interrupts for charger detection, > and retry charging at a lower rate if charging fails. When an acceptable > charge rate is found, the chrgcurr1 interrupts stop. Do you still see these problems with "good" charger? (Wall one, capable of providing 2A)? Note that 1A charging will decrease battery lifetime, and that phone definitely should not be charging with more than 500mA when charging from computer. I actually prefer the way it charges slowly in mainline... We'll eventually need a library or something; we don't want every driver to reinvent charging code.. Best regards, Pavel
* Pavel Machek <pavel@ucw.cz> [190919 09:35]: > On Tue 2019-09-17 14:52:53, Tony Lindgren wrote: > > When debugging why higher than 500 mA charge current does not work, I > > noticed that we start getting lots of chrgcurr1 interrupts if we attempt > > to charge at rates higher than the charger can provide. > > > > We can take advantage of the chrgcurr1 interrupts for charger detection, > > and retry charging at a lower rate if charging fails. When an acceptable > > charge rate is found, the chrgcurr1 interrupts stop. > > Do you still see these problems with "good" charger? (Wall one, > capable of providing 2A)? Yes, need to recheck again with the updated fix I posted. > Note that 1A charging will decrease battery lifetime, and that phone > definitely should not be charging with more than 500mA when charging > from computer. I actually prefer the way it charges slowly in mainline... It should still charge at 500mA when connected to a computer because of different charger detection bits. Needs to be checked again .though > We'll eventually need a library or something; we don't want every > driver to reinvent charging code.. Yeah currently implementing a charger takes weeks of work :) Regards, Tony
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -145,6 +145,12 @@ enum { CPCAP_CHARGER_IIO_NR, }; +enum { + CPCAP_CHARGER_DISCONNECTED, + CPCAP_CHARGER_DETECTING, + CPCAP_CHARGER_CONNECTED, +}; + struct cpcap_charger_ddata { struct device *dev; struct regmap *reg; @@ -161,6 +167,9 @@ struct cpcap_charger_ddata { unsigned int vbus_enabled:1; unsigned int feeding_vbus:1; int const_charge_voltage; + int state; + int last_current; + int last_current_retries; atomic_t active; int status; @@ -551,6 +560,15 @@ static void cpcap_usb_detect(struct work_struct *work) if (error) return; + /* Just init the state if a charger is connected with no chrg_det set */ + if (!ddata->feeding_vbus && !s.chrg_det && s.chrgcurr1 && s.vbusvld) { + ddata->state = CPCAP_CHARGER_DETECTING; + ddata->last_current = 0; + + return; + } + + /* Start charger on chrgcurr1, stop chrger otherwise */ if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) { int max_current; @@ -561,6 +579,32 @@ static void cpcap_usb_detect(struct work_struct *work) else max_current = CPCAP_REG_CRM_ICHRG_0A532; + switch (ddata->state) { + case CPCAP_CHARGER_DETECTING: + ddata->state = CPCAP_CHARGER_CONNECTED; + ddata->last_current_retries = 0; + break; + case CPCAP_CHARGER_DISCONNECTED: + if (ddata->last_current > CPCAP_REG_CRM_ICHRG_0A532) { + /* Attempt current 3 times before lowering */ + if (ddata->last_current_retries++ >= 3) { + ddata->last_current--; + ddata->last_current_retries = 0; + /* Wait a bit for voltage to ramp up */ + usleep_range(40000, 50000); + } + max_current = ddata->last_current; + } + ddata->state = CPCAP_CHARGER_CONNECTED; + dev_info(ddata->dev, "enabling charger with current %i\n", + max_current); + break; + default: + ddata->last_current_retries = 0; + break; + } + + ddata->last_current = max_current; cpcap_charger_match_voltage(ddata, ddata->const_charge_voltage, &vchrg); error = cpcap_charger_set_state(ddata, @@ -569,6 +613,7 @@ static void cpcap_usb_detect(struct work_struct *work) if (error) goto out_err; } else { + ddata->state = CPCAP_CHARGER_DISCONNECTED; error = cpcap_charger_set_state(ddata, 0, 0, 0); if (error) goto out_err;
When debugging why higher than 500 mA charge current does not work, I noticed that we start getting lots of chrgcurr1 interrupts if we attempt to charge at rates higher than the charger can provide. We can take advantage of the chrgcurr1 interrupts for charger detection, and retry charging at a lower rate if charging fails. When an acceptable charge rate is found, the chrgcurr1 interrupts stop. Cc: Merlijn Wajer <merlijn@wizzup.org> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Tony Lindgren <tony@atomide.com> --- drivers/power/supply/cpcap-charger.c | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)