[PATCH v4 3/4] iio: light: tsl2591: report saturation

From: Jan Remes

Date: Thu Oct 22 2026 - 14:57:58 EST


From: Jan Remes <jan.remes@xxxxxxxxxxxxxxx>

When the TSL2591 sensor is saturated, it reports its maximum value
(specific one for 100ms integration time, UINT16_MAX otherwise).

When either raw channel becomes saturated, return -EOVERFLOW (like
as73211 and si1133 do) instead of calculating an invalid number when
reading 'in_illuminance_input'. Keep existing behavior on raw channels.

Note: Datasheet versions differ in the saturation number for 100ms. Old
2013 datasheet lists it as 37888, newer versions say 36863. Use the new
value although the hardware can report up to 37888.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxx>
Signed-off-by: Jan Remes <jan.remes@xxxxxxxxxxxxxxx>
---
drivers/iio/light/tsl2591.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/light/tsl2591.c b/drivers/iio/light/tsl2591.c
index 8cfce720efb9..e3092ae77a11 100644
--- a/drivers/iio/light/tsl2591.c
+++ b/drivers/iio/light/tsl2591.c
@@ -139,7 +139,9 @@

/* TSL2591 maximum values */
#define TSL2591_MAX_ALS_INT_TIME_MS 600
+/* Maximal values per datasheet [v3-00] 2023-Feb-08 */
#define TSL2591_ALS_MAX_VALUE (BIT(16) - 1)
+#define TSL2591_ALS_MAX_VALUE_100MS 36863

/*
* LUX calculations;
@@ -379,7 +381,7 @@ static int tsl2591_read_channel_data(struct iio_dev *indio_dev,
struct i2c_client *client = chip->client;
u8 als_data[TSL2591_NUM_DATA_REGISTERS];
int int_time_fval, gain_multi;
- u16 als_ch0, als_ch1;
+ u16 als_ch0, als_ch1, als_max;
u64 lux;
u32 rem;
int ret;
@@ -417,6 +419,14 @@ static int tsl2591_read_channel_data(struct iio_dev *indio_dev,
return gain_multi;
}

+ /* Check for overflow; special case for 100ms integration time */
+ als_max = TSL2591_ALS_MAX_VALUE;
+ if (settings->als_int_time == TSL2591_CTRL_ALS_INTEGRATION_100MS)
+ als_max = TSL2591_ALS_MAX_VALUE_100MS;
+
+ if (als_ch0 >= als_max || als_ch1 >= als_max)
+ return -EOVERFLOW;
+
/* No visible light, this also catches C0DATA == 0 */
if (als_ch0 <= als_ch1) {
*val = 0;

--
2.53.0