[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250721195419.526920-2-akshayaj.lkd@gmail.com>
Date: Tue, 22 Jul 2025 01:24:19 +0530
From: Akshay Jindal <akshayaj.lkd@...il.com>
To: anshulusr@...il.com,
jic23@...nel.org,
dlechner@...libre.com,
nuno.sa@...log.com,
andy@...nel.org
Cc: shuah@...nel.org,
linux-iio@...r.kernel.org,
linux-kernel@...r.kernel.org,
Akshay Jindal <akshayaj.lkd@...il.com>
Subject: [PATCH 2/2] iio: light: ltr390: Add conditional data freshness check with sysfs control
Add logic to check the sensor’s data freshness status bit before reading
data, and skip reads if the data is stale.
Introduce a new boolean sysfs attribute, `data_fresh_check_enable`, to allow
users to enable or disable this behavior at runtime:
- 1: Enable data freshness check (default)
- 0: Disable data freshness check
This provides flexibility to choose between ensuring fresh data and allowing
faster reads when occasional staleness is acceptable.
Document the new attribute under Documentation/ABI/testing/sysfs-bus-iio.
Signed-off-by: Akshay Jindal <akshayaj.lkd@...il.com>
---
-> Tested on Raspberrypi 4B. Follow for more details.
akshayajpi@...pberrypi:~ $ uname -r
6.12.35-v8+
akshayajpi@...pberrypi:~ $ uname -a
Linux raspberrypi 6.12.35-v8+ #5 SMP PREEMPT Tue Jul 15 17:38:06 IST 2025 aarch64 GNU/Linux
-> Sensor Detection, overlaying of device tree and Driver loading
akshayajpi@...pberrypi:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- 53 -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
akshayajpi@...pberrypi:~ $ sudo dtoverlay i2c-sensor ltr390
akshayajpi@...pberrypi:~ $ lsmod|grep ltr390
ltr390 16384 0
industrialio 110592 1 ltr390
regmap_i2c 12288 1 ltr390
-> Sysfs Attribute Creation validation
akshayajpi@...pberrypi:~ $ ls -ltrh /sys/bus/iio/devices/iio\:device0/
total 0
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 uevent
-r--r--r-- 1 root root 4.0K Jul 21 23:52 name
-r--r--r-- 1 root root 4.0K Jul 21 23:52 waiting_for_supplier
lrwxrwxrwx 1 root root 0 Jul 21 23:52 subsystem -> ../../../../../../../bus/iio
-r--r--r-- 1 root root 4.0K Jul 21 23:52 scale_available
-r--r--r-- 1 root root 4.0K Jul 21 23:52 sampling_frequency_available
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 sampling_frequency
drwxr-xr-x 2 root root 0 Jul 21 23:52 power
lrwxrwxrwx 1 root root 0 Jul 21 23:52 of_node -> ../../../../../../../firmware/devicetree/base/soc/i2c@...04000/ltr390@53
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 in_uvindex_scale
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 in_uvindex_raw
-r--r--r-- 1 root root 4.0K Jul 21 23:52 integration_time_available
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 integration_time
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 in_illuminance_scale
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 in_illuminance_raw
drwxr-xr-x 2 root root 0 Jul 21 23:52 events
-r--r--r-- 1 root root 4.0K Jul 21 23:52 dev
-rw-r--r-- 1 root root 4.0K Jul 21 23:52 data_fresh_check_enable<-----
-r--r--r-- 1 root root 4.0K Jul 21 23:52 data_fresh
-> Default value 1 for data_fresh_check_enable
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh
1
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
1
-> Disable fresh measurement in the sensor
akshayajpi@...pberrypi:~ $ i2cset -f -y 1 0x53 0x0 0x0
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
1
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
1
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
647
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh
0
-> Since data_fresh_enable_check is enabled by default, driver skips
stale data read and emits -EAGAIN.
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
cat: '/sys/bus/iio/devices/iio:device0/in_illuminance_raw': Resource temporarily unavailable
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
cat: '/sys/bus/iio/devices/iio:device0/in_illuminance_raw': Resource temporarily unavailable
akshayajpi@...pberrypi:~ $
-> Disable data_fresh_check_en
akshayajpi@...pberrypi:~ $ echo 0 | sudo tee /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
0
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
0
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh
0
-> Since freshness check is disabled, driver reads and prints stale
data.
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
647
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
647
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
647
-> Re-enabling freshness check, results in driver emitting -EAGAIN.
akshayajpi@...pberrypi:~ $ echo 1 | sudo tee /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
1
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/data_fresh_check_enable
1
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
cat: '/sys/bus/iio/devices/iio:device0/in_illuminance_raw': Resource temporarily unavailable
akshayajpi@...pberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_illuminance_raw
cat: '/sys/bus/iio/devices/iio:device0/in_illuminance_raw': Resource temporarily unavailable
Documentation/ABI/testing/sysfs-bus-iio | 12 ++++++
drivers/iio/light/ltr390.c | 55 ++++++++++++++++++++++++-
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 5d176d46c15d..da881e16ee3d 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -2397,3 +2397,15 @@ Description:
Provides userspace visibility into data_freshness status which
can be used for debugging and informational use.
+
+What: /sys/.../iio:deviceX/data_fresh_check_enable
+KernelVersion: 6.16
+Contact: linux-iio@...r.kernel.org
+Description:
+ Read-write boolean attribute controlling whether the driver
+ checks the data freshness status bit before reading sensor data.
+
+ 0 - Freshness check disabled
+ 1 - Enable check; driver will skip reading stale data (default)
+
+ This flag affects the behavior of data reads.
diff --git a/drivers/iio/light/ltr390.c b/drivers/iio/light/ltr390.c
index 5af0ffd3df1d..b13f01835aeb 100644
--- a/drivers/iio/light/ltr390.c
+++ b/drivers/iio/light/ltr390.c
@@ -98,6 +98,7 @@ struct ltr390_data {
enum ltr390_mode mode;
int gain;
int int_time_us;
+ bool data_fresh_check_en;
};
static const struct regmap_config ltr390_regmap_config = {
@@ -199,10 +200,40 @@ static ssize_t data_fresh_show(struct device *dev,
return sysfs_emit(buf, "%d\n", !!(status & LTR390_DATA_STATUS_MASK));
}
+static ssize_t data_fresh_check_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr390_data *data = iio_priv(dev_to_iio_dev(dev));
+
+ guard(mutex)(&data->lock);
+
+ return sysfs_emit(buf, "%d\n", data->data_fresh_check_en);
+}
+
+static ssize_t data_fresh_check_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ int ret;
+ bool data_fresh_check_en;
+ struct ltr390_data *data = iio_priv(dev_to_iio_dev(dev));
+
+ ret = kstrtobool(buf, &data_fresh_check_en);
+ if (ret)
+ return ret;
+
+ guard(mutex)(&data->lock);
+
+ data->data_fresh_check_en = data_fresh_check_en;
+ return len;
+}
+
static IIO_DEVICE_ATTR_RO(data_fresh, 0);
+static IIO_DEVICE_ATTR_RW(data_fresh_check_enable, 0);
static struct attribute *ltr390_attributes[] = {
&iio_dev_attr_data_fresh.dev_attr.attr,
+ &iio_dev_attr_data_fresh_check_enable.dev_attr.attr,
NULL
};
@@ -214,7 +245,7 @@ static int ltr390_read_raw(struct iio_dev *iio_device,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
- int ret;
+ int ret, status;
struct ltr390_data *data = iio_priv(iio_device);
guard(mutex)(&data->lock);
@@ -226,6 +257,16 @@ static int ltr390_read_raw(struct iio_dev *iio_device,
if (ret < 0)
return ret;
+ if (data->data_fresh_check_en) {
+ ret = ltr390_register_read(data, LTR390_MAIN_STATUS);
+ if (ret < 0)
+ return ret;
+
+ status = ret;
+ if (!(status & LTR390_DATA_STATUS_MASK))
+ return -EAGAIN;
+ }
+
ret = ltr390_register_read(data, LTR390_UVS_DATA);
if (ret < 0)
return ret;
@@ -236,6 +277,16 @@ static int ltr390_read_raw(struct iio_dev *iio_device,
if (ret < 0)
return ret;
+ if (data->data_fresh_check_en) {
+ ret = ltr390_register_read(data, LTR390_MAIN_STATUS);
+ if (ret < 0)
+ return ret;
+
+ status = ret;
+ if (!(status & LTR390_DATA_STATUS_MASK))
+ return -EAGAIN;
+ }
+
ret = ltr390_register_read(data, LTR390_ALS_DATA);
if (ret < 0)
return ret;
@@ -687,6 +738,8 @@ static int ltr390_probe(struct i2c_client *client)
data->gain = 3;
/* default mode for ltr390 is ALS mode */
data->mode = LTR390_SET_ALS_MODE;
+ /* default value for data_fresh_check_en is 1 */
+ data->data_fresh_check_en = 1;
mutex_init(&data->lock);
--
2.43.0
Powered by blists - more mailing lists