[PATCH RFC 0/6] Battery temperature ADC plumbing on Qualcomm platforms

Luca Weiss posted 6 patches 3 months, 4 weeks ago
.../bindings/thermal/generic-adc-thermal.yaml      |  4 ++
arch/arm64/boot/dts/qcom/pm7250b.dtsi              | 24 +++++++
arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts  | 83 ++++++++++++++++++++++
drivers/iio/adc/qcom-spmi-adc5.c                   |  6 ++
drivers/iio/adc/qcom-vadc-common.c                 | 16 +++++
drivers/thermal/thermal-generic-adc.c              | 68 ++++++++++++++++--
include/linux/iio/adc/qcom-vadc-common.h           |  3 +
7 files changed, 198 insertions(+), 6 deletions(-)
[PATCH RFC 0/6] Battery temperature ADC plumbing on Qualcomm platforms
Posted by Luca Weiss 3 months, 4 weeks ago
This is an RFC which implements a potential solution to get battery
temperature readings working on for example smartphones with Qualcomm
SoCs.

The solution chosen in downstream Qualcomm kernels is exposing
ADC_BAT_THERM_PU* in the ADC driver as temperature channels with the
lookup table ("struct vadc_map_pt") for the specific NTC found in a
device's battery patched to adjust the lookup table.

The high level solution proposed here:
* ADC driver provides temperature channel in (milli)volt as IIO channel
* generic-adc-thermal driver converts voltage to temperature based on
  provided lookup table from DT (driver has one IIO channel input, one
  IIO channel output)
* The fuel gauge driver can use that temperature IIO channel to expose
  battery temperature via the power supply device

Variants/alternatives considered:

1. Do not implement IIO device in generic-adc-thermal

Without an IIO channel and using thermal zone directly it becomes more
difficult. You cannot get thermal zone by reference (e.g.
thermal-sensors = <&foo>;). The function thermal_zone_get_zone_by_name()
exists but lookup by name is kinda clunky. Adding by-phandle support
might be possible but is lots of work. It also doesn't really look like
thermal-sensor is really meant to be used by other drivers. E.g.
there's also no "thermal-sensor-names" property to designate passing
multiple thermal sensors. So I believe IIO is a better fitting API for
this.

2. Expose IIO channel as temperature in ADC driver

This would require passing in the temperature lookup table somehow to
the ADC driver via DT. I think this passes too many details about the
hardware that's connected into the ADC driver. While possible, at least
for Qcom ADC there's no precedent yet.

3. Add temperature-lookup-table as property to simple-battery

Since the NTC is a part of the battery pack, adding a
temperature-lookup-table property to simple-battery would make sense
instead of having this lookup table be standalone in the
generic-adc-thermal node. However being able to re-use the existing code
in generic-adc-thermal lead me to the current proposal.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
Luca Weiss (6):
      iio: adc: qcom-spmi-adc5: Add battery thermal channels
      dt-bindings: thermal: generic-adc: Document #io-channel-cells
      thermal/drivers/generic-adc: Register as IIO device
      thermal/drivers/generic-adc: Allow probe without TZ registration
      arm64: dts: qcom: pm7250b: Define battery temperature ADC channels
      arm64: dts: qcom: sm7225-fairphone-fp4: Add battery temperature node

 .../bindings/thermal/generic-adc-thermal.yaml      |  4 ++
 arch/arm64/boot/dts/qcom/pm7250b.dtsi              | 24 +++++++
 arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts  | 83 ++++++++++++++++++++++
 drivers/iio/adc/qcom-spmi-adc5.c                   |  6 ++
 drivers/iio/adc/qcom-vadc-common.c                 | 16 +++++
 drivers/thermal/thermal-generic-adc.c              | 68 ++++++++++++++++--
 include/linux/iio/adc/qcom-vadc-common.h           |  3 +
 7 files changed, 198 insertions(+), 6 deletions(-)
---
base-commit: 6063257da111c7639d020c5f15bfb37fb839d8b6
change-id: 20251010-bat-temp-adc-8539bf0b85bc

Best regards,
-- 
Luca Weiss <luca.weiss@fairphone.com>
Re: [PATCH RFC 0/6] Battery temperature ADC plumbing on Qualcomm platforms
Posted by David Lechner 3 months, 4 weeks ago
On 10/10/25 6:21 AM, Luca Weiss wrote:
> This is an RFC which implements a potential solution to get battery
> temperature readings working on for example smartphones with Qualcomm
> SoCs.
> 

...

> 3. Add temperature-lookup-table as property to simple-battery
> 
> Since the NTC is a part of the battery pack, adding a
> temperature-lookup-table property to simple-battery would make sense
> instead of having this lookup table be standalone in the
> generic-adc-thermal node. However being able to re-use the existing code
> in generic-adc-thermal lead me to the current proposal.
> 
Did you consider creating a specific compatible string for the battery pack?
Then the battery node could have the io-channels property for the ADC
connected to the temperature sensor. Then a specific battery driver could
handle the conversion as needed rather than filling the devicetree with
conversion tables.

The simple-battery bindings are already far from simple! So I would not
be inclined to add more to it.
Re: [PATCH RFC 0/6] Battery temperature ADC plumbing on Qualcomm platforms
Posted by Hans de Goede 3 months, 4 weeks ago
Hi All,

Luca thank you for Cc-ing me.

On 10-Oct-25 10:56 PM, David Lechner wrote:
> On 10/10/25 6:21 AM, Luca Weiss wrote:
>> This is an RFC which implements a potential solution to get battery
>> temperature readings working on for example smartphones with Qualcomm
>> SoCs.
>>
> 
> ...
> 
>> 3. Add temperature-lookup-table as property to simple-battery
>>
>> Since the NTC is a part of the battery pack, adding a
>> temperature-lookup-table property to simple-battery would make sense
>> instead of having this lookup table be standalone in the
>> generic-adc-thermal node. However being able to re-use the existing code
>> in generic-adc-thermal lead me to the current proposal.
>>
> Did you consider creating a specific compatible string for the battery pack?
> Then the battery node could have the io-channels property for the ADC
> connected to the temperature sensor. Then a specific battery driver could
> handle the conversion as needed rather than filling the devicetree with
> conversion tables.

That will require a driver update, filling the driver (and thus memory)
with conversion tables each time a new battery model (one model phone
can have multiple battery revisions) comes out.

That seems undesirable. To me these conversion tables are very much
something which belongs in DT rather then being hardcoded in
the driver.

Also contrast this to ACPI where there actually is a mechanism defined
for thermal lookup tables and there all these things typically just
work when the ACPI tables are written properly. IMHO we want to move
more towards this direction where things just work without requiring
kernel code changes for every new model.

And we already have a mechanism in DT to map an ADC voltage to
a temperature in the generic-adc-thermal driver.

So all that is left to do really is to come up with a clean way
to export the temperature from the generic-adc-thermal driver
to the generic-adc-battery driver.

> The simple-battery bindings are already far from simple! So I would not
> be inclined to add more to it.

I think we all agree on this and we also don't want to duplicate
the generic-adc-thermal bindings + code implementing that functionality.

IMHO not wanting to duplicate the bindings + functionality applies to
both: a) directly exporting an IIO temp channel from the ADC driver and
b) adding volt -> temp mapping functionality to the simple-battery bindings.

So that basically leaves us with coming up with a way for
the generic-adc-battery code to consume the temperature coming out of
the generic-adc-thermal code and there are 2 ways to do this:

1. Modify the generic-adc-thermal driver to export an IIO channel
2. Modify the thermal-zone core to allow referencing to a thermal-zone
   with a phandle *and* modify generic-adc-battery to be able to
   optionally get the temperature from a thermal-zone instead of
   from an IIO-channel

Of these two options 1. clear is the most KISS option. SO I agree with
Luca that 1. as implemented in this series is the best way forward.

Regards,

Hans
Re: [PATCH RFC 0/6] Battery temperature ADC plumbing on Qualcomm platforms
Posted by Jonathan Cameron 3 months, 3 weeks ago
On Sat, 11 Oct 2025 11:52:43 +0200
Hans de Goede <hansg@kernel.org> wrote:

