Skip to contentSkip to conversation

power: supply: Initial support for ROHM BD70528 PMIC charger block

RFC PATCH Superseded Matti Vaittinen 2 participants 9 messages Jan 25, 2019 – Feb 11, 2020

Subsystems (5)

v2 of 15 Superseded Latest is v15 →

lore
Share & tools
lore
#0 lore raw

RFC PATCH v2 9/10 power: supply: Initial support for ROHM BD70528 PMIC charger block

ROHM BD70528 PMIC includes battery charger block. Support charger staus queries and doing few basic settings like input current limit and charging current.

---
 drivers/power/supply/Kconfig           |   9 +
 drivers/power/supply/Makefile          |   1 +
 drivers/power/supply/bd70528-charger.c | 670 +++++++++++++++++++++++++++++++++
 3 files changed, 680 insertions(+)
 create mode 100644 drivers/power/supply/bd70528-charger.c
drivers/power/supply/Kconfig +9 -0
index e901b9879e7e..903c97a67bf0 100644
@@ -660,4 +660,13 @@ config FUEL_GAUGE_SC27XX
 	 Say Y here to enable support for fuel gauge with SC27XX
 	 PMIC chips.
 
+config CHARGER_BD70528
+	tristate "ROHM bd70528 charger driver"
+	depends on MFD_ROHM_BD70528
+	default n
+	help
+	 Say Y here to enable support for getting battery status
+	 information and altering charger configurations from charger
+	 block of the ROHM BD70528 Power Management IC.
+
 endif # POWER_SUPPLY
drivers/power/supply/Makefile +1 -0
index b731c2a9b695..c60387b04bfa 100644
@@ -87,3 +87,4 @@ obj-$(CONFIG_AXP288_CHARGER)	+= axp288_charger.o
 obj-$(CONFIG_CHARGER_CROS_USBPD)	+= cros_usbpd-charger.o
 obj-$(CONFIG_CHARGER_SC2731)	+= sc2731_charger.o
 obj-$(CONFIG_FUEL_GAUGE_SC27XX)	+= sc27xx_fuel_gauge.o
+obj-$(CONFIG_CHARGER_BD70528)	+= bd70528-charger.o
drivers/power/supply/bd70528-charger.c new file +670 -0

670 lines not on this page · raw message

Signature · 8 lines
2.14.3


-- 
Matti Vaittinen
ROHM Semiconductors

~~~ "I don't think so," said Rene Descartes.  Just then, he vanished ~~~
#1 lore raw

Hi Matti!

Thanks for your patch.

We are going to have a problem with the power subsystem.

These charging drivers are growing wild. This is starting to get out of hand, we need some more framework for properly handling charging state machines the kernel. Not specifically your problem, but when working on the driver try to keep generic support in mind.

drivers/power/supply/bd70528-charger.c line 25

Quoted 12 lines · Matti Vaittinen
drivers/power/supply/bd70528-charger.c new file +12 -0
+#define CHG_STAT_SUSPEND       0x0
+#define CHG_STAT_TRICKLE       0x1
+#define CHG_STAT_FAST          0x3
+#define CHG_STAT_TOPOFF                0xe
+#define CHG_STAT_DONE          0xf
+#define CHG_STAT_OTP_TRICKLE   0x10
+#define CHG_STAT_OTP_FAST      0x11
+#define CHG_STAT_OTP_DONE      0x12
+#define CHG_STAT_TSD_TRICKLE   0x20
+#define CHG_STAT_TSD_FAST      0x21
+#define CHG_STAT_TSD_TOPOFF    0x22
+#define CHG_STAT_BAT_ERR       0x7f

So what I am seeing is that these states are starting to turn up in more and more drivers, so we really need to think about a central management component for charging state machines. I do not think they are all that different after all.

