Linux IIO development
 help / color / mirror / Atom feed
* [PATCH 0/1] iio: light: isl29018: cover-glass gain compensation via DT
@ 2026-06-04  5:47 Herman van Hazendonk
  2026-06-04  5:47 ` [PATCH 1/1] iio: light: isl29018: support " Herman van Hazendonk
  2026-06-04  6:49 ` [PATCH v2 0/2] iio: light: isl29018: overflow fix + cover-glass gain " Herman van Hazendonk
  0 siblings, 2 replies; 7+ messages in thread
From: Herman van Hazendonk @ 2026-06-04  5:47 UTC (permalink / raw)
  To: linux-iio
  Cc: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
	devicetree, linux-kernel, masneyb

The ISL29018/ISL29023 is commonly mounted behind a tinted or coated
cover glass on consumer devices (HP TouchPad being one example). In
that configuration the visible-light photodiode reads roughly 1/100th
of actual ambient lux, causing downstream consumers (brightness daemons,
display managers) to permanently classify the environment as near-dark
and pin the backlight at a fraction of its range.

The driver already exposes in_illuminance0_calibscale for runtime
compensation, but that requires udev rules or userspace re-application
after every reboot.  The optical loss is a board-level hardware constant
and belongs in firmware.

This series adds an "isil,cover-comp-gain" DT property that seeds
calibscale at probe time, following the precedent established by
tsl2563.c (amstaos,cover-comp-gain) for the same class of problem.
The default stays 1 so existing systems are unaffected, and userspace
can still override the value through sysfs afterwards.

A follow-up DTS patch enabling this for the HP TouchPad will be sent
separately to the ARM/DTS tree once this driver change is upstream.

Herman van Hazendonk (1):
  iio: light: isl29018: support cover-glass gain compensation via DT

 .../devicetree/bindings/iio/light/isl29018.yaml     | 13 +++++++++++++
 drivers/iio/light/isl29018.c                        |  9 +++++++++
 2 files changed, 22 insertions(+)

-- 
2.43.0


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

* [PATCH 1/1] iio: light: isl29018: support cover-glass gain compensation via DT
  2026-06-04  5:47 [PATCH 0/1] iio: light: isl29018: cover-glass gain compensation via DT Herman van Hazendonk
