mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Vincent Whitchurch <vincent.whitchurch@axis.com>
To: <jic23@kernel.org>
Cc: <kernel@axis.com>,
	Vincent Whitchurch <vincent.whitchurch@axis.com>,
	<andy.shevchenko@gmail.com>, <lars@metafoo.de>,
	<linux-iio@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH v2 1/5] iio: adc: mcp320x: use callbacks for RX conversion
Date: Wed, 31 Aug 2022 12:05:02 +0200	[thread overview]
Message-ID: <20220831100506.3368103-2-vincent.whitchurch@axis.com> (raw)
In-Reply-To: <20220831100506.3368103-1-vincent.whitchurch@axis.com>

Replace the device_index switch with callbacks from the chip_info
structure, so that the latter has all the information needed to handle
the variants.

Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
---
 drivers/iio/adc/mcp320x.c | 115 ++++++++++++++++++++++----------------
 1 file changed, 67 insertions(+), 48 deletions(-)

diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
index b4c69acb33e3..c71d90babb39 100644
--- a/drivers/iio/adc/mcp320x.c
+++ b/drivers/iio/adc/mcp320x.c
@@ -61,11 +61,14 @@ enum {
 	mcp3553,
 };
 
+struct mcp320x;
+
 struct mcp320x_chip_info {
 	const struct iio_chan_spec *channels;
 	unsigned int num_channels;
 	unsigned int resolution;
 	unsigned int conv_time; /* usec */
+	int (*convert_rx)(struct mcp320x *adc);
 };
 
 /**
@@ -96,6 +99,54 @@ struct mcp320x {
 	u8 rx_buf[4];
 };
 
+static int mcp3001_convert_rx(struct mcp320x *adc)
+{
+	return adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3;
+}
+
+static int mcp3002_convert_rx(struct mcp320x *adc)
+{
+	return adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6;
+}
+
+static int mcp3201_convert_rx(struct mcp320x *adc)
+{
+	return adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1;
+}
+
+static int mcp3202_convert_rx(struct mcp320x *adc)
+{
+	return adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4;
+}
+
+static int mcp3301_convert_rx(struct mcp320x *adc)
+{
+	return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12);
+}
+
+static int mcp3550_convert_rx(struct mcp320x *adc)
+{
+	u32 raw = be32_to_cpup((__be32 *)adc->rx_buf);
+
+	if (!(adc->spi->mode & SPI_CPOL))
+		raw <<= 1; /* strip Data Ready bit in SPI mode 0,0 */
+
+	/*
+	 * If the input is within -vref and vref, bit 21 is the sign.
+	 * Up to 12% overrange or underrange are allowed, in which case
+	 * bit 23 is the sign and bit 0 to 21 is the value.
+	 */
+	raw >>= 8;
+	if (raw & BIT(22) && raw & BIT(23))
+		return -EIO; /* cannot have overrange AND underrange */
+	else if (raw & BIT(22))
+		raw &= ~BIT(22); /* overrange */
+	else if (raw & BIT(23) || raw & BIT(21))
+		raw |= GENMASK(31, 22); /* underrange or negative */
+
+	return (s32)raw;
+}
+
 static int mcp320x_channel_to_tx_data(int device_index,
 			const unsigned int channel, bool differential)
 {
@@ -120,6 +171,7 @@ static int mcp320x_channel_to_tx_data(int device_index,
 static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
 				  bool differential, int device_index, int *val)
 {
+	const struct mcp320x_chip_info *info = adc->chip_info;
 	int ret;
 
 	if (adc->chip_info->conv_time) {
@@ -140,55 +192,9 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
 	if (ret < 0)
 		return ret;
 
-	switch (device_index) {
-	case mcp3001:
-		*val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3);
-		return 0;
-	case mcp3002:
-	case mcp3004:
-	case mcp3008:
-		*val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6);
-		return 0;
-	case mcp3201:
-		*val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1);
-		return 0;
-	case mcp3202:
-	case mcp3204:
-	case mcp3208:
-		*val = (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
-		return 0;
-	case mcp3301:
-		*val = sign_extend32((adc->rx_buf[0] & 0x1f) << 8
-				    | adc->rx_buf[1], 12);
-		return 0;
-	case mcp3550_50:
-	case mcp3550_60:
-	case mcp3551:
-	case mcp3553: {
-		u32 raw = be32_to_cpup((__be32 *)adc->rx_buf);
-
-		if (!(adc->spi->mode & SPI_CPOL))
-			raw <<= 1; /* strip Data Ready bit in SPI mode 0,0 */
+	*val = info->convert_rx(adc);
 
-		/*
-		 * If the input is within -vref and vref, bit 21 is the sign.
-		 * Up to 12% overrange or underrange are allowed, in which case
-		 * bit 23 is the sign and bit 0 to 21 is the value.
-		 */
-		raw >>= 8;
-		if (raw & BIT(22) && raw & BIT(23))
-			return -EIO; /* cannot have overrange AND underrange */
-		else if (raw & BIT(22))
-			raw &= ~BIT(22); /* overrange */
-		else if (raw & BIT(23) || raw & BIT(21))
-			raw |= GENMASK(31, 22); /* underrange or negative */
-
-		*val = (s32)raw;
-		return 0;
-		}
-	default:
-		return -EINVAL;
-	}
+	return 0;
 }
 
 static int mcp320x_read_raw(struct iio_dev *indio_dev,
@@ -302,51 +308,61 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = {
 	[mcp3001] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3001_convert_rx,
 		.resolution = 10
 	},
 	[mcp3002] = {
 		.channels = mcp3202_channels,
 		.num_channels = ARRAY_SIZE(mcp3202_channels),
+		.convert_rx = mcp3002_convert_rx,
 		.resolution = 10
 	},
 	[mcp3004] = {
 		.channels = mcp3204_channels,
 		.num_channels = ARRAY_SIZE(mcp3204_channels),
+		.convert_rx = mcp3002_convert_rx,
 		.resolution = 10
 	},
 	[mcp3008] = {
 		.channels = mcp3208_channels,
 		.num_channels = ARRAY_SIZE(mcp3208_channels),
+		.convert_rx = mcp3002_convert_rx,
 		.resolution = 10
 	},
 	[mcp3201] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3201_convert_rx,
 		.resolution = 12
 	},
 	[mcp3202] = {
 		.channels = mcp3202_channels,
 		.num_channels = ARRAY_SIZE(mcp3202_channels),
+		.convert_rx = mcp3202_convert_rx,
 		.resolution = 12
 	},
 	[mcp3204] = {
 		.channels = mcp3204_channels,
 		.num_channels = ARRAY_SIZE(mcp3204_channels),
+		.convert_rx = mcp3202_convert_rx,
 		.resolution = 12
 	},
 	[mcp3208] = {
 		.channels = mcp3208_channels,
 		.num_channels = ARRAY_SIZE(mcp3208_channels),
+		.convert_rx = mcp3202_convert_rx,
 		.resolution = 12
 	},
 	[mcp3301] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3301_convert_rx,
 		.resolution = 13
 	},
 	[mcp3550_50] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3550_convert_rx,
 		.resolution = 21,
 		/* 2% max deviation + 144 clock periods to exit shutdown */
 		.conv_time = 80000 * 1.02 + 144000 / 102.4,