Quoted 7 lines
drivers/power/supply/bd70528-charger.c new file +7 -0
+BD_ERR_IRQ_HND(BAT_OV_DET, "Battery overvoltage detected\n");
+BD_ERR_IRQ_HND(DBAT_DET, "Dead battery detected\n");
+BD_ERR_IRQ_HND(COLD_DET, "Battery cold\n");
+BD_ERR_IRQ_HND(HOT_DET, "Battery hot\n");
+BD_ERR_IRQ_HND(CHG_TSD, "Charger thermal shutdown\n");
+BD_ERR_IRQ_HND(DCIN2_OV_DET, "DCIN2 overvoltage detected\n");
+

drivers/power/supply/bd70528-charger.c line 70

Quoted 10 lines
drivers/power/supply/bd70528-charger.c new file +10 -0
+BD_INFO_IRQ_HND(BAT_OV_RES, "Battery voltage back to normal\n");
+BD_INFO_IRQ_HND(COLD_RES, "Battery temperature back to normal\n");
+BD_INFO_IRQ_HND(HOT_RES, "Battery temperature back to normal\n");
+BD_INFO_IRQ_HND(BAT_RMV, "Battery removed\n");
+BD_INFO_IRQ_HND(BAT_DET, "Battery detected\n");
+BD_INFO_IRQ_HND(DCIN2_OV_RES, "DCIN2 voltage back to normal\n");
+BD_INFO_IRQ_HND(DCIN2_RMV, "DCIN2 removed\n");
+BD_INFO_IRQ_HND(DCIN2_DET, "DCIN2 detected\n");
+BD_INFO_IRQ_HND(DCIN1_RMV, "DCIN1 removed\n");
+BD_INFO_IRQ_HND(DCIN1_DET, "DCIN1 detected\n");

So we have states and events, and these events form edges between the states, right?

I am certain you must have a graphical picture of this state machine somewhere, it seems to be how charging hardware people do their thinking.

Quoted 24 lines
drivers/power/supply/bd70528-charger.c new file +24 -0
+/*
+ * For BD70528 voltage/current limits we happily accept any value which
+ * belongs the range. We could check if value matching the selector is
+ * desired by computing the range min + (sel - sel_low) * range step - but
+ * I guess it is enough if we use voltage/current which is closest (below)
+ * the requested?
+ */
+static int find_selector_for_value_low(struct linear_range *r, int selectors,
+                                      unsigned int val, unsigned int *sel,
+                                      bool *found)
+{
+       int i;
+       int ret = -EINVAL;
+
+       *found = false;
+       for (i = 0; i < selectors; i++) {
+               if (r[i].min <= val) {
+                       if (r[i].min + r[i].step * r[i].vals >= val) {
+                               *found = true;
+                               *sel = r[i].low_sel + (val - r[i].min) /
+                                      r[i].step;
+                               ret = 0;
+                               break;
+                       }

drivers/power/supply/bd70528-charger.c line 380

Quoted 10 lines
drivers/power/supply/bd70528-charger.c new file +10 -0
+                       /*
+                        * If the range max is smaller than requested
+                        * we can set the max supported value from range
+                        */
+                       *sel = r[i].low_sel + r[i].vals;
+                       ret = 0;
+               }
+       }
+       return ret;
+}

If I'm not mistaken this is yet another instance of linear interpolation from a table?

We really need to think about abstracting this. Last time this duplication appeared I suggested adding linear interpolation primitives to:
include/linux/fixp-arith.h

I don't know what others say though?

Yours,
Linus Walleij

#2 lore raw

Hello Linus,

Big Thanks for the proper review at this early satge!

Quoted 10 lines · Linus Walleij

Hi Matti!

Thanks for your patch.

We are going to have a problem with the power subsystem.

These charging drivers are growing wild. This is starting to get out of hand, we need some more framework for properly handling charging state machines the kernel. Not specifically your problem, but when working on the driver try to keep generic support in mind.

I for sure can try - but as the power subsystem is quite new to me - any specific items you would like me to really pay attention?

Quoted 12 lines
Quoted 9 lines · Matti Vaittinen
drivers/power/supply/bd70528-charger.c new file +9 -0
+#define CHG_STAT_SUSPEND       0x0
+#define CHG_STAT_TRICKLE       0x1
+#define CHG_STAT_FAST          0x3
+#define CHG_STAT_TOPOFF                0xe
+#define CHG_STAT_DONE          0xf
+#define CHG_STAT_OTP_TRICKLE   0x10
+#define CHG_STAT_OTP_FAST      0x11
+#define CHG_STAT_OTP_DONE      0x12
+#define CHG_STAT_TSD_TRICKLE   0x20
Quoted 8 lines

drivers/power/supply/bd70528-charger.c line 25

Quoted 3 lines
drivers/power/supply/bd70528-charger.c new file +3 -0
+#define CHG_STAT_TSD_FAST      0x21
+#define CHG_STAT_TSD_TOPOFF    0x22
+#define CHG_STAT_BAT_ERR       0x7f

So what I am seeing is that these states are starting to turn up in more and more drivers, so we really need to think about a central management component for charging state machines. I do not think they are all that different after all.

Any suggestions how I should take this into account with bd70528?

Quoted 12 lines
Quoted 12 lines
drivers/power/supply/bd70528-charger.c new file +12 -0
+BD_ERR_IRQ_HND(BAT_OV_DET, "Battery overvoltage detected\n");
+BD_ERR_IRQ_HND(DBAT_DET, "Dead battery detected\n");
+BD_ERR_IRQ_HND(COLD_DET, "Battery cold\n");
+BD_ERR_IRQ_HND(HOT_DET, "Battery hot\n");
+BD_ERR_IRQ_HND(CHG_TSD, "Charger thermal shutdown\n");
+BD_ERR_IRQ_HND(DCIN2_OV_DET, "DCIN2 overvoltage detected\n");
+
+BD_INFO_IRQ_HND(BAT_OV_RES, "Battery voltage back to normal\n");
+BD_INFO_IRQ_HND(COLD_RES, "Battery temperature back to normal\n");
+BD_INFO_IRQ_HND(HOT_RES, "Battery temperature back to normal\n");
+BD_INFO_IRQ_HND(BAT_RMV, "Battery removed\n");
+BD_INFO_IRQ_HND(BAT_DET, "Battery detected\n");
Quoted 8 lines

drivers/power/supply/bd70528-charger.c line 70

Quoted 5 lines
drivers/power/supply/bd70528-charger.c new file +5 -0
+BD_INFO_IRQ_HND(DCIN2_OV_RES, "DCIN2 voltage back to normal\n");
+BD_INFO_IRQ_HND(DCIN2_RMV, "DCIN2 removed\n");
+BD_INFO_IRQ_HND(DCIN2_DET, "DCIN2 detected\n");
+BD_INFO_IRQ_HND(DCIN1_RMV, "DCIN1 removed\n");
+BD_INFO_IRQ_HND(DCIN1_DET, "DCIN1 detected\n");

So we have states and events, and these events form edges between the states, right?

Right. State change causes an irq.

Quoted 3 lines

I am certain you must have a graphical picture of this state machine somewhere, it seems to be how charging hardware people do their thinking.

I don't have any document I could link to yet. I can ask around if we can have some public doc for this :/ And as a last resort I can do some ASCII art in commenets - if this is seen helpfull.

Quoted 29 lines
Quoted 29 lines
drivers/power/supply/bd70528-charger.c new file +29 -0
+/*
+ * For BD70528 voltage/current limits we happily accept any value which
+ * belongs the range. We could check if value matching the selector is
+ * desired by computing the range min + (sel - sel_low) * range step - but
+ * I guess it is enough if we use voltage/current which is closest (below)
+ * the requested?
+ */
+static int find_selector_for_value_low(struct linear_range *r, int selectors,
+                                      unsigned int val, unsigned int *sel,
+                                      bool *found)
+{
+       int i;
+       int ret = -EINVAL;
+
+       *found = false;
+       for (i = 0; i < selectors; i++) {
+               if (r[i].min <= val) {
+                       if (r[i].min + r[i].step * r[i].vals >= val) {
+                               *found = true;
+                               *sel = r[i].low_sel + (val - r[i].min) /
+                                      r[i].step;
+                               ret = 0;
+                               break;
+                       }
+                       /*
+                        * If the range max is smaller than requested
+                        * we can set the max supported value from range
+                        */
+                       *sel = r[i].low_sel + r[i].vals;
Quoted 8 lines

drivers/power/supply/bd70528-charger.c line 380

Quoted 5 lines
drivers/power/supply/bd70528-charger.c new file +5 -0
+                       ret = 0;
+               }
+       }
+       return ret;
+}