@ 2026-06-04  5:47 ` Herman van Hazendonk
  2026-06-04  7:17   ` Andy Shevchenko
  2026-06-04  6:49 ` [PATCH v2 0/2] iio: light: isl29018: overflow fix + cover-glass gain " Herman van Hazendonk
  1 sibling, 1 reply; 7+ messages in thread
From: Herman van Hazendonk @ 2026-06-04  5:47 UTC (permalink / raw)
  To: linux-iio
  Cc: jic23, dlechner, nuno.sa, andy, robh, krzk+dt, conor+dt,
	devicetree, linux-kernel, masneyb

Boards that mount the sensor under a tinted or coated cover glass need
to compensate for the optical loss before downstream consumers can map
the reading onto a useful lux range. The driver already exposes a
runtime knob through in_illuminance0_calibscale, but every user has to
re-apply it after every reboot (or rely on a board-specific udev rule),
and a power-of-two cover gain like 100x is a hardware constant of the
board rather than a policy choice that belongs in userspace.

Add an "isil,cover-comp-gain" device-tree property that seeds calibscale
at probe, mirroring the pattern tsl2563.c already uses for the same
class of problem (amstaos,cover-comp-gain). The default stays 1 so
existing systems are unaffected, and userspace can still re-tune via
the sysfs attribute afterwards.

Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
 .../devicetree/bindings/iio/light/isl29018.yaml     | 13 +++++++++++++
 drivers/iio/light/isl29018.c                        |  9 +++++++++
 2 files changed, 22 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/light/isl29018.yaml b/Documentation/devicetree/bindings/iio/light/isl29018.yaml
index 0ea278b07d1c..92ea2742bbd3 100644
--- a/Documentation/devicetree/bindings/iio/light/isl29018.yaml
+++ b/Documentation/devicetree/bindings/iio/light/isl29018.yaml
@@ -34,6 +34,19 @@ properties:
   vcc-supply:
     description: Regulator that provides power to the sensor
 
+  isil,cover-comp-gain:
+    description: |
+      Multiplier applied to the ambient-light reading at startup to
+      compensate for optical loss in the board's cover glass. Boards
+      that mount the sensor under a tinted or coated window typically
+      need a value between a few and a few hundred. The value seeds
+      in_illuminance0_calibscale, so it can still be retuned at
+      runtime through sysfs.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 65535
+    default: 1
+
 required:
   - compatible
   - reg
diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c
index b6ab726d1dae..427dbb639141 100644
--- a/drivers/iio/light/isl29018.c
+++ b/drivers/iio/light/isl29018.c
@@ -727,7 +727,16 @@ static int isl29018_probe(struct i2c_client *client)
 	mutex_init(&chip->lock);
 
 	chip->type = dev_id;
+	/*
+	 * Allow boards that mount the sensor behind tinted / coated cover
+	 * glass to bake the optical-loss compensation into firmware via
+	 * "isil,cover-comp-gain", following the precedent set by
+	 * tsl2563.c. The value seeds calibscale (default 1), so userspace
+	 * can still retune through in_illuminance0_calibscale.
+	 */
 	chip->calibscale = 1;
+	device_property_read_u32(&client->dev, "isil,cover-comp-gain",
+				 &chip->calibscale);
 	chip->ucalibscale = 0;
 	chip->int_time = ISL29018_INT_TIME_16;
 	chip->scale = isl29018_scales[chip->int_time][0];
-- 
2.43.0


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

* [PATCH v2 0/2] iio: light: isl29018: overflow fix + cover-glass gain via DT
  2026-06-04  5:47 [PATCH 0/1] iio: light: isl29018: cover-glass gain compensation via DT Herman van Hazendonk
  2026-06-04  5:47 ` [PATCH 1/1] iio: light: isl29018: support " Herman van Hazendonk
@ 2026-06-04  6:49 ` Herman van Hazendonk
  2026-06-04  6:49   ` [PATCH v2 1/2] iio: light: isl29018: fix 32-bit overflow in isl29018_read_lux() Herman van Hazendonk
  2026-06-04  6:49   ` [PATCH v2 2/2] iio: light: isl29018: support cover-glass gain compensation via DT Herman van Hazendonk
  1 sibling, 2 replies; 7+ messages in thread
From: Herman van Hazendonk @ 2026-06-04  6:49 UTC (permalink / raw)
  To: linux-iio
  Cc: jic23, dlechner, nuno.sa, robh, krzk+dt, conor+dt, devicetree,
	Herman van Hazendonk

v2: split into two patches after review feedback on v1.

PATCH 1/2 fixes a pre-existing 32-bit overflow in isl29018_read_lux()
that the reviewer correctly identified: lux_data * scale.uscale can
reach ~64 billion at full-scale 16-bit readings (65535 × 976562),
overflowing UINT_MAX before the /1000000 division.  A second overflow
occurs when the result is multiplied by calibscale and stored in the
signed int *lux.  Both are fixed by widening intermediate arithmetic to
u64 and clamping the output.

PATCH 2/2 is unchanged from v1: it adds the "isil,cover-comp-gain" DT
property to seed calibscale at probe time, following the precedent set
by tsl2563.c (amstaos,cover-comp-gain).  The default stays 1 so
existing systems are unaffected.  The overflow fix in patch 1 is a
natural prerequisite because patch 2 makes large calibscale values
straightforward to deploy from firmware.

A follow-up DTS patch enabling this for the HP TouchPad will be sent
separately to the ARM/DTS tree once the driver change is upstream.

Herman van Hazendonk (2):
  iio: light: isl29018: fix 32-bit overflow in isl29018_read_lux()
  iio: light: isl29018: support cover-glass gain compensation via DT

 .../bindings/iio/light/isl29018.yaml          | 13 ++++++++++++
 drivers/iio/light/isl29018.c                  | 20 ++++++++++++++-----
 2 files changed, 28 insertions(+), 5 deletions(-)


base-commit: 944125b4c454b58d2fe6e35f1087a932b2050dff
-- 
2.43.0


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

* [PATCH v2 1/2] iio: light: isl29018: fix 32-bit overflow in isl29018_read_lux()
  2026-06-04  6:49 ` [PATCH v2 0/2] iio: light: isl29018: overflow fix + cover-glass gain " Herman van Hazendonk
