[Letux-kernel] twl4030 charging

H. Nikolaus Schaller hns at goldelico.com
Mon Jul 25 21:50:34 CEST 2016

> Am 25.07.2016 um 18:54 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> The problem is for pulling out ones hair :)
> So far I know:
> * during boot an USB OTG plug event is recognised
> * this updates the current to 500mA
> * this properly sets BCIAUTOUSB and a little later USBFASTMCHG
> * after that, ITHEN and MESVAC become 1
> * and BCIMSTATEC reports "Quick charge USB 1"
> * this indicates that charging has started
> * then, an ICHGLOW interrupt occurs and is processed (again updating the current to 500mA)
> * then some background process reads charger properties (/sys)
> * suddenly (after ca. 20ms) - without obvious reason - ITHEN and MESVAC become 0
> * shortly after, another ICHGLOW interrupt occurs and is processed (unclear if that always occurs)
> * and again a little later BCIMSTATEC switches from "Quick charge USB 1" to "No charging device"
> * no more interrupts observed
> This all happens within ~20 ms
> So the symptoms can be summarized as:
> After successful plug-in detection the charger starts, but almost immediately stops again for invisible reasons.
> It ends in a state (ITHEN disabled, simulating a non-existing battery) that the driver does take the twl4030 out
> of, even after replugging USB.
> It is still a big mystery...

I could now trace it down to be a little random.

1st insight:
it is not related to interrupt processing. I have almost disabled the bci_irq handler so that it only prints the irq
and resets the status registers and does no update of the current settings.

2nd insight:
The position where ITHEN and MESVAC go to 0 again is not related to the read/write activities.
Sometimes it takes longer, sometimes shorter.
In one trace it even happened while processing the first ICHGLOW interrupt.

So what does that mean?

I have studied the source code a little more and have tried to understand twl4030_charger_update_current().

That function sets several limit current values for comparators (in a way that I must admit that I don't
understand at all - strange bit patterns not directly related to the data sheet).

Now what could be is that these calculations are wrong. And set the wrong bit patterns so that the
charger stops immediately. But what "immedialtey" means depends on the speed of the BCI ADCs
and might also depend on hardware induced noise.

Another thought is that since the battery is connected in parallel with the system to the charger, this
means that all current measurements are based on the sum of the charging current + system demand.

So such current limits heavily depend on the system load - and mixed with battery quality.
Here the driver might make assumptions that are not always true. This might explain why it works
on some devices and doesn't on others. Which must be some hardware dependency.

Why does it work on 4.3 kernel but no longer on 4.4, although all this charger code was introduced in 4.3-rc1?

This is a good question... Next one :)

Well, there is no apparently significant difference between 4.3-rc1 and 4.7.0 in drivers/power/twl4030_charger.c

* moved the current limit setting from a private /sys property to the standard one
* probing sequence changed so that irqs are initialized last (and after EPROBEDEFER can occur)
* use iio for getting the AC voltage (which can be completely disabled to show that it has no effect)
* battery presence detection has been removed (assuming that reading 2 registers does not initialize anything)

So, as we already know, it must be outside. Either regmaps have changed. Or what I have never checked
is twl4030 audio. Or some processes are not more parallelized than before (some different mutex).

Mystery remains...


More information about the Letux-kernel mailing list