If I'm not mistaken this is yet another instance of linear interpolation from a table?

"linear interpolation from a table" is really not part of my vocabulary :] But I guess you know the REGULATOR_LINEAR_VOLTAGE - macro? I borrowed the idea from there...

Quoted 5 lines

We really need to think about abstracting this. Last time this duplication appeared I suggested adding linear interpolation primitives to:
include/linux/fixp-arith.h

... I really think a generic helper for this would be usefull.

It will take some time untill I can send a proper (non RFC patch) for the charger block as I currently lack of HW I could use for testing the charger properly. Do you think it is better to drop the charger part from the series untill then and submit it only later? As I mentioned in cover-letter, the charger part is currently submitted more to give an overview of the chip than to be applied as 'finalized' version of driver.

Br,
Matti Vaittinen

#3 lore raw
Quoted 7 lines · Matti Vaittinen
Quoted 4 lines

These charging drivers are growing wild. This is starting to get out of hand, we need some more framework for properly handling charging state machines the kernel. Not specifically your problem, but when working on the driver try to keep generic support in mind.

I for sure can try - but as the power subsystem is quite new to me - any specific items you would like me to really pay attention?

So I am not saying you have to do this or anything, but I think what we need is a generic state machine and policy engine for charging, where different charging drivers just plug in.

They all seem to have trickle and fast charging, USB phy interaction and AC plug interaction of some kind for detecting those and in some cases temperature detection directly or using an ADC.

We have a bunch of drivers with software-controlled charging:
ab8500*
axp288*
etc.

If we could get just two drivers to share some changing infrastructure we would have a start.

I have no idea how hard it could be, but I think it would be a pretty interesting adventure if someone gathered some different hardwares and started to generalize parts of this.

Quoted 6 lines
Quoted 4 lines

So what I am seeing is that these states are starting to turn up in more and more drivers, so we really need to think about a central management component for charging state machines. I do not think they are all that different after all.

Any suggestions how I should take this into account with bd70528?

Not more than above, it is unfair to ask random contributors to invent entire new worlds of kernel infrastructure. But I guess I just need to say it so we are aware: this charging state machine engine is needed. Doing it is another thing.

Quoted 7 lines
Quoted 3 lines

I am certain you must have a graphical picture of this state machine somewhere, it seems to be how charging hardware people do their thinking.

I don't have any document I could link to yet. I can ask around if we can have some public doc for this :/ And as a last resort I can do some ASCII art in commenets - if this is seen helpfull.

That'd be nice.

Quoted 6 lines
Quoted 2 lines

If I'm not mistaken this is yet another instance of linear interpolation from a table?

"linear interpolation from a table" is really not part of my vocabulary :] But I guess you know the REGULATOR_LINEAR_VOLTAGE - macro? I borrowed the idea from there...

I'm referring to this essentially:
https://en.wikipedia.org/wiki/Linear_interpolation

What many charging drivers tends to do is:
- Look up where I am in a table, say between row 4 and 5
- For x-axis n..n+1, interpolate y-axis between the values found for x=1 and x=n+1 using common linear interpolation.

Quoted 6 lines
Quoted 4 lines

We really need to think about abstracting this. Last time this duplication appeared I suggested adding linear interpolation primitives to:
include/linux/fixp-arith.h

... I really think a generic helper for this would be usefull.

Indeed.

Quoted 4 lines

It will take some time untill I can send a proper (non RFC patch) for the charger block as I currently lack of HW I could use for testing the charger properly. Do you think it is better to drop the charger part from the series untill then and submit it only later?

Not really, we need to face the hardware out there and I usually use the stance "rough consensus and running code". If noone invents a unified charging framework, your hardware needs to run so a custom driver isn't that bad either, and it's still better to have it in-tree than to maintain it out-of-tree as long as it is clearly isolated.