@ 2026-06-04  6:49   ` Herman van Hazendonk
  2026-06-04  6:49   ` [PATCH v2 2/2] iio: light: isl29018: support cover-glass gain compensation via DT Herman van Hazendonk
  1 sibling, 0 replies; 7+ messages in thread
From: Herman van Hazendonk @ 2026-06-04  6:49 UTC (permalink / raw)
  To: linux-iio
  Cc: jic23, dlechner, nuno.sa, robh, krzk+dt, conor+dt, devicetree,
	Herman van Hazendonk

The intermediate calculations in isl29018_read_lux() use 32-bit
arithmetic throughout, which overflows in two distinct ways:

1. lux_data * chip->scale.uscale — at 16-bit integration time and the
   1000 fc range, scale.uscale is 976562.  A full-scale 16-bit reading
   (65535) gives 65535 * 976562 ≈ 64 billion, far beyond UINT_MAX.
   The value wraps before the / 1000000 division can save it, producing
   a wildly wrong data_x_range.

2. data_x_range * chip->calibscale — even after a correct data_x_range,
   multiplying by a calibscale of a few hundred (reasonable for a deeply
   tinted cover glass) pushes the product past INT_MAX, causing *lux to
   wrap negative.

Fix both by widening the intermediate variables to u64 and clamping the
final result to INT_MAX before storing it in the signed int *lux out
parameter.

Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
 drivers/iio/light/isl29018.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c
index b6ab726d1dae..eafdfd9c4635 100644
--- a/drivers/iio/light/isl29018.c
+++ b/drivers/iio/light/isl29018.c
@@ -193,17 +193,18 @@ static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode)
 static int isl29018_read_lux(struct isl29018_chip *chip, int *lux)
 {
 	int lux_data;
-	unsigned int data_x_range;
+	u64 data_x_range, result;
 
 	lux_data = isl29018_read_sensor_input(chip,
 					      ISL29018_CMD1_OPMODE_ALS_ONCE);
 	if (lux_data < 0)
 		return lux_data;
 
-	data_x_range = lux_data * chip->scale.scale +
-		       lux_data * chip->scale.uscale / 1000000;
-	*lux = data_x_range * chip->calibscale +
-	       data_x_range * chip->ucalibscale / 1000000;
+	data_x_range = (u64)lux_data * chip->scale.scale +
+		       (u64)lux_data * chip->scale.uscale / 1000000;
+	result = data_x_range * chip->calibscale +
+		 data_x_range * chip->ucalibscale / 1000000;
+	*lux = (int)min_t(u64, result, INT_MAX);
 
 	return 0;
 }
-- 
2.43.0


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

* [PATCH v2 2/2] iio: light: isl29018: support cover-glass gain compensation via DT
  2026-06-04  6:49 ` [PATCH v2 0/2] iio: light: isl29018: overflow fix + cover-glass gain " Herman van Hazendonk
  2026-06-04  6:49   ` [PATCH v2 1/2] iio: light: isl29018: fix 32-bit overflow in isl29018_read_lux() Herman van Hazendonk
