.../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(-)
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>
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.
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
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 > >
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,
© 2016 - 2026 Red Hat, Inc.