lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6d9baa8d553d03a41fbd97bca0377a7a4779a93e.1768759292.git.marcelo.schmitt1@gmail.com>
Date: Sun, 18 Jan 2026 15:21:46 -0300
From: Marcelo Schmitt <marcelo.schmitt1@...il.com>
To: linux-iio@...r.kernel.org, linux-kernel@...r.kernel.org
Cc: jic23@...nel.org, Jonathan.Cameron@...wei.com, nuno.sa@...log.com,
	andy@...nel.org, dlechner@...libre.com, marcelo.schmitt1@...il.com
Subject: [RFC PATCH v1 7/9] iio: Expand IIO event interface for real-world
 unit handling

The IIO event ABI documentation distinguishes between interfaces that
handle values in device-specific units (_raw) and event interfaces that
handle values in real-world units (e.g. meters, Joules, lux, etc).
However, the IIO event code infrastructure had never really implemented the
bits to distinguish between those two types of interfaces and had always
presumed events to handle raw device values.

For most current use cases, assuming events to handle values in device raw
units is reasonable because it often matches the type of the associated IIO
channel. There are a few cases where drivers provide events along side
channels with both _raw and _input interfaces, though. Also, when
real-world values can be mapped back to device configurations, it enables
drivers to provide event interfaces that are arguably easier to use.

Expand the IIO events support, enabling IIO drivers to provide event
interfaces that handle values in real-world units.

Signed-off-by: Marcelo Schmitt <marcelo.schmitt1@...il.com>
---
 drivers/iio/industrialio-event.c | 47 +++++++++++++++++++++++---------
 include/linux/iio/iio.h          |  8 ++++--
 include/uapi/linux/iio/types.h   |  5 ++++
 3 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 06295cfc2da8..68bba21cae14 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -258,6 +258,11 @@ static const char * const iio_ev_info_text[] = {
 	[IIO_EV_INFO_RUNNING_COUNT] = "runningcount",
 };
 
+static const char * const iio_ev_unit_text[] = {
+	[IIO_EV_UNIT_RAW] = "raw",
+	[IIO_EV_UNIT_PROCESSED] = "input",
+};
+
 static enum iio_event_direction iio_ev_attr_dir(struct iio_dev_attr *attr)
 {
 	return attr->c->event_spec[attr->address & 0xffff].dir;
@@ -273,6 +278,11 @@ static enum iio_event_info iio_ev_attr_info(struct iio_dev_attr *attr)
 	return (attr->address >> 16) & 0xffff;
 }
 