@ 2026-06-04  6:49   ` Herman van Hazendonk
  1 sibling, 0 replies; 7+ messages in thread
From: Herman van Hazendonk @ 2026-06-04  6:49 UTC (permalink / raw)
  To: linux-iio
  Cc: jic23, dlechner, nuno.sa, robh, krzk+dt, conor+dt, devicetree,
	Herman van Hazendonk

Boards that mount the sensor under a tinted or coated cover glass need
to compensate for the optical loss before downstream consumers can map
the reading onto a useful lux range. The driver already exposes a
runtime knob through in_illuminance0_calibscale, but every user has to
re-apply it after every reboot (or rely on a board-specific udev rule),
and a power-of-two cover gain like 100x is a hardware constant of the
board rather than a policy choice that belongs in userspace.

Add an "isil,cover-comp-gain" device-tree property that seeds calibscale
at probe, mirroring the pattern tsl2563.c already uses for the same
class of problem (amstaos,cover-comp-gain). The default stays 1 so
existing systems are unaffected, and userspace can still re-tune via
the sysfs attribute afterwards.

Signed-off-by: Herman van Hazendonk <github.com@herrie.org>
---
 .../devicetree/bindings/iio/light/isl29018.yaml     | 13 +++++++++++++
 drivers/iio/light/isl29018.c                        |  9 +++++++++
 2 files changed, 22 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/light/isl29018.yaml b/Documentation/devicetree/bindings/iio/light/isl29018.yaml
index 0ea278b07d1c..92ea2742bbd3 100644
--- a/Documentation/devicetree/bindings/iio/light/isl29018.yaml
+++ b/Documentation/devicetree/bindings/iio/light/isl29018.yaml
@@ -34,6 +34,19 @@ properties:
   vcc-supply:
     description: Regulator that provides power to the sensor
 
+  isil,cover-comp-gain:
+    description: |
+      Multiplier applied to the ambient-light reading at startup to
+      compensate for optical loss in the board's cover glass. Boards
+      that mount the sensor under a tinted or coated window typically
+      need a value between a few and a few hundred. The value seeds
+      in_illuminance0_calibscale, so it can still be retuned at
+      runtime through sysfs.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 65535
+    default: 1
+
 required:
   - compatible
   - reg
diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c
index eafdfd9c4635..6d2f1e9f59b5 100644
--- a/drivers/iio/light/isl29018.c
+++ b/drivers/iio/light/isl29018.c
@@ -728,7 +728,16 @@ static int isl29018_probe(struct i2c_client *client)
 	mutex_init(&chip->lock);
 
 	chip->type = dev_id;
+	/*
+	 * Allow boards that mount the sensor behind tinted / coated cover
+	 * glass to bake the optical-loss compensation into firmware via
+	 * "isil,cover-comp-gain", following the precedent set by
+	 * tsl2563.c. The value seeds calibscale (default 1), so userspace
+	 * can still retune through in_illuminance0_calibscale.
+	 */
 	chip->calibscale = 1;
+	device_property_read_u32(&client->dev, "isil,cover-comp-gain",
+				 &chip->calibscale);
 	chip->ucalibscale = 0;
 	chip->int_time = ISL29018_INT_TIME_16;
 	chip->scale = isl29018_scales[chip->int_time][0];
-- 
2.43.0


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

* Re: [PATCH 1/1] iio: light: isl29018: support cover-glass gain compensation via DT
  2026-06-04  5:47 ` [PATCH 1/1] iio: light: isl29018: support " Herman van Hazendonk
@ 2026-06-04  7:17   ` Andy Shevchenko
  2026-06-04  7:22     ` Joshua Crofts
  0 siblings, 1 reply; 7+ messages in thread
From: Andy Shevchenko @ 2026-06-04  7:17 UTC (permalink / raw)
  To: Herman van Hazendonk
  Cc: linux-iio, jic23, dlechner, nuno.sa, andy, robh, krzk+dt,
	conor+dt, devicetree, linux-kernel, masneyb

On Thu, Jun 04, 2026 at 07:47:23AM +0200, Herman van Hazendonk wrote:
> Boards that mount the sensor under a tinted or coated cover glass need
> to compensate for the optical loss before downstream consumers can map
> the reading onto a useful lux range. The driver already exposes a
> runtime knob through in_illuminance0_calibscale, but every user has to
> re-apply it after every reboot (or rely on a board-specific udev rule),
> and a power-of-two cover gain like 100x is a hardware constant of the
> board rather than a policy choice that belongs in userspace.
> 
> Add an "isil,cover-comp-gain" device-tree property that seeds calibscale
> at probe, mirroring the pattern tsl2563.c already uses for the same
> class of problem (amstaos,cover-comp-gain). The default stays 1 so
> existing systems are unaffected, and userspace can still re-tune via
> the sysfs attribute afterwards.