@@ -354,18 +370,21 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = {
 	[mcp3550_60] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3550_convert_rx,
 		.resolution = 21,
 		.conv_time = 66670 * 1.02 + 144000 / 122.88,
 	},
 	[mcp3551] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3550_convert_rx,
 		.resolution = 21,
 		.conv_time = 73100 * 1.02 + 144000 / 112.64,
 	},
 	[mcp3553] = {
 		.channels = mcp3201_channels,
 		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.convert_rx = mcp3550_convert_rx,
 		.resolution = 21,
 		.conv_time = 16670 * 1.02 + 144000 / 122.88,
 	},
-- 
2.34.1


  reply	other threads:[~2022-08-31 10:05 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-31 10:05 [PATCH v2 0/5] iio: adc: mcp320x: Add triggered buffer support Vincent Whitchurch
2022-08-31 10:05 ` Vincent Whitchurch [this message]
2022-08-31 12:40   ` [PATCH v2 1/5] iio: adc: mcp320x: use callbacks for RX conversion Andy Shevchenko
2022-08-31 14:19     ` Vincent Whitchurch
2022-08-31 20:21       ` Andy Shevchenko
2022-09-04 16:15     ` Jonathan Cameron
2022-09-05  8:27       ` Vincent Whitchurch
2022-09-05  8:38         ` Andy Shevchenko
2022-08-31 10:05 ` [PATCH v2 2/5] iio: adc: mcp320x: remove device_index check for TX Vincent Whitchurch
2022-08-31 12:42   ` Andy Shevchenko
2022-08-31 10:05 ` [PATCH v2 3/5] iio: adc: mcp320x: use conv_time instead of device_index switch Vincent Whitchurch
2022-08-31 12:43   ` Andy Shevchenko
2022-08-31 10:05 ` [PATCH v2 4/5] iio: adc: mcp320x: use device managed functions Vincent Whitchurch
2022-08-31 12:50   ` Andy Shevchenko
2022-09-04 16:08     ` Jonathan Cameron
2022-08-31 10:05 ` [PATCH v2 5/5] iio: adc: mcp320x: add triggered buffer support Vincent Whitchurch
2022-09-04 16:26   ` Jonathan Cameron

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20220831100506.3368103-2-vincent.whitchurch@axis.com \
    --to=vincent.whitchurch@axis.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=jic23@kernel.org \
    --cc=kernel@axis.com \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

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

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

all inboxes | Powered by JetHome®