> Hi All,
> 
> Luca thank you for Cc-ing me.
> 
> On 10-Oct-25 10:56 PM, David Lechner wrote:
> > On 10/10/25 6:21 AM, Luca Weiss wrote:  
> >> This is an RFC which implements a potential solution to get battery
> >> temperature readings working on for example smartphones with Qualcomm
> >> SoCs.
> >>  
> > 
> > ...
> >   
> >> 3. Add temperature-lookup-table as property to simple-battery
> >>
> >> Since the NTC is a part of the battery pack, adding a
> >> temperature-lookup-table property to simple-battery would make sense
> >> instead of having this lookup table be standalone in the
> >> generic-adc-thermal node. However being able to re-use the existing code
> >> in generic-adc-thermal lead me to the current proposal.
> >>  
> > Did you consider creating a specific compatible string for the battery pack?
> > Then the battery node could have the io-channels property for the ADC
> > connected to the temperature sensor. Then a specific battery driver could
> > handle the conversion as needed rather than filling the devicetree with
> > conversion tables.  
> 
> That will require a driver update, filling the driver (and thus memory)
> with conversion tables each time a new battery model (one model phone
> can have multiple battery revisions) comes out.
> 
> That seems undesirable. To me these conversion tables are very much
> something which belongs in DT rather then being hardcoded in
> the driver.
> 
> Also contrast this to ACPI where there actually is a mechanism defined
> for thermal lookup tables and there all these things typically just
> work when the ACPI tables are written properly. IMHO we want to move
> more towards this direction where things just work without requiring
> kernel code changes for every new model.
> 
> And we already have a mechanism in DT to map an ADC voltage to
> a temperature in the generic-adc-thermal driver.
> 
> So all that is left to do really is to come up with a clean way
> to export the temperature from the generic-adc-thermal driver
> to the generic-adc-battery driver.
> 
> > The simple-battery bindings are already far from simple! So I would not
> > be inclined to add more to it.  
> 
> I think we all agree on this and we also don't want to duplicate
> the generic-adc-thermal bindings + code implementing that functionality.
> 
> IMHO not wanting to duplicate the bindings + functionality applies to
> both: a) directly exporting an IIO temp channel from the ADC driver and
> b) adding volt -> temp mapping functionality to the simple-battery bindings.
> 
> So that basically leaves us with coming up with a way for
> the generic-adc-battery code to consume the temperature coming out of
> the generic-adc-thermal code and there are 2 ways to do this:
> 
> 1. Modify the generic-adc-thermal driver to export an IIO channel

Other than the fact this is embedded in an existing driver, this is just
a case of modelling an analog sensor in IIO. There's an ancient accelerometer
that does this and the analog fronted ends handle things like potential dividers
which are similar but with far simpler DT than this.

So conceptually I have no problem with the approach.

If we were starting from scratch we might have had an explicit representation
of the thermal sensor analog part (like our accelerometer), and then done

Generic temperature device sensor driver is consumer of the ADC channel.
generic-adc-thermal is consumer of the generic temp device sensor.

But retrofitting that split may be a pain (I haven't looked at this though so
maybe not!)