Haven't DT schema patches needed to go separately?

...

> +	/*
> +	 * Allow boards that mount the sensor behind tinted / coated cover
> +	 * glass to bake the optical-loss compensation into firmware via
> +	 * "isil,cover-comp-gain", following the precedent set by
> +	 * tsl2563.c. The value seeds calibscale (default 1), so userspace
> +	 * can still retune through in_illuminance0_calibscale.
> +	 */
>  	chip->calibscale = 1;
> +	device_property_read_u32(&client->dev, "isil,cover-comp-gain",
> +				 &chip->calibscale);

With

	struct device *dev = &client->dev;

at the top of the function this will be made shorter.

Additionally the above approach won't be accurate when property is present in
DT but by some reason can't be retrieved. It will puzzle the user. That's why
the robust approach is

	struct device *dev = &client->dev;
	const char *propname;
	...

	propname = "isil,cover-comp-gain";
	if (device_property_present(dev, &chip->calibscale)) {
		ret = device_property_read_u32(dev, propname, &chip->calibscale);
		if (ret)
			return ret; // optionally dev_err_probe()
	} else {
		chip->calibscale = 1;
	}

Taking the expansion of this pattern we might need to actually introduce a full
set of device_property_read_*_optional() to make this churn less required.
Perhaps for v7.3.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 1/1] iio: light: isl29018: support cover-glass gain compensation via DT
  2026-06-04  7:17   ` Andy Shevchenko
@ 2026-06-04  7:22     ` Joshua Crofts
  0 siblings, 0 replies; 7+ messages in thread
From: Joshua Crofts @ 2026-06-04  7:22 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Herman van Hazendonk, linux-iio, jic23, dlechner, nuno.sa, andy,
	robh, krzk+dt, conor+dt, devicetree, linux-kernel, masneyb

On Thu, 4 Jun 2026 at 09:18, Andy Shevchenko
<andriy.shevchenko@intel.com> wrote:
>
> On Thu, Jun 04, 2026 at 07:47:23AM +0200, Herman van Hazendonk wrote:
> > Boards that mount the sensor under a tinted or coated cover glass need
> > to compensate for the optical loss before downstream consumers can map
> > the reading onto a useful lux range. The driver already exposes a
> > runtime knob through in_illuminance0_calibscale, but every user has to
> > re-apply it after every reboot (or rely on a board-specific udev rule),
> > and a power-of-two cover gain like 100x is a hardware constant of the
> > board rather than a policy choice that belongs in userspace.
> >
> > Add an "isil,cover-comp-gain" device-tree property that seeds calibscale
> > at probe, mirroring the pattern tsl2563.c already uses for the same
> > class of problem (amstaos,cover-comp-gain). The default stays 1 so
> > existing systems are unaffected, and userspace can still re-tune via
> > the sysfs attribute afterwards.
>
> Haven't DT schema patches needed to go separately?

Yes, with the correct subject line/commit message title as well.
(e.g. dt-bindings: iio: light: isl29018: add support cover gain comp)

-- 
Kind regards

CJD

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

end of thread, other threads:[~2026-06-04  7:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04  5:47 [PATCH 0/1] iio: light: isl29018: cover-glass gain compensation via DT Herman van Hazendonk
2026-06-04  5:47 ` [PATCH 1/1] iio: light: isl29018: support " Herman van Hazendonk
2026-06-04  7:17   ` Andy Shevchenko
2026-06-04  7:22     ` Joshua Crofts
2026-06-04  6:49 ` [PATCH v2 0/2] iio: light: isl29018: overflow fix + cover-glass gain " Herman van Hazendonk
2026-06-04  6:49   ` [PATCH v2 1/2] iio: light: isl29018: fix 32-bit overflow in isl29018_read_lux() Herman van Hazendonk
2026-06-04  6:49   ` [PATCH v2 2/2] iio: light: isl29018: support cover-glass gain compensation via DT Herman van Hazendonk

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