Devicetree
 help / color / mirror / Atom feed
* [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms
@ 2026-11-13 15:56 Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels Luca Weiss
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Luca Weiss @ 2026-11-13 15:56 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano
  Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree, Luca Weiss, Konrad Dybcio

This implements a 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. Patching a kernel
per-device is obviously nothing we can put upstream.

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

See RFC for other variants or alternatives considered.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
Changes in v3:
- Expand commit message on dt-bindings patch (Rob)
- Some commit message improvements in generic-adc patch (Andy)
- Fix dt node location, move higher up (Konrad)
- Pick up tags
- Link to v2: https://lore.kernel.org/r/20260220-bat-temp-adc-v2-0-fe34ed4ea851@fairphone.com

Changes in v2:
- Rebase on linux-next (a different patch to add IIO to
  generic-adc-thermal has already landed upstream)
- Un-mark as RFC
- Link to v1: https://lore.kernel.org/r/20251010-bat-temp-adc-v1-0-d51ec895dac6@fairphone.com

---
Luca Weiss (5):
      iio: adc: qcom-spmi-adc5: Add battery thermal channels
      dt-bindings: thermal: generic-adc: Document #io-channel-cells
      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              | 20 +++---
 include/linux/iio/adc/qcom-vadc-common.h           |  3 +
 7 files changed, 147 insertions(+), 9 deletions(-)
---
base-commit: 6aa7dbf8ad5ebd3babf53a4d6209018f86939f17
change-id: 20251010-bat-temp-adc-8539bf0b85bc

Best regards,
--  
Luca Weiss <luca.weiss@fairphone.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels
  2026-11-13 15:56 [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms Luca Weiss
@ 2026-11-13 15:56 ` Luca Weiss
  2026-11-13 16:17   ` sashiko-bot
  2026-11-13 16:24   ` Andy Shevchenko
  2026-11-13 15:56 ` [PATCH v3 2/5] dt-bindings: thermal: generic-adc: Document #io-channel-cells Luca Weiss
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 9+ messages in thread
From: Luca Weiss @ 2026-11-13 15:56 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano
  Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree, Luca Weiss

Add the BAT_THERM channels with millivolt as output, which can then be
used along with information regarding the NTC in the battery, to get the
actual battery temperature.

A static lookup table in the ADC driver won't work since different
devices have different Ohm and Beta values in their battery NTCs, for
example a NTC can be 10kOhm & B=3435K.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
 drivers/iio/adc/qcom-spmi-adc5.c         |  6 ++++++
 drivers/iio/adc/qcom-vadc-common.c       | 16 ++++++++++++++++
 include/linux/iio/adc/qcom-vadc-common.h |  3 +++
 3 files changed, 25 insertions(+)

diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
index d57ba8526e0c..24ac84580570 100644
--- a/drivers/iio/adc/qcom-spmi-adc5.c
+++ b/drivers/iio/adc/qcom-spmi-adc5.c
@@ -542,6 +542,12 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
 					SCALE_HW_CALIB_DEFAULT)
 	[ADC5_XO_THERM_100K_PU]	= ADC5_CHAN_TEMP("xo_therm", 0,
 					SCALE_HW_CALIB_XOTHERM)
+	[ADC5_BAT_THERM_30K_PU]	= ADC5_CHAN_VOLT("bat_therm_30k_pu", 0,
+					SCALE_HW_CALIB_THERM_VOLT)
+	[ADC5_BAT_THERM_100K_PU] = ADC5_CHAN_VOLT("bat_therm_100k_pu", 0,
+					SCALE_HW_CALIB_THERM_VOLT)
+	[ADC5_BAT_THERM_400K_PU] = ADC5_CHAN_VOLT("bat_therm_400k_pu", 0,
+					SCALE_HW_CALIB_THERM_VOLT)
 	[ADC5_BAT_ID_100K_PU]	= ADC5_CHAN_TEMP("bat_id", 0,
 					SCALE_HW_CALIB_DEFAULT)
 	[ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
index b03cf584b165..09a13e2b0ef4 100644
--- a/drivers/iio/adc/qcom-vadc-common.c
+++ b/drivers/iio/adc/qcom-vadc-common.c
@@ -309,6 +309,10 @@ static int qcom_vadc_scale_hw_calib_therm(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
 				u16 adc_code, int *result_mdec);
+static int qcom_vadc_scale_hw_calib_therm_volt(
+				const struct u32_fract *prescale,
+				const struct adc5_data *data,
+				u16 adc_code, int *result_mdec);
 static int qcom_vadc7_scale_hw_calib_therm(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
@@ -333,6 +337,7 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
 static const struct qcom_adc5_scale_type scale_adc5_fn[] = {
 	[SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
 	[SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
+	[SCALE_HW_CALIB_THERM_VOLT] = {qcom_vadc_scale_hw_calib_therm_volt},
 	[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
 	[SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
 					qcom_vadc7_scale_hw_calib_therm},
@@ -583,6 +588,17 @@ static int qcom_vadc_scale_hw_calib_therm(
 				 voltage, result_mdec);
 }
 
+static int qcom_vadc_scale_hw_calib_therm_volt(
+				const struct u32_fract *prescale,
+				const struct adc5_data *data,
+				u16 adc_code, int *result_uv)
+{
+	*result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
+				prescale, data, 1000);
+
+	return 0;
+}
+
 static int qcom_vadc_scale_hw_calib_die_temp(
 				const struct u32_fract *prescale,
 				const struct adc5_data *data,
diff --git a/include/linux/iio/adc/qcom-vadc-common.h b/include/linux/iio/adc/qcom-vadc-common.h
index 3bf4c49726a7..ce037994b019 100644
--- a/include/linux/iio/adc/qcom-vadc-common.h
+++ b/include/linux/iio/adc/qcom-vadc-common.h
@@ -93,6 +93,8 @@ struct vadc_linear_graph {
  *	voltage (uV) with hardware applied offset/slope values to adc code.
  * @SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using
  *	lookup table. The hardware applies offset/slope to adc code.
+ * @SCALE_HW_CALIB_THERM_VOLT: Returns voltage in uV of a temperature channel.
+ *	The hardware applies offset/slope to adc code.
  * @SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using
  *	100k pullup. The hardware applies offset/slope to adc code.
  * @SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using
@@ -114,6 +116,7 @@ enum vadc_scale_fn_type {
 	SCALE_PMI_CHG_TEMP,
 	SCALE_HW_CALIB_DEFAULT,
 	SCALE_HW_CALIB_THERM_100K_PULLUP,
+	SCALE_HW_CALIB_THERM_VOLT,
 	SCALE_HW_CALIB_XOTHERM,
 	SCALE_HW_CALIB_THERM_100K_PU_PM7,
 	SCALE_HW_CALIB_PMIC_THERM,

-- 
2.56.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/5] dt-bindings: thermal: generic-adc: Document #io-channel-cells
  2026-11-13 15:56 [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels Luca Weiss
@ 2026-11-13 15:56 ` Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 3/5] thermal/drivers/generic-adc: Allow probe without TZ registration Luca Weiss
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Luca Weiss @ 2026-11-13 15:56 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano
  Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree, Luca Weiss

Document the property to allow using this sensor with io-channels.

This means that the output of generic-adc-thermal can be used as an
input into a different node.

As a specific example, generic-adc-thermal takes in an ADC io-channel in
Volt, outputs temperature in degC, which can then be consumed by a fuel
gauge driver to provide the battery temperature readings to user space.

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
 Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml b/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml
index 12e6418dc24d..317fc39ed46a 100644
--- a/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/generic-adc-thermal.yaml
@@ -24,6 +24,9 @@ properties:
   '#thermal-sensor-cells':
     const: 0
 
+  "#io-channel-cells":
+    const: 0
+
   io-channels:
     maxItems: 1
 
@@ -58,6 +61,7 @@ examples:
     thermal-sensor {
         compatible = "generic-adc-thermal";
         #thermal-sensor-cells = <0>;
+        #io-channel-cells = <0>;
         io-channels = <&ads1015 1>;
         io-channel-names = "sensor-channel";
         temperature-lookup-table = <

-- 
2.56.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/5] thermal/drivers/generic-adc: Allow probe without TZ registration
  2026-11-13 15:56 [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 2/5] dt-bindings: thermal: generic-adc: Document #io-channel-cells Luca Weiss
@ 2026-11-13 15:56 ` Luca Weiss
  2026-11-13 16:28   ` Andy Shevchenko
  2026-11-13 15:56 ` [PATCH v3 4/5] arm64: dts: qcom: pm7250b: Define battery temperature ADC channels Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 5/5] arm64: dts: qcom: sm7225-fairphone-fp4: Add battery temperature node Luca Weiss
  4 siblings, 1 reply; 9+ messages in thread
From: Luca Weiss @ 2026-11-13 15:56 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano
  Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree, Luca Weiss

If the devicetree node is not referenced in a zone under /thermal-zones,
devm_thermal_of_zone_register() will fail with -ENODEV.

Since the driver is now also registering as an IIO device[0], allow the
probe to continue without the thermal zone.

We also can't use gadc_thermal_get_temp() anymore because we haven't
necessarily initialized tz_dev.

Link: https://git.kernel.org/torvalds/c/3762f5851ac5 [0]
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
 drivers/thermal/thermal-generic-adc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index c6a7a65aa6a6..40a34e97a515 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -86,14 +86,16 @@ static int gadc_thermal_read_raw(struct iio_dev *indio_dev,
 				 int *val, int *val2, long mask)
 {
 	struct gadc_thermal_info *gtinfo = iio_priv(indio_dev);
+	int iio_val;
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_PROCESSED:
-		ret = gadc_thermal_get_temp(gtinfo->tz_dev, val);
-		if (ret)
+		ret = iio_read_channel_processed(gtinfo->channel, &iio_val);
+		if (ret < 0)
 			return ret;
 
+		*val = gadc_thermal_adc_to_temp(gtinfo, iio_val);
 		return IIO_VAL_INT;
 
 	default:
@@ -195,14 +197,14 @@ static int gadc_thermal_probe(struct platform_device *pdev)
 						    &gadc_thermal_ops);
 	if (IS_ERR(gti->tz_dev)) {
 		ret = PTR_ERR(gti->tz_dev);
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev,
-				"Thermal zone sensor register failed: %d\n",
-				ret);
-		return ret;
-	}
+		if (ret != -ENODEV)
+			return ret;
 
-	devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev);
+		dev_info(dev, "Thermal zone sensor register failed: %d\n",
+			 ret);
+	} else {
+		devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev);
+	}
 
 	return gadc_iio_register(&pdev->dev, gti);
 }

-- 
2.56.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/5] arm64: dts: qcom: pm7250b: Define battery temperature ADC channels
  2026-11-13 15:56 [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms Luca Weiss
                   ` (2 preceding siblings ...)
  2026-11-13 15:56 ` [PATCH v3 3/5] thermal/drivers/generic-adc: Allow probe without TZ registration Luca Weiss
@ 2026-11-13 15:56 ` Luca Weiss
  2026-11-13 15:56 ` [PATCH v3 5/5] arm64: dts: qcom: sm7225-fairphone-fp4: Add battery temperature node Luca Weiss
  4 siblings, 0 replies; 9+ messages in thread
From: Luca Weiss @ 2026-11-13 15:56 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano
  Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree, Luca Weiss, Konrad Dybcio

Add the definition for these ADC channels to the PM7250B definition.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
 arch/arm64/boot/dts/qcom/pm7250b.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/pm7250b.dtsi b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
index 43cab07126c5..91e83587adf2 100644
--- a/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm7250b.dtsi
@@ -155,6 +155,22 @@ channel@1e {
 				label = "chg_mid";
 			};
 
+			channel@2a {
+				reg = <ADC5_BAT_THERM_30K_PU>;
+				qcom,hw-settle-time = <200>;
+				qcom,pre-scaling = <1 1>;
+				qcom,ratiometric;
+				label = "bat_therm_30k";
+			};
+
+			channel@4a {
+				reg = <ADC5_BAT_THERM_100K_PU>;
+				qcom,hw-settle-time = <200>;
+				qcom,pre-scaling = <1 1>;
+				qcom,ratiometric;
+				label = "bat_therm_100k";
+			};
+
 			channel@4b {
 				reg = <ADC5_BAT_ID_100K_PU>;
 				qcom,hw-settle-time = <200>;
@@ -163,6 +179,14 @@ channel@4b {
 				label = "bat_id";
 			};
 
+			channel@6a {
+				reg = <ADC5_BAT_THERM_400K_PU>;
+				qcom,hw-settle-time = <200>;
+				qcom,pre-scaling = <1 1>;
+				qcom,ratiometric;
+				label = "bat_therm_400k";
+			};
+
 			channel@83 {
 				reg = <ADC5_VPH_PWR>;
 				qcom,pre-scaling = <1 3>;

-- 
2.56.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 5/5] arm64: dts: qcom: sm7225-fairphone-fp4: Add battery temperature node
  2026-11-13 15:56 [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms Luca Weiss
                   ` (3 preceding siblings ...)
  2026-11-13 15:56 ` [PATCH v3 4/5] arm64: dts: qcom: pm7250b: Define battery temperature ADC channels Luca Weiss
@ 2026-11-13 15:56 ` Luca Weiss
  4 siblings, 0 replies; 9+ messages in thread
From: Luca Weiss @ 2026-11-13 15:56 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano
  Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree, Luca Weiss

Add a generic-adc-thermal node to convert the voltage read by the
battery temperature ADC into degree Celsius using the provided lookup
table.

This will later be used as input for the fuel gauge node (QGauge on the
PM7250B).

Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
 arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts | 83 +++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
index 37aa272019cc..0b8c6f353f96 100644
--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -96,6 +96,89 @@ memory@efe01000 {
 		};
 	};
 
+	bat_therm_sensor: thermal-sensor-bat-therm {
+		compatible = "generic-adc-thermal";
+		#thermal-sensor-cells = <0>;
+		#io-channel-cells = <0>;
+		io-channels = <&pm7250b_adc ADC5_BAT_THERM_30K_PU>;
+		io-channel-names = "sensor-channel";
+		/*
+		 * Voltage to temperature table for 10kΩ (B=3435K) NTC with a
+		 * 1.875V reference and 30kΩ pull-up.
+		 */
+		temperature-lookup-table = <
+			(-40000) 1673
+			(-38000) 1649
+			(-36000) 1623
+			(-34000) 1596
+			(-32000) 1566
+			(-30000) 1535
+			(-28000) 1502
+			(-26000) 1467
+			(-24000) 1430
+			(-22000) 1392
+			(-20000) 1352
+			(-18000) 1311
+			(-16000) 1269
+			(-14000) 1226
+			(-12000) 1182
+			(-10000) 1138
+			 (-8000) 1093
+			 (-6000) 1049
+			 (-4000) 1004
+			 (-2000) 960
+			       0 917
+			    2000 874
+			    4000 832
+			    6000 791
+			    8000 752
+			   10000 713
+			   12000 676
+			   14000 640
+			   16000 606
+			   18000 573
+			   20000 541
+			   22000 511
+			   24000 483
+			   26000 455
+			   28000 430
+			   30000 405
+			   32000 382
+			   34000 360
+			   36000 340
+			   38000 320
+			   40000 302
+			   42000 285
+			   44000 269
+			   46000 253
+			   48000 239
+			   50000 225
+			   52000 213
+			   54000 201
+			   56000 190
+			   58000 179
+			   60000 169
+			   62000 160
+			   64000 152
+			   66000 143
+			   68000 136
+			   70000 128
+			   72000 122
+			   74000 115
+			   76000 109
+			   78000 104
+			   80000 98
+			   82000 93
+			   84000 89
+			   86000 84
+			   88000 80
+			   90000 76
+			   92000 73
+			   94000 69
+			   96000 66
+			   98000 63>;
+	};
+
 	msm_therm_sensor: thermal-sensor-msm {
 		compatible = "generic-adc-thermal";
 		#thermal-sensor-cells = <0>;

-- 
2.56.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels
  2026-11-13 15:56 ` [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels Luca Weiss
@ 2026-11-13 16:17   ` sashiko-bot
  2026-11-13 16:24   ` Andy Shevchenko
  1 sibling, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-11-13 16:17 UTC (permalink / raw)
  To: Luca Weiss; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Low] iio: adc: qcom-vadc: unit mismatch in
  qcom_vadc_scale_hw_calib_therm_volt()
--

commit e0ceb603a8d45a55cad2b26a93189eb6391e4af4
Author: Luca Weiss <luca.weiss@fairphone.com>

iio: adc: qcom-spmi-adc5: Add battery thermal channels

This commit adds ADC5_BAT_THERM_30K_PU, ADC5_BAT_THERM_100K_PU, and
ADC5_BAT_THERM_400K_PU voltage channels and the SCALE_HW_CALIB_THERM_VOLT
scaling type for reading battery thermistor voltages.

> diff --git a/drivers/iio/adc/qcom-spmi-adc5.c b/drivers/iio/adc/qcom-spmi-adc5.c
> index d57ba8526e0c5..24ac845805705 100644
> --- a/drivers/iio/adc/qcom-spmi-adc5.c
> +++ b/drivers/iio/adc/qcom-spmi-adc5.c
> @@ -542,6 +542,12 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
>  					SCALE_HW_CALIB_DEFAULT)
>  	[ADC5_XO_THERM_100K_PU]	= ADC5_CHAN_TEMP("xo_therm", 0,
>  					SCALE_HW_CALIB_XOTHERM)
> +	[ADC5_BAT_THERM_30K_PU]	= ADC5_CHAN_VOLT("bat_therm_30k_pu", 0,
> +					SCALE_HW_CALIB_THERM_VOLT)
> +	[ADC5_BAT_THERM_100K_PU] = ADC5_CHAN_VOLT("bat_therm_100k_pu", 0,
> +					SCALE_HW_CALIB_THERM_VOLT)
> +	[ADC5_BAT_THERM_400K_PU] = ADC5_CHAN_VOLT("bat_therm_400k_pu", 0,
> +					SCALE_HW_CALIB_THERM_VOLT)
>  	[ADC5_BAT_ID_100K_PU]	= ADC5_CHAN_TEMP("bat_id", 0,
>  					SCALE_HW_CALIB_DEFAULT)
>  	[ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
> diff --git a/drivers/iio/adc/qcom-vadc-common.c b/drivers/iio/adc/qcom-vadc-common.c
> index b03cf584b1657..09a13e2b0ef43 100644
> --- a/drivers/iio/adc/qcom-vadc-common.c
> +++ b/drivers/iio/adc/qcom-vadc-common.c
> @@ -309,6 +309,10 @@ static int qcom_vadc_scale_hw_calib_therm(
>  				const struct u32_fract *prescale,
>  				const struct adc5_data *data,
>  				u16 adc_code, int *result_mdec);
> +static int qcom_vadc_scale_hw_calib_therm_volt(
> +				const struct u32_fract *prescale,
> +				const struct adc5_data *data,
> +				u16 adc_code, int *result_mdec);
>  static int qcom_vadc7_scale_hw_calib_therm(
>  				const struct u32_fract *prescale,
>  				const struct adc5_data *data,
> @@ -333,6 +337,7 @@ static int qcom_vadc7_scale_hw_calib_die_temp(
>  static const struct qcom_adc5_scale_type scale_adc5_fn[] = {
>  	[SCALE_HW_CALIB_DEFAULT] = {qcom_vadc_scale_hw_calib_volt},
>  	[SCALE_HW_CALIB_THERM_100K_PULLUP] = {qcom_vadc_scale_hw_calib_therm},
> +	[SCALE_HW_CALIB_THERM_VOLT] = {qcom_vadc_scale_hw_calib_therm_volt},
>  	[SCALE_HW_CALIB_XOTHERM] = {qcom_vadc_scale_hw_calib_therm},
>  	[SCALE_HW_CALIB_THERM_100K_PU_PM7] = {
>  					qcom_vadc7_scale_hw_calib_therm},
> @@ -583,6 +588,17 @@ static int qcom_vadc_scale_hw_calib_therm(
>  				 voltage, result_mdec);
>  }
>  
> +static int qcom_vadc_scale_hw_calib_therm_volt(
> +				const struct u32_fract *prescale,
> +				const struct adc5_data *data,
> +				u16 adc_code, int *result_uv)
> +{
> +	*result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
> +				prescale, data, 1000);
> +
> +	return 0;
> +}
> +
>  static int qcom_vadc_scale_hw_calib_die_temp(
>  				const struct u32_fract *prescale,
>  				const struct adc5_data *data,
> diff --git a/include/linux/iio/adc/qcom-vadc-common.h b/include/linux/iio/adc/qcom-vadc-common.h
> index 3bf4c49726a73..ce037994b0197 100644
> --- a/include/linux/iio/adc/qcom-vadc-common.h
> +++ b/include/linux/iio/adc/qcom-vadc-common.h
> @@ -93,6 +93,8 @@ struct vadc_linear_graph {
>   *	voltage (uV) with hardware applied offset/slope values to adc code.
>   * @SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using
>   *	lookup table. The hardware applies offset/slope to adc code.
> + * @SCALE_HW_CALIB_THERM_VOLT: Returns voltage in uV of a temperature channel.
> + *	The hardware applies offset/slope to adc code.

[Severity: Low]
Is there a unit mismatch in qcom_vadc_scale_hw_calib_therm_volt() and the
new ADC5_CHAN_VOLT channels?

qcom_vadc_scale_code_voltage_factor() computes microvolts and divides by
factor, so passing factor = 1000 returns integer millivolts rather than
microvolts:

drivers/iio/adc/qcom-vadc-common.c:qcom_vadc_scale_code_voltage_factor() {
    ...
	/* (ADC code * vref_vadc (1.875V)) / full_scale_code */
	voltage = (s64) adc_code * adc_vdd_ref_mv * 1000;
	voltage = div64_s64(voltage, data->full_scale_code_volt);
	if (voltage > 0) {
		voltage *= prescale->denominator;
		temp = prescale->numerator * factor;
		voltage = div64_s64(voltage, temp);
    ...
}

However, the kernel-doc for SCALE_HW_CALIB_THERM_VOLT and the definition of
qcom_vadc_scale_hw_calib_therm_volt() state that the result is in uV
(result_uv), while its forward declaration names the parameter result_mdec.
In addition, all other ADC5_CHAN_VOLT channels in adc5_chans_pmic use
SCALE_HW_CALIB_DEFAULT (qcom_vadc_scale_hw_calib_volt(), which passes
factor = 1) and return microvolts, so returning integer millivolts here
creates a 1000x unit inconsistency across ADC5_CHAN_VOLT channels and
truncates sub-millivolt precision.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261113-bat-temp-adc-v3-0-743979a8fd90@fairphone.com?part=1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels
  2026-11-13 15:56 ` [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels Luca Weiss
  2026-11-13 16:17   ` sashiko-bot
@ 2026-11-13 16:24   ` Andy Shevchenko
  1 sibling, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:24 UTC (permalink / raw)
  To: Luca Weiss
  Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano,
	~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree

On Fri, Nov 13, 2026 at 04:56:42PM +0100, Luca Weiss wrote:
> Add the BAT_THERM channels with millivolt as output, which can then be
> used along with information regarding the NTC in the battery, to get the
> actual battery temperature.
> 
> A static lookup table in the ADC driver won't work since different
> devices have different Ohm and Beta values in their battery NTCs, for
> example a NTC can be 10kOhm & B=3435K.

...

> +static int qcom_vadc_scale_hw_calib_therm_volt(

This is broken indentation. Was `clang-format` being used to achieve that?

> +				const struct u32_fract *prescale,
> +				const struct adc5_data *data,
> +				u16 adc_code, int *result_uv)

result_uV

> +{
> +	*result_uv = qcom_vadc_scale_code_voltage_factor(adc_code,
> +				prescale, data, 1000);

1000 is odd, can you use something from units.h or combination of those
to show what this multiplier is for?

> +	return 0;
> +}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 3/5] thermal/drivers/generic-adc: Allow probe without TZ registration
  2026-11-13 15:56 ` [PATCH v3 3/5] thermal/drivers/generic-adc: Allow probe without TZ registration Luca Weiss
@ 2026-11-13 16:28   ` Andy Shevchenko
  0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:28 UTC (permalink / raw)
  To: Luca Weiss
  Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Rafael J. Wysocki, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Laxman Dewangan,
	Bjorn Andersson, Konrad Dybcio, Hans de Goede, Jens Reidel,
	Casey Connolly, Val Packett, Daniel Lezcano,
	~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-iio,
	linux-kernel, linux-pm, devicetree

On Fri, Nov 13, 2026 at 04:56:44PM +0100, Luca Weiss wrote:
> If the devicetree node is not referenced in a zone under /thermal-zones,
> devm_thermal_of_zone_register() will fail with -ENODEV.
> 
> Since the driver is now also registering as an IIO device[0], allow the
> probe to continue without the thermal zone.
> 
> We also can't use gadc_thermal_get_temp() anymore because we haven't
> necessarily initialized tz_dev.

...

>  	if (IS_ERR(gti->tz_dev)) {
>  		ret = PTR_ERR(gti->tz_dev);
> -		if (ret != -EPROBE_DEFER)
> -			dev_err(dev,
> -				"Thermal zone sensor register failed: %d\n",
> -				ret);
> -		return ret;
> -	}
> +		if (ret != -ENODEV)
> +			return ret;
>  
> -	devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev);

> +		dev_info(dev, "Thermal zone sensor register failed: %d\n",
> +			 ret);

It fits one line.

> +	} else {
> +		devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev);
> +	}

Can we write it as

	ret = PTR_ERR_OR_ZERO(gti->tz_dev);
	if (ret == -ENODEV)
		dev_info(dev, "Thermal zone sensor register failed: %d\n", ret);
	else if (ret)
		return ret;
	else
		devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev);

?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-11-13 16:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13 15:56 [PATCH v3 0/5] Battery temperature ADC plumbing on Qualcomm platforms Luca Weiss
2026-11-13 15:56 ` [PATCH v3 1/5] iio: adc: qcom-spmi-adc5: Add battery thermal channels Luca Weiss
2026-11-13 16:17   ` sashiko-bot
2026-11-13 16:24   ` Andy Shevchenko
2026-11-13 15:56 ` [PATCH v3 2/5] dt-bindings: thermal: generic-adc: Document #io-channel-cells Luca Weiss
2026-11-13 15:56 ` [PATCH v3 3/5] thermal/drivers/generic-adc: Allow probe without TZ registration Luca Weiss
2026-11-13 16:28   ` Andy Shevchenko
2026-11-13 15:56 ` [PATCH v3 4/5] arm64: dts: qcom: pm7250b: Define battery temperature ADC channels Luca Weiss
2026-11-13 15:56 ` [PATCH v3 5/5] arm64: dts: qcom: sm7225-fairphone-fp4: Add battery temperature node Luca Weiss

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox