mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Marcelo Schmitt <marcelo.schmitt1@gmail.com>
To: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: jic23@kernel.org, Jonathan.Cameron@huawei.com,
	nuno.sa@analog.com, andy@kernel.org, dlechner@baylibre.com,
	marcelo.schmitt1@gmail.com
Subject: [RFC PATCH v1 7/9] iio: Expand IIO event interface for real-world unit handling
Date: Sun, 18 Jan 2026 15:21:46 -0300	[thread overview]
Message-ID: <6d9baa8d553d03a41fbd97bca0377a7a4779a93e.1768759292.git.marcelo.schmitt1@gmail.com> (raw)
In-Reply-To: <cover.1768759292.git.marcelo.schmitt1@gmail.com>

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@gmail.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


  parent reply	other threads:[~2026-01-18 18:19 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-18 18:18 [RFC PATCH v1 0/9] " Marcelo Schmitt
2026-01-18 18:18 ` [RFC PATCH v1 1/9] iio: ABI: Drop unused in_energy_input Marcelo Schmitt
2026-01-31 18:51   ` Jonathan Cameron
2026-01-18 18:20 ` [RFC PATCH v1 2/9] iio: ABI: Accurately describe in_distance_input Marcelo Schmitt
2026-01-18 19:46   ` David Lechner
2026-01-21  2:49     ` Marcelo Schmitt
2026-01-31 18:52       ` Jonathan Cameron
2026-01-18 18:20 ` [RFC PATCH v1 3/9] iio: ABI: Accurately describe in_illuminance[Y]_input Marcelo Schmitt
2026-01-18 18:20 ` [RFC PATCH v1 4/9] iio: ABI: Slight readability improve for event threshold value doc Marcelo Schmitt
2026-01-18 18:21 ` [RFC PATCH v1 5/9] iio: ABI: Update event threshold value documentation Marcelo Schmitt
2026-01-18 18:21 ` [RFC PATCH v1 6/9] iio: ABI: Adjust event threshold enable desc to unitless thresh values Marcelo Schmitt
2026-01-18 18:21 ` Marcelo Schmitt [this message]
2026-01-18 20:10   ` [RFC PATCH v1 7/9] iio: Expand IIO event interface for real-world unit handling David Lechner
2026-01-31 18:55   ` Jonathan Cameron
2026-01-18 18:22 ` [RFC PATCH v1 8/9] iio: dummy: iio_simple_dummy: Update to event unit expanded interface Marcelo Schmitt
2026-01-18 18:22 ` [RFC PATCH v1 9/9] iio: adc: ad7091r-base: " Marcelo Schmitt
2026-01-18 20:33 ` [RFC PATCH v1 0/9] iio: Expand IIO event interface for real-world unit handling David Lechner
2026-01-21  2:40   ` Marcelo Schmitt
2026-01-21  9:33   ` Nuno Sá
2026-01-21 17:43     ` David Lechner
2026-01-31 18:48       ` Jonathan Cameron
2026-02-02 10:21         ` Nuno Sá

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6d9baa8d553d03a41fbd97bca0377a7a4779a93e.1768759292.git.marcelo.schmitt1@gmail.com \
    --to=marcelo.schmitt1@gmail.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=andy@kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=jic23@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nuno.sa@analog.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®