[PATCH V9 3/4] power: supply: Add charger driver for Rockchip RK817

Matti Vaittinen mazziesaccount at gmail.com
Thu Aug 25 22:52:40 PDT 2022


On 8/25/22 18:37, Chris Morgan wrote:
> On Thu, Aug 25, 2022 at 03:54:06PM +0300, Matti Vaittinen wrote:
>> On 8/23/22 22:30, Chris Morgan wrote:
>>> From: Chris Morgan <macromorgan at hotmail.com>
>>>
>>> Add support for the Rockchip rk817 battery charger integrated into the
>>> rk817 PMIC.
>>>
>>> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
>>> Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
>>> ---
>>>    drivers/power/supply/Kconfig         |    6 +
>>>    drivers/power/supply/Makefile        |    1 +
>>>    drivers/power/supply/rk817_charger.c | 1157 ++++++++++++++++++++++++++
>>>    3 files changed, 1164 insertions(+)
>>>    create mode 100644 drivers/power/supply/rk817_charger.c
>>>
>>> +
>>> +static void rk817_charging_monitor(struct work_struct *work)
>>> +{
>>> +	struct rk817_charger *charger;
>>> +
>>> +	charger = container_of(work, struct rk817_charger, work.work);
>>> +
>>> +	rk817_read_props(charger);
>>> +
>>> +	/* Run every 8 seconds like the BSP driver did. */
>>> +	queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000));
>>> +}
>>
>> I really think we would benefit from some more framework code which could
>> handle the periodic polling tasks and the coulomb counter drift corrections
>> when battery is full/relaxed. I think I might revive the simple-gauge patch
>> series...
> 
> Possibly, does such exist or is that a future endeavor?

No. Such a feature does not exist upstream. It was just some babbling I 
did here :) I started drafting something "generic" that would do polling 
of coulomb counter / battery state (full/relaxed) and then perform some 
'CC resetting' to correct drifitng error and compute the SOC based on CC 
values. That would obviously just be a machinery that calls driver 
callbacks. I did support for two ROHM chargers using this concept but I 
had to switch to some urgent tasks before I managed to do proper 
testing. Might get back to that later though (depending on the other 
duties).

> I'm only really
> doing the polling because that's how the BSP driver was set up (and I
> think it makes sense to not repeatedly check for teeny-tiny changes all
> the time). 

I am far from being and expert on the chargers so I can't say if this is 
the "de-facto" way of doing things. I just have a feeling this (this 
meaning periodic reading from HW and then returning the 'cached' values 
to user-space) is quite common (I may be wrong though, many others 
including Sebastian and Linus W have _much_ more insight into how 
chargers/charger drivers/user-space operate). Caching/polling sounds 
like a task that could be implemented in the framework code rather than 
in many individual drivers. (This comment does not mean I would expect 
You to write such a framework for this driver - as I said, I am just 
pondering aloud and waiting to see how others think of this :] )

> If there's an existing framework let me know, otherwise I'll
> keep my eye out in the future and revise this if I can when it's live.

So no existing framework and please, don't hold your breath waiting for 
one ;) It's still great to know that you can be pinged if I manage to 
cook-up something.

>>> +
>>> +static int rk817_charger_probe(struct platform_device *pdev)
>>> +{
>>> +
>>> +	charger->sleep_filter_current_ua = of_value;
>>> +
>>> +	charger->bat_ps = devm_power_supply_register(&pdev->dev,
>>> +						     &rk817_bat_desc, &pscfg);
>>> +
>>> +	charger->chg_ps = devm_power_supply_register(&pdev->dev,
>>> +						     &rk817_chg_desc, &pscfg);
>>
>> Hmm. I think I should respin the patch which added interface for getting the
>> battery info w/o psy-device. Now we need to take into account the situation
>> where the psy-core accesses the driver after the registration - and prior
>> filling the battery details from the battery node (below) :/
> 
> I used the AXP209 battery driver to help me fill in some of the gaps in
> my understanding, that driver gets the battery details after
> registration (ditto for the ingenic battery driver, which I also looked
> at.
> 

Sure. I think the current battery_info API requires a psy-device so 
registration needs to be done prior calling it. This was one of the 
things I changed while I was twiddling with the simple-gauge RFC series 
(which is not in-tree). So this was also not a request to change your 
driver but a generic note that it would be beneficial to decouple the 
battery-info API from psy-device.

>>
>>> +
>>> +	if (IS_ERR(charger->chg_ps))
>>> +		return dev_err_probe(dev, -EINVAL,
>>> +				     "Battery failed to probe\n");
>>> +
>>> +	if (IS_ERR(charger->chg_ps))
>>> +		return dev_err_probe(dev, -EINVAL,
>>> +				     "Charger failed to probe\n");
>>> +
>>> +	ret = power_supply_get_battery_info(charger->bat_ps,
>>> +					    &bat_info);
>>> +	if (ret) {
>>> +		return dev_err_probe(dev, ret,
>>> +				     "Unable to get battery info: %d\n", ret);
>>> +	} > +
>>> +	if ((!bat_info->charge_full_design_uah) ||
>>> +	    (!bat_info->voltage_min_design_uv) ||
>>> +	    (!bat_info->voltage_max_design_uv) ||
>>> +	    (!bat_info->constant_charge_voltage_max_uv) ||
>>> +	    (!bat_info->constant_charge_current_max_ua) ||
>>> +	    (!bat_info->charge_term_current_ua)) {
>>> +		return dev_err_probe(dev, -EINVAL,
>>> +				     "Required battery info missing.\n");
>>> +	}
>>
>> Just a question - should the values be compared to -EINVAL (I think the
>> power_supply_get_battery_info() did internally initialize many of the fields
>> to -EINVAL and not to 0?). Maybe I am wrong...
> 
> No, you're not wrong. The power_supply_get_battery_info does set the
> values to -EINVAL, but it also then sets them based on the devicetree
> without checking the return values.

You might want to check whether the device-tree APIs update the value if 
property is not found - or if some error occurs. AFAIR they do not.

> I'm not entirely clear if in the
> event of an error it could set it to another value though or null,
> so do you think performing a check to see if the value is less than or
> equal to 0 would be sufficient?

I'd say this depends on the property. Some properties may have valid 
negative values but I guess you know what to expect. In any case, I 
assume that the value being non-zero does not guarantee it is valid so 
the check should probably be improved.

> 
>>
>>> +
>>> +	charger->bat_charge_full_design_uah = bat_info->charge_full_design_uah;
>>> +	charger->bat_voltage_min_design_uv = bat_info->voltage_min_design_uv;
>>> +	charger->bat_voltage_max_design_uv = bat_info->voltage_max_design_uv;
>>> +
>>
>> Generally, I did _really_ like the proper commenting/documenting of the
>> driver. In my eyes this looked like one nice piece of a driver.
> 
> It's confusing as hell (my first battery driver, so the comments
> hopefully help everyone else as much as they helped me).

I think the fuel-gauging can be complex topic. Hence comments help a 
lot. I do definitely like the comments in charger / fuel gauge drivers.

> There was
> also a bunch of weird errata like resetting the max charge current
> when the plug-in IRQ fires that I felt needed to be documented.

Yes.

> 
> Thanks for looking at this, I value your input and will make the
> changes once you let me know about the -EINVAL check.

The v9 was caught by my mail-filters :D Probably due to addition of the 
autocancel work-queue. It was actually good for me to be pinged by 
power-supply patches as I might find some time to continue fuel-gauge 
work during the autumn/winter.

-- Matti

-- 
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~



More information about the Linux-rockchip mailing list