+static enum iio_event_unit iio_ev_attr_unit(struct iio_dev_attr *attr)
+{
+	return attr->c->event_spec[attr->address & 0xffff].unit;
+}
+
 static ssize_t iio_ev_state_store(struct device *dev,
 				  struct device_attribute *attr,
 				  const char *buf,
@@ -332,7 +342,7 @@ static ssize_t iio_ev_value_show(struct device *dev,
 	ret = indio_dev->info->read_event_value(indio_dev,
 		this_attr->c, iio_ev_attr_type(this_attr),
 		iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
-		&val, &val2);
+		iio_ev_attr_unit(this_attr), &val, &val2);
 	if (ret < 0)
 		return ret;
 	val_arr[0] = val;
@@ -359,7 +369,7 @@ static ssize_t iio_ev_value_store(struct device *dev,
 	ret = indio_dev->info->write_event_value(indio_dev,
 		this_attr->c, iio_ev_attr_type(this_attr),
 		iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
-		val, val2);
+		iio_ev_attr_unit(this_attr), val, val2);
 	if (ret < 0)
 		return ret;
 
@@ -384,7 +394,8 @@ static ssize_t iio_ev_label_show(struct device *dev,
 static int iio_device_add_event(struct iio_dev *indio_dev,
 	const struct iio_chan_spec *chan, unsigned int spec_index,
 	enum iio_event_type type, enum iio_event_direction dir,
-	enum iio_shared_by shared_by, const unsigned long *mask)
+	enum iio_event_unit unit, enum iio_shared_by shared_by,
+	const unsigned long *mask)
 {
 	struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
 	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
@@ -399,15 +410,23 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
 	for_each_set_bit(i, mask, sizeof(*mask)*8) {
 		if (i >= ARRAY_SIZE(iio_ev_info_text))
 			return -EINVAL;
-		if (dir != IIO_EV_DIR_NONE)
-			postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
-					iio_ev_type_text[type],
-					iio_ev_dir_text[dir],
-					iio_ev_info_text[i]);
-		else
+		if (dir != IIO_EV_DIR_NONE) {
+			if (i == IIO_EV_INFO_ENABLE)
+				postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
+						iio_ev_type_text[type],
+						iio_ev_dir_text[dir],
+						iio_ev_info_text[i]);
+			else
+				postfix = kasprintf(GFP_KERNEL, "%s_%s_%s_%s",
+						iio_ev_unit_text[unit],
+						iio_ev_type_text[type],
+						iio_ev_dir_text[dir],
+						iio_ev_info_text[i]);
+		} else {
 			postfix = kasprintf(GFP_KERNEL, "%s_%s",
 					iio_ev_type_text[type],
 					iio_ev_info_text[i]);
+		}
 		if (postfix == NULL)
 			return -ENOMEM;
 
@@ -478,32 +497,34 @@ static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
 	int ret = 0, i, attrcount = 0;
 	enum iio_event_direction dir;
 	enum iio_event_type type;
+	enum iio_event_unit unit;
 
 	for (i = 0; i < chan->num_event_specs; i++) {
 		type = chan->event_spec[i].type;
 		dir = chan->event_spec[i].dir;
+		unit = chan->event_spec[i].unit;
 
-		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+		ret = iio_device_add_event(indio_dev, chan, i, type, dir, unit,
 			IIO_SEPARATE, &chan->event_spec[i].mask_separate);
 		if (ret < 0)
 			return ret;
 		attrcount += ret;
 
-		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+		ret = iio_device_add_event(indio_dev, chan, i, type, dir, unit,
 			IIO_SHARED_BY_TYPE,
 			&chan->event_spec[i].mask_shared_by_type);
 		if (ret < 0)
 			return ret;
 		attrcount += ret;
 
-		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+		ret = iio_device_add_event(indio_dev, chan, i, type, dir, unit,
 			IIO_SHARED_BY_DIR,
 			&chan->event_spec[i].mask_shared_by_dir);
 		if (ret < 0)
 			return ret;
 		attrcount += ret;
 
-		ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+		ret = iio_device_add_event(indio_dev, chan, i, type, dir, unit,
 			IIO_SHARED_BY_ALL,
 			&chan->event_spec[i].mask_shared_by_all);
 		if (ret < 0)
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 872ebdf0dd77..82d0a30e443f 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -156,6 +156,7 @@ typedef const struct iio_mount_matrix *
  * struct iio_event_spec - specification for a channel event
  * @type:		    Type of the event
  * @dir:		    Direction of the event
+ * @unit:		    Unit of the data to be handled (raw or processed).
  * @mask_separate:	    Bit mask of enum iio_event_info values. Attributes
  *			    set in this mask will be registered per channel.
  * @mask_shared_by_type:    Bit mask of enum iio_event_info values. Attributes
@@ -169,6 +170,7 @@ typedef const struct iio_mount_matrix *
 struct iio_event_spec {
 	enum iio_event_type type;
 	enum iio_event_direction dir;
+	enum iio_event_unit unit;
 	unsigned long mask_separate;
 	unsigned long mask_shared_by_type;
 	unsigned long mask_shared_by_dir;
@@ -522,13 +524,15 @@ struct iio_info {
 				const struct iio_chan_spec *chan,
 				enum iio_event_type type,
 				enum iio_event_direction dir,
-				enum iio_event_info info, int *val, int *val2);
+				enum iio_event_info info,
+				enum iio_event_unit unit, int *val, int *val2);
 
 	int (*write_event_value)(struct iio_dev *indio_dev,
 				 const struct iio_chan_spec *chan,
 				 enum iio_event_type type,
 				 enum iio_event_direction dir,
-				 enum iio_event_info info, int val, int val2);
+				 enum iio_event_info info,
+				 enum iio_event_unit unit, int val, int val2);
 
 	int (*read_event_label)(struct iio_dev *indio_dev,
 				struct iio_chan_spec const *chan,
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index 6d269b844271..4898444deb9e 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -137,4 +137,9 @@ enum iio_event_direction {
 	IIO_EV_DIR_FAULT_OPENWIRE,
 };
 
+enum iio_event_unit {
+	IIO_EV_UNIT_RAW,
+	IIO_EV_UNIT_PROCESSED,
+};
+
 #endif /* _UAPI_IIO_TYPES_H_ */
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