From nobody Thu Apr 2 17:18:15 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 0F36232FA28; Tue, 10 Feb 2026 19:42:18 +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=1770752538; cv=none; b=hRyh5K9tUO4LErSKlBdM9JBNpb5jZDAW3QWv2rc+qF0PADLHHuASD+vuzSnsBLAn3Cz3HJSmUaiEXMFzy3PRfWL18i6/GgcjE9nnu5ZlY2eZ8POsiNedC/zobbgv3H7YKUwnHrP3mi/UTh0/n5yEqYuFHkwAG56ZYFdH/32RQ4o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770752538; c=relaxed/simple; bh=gFisofjRmRDkCElxihVrUt91J4Goj29Lj706xglJ8+E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=f5fwoOq97E+yaQxxu/s5VvM6MssSxUzkYF3+8tiIPtpg6fBEXJPuKrWK6H+nqgJyRyDuxQL7qVkDIfDYZQmDaRSnc/GwWP4EnirDPsC+F5sPLUQufe5I7OdA3oo003vCQkb8Q89kCK9THEQPnEgIi2uXdbwh2Rx9K0+a6BfUK5s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gfKCgE3e; 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="gfKCgE3e" Received: by smtp.kernel.org (Postfix) with ESMTPS id E392BC2BCAF; Tue, 10 Feb 2026 19:42:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770752537; bh=gFisofjRmRDkCElxihVrUt91J4Goj29Lj706xglJ8+E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=gfKCgE3e5pbICWl4GW+IBvgezP48EPwEIiFubKnU0fXtGZEyQz4c7Iv0rtt6J6xrh 8g/Vx/A2xxKK9sG67H/Atgb3NQkYVBKPgGhqs/qP/xFvbps9lpJmO095XXS/DcaxbF 6VWpbzFdJI7UiT3xaNWdClCYJH8NNBDXVq76XFQsmiPHza0GgticcTqWxI0IGmbZZA 5u3wWoXb4KPwPDPMwe5jrks7oGoz25IYb6mMqoW+urB/YI6oXyn8z806k1SHdQFDxN MCh53/f9tmnfzaSidWE8Yuw5ZeYbYoeM4zYpHiF0Z5ctYYgSGzw5yKzlzVCbhrs6iy AdwvGhC8zS9Rw== 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 DC756EB2706; Tue, 10 Feb 2026 19:42:17 +0000 (UTC) From: Rodrigo Alencar via B4 Relay Date: Tue, 10 Feb 2026 19:42:08 +0000 Subject: [PATCH v4 08/11] iio: amplifiers: ad8366: prepare for device-tree 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: <20260210-iio-ad8366-update-v4-8-15505f7b15b4@analog.com> References: <20260210-iio-ad8366-update-v4-0-15505f7b15b4@analog.com> In-Reply-To: <20260210-iio-ad8366-update-v4-0-15505f7b15b4@analog.com> To: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, devicetree@vger.kernel.org Cc: Michael Hennerich , Lars-Peter Clausen , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Rodrigo Alencar X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1770752535; l=7157; i=rodrigo.alencar@analog.com; s=default; h=from:subject:message-id; bh=Zdn1IjVL+LQBedLBJP4SxLg0QqdNykisF4eKilB9Xc4=; b=JrMfelEnl3N9RfcUtZKGo+WOxkU4yccNxAYuUHxU/1MuiyMyMc3HLkwfSx7RhM3fwVNVD6EYE WEFJ3ejZp/zBLy6U7UYQqhlQZgClhTC6DHdlWlCJf/L3ZglukZ1VUnb 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 Drop switch case on the enum ID in favor of extended chip info table, containing: - gain_step, indicating with sign the start of the code range; - num_channels, to indicate the number IIO channels; - pack_code() function to describe how SPI buffer is populated; Which allowed for a simplified read_raw() and write_raw() callbacks. The probe() function was adjusted accordingly. Signed-off-by: Rodrigo Alencar --- drivers/iio/amplifiers/ad8366.c | 139 +++++++++++++-----------------------= ---- 1 file changed, 46 insertions(+), 93 deletions(-) diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad836= 6.c index 343f370eae65..1ae75643e89b 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 #include =20 @@ -30,16 +31,20 @@ enum ad8366_type { ID_HMC1119, }; =20 +struct ad8366_state; + struct ad8366_info { int gain_min; int gain_max; + int gain_step; + int num_channels; + size_t (*pack_code)(struct ad8366_state *st); }; =20 struct ad8366_state { struct spi_device *spi; struct mutex lock; /* protect sensor state */ unsigned char ch[2]; - enum ad8366_type type; const struct ad8366_info *info; /* * DMA (thus cache coherency maintenance) may require the @@ -48,60 +53,58 @@ struct ad8366_state { unsigned char data[2] __aligned(IIO_DMA_MINALIGN); }; =20 +static size_t ad8366_pack_code(struct ad8366_state *st) +{ + u8 ch_a =3D bitrev8(st->ch[0]) >> 2; + u8 ch_b =3D bitrev8(st->ch[1]) >> 2; + + put_unaligned_be16((ch_b << 6) | ch_a, &st->data[0]); + return sizeof(__be16); +} + static const struct ad8366_info ad8366_infos[] =3D { [ID_AD8366] =3D { .gain_min =3D 4500, .gain_max =3D 20500, + .gain_step =3D 253, + .num_channels =3D 2, + .pack_code =3D ad8366_pack_code, }, [ID_ADA4961] =3D { .gain_min =3D -6000, .gain_max =3D 15000, + .gain_step =3D -1000, + .num_channels =3D 1, }, [ID_ADL5240] =3D { .gain_min =3D -11500, .gain_max =3D 20000, + .gain_step =3D 500, + .num_channels =3D 1, }, [ID_HMC792] =3D { .gain_min =3D -15750, .gain_max =3D 0, + .gain_step =3D 250, + .num_channels =3D 1, }, [ID_HMC1119] =3D { .gain_min =3D -31750, .gain_max =3D 0, + .gain_step =3D -250, + .num_channels =3D 1, }, }; =20 -static int ad8366_write(struct iio_dev *indio_dev, - unsigned char ch_a, unsigned char ch_b) +static int ad8366_write_code(struct ad8366_state *st) { - struct ad8366_state *st =3D iio_priv(indio_dev); - int ret; + const struct ad8366_info *inf =3D st->info; =20 - switch (st->type) { - case ID_AD8366: - ch_a =3D bitrev8(ch_a & 0x3F); - ch_b =3D bitrev8(ch_b & 0x3F); + if (inf->pack_code) + spi_write(st->spi, st->data, inf->pack_code(st)); =20 - st->data[0] =3D ch_b >> 4; - st->data[1] =3D (ch_b << 4) | (ch_a >> 2); - break; - case ID_ADA4961: - st->data[0] =3D ch_a & 0x1F; - break; - case ID_ADL5240: - st->data[0] =3D (ch_a & 0x3F); - break; - case ID_HMC792: - case ID_HMC1119: - st->data[0] =3D ch_a; - break; - } - - ret =3D spi_write(st->spi, st->data, indio_dev->num_channels); - if (ret < 0) - dev_err(&indio_dev->dev, "write failed (%d)", ret); - - return ret; + st->data[0] =3D st->ch[0]; + return spi_write(st->spi, st->data, 1); } =20 static int ad8366_read_raw(struct iio_dev *indio_dev, @@ -111,6 +114,7 @@ static int ad8366_read_raw(struct iio_dev *indio_dev, long m) { struct ad8366_state *st =3D iio_priv(indio_dev); + const struct ad8366_info *inf =3D st->info; int ret; int code, gain =3D 0; =20 @@ -118,25 +122,8 @@ static int ad8366_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_HARDWAREGAIN: code =3D st->ch[chan->channel]; - - switch (st->type) { - case ID_AD8366: - gain =3D code * 253 + 4500; - break; - case ID_ADA4961: - gain =3D 15000 - code * 1000; - break; - case ID_ADL5240: - gain =3D 20000 - 31500 + code * 500; - break; - case ID_HMC792: - gain =3D -1 * code * 500; - break; - case ID_HMC1119: - gain =3D -1 * code * 250; - break; - } - + gain =3D inf->gain_step > 0 ? inf->gain_min : inf->gain_max; + gain +=3D inf->gain_step * code; /* Values in dB */ *val =3D gain / 1000; *val2 =3D (gain % 1000) * 1000; @@ -171,29 +158,14 @@ static int ad8366_write_raw(struct iio_dev *indio_dev, if (gain > inf->gain_max || gain < inf->gain_min) return -EINVAL; =20 - switch (st->type) { - case ID_AD8366: - code =3D (gain - 4500) / 253; - break; - case ID_ADA4961: - code =3D (15000 - gain) / 1000; - break; - case ID_ADL5240: - code =3D ((gain - 500 - 20000) / 500) & 0x3F; - break; - case ID_HMC792: - code =3D (abs(gain) / 500) & 0x3F; - break; - case ID_HMC1119: - code =3D (abs(gain) / 250) & 0x7F; - break; - } + gain -=3D inf->gain_step > 0 ? inf->gain_min : inf->gain_max; + code =3D DIV_ROUND_CLOSEST(gain, inf->gain_step); =20 mutex_lock(&st->lock); switch (mask) { case IIO_CHAN_INFO_HARDWAREGAIN: st->ch[chan->channel] =3D code; - ret =3D ad8366_write(indio_dev, st->ch[0], st->ch[1]); + ret =3D ad8366_write_code(st); break; default: ret =3D -EINVAL; @@ -234,10 +206,6 @@ static const struct iio_chan_spec ad8366_channels[] = =3D { AD8366_CHAN(1), }; =20 -static const struct iio_chan_spec ada4961_channels[] =3D { - AD8366_CHAN(0), -}; - static int ad8366_probe(struct spi_device *spi) { struct device *dev =3D &spi->dev; @@ -261,35 +229,20 @@ static int ad8366_probe(struct spi_device *spi) return dev_err_probe(dev, ret, "Failed to get regulator\n"); =20 st->spi =3D spi; - st->type =3D spi_get_device_id(spi)->driver_data; + st->info =3D &ad8366_infos[spi_get_device_id(spi)->driver_data]; =20 - switch (st->type) { - case ID_AD8366: - indio_dev->channels =3D ad8366_channels; - indio_dev->num_channels =3D ARRAY_SIZE(ad8366_channels); - break; - case ID_ADA4961: - case ID_ADL5240: - case ID_HMC792: - case ID_HMC1119: - rstc =3D devm_reset_control_get_optional_exclusive_deasserted(dev, NULL); - if (IS_ERR(rstc)) - return dev_err_probe(dev, PTR_ERR(rstc), - "Failed to get reset controller\n"); + rstc =3D devm_reset_control_get_optional_exclusive_deasserted(dev, NULL); + if (IS_ERR(rstc)) + return dev_err_probe(dev, PTR_ERR(rstc), + "Failed to get reset controller\n"); =20 - indio_dev->channels =3D ada4961_channels; - indio_dev->num_channels =3D ARRAY_SIZE(ada4961_channels); - break; - default: - return dev_err_probe(dev, -EINVAL, "Invalid device ID\n"); - } - - st->info =3D &ad8366_infos[st->type]; indio_dev->name =3D spi_get_device_id(spi)->name; indio_dev->info =3D &ad8366_info; indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->channels =3D ad8366_channels; + indio_dev->num_channels =3D st->info->num_channels; =20 - ret =3D ad8366_write(indio_dev, 0, 0); + ret =3D ad8366_write_code(st); if (ret < 0) return dev_err_probe(dev, ret, "failed to write initial gain\n"); =20 --=20 2.43.0