From nobody Sun Apr 5 13:12:37 2026 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 B3B7B3D811A for ; Tue, 24 Mar 2026 08:47:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342058; cv=none; b=ngJvihyQgRc+7fEQjEjzPcoggZhCPlO/F1J/E1d/tQ6nGaaIhM+uEd6cO1P7b3zWUZKvD58ciiplyZiDESppUszN8GAR+CV203ouZA8ROWtZNb08shvtcRB+8drOS7nwO8JnMVOSLMjmQLQDBZxQ8Hq++f6ez5pbZMRneGhvS14= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342058; c=relaxed/simple; bh=LhhuQW+kXumxf4ZHnfybInW36mhcntwwfWxHRNAL3MI=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=p8l+TnUJ0SmiaBBNBr2yP7TBRs03lrUm692OYA1BuDV3qkB+aytw4ZoDRCwVSPwOAMfKmaB90wEcMdyGFzZ5mMXeT/0EfAkJjKAyh31SiwQS11yGXsJ5r/xHVzGvQWpoxxDDKRBtO5lp1MSXnvK2vgWmBwmIB84ItJhuBi0tYYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=2vag2aFf; arc=none smtp.client-ip=209.85.128.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="2vag2aFf" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4870206f73bso20681745e9.3 for ; Tue, 24 Mar 2026 01:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1774342055; x=1774946855; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=D6Ly+Y1OaGrVPqGuh6+YPQYhQbgbR6xEfPk5ktqV5IQ=; b=2vag2aFfDgWe2MSYJMaX/FTfJPtLNUnY5FjFHKiPa5MjdQo9Y9IMXJbDCGmwj97OXC pLAWLzCf1fYvHz4pc9zwNELSsNw8KWUIsVfceJArYz2Rmffk5hJo16OYB14E76iplX8V BcjoSwm+WUFBrgt5ESvPZUO/mA8N0mvzYdXs4eVUj2xNBwbjByq3mCqSlHzM8lvOdyGo a/oVdkq40uwjWYVN0wujWk/ADfZ/eahkoufcynX3g58oVVVwFDzn82bg6/SuCcBF3o+K Zk1Fv6xwqYdQHUtaCytIEVHwTLkl71ryfrACqV78LTJGDTQ0S069/l65qemHadvpT7Ai dhOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774342055; x=1774946855; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=D6Ly+Y1OaGrVPqGuh6+YPQYhQbgbR6xEfPk5ktqV5IQ=; b=mT3xkMrFS3rf7rMGLV851MKKO776xlUvrw8bKADXG1w0X8yI3tZOd13OoqEtCTwzY5 wOnz6MMeWdLW56ZzKUxdsuohvjoPfZrObXmAcby7p+O/arQ0OwkbTxj8usIlWbsoB3KZ cNVGtFMA61z0/eAViwx1lFswUweaZQl+bvCxA44Mbic13E2D3jKOrw2v173UjySbq7WT YDSauy9YQud9VrbnykR9AgdsGD0tzJYVrbX5hjq581MjVduhdbopmuyRzvNcODzNzs8p 80zRTz9IixRQwsVjxboTOawceCa9WjVp+upBPVzAtRyROF1ZzmHGJFc4c+T3m5usYJhi JS/A== X-Forwarded-Encrypted: i=1; AJvYcCWT23g+42kOpiw2+i45sXhIIMQ9nF7QLI5aRAHVKivHjRwn7NTeejZxGaUgmDIzM+B4zSz/w1eNi/tZecU=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9ClBfB6oRHLzI12K4apajoVNn17mIaSl3l5Q1vDoxnYz4Z2GN AvNMdRr7d03Z9pEQQDiVqHpyaP3oam1ncm+jd5iutfAz4i/B4sxWebcgp3FB+KAVgF0= X-Gm-Gg: ATEYQzyJFtNClr+zh5T4/AZM2aEZFKs55hZ/LsicBuWigY/voMoFw3JFGHr1Y+mO0an Y7f25MHSXhTXLlI8BWlh0/1sgXbHCgFw0Il3y+xaB5d7zI5isC+uElKMMSBQrSlgpYJyu745PCq dvqu0Idt634ETY3GDRccT+UNsaLxthr0TQhbtuK6uJi2LrRvCuC56qXERJsNMtU0JmmbmFdqDK9 amIzXN2wEgl+GZow+V7dadajkYEeEa+FF5bl4jh+hRC2LYWHMXi7eFPZlU0RpZQRRmzTS+1yRJc H4dYB9t/svB8DFkfaJp2GF++MTxGai1FVF5/p5+9ojNfGM46F9kzVb5V/h/rKmPw73rzHav2vcu 1CzJ1mRImliBvDsMr/U9AdTFtKw9W5Z8Z3dSRZFAodEZrI3/d6sKgaPzkGFWd62xVUds= X-Received: by 2002:a05:600c:c167:b0:486:fb5c:3b20 with SMTP id 5b1f17b1804b1-486fedc39e5mr196391305e9.13.1774342055028; Tue, 24 Mar 2026 01:47:35 -0700 (PDT) Received: from localhost ([151.43.230.2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-487116f17f3sm31333105e9.1.2026.03.24.01.47.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 01:47:34 -0700 (PDT) From: Francesco Lavra To: Lorenzo Bianconi , Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v9 1/6] iio: imu: st_lsm6dsx: Fix check for invalid samples from FIFO Date: Tue, 24 Mar 2026 09:47:33 +0100 Message-Id: <20260324084733.653906-1-flavra@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260324084655.653781-1-flavra@baylibre.com> References: <20260324084655.653781-1-flavra@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3896; i=flavra@baylibre.com; h=from:subject; bh=LhhuQW+kXumxf4ZHnfybInW36mhcntwwfWxHRNAL3MI=; b=owEB7QES/pANAwAKAe3xO3POlDZfAcsmYgBpwk+lL3a1po6S4t6UgIXVMNxGsQxe+I2iIBwUl 6sQCXcfE7yJAbMEAAEKAB0WIQSGV4VPlTvcox7DFObt8TtzzpQ2XwUCacJPpQAKCRDt8TtzzpQ2 X/YpC/wIwu5GGBLlNaWQ+zF2JSZosTWqJ7IQSMY98lF9BVvCHPMKn2kYlHSIRSvhIu7veNsOr/E xV+wuYVF6uQZDHgJCkV3u3T1t7OEHdlQvN1dHf9YGxWCfYcAw1AmhvLktRgHUhJksZZ4p7HYrqh Ds+yEkA5n73knf0JR2XNlSm3JRkii6QXO7i/rvuj9uElv2QhAKRuldoAInaXZQ7K/IRgo3Fq56r NyMB4vUE70ggPzM2drhmucN6k+1uxgjHnMAcDBO6a6gjPbqXF6Tr1KQbwc8crVM4Syyl+e8ONiG +FCbaBtrvcqFJermd1C0YBASiOZhXM0T2hjdpxk5Ln0Mz3QbgS7TmaPquIUNO6CwqWaHaeQLxL2 vADLzOJU5jc5849eap7oabdOtGrm8obxYtCeuVMPCkRusBItUoXlghQkeaAySr0Dmy06H5GtVZh yIM8yayG+bdyURhkHL+u1wgFPITd3yeAwTXgBWu8FVdMCLynEwakfhvetDQz7jaO1n770= X-Developer-Key: i=flavra@baylibre.com; a=openpgp; fpr=8657854F953BDCA31EC314E6EDF13B73CE94365F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The DRDY_MASK feature implemented in sensor chips marks gyroscope and accelerometer invalid samples (i.e. samples that have been acquired during the settling time of sensor filters) with the special values 0x7FFFh, 0x7FFE, and 0x7FFD. The driver checks FIFO samples against these special values in order to discard invalid samples; however, it does the check regardless of the type of samples being processed, whereas this feature is specific to gyroscope and accelerometer data. This could cause valid samples to be discarded. Fix the above check so that it takes into account the type of samples being processed. To avoid casting to __le16 * when checking sample values, clean up the type representation for data read from the FIFO. Fixes: 960506ed2c69 ("iio: imu: st_lsm6dsx: enable drdy-mask if available") Signed-off-by: Francesco Lavra Acked-by: Lorenzo Bianconi --- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/i= mu/st_lsm6dsx/st_lsm6dsx_buffer.c index 5b28a3ffcc3d..19232146bd61 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -365,8 +365,6 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6d= sx_hw *hw, u8 addr, return 0; } =20 -#define ST_LSM6DSX_IIO_BUFF_SIZE (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \ - sizeof(s64)) + sizeof(s64)) /** * st_lsm6dsx_read_fifo() - hw FIFO read routine * @hw: Pointer to instance of struct st_lsm6dsx_hw. @@ -537,16 +535,24 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) } =20 #define ST_LSM6DSX_INVALID_SAMPLE 0x7ffd +static bool st_lsm6dsx_check_data(u8 tag, __le16 *data) +{ + if ((tag =3D=3D ST_LSM6DSX_GYRO_TAG || tag =3D=3D ST_LSM6DSX_ACC_TAG) && + (s16)le16_to_cpup(data) >=3D ST_LSM6DSX_INVALID_SAMPLE) + return false; + + return true; +} + static int st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, - u8 *data, s64 ts) + __le16 *data, s64 ts) { - s16 val =3D le16_to_cpu(*(__le16 *)data); struct st_lsm6dsx_sensor *sensor; struct iio_dev *iio_dev; =20 /* invalid sample during bootstrap phase */ - if (val >=3D ST_LSM6DSX_INVALID_SAMPLE) + if (!st_lsm6dsx_check_data(tag, data)) return -EINVAL; =20 /* @@ -609,7 +615,13 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *= hw) * must be passed a buffer that is aligned to 8 bytes so * as to allow insertion of a naturally aligned timestamp. */ - u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8); + struct { + union { + __le16 data[3]; + __le32 fifo_ts; + }; + aligned_s64 timestamp; + } iio_buff =3D { }; u8 tag; bool reset_ts =3D false; int i, err, read_len; @@ -648,7 +660,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *h= w) =20 for (i =3D 0; i < pattern_len; i +=3D ST_LSM6DSX_TAGGED_SAMPLE_SIZE) { - memcpy(iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE], + memcpy(&iio_buff, &hw->buff[i + ST_LSM6DSX_TAG_SIZE], ST_LSM6DSX_SAMPLE_SIZE); =20 tag =3D hw->buff[i] >> 3; @@ -659,7 +671,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *h= w) * B0 =3D ts[7:0], B1 =3D ts[15:8], B2 =3D ts[23:16], * B3 =3D ts[31:24] */ - ts =3D le32_to_cpu(*((__le32 *)iio_buff)); + ts =3D le32_to_cpu(iio_buff.fifo_ts); /* * check if hw timestamp engine is going to * reset (the sensor generates an interrupt @@ -670,7 +682,8 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *h= w) reset_ts =3D true; ts *=3D hw->ts_gain; } else { - st_lsm6dsx_push_tagged_data(hw, tag, iio_buff, + st_lsm6dsx_push_tagged_data(hw, tag, + iio_buff.data, ts); } } --=20 2.39.5 From nobody Sun Apr 5 13:12:37 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (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 2CC131A680E for ; Tue, 24 Mar 2026 08:47:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342065; cv=none; b=FSaHfEw4LdFf0sEmDmTHYKPmahZ1WMdQ33wykaU1+WQp8anOVHLam6jsAIKipOYSUJpHS8szUMoqBmewccfuwtis2MFicYbzPBubz4ktuMlnrURk3JZE9ik9sdWGvtUa4iqbJ4Cd/iFlUOgXcgboHtB2HmvvbgQbxCplvKHoPTw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342065; c=relaxed/simple; bh=zgp8NTdUREy2MLh20H6a+tMiC/1Tlmkrf0vlY1q2WQU=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WiFsKNyEcAqxX6M23HnKckv0PmzPIm0bhAMxhQKzhmuktgPY4O6PKiAuuov2Yu9ABk9KS8gTcu0kg6K3MKXMKEGL4ss2I6NJAp+pqQ1WKwRDfBTvaS7D2GmuftVTSGUBdV4idDZDOROFCE1guvD+4SrjyXEA213B7Wi2cJh7F2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=kV8jtjox; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="kV8jtjox" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-486fb14227cso9733715e9.3 for ; Tue, 24 Mar 2026 01:47:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1774342062; x=1774946862; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=cAfHzDr51uvPOkiugJ4Kjtulax/W7M8Q/janGYkUI3o=; b=kV8jtjoxsru5ULi6IxtF9IAp3DD1WcWwyjhzNmwc5+4JslaOEcd1nr9Z9oOiW4BsOA i3b62bGuJPZ2vNNRXRqe1pVox1rCdKrDswzb+2ZCPCoDH/Y+q0nYlZ1Uz9xWcVTehHCD c7nOc6WyFEdsFrsrzvZn9unPYEJN2f3LwIEWhgrgkWLnsKEvMZrcFPUbi9AfJdZYhIRM b2+e8ZC/jf+vH7yGBW80X9DMk5pgXZCKguioUfbap0UokANtdbZ9NK2LXM7/DvKuQvuH qcitEyeYiu+MsKliIew46UR+HEZboNgWxloN7aNaHqjbgAz5iVjpDpN+OklINMYSMJUL QX9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774342062; x=1774946862; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=cAfHzDr51uvPOkiugJ4Kjtulax/W7M8Q/janGYkUI3o=; b=LmlQ28qqpxoNIEaTeW762wiuPd3jAzssrNRV6vajORbQWT++cHF9TRS3hJ5LxE6DdZ uOWpofEnCygeOndzZcqizYk/o7oimCYyO1DShO8rfVU3SWP+mwFq5dc7EbpgD3o7r3b2 CMRroUB2JxTmKjstY2aENCs2c69g67fe9fPAUgpb/AMv47fzy1lJ5bWZoxxskbH/sOLi XNx17zA3B9ShAKuubviV3XDxZw+8bb58TWm0T5q5chWZznuzs2nUEdBxOh2I6Typnkbe UI3usSjE+Hz86lxnLip+NJYN/Dklu3pvfpvHnvl5OgwYQU7xYUvFeZc6bH00slaZIofe nJpA== X-Forwarded-Encrypted: i=1; AJvYcCUiNAutKsv93/8WUgyqLqcjgB8ui4pIkHzUjHnUWiaKd2BThZ9Cqcpl4+W3i5vDb0h8pbrhUEj/I/VjOOA=@vger.kernel.org X-Gm-Message-State: AOJu0YyFHv9fVGvKsaHIHsxhoG38GZTa0WKedgE2EZFDzJkY4HaXmfbK nVB+AzcbNDL1MFwuJ/fSz+QLHTJjA+wrbfIvHKF8/L2N25EKKcfvYie64LuM4HZcdySfE3jwyy2 m5aHel44= X-Gm-Gg: ATEYQzzfhfvcmjL4PDfiKjuHVz4C5DbPLzmFQqfeTeOB4rjLFLrBlF2p0CiA5GlwxAd GhcR2uOSgB6hUu/fWvWVWq4aZqWNTmImDV+VTobGrrjnWSZh7Wkf/8WD4X0noTyC+QVlw0QcbMt HTXFltu7zMlWu2S4ZBRlUnpYFm8/BYjwqCWM4GOKPJuZuXensoRVEdM41RjHsrhtr/kY9NOOvAD vAmHoSI3rdOJQD+R2zMoEIQ/sLnWGQp8w6wuWDb5b/2jmVZtkCnQy8eYo7hxEd61gybE45RfaTf hkuK0drkR5U+Qbrlgrx4ouwRvbkYuBxIXaglzPbVooG0nyESEeO/WqDwFcrFQfSmdb9kI+E3adc /QpUBKPB7Fo0u82zADRNsNa3I81Kp8DfLOnaULbYSOsNGi2DSM4UvDY1BhnCBZ66I/Hw= X-Received: by 2002:a05:600c:a47:b0:486:fc46:be9e with SMTP id 5b1f17b1804b1-486fee265demr224481385e9.24.1774342062456; Tue, 24 Mar 2026 01:47:42 -0700 (PDT) Received: from localhost ([151.43.230.2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4871174f2cesm33827245e9.10.2026.03.24.01.47.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 01:47:42 -0700 (PDT) From: Francesco Lavra To: Jonathan Corbet , Shuah Khan , Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org Subject: [PATCH v9 2/6] iio: Replace 'sign' field with union in struct iio_scan_type Date: Tue, 24 Mar 2026 09:47:40 +0100 Message-Id: <20260324084741.653947-1-flavra@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260324084655.653781-1-flavra@baylibre.com> References: <20260324084655.653781-1-flavra@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2823; i=flavra@baylibre.com; h=from:subject; bh=zgp8NTdUREy2MLh20H6a+tMiC/1Tlmkrf0vlY1q2WQU=; b=owEB7QES/pANAwAKAe3xO3POlDZfAcsmYgBpwk+sqeS/zfgDOZiBZSkdRU3R1Qf8Cd1bbq5y4 gzJi2myTLmJAbMEAAEKAB0WIQSGV4VPlTvcox7DFObt8TtzzpQ2XwUCacJPrAAKCRDt8TtzzpQ2 XxnqDACRZgIzL9sjnA3P7g6oBaKS1FYPPr2rjtJE6XkxXXVkBlM4QUEIBrGlgDWllpblvh9QfsK K+63M2UmJJMM2SqOBcAqCv6Oi/CyN42A3LX8MIHcX4bdbsWE7rwFJX6wapr5/66xCO1oDBdA3eC /jnSCQU+HK8/iSgaPG1ojwPm5e2RORKbURQmq72K6/rC/FmTkDvRpHwq4LmyvLTjZfugZbIk6XU X9VyfjvQcPoniIhndyNH2vNfZ/7R36lSJspy+gkETGpzBq6u6aj7PHi6j5NY8cS5B8qie1jzfZj Pdr7C1Gb2zUPP2Qamp2x5UuDxV23rVhjOHxuG11K78IlwKYBE1o66ywcK+DygFk//rEVH9zgGuD c4Q8D5JppPBEBFOqG0fS7FAT7b+F4YAJqjDjaZM9PJfT74wVfAicJHlorxQS7teN2a0mVKP/QSl Juh2dyOjTvKGDJY509nfXn5Y84c1L3Dks+kFU0JoIwQR6w/lDLZiS/GSZKeiX977ejm28= X-Developer-Key: i=flavra@baylibre.com; a=openpgp; fpr=8657854F953BDCA31EC314E6EDF13B73CE94365F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This field is used to differentiate between signed and unsigned integers. A following commit will extend its use in order to add support for non- integer scan elements; therefore, replace it with a union that contains a more generic 'format' field. This union will be dropped when all drivers are changed to use the format field. Opportunistically replace character literals with symbolic constants that represent the set of allowed values for the format field. Signed-off-by: Francesco Lavra --- Documentation/driver-api/iio/buffers.rst | 4 ++-- include/linux/iio/iio.h | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Documentation/driver-api/iio/buffers.rst b/Documentation/drive= r-api/iio/buffers.rst index 63f364e862d1..e16abaf826fe 100644 --- a/Documentation/driver-api/iio/buffers.rst +++ b/Documentation/driver-api/iio/buffers.rst @@ -78,7 +78,7 @@ fields in iio_chan_spec definition:: /* other members */ int scan_index struct { - char sign; + char format; u8 realbits; u8 storagebits; u8 shift; @@ -98,7 +98,7 @@ following channel definition:: /* other stuff here */ .scan_index =3D 0, .scan_type =3D { - .sign =3D 's', + .format =3D IIO_SCAN_FORMAT_SIGNED_INT, .realbits =3D 12, .storagebits =3D 16, .shift =3D 4, diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index a9ecff191bd9..745290bd9af4 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -176,9 +176,25 @@ struct iio_event_spec { unsigned long mask_shared_by_all; }; =20 +/** + * define IIO_SCAN_FORMAT_SIGNED_INT - signed integer data format + * + * &iio_scan_type.format value for signed integers (two's complement). + */ +#define IIO_SCAN_FORMAT_SIGNED_INT 's' + +/** + * define IIO_SCAN_FORMAT_UNSIGNED_INT - unsigned integer data format + * + * &iio_scan_type.format value for unsigned integers. + */ +#define IIO_SCAN_FORMAT_UNSIGNED_INT 'u' + /** * struct iio_scan_type - specification for channel data format in buffer - * @sign: 's' or 'u' to specify signed or unsigned + * @sign: Deprecated, use @format instead. + * @format: Data format, can have any of the IIO_SCAN_FORMAT_* + * values. * @realbits: Number of valid bits of data * @storagebits: Realbits + padding * @shift: Shift right by this before masking out realbits. @@ -189,7 +205,10 @@ struct iio_event_spec { * @endianness: little or big endian */ struct iio_scan_type { - char sign; + union { + char sign; + char format; + }; u8 realbits; u8 storagebits; u8 shift; --=20 2.39.5 From nobody Sun Apr 5 13:12:37 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 6C9123D88E2 for ; Tue, 24 Mar 2026 08:47:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342072; cv=none; b=IQyaDxWGRx1QsK1mnMw44YepYuKJVX1GrIHmDej3Y9z5D9QxFt0MBLHlUdQcNvGm9uyvn8by7nvjqObtd5MBSZlTGFW739vql0vejZ+elhTV/YvBqt8eKJawUlWaX585H6CKwT+n1pLAYLs7TwTO3cKrl9OJnctoZRN7q9Cnmdc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342072; c=relaxed/simple; bh=Pmx09FjUuabFWsJvX9ZIiyJWEPRXSi3I/1OkkdhbSUY=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dkgI/0AsUJ8kxHoJ2dTcTtfuqnKogYcr1twEa6OQ9aJeYzyu6zeuH/SrDS+beKCvo3j3l5rt6eQbixmaYLoqaWZ0x+71ASShxSK2RGswb7hOjXka5eGmDnO55k69Q/nQ4mxnOthkp9Ry+43ZpIRxJewin/iCrCBZgBXSirwV3rM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=LghlXToY; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="LghlXToY" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-486fb112c09so32744825e9.1 for ; Tue, 24 Mar 2026 01:47:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1774342068; x=1774946868; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=r00Ss0X9VzFEuDRGE5q7OfOKcRugbWSqniqvg/LPyQ0=; b=LghlXToYcVJwwPS4uuhLR3fSgimoJ9WWjWJwWUHhL17gztjxEK0HOLPlUYT1N/aMTv cGg+jk3icATChIJtBznLZSukyIm4th66uMt3GloxJ5zOadCT4WGTU2WzlpfH4e7/I+sX joRjxM67/egRggWjemwcCGIWwQ2mQn1LhEXoK5bPeyvtv7QV8eGLprKZoO0rfa9SXswK aP1/L5iL3HqJyc7eQHxgiBdvYJJQLp1yf3HjFjXTHVPUg0HmdPSMi9yf1Awyu/aJmp7x R2nB8N7xDgrQDDobqnp+8qk+CTgv3wK5lWxoaGOUuoIy3oDRapa+VEjsqe5TMxN+d8t4 NdFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774342068; x=1774946868; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=r00Ss0X9VzFEuDRGE5q7OfOKcRugbWSqniqvg/LPyQ0=; b=s4DEXTVFlKFp4DuxVfA35vgBPlagHdbXSIgxUfKcVIwKNx8HtuIxJrb6BmMcoU7t4k ppTqFGYLHO+ck/Lk62tvUnnTCzd/gXJWuEahHqtJVfb/G5Y6C8G7GgynMukxq3I0MNUe UxKDq3xSxz+/zII8kD1ftLEHyGPgMoFFskCxwIX89LVBLmZEQZmSX/3R6qr7lifHEx87 PSZ49/tXwm0kHLOQIWO63nHYABCjHl8ZZ31oNS4JyIRLE5WV6tFI+/JYkJcnRHehwhYr ODUcGNAaCKs5IQP3qB5IorWhj6QARW3ZSZkOCTLiuPpDflOoXaFer7X3W98WMtZpKn0i QKdg== X-Forwarded-Encrypted: i=1; AJvYcCXMb/DIOfLe3Z08aE7Xp5Gnhq/pchoMkoyvybYjaa6F0d/S36PwmsEqSzRXbAVrxMLPGj6iYyl1wNWSyAQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxFWmRiQ2vhhLCCcj0zArH0hXbNqBDHARj2UDur+ck8xwLeFfDE 9jOX+0vtH9Vbv20GIwA9VaLqidqkf1LxBz1BYkDFdpouopydielJP7i/oY2GwvRUntw= X-Gm-Gg: ATEYQzwjbHjyb5wpXJ+Ggh16Z+/g4uA/osYVFqWioVwHYLP9tvbekcqOs1QQk6sEjcF FYYD5xuKn23W3Q4JyYr/7Hzj5SpvOPZtX/9pCoPKVZNq890O1c3mqG2zLEMXe+Aki8nN+0oOoWW TQndObjhH5xvIPNBmcX9VsnL0LZ+C4eAKzjUNCZ6YAvktOqQ01eC1J8BsL8T+M3WruiTJq1jE8t LUoaN4f4ZHx+io3y0zghcCoJCDe7Q6ms9cLqHlCDgPKSfge/cJcugqMITLeNBnQ4MNkuCQo2x+i wU8fISgHJx/IR/OpPn1T3nKqxUqBVcbcnXxG7qk4z7VBKPbYd2QVMRGLQaCfUDm09/HlmNZZdPk wbM53zYKBK9M8vI0CqICKST0kkEzUozdJyZUn4yQZz4M9EjYsbJNlHEfYa2rKxVnMSYECVBTiJS L5zw== X-Received: by 2002:a05:600c:5294:b0:486:fe46:b647 with SMTP id 5b1f17b1804b1-4870334cb27mr162699155e9.10.1774342067728; Tue, 24 Mar 2026 01:47:47 -0700 (PDT) Received: from localhost ([151.43.230.2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4871174f2desm42738755e9.9.2026.03.24.01.47.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 01:47:47 -0700 (PDT) From: Francesco Lavra To: Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v9 3/6] iio: tools: Add support for floating-point types in buffer scan elements Date: Tue, 24 Mar 2026 09:47:46 +0100 Message-Id: <20260324084746.653984-1-flavra@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260324084655.653781-1-flavra@baylibre.com> References: <20260324084655.653781-1-flavra@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6732; i=flavra@baylibre.com; h=from:subject; bh=Pmx09FjUuabFWsJvX9ZIiyJWEPRXSi3I/1OkkdhbSUY=; b=owEB7QES/pANAwAKAe3xO3POlDZfAcsmYgBpwk+yvAIzq2SkukP7iiVaZG3ChhyjyTILdbl1o IntpAUDUOuJAbMEAAEKAB0WIQSGV4VPlTvcox7DFObt8TtzzpQ2XwUCacJPsgAKCRDt8TtzzpQ2 X+x3C/9jcXLhig2HmXyjJ4uTsWGddZHaV4l20UtvgR6RzulQHZ3Qo+DeA/LGvD5xibYz9YACxng f7czaBF+mdD5SOxB12FYKujod7WD8gCmp6U1O0NUvY21YkhrB36b1okQHvqsNTEzSn6hckmWbo4 vAzRG64eWtxIjJk2oITn+Mw9zg2tYjoRNA7UCpb+1/XbgXA4IxyLbz8O/4J6bx12IC57qwI//DX sBtvu4KReW4kegDK2fAPrflfWYEHzTRdHj5+yBmfgqc9bS5nPCNNWk1JMCpW2QhWvYH2S3xwBhR UPL7K57UNURVw+Dj0bOg/5g4Qb/8KyGfjd7gtzJYB/g84Wc4C/ZlyQt84Raa4/7YfnxhmHHwrlq sMbAOvmfcslYEBBrnWu4ZYHgFJ7ZRQ2e4KnYlp+y6JfxvCdg2xrb51+rIjdUHYn72z9xPU3Yyg9 cIUedYihR52VycF4dlN8OeXLmzfxM8SJD6GRhroOtGgBlX6WGBmOEOO9AFvlaTN95HC/U= X-Developer-Key: i=flavra@baylibre.com; a=openpgp; fpr=8657854F953BDCA31EC314E6EDF13B73CE94365F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A subsequent commit will add floating-point support to the ABI; enhance the iio_generic_buffer tool to be able to parse this new data format. Signed-off-by: Francesco Lavra --- tools/iio/iio_generic_buffer.c | 70 ++++++++++++++++++++++++++++++---- tools/iio/iio_utils.c | 12 +++--- tools/iio/iio_utils.h | 4 +- 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c index bc82bb6a7a2a..000193612aad 100644 --- a/tools/iio/iio_generic_buffer.c +++ b/tools/iio/iio_generic_buffer.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -89,12 +90,19 @@ static void print1byte(uint8_t input, struct iio_channe= l_info *info) */ input >>=3D info->shift; input &=3D info->mask; - if (info->is_signed) { + switch (info->format) { + case 's': { int8_t val =3D (int8_t)(input << (8 - info->bits_used)) >> (8 - info->bits_used); printf("%05f ", ((float)val + info->offset) * info->scale); - } else { + break; + } + case 'u': printf("%05f ", ((float)input + info->offset) * info->scale); + break; + case 'f': + printf(" "); + break; } } =20 @@ -112,12 +120,30 @@ static void print2byte(uint16_t input, struct iio_cha= nnel_info *info) */ input >>=3D info->shift; input &=3D info->mask; - if (info->is_signed) { + switch (info->format) { + case 's': { int16_t val =3D (int16_t)(input << (16 - info->bits_used)) >> (16 - info->bits_used); printf("%05f ", ((float)val + info->offset) * info->scale); - } else { + break; + } + case 'u': printf("%05f ", ((float)input + info->offset) * info->scale); + break; + case 'f': { +#if defined(__FLT16_MAX__) + union { + uint16_t u; + _Float16 f; + } converter; + + converter.u =3D input; + printf("%05f ", ((float)converter.f + info->offset) * info->scale); +#else + printf(" "); +#endif + break; + } } } =20 @@ -135,12 +161,26 @@ static void print4byte(uint32_t input, struct iio_cha= nnel_info *info) */ input >>=3D info->shift; input &=3D info->mask; - if (info->is_signed) { + switch (info->format) { + case 's': { int32_t val =3D (int32_t)(input << (32 - info->bits_used)) >> (32 - info->bits_used); printf("%05f ", ((float)val + info->offset) * info->scale); - } else { + break; + } + case 'u': printf("%05f ", ((float)input + info->offset) * info->scale); + break; + case 'f': { + union { + uint32_t u; + float f; + } converter; + + converter.u =3D input; + printf("%05f ", (converter.f + info->offset) * info->scale); + break; + } } } =20 @@ -158,7 +198,8 @@ static void print8byte(uint64_t input, struct iio_chann= el_info *info) */ input >>=3D info->shift; input &=3D info->mask; - if (info->is_signed) { + switch (info->format) { + case 's': { int64_t val =3D (int64_t)(input << (64 - info->bits_used)) >> (64 - info->bits_used); /* special case for timestamp */ @@ -167,8 +208,21 @@ static void print8byte(uint64_t input, struct iio_chan= nel_info *info) else printf("%05f ", ((float)val + info->offset) * info->scale); - } else { + break; + } + case 'u': printf("%05f ", ((float)input + info->offset) * info->scale); + break; + case 'f': { + union { + uint64_t u; + double f; + } converter; + + converter.u =3D input; + printf("%05f ", (converter.f + info->offset) * info->scale); + break; + } } } =20 diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c index c5c5082cb24e..e274a0d8376b 100644 --- a/tools/iio/iio_utils.c +++ b/tools/iio/iio_utils.c @@ -70,7 +70,7 @@ int iioutils_break_up_name(const char *full_name, char **= generic_name) =20 /** * iioutils_get_type() - find and process _type attribute data - * @is_signed: output whether channel is signed + * @format: output channel format * @bytes: output how many bytes the channel storage occupies * @bits_used: output number of valid bits of data * @shift: output amount of bits to shift right data before applying bit m= ask @@ -83,7 +83,7 @@ int iioutils_break_up_name(const char *full_name, char **= generic_name) * * Returns a value >=3D 0 on success, otherwise a negative error code. **/ -static int iioutils_get_type(unsigned int *is_signed, unsigned int *bytes, +static int iioutils_get_type(char *format, unsigned int *bytes, unsigned int *bits_used, unsigned int *shift, uint64_t *mask, unsigned int *be, const char *device_dir, int buffer_idx, @@ -93,7 +93,7 @@ static int iioutils_get_type(unsigned int *is_signed, uns= igned int *bytes, int ret; DIR *dp; char *scan_el_dir, *builtname, *builtname_generic, *filename =3D 0; - char signchar, endianchar; + char formatchar, endianchar; unsigned padint; const struct dirent *ent; =20 @@ -140,7 +140,7 @@ static int iioutils_get_type(unsigned int *is_signed, u= nsigned int *bytes, ret =3D fscanf(sysfsfp, "%ce:%c%u/%u>>%u", &endianchar, - &signchar, + &formatchar, bits_used, &padint, shift); if (ret < 0) { @@ -162,7 +162,7 @@ static int iioutils_get_type(unsigned int *is_signed, u= nsigned int *bytes, else *mask =3D (1ULL << *bits_used) - 1ULL; =20 - *is_signed =3D (signchar =3D=3D 's'); + *format =3D formatchar; if (fclose(sysfsfp)) { ret =3D -errno; fprintf(stderr, "Failed to close %s\n", @@ -487,7 +487,7 @@ int build_channel_array(const char *device_dir, int buf= fer_idx, if ((ret < 0) && (ret !=3D -ENOENT)) goto error_cleanup_array; =20 - ret =3D iioutils_get_type(¤t->is_signed, + ret =3D iioutils_get_type(¤t->format, ¤t->bytes, ¤t->bits_used, ¤t->shift, diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h index 663c94a6c705..8c72f002d050 100644 --- a/tools/iio/iio_utils.h +++ b/tools/iio/iio_utils.h @@ -32,7 +32,7 @@ extern const char *iio_dir; * @shift: amount of bits to shift right data before applying bit mask * @mask: a bit mask for the raw output * @be: flag if data is big endian - * @is_signed: is the raw value stored signed + * @format: format of the raw value * @location: data offset for this channel inside the buffer (in bytes) **/ struct iio_channel_info { @@ -46,7 +46,7 @@ struct iio_channel_info { unsigned shift; uint64_t mask; unsigned be; - unsigned is_signed; + char format; unsigned location; }; =20 --=20 2.39.5 From nobody Sun Apr 5 13:12:37 2026 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (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 18F203D8905 for ; Tue, 24 Mar 2026 08:47:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342077; cv=none; b=s8yxIw2d9bmnYK9if7aGXhmZgFbqNGipk+QO6A3giRNhrQWKoJlekHgu944SdWSmcCUxTKssbiekPLe5aF96ctXTkrexzM+d2AILDLq34pbbkKmIVMWV5HFxK22n+o7zNBWULoYBRmpxcei5liuZBzdn6Y69Mwj4wKwf8+Cc4e8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342077; c=relaxed/simple; bh=xFpob9c+xdUrGxlB4E2lbBybpHAq+lDyjDXxB70k3Yw=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Z8oyvxtvdZilvDet62sDpfgCUgTMKyks0tnS274B0nITLG4Bmmswtvud38fEOf6EP3R9rFJ+vsENlV+iCL4MmmSKhoeytnTsS4zBB21h+wR612G9ffcmgfZ3MqjUkiQpe5DUzBCljhUosk63NsmhptbvxwvRVe5aVKg8nlQxO7Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=apnL3AwH; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="apnL3AwH" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-486507134e4so11940775e9.0 for ; Tue, 24 Mar 2026 01:47:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1774342074; x=1774946874; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=eF1e1Cyy5V3LKfwsAPdeSvaTgNGlIqK/dZZ0MK0ok9s=; b=apnL3AwHZVba907nCL5CURBmZKXKIiIA/RtBTxo91xN49zSRRmAZhfYlKkZSoomKv5 8FSQGZXdO6Emy8qhNttAZ/d16E4nxuLySaJA0AzOuFS+cqhg6OtkCyiNE5y+jAnghrrp 2YojOkzB+BTOgsOY7DIxbLTvmrZn/Y/cdzRs0sq7mSZiDvNDAOanRcdlRhrK5ReCkvr3 2N6+9iAWhOtxUcZgaKeoJbR5oitMoaRr/6IhASIXmqfHVfl6lcZPJdzNvoVqFeIf6SAf mWFXsWRpTYyZCt9rDNSTKlJqJnGr5QqzYz75heOaE00fH7VAq6IBKH3QDnrik4XZpkJB kSng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774342074; x=1774946874; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=eF1e1Cyy5V3LKfwsAPdeSvaTgNGlIqK/dZZ0MK0ok9s=; b=rh/hdT0n6Do5DkTL9YO24x2ZNrhTyabbGp+iwtgh/RQfcEUGbgFcZdeFUmDvn9EbzV A0W8ddznc71NruBgxMd1jk07ZogItiHI8k4kWukPcyEu1EAqCJesOq0rtoHV3hpumoHf XYavL7l4XYPbmkvd8N5WdEZT9U9du9nESF1C4Klt5c/Egeb25ZEGXFyuCdssz4XvTSK/ 4FVZGfgTdYeoeY2lH43VwDrvrtRWHCmYSs1JjUMG8nfOCTyJfCfPYuU2gEYPw/KqL2m2 rqOYQYFaLdxvFLoMQCob+9aR4xm6jAiSJpMRAwmuzvYnpwEfslvhNJh9u7xcdSNvw/Tn zjAA== X-Forwarded-Encrypted: i=1; AJvYcCV8B0pkpv9muDKWEDPn21GRoQViCZXVNREibjzmtjsg7orE/rKGLOt5Hen2nkfjyuhV8RDqTO/bQQ0Mpb0=@vger.kernel.org X-Gm-Message-State: AOJu0Yy/puSMxBazCmOFs8eWSe1a7BLPhgGYZ/1aNlRHs+I/4spUVnu6 gKHZUEDM/1JaPNTrtDZBhhfja+txXLMjiVaWeEVII9g3sJhVUWjNNX1M+m/kmOa/7g4= X-Gm-Gg: ATEYQzwx94UD/7Hw5qmMMq0r4nVrC9qBthjE9NdJIlVgZPg0EoR8zYD02DI/iRokAeS EsKLnfKu3F+7l/E8USZGLs3SQ1H4pI6IuRB6/zEZWEXt65W0ezsHUcXDXbYdNAHwtXN8I5IcQtC znNjOZqDcPTsdrMjft2gnQ+0X9soeV030FpsiF6pcp2DMuf2l+HEY8udU1Jm122OOk/x8L+gaAS iG6cbte8FdQ55OSeQ6o7KF0VQUOcZUXETVk3RjTMpaJJHno1jy+fSQmxC5bRJBmimKOFRDeC+cK cCInnSfLgq9aZpv02UfY/2RZ2hRfnVpf/0yWGrnlnzDKC/z8KDpXW5crrgCGPO6jyBpeAitdx2T DADeNXmz3ZAo5bB+w1QPHuKhtlimN0mTWNDo1QMNIwuJL0tuIbgjrl+xOeJ3GBloULZE= X-Received: by 2002:a05:600c:3b07:b0:485:4278:2558 with SMTP id 5b1f17b1804b1-486fedab705mr205574955e9.6.1774342074389; Tue, 24 Mar 2026 01:47:54 -0700 (PDT) Received: from localhost ([151.43.230.2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4871105c7a5sm13620915e9.16.2026.03.24.01.47.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 01:47:54 -0700 (PDT) From: Francesco Lavra To: Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , Jonathan Corbet , Shuah Khan , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Subject: [PATCH v9 4/6] iio: ABI: Add support for floating-point numbers in buffer scan elements Date: Tue, 24 Mar 2026 09:47:53 +0100 Message-Id: <20260324084753.654037-1-flavra@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260324084655.653781-1-flavra@baylibre.com> References: <20260324084655.653781-1-flavra@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5730; i=flavra@baylibre.com; h=from:subject; bh=xFpob9c+xdUrGxlB4E2lbBybpHAq+lDyjDXxB70k3Yw=; b=owEB7QES/pANAwAKAe3xO3POlDZfAcsmYgBpwk+47k6zuOvuU9cHfiHzsxR9jkRQJzMMrJo3m Jv+TAeOEyKJAbMEAAEKAB0WIQSGV4VPlTvcox7DFObt8TtzzpQ2XwUCacJPuAAKCRDt8TtzzpQ2 X57EC/43WSzXh5yhYFg1UnElcKGkaOMJShfdS/lwgczqeTfBJX3nWtBAGKO5qHT3g5BtxM6DpjF GA0BGtlK9AMIQKDY8G4fJuKl3S5S1ruusuJHMYzo5Ro040Llo7L0vpdQsQAiINabLg3nL4xfts+ iEk+xEJvusQ5aBPcHvf+EDOI9AAdcC+TMc5HVRmjWt2vw9yT+6hN0guZ8tB8blTHQ1kxCVifiTf ZuPak3ArdPOCgfCCU1DfS8AHfYtnqt7i2WdIY/fu4YzrzmHl6Vk9TuIaJO9Wz3iWYmW3vkC10Kd E29UnD4RPr5AhrXQXaD810MTg/sJ7Z5R70X7fTeU/WmBe4P3QbwDMqOYy2P3DiWXwRAK5pFVIEt IrimJoKIxV1JJZdAdme76Hd7a9DHrXTi92e7gSLZVyhdhUQflwWOg5ayxZodI5TKS+57O7RxL5k EMLCXLHrfdFH3KJQjaXMOKOzHqxBVAW+000wg/z/Kz3ihIYj3YN66UPh+26g03QJizqPo= X-Developer-Key: i=flavra@baylibre.com; a=openpgp; fpr=8657854F953BDCA31EC314E6EDF13B73CE94365F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the data storage description of a scan element, the first character after the colon can have the values 's' and 'u' to specify signed and unsigned integers, respectively. Add 'f' as an allowed value to specify floating-point numbers formatted according to the IEEE 754 standard. Signed-off-by: Francesco Lavra --- Documentation/ABI/testing/sysfs-bus-iio | 33 +++++++++++++----------- Documentation/driver-api/iio/buffers.rst | 3 ++- Documentation/iio/iio_devbuf.rst | 3 ++- include/linux/iio/iio.h | 7 +++++ 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/te= sting/sysfs-bus-iio index 5f87dcee78f7..bd6c3305dd2b 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1510,21 +1510,24 @@ Contact: linux-iio@vger.kernel.org Description: Description of the scan element data storage within the buffer and hence the form in which it is read from user-space. - Form is [be|le]:[s|u]bits/storagebits[>>shift]. - be or le specifies big or little endian. s or u specifies if - signed (2's complement) or unsigned. bits is the number of bits - of data and storagebits is the space (after padding) that it - occupies in the buffer. shift if specified, is the shift that - needs to be applied prior to masking out unused bits. Some - devices put their data in the middle of the transferred elements - with additional information on both sides. Note that some - devices will have additional information in the unused bits - so to get a clean value, the bits value must be used to mask - the buffer output value appropriately. The storagebits value - also specifies the data alignment. So s48/64>>2 will be a - signed 48 bit integer stored in a 64 bit location aligned to - a 64 bit boundary. To obtain the clean value, shift right 2 - and apply a mask to zero the top 16 bits of the result. + Form is [be|le]:[f|s|u]bits/storagebits[>>shift]. + be or le specifies big or little endian. f means floating-point + (IEEE 754 binary format), s means signed (2's complement), u means + unsigned. bits is the number of bits of data and storagebits is the + space (after padding) that it occupies in the buffer; when using a + floating-point format, bits must be one of the width values defined + in the IEEE 754 standard for binary interchange formats (e.g. 16 + indicates the binary16 format for half-precision numbers). shift, + if specified, is the shift that needs to be applied prior to + masking out unused bits. Some devices put their data in the middle + of the transferred elements with additional information on both + sides. Note that some devices will have additional information in + the unused bits, so to get a clean value the bits value must be + used to mask the buffer output value appropriately. The storagebits + value also specifies the data alignment. So s48/64>>2 will be a + signed 48 bit integer stored in a 64 bit location aligned to a 64 + bit boundary. To obtain the clean value, shift right 2 and apply a + mask to zero the top 16 bits of the result. For other storage combinations this attribute will be extended appropriately. =20 diff --git a/Documentation/driver-api/iio/buffers.rst b/Documentation/drive= r-api/iio/buffers.rst index e16abaf826fe..8779022e3da5 100644 --- a/Documentation/driver-api/iio/buffers.rst +++ b/Documentation/driver-api/iio/buffers.rst @@ -37,9 +37,10 @@ directory contains attributes of the following form: * :file:`index`, the scan_index of the channel. * :file:`type`, description of the scan element data storage within the bu= ffer and hence the form in which it is read from user space. - Format is [be|le]:[s|u]bits/storagebits[Xrepeat][>>shift] . + Format is [be|le]:[f|s|u]bits/storagebits[Xrepeat][>>shift] . =20 * *be* or *le*, specifies big or little endian. + * *f*, specifies if floating-point. * *s* or *u*, specifies if signed (2's complement) or unsigned. * *bits*, is the number of valid data bits. * *storagebits*, is the number of bits (after padding) that it occupies = in the diff --git a/Documentation/iio/iio_devbuf.rst b/Documentation/iio/iio_devbu= f.rst index dca1f0200b0d..e91730fa3cea 100644 --- a/Documentation/iio/iio_devbuf.rst +++ b/Documentation/iio/iio_devbuf.rst @@ -83,9 +83,10 @@ and the relevant _type attributes to establish the data = storage format. =20 Read-only attribute containing the description of the scan element data st= orage within the buffer and hence the form in which it is read from userspace. F= ormat -is [be|le]:[s|u]bits/storagebits[Xrepeat][>>shift], where: +is [be|le]:[f|s|u]bits/storagebits[Xrepeat][>>shift], where: =20 - **be** or **le** specifies big or little-endian. +- **f** specifies if floating-point. - **s** or **u** specifies if signed (2's complement) or unsigned. - **bits** is the number of valid data bits. - **storagebits** is the number of bits (after padding) that it occupies i= n the diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 745290bd9af4..97ac4961585f 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -190,6 +190,13 @@ struct iio_event_spec { */ #define IIO_SCAN_FORMAT_UNSIGNED_INT 'u' =20 +/** + * define IIO_SCAN_FORMAT_FLOAT - floating-point data format + * + * &iio_scan_type.format value for IEEE 754 floating-point numbers. + */ +#define IIO_SCAN_FORMAT_FLOAT 'f' + /** * struct iio_scan_type - specification for channel data format in buffer * @sign: Deprecated, use @format instead. --=20 2.39.5 From nobody Sun Apr 5 13:12:37 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 C75C8390215 for ; Tue, 24 Mar 2026 08:48:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342084; cv=none; b=E/DrTj+tD2vHfnn07NaLW9kM7eeyuza7L+1YS/y0xr2qNylhqNe/JiNz6YE2tuJbpDf7KT9bMNMUfh7XfSXTgjWoH7Zx2r+5Of/Zcdfz9VRDXFkqBZvvJvLjYj2rL59yJHQpovDdr9spNFhvJITfklY/4FvbWb8svS0zE3UJZxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342084; c=relaxed/simple; bh=VDP5t4BDn3RTQYsYXBM61NGLGoZsGItzqihhTlW1ldg=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ej6RrsNwThwvjmbqGXQul9zgDaz1d7LkcfXeb3+lJqciyFP/+RArsH45LKuaujmdXkKIlBVTIiZhVUtdYF79z33ex+XdFZiN5sq8vivOBGMovEMobdLWMwV2dZ8RtBRqBMTfjWDK1pbU7huKrdKqkuGrRvJPZYkte75zzGCQHKk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=sIK46Yz+; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="sIK46Yz+" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-486b96760easo8971825e9.2 for ; Tue, 24 Mar 2026 01:48:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1774342081; x=1774946881; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=5+yw1a0G+6ay0y10P15I6U/dA0zfGZMo00ZafFMMNF4=; b=sIK46Yz+7p2bBaqd4fagPwywAPJZbGizP8yoqzIMPVQBNvlTI6J7bW1ZRa2UljAFji zRLhjhq/pXYcvSZxd6yoWJ9120qQBHSObTdiGAL47PF9dCUQqPum/7UfOkeWn86NhWsm /40wfgp210RLYx1NeQ7io1JfuZF8SE2QuO+Ob+7Cw85638NxRtPhTZi6Hz3JQiJHOGhX q+RXP0cEBQLeklVkehnVt0wix38hP6Bua9h/5ZQXbcfbPUJbOyk/osM/lGKZ1EKkFUNU fbhfPTSCndn3yH9DqCnam/DLo65bPk93nIkc/fOqjg01sdSetA/4Ijkd4YBU2AOkGQoU RhQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774342081; x=1774946881; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=5+yw1a0G+6ay0y10P15I6U/dA0zfGZMo00ZafFMMNF4=; b=diUBpwjICiO2uHI3L07cGyohfSSb8fTfKXH2PqT9Ri2cLXSMsI9Vy9GqrCxcDjGqaM MSboAHVOR8hosgpTpmZP9sKOQy9qnkRC2UYqd8YpgSXzySZqiviux162LXf7IMZoH2qp yCwGBjoP65lkihtOe0S9+qlqSR+2pNeS3z8xhA/uy3cgIOXP/QEpkm1A99GJGcXY8uZk MEXbtKz6mtEgzUUdPQ6ndEdPuBxWwpL2uxhT61gEpEbJvSeh9DANHlSbKXkevhxDu0tD h79zEymlLCiZJTSLWO4B8kt+YqgA2Dcz6hQkWATSbjJSRD6bEATEDLx8gBGpjj11bPoR 6Xgg== X-Forwarded-Encrypted: i=1; AJvYcCVS5QVrcq38FDugdGZdmysb/22Cskd0bYXPKuNGYtE9y731MvJFB2GBGNCt7Dr6kyYyJ190Mvw90DoZcYs=@vger.kernel.org X-Gm-Message-State: AOJu0YyWVRJSE8csIPF+B4O0aM87IEAAoDqKsXXRZSIhFvFgOChOJIa/ C2wKeUty4AIDcKGfAdQ2iYXhBsFbuZjKv1aBOOCNgRsuenKYa64+j2qi1owU8fpBrOc= X-Gm-Gg: ATEYQzxEL1ymk7QUIOELazCP/XcBqBHXom7fki5Xjc1yNJHUwuQxFZScJecCt5Hw5U5 D1gjumNq18Nm5c3J0UablnDOx9lY+/7wtAEYvrx+tn6i3LCTZe2pXq8pRpCZSOFQPayx5RBcYE2 LfaXoFZ/msrdTgmcv/eBnVtXE46iB0SPlsskVMZ/C45wZ9MzzSA0MbJsvj3gzOA7D4tfIzAGkUi S80e++7Zg0fDZsH3UMRK+MhhoBbYWe5VuNee0n5B2tTJV5VXiHA37V3Z0KZ45r3lgEYFoZYBBnE e15gW1WJIeMb6Dkw/6B0rNacl+NARbwHBX0nJ09yYhsOksn1qXl69loRFLCOcylO8+1nlei4IYu FTpnnBsefosenhmnVO37vjzzNtrHFdAsUNDXhtLoQn9V0POGGI7xwrai9do9MJ7N2/TI= X-Received: by 2002:a05:600c:8b0a:b0:47e:e57d:404 with SMTP id 5b1f17b1804b1-486fee0f917mr214427215e9.16.1774342081149; Tue, 24 Mar 2026 01:48:01 -0700 (PDT) Received: from localhost ([151.43.230.2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48711764509sm35219835e9.13.2026.03.24.01.48.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 01:48:00 -0700 (PDT) From: Francesco Lavra To: Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v9 5/6] iio: ABI: Add quaternion axis modifier Date: Tue, 24 Mar 2026 09:47:59 +0100 Message-Id: <20260324084800.654073-1-flavra@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260324084655.653781-1-flavra@baylibre.com> References: <20260324084655.653781-1-flavra@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3267; i=flavra@baylibre.com; h=from:subject; bh=VDP5t4BDn3RTQYsYXBM61NGLGoZsGItzqihhTlW1ldg=; b=owEB7QES/pANAwAKAe3xO3POlDZfAcsmYgBpwk+/23RdMrDKvc0bNMn04jz/xaWYU+32xhFNB YLa5+a4A7+JAbMEAAEKAB0WIQSGV4VPlTvcox7DFObt8TtzzpQ2XwUCacJPvwAKCRDt8TtzzpQ2 X4iBDACgpvWhlNer+JawhsKSoPfJgLM1ZEHsKETRhDXtzr+v/k38Z8QvYY02Wd56juhgwQ//wRb i3sZbavPc3LR935R5DEOjYFyaDNL0gBYDSLb44XnM2EtF3LjGMpCW3AuKssbptnsODE/8rmYT1a GEmvfGqqeF+SAxqJNF/TtQ3udxgBng2Oos83gVvg7Ou5UVGGoTvi2dOYGmA4wDDsIjZf0aWTlFn I2Xv8Ib9C7Dn5sENDfsYz6pIj1IX6Yu5+3S4E+b6mdvSCyd9RUh3Wgn3hhg159rgPO3dtOdxXrN qQg0RWosSMPz5GCfiPg5VSvvoRx888VFXYO0T2P4D+pu/laHotOC3o0iFOFIjgzhD5BA8lqsw1t fnjj9ucL0dDtQjr4cdoXmmcX9eWJgEZygeqYuxpuM0mWjTnEiYBpfbWCHXLNUasZU7iZUew7sSO qFihUOmhtXHb1ruv0xDA/bwM6vmMOhJGKztjvCU7jUBQ6UMT3+Bl//EdDb3JKcoOSy8Uc= X-Developer-Key: i=flavra@baylibre.com; a=openpgp; fpr=8657854F953BDCA31EC314E6EDF13B73CE94365F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This modifier applies to the IIO_ROT channel type, and indicates a data representation that specifies the {x, y, z} components of the normalized quaternion vector. Signed-off-by: Francesco Lavra Reviewed-by: David Lechner --- The use of this modifier depends on [1] to get the correct sizing of the buffer in userspace. [1]: https://lore.kernel.org/linux-iio/20260307-iio-fix-timestamp-alignment= -v2-4-d1d48fbadbbf@baylibre.com/ --- Documentation/ABI/testing/sysfs-bus-iio | 15 +++++++++++++++ drivers/iio/industrialio-core.c | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 1 + 4 files changed, 18 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/te= sting/sysfs-bus-iio index bd6c3305dd2b..46fef26e5376 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1755,6 +1755,21 @@ Description: measurement from channel Y. Units after application of scale and offset are milliamps. =20 +What: /sys/bus/iio/devices/iio:deviceX/in_rot_quaternionaxis_raw +KernelVersion: 7.1 +Contact: linux-iio@vger.kernel.org +Description: + Raw value of {x, y, z} components of the quaternion vector. These + components represent the axis about which a rotation occurs, and are + subject to the following constraints: + + - the quaternion vector is normalized, i.e. w^2 + x^2 + y^2 + z^2 =3D 1 + - the rotation angle is within the [-pi, pi] range, i.e. the w + component (which represents the amount of rotation) is non-negative + + These constraints allow the w value to be calculated from the other + components: w =3D sqrt(1 - (x^2 + y^2 + z^2)). + What: /sys/.../iio:deviceX/in_energy_en What: /sys/.../iio:deviceX/in_distance_en What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_en diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-cor= e.c index 22eefd048ba9..bd6f4f9f4533 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -157,6 +157,7 @@ static const char * const iio_modifier_names[] =3D { [IIO_MOD_ACTIVE] =3D "active", [IIO_MOD_REACTIVE] =3D "reactive", [IIO_MOD_APPARENT] =3D "apparent", + [IIO_MOD_QUATERNION_AXIS] =3D "quaternionaxis", }; =20 /* relies on pairs of these shared then separate */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 6d269b844271..d7c2bb223651 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -113,6 +113,7 @@ enum iio_modifier { IIO_MOD_ACTIVE, IIO_MOD_REACTIVE, IIO_MOD_APPARENT, + IIO_MOD_QUATERNION_AXIS, }; =20 enum iio_event_type { diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c index 03ca33869ce8..df6c43d7738d 100644 --- a/tools/iio/iio_event_monitor.c +++ b/tools/iio/iio_event_monitor.c @@ -145,6 +145,7 @@ static const char * const iio_modifier_names[] =3D { [IIO_MOD_ACTIVE] =3D "active", [IIO_MOD_REACTIVE] =3D "reactive", [IIO_MOD_APPARENT] =3D "apparent", + [IIO_MOD_QUATERNION_AXIS] =3D "quaternionaxis", }; =20 static bool event_is_known(struct iio_event_data *event) --=20 2.39.5 From nobody Sun Apr 5 13:12:37 2026 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (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 15E7C3D75C1 for ; Tue, 24 Mar 2026 08:48:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342092; cv=none; b=aogjWbEAyubyWKAfrDeppbVgciNRYIZN2o7gKWpI8BT6YaIbcVF0u1KANCtRXcr8Ry5SMD9bjZgjiO86bJJdSgfDSZzwSt7PEhpDYW2t7Ta0MiUSCu7YoNa3854U7pTknTYsC9bEgZW/AMeA24+NJcijGFHXJMU9IU8KO+wSQ6A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774342092; c=relaxed/simple; bh=M1bR74SI0tPTaMhcE4VEei67wFggtRphkmaDhDzfPG4=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RAaEdJoo2xEvkR7hCKBPOtT6EA9UH73aXR4qkjcldR4JfhdY933X2oiF0NLR0RMqMW+gNYxUAFjtvERakRVQ1UkXiO0JuMEGf9fj6zo/w+XA4SFgNvmj6N3S2G11N5hLAtXN7Z5wM8jix2SQGc+88CGXKXEv8Ek2ZTaiUOG9ukQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=uKWVMSYb; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="uKWVMSYb" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-439b94a19fdso3413848f8f.0 for ; Tue, 24 Mar 2026 01:48:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1774342089; x=1774946889; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=1Hd4/1E+XbufIZzEkLmBvSNQOVRMbBwqb3I3G56EJbg=; b=uKWVMSYbdZTj+1irmUO3gFhc/WP2SdvtdQnwwM3SAxfar9q0/SmVFGBL59usHqBMYu ZOLk5tWyYjgGA6xC2r7vr+W9tsAi3Ln4DzhEPWguNRt/kbYzhGessUZ5FL738+emil62 EOpK18b96j3DKcb9e9ARAJVPQ2cdAFySWW9NzmLLAnf6Eoi+tK/q+P+/upEaouGPti8j EDAn3qt9c80zNVaZcZh/F57wMuepMIy6rMocDD/+5/CWeWWnQbTMh6vLVfsXTgr5/NdQ wm9rzLaTC4VmY0W1xsG2p29WbOECcDMg56viIBdVsz3q9tcMYmideSQNhNDbamykkPiq L6lA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774342089; x=1774946889; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=1Hd4/1E+XbufIZzEkLmBvSNQOVRMbBwqb3I3G56EJbg=; b=EW/bBkmT4U2p2EXPZB1V9c6uLWSMKEzVqdZ0Z5kLsctcPkSI0dslXpqRO2MAXDLWtB 9ASQnLeQREvZuHyl6QWiRkQFHuYEArJWBTHNMaAapoz9hWJuje0c95B3eLYAg8Fdh95w o1P4ZkZ6yfOYnwGZ2UoZc6tqjdRn6BMEZNuswBn/0s74RV6RXF5UaxPswrpAsSJ2Y4w+ rTPCf36DeAZuECDuLUMwVaBShoKCgp/4wktSm2Xn8OkoLAZhTT72NeNzBl1NZRYFpu6k m4o8HT5j2YfNrj8SnhJPpQC/EP494vcDDWyEWv3nPO7EpezPNXni14BU4IuZb6yZkunZ aZBw== X-Forwarded-Encrypted: i=1; AJvYcCUghfdvnxVLuwgTREfYhhj9YLOnX9IGMoTeI30qW65xTiQK8j/RJAHIJltw2btYm3KtpPvIpDKKP0FnHws=@vger.kernel.org X-Gm-Message-State: AOJu0Ywah8MSWbtX+v0HIvW9w5H726qWMNhRrUE+kGxgHt15+3hOM6C6 q4j+dH8Wk53gNKXaQCs42LspDTPx3VDwf/664b0wuOHr2BmRCn/Ao/RWc5+BPnYfv/I= X-Gm-Gg: ATEYQzx3mgULmFZb+wIWJQ0lnAqTebCLM0/bPATRsw42aTxvGTojnW7LgasXn6DoCOz I2eNadQ17NJukCVk8hLAwXhdAwTnntl8ZhQFRv1biTa75YFDUrI63kBc1ZhCm/WiKQsVBfuGhZL YWr5SnVeb7EkgwBoNXrNIUyXZQuPTimMybIkCM670n1n7GRN1+xNf8nfeVxtjn2+CzeY0n8sq42 B3M24AkqL1DIdoR0/qTGdbvyzFiWpDT8TZOnAa2nOPYd+mzuvkei4FieC2/RIwj3macti1DuGQG gdweuI0daAsHbl8GoRUaE9LP/AZtt2Ztv8MfhPn5msCGjU2u3zkPnsVTmkVJYT0RTgMTUt+zt7n CuHDDzRKs4/yHYKeBuI5CRQiDc63qK2hOqI7+Gxkhiqfgbphd6ezfnWxicHxnIMAXPn8= X-Received: by 2002:a05:6000:608:b0:43b:436d:781b with SMTP id ffacd0b85a97d-43b64270a9amr22082536f8f.40.1774342089335; Tue, 24 Mar 2026 01:48:09 -0700 (PDT) Received: from localhost ([151.43.230.2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43b644ae16fsm36761005f8f.8.2026.03.24.01.48.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 01:48:09 -0700 (PDT) From: Francesco Lavra To: Lorenzo Bianconi , Jonathan Cameron , David Lechner , =?UTF-8?q?Nuno=20S=C3=A1?= , Andy Shevchenko , linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org Subject: [PATCH v9 6/6] iio: imu: st_lsm6dsx: Add support for rotation sensor Date: Tue, 24 Mar 2026 09:48:07 +0100 Message-Id: <20260324084808.654118-1-flavra@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260324084655.653781-1-flavra@baylibre.com> References: <20260324084655.653781-1-flavra@baylibre.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=15155; i=flavra@baylibre.com; h=from:subject; bh=M1bR74SI0tPTaMhcE4VEei67wFggtRphkmaDhDzfPG4=; b=owEB7QES/pANAwAKAe3xO3POlDZfAcsmYgBpwk/HMAsJ2gfTF3gpX6MPW8rgNZenxrT3ZNQOE M6V9WzNFk+JAbMEAAEKAB0WIQSGV4VPlTvcox7DFObt8TtzzpQ2XwUCacJPxwAKCRDt8TtzzpQ2 X+C/DACE2rA47CuZVHL4L4T/agSifz+mrBuwbRbp25Q2sBYXIHQViQlViVC5V5CAHM6oAsHtneC ysb/H/aiHdtKeqzjPJsz3stNXqDpmn/xaq5zwqeCb9ntzhBF/l40y2juaVkW6Oxsqfv5YYeF+LH UEthpaMr5L4gkM87EOQrHu3fxsvo2rNq6tgFOJ4eNQcPI3FYetgbDSsWya/VluQYUbnDfMkKtAI Eb0WgME5XEpbG8+NfcBRAQmSTVRw19aJr7LqmZVTF7Yqov1Qsr+pqkeb5vHcb2g5uzcOeepnvm8 GVmBhihOYkC57wtdWU3Ab8ZnSZt8BJ2OyGS20Lc1XzUGZ6dSZaSPUppgH+2byNJj6ZLBCfBvmpr nU6e8/ofHrAhbllL9hfzJiflf2vwYXX3OWwOINvDg9js2hSAVZqrF2EO2IDzpVa2YvX3xk3PXnf w8kEVP938XaNKm1TufPFBO136xxSKexlUBuWmDBxUpEk7HMnuKUVy3KRfZXu3w913y2IU= X-Developer-Key: i=flavra@baylibre.com; a=openpgp; fpr=8657854F953BDCA31EC314E6EDF13B73CE94365F Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some IMU chips in the LSM6DSX family have sensor fusion features that combine data from the accelerometer and gyroscope. One of these features generates rotation vector data and makes it available in the hardware FIFO as a quaternion (more specifically, the X, Y and Z components of the quaternion vector, expressed as 16-bit half-precision floating-point numbers). Add support for a new sensor instance that allows receiving sensor fusion data, by defining a new struct st_lsm6dsx_fusion_settings (which contains chip-specific details for the sensor fusion functionality), and adding this struct as a new field in struct st_lsm6dsx_settings. In st_lsm6dsx_core.c, populate this new struct for the LSM6DSV and LSM6DSV16X chips, and add the logic to initialize an additional IIO device if this struct is populated for the hardware type being probed. Note: a new IIO device is being defined (as opposed to adding channels to an existing device) because the rate at which sensor fusion data is generated may not match the data rate from any of the existing devices. Tested on LSM6DSV16X. Signed-off-by: Francesco Lavra Acked-by: Lorenzo Bianconi --- drivers/iio/imu/st_lsm6dsx/Makefile | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 28 +- .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 9 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 58 +++++ .../iio/imu/st_lsm6dsx/st_lsm6dsx_fusion.c | 243 ++++++++++++++++++ 5 files changed, 333 insertions(+), 7 deletions(-) create mode 100644 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_fusion.c diff --git a/drivers/iio/imu/st_lsm6dsx/Makefile b/drivers/iio/imu/st_lsm6d= sx/Makefile index 57cbcd67d64f..19a488254de3 100644 --- a/drivers/iio/imu/st_lsm6dsx/Makefile +++ b/drivers/iio/imu/st_lsm6dsx/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only st_lsm6dsx-y :=3D st_lsm6dsx_core.o st_lsm6dsx_buffer.o \ - st_lsm6dsx_shub.o + st_lsm6dsx_shub.o st_lsm6dsx_fusion.o =20 obj-$(CONFIG_IIO_ST_LSM6DSX) +=3D st_lsm6dsx.o obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) +=3D st_lsm6dsx_i2c.o diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_l= sm6dsx/st_lsm6dsx.h index 07b1773c87bd..767aadfe7061 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -294,6 +294,7 @@ enum st_lsm6dsx_sensor_id { ST_LSM6DSX_ID_EXT0, ST_LSM6DSX_ID_EXT1, ST_LSM6DSX_ID_EXT2, + ST_LSM6DSX_ID_FUSION, ST_LSM6DSX_ID_MAX }; =20 @@ -301,6 +302,17 @@ enum st_lsm6dsx_ext_sensor_id { ST_LSM6DSX_ID_MAGN, }; =20 +struct st_lsm6dsx_fusion_settings { + const struct iio_chan_spec *chan; + int chan_len; + struct st_lsm6dsx_reg odr_reg; + int odr_hz[ST_LSM6DSX_ODR_LIST_SIZE]; + int odr_len; + struct st_lsm6dsx_reg fifo_enable; + struct st_lsm6dsx_reg page_mux; + struct st_lsm6dsx_reg enable; +}; + /** * struct st_lsm6dsx_ext_dev_settings - i2c controller slave settings * @i2c_addr: I2c slave address list. @@ -388,6 +400,7 @@ struct st_lsm6dsx_settings { struct st_lsm6dsx_hw_ts_settings ts_settings; struct st_lsm6dsx_shub_settings shub_settings; struct st_lsm6dsx_event_settings event_settings; + struct st_lsm6dsx_fusion_settings fusion_settings; }; =20 enum st_lsm6dsx_fifo_mode { @@ -510,6 +523,9 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sens= or, u32 odr, u8 *val); int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name); int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enab= le); int st_lsm6dsx_shub_read_output(struct st_lsm6dsx_hw *hw, u8 *data, int le= n); +int st_lsm6dsx_fusion_probe(struct st_lsm6dsx_hw *hw, const char *name); +int st_lsm6dsx_fusion_set_enable(struct st_lsm6dsx_sensor *sensor, bool en= able); +int st_lsm6dsx_fusion_set_odr(struct st_lsm6dsx_sensor *sensor, bool enabl= e); int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable); =20 static inline int @@ -564,12 +580,14 @@ st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio= _dev, static inline int st_lsm6dsx_device_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) { - if (sensor->id =3D=3D ST_LSM6DSX_ID_EXT0 || - sensor->id =3D=3D ST_LSM6DSX_ID_EXT1 || - sensor->id =3D=3D ST_LSM6DSX_ID_EXT2) + switch (sensor->id) { + case ST_LSM6DSX_ID_EXT0 ... ST_LSM6DSX_ID_EXT2: return st_lsm6dsx_shub_set_enable(sensor, enable); - - return st_lsm6dsx_sensor_set_enable(sensor, enable); + case ST_LSM6DSX_ID_FUSION: + return st_lsm6dsx_fusion_set_enable(sensor, enable); + default: + return st_lsm6dsx_sensor_set_enable(sensor, enable); + } } =20 static const diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/i= mu/st_lsm6dsx/st_lsm6dsx_buffer.c index 19232146bd61..d5935106a373 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -88,6 +88,7 @@ enum st_lsm6dsx_fifo_tag { ST_LSM6DSX_EXT0_TAG =3D 0x0f, ST_LSM6DSX_EXT1_TAG =3D 0x10, ST_LSM6DSX_EXT2_TAG =3D 0x11, + ST_LSM6DSX_ROT_TAG =3D 0x13, }; =20 static const @@ -226,8 +227,11 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_s= ensor *sensor, u8 data; =20 /* Only internal sensors have a FIFO ODR configuration register. */ - if (sensor->id >=3D ARRAY_SIZE(hw->settings->batch)) + if (sensor->id >=3D ARRAY_SIZE(hw->settings->batch)) { + if (sensor->id =3D=3D ST_LSM6DSX_ID_FUSION) + return st_lsm6dsx_fusion_set_odr(sensor, enable); return 0; + } =20 batch_reg =3D &hw->settings->batch[sensor->id]; if (batch_reg->addr) { @@ -586,6 +590,9 @@ st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u= 8 tag, case ST_LSM6DSX_EXT2_TAG: iio_dev =3D hw->iio_devs[ST_LSM6DSX_ID_EXT2]; break; + case ST_LSM6DSX_ROT_TAG: + iio_dev =3D hw->iio_devs[ST_LSM6DSX_ID_FUSION]; + break; default: return -EINVAL; } diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu= /st_lsm6dsx/st_lsm6dsx_core.c index 450cb5b47346..630e2cae6f19 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -94,6 +94,26 @@ =20 #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f =20 +/* Raw values from the IMU are 16-bit half-precision floating-point number= s. */ +#define ST_LSM6DSX_CHANNEL_ROT \ +{ \ + .type =3D IIO_ROT, \ + .modified =3D 1, \ + .channel2 =3D IIO_MOD_QUATERNION_AXIS, \ + .info_mask_shared_by_all =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available =3D \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index =3D 0, \ + .scan_type =3D { \ + .format =3D IIO_SCAN_FORMAT_FLOAT, \ + .realbits =3D 16, \ + .storagebits =3D 16, \ + .endianness =3D IIO_LE, \ + .repeat =3D 3, \ + }, \ + .ext_info =3D st_lsm6dsx_ext_info, \ +} + static const struct iio_event_spec st_lsm6dsx_ev_motion[] =3D { { .type =3D IIO_EV_TYPE_THRESH, @@ -153,6 +173,11 @@ static const struct iio_chan_spec st_lsm6ds0_gyro_chan= nels[] =3D { IIO_CHAN_SOFT_TIMESTAMP(3), }; =20 +static const struct iio_chan_spec st_lsm6dsx_fusion_channels[] =3D { + ST_LSM6DSX_CHANNEL_ROT, + IIO_CHAN_SOFT_TIMESTAMP(1), +}; + static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] =3D { { .reset =3D { @@ -1492,6 +1517,33 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_s= ensor_settings[] =3D { }, }, }, + .fusion_settings =3D { + .chan =3D st_lsm6dsx_fusion_channels, + .chan_len =3D ARRAY_SIZE(st_lsm6dsx_fusion_channels), + .odr_reg =3D { + .addr =3D 0x5e, + .mask =3D GENMASK(5, 3), + }, + .odr_hz[0] =3D 15, + .odr_hz[1] =3D 30, + .odr_hz[2] =3D 60, + .odr_hz[3] =3D 120, + .odr_hz[4] =3D 240, + .odr_hz[5] =3D 480, + .odr_len =3D 6, + .fifo_enable =3D { + .addr =3D 0x44, + .mask =3D BIT(1), + }, + .page_mux =3D { + .addr =3D 0x01, + .mask =3D BIT(7), + }, + .enable =3D { + .addr =3D 0x04, + .mask =3D BIT(1), + }, + }, }, { .reset =3D { @@ -2899,6 +2951,12 @@ int st_lsm6dsx_probe(struct device *dev, int irq, in= t hw_id, return err; } =20 + if (hw->settings->fusion_settings.chan) { + err =3D st_lsm6dsx_fusion_probe(hw, name); + if (err) + return err; + } + if (hw->irq > 0) { err =3D st_lsm6dsx_irq_setup(hw); if (err < 0) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_fusion.c b/drivers/iio/i= mu/st_lsm6dsx/st_lsm6dsx_fusion.c new file mode 100644 index 000000000000..9fb3e19e4a55 --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_fusion.c @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * STMicroelectronics st_lsm6dsx IMU sensor fusion + * + * Copyright 2026 BayLibre, SAS + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "st_lsm6dsx.h" + +static int +st_lsm6dsx_fusion_get_odr_val(const struct st_lsm6dsx_fusion_settings *set= tings, + u32 odr_mHz, u8 *val) +{ + int odr_hz =3D odr_mHz / MILLI; + int i; + + for (i =3D 0; i < settings->odr_len; i++) { + if (settings->odr_hz[i] =3D=3D odr_hz) + break; + } + if (i =3D=3D settings->odr_len) + return -EINVAL; + + *val =3D i; + return 0; +} + +/** + * st_lsm6dsx_fusion_page_enable - Enable access to sensor fusion configur= ation + * registers. + * @hw: Sensor hardware instance. + * + * Return: 0 on success, negative value on error. + */ +static int st_lsm6dsx_fusion_page_enable(struct st_lsm6dsx_hw *hw) +{ + const struct st_lsm6dsx_reg *mux; + + mux =3D &hw->settings->fusion_settings.page_mux; + + return regmap_set_bits(hw->regmap, mux->addr, mux->mask); +} + +/** + * st_lsm6dsx_fusion_page_disable - Disable access to sensor fusion + * configuration registers. + * @hw: Sensor hardware instance. + * + * Return: 0 on success, negative value on error. + */ +static int st_lsm6dsx_fusion_page_disable(struct st_lsm6dsx_hw *hw) +{ + const struct st_lsm6dsx_reg *mux; + + mux =3D &hw->settings->fusion_settings.page_mux; + + return regmap_clear_bits(hw->regmap, mux->addr, mux->mask); +} + +static int st_lsm6dsx_fusion_set_odr_locked(struct st_lsm6dsx_sensor *sens= or, + bool enable) +{ + const struct st_lsm6dsx_fusion_settings *settings; + struct st_lsm6dsx_hw *hw =3D sensor->hw; + int err; + + settings =3D &hw->settings->fusion_settings; + if (enable) { + const struct st_lsm6dsx_reg *reg =3D &settings->odr_reg; + u8 odr_val; + u8 data; + + st_lsm6dsx_fusion_get_odr_val(settings, sensor->hwfifo_odr_mHz, + &odr_val); + data =3D ST_LSM6DSX_SHIFT_VAL(odr_val, reg->mask); + err =3D regmap_update_bits(hw->regmap, reg->addr, reg->mask, + data); + if (err) + return err; + } + + return regmap_assign_bits(hw->regmap, settings->fifo_enable.addr, + settings->fifo_enable.mask, enable); +} + +int st_lsm6dsx_fusion_set_enable(struct st_lsm6dsx_sensor *sensor, bool en= able) +{ + struct st_lsm6dsx_hw *hw =3D sensor->hw; + const struct st_lsm6dsx_reg *en_reg; + int err; + + guard(mutex)(&hw->page_lock); + + en_reg =3D &hw->settings->fusion_settings.enable; + err =3D st_lsm6dsx_fusion_page_enable(hw); + if (err) + return err; + + err =3D regmap_assign_bits(hw->regmap, en_reg->addr, en_reg->mask, enable= ); + if (err) { + st_lsm6dsx_fusion_page_disable(hw); + return err; + } + + return st_lsm6dsx_fusion_page_disable(hw); +} + +int st_lsm6dsx_fusion_set_odr(struct st_lsm6dsx_sensor *sensor, bool enabl= e) +{ + struct st_lsm6dsx_hw *hw =3D sensor->hw; + int err; + + guard(mutex)(&hw->page_lock); + + err =3D st_lsm6dsx_fusion_page_enable(hw); + if (err) + return err; + + err =3D st_lsm6dsx_fusion_set_odr_locked(sensor, enable); + if (err) { + st_lsm6dsx_fusion_page_disable(hw); + return err; + } + + return st_lsm6dsx_fusion_page_disable(hw); + +out: +} + +static int st_lsm6dsx_fusion_read_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *ch, + int *val, int *val2, long mask) +{ + struct st_lsm6dsx_sensor *sensor =3D iio_priv(iio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *val =3D sensor->hwfifo_odr_mHz / MILLI; + *val2 =3D (sensor->hwfifo_odr_mHz % MILLI) * (MICRO / MILLI); + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int st_lsm6dsx_fusion_write_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct st_lsm6dsx_sensor *sensor =3D iio_priv(iio_dev); + const struct st_lsm6dsx_fusion_settings *settings; + int err; + + settings =3D &sensor->hw->settings->fusion_settings; + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + u32 odr_mHz =3D val * MILLI + val2 * (MILLI / MICRO); + u8 odr_val; + + /* check that the requested frequency is supported */ + err =3D st_lsm6dsx_fusion_get_odr_val(settings, odr_mHz, &odr_val); + if (err) + return err; + + sensor->hwfifo_odr_mHz =3D odr_mHz; + return 0; + } + default: + return -EINVAL; + } +} + +static int st_lsm6dsx_fusion_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, + int *length, long mask) +{ + struct st_lsm6dsx_sensor *sensor =3D iio_priv(indio_dev); + const struct st_lsm6dsx_fusion_settings *settings; + + settings =3D &sensor->hw->settings->fusion_settings; + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals =3D settings->odr_hz; + *type =3D IIO_VAL_INT; + *length =3D settings->odr_len; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static const struct iio_info st_lsm6dsx_fusion_info =3D { + .read_raw =3D st_lsm6dsx_fusion_read_raw, + .read_avail =3D st_lsm6dsx_fusion_read_avail, + .write_raw =3D st_lsm6dsx_fusion_write_raw, + .hwfifo_set_watermark =3D st_lsm6dsx_set_watermark, +}; + +int st_lsm6dsx_fusion_probe(struct st_lsm6dsx_hw *hw, const char *name) +{ + const struct st_lsm6dsx_fusion_settings *settings; + struct st_lsm6dsx_sensor *sensor; + struct iio_dev *iio_dev; + int ret; + + iio_dev =3D devm_iio_device_alloc(hw->dev, sizeof(*sensor)); + if (!iio_dev) + return -ENOMEM; + + settings =3D &hw->settings->fusion_settings; + sensor =3D iio_priv(iio_dev); + sensor->id =3D ST_LSM6DSX_ID_FUSION; + sensor->hw =3D hw; + sensor->hwfifo_odr_mHz =3D settings->odr_hz[0] * MILLI; + sensor->watermark =3D 1; + iio_dev->modes =3D INDIO_DIRECT_MODE; + iio_dev->info =3D &st_lsm6dsx_fusion_info; + iio_dev->channels =3D settings->chan; + iio_dev->num_channels =3D settings->chan_len; + ret =3D snprintf(sensor->name, sizeof(sensor->name), "%s_fusion", name); + if (ret >=3D sizeof(sensor->name)) + return -E2BIG; + iio_dev->name =3D sensor->name; + + /* + * Put the IIO device pointer in the iio_devs array so that the caller + * can set up a buffer and register this IIO device. + */ + hw->iio_devs[ST_LSM6DSX_ID_FUSION] =3D iio_dev; + + return 0; +} --=20 2.39.5