From nobody Sun Feb 8 13:52:55 2026 Received: from mail-dy1-f169.google.com (mail-dy1-f169.google.com [74.125.82.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D09461D5CC6 for ; Sun, 18 Jan 2026 18:19:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768760399; cv=none; b=OOajSj0Xb5IvvNduTld1txU1rd/q83OrdJJGWbSIwIycH1XlWsfHj6u/KfUn8/WkcJWuZerMtuH6NAX80CBBQdKQoXxNEdotip1HAN2RSifw4APevHgTrSYNUfbpgdQ5PIhtmf8bX3gjp6UWOIGhp2Hr0YiKxnFwSdIb4xAiHFU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768760399; c=relaxed/simple; bh=T6a8BQUbWqU9GMRGIo9BhMSECj/L+r2E/Y035vRhNEk=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=YuWCiiLg3S66P+Ot2ofxhAI1Jv4sRmF5vjKMPjTguzU74Kdsta6c9mvjyK0//eYnMnUbGGCEc1q//0/LGWGd5+VHf7w6/2zKqdM5KqgNv6ZNI3fLHYXLbo1k4RK165KSTe1HjUkvOCZAQiD77b5fQ7fqWaexQIDsPA0D3dq8P+0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KPzfDQPc; arc=none smtp.client-ip=74.125.82.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KPzfDQPc" Received: by mail-dy1-f169.google.com with SMTP id 5a478bee46e88-2b1981ca515so3900071eec.1 for ; Sun, 18 Jan 2026 10:19:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768760397; x=1769365197; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=m15yqdQHaxmYRVMpA6zrhF4sJGCIUQR0mh1h/cFJQfg=; b=KPzfDQPcXRDQ/fLVz/2GspHj5MVH8PoVoRRWj5ND/GdaU7K/jcLq9Wzf4WakHFizbg zB+nxvf91QKXirn5F9u6li1h6sLPoxUp4SVdCRcA6bPuhKXfkZL7vFMZb6jY7kYkRcYz mAZdZEMVciS22lcCchr0WgVFaVU1XDOoSRuLwjuQfM+AqQ5wlIub13e+0UkpBUUX9N/V 02UmkbfmVhW+EWz8FMn12IWWZvo6jG2b0thpUchkE7myzPQ2Iu3f2XluTdVipek6X6ai APu+L+nYqQwoQ8M+mm1NVL6m69dhtMsGXYXIUy031llFIY8A7c3l56c6V4atDd+U8qfj c4Bw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768760397; x=1769365197; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=m15yqdQHaxmYRVMpA6zrhF4sJGCIUQR0mh1h/cFJQfg=; b=d8kW96+jxTV5XnTujC7p8HEMDSg9VwFpuQ04EfBNdqXHLob68ESzTxJaaVjSh0O56f /CvpBLjH5hm7ZDKD/IP0Q4FG6mRTlZS0UVjmRq6Xt9WnxTbvS2PSsetPjKOTd3WTV/RQ Ic4EKVYlbKCzGbnYGpBvqwgHVNmCtAXhdd1KTU2zPgN40aClvLRPFk3N420K91bL9C2U IifQ1zkndiBCDfofjGhyA01pgjNVktUk3ZKVB1Aq6c2jLuj/OVCFWyFCfD7h2KRkb5vx y8YwB5jLG4MyliT4WNrn9ObHNR7AMBpH7egBQLXwm9lP7ZUavO3lVP9Llp50mn1cZEyF DODA== X-Forwarded-Encrypted: i=1; AJvYcCXlebrt0zhLwxt312dJtSu5C/tHCi/Q+muoiDr4lBVCkI7p7FHERVXRZxiCw+MLN0ExBNOs3UKt7SIWpbk=@vger.kernel.org X-Gm-Message-State: AOJu0YyVbZALcO407+3uXamXFvxw+Dug1NmbMXTWM1uu2fb4JM+Ab1x4 lZ8JNlBNV5Omw9EEFD1dmF+8iSJyyasi9FDMqm9/AuB9eOVUX/UG6FQg X-Gm-Gg: AY/fxX7HmASAamFuV+sl654tzhZcVl7u2EZvrtD40P8nrtb0xPZz4nney0VCSCmTZq5 Z47OTkLwafKVpTOWwcJXG0+k2bFKP42xp/uILTY59ZnbLbGDEo49mvh1gIUk1ELpqUqzLN43X1F lY1lvgVQ6AeeHOjVVI+ssrNmoLTEU32h+vEhB6+9VKuTT/ZaMte2KZEdjPOQV9gJIC0NBQt9t+Y ec+IDc+KGIs2mnQ5XYieuhPf312tWYA3UqpRwKHohxZ5dICiDVwjbVG8Mih+Mv6xGmIXhFARolA hUFItksLQEEC6iil63aP98gTsfPLXCD2iQ6EzFmQFNhN2fqk0szVNoE7O+0xMs8Gvdjrpiy0v1W YS9m1PStEDu+Xv0cI0Q3EAoEEekRCz77Bu6EjenGV2jAzMWqSvOUq3wrSthyNFrkaU/zEH3buc9 oNdHPiK14zIisdqhmGkcw= X-Received: by 2002:a05:7301:4104:b0:2b0:59da:f799 with SMTP id 5a478bee46e88-2b6b3ed9f07mr5997350eec.5.1768760396742; Sun, 18 Jan 2026 10:19:56 -0800 (PST) Received: from localhost ([2804:30c:2766:a500:b70:8c42:f792:bef6]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b34c122bsm9907807eec.5.2026.01.18.10.19.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Jan 2026 10:19:56 -0800 (PST) Date: Sun, 18 Jan 2026 15:21:46 -0300 From: Marcelo Schmitt 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 Message-ID: <6d9baa8d553d03a41fbd97bca0377a7a4779a93e.1768759292.git.marcelo.schmitt1@gmail.com> References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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-ev= ent.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[] =3D { [IIO_EV_INFO_RUNNING_COUNT] =3D "runningcount", }; =20 +static const char * const iio_ev_unit_text[] =3D { + [IIO_EV_UNIT_RAW] =3D "raw", + [IIO_EV_UNIT_PROCESSED] =3D "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; } =20 +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 =3D 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] =3D val; @@ -359,7 +369,7 @@ static ssize_t iio_ev_value_store(struct device *dev, ret =3D 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; =20 @@ -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 =3D 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 >=3D ARRAY_SIZE(iio_ev_info_text)) return -EINVAL; - if (dir !=3D IIO_EV_DIR_NONE) - postfix =3D kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_ev_type_text[type], - iio_ev_dir_text[dir], - iio_ev_info_text[i]); - else + if (dir !=3D IIO_EV_DIR_NONE) { + if (i =3D=3D IIO_EV_INFO_ENABLE) + postfix =3D kasprintf(GFP_KERNEL, "%s_%s_%s", + iio_ev_type_text[type], + iio_ev_dir_text[dir], + iio_ev_info_text[i]); + else + postfix =3D 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 =3D kasprintf(GFP_KERNEL, "%s_%s", iio_ev_type_text[type], iio_ev_info_text[i]); + } if (postfix =3D=3D NULL) return -ENOMEM; =20 @@ -478,32 +497,34 @@ static int iio_device_add_event_sysfs(struct iio_dev = *indio_dev, int ret =3D 0, i, attrcount =3D 0; enum iio_event_direction dir; enum iio_event_type type; + enum iio_event_unit unit; =20 for (i =3D 0; i < chan->num_event_specs; i++) { type =3D chan->event_spec[i].type; dir =3D chan->event_spec[i].dir; + unit =3D chan->event_spec[i].unit; =20 - ret =3D iio_device_add_event(indio_dev, chan, i, type, dir, + ret =3D 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 +=3D ret; =20 - ret =3D iio_device_add_event(indio_dev, chan, i, type, dir, + ret =3D 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 +=3D ret; =20 - ret =3D iio_device_add_event(indio_dev, chan, i, type, dir, + ret =3D 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 +=3D ret; =20 - ret =3D iio_device_add_event(indio_dev, chan, i, type, dir, + ret =3D 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. Attrib= utes @@ -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); =20 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); =20 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, }; =20 +enum iio_event_unit { + IIO_EV_UNIT_RAW, + IIO_EV_UNIT_PROCESSED, +}; + #endif /* _UAPI_IIO_TYPES_H_ */ --=20 2.51.0