Quoted 4 lines

As I mentioned in
cover-letter, the charger part is currently submitted more to give an overview of the chip than to be applied as 'finalized' version of driver.

That's OK.

Yours,
Linus Walleij

#4 lore raw

Hi dee Ho Peeps!

I started working for a driver for ROHM BD99954 charger chip and ended up writing the linear range code once again. And that reminded me of this year old discussion :)

Quoted 10 lines · Linus Walleij
Quoted 7 lines · Matti Vaittinen
Quoted 6 lines

These charging drivers are growing wild. This is starting to get out
of hand, we need some more framework for properly handling charging
state machines the kernel. Not specifically your problem, but when working on the driver try to keep generic support in mind.

Quoted 7 lines
Quoted 3 lines

I for sure can try - but as the power subsystem is quite new to me
- any
specific items you would like me to really pay attention?

So I am not saying you have to do this or anything, but I think what we need is a generic state machine and policy engine for charging, where different charging drivers just plug in.

The BD99954 charger as well as the BD70528 charger (and BD71828 charger
- which I have not yet sumitted in-tree as it has a tuned-to-work-with- only-one-battery fuel-gauge algorithm) do not need much of SW control for the state machine. Basically the SW mostly needs to set the voltage/current thresholds which match the system HW design and the battery. My current idea is to bring these from DT - if this is a way to go, then I can try seeing how much common DT-parsing/binding naming I can use for these ROHM chargers...

Quoted 4 lines

They all seem to have trickle and fast charging, USB phy interaction and AC plug interaction of some kind for detecting those and in some cases temperature detection directly or using an ADC.

Yes. That's pretty much what these ROHM chips have. But SW mostly needs to set the limit values - it does not need to participate in state changing and most of these things are also something users do not care (I guess). Fuel gauging is other topic but I'm not planning to implement it for in-tree drivers at least for now :/

The thing that comes to (my) mind is just a common DT properties for input current/voltage limits, battery voltages for switching to next charging state, current values for different charging states - and parsing of these properties.

I've seen some comments about DT not being a good place for battery specific properties as batteries may be replaced with another having different type - but I don't think this is valid problem for many of the devices today. Of course some devices may have batteries that can be changed - but many don't - and for those it is perfectly Ok to have battery data defined in DT, right?

First thought is that setting these values needs to be done by driver (as it's chip specific) - and that the power-supply framework does not need to know anything about this - it could just provide of-helper for parsing the DT. That would be simple and no callbacks would be needed.

But ... do we need to provide a way for user-space to configure these settings instead of the DT? Or any other possible sources for this information?

If this is needed - then we probably would want to have the callbacks. Individual driver would not need to care where the configuration comes from - it would just provide callback and leave it to power-supply framework to check if the limits are in DT or come from user-space or some other source.

This is just some initial thinking - currently I have set of good old rohm,blahblah-microvolts and rohm,blahblah-microamp charger specific properties and parsing code is getting in-driver... But I would like to hear about any thoughts this may invoke.

Quoted 7 lines

We have a bunch of drivers with software-controlled charging:
ab8500*
axp288*
etc.

If we could get just two drivers to share some changing infrastructure we would have a start.

Hmm. If changing means state changes - then these ROHM chips probably play no role here as there the HW does most of the state changes autonomously. (AFAIR, it's been a while since I looked the other but BD99954).

Quoted 18 lines
Quoted 8 lines
Quoted 3 lines

If I'm not mistaken this is yet another instance of linear interpolation
from a table?

"linear interpolation from a table" is really not part of my vocabulary :] But I guess you know the REGULATOR_LINEAR_VOLTAGE - macro?
I borrowed the idea from there...

I'm referring to this essentially:
https://en.wikipedia.org/wiki/Linear_interpolation

What many charging drivers tends to do is:
- Look up where I am in a table, say between row 4 and 5
- For x-axis n..n+1, interpolate y-axis between the values found for x=1 and x=n+1 using common linear interpolation.

Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

We really need to think about abstracting this. Last time this duplication appeared I suggested adding linear interpolation primitives to:
include/linux/fixp-arith.h

... I really think a generic helper for this would be usefull.

Indeed.

And I am again doing the value lookup code here. I again have voltage/current registers where writing value n (where n is in a range 0,...,N) will cause voltage Vto be set V = V0 + n*(Vstep). (Okay, n can start from something else than 0 too - but I just wanted to explain the idea). So I am again writing a look-up code to match "selector" n to a value V or a value V to a selector n. This is required for example when I convert voltage/current DT values to register values.

So ... If I extract the linear_range code from BD70528 driver (it should be usable for the BD99954 as such) - should I place it to some common header/lib? (This is plain integer maths so I don't like the idea of placing it in fixp-arith.h). I would assume there is quite a few chips with registers where increment of 1 in register means fixed increment in some physical value (current, voltage, something else,...) so having this code in some rohm-helpers.c and internal header is suboptimal (but I can do that too).

Any guidance or suggestions?

Br,
Matti Vaittinen

#5 lore raw
Quoted 3 lines · Matti

I started working for a driver for ROHM BD99954 charger chip and ended up writing the linear range code once again. And that reminded me of this year old discussion :)

OK!

Quoted 16 lines
Quoted 4 lines

They all seem to have trickle and fast charging, USB phy interaction and AC plug interaction of some kind for detecting those and in some cases temperature detection directly or using an ADC.

Yes. That's pretty much what these ROHM chips have. But SW mostly needs to set the limit values - it does not need to participate in state changing and most of these things are also something users do not care (I guess). Fuel gauging is other topic but I'm not planning to implement it for in-tree drivers at least for now :/

The thing that comes to (my) mind is just a common DT properties for input current/voltage limits, battery voltages for switching to next charging state, current values for different charging states - and parsing of these properties.

Quoted 6 lines

I've seen some comments about DT not being a good place for battery specific properties as batteries may be replaced with another having different type - but I don't think this is valid problem for many of the devices today. Of course some devices may have batteries that can be changed - but many don't - and for those it is perfectly Ok to have battery data defined in DT, right?

If something is a property of the charging circuit, then it can be derived from the compatible value, so anything that is just peculiar for this chip version doesn't go into device tree, just use a custom struct and the match data for that.

Then we have the battery. I suppose that could be defined as a DT node for the battery itself, and not as part of the charging IC, and we should think about how to create a battery DT binding. What characteristics are chargers really interested in? This could be some work.

If different devices have different batteries then the boot loader could ideally patch the DT with the right battery. This was the solution advocated for devices with different display panels, to a question from Hans de Goede at one point IIRC.

Quoted 3 lines

But ... do we need to provide a way for user-space to configure these settings instead of the DT? Or any other possible sources for this information?

What we usually have said is that "policy should be in userspace" and "kernel manages hardware". This creates a not-so-small grey area in between and it is unfortunately up to interpretation.

Today there is also a THIRD alternative, and that is to let userspace insert a policy using a BPF program. This is the approach taken by the network and tracing stacks and we look at more applications. If the kernel needs to be able to handle charging and emergencies even if userspace is not up or available, this or other userspace policies are not viable.

I have a strong feeling that it should be a battery node in the device tree.

Quoted 4 lines

Hmm. If changing means state changes - then these ROHM chips probably play no role here as there the HW does most of the state changes autonomously. (AFAIR, it's been a while since I looked at the other but BD99954).

Good it's a simpler hardware. We just need to think about making the code reusable.

Quoted 4 lines

So ... If I extract the linear_range code from BD70528 driver (it should be usable for the BD99954 as such) - should I place it to some common header/lib? (This is plain integer math so I don't like the idea of placing it in fixp-arith.h).

Start with moving it to some separate file, like power_supply_interpolation.c that we just always compile in and we can take it from there.

Just some thoughts...

Yours,
Linus Walleij

#6 lore raw

Hello Linus,

First of all - thanks for taking the time to help me once again.

I just some time ago did submit the RFC for BD99954 - and immediately regretted doing so as only few minutes later I spotted the already existing battery code/bindings. It's quite embarrassing to send out an email for wide audience just to notice that I've written large amount of nonsense :/ (I suggested adding common bindings and parsers and didn't notice we already had bunch of them).

Quoted 35 lines · Linus Walleij
Quoted 20 lines · Matti
Quoted 4 lines

They all seem to have trickle and fast charging, USB phy interaction and AC plug interaction of some kind for detecting those and in some cases temperature detection directly or using an ADC.

Yes. That's pretty much what these ROHM chips have. But SW mostly needs
to set the limit values - it does not need to participate in state changing and most of these things are also something users do not care
(I guess). Fuel gauging is other topic but I'm not planning to implement it for in-tree drivers at least for now :/

The thing that comes to (my) mind is just a common DT properties for
input current/voltage limits, battery voltages for switching to next
charging state, current values for different charging states - and parsing of these properties.

Quoted 10 lines

I've seen some comments about DT not being a good place for battery specific properties as batteries may be replaced with another having
different type - but I don't think this is valid problem for many of
the devices today. Of course some devices may have batteries that can
be changed - but many don't - and for those it is perfectly Ok to have
battery data defined in DT, right?

Quoted 6 lines

If something is a property of the charging circuit, then it can be derived
from the compatible value, so anything that is just peculiar for this chip version doesn't go into device tree, just use a custom struct and
the match data for that.

Agree. Assuming the limitation comes from charging circuit itself. But I thought that for example some input current limits might come from the external circuitry (neither from charger, nor from battery).

Quoted 4 lines

Then we have the battery. I suppose that could be defined as a DT node for the battery itself, and not as part of the charging IC, and we
should think about how to create a battery DT binding.

Oh, yes. This is my newest mistake. We already seem to have the "simple-battery" bindings and a helper to retrieve given configs. After I understood that I noticed that there is only couple of bindings I might add there.

Quoted 9 lines

What
characteristics are chargers really interested in? This could be some work.

If different devices have different batteries then the boot loader could ideally patch the DT with the right battery. This was the solution
advocated for devices with different display panels, to a question from Hans de Goede at one point IIRC.

Hmm. This sounds simpler than adding bunch of charger drivers in boot loader. OTOH, if boot loader can detect the type of the battery, then I see why linux couldn't? And if type of battery can be hard-coded in boot, then I don't see why it couldn't be hard-coded in DT. But this all goes far beyond my area of expertice ;)

Quoted 9 lines
Quoted 4 lines

But ... do we need to provide a way for user-space to configure these
settings instead of the DT? Or any other possible sources for this information?

What we usually have said is that "policy should be in userspace" and "kernel manages hardware". This creates a not-so-small grey area in between and it is unfortunately up to interpretation.

Quoted 7 lines

Today there is also a THIRD alternative, and that is to let userspace insert a policy using a BPF program. This is the approach taken by the network and tracing stacks and we look at more applications. If the kernel needs to be able to handle charging and emergencies even if userspace is not up or available, this or other
userspace policies are not viable.

Just as a theoretical discussion this is interesting topic. I think the fuel-gauge might be area where we could want to avoid waking up the user-space when states change. But for my current crusade to power- supply-world we are mostly limited to one-time configurations like battery properties and system constraints for input currents etc.

Quoted 3 lines

I have a strong feeling that it should be a battery node in the device
tree.

Yes. Now that I learned about it - mostly so. Except the input current limits and VSYS regulation.

Quoted 16 lines
Quoted 6 lines

Hmm. If changing means state changes - then these ROHM chips probably
play no role here as there the HW does most of the state changes autonomously. (AFAIR, it's been a while since I looked at the other but
BD99954).

Good it's a simpler hardware. We just need to think about making the code reusable.

Quoted 5 lines

So ... If I extract the linear_range code from BD70528 driver (it should be usable for the BD99954 as such) - should I place it to some
common header/lib? (This is plain integer math so I don't like the idea of placing it in fixp-arith.h).

Quoted 3 lines

Start with moving it to some separate file, like power_supply_interpolation.c that we just always compile in and we can take it from there.

Oh, that's pretty much what I did :) And that is pretty much the only patch that makes sense in this first RFC version :|

Quoted 3 lines

Just some thoughts...

Thanks Linus. I _really_ appreciate your time and help! :)

Best Regards,
Matti Vaittinen

#7 lore raw
Quoted 8 lines · Matti
Quoted 5 lines · Linus Walleij

If different devices have different batteries then the boot loader could ideally patch the DT with the right battery. This was the solution
advocated for devices with different display panels, to a question from Hans de Goede at one point IIRC.

Quoted 5 lines

Hmm. This sounds simpler than adding bunch of charger drivers in boot loader. OTOH, if boot loader can detect the type of the battery, then I see why linux couldn't? And if type of battery can be hard-coded in boot, then I don't see why it couldn't be hard-coded in DT. But this all goes far beyond my area of expertice ;)

It's a gray area.

The boot loader, as well as the kernel, can detect the presence of some specific battery and screen using e.g. probing with i2c addresses or by reading GPIO lines or some other magic number such as the serial number of the device.

The kernel does have similar code in some places. Also the function where we enter is module is deceptively named "probe()".

So at some point it was common practice for the kernel to do this.

After the introduction of device tree, there has been some pushback from boot architecture people (this is the name for people doing thinking around DT, ACPI, UEFI and U-Boot) that this kind of funny probing code should be done in the boot loader, then the boot loader need to figure out how the device tree should actually look, construct it and pass the result to the kernel. This works for anything that detectable and not hot-plugged.

As we are in parallel, especially on the ARM architectures, pushing a "single kernel image" concept this makes a lot of sense, so we keep down the number of funny probing code in that single kernel image.

Maybe we should actually write this up somewhere. (Or it is already?) I only picked the above up from misc conversations.

Yours,
Linus Walleij

#8 lore raw

Hello Linus,

Quoted 27 lines · Linus Walleij
Quoted 9 lines · Matti
Quoted 7 lines · Linus Walleij

If different devices have different batteries then the boot loader
could ideally patch the DT with the right battery. This was the solution
advocated for devices with different display panels, to a question
from Hans de Goede at one point IIRC.

Quoted 8 lines

Hmm. This sounds simpler than adding bunch of charger drivers in boot
loader. OTOH, if boot loader can detect the type of the battery, then I
see why linux couldn't? And if type of battery can be hard-coded in boot, then I don't see why it couldn't be hard-coded in DT. But this
all goes far beyond my area of expertice ;)

It's a gray area.

The boot loader, as well as the kernel, can detect the presence of some specific battery and screen using e.g. probing with i2c addresses or by reading GPIO lines or some other magic number such as the serial number of the device.

Quoted 4 lines

The kernel does have similar code in some places. Also the function where we enter is module is deceptively named "probe()".

So at some point it was common practice for the kernel to do this.

Hm. I think I've seen some i2c drivers doing cool probing to detect if connected decvice is what it is expected to be :) So this didn't really come as surprize to me :)

Quoted 8 lines

After the introduction of device tree, there has been some pushback from boot architecture people (this is the name for people doing thinking around DT, ACPI, UEFI and U-Boot) that this kind of funny probing code should be done in the boot loader, then the boot loader need to figure out how the device tree should actually look, construct
it and pass the result to the kernel. This works for anything that detectable and not hot-plugged.

Ah. I didn't know about this push. Besides, this may fall apart when hot-plug comes to play :/

Although, I once worked with a device that had pluggable cards - each of the different type of cards had a dt-binary blob on on-board eeprom describing the contents of this card - and when the card was plugged in the processor was reading the EEPROM and did overlay merging of the found dt-blob. That made devices on plugged card detected and usable. If card was removed the dt-overlay was removed... Oh, that was a fancy project all in all :)

Quoted 7 lines

As we are in parallel, especially on the ARM architectures, pushing a "single kernel image" concept this makes a lot of sense, so we keep down the number of funny probing code in that single kernel image.

Maybe we should actually write this up somewhere. (Or it is already?) I only picked the above up from misc conversations.

Well, that would be helpful - assuming the reader is able to look up the documentation - I know that some people fail on this occasionally *ahem*

Anyways, thanks for the explanation!

Best Regards
Matti Vaittinen