> 2. Modify the thermal-zone core to allow referencing to a thermal-zone
>    with a phandle *and* modify generic-adc-battery to be able to
>    optionally get the temperature from a thermal-zone instead of
>    from an IIO-channel
> 
> Of these two options 1. clear is the most KISS option. SO I agree with
> Luca that 1. as implemented in this series is the best way forward.
> 
> Regards,
> 
> Hans
> 
>
Re: [PATCH RFC 0/6] Battery temperature ADC plumbing on Qualcomm platforms
Posted by Nuno Sá 3 months, 4 weeks ago
On Fri, 2025-10-10 at 13:21 +0200, Luca Weiss wrote:
> This is an RFC which implements a potential solution to get battery
> temperature readings working on for example smartphones with Qualcomm
> SoCs.
> 
> The solution chosen in downstream Qualcomm kernels is exposing
> ADC_BAT_THERM_PU* in the ADC driver as temperature channels with the
> lookup table ("struct vadc_map_pt") for the specific NTC found in a
> device's battery patched to adjust the lookup table.
> 
> The high level solution proposed here:
> * ADC driver provides temperature channel in (milli)volt as IIO channel
> * generic-adc-thermal driver converts voltage to temperature based on
>   provided lookup table from DT (driver has one IIO channel input, one
>   IIO channel output)
> * The fuel gauge driver can use that temperature IIO channel to expose
>   battery temperature via the power supply device
> 
> Variants/alternatives considered:
> 
> 1. Do not implement IIO device in generic-adc-thermal
> 
> Without an IIO channel and using thermal zone directly it becomes more
> difficult. You cannot get thermal zone by reference (e.g.
> thermal-sensors = <&foo>;). The function thermal_zone_get_zone_by_name()
> exists but lookup by name is kinda clunky. Adding by-phandle support
> might be possible but is lots of work. It also doesn't really look like
> thermal-sensor is really meant to be used by other drivers. E.g.
> there's also no "thermal-sensor-names" property to designate passing
> multiple thermal sensors. So I believe IIO is a better fitting API for
> this.

The only thing that I dislike is that using IIO just feels like hacking around
the lack of an inkernel interface (as you pointed out and which IIO provides)
for thermal devices. My main question is, what makes this device an IIO device
despite the fact that we (you) want to use the IIO inkernel API (IIUC)? AFAIU,
the sensor is already being implemented as the ADC driver and this is just
convenience.

Anyways, that said, there's precedent (at least in 2 places) about registering
IIO devices outside of the subsystem.

Maybe we need the concept of an IIO proxy for the IIO inkernel interface. Like
consumers of IIO devices that can use some the measurements (channels), do
something with them and then be IIO providers. I guess I'm already rambling :)
 
> 
> 2. Expose IIO channel as temperature in ADC driver
> 
> This would require passing in the temperature lookup table somehow to
> the ADC driver via DT. I think this passes too many details about the
> hardware that's connected into the ADC driver. While possible, at least
> for Qcom ADC there's no precedent yet.

Not really familiar with the HW setup but (just for my understanding) why it
would not make sense to pass that info to the IIO driver? I guess that table is
just not part of the ADC?

> 
> 3. Add temperature-lookup-table as property to simple-battery
> 
> Since the NTC is a part of the battery pack, adding a
> temperature-lookup-table property to simple-battery would make sense
> instead of having this lookup table be standalone in the
> generic-adc-thermal node. However being able to re-use the existing code
> in generic-adc-thermal lead me to the current proposal.

What about turning it into a small lib module? No idea where to put it though.
But while I was thinking about this, your option 3 looks the one that makes more
sense to me.

My 2 cents!
- Nuno Sá


> 
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> Luca Weiss (6):
>       iio: adc: qcom-spmi-adc5: Add battery thermal channels
>       dt-bindings: thermal: generic-adc: Document #io-channel-cells
>       thermal/drivers/generic-adc: Register as IIO device
>       thermal/drivers/generic-adc: Allow probe without TZ registration
>       arm64: dts: qcom: pm7250b: Define battery temperature ADC channels
>       arm64: dts: qcom: sm7225-fairphone-fp4: Add battery temperature node
> 
>  .../bindings/thermal/generic-adc-thermal.yaml      |  4 ++
>  arch/arm64/boot/dts/qcom/pm7250b.dtsi              | 24 +++++++
>  arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts  | 83
> ++++++++++++++++++++++
>  drivers/iio/adc/qcom-spmi-adc5.c                   |  6 ++
>  drivers/iio/adc/qcom-vadc-common.c                 | 16 +++++
>  drivers/thermal/thermal-generic-adc.c              | 68 ++++++++++++++++--
>  include/linux/iio/adc/qcom-vadc-common.h           |  3 +
>  7 files changed, 198 insertions(+), 6 deletions(-)
> ---
> base-commit: 6063257da111c7639d020c5f15bfb37fb839d8b6
> change-id: 20251010-bat-temp-adc-8539bf0b85bc
> 
> Best regards,