From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 51C8B4189C0; Fri, 10 Jul 2026 11:21:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; cv=none; b=qwQ3203kU+rKWIE7faTb0sDnZWrBNNNg4Z2TZAYurwswAhip3l/AWOdG+e+EeSJ9aQqp9I7EmW8bcRVC5C6NoR90Z3R+XBzQdhUPikKRweYg+n9v5PX+wTWSGt80N3x8vJ4P9FcS4hA6uN/KdPOT6IUZZhZQPiI4Z9WObIIRNrY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; c=relaxed/simple; bh=Z+/c89j32b2vZ9L146b8G0oQcfROD134sssyE4LiTYU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A2rYvNPo4r4t9iTjHM8GTP80zhYyUfyUEYxw1ze/M+Zfnzl2RvtE1NgljraN4sIeKR5rxuUsvmWybxfpGicHpvgU/HlRKitdg2uO8ko3AJgUr4Y/tSRGeUFRNdK5XkbO/fvUMNrG5t3SRYZk8vcAx85fN8DsGRvT+rjc+hVSXAY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TzJcTo77; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TzJcTo77" Received: by smtp.kernel.org (Postfix) with ESMTPS id 51A31C2BCC9; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=Z+/c89j32b2vZ9L146b8G0oQcfROD134sssyE4LiTYU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=TzJcTo77kQErvdg1VQVZpO4p3/3zN7ETQ5/SUkFcTAyObT+pFg+13QcQ2uD921Ti8 T2kM05xyxvWF2cQG3r/2Xzpf0Pz4o8MQFvDYKv2rqMGLHSEgcMsVkLf2BozsU5W5s/ UltzjRh500CHfhzZ9C3PFhw9kWeORC3o4U1XVaVapDmgea/obr4eePVacb71fSg9/j +QfxE4gqccsk0BIy2Mc37o7wr9N+1+jbKRIsvudUUH8eQ/B0+lSY9sQQ4UlP4x2ci4 HwqUrnwZibLVI+FTQaWkK7//ONxh9Pkon2ukUR25oVYNM/BBJeJe0nlDdMabuH8Ejd OtRWm+teXeZFA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32B79C44507; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:45 +0100 Subject: [PATCH v7 1/7] iio: dac: ad5696: properly check i2c_transfer() return value Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-1-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar , sashiko-bot@kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=1018; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=0adqBlbl4dTMRxAIOk7QAvkBMzJDBt+Tq03dU+E4TBY=; b=c8W3eMCQ7RttpJqMVNWBVpt6H4evr+Hzn9ii0d40rXKHBOFgc69V5O+4idXLDb9nQZCms6vSD XK1ZMyF+YbQD+5nze3fgGxjs19mzL/IVF/w6vgmMQW9d6PVs/EQ/AiD X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Verify that the expected number of i2c messages were transferred when ad5686_i2c_read() is called. This issue exists since the support for I2C devices where first introduced. Fixes: 4177381b4401 ("iio:dac:ad5686: Add AD5671R/75R/94/94R/95R/96/96R sup= port") Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/all/20260705114746.1485F1F000E9@smtp.kernel= .org/ Signed-off-by: Rodrigo Alencar Reviewed-by: David Lechner --- drivers/iio/dac/ad5696-i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index 279309329b64..6f726e6301a6 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -40,8 +40,8 @@ static int ad5686_i2c_read(struct ad5686_state *st, u8 ad= dr) 0x00); =20 ret =3D i2c_transfer(i2c->adapter, msg, 2); - if (ret < 0) - return ret; + if (ret !=3D 2) + return ret < 0 ? ret : -EIO; =20 return be16_to_cpu(st->data[0].d16); } --=20 2.43.0 From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52CBC4192E2; Fri, 10 Jul 2026 11:21:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; cv=none; b=kVMDKy/nPh99YVi4yD21J+LOFCwO4V8tMv+FrmUmCpn0/IIcmOt+/007j5bZ6nlc0tx+Lgu9M1DLqSBoENPAigq8vJbqM/wgsyK839hVokAnQ9pBV3GcZybMm2XQfAfiJRv/QuYWw5i/74ltDpRMn60IYud+ETFUz1j/+ketWv8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; c=relaxed/simple; bh=qtq4eiaVGYxzcA6lYNEKl8443SsdNTAWffYeDYhIzjo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OOu6Enf/7bhb3MJeojIXB7Z2WDmUdj2q4+cX+6UDhbheL6Gn5g26xIXsZ+50qWIe2zWK4HiHEHrNSZ1PaMlemlb36Nmok8AInsAcrYyxlq2z0Fo4Ixb7c+RxjSz3ZYYV5ycrLlZzldgUnu0iIshFkCKeIhO9gIkZ0QITKbOsjGU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hxr9Mykg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hxr9Mykg" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6377DC2BCF4; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=qtq4eiaVGYxzcA6lYNEKl8443SsdNTAWffYeDYhIzjo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=hxr9Mykg21S7/3d8GNn9pNPELgupyaIYWPQCE6Kav361Mk3YryS+lTYPycMhx63DL KV7k/Q2ZD5yzuI1vE45YHb/4GvMEVrhs4WAA1zYRUxnclW87FwMiaV2xQPhedduL/4 MEb8edvLYWL+jSv5QnPw59s9YCk42RllmYw1ym2Noy9zwy52xXxjqJ8OoDgez7syvF tvC3qo7risO//dJN5ZrnfrvEun/C5CtC/IRFqTCQ1XZhE+OU1QxVAqvBXY3qN0E16v Ff5bmkInGCHjPVOoydJWe4yQucr388DJ6kwgRpxWiO0mSmwOGEPCY8hhLGyvtWK1YU Z3afXr0SLAUcg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44510C44501; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:46 +0100 Subject: [PATCH v7 2/7] iio: dac: ad5686: refactor command/data macros Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-2-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar , sashiko-bot@kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=7147; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=qRHhDvXGjsAHu+93uFBdiAIlGZwBaY4I1ZjDTZ6pcx8=; b=WUUdOw/nwbKkYyAOpe2Hstci3fxn9nohhUXtpvUDp3h4WZf5E91t+EEjdtAHHEVOpa/rzbIdn J6XiYns/tj4BethZB++H0uhoTo8ywpfDSt5wLb9Jo3XK9hXs9GKrXGt X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Replace usage of bit shifting macros for FIELD_PREP(), which would not ignore bit masking when preparing SPI/I2C commands. This change is a code hardening measure to be paired with the upcoming triggered buffer support. For the AD5310 regmap case, 16-bit data coming from the buffer may overlap with command bits if the data field is unmasked. *_REF_BIT_MSK and *_PD_MSK bit position macros are renamed (with a DATA prefix) so to indicate that they are relative to the DATA field. Reported-by: sashiko-bot@kernel.org Link: https://lore.kernel.org/all/20260628143026.EC6CA1F000E9@smtp.kernel.o= rg/#t Signed-off-by: Rodrigo Alencar Reviewed-by: David Lechner --- drivers/iio/dac/ad5686-spi.c | 21 +++++++++++---------- drivers/iio/dac/ad5686.c | 10 +++++----- drivers/iio/dac/ad5686.h | 22 ++++++++++++---------- drivers/iio/dac/ad5696-i2c.c | 11 ++++++----- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/drivers/iio/dac/ad5686-spi.c b/drivers/iio/dac/ad5686-spi.c index 6b6ef1d7071f..d3b64b4361d5 100644 --- a/drivers/iio/dac/ad5686-spi.c +++ b/drivers/iio/dac/ad5686-spi.c @@ -9,6 +9,7 @@ */ =20 #include +#include #include #include #include @@ -26,21 +27,21 @@ static int ad5686_spi_write(struct ad5686_state *st, =20 switch (st->chip_info->regmap_type) { case AD5310_REGMAP: - st->data[0].d16 =3D cpu_to_be16(AD5310_CMD(cmd) | - val); + st->data[0].d16 =3D cpu_to_be16(FIELD_PREP(AD5310_CMD_MSK, cmd) | + FIELD_PREP(AD5310_DATA_MSK, val)); buf =3D &st->data[0].d8[0]; tx_len =3D 2; break; case AD5683_REGMAP: - st->data[0].d32 =3D cpu_to_be32(AD5686_CMD(cmd) | - AD5683_DATA(val)); + st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | + FIELD_PREP(AD5683_DATA_MSK, val)); buf =3D &st->data[0].d8[1]; tx_len =3D 3; break; case AD5686_REGMAP: - st->data[0].d32 =3D cpu_to_be32(AD5686_CMD(cmd) | - AD5686_ADDR(addr) | - val); + st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | + FIELD_PREP(AD5686_ADDR_MSK, addr) | + FIELD_PREP(AD5686_DATA_MSK, val)); buf =3D &st->data[0].d8[1]; tx_len =3D 3; break; @@ -81,9 +82,9 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 ad= dr) return -EINVAL; } =20 - st->data[0].d32 =3D cpu_to_be32(AD5686_CMD(cmd) | - AD5686_ADDR(addr)); - st->data[1].d32 =3D cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP)); + st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | + FIELD_PREP(AD5686_ADDR_MSK, addr)); + st->data[1].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, AD5686_CMD_NOO= P)); =20 ret =3D spi_sync_transfer(spi, t, ARRAY_SIZE(t)); if (ret < 0) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 713fe71ad1e7..120dd095dd2e 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -35,8 +35,8 @@ static int ad5310_control_sync(struct ad5686_state *st) unsigned int pd_val =3D st->pwr_down_mask & st->pwr_down_mode; =20 return ad5686_write(st, AD5686_CMD_CONTROL_REG, 0, - FIELD_PREP(AD5310_PD_MSK, pd_val & AD5686_PD_MSK) | - FIELD_PREP(AD5310_REF_BIT_MSK, st->use_internal_vref ? 0 : 1)); + FIELD_PREP(AD5310_DATA_PD_MSK, pd_val & AD5686_PD_MSK) | + FIELD_PREP(AD5310_DATA_REF_MSK, st->use_internal_vref ? 0 : 1)); } =20 static int ad5683_control_sync(struct ad5686_state *st) @@ -44,8 +44,8 @@ static int ad5683_control_sync(struct ad5686_state *st) unsigned int pd_val =3D st->pwr_down_mask & st->pwr_down_mode; =20 return ad5686_write(st, AD5686_CMD_CONTROL_REG, 0, - FIELD_PREP(AD5683_PD_MSK, pd_val & AD5686_PD_MSK) | - FIELD_PREP(AD5683_REF_BIT_MSK, st->use_internal_vref ? 0 : 1)); + FIELD_PREP(AD5683_DATA_PD_MSK, pd_val & AD5686_PD_MSK) | + FIELD_PREP(AD5683_DATA_REF_MSK, st->use_internal_vref ? 0 : 1)); } =20 static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec= *chan) @@ -562,7 +562,7 @@ int ad5686_probe(struct device *dev, break; case AD5686_REGMAP: ret =3D ad5686_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0, - st->use_internal_vref ? 0 : AD5686_REF_BIT_MSK); + st->use_internal_vref ? 0 : AD5686_DATA_REF_MSK); if (ret) return ret; break; diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index c424720f8f72..32cb3931413c 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -14,12 +14,14 @@ =20 #include =20 -#define AD5310_CMD(x) ((x) << 12) +#define AD5310_CMD_MSK GENMASK(15, 12) +#define AD5310_DATA_MSK GENMASK(11, 0) =20 -#define AD5683_DATA(x) ((x) << 4) +#define AD5683_DATA_MSK GENMASK(19, 4) =20 -#define AD5686_ADDR(x) ((x) << 16) -#define AD5686_CMD(x) ((x) << 20) +#define AD5686_CMD_MSK GENMASK(23, 20) +#define AD5686_ADDR_MSK GENMASK(19, 16) +#define AD5686_DATA_MSK GENMASK(15, 0) =20 #define AD5686_ADDR_DAC(chan) (0x1 << (chan)) #define AD5686_ADDR_ALL_DAC 0xF @@ -38,15 +40,15 @@ #define AD5686_CMD_CONTROL_REG 0x4 #define AD5686_CMD_READBACK_ENABLE_V2 0x5 =20 -#define AD5310_REF_BIT_MSK BIT(8) -#define AD5310_PD_MSK GENMASK(10, 9) +#define AD5310_DATA_REF_MSK BIT(8) +#define AD5310_DATA_PD_MSK GENMASK(10, 9) =20 -#define AD5683_REF_BIT_MSK BIT(12) -#define AD5683_PD_MSK GENMASK(14, 13) +#define AD5683_DATA_REF_MSK BIT(12) /* DB16 */ +#define AD5683_DATA_PD_MSK GENMASK(14, 13) /* DB18:DB17 */ + +#define AD5686_DATA_REF_MSK BIT(0) =20 -#define AD5686_REF_BIT_MSK BIT(0) #define AD5686_PD_MSK GENMASK(1, 0) - #define AD5686_PD_MODE_1K_TO_GND 0x1 #define AD5686_PD_MODE_100K_TO_GND 0x2 #define AD5686_PD_MODE_THREE_STATE 0x3 diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index 6f726e6301a6..73dcd2e6f51b 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -7,6 +7,7 @@ * Copyright 2018 Analog Devices Inc. */ =20 +#include #include #include #include @@ -35,9 +36,8 @@ static int ad5686_i2c_read(struct ad5686_state *st, u8 ad= dr) }; int ret; =20 - st->data[0].d32 =3D cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP) | - AD5686_ADDR(addr) | - 0x00); + st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, AD5686_CMD_NOO= P) | + FIELD_PREP(AD5686_ADDR_MSK, addr)); =20 ret =3D i2c_transfer(i2c->adapter, msg, 2); if (ret !=3D 2) @@ -52,8 +52,9 @@ static int ad5686_i2c_write(struct ad5686_state *st, struct i2c_client *i2c =3D to_i2c_client(st->dev); int ret; =20 - st->data[0].d32 =3D cpu_to_be32(AD5686_CMD(cmd) | AD5686_ADDR(addr) - | val); + st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | + FIELD_PREP(AD5686_ADDR_MSK, addr) | + FIELD_PREP(AD5686_DATA_MSK, val)); =20 ret =3D i2c_master_send(i2c, &st->data[0].d8[1], 3); if (ret < 0) --=20 2.43.0 From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50BDA416CE3; Fri, 10 Jul 2026 11:21:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; cv=none; b=gVVrICA1v+P+LPQIilzq9q92a0pOsTGqcjucMArafAsoCDxAlutw5POMmft7yw5w8uq8OFbXzoGjhj05FYEQbM4P6Wd1LKdowHk1Y4Ddthd+IMF88dC1SIY+wWzuSKZgwgamCtiE8a7Nbz+WKQz0SeDlXWspV6XP3xIV3Zzjkxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; c=relaxed/simple; bh=UC3Fb0K/osa1Y5Q6O+cQe5RPOAEjTKbM+sRmsfxCYRI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZaAHIIkIxGOX3ZUW7lsmrpUlhar/ByDgjIqvjfqo4pYflzwM1M/bnY28vdohdcNs1pIWJ4avl0QJkze85Smxzpcgf6UVxiBCxL61NobrL2/87KLbXkwEqOYN3q8kcKlOa5ytoEQ/1T5SamgSfAB5I/MOTR5nHthzxERXvnQEk/c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pWGRNbnK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pWGRNbnK" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7070CC2BCFA; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=UC3Fb0K/osa1Y5Q6O+cQe5RPOAEjTKbM+sRmsfxCYRI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=pWGRNbnKK97MTuEGhdtozmzl+UdYhzrCWObETIKleO7+Ut196x0ErpcBctEW41u5W xVhIqTSzo5VYTtZQFVNOJ/8p0dYj4K3jdjLVOh5QIN9Y8cCexTsKyHGxREja1JDIfa 4vRFwqUd737uKtM/4sa58NBmT80wVlrjTTav7iPe8twvWM4T4uXybdzi9zMjmAbfxz otUGJCQxLHF3NyPuAcC+P2oVBp91Ei/WbRXHiOI3uYHXL+ckvyW4Y3v6dkmHyXait7 UBmDBYdnE+Vjw3b/ibsZsSOtHKLgsW0SBk4etWBnTD2SRu/Pu8GOujNxfHgPmL3Hog NDRGAhNfQ0cbA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55A77C44509; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:47 +0100 Subject: [PATCH v7 3/7] iio: dac: ad5686: introduce sync operation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-3-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=1436; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=AMX5SeS0etW8inHhzpcq0acC46wU0BKcTGY/05CNxgA=; b=VKOx/7mHfJL+l/bGfAe9yG6bGyScVHBdYFCi5zsyb4cSIKJ+HZ5yGnWIVGwGsX7tV4+KzeEm7 1CiU7H91ajeDOhdDm2jCyPB7k0JAAMWHPggxHXjNcMt1SO6oBq4t86x X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Add sync() to operation to ad5686_bus_ops, which can be used to flush multiple pending data transfers at once. This is going to be used when implementing triggered buffer support. Signed-off-by: Rodrigo Alencar Reviewed-by: David Lechner --- drivers/iio/dac/ad5686.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 32cb3931413c..ae9aeda2d201 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -70,10 +70,12 @@ struct ad5686_state; * struct ad5686_bus_ops - bus specific read/write operations * @read: read a register value at the given address * @write: write a command, address and value to the device + * @sync: ensure the completion of the write operation (optional) */ struct ad5686_bus_ops { int (*read)(struct ad5686_state *st, u8 addr); int (*write)(struct ad5686_state *st, u8 cmd, u8 addr, u16 val); + int (*sync)(struct ad5686_state *st); }; =20 /** @@ -162,7 +164,13 @@ int ad5686_probe(struct device *dev, =20 static inline int ad5686_write(struct ad5686_state *st, u8 cmd, u8 addr, u= 16 val) { - return st->ops->write(st, cmd, addr, val); + int ret; + + ret =3D st->ops->write(st, cmd, addr, val); + if (ret) + return ret; + + return st->ops->sync ? st->ops->sync(st) : 0; } =20 static inline int ad5686_read(struct ad5686_state *st, u8 addr) --=20 2.43.0 From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 556E34192EA; Fri, 10 Jul 2026 11:21:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; cv=none; b=fXWY+zv2oVXTxaSOZbPNE71teoAUS8cbJ+sDPw1t6qj7ZlKpqTJMwVWpb/72cdLUakeYOXVczLcs7J17RF9GSS6SHgtSdo5ofoNWCcZ10Lf3nMqniPC7TRlw6w5RkBULYMjC2GUCmQ531CWgIHvCS2yBwHA3u+pmfQEj7ZlXQfA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682460; c=relaxed/simple; bh=ntHGY55JFXOVuGQaVUZ34CsGt/7YAIh1ZUBbVWP3CsQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KEvYqcd8KK2NUmpg4Tqsguwg9QXiQotV0B7GrRUT/XToqhO4v/R8fsuoZt2JKD559KnH6btbbWdntKgTUAqyJXTfNlOHRKJVBqtTge7YpgQ/RWmDkau6VP/P/5yh4s1njHbNUjdk6Hlejgpgc71zN2pAsCpa2J8XBWnDKJbAvxg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YWaIVFJm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YWaIVFJm" Received: by smtp.kernel.org (Postfix) with ESMTPS id 78D82C2BD04; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=ntHGY55JFXOVuGQaVUZ34CsGt/7YAIh1ZUBbVWP3CsQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=YWaIVFJmtghM4jlNTfd7qG3GUI4aef7xoRbh0+7Y7uRrW2fXefoZNxXYqmiqSg0cF xGu2zgJNv82tpY9FzevENb13x238gp54D1rYA30KBtxSOay7M9k8W7+KcWIvkEK0kE DLWo1u/qhgvSuGzWOLUqAra53MAmMHzqOoWVoK4IlJf007OT+eZU65df08/9SJUgxU RPJZPD+GhKL9PeBaB6Qq3yarnGTnjLmdj4VvLZ0XQXT3QBcVFlZKHuFJRhKoL+4kR0 0e3YEgftlGbUaMC8gqBKgYMJ5ZjTzxd9EvCNLclGhQ0qAmDdaw2VJ/GwGhMFa1sdc9 wz4M5kw04Z2QQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6689AC43458; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:48 +0100 Subject: [PATCH v7 4/7] iio: dac: ad5686: implement new sync() op for the spi bus Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-4-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=9034; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=97qIi6+LeMKQRfC0Ku/wZdiBRB5IRSJ+Abel0ki2gI4=; b=BHVoXDgE1BLb2xRaUD0aOOj4zUuENpIUOiCkTOvwS3bsDeBYObNOXMMXvQoUhJJuB8enSNHEp vbxcR1fW981AWjmaUWLAtUMleyRExm6JyTA4gFxBJIuhCQ6+Zw3v05T X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Use of local SPI bus data to manage a collection of SPI transfers and flush them to the SPI platform driver with the sync() operation. This allows for faster handling of multiple channel DAC writes, avoiding kernel overhead per spi_sync() call, which will be helpful when enabling triggered buffer support. Signed-off-by: Rodrigo Alencar Reviewed-by: David Lechner --- drivers/iio/dac/ad5686-spi.c | 129 ++++++++++++++++++++++++++++++++-------= ---- drivers/iio/dac/ad5686.c | 4 +- drivers/iio/dac/ad5686.h | 8 ++- drivers/iio/dac/ad5696-i2c.c | 2 +- 4 files changed, 108 insertions(+), 35 deletions(-) diff --git a/drivers/iio/dac/ad5686-spi.c b/drivers/iio/dac/ad5686-spi.c index d3b64b4361d5..ae74a17ba48e 100644 --- a/drivers/iio/dac/ad5686-spi.c +++ b/drivers/iio/dac/ad5686-spi.c @@ -13,59 +13,95 @@ #include #include #include +#include #include =20 #include =20 #include "ad5686.h" =20 +/** + * struct ad5686_spi_data - SPI bus specific data + * @msg: SPI message used for transfers + * @size: number of transfers currently in the message + * @capacity: maximum number of transfers that can be added to the message + * @xfers: array of SPI transfers, allocated with the provided capacity + */ +struct ad5686_spi_data { + struct spi_message msg; + unsigned int size; + unsigned int capacity; + struct spi_transfer xfers[] __counted_by(capacity); +}; + static int ad5686_spi_write(struct ad5686_state *st, u8 cmd, u8 addr, u16 val) { - struct spi_device *spi =3D to_spi_device(st->dev); - u8 tx_len, *buf; + struct ad5686_spi_data *bus_data =3D st->bus_data; + struct spi_transfer *xfer; =20 + if (bus_data->size >=3D bus_data->capacity) + return -E2BIG; + + if (bus_data->size) + bus_data->xfers[bus_data->size - 1].cs_change =3D 1; + else + spi_message_init(&bus_data->msg); + + xfer =3D &bus_data->xfers[bus_data->size]; switch (st->chip_info->regmap_type) { case AD5310_REGMAP: - st->data[0].d16 =3D cpu_to_be16(FIELD_PREP(AD5310_CMD_MSK, cmd) | - FIELD_PREP(AD5310_DATA_MSK, val)); - buf =3D &st->data[0].d8[0]; - tx_len =3D 2; + st->data[bus_data->size].d16 =3D + cpu_to_be16(FIELD_PREP(AD5310_CMD_MSK, cmd) | + FIELD_PREP(AD5310_DATA_MSK, val)); + *xfer =3D (struct spi_transfer) { + .tx_buf =3D &st->data[bus_data->size].d16, + .len =3D sizeof(st->data[bus_data->size].d16), + }; break; case AD5683_REGMAP: - st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | - FIELD_PREP(AD5683_DATA_MSK, val)); - buf =3D &st->data[0].d8[1]; - tx_len =3D 3; + st->data[bus_data->size].d32 =3D + cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | + FIELD_PREP(AD5683_DATA_MSK, val)); + *xfer =3D (struct spi_transfer) { + .tx_buf =3D &st->data[bus_data->size].d8[1], + .len =3D sizeof(st->data[bus_data->size].d8) - 1, + }; break; case AD5686_REGMAP: - st->data[0].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | - FIELD_PREP(AD5686_ADDR_MSK, addr) | - FIELD_PREP(AD5686_DATA_MSK, val)); - buf =3D &st->data[0].d8[1]; - tx_len =3D 3; + st->data[bus_data->size].d32 =3D + cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, cmd) | + FIELD_PREP(AD5686_ADDR_MSK, addr) | + FIELD_PREP(AD5686_DATA_MSK, val)); + *xfer =3D (struct spi_transfer) { + .tx_buf =3D &st->data[bus_data->size].d8[1], + .len =3D sizeof(st->data[bus_data->size].d8) - 1, + }; break; default: return -EINVAL; } =20 - return spi_write(spi, buf, tx_len); + spi_message_add_tail(xfer, &bus_data->msg); + bus_data->size++; + + return 0; +} + +static int ad5686_spi_sync(struct ad5686_state *st) +{ + struct spi_device *spi =3D to_spi_device(st->dev); + struct ad5686_spi_data *bus_data =3D st->bus_data; + + bus_data->size =3D 0; /* always reset, even on sync failure */ + return spi_sync(spi, &bus_data->msg); } =20 static int ad5686_spi_read(struct ad5686_state *st, u8 addr) { - struct spi_transfer t[] =3D { - { - .tx_buf =3D &st->data[0].d8[1], - .len =3D 3, - .cs_change =3D 1, - }, { - .tx_buf =3D &st->data[1].d8[1], - .rx_buf =3D &st->data[2].d8[1], - .len =3D 3, - }, - }; struct spi_device *spi =3D to_spi_device(st->dev); + struct ad5686_spi_data *bus_data =3D st->bus_data; + struct spi_transfer *xfer =3D &bus_data->xfers[0]; u8 cmd =3D 0; int ret; =20 @@ -86,8 +122,21 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 = addr) FIELD_PREP(AD5686_ADDR_MSK, addr)); st->data[1].d32 =3D cpu_to_be32(FIELD_PREP(AD5686_CMD_MSK, AD5686_CMD_NOO= P)); =20 - ret =3D spi_sync_transfer(spi, t, ARRAY_SIZE(t)); - if (ret < 0) + xfer[0] =3D (struct spi_transfer) { + .tx_buf =3D &st->data[0].d8[1], + .len =3D sizeof(st->data[0].d8) - 1, + .cs_change =3D 1, + }; + xfer[1] =3D (struct spi_transfer) { + .tx_buf =3D &st->data[1].d8[1], + .rx_buf =3D &st->data[2].d8[1], + .len =3D sizeof(st->data[1].d8) - 1, + }; + + spi_message_init_with_transfers(&bus_data->msg, xfer, 2); + + ret =3D spi_sync(spi, &bus_data->msg); + if (ret) return ret; =20 return be32_to_cpu(st->data[2].d32); @@ -96,12 +145,30 @@ static int ad5686_spi_read(struct ad5686_state *st, u8= addr) static const struct ad5686_bus_ops ad5686_spi_ops =3D { .write =3D ad5686_spi_write, .read =3D ad5686_spi_read, + .sync =3D ad5686_spi_sync, }; =20 static int ad5686_spi_probe(struct spi_device *spi) { - return ad5686_probe(&spi->dev, spi_get_device_match_data(spi), - spi->modalias, &ad5686_spi_ops); + const struct ad5686_chip_info *info; + struct ad5686_spi_data *bus_data; + struct device *dev =3D &spi->dev; + unsigned int capacity; + + info =3D spi_get_device_match_data(spi); + if (!info) + return -ENODEV; + + /* read operation requires at least 2 transfers */ + capacity =3D max(info->num_channels, 2); + bus_data =3D devm_kzalloc(dev, struct_size(bus_data, xfers, capacity), + GFP_KERNEL); + if (!bus_data) + return -ENOMEM; + + bus_data->capacity =3D capacity; + + return ad5686_probe(dev, info, spi->modalias, &ad5686_spi_ops, bus_data); } =20 static const struct spi_device_id ad5686_spi_id[] =3D { diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 120dd095dd2e..316f9ccf54d9 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -472,7 +472,8 @@ EXPORT_SYMBOL_NS_GPL(ad5679r_chip_info, "IIO_AD5686"); =20 int ad5686_probe(struct device *dev, const struct ad5686_chip_info *chip_info, - const char *name, const struct ad5686_bus_ops *ops) + const char *name, const struct ad5686_bus_ops *ops, + void *bus_data) { struct reset_control *rstc; struct ad5686_state *st; @@ -487,6 +488,7 @@ int ad5686_probe(struct device *dev, =20 st->dev =3D dev; st->ops =3D ops; + st->bus_data =3D bus_data; st->chip_info =3D chip_info; =20 rstc =3D devm_reset_control_get_optional_exclusive(dev, NULL); diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index ae9aeda2d201..2c3d7d5b1d6b 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -25,6 +25,7 @@ =20 #define AD5686_ADDR_DAC(chan) (0x1 << (chan)) #define AD5686_ADDR_ALL_DAC 0xF +#define AD5686_MAX_CHANNELS 16 =20 #define AD5686_CMD_NOOP 0x0 #define AD5686_CMD_WRITE_INPUT_N 0x1 @@ -132,6 +133,7 @@ extern const struct ad5686_chip_info ad5679r_chip_info; * @use_internal_vref: set to true if the internal reference voltage is us= ed * @lock: lock to protect access to state fields, which includes * the data buffer during regmap ops + * @bus_data: bus specific data * @data: transfer buffers */ struct ad5686_state { @@ -144,6 +146,7 @@ struct ad5686_state { unsigned int pwr_down_mode; bool use_internal_vref; struct mutex lock; + void *bus_data; =20 /* * DMA (thus cache coherency maintenance) may require the @@ -154,13 +157,14 @@ struct ad5686_state { __be32 d32; __be16 d16; u8 d8[4]; - } data[3] __aligned(IIO_DMA_MINALIGN); + } data[AD5686_MAX_CHANNELS] __aligned(IIO_DMA_MINALIGN); }; =20 =20 int ad5686_probe(struct device *dev, const struct ad5686_chip_info *chip_info, - const char *name, const struct ad5686_bus_ops *ops); + const char *name, const struct ad5686_bus_ops *ops, + void *bus_data); =20 static inline int ad5686_write(struct ad5686_state *st, u8 cmd, u8 addr, u= 16 val) { diff --git a/drivers/iio/dac/ad5696-i2c.c b/drivers/iio/dac/ad5696-i2c.c index 73dcd2e6f51b..b122d8d938e4 100644 --- a/drivers/iio/dac/ad5696-i2c.c +++ b/drivers/iio/dac/ad5696-i2c.c @@ -71,7 +71,7 @@ static const struct ad5686_bus_ops ad5686_i2c_ops =3D { static int ad5686_i2c_probe(struct i2c_client *i2c) { return ad5686_probe(&i2c->dev, i2c_get_match_data(i2c), - i2c->name, &ad5686_i2c_ops); + i2c->name, &ad5686_i2c_ops, NULL); } =20 static const struct i2c_device_id ad5686_i2c_id[] =3D { --=20 2.43.0 From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0DE441610D; Fri, 10 Jul 2026 11:21:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682461; cv=none; b=Wq2fZXiYfbe6ZWWVySRIO/tFFjXUi8T2zCalIbPyMszB06bl+SFwP93TnkeTVCwQ9FLQtgtWCh/kZCW1gWpMJWCL22zPyAclHHzMGTEpbUuEug+mB2Np1Q2vfinDyImHIlmTrzLBI7gJQfJ3arm1/zOJ+PL5O4I3sZdn4/cT2dM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682461; c=relaxed/simple; bh=bvM61nZlVlm3Dqfqh6pLDa+6KikA7MazMtB8NJEhcEE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Zd1cFsGqMpI4wb34eRBluy9wgXoUqv3FwcSSTPfIvHwYwpa0z3eJXg0AGPvrTs48Ztpnv0sHbkGueF3tcCb93Dsp5LaCN0r9fhwhJQqY9yv+dgRUiFxhCvhVkElZbPVZI6vgvq/aH6nXRs8KSuDQsBC9yQiMK3NwI/rkZqOP6EE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ag3hhozV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ag3hhozV" Received: by smtp.kernel.org (Postfix) with ESMTPS id 8C60DC4AF10; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=bvM61nZlVlm3Dqfqh6pLDa+6KikA7MazMtB8NJEhcEE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Ag3hhozV4S45f8SFv5OZ3AhHGMdAp8t7ZMbwJKVpQZJuP9lEHPGI3pdATItah4SOJ eUd4DIb1vBhj591DJYvQ1Qp7HtwGK9d+9889IANsJKb2z/mjCS2Canh3dS8Nq0wDDH GYAlyo9+uKHlaxEGlbPDDZPSCRQOorxK9mxLOHOsbgsgSYtujsvrDsSZi6r3LYook3 gGwb0R9Xf/W0JGi88c0Zc3W5oj7fjY22xOIxKARfGR3dGQavnf5RWSiMwnpIQ2/UYP 8AAfJYCCeJ74LeaUake75adAShIKa+MO2jHUNLgcfM9cw8b9/reD4Kv41hD/CB0ibh pPe3FcaWhqAZA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79591C44507; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:49 +0100 Subject: [PATCH v7 5/7] iio: dac: ad5686: read_raw/write_raw: use guard(mutex)() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-5-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar , Maxwell Doose , Joshua Crofts X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=2132; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=4HNzAutLFGeXIbyru6R+loI4tx3NII/f1eSB75Ol0ao=; b=XVywTb/qzdZLK070cIpxzqti+5w13j0cJ4eqN8F68hkkTSAnN0NyuoINK7cbHjtXNdybhCxMf k0L1DABfT7jAoaBEu62qBNJT/zJTGXT8bBf2SRHRix/gYJpzbPEta3a X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Use guarded mutex lock to facilitate code review when adding new attributes. This will allow for early returns, avoiding error-prone locking and unlocking in error paths. This also adds missing include linux/cleanup.h. Gain-control support will allow the scale attribute to be configurable. Reviewed-by: Maxwell Doose Reviewed-by: Joshua Crofts Signed-off-by: Rodrigo Alencar Reviewed-by: Andy Shevchenko Reviewed-by: David Lechner --- drivers/iio/dac/ad5686.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 316f9ccf54d9..df32f46db81e 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -177,11 +178,11 @@ static int ad5686_read_raw(struct iio_dev *indio_dev, struct ad5686_state *st =3D iio_priv(indio_dev); int ret; =20 + guard(mutex)(&st->lock); + switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&st->lock); ret =3D ad5686_read(st, chan->address); - mutex_unlock(&st->lock); if (ret < 0) return ret; *val =3D (ret >> chan->scan_type.shift) & @@ -202,23 +203,19 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, long mask) { struct ad5686_state *st =3D iio_priv(indio_dev); - int ret; + + guard(mutex)(&st->lock); =20 switch (mask) { case IIO_CHAN_INFO_RAW: if (val >=3D (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; =20 - mutex_lock(&st->lock); - ret =3D ad5686_write(st, AD5686_CMD_WRITE_INPUT_N_UPDATE_N, - chan->address, val << chan->scan_type.shift); - mutex_unlock(&st->lock); - break; + return ad5686_write(st, AD5686_CMD_WRITE_INPUT_N_UPDATE_N, + chan->address, val << chan->scan_type.shift); default: - ret =3D -EINVAL; + return -EINVAL; } - - return ret; } =20 static const struct iio_info ad5686_info =3D { --=20 2.43.0 From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 979F241B34F; Fri, 10 Jul 2026 11:21:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682461; cv=none; b=SMkqdRtQhWsnulhwLlkycbctToZr2BpzF0gzCrauMx/AmQMPIBPzJhX8xCVqIUyZZmNzgcuTrIHrI8M7iKkQYlKNu9YBvj/2vRND8pQN4zheLQVzAZuYQXZrRsSwsYmklXDatUA15Eu3pCT6BhVLJLoBu9Esup8x5QUxovddF20= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682461; c=relaxed/simple; bh=uN7Z8Ew279MY+AExisHqz6gIW60wlE5ho1J17F03mew=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=W2TEAmjcgWzlp/rhS887wC50N0xdJ+fKBUkVJ6UfnasJ7ndwTLrqmBzcoe733mO27uvGq1b6B8rBzpjpNyWuKIZTNeD+vV/hVTDwpUmpUM2zA/erbxXbnI91cU76hw/jVKu+th7gUjEOcivUTARPjGHsf325CZxj+300W6Y96C4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fsLoNMFM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fsLoNMFM" Received: by smtp.kernel.org (Postfix) with ESMTPS id A27A4C4AF0D; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=uN7Z8Ew279MY+AExisHqz6gIW60wlE5ho1J17F03mew=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=fsLoNMFMQgf+R+Zpo4tjsztKlNiJyMVPAEB6e8tbygAMDQcRq4Tk5u3lxVKrcANqc 9cqbYry8aDPJO8G4pY0vmRJm/X1d5Rdaw+CxqxMmGPEKJKDo7BN1H4Rkp32wOQrZkd oAXw1oud7KWHwbnmuhl18DLbmzdPyGCVic66w6ryY0/wWJdI2CyNdIO2CYujg+bzuB lL32B71JbWkLySbvyXSSpV2zzretnybw+clMlUoULGhOiTGoDg3DlK5cJ3rs6a3A85 +P0kbRC5t+ZJHJT+4/Aj4uT1Padxlly4bjyeh9WjJlX7u1ZKr7kiBT2yRIt9QOI1il H89LNdeAswFIA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89251C44501; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:50 +0100 Subject: [PATCH v7 6/7] iio: dac: ad5686: add triggered buffer support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-6-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=3808; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=KZ2u0xEBG+Aov9HJ5AY/CmkFVIWJa7smaIe8W94Ojw0=; b=URSIHr+lRpynV24YqYFbkrx8vRKyI3TuZL9TPSG9PdLG228QeSh5JdjRN3l/vHEeOGvgx53xS d4Mn3dZiEgLAy4OEQG5kVtoTB5Cy5hr4xlkdZaCCVQOPnbedCQLw6e1 X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Implement trigger handler by leveraging the LDAC gpio to update all DAC channels at once when it is available. Also, the multiple channel writes can be flushed at once with the sync() operation. Signed-off-by: Rodrigo Alencar Reviewed-by: David Lechner --- drivers/iio/dac/Kconfig | 2 ++ drivers/iio/dac/ad5686.c | 66 ++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 68 insertions(+) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 17529509da9d..d6d560c09e25 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -243,6 +243,8 @@ config LTC2688 =20 config AD5686 tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER =20 config AD5686_SPI tristate "Analog Devices AD5686 and similar multi-channel DACs (SPI)" diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index df32f46db81e..eeeff5c6cf38 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -21,7 +21,11 @@ #include #include =20 +#include #include +#include +#include +#include =20 #include "ad5686.h" =20 @@ -243,6 +247,7 @@ static const struct iio_chan_spec_ext_info ad5686_ext_i= nfo[] =3D { .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE),\ .address =3D addr, \ + .scan_index =3D chan, \ .scan_type =3D { \ .sign =3D 'u', \ .realbits =3D (bits), \ @@ -467,6 +472,60 @@ const struct ad5686_chip_info ad5679r_chip_info =3D { }; EXPORT_SYMBOL_NS_GPL(ad5679r_chip_info, "IIO_AD5686"); =20 +static void do_ad5686_trigger_handler(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer =3D indio_dev->buffer; + struct ad5686_state *st =3D iio_priv(indio_dev); + u16 val[AD5686_MAX_CHANNELS] =3D { }; + unsigned int scan_count, ch, i; + bool async_update; + u8 cmd; + + if (iio_pop_from_buffer(buffer, val)) + return; + + guard(mutex)(&st->lock); + + scan_count =3D bitmap_weight(indio_dev->active_scan_mask, + iio_get_masklength(indio_dev)); + async_update =3D st->ldac_gpio && scan_count > 1; + if (async_update) { + /* use LDAC to update all channels simultaneously */ + cmd =3D AD5686_CMD_WRITE_INPUT_N; + gpiod_set_value_cansleep(st->ldac_gpio, 0); + } else { + cmd =3D AD5686_CMD_WRITE_INPUT_N_UPDATE_N; + } + + i =3D 0; + iio_for_each_active_channel(indio_dev, ch) { + if (st->ops->write(st, cmd, indio_dev->channels[ch].address, val[i++])) + break; + } + + /* + * If sync() is available, it is called here regardless of write + * failure to allow bus implementation to reset. In that case, partial + * writes are unlikely as the write operations would just queue up + * the transfers. + */ + if (st->ops->sync) + st->ops->sync(st); + + if (async_update) + gpiod_set_value_cansleep(st->ldac_gpio, 1); +} + +static irqreturn_t ad5686_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf =3D p; + struct iio_dev *indio_dev =3D pf->indio_dev; + + do_ad5686_trigger_handler(indio_dev); + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + int ad5686_probe(struct device *dev, const struct ad5686_chip_info *chip_info, const char *name, const struct ad5686_bus_ops *ops, @@ -569,6 +628,13 @@ int ad5686_probe(struct device *dev, return -EINVAL; } =20 + ret =3D devm_iio_triggered_buffer_setup_ext(dev, indio_dev, NULL, + &ad5686_trigger_handler, + IIO_BUFFER_DIRECTION_OUT, + NULL, NULL); + if (ret) + return ret; + return devm_iio_device_register(dev, indio_dev); } EXPORT_SYMBOL_NS_GPL(ad5686_probe, "IIO_AD5686"); --=20 2.43.0 From nobody Sun Jul 26 01:07:21 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97AF441B352; Fri, 10 Jul 2026 11:21:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682461; cv=none; b=dDUHY1zeWRA1sbN5ay/AXuU1dPhO46SBVDGcaeb1VlCswyIESHVweKROh8N41C+Ga0rO1pHpNOkfDJwbO8kBGh0IUI5NZDgQSxAsARSt1efpIxeSCxJI6WU3hBj7Re1S5/puX84oopCQRyKjmAcqAkt0FdaiL+PNF/wZQ3MNEjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783682461; c=relaxed/simple; bh=Z/eejM/jXTdFC8dNLQbeLzns8UN8vdimBvJfTLw+9iA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jCDdL1aHcAJCxX2nBvOVKhpg0gcYqUkWve4ydhNX5oImksm3NW08cWgz5g8I8JgqZOZT/R9h19XiLYnrWsyyLADY+04AlvBnQQnjWDJ8h2IR8E35qWtlm0qD06OSyf/pkjlcvIRTettZG8XD7hKxpJWi61ebTid3Iy4Qjit1FrY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CEputXfU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CEputXfU" Received: by smtp.kernel.org (Postfix) with ESMTPS id ABA48C2BCC7; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783682458; bh=Z/eejM/jXTdFC8dNLQbeLzns8UN8vdimBvJfTLw+9iA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=CEputXfUH38DJLrYj/vSPRKBw4JLxei+wDLwD4Ewe3x4ooAitnSZgJxh8AerbbArT zIPpplJWL7Iw+mZjg6oouKkd7/OKsbp9vUcSr7Pb4hKRbnNY+SQtAzHwl9lI8yxyD/ 2nNl8/S6xU1CmvXMc+btOITMZUCKPIHGCxiST340qR3dXKMhpVgC9URC7OKf6Bh4qg CZBxsMQw6dB4akaDGm/AsomNu/uqHSAotyS5vlWIISH42djTN7KhgjkV9s+8Fns1MQ 6Fyt+tisrIY7DU6hkzHTvY1/CKisjj+0HoBYX0JXYAc798I/UtD0ofZ+fHwC4l84zl 04ufZ43At1qqg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9983CC44509; Fri, 10 Jul 2026 11:20:58 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Fri, 10 Jul 2026 12:20:51 +0100 Subject: [PATCH v7 7/7] iio: dac: ad5686: add gain control support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260710-ad5686-new-features-v7-7-1bcc8c280e4d@analog.com> References: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> In-Reply-To: <20260710-ad5686-new-features-v7-0-1bcc8c280e4d@analog.com> To: Michael Auchter , linux@analog.com, linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Cc: Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Kees Cook , "Gustavo A. R. Silva" , Rodrigo Alencar X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783682457; l=9019; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=UM/F6VG7k7aLWVE1TZa3gxJ3sHaemMi2bmtGRhi/bas=; b=eXMJ1xym825+n02iDPgWbtpTmG3MOINpIYE1EhTGmaSGRCxXQxOr50Zw5EFPQ6FEKN9vVQnt2 ikUG5iKBA/DDAUvrxi+xOE7uv0lcyShowR/74dfnnNmmuro5cbrNbg5 X-Developer-Key: i=rodrigo.alencar@analog.com; a=ed25519; pk=ULeHbgU/OYh/PG/4anHDfLgldFItQHAhOktYRVLMFRo= X-Endpoint-Received: by B4 Relay for rodrigo.alencar@analog.com/default with auth_id=561 X-Original-From: Rodrigo Alencar Reply-To: rodrigo.alencar@analog.com From: Rodrigo Alencar Most of the supported devices rely on a GAIN pin to control a 2x multiplier applied to the output voltage. Other devices, e.g. the single-channel ones, provides a gain control through a bit field in the control register. Some designs might have the GAIN pin hardwired to VDD/VLOGIC or GND, which would have no "gain-gpios" device property, being able to set "adi,range-double" if it is hardwired to VDD. The vref_mv field is moved down in the struct ad5686_state, so that the overall size increase is reduced. Signed-off-by: Rodrigo Alencar Reviewed-by: David Lechner --- drivers/iio/dac/ad5686.c | 120 +++++++++++++++++++++++++++++++++++++++++++= ++-- drivers/iio/dac/ad5686.h | 12 ++++- 2 files changed, 125 insertions(+), 7 deletions(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index eeeff5c6cf38..18ecd4abdfea 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -15,10 +15,13 @@ #include #include #include +#include #include +#include #include #include #include +#include #include =20 #include @@ -41,7 +44,8 @@ static int ad5310_control_sync(struct ad5686_state *st) =20 return ad5686_write(st, AD5686_CMD_CONTROL_REG, 0, FIELD_PREP(AD5310_DATA_PD_MSK, pd_val & AD5686_PD_MSK) | - FIELD_PREP(AD5310_DATA_REF_MSK, st->use_internal_vref ? 0 : 1)); + FIELD_PREP(AD5310_DATA_REF_MSK, st->use_internal_vref ? 0 : 1) | + FIELD_PREP(AD5310_DATA_GAIN_MSK, st->double_scale ? 1 : 0)); } =20 static int ad5683_control_sync(struct ad5686_state *st) @@ -50,7 +54,8 @@ static int ad5683_control_sync(struct ad5686_state *st) =20 return ad5686_write(st, AD5686_CMD_CONTROL_REG, 0, FIELD_PREP(AD5683_DATA_PD_MSK, pd_val & AD5686_PD_MSK) | - FIELD_PREP(AD5683_DATA_REF_MSK, st->use_internal_vref ? 0 : 1)); + FIELD_PREP(AD5683_DATA_REF_MSK, st->use_internal_vref ? 0 : 1) | + FIELD_PREP(AD5683_DATA_GAIN_MSK, st->double_scale ? 1 : 0)); } =20 static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec= *chan) @@ -193,9 +198,14 @@ static int ad5686_read_raw(struct iio_dev *indio_dev, GENMASK(chan->scan_type.realbits - 1, 0); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val =3D st->vref_mv; - *val2 =3D chan->scan_type.realbits; - return IIO_VAL_FRACTIONAL_LOG2; + if (st->double_scale) { + *val =3D st->scale_avail[2]; + *val2 =3D st->scale_avail[3]; + } else { + *val =3D st->scale_avail[0]; + *val2 =3D st->scale_avail[1]; + } + return IIO_VAL_INT_PLUS_NANO; } return -EINVAL; } @@ -207,6 +217,8 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, long mask) { struct ad5686_state *st =3D iio_priv(indio_dev); + bool double_scale; + int ret; =20 guard(mutex)(&st->lock); =20 @@ -217,6 +229,82 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, =20 return ad5686_write(st, AD5686_CMD_WRITE_INPUT_N_UPDATE_N, chan->address, val << chan->scan_type.shift); + case IIO_CHAN_INFO_SCALE: + if (val =3D=3D st->scale_avail[0] && val2 =3D=3D st->scale_avail[1]) + double_scale =3D false; + else if (val =3D=3D st->scale_avail[2] && val2 =3D=3D st->scale_avail[3]) + double_scale =3D true; + else + return -EINVAL; + + if (st->double_scale =3D=3D double_scale) + return 0; /* no change */ + + if (st->chip_info->regmap_type =3D=3D AD5686_REGMAP && !st->gain_gpio) + return -EINVAL; /* GAIN pin is board-strapped */ + + st->double_scale =3D double_scale; + switch (st->chip_info->regmap_type) { + case AD5310_REGMAP: + ret =3D ad5310_control_sync(st); + break; + case AD5683_REGMAP: + ret =3D ad5683_control_sync(st); + break; + case AD5686_REGMAP: + ret =3D gpiod_set_value_cansleep(st->gain_gpio, + st->double_scale ? 1 : 0); + break; + default: + ret =3D -EINVAL; + } + if (ret) + st->double_scale =3D !double_scale; /* revert on failure */ + return ret; + default: + return -EINVAL; + } +} + +static int ad5686_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_RAW: + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int ad5686_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct ad5686_state *st =3D iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *type =3D IIO_VAL_INT_PLUS_NANO; + + if (st->chip_info->regmap_type =3D=3D AD5686_REGMAP && !st->gain_gpio) { + /* + * GAIN pin is board-strapped, so only the current + * scale is available. + */ + *vals =3D st->double_scale ? &st->scale_avail[2] : + &st->scale_avail[0]; + *length =3D 2; + return IIO_AVAIL_LIST; + } + + *vals =3D st->scale_avail; + *length =3D ARRAY_SIZE(st->scale_avail); + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -225,6 +313,8 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5686_info =3D { .read_raw =3D ad5686_read_raw, .write_raw =3D ad5686_write_raw, + .write_raw_get_fmt =3D ad5686_write_raw_get_fmt, + .read_avail =3D ad5686_read_avail, }; =20 static const struct iio_chan_spec_ext_info ad5686_ext_info[] =3D { @@ -246,6 +336,7 @@ static const struct iio_chan_spec_ext_info ad5686_ext_i= nfo[] =3D { .channel =3D chan, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE),\ + .info_mask_shared_by_type_available =3D BIT(IIO_CHAN_INFO_SCALE),\ .address =3D addr, \ .scan_index =3D chan, \ .scan_type =3D { \ @@ -472,6 +563,15 @@ const struct ad5686_chip_info ad5679r_chip_info =3D { }; EXPORT_SYMBOL_NS_GPL(ad5679r_chip_info, "IIO_AD5686"); =20 +static void ad5686_init_scale_avail(struct ad5686_state *st) +{ + int realbits =3D st->chip_info->channels[0].scan_type.realbits; + s64 tmp =3D 2ULL * st->vref_mv * NANO >> realbits; + + st->scale_avail[2] =3D div_s64_rem(tmp, NANO, &st->scale_avail[3]); + st->scale_avail[0] =3D div_s64_rem(tmp >> 1, NANO, &st->scale_avail[1]); +} + static void do_ad5686_trigger_handler(struct iio_dev *indio_dev) { struct iio_buffer *buffer =3D indio_dev->buffer; @@ -585,6 +685,16 @@ int ad5686_probe(struct device *dev, return dev_err_probe(dev, PTR_ERR(st->ldac_gpio), "Failed to get LDAC GPIO\n"); =20 + st->double_scale =3D device_property_read_bool(dev, "adi,range-double"); + st->gain_gpio =3D devm_gpiod_get_optional(dev, "gain", + st->double_scale ? GPIOD_OUT_HIGH : + GPIOD_OUT_LOW); + if (IS_ERR(st->gain_gpio)) + return dev_err_probe(dev, PTR_ERR(st->gain_gpio), + "Failed to get GAIN GPIO\n"); + + ad5686_init_scale_avail(st); + /* Initialize masks to all ones */ st->pwr_down_mask =3D ~0; st->pwr_down_mode =3D ~0; diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index 2c3d7d5b1d6b..c1222ef83a4f 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -41,9 +41,11 @@ #define AD5686_CMD_CONTROL_REG 0x4 #define AD5686_CMD_READBACK_ENABLE_V2 0x5 =20 +#define AD5310_DATA_GAIN_MSK BIT(7) #define AD5310_DATA_REF_MSK BIT(8) #define AD5310_DATA_PD_MSK GENMASK(10, 9) =20 +#define AD5683_DATA_GAIN_MSK BIT(11) /* DB15 */ #define AD5683_DATA_REF_MSK BIT(12) /* DB16 */ #define AD5683_DATA_PD_MSK GENMASK(14, 13) /* DB18:DB17 */ =20 @@ -127,9 +129,12 @@ extern const struct ad5686_chip_info ad5679r_chip_info; * @chip_info: chip model specific constants, available modes etc * @ops: bus specific operations * @ldac_gpio: LDAC pin GPIO descriptor - * @vref_mv: actual reference voltage used + * @gain_gpio: GAIN pin GPIO descriptor * @pwr_down_mask: power down mask * @pwr_down_mode: current power down mode + * @scale_avail: pre-calculated available scale values + * @vref_mv: actual reference voltage used + * @double_scale: flag to indicate the gain multiplier is applied * @use_internal_vref: set to true if the internal reference voltage is us= ed * @lock: lock to protect access to state fields, which includes * the data buffer during regmap ops @@ -141,9 +146,12 @@ struct ad5686_state { const struct ad5686_chip_info *chip_info; const struct ad5686_bus_ops *ops; struct gpio_desc *ldac_gpio; - unsigned short vref_mv; + struct gpio_desc *gain_gpio; unsigned int pwr_down_mask; unsigned int pwr_down_mode; + int scale_avail[4]; + unsigned short vref_mv; + bool double_scale; bool use_internal_vref; struct mutex lock; void *bus_data; --=20 2.43.0