From nobody Tue Apr 7 03:52:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8208ECAAD4 for ; Wed, 31 Aug 2022 10:05:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231192AbiHaKFf (ORCPT ); Wed, 31 Aug 2022 06:05:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230304AbiHaKFV (ORCPT ); Wed, 31 Aug 2022 06:05:21 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD29D7D79E; Wed, 31 Aug 2022 03:05:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1661940318; x=1693476318; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=i+k41+n3odUDXGPNoejWF6hYf5Nr1U+AWwm9/HsCGUk=; b=fi1zAo2Xz66IzFtu4jEbjEDMjkAoclzdeQ/n+aj8/cH6Yl5KV7kWnhcz iV2VLoFtBzQeO8OdSpGPEbDo8kVYuoqBYyJ+mOmc2CuP9gzn+P8En99qq IBVsuSM32bd0dwD5Wy8Q6kKZDBYh/LOFwjf4muWICKKOlHluUCIqxAbT0 a4eI5OykGWvy1iOupdO52O9zpZ17dbs+M6/yVVQr8WQLBNvliCk95ZZd0 aOEIBlYziL6emC5naq5THu5/BcAVK6k2ii3pQWAUHkeTsNfc9xeWv32/G 02i+dboVH6rTfcb3cVRKUQiFOduiQQD1UTjj82/TIJGOPYPcy5GU/KjdT A==; From: Vincent Whitchurch To: CC: , Vincent Whitchurch , , , , Subject: [PATCH v2 1/5] iio: adc: mcp320x: use callbacks for RX conversion Date: Wed, 31 Aug 2022 12:05:02 +0200 Message-ID: <20220831100506.3368103-2-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831100506.3368103-1-vincent.whitchurch@axis.com> References: <20220831100506.3368103-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 --- 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, }; =20 +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); }; =20 /** @@ -96,6 +99,54 @@ struct mcp320x { u8 rx_buf[4]; }; =20 +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 =3D be32_to_cpup((__be32 *)adc->rx_buf); + + if (!(adc->spi->mode & SPI_CPOL)) + raw <<=3D 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 >>=3D 8; + if (raw & BIT(22) && raw & BIT(23)) + return -EIO; /* cannot have overrange AND underrange */ + else if (raw & BIT(22)) + raw &=3D ~BIT(22); /* overrange */ + else if (raw & BIT(23) || raw & BIT(21)) + raw |=3D 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 =3D adc->chip_info; int ret; =20 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; =20 - switch (device_index) { - case mcp3001: - *val =3D (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3); - return 0; - case mcp3002: - case mcp3004: - case mcp3008: - *val =3D (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6); - return 0; - case mcp3201: - *val =3D (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1); - return 0; - case mcp3202: - case mcp3204: - case mcp3208: - *val =3D (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4); - return 0; - case mcp3301: - *val =3D 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 =3D be32_to_cpup((__be32 *)adc->rx_buf); - - if (!(adc->spi->mode & SPI_CPOL)) - raw <<=3D 1; /* strip Data Ready bit in SPI mode 0,0 */ + *val =3D info->convert_rx(adc); =20 - /* - * 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 >>=3D 8; - if (raw & BIT(22) && raw & BIT(23)) - return -EIO; /* cannot have overrange AND underrange */ - else if (raw & BIT(22)) - raw &=3D ~BIT(22); /* overrange */ - else if (raw & BIT(23) || raw & BIT(21)) - raw |=3D GENMASK(31, 22); /* underrange or negative */ - - *val =3D (s32)raw; - return 0; - } - default: - return -EINVAL; - } + return 0; } =20 static int mcp320x_read_raw(struct iio_dev *indio_dev, @@ -302,51 +308,61 @@ static const struct mcp320x_chip_info mcp320x_chip_in= fos[] =3D { [mcp3001] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3001_convert_rx, .resolution =3D 10 }, [mcp3002] =3D { .channels =3D mcp3202_channels, .num_channels =3D ARRAY_SIZE(mcp3202_channels), + .convert_rx =3D mcp3002_convert_rx, .resolution =3D 10 }, [mcp3004] =3D { .channels =3D mcp3204_channels, .num_channels =3D ARRAY_SIZE(mcp3204_channels), + .convert_rx =3D mcp3002_convert_rx, .resolution =3D 10 }, [mcp3008] =3D { .channels =3D mcp3208_channels, .num_channels =3D ARRAY_SIZE(mcp3208_channels), + .convert_rx =3D mcp3002_convert_rx, .resolution =3D 10 }, [mcp3201] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3201_convert_rx, .resolution =3D 12 }, [mcp3202] =3D { .channels =3D mcp3202_channels, .num_channels =3D ARRAY_SIZE(mcp3202_channels), + .convert_rx =3D mcp3202_convert_rx, .resolution =3D 12 }, [mcp3204] =3D { .channels =3D mcp3204_channels, .num_channels =3D ARRAY_SIZE(mcp3204_channels), + .convert_rx =3D mcp3202_convert_rx, .resolution =3D 12 }, [mcp3208] =3D { .channels =3D mcp3208_channels, .num_channels =3D ARRAY_SIZE(mcp3208_channels), + .convert_rx =3D mcp3202_convert_rx, .resolution =3D 12 }, [mcp3301] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3301_convert_rx, .resolution =3D 13 }, [mcp3550_50] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3550_convert_rx, .resolution =3D 21, /* 2% max deviation + 144 clock periods to exit shutdown */ .conv_time =3D 80000 * 1.02 + 144000 / 102.4, @@ -354,18 +370,21 @@ static const struct mcp320x_chip_info mcp320x_chip_in= fos[] =3D { [mcp3550_60] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3550_convert_rx, .resolution =3D 21, .conv_time =3D 66670 * 1.02 + 144000 / 122.88, }, [mcp3551] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3550_convert_rx, .resolution =3D 21, .conv_time =3D 73100 * 1.02 + 144000 / 112.64, }, [mcp3553] =3D { .channels =3D mcp3201_channels, .num_channels =3D ARRAY_SIZE(mcp3201_channels), + .convert_rx =3D mcp3550_convert_rx, .resolution =3D 21, .conv_time =3D 16670 * 1.02 + 144000 / 122.88, }, --=20 2.34.1 From nobody Tue Apr 7 03:52:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCD2CECAAD1 for ; Wed, 31 Aug 2022 10:05:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230498AbiHaKFU (ORCPT ); Wed, 31 Aug 2022 06:05:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59132 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229916AbiHaKFP (ORCPT ); Wed, 31 Aug 2022 06:05:15 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D957818B1C; Wed, 31 Aug 2022 03:05:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1661940313; x=1693476313; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=OBlIcerlLMxcXOCk6lLphH5SI/cE6LX4zmms8VOffM4=; b=Uf64svgJVZ6xeMde5BtURIEd2goDWo0l3Nn7MYTgidr+I64in9LfxHmI FJp0UeRa1ePymE20mKiWeib45b1ZvE2exwDOvBFH0m9u2rzFP1q8avG6r ytWxiaMUXdSIHUOMa66rx15UEhKQV/z6ag81lNA7nnXwVHt7js2bRKObo E5vnmuQ2wMD+0Zc/j70AjaX7RFPkhiOZGHolSMScCVw1AHbOSJcNlBZZj oPG+CHjsAATSg4l5/E/DHGg2IaDFJt1SfYujpGdAAXKqLc86CbMx9xlw0 Wl0G3g8xZmGt7sILJ2dS31uwDYFq2X5C5i9fBdYqpXwn2YGtpiAHTLdto w==; From: Vincent Whitchurch To: CC: , Vincent Whitchurch , , , , Subject: [PATCH v2 2/5] iio: adc: mcp320x: remove device_index check for TX Date: Wed, 31 Aug 2022 12:05:03 +0200 Message-ID: <20220831100506.3368103-3-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831100506.3368103-1-vincent.whitchurch@axis.com> References: <20220831100506.3368103-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Replace the device_index switch with a TX value computation based on the number of channels in the chip_info structure, so that the latter has all the information needed to handle the variants. Signed-off-by: Vincent Whitchurch --- drivers/iio/adc/mcp320x.c | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index c71d90babb39..77fb4522a378 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -147,29 +147,34 @@ static int mcp3550_convert_rx(struct mcp320x *adc) return (s32)raw; } =20 -static int mcp320x_channel_to_tx_data(int device_index, - const unsigned int channel, bool differential) +static int mcp320x_channel_to_tx_data(const struct mcp320x_chip_info *info, + const struct iio_chan_spec *channel) { int start_bit =3D 1; + bool differential =3D channel->differential; + u8 address =3D channel->address; + /* + * This happens to be the same as the last number of the model name for + * multi-channel MCP300X and MCP320X. + */ + unsigned int num_nondiff_channels =3D info->num_channels / 2; =20 - switch (device_index) { - case mcp3002: - case mcp3202: + switch (num_nondiff_channels) { + case 2: return ((start_bit << 4) | (!differential << 3) | - (channel << 2)); - case mcp3004: - case mcp3204: - case mcp3008: - case mcp3208: + (address << 2)); + case 4: + case 8: return ((start_bit << 6) | (!differential << 5) | - (channel << 2)); + (address << 2)); default: - return -EINVAL; + return 0; } } =20 -static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel, - bool differential, int device_index, int *val) +static int mcp320x_adc_conversion(struct mcp320x *adc, + const struct iio_chan_spec *channel, + int *val) { const struct mcp320x_chip_info *info =3D adc->chip_info; int ret; @@ -185,8 +190,7 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, = u8 channel, =20 memset(&adc->rx_buf, 0, sizeof(adc->rx_buf)); if (adc->chip_info->num_channels > 1) - adc->tx_buf =3D mcp320x_channel_to_tx_data(device_index, channel, - differential); + adc->tx_buf =3D mcp320x_channel_to_tx_data(info, channel); =20 ret =3D spi_sync(adc->spi, &adc->msg); if (ret < 0) @@ -203,16 +207,12 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, { struct mcp320x *adc =3D iio_priv(indio_dev); int ret =3D -EINVAL; - int device_index =3D 0; =20 mutex_lock(&adc->lock); =20 - device_index =3D spi_get_device_id(adc->spi)->driver_data; - switch (mask) { case IIO_CHAN_INFO_RAW: - ret =3D mcp320x_adc_conversion(adc, channel->address, - channel->differential, device_index, val); + ret =3D mcp320x_adc_conversion(adc, channel, val); if (ret < 0) goto out; =20 @@ -452,8 +452,8 @@ static int mcp320x_probe(struct spi_device *spi) * conversions without delay between them resets the chip * and ensures all subsequent conversions succeed. */ - mcp320x_adc_conversion(adc, 0, 1, device_index, &ret); - mcp320x_adc_conversion(adc, 0, 1, device_index, &ret); + mcp320x_adc_conversion(adc, &chip_info->channels[0], &ret); + mcp320x_adc_conversion(adc, &chip_info->channels[0], &ret); } =20 adc->reg =3D devm_regulator_get(&spi->dev, "vref"); --=20 2.34.1 From nobody Tue Apr 7 03:52:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FC7DECAAD4 for ; Wed, 31 Aug 2022 10:05:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229629AbiHaKFh (ORCPT ); Wed, 31 Aug 2022 06:05:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59790 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230497AbiHaKFY (ORCPT ); Wed, 31 Aug 2022 06:05:24 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84D9C99247; Wed, 31 Aug 2022 03:05:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1661940319; x=1693476319; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XUwffz74uZ7Ute+FLoHNJJSSnt2Skf2zaVZglgR4zyk=; b=RH/X2wRVDfLx6fmgYCYmq5djOa1uOrvTwBGOzUsbtS7ASb9MzPhImSpK JQlaHUlplR1rdYDVn2y9rxiC5cw1v/jlnQNb1IXr6+f3oY2uhILME0S8U 9PgZHTLui7FUh/f5MbAa3Vu9jdc/+126ldXh0Wl/p6f8LzzCxJtYQIQNH 4/Tfhov/KVzml0xQLMxpNxC2Io1/QkZ3ixt7NLBIa8HKfTzooIOLoY7Vh s6w/8/XtB8+k+Ors1x7BRV3q3/+brOYp+CYyUp8apBpymwNtpzTFEAtIb xWJbc5L9Jk8q3b/usXzN/+9o/tE2i6WuvccTypJA9ny0U3oaoF1UZglwj w==; From: Vincent Whitchurch To: CC: , Vincent Whitchurch , , , , Subject: [PATCH v2 3/5] iio: adc: mcp320x: use conv_time instead of device_index switch Date: Wed, 31 Aug 2022 12:05:04 +0200 Message-ID: <20220831100506.3368103-4-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831100506.3368103-1-vincent.whitchurch@axis.com> References: <20220831100506.3368103-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In mcp320x_adc_conversion(), the presence of the chip_info's conv_time is used as a condition for using the conversion message. Use that same condition when initializing the conversion message and the other handling for variants which need it, instead of the different condition (checking of the device_index) which is used currently. Signed-off-by: Vincent Whitchurch --- drivers/iio/adc/mcp320x.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 77fb4522a378..8ed27df9a0bb 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -429,11 +429,7 @@ static int mcp320x_probe(struct spi_device *spi) spi_message_init_with_transfers(&adc->msg, adc->transfer, ARRAY_SIZE(adc->transfer)); =20 - switch (device_index) { - case mcp3550_50: - case mcp3550_60: - case mcp3551: - case mcp3553: + if (chip_info->conv_time) { /* rx len increases from 24 to 25 bit in SPI mode 0,0 */ if (!(spi->mode & SPI_CPOL)) adc->transfer[1].len++; --=20 2.34.1 From nobody Tue Apr 7 03:52:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B46EECAAD1 for ; Wed, 31 Aug 2022 10:05:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231168AbiHaKFc (ORCPT ); Wed, 31 Aug 2022 06:05:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230459AbiHaKFV (ORCPT ); Wed, 31 Aug 2022 06:05:21 -0400 Received: from smtp1.axis.com (smtp1.axis.com [195.60.68.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2AA19543F3; Wed, 31 Aug 2022 03:05:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1661940317; x=1693476317; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=IV6/GgZtvZM/HS0HfOk29zo087rTH6OyitDmydT3TPc=; b=MI+LNoqsJCy2Kkkg27zpOmFqFqpaVwsfQjFC+B1/1OOmkIAHk0ehzs9R sma56gJoNT8wlDpd7F39bcEW+hAAEbvU0iKa8m9sZyJ5VlHTn4mifKM37 YoEkev4a0+4hBayPcbensKILZL8ZvVynN08nC3p1KfeROp5zf6ZiHe72Z 8mYvN0NVuINcTzj3W9HM4Rp60UJ3fUoPUpQhRNmK/T7xe0vmp7DuiEyLG FalSgheXJvmRmuwrza4O+SLnemTEcQfWjgEXFHIkw9M3xB+PlMOqf/3zg vMUmA70AXWGRs5U6ICBk1ZMIzhIruy2FdxfRsTomc6KpRBGA+9LwpeDav A==; From: Vincent Whitchurch To: CC: , Vincent Whitchurch , , , , Subject: [PATCH v2 4/5] iio: adc: mcp320x: use device managed functions Date: Wed, 31 Aug 2022 12:05:05 +0200 Message-ID: <20220831100506.3368103-5-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831100506.3368103-1-vincent.whitchurch@axis.com> References: <20220831100506.3368103-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Use devm_* functions in probe to remove some code and to make it easier to add further calls to the probe function. Signed-off-by: Vincent Whitchurch --- drivers/iio/adc/mcp320x.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index 8ed27df9a0bb..b1c1bf4b8047 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -390,6 +390,11 @@ static const struct mcp320x_chip_info mcp320x_chip_inf= os[] =3D { }, }; =20 +static void mcp320x_reg_disable(void *reg) +{ + regulator_disable(reg); +} + static int mcp320x_probe(struct spi_device *spi) { struct iio_dev *indio_dev; @@ -460,27 +465,13 @@ static int mcp320x_probe(struct spi_device *spi) if (ret < 0) return ret; =20 - mutex_init(&adc->lock); - - ret =3D iio_device_register(indio_dev); - if (ret < 0) - goto reg_disable; - - return 0; - -reg_disable: - regulator_disable(adc->reg); - - return ret; -} + ret =3D devm_add_action_or_reset(&spi->dev, mcp320x_reg_disable, adc->reg= ); + if (ret) + return ret; =20 -static void mcp320x_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev =3D spi_get_drvdata(spi); - struct mcp320x *adc =3D iio_priv(indio_dev); + mutex_init(&adc->lock); =20 - iio_device_unregister(indio_dev); - regulator_disable(adc->reg); + return devm_iio_device_register(&spi->dev, indio_dev); } =20 static const struct of_device_id mcp320x_dt_ids[] =3D { @@ -535,7 +526,6 @@ static struct spi_driver mcp320x_driver =3D { .of_match_table =3D mcp320x_dt_ids, }, .probe =3D mcp320x_probe, - .remove =3D mcp320x_remove, .id_table =3D mcp320x_id, }; module_spi_driver(mcp320x_driver); --=20 2.34.1 From nobody Tue Apr 7 03:52:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B1A9ECAAD1 for ; Wed, 31 Aug 2022 10:05:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231130AbiHaKFp (ORCPT ); Wed, 31 Aug 2022 06:05:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230456AbiHaKF1 (ORCPT ); Wed, 31 Aug 2022 06:05:27 -0400 Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F29E37AC18; Wed, 31 Aug 2022 03:05:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1661940323; x=1693476323; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=A328sWqGzLU7ZHtuD5eFjCMoh+NiSka+pxCXJOHpsFU=; b=DO05v3TDy/5D7h3seB4kYPMbu5xID+qCIeirqA7nWq0377+5A1RHdb0h b/+rLZrkIG4WR9WRhxPLtt6a4slCgKVvQMGoKY+s29r4gOQmOBJuO6886 FqyVecdBV9xMpkZ3kDvCbl96RASmakfRZfdTqc9O2OnPJfpJM7H17FuEl iTUK4hCbe/Q3LAIs6J56H+xttN02J8MidVkV8PfSolia+pdS4DozKYbDN HvcTIRkaxLbi1mTSJK2KoEUTD3MSO7+LFOUf/1n61AwXhdzacuVQ7wI8L Lhg0A3p2vZO3si/OXqKOnc7VSnRZhqI4j0/Nb1uUtn39P7hYkohd/nBhW Q==; From: Vincent Whitchurch To: CC: , Vincent Whitchurch , , , , , Axel Jonsson Subject: [PATCH v2 5/5] iio: adc: mcp320x: add triggered buffer support Date: Wed, 31 Aug 2022 12:05:06 +0200 Message-ID: <20220831100506.3368103-6-vincent.whitchurch@axis.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831100506.3368103-1-vincent.whitchurch@axis.com> References: <20220831100506.3368103-1-vincent.whitchurch@axis.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Axel Jonsson Add support for triggered buffers. The hardware doesn't provide any special method of reading multiple channels, so just read the channels in a loop to keep things simple. Signed-off-by: Axel Jonsson Signed-off-by: Vincent Whitchurch --- drivers/iio/adc/Kconfig | 2 + drivers/iio/adc/mcp320x.c | 100 ++++++++++++++++++++++++++++++-------- 2 files changed, 82 insertions(+), 20 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 48ace7412874..9f2628120885 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -696,6 +696,8 @@ config MAX9611 config MCP320X tristate "Microchip Technology MCP3x01/02/04/08 and MCP3550/1/3" depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Microchip Technology's MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204, diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c index b1c1bf4b8047..bdc986285e1b 100644 --- a/drivers/iio/adc/mcp320x.c +++ b/drivers/iio/adc/mcp320x.c @@ -37,13 +37,18 @@ * http://ww1.microchip.com/downloads/en/DeviceDoc/21950D.pdf mcp3550/1/3 */ =20 -#include #include -#include -#include +#include +#include #include -#include +#include #include +#include + +#include +#include +#include +#include =20 enum { mcp3001, @@ -243,31 +248,45 @@ static int mcp320x_read_raw(struct iio_dev *indio_dev, .indexed =3D 1, \ .channel =3D (num), \ .address =3D (num), \ + .scan_index =3D (num), \ + .scan_type =3D { \ + .sign =3D 's', \ + .realbits =3D 32, \ + .storagebits =3D 32, \ + .endianness =3D IIO_CPU, \ + }, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE) \ } =20 -#define MCP320X_VOLTAGE_CHANNEL_DIFF(chan1, chan2) \ +#define MCP320X_VOLTAGE_CHANNEL_DIFF(si, chan1, chan2) \ { \ .type =3D IIO_VOLTAGE, \ .indexed =3D 1, \ .channel =3D (chan1), \ .channel2 =3D (chan2), \ .address =3D (chan1), \ + .scan_index =3D (si), \ + .scan_type =3D { \ + .sign =3D 's', \ + .realbits =3D 32, \ + .storagebits =3D 32, \ + .endianness =3D IIO_CPU, \ + }, \ .differential =3D 1, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE) \ } =20 static const struct iio_chan_spec mcp3201_channels[] =3D { - MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1), + MCP320X_VOLTAGE_CHANNEL_DIFF(0, 0, 1), }; =20 static const struct iio_chan_spec mcp3202_channels[] =3D { MCP320X_VOLTAGE_CHANNEL(0), MCP320X_VOLTAGE_CHANNEL(1), - MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1), - MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0), + MCP320X_VOLTAGE_CHANNEL_DIFF(2, 0, 1), + MCP320X_VOLTAGE_CHANNEL_DIFF(3, 1, 0), }; =20 static const struct iio_chan_spec mcp3204_channels[] =3D { @@ -275,10 +294,10 @@ static const struct iio_chan_spec mcp3204_channels[] = =3D { MCP320X_VOLTAGE_CHANNEL(1), MCP320X_VOLTAGE_CHANNEL(2), MCP320X_VOLTAGE_CHANNEL(3), - MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1), - MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0), - MCP320X_VOLTAGE_CHANNEL_DIFF(2, 3), - MCP320X_VOLTAGE_CHANNEL_DIFF(3, 2), + MCP320X_VOLTAGE_CHANNEL_DIFF(4, 0, 1), + MCP320X_VOLTAGE_CHANNEL_DIFF(5, 1, 0), + MCP320X_VOLTAGE_CHANNEL_DIFF(6, 2, 3), + MCP320X_VOLTAGE_CHANNEL_DIFF(7, 3, 2), }; =20 static const struct iio_chan_spec mcp3208_channels[] =3D { @@ -290,14 +309,14 @@ static const struct iio_chan_spec mcp3208_channels[] = =3D { MCP320X_VOLTAGE_CHANNEL(5), MCP320X_VOLTAGE_CHANNEL(6), MCP320X_VOLTAGE_CHANNEL(7), - MCP320X_VOLTAGE_CHANNEL_DIFF(0, 1), - MCP320X_VOLTAGE_CHANNEL_DIFF(1, 0), - MCP320X_VOLTAGE_CHANNEL_DIFF(2, 3), - MCP320X_VOLTAGE_CHANNEL_DIFF(3, 2), - MCP320X_VOLTAGE_CHANNEL_DIFF(4, 5), - MCP320X_VOLTAGE_CHANNEL_DIFF(5, 4), - MCP320X_VOLTAGE_CHANNEL_DIFF(6, 7), - MCP320X_VOLTAGE_CHANNEL_DIFF(7, 6), + MCP320X_VOLTAGE_CHANNEL_DIFF(8, 0, 1), + MCP320X_VOLTAGE_CHANNEL_DIFF(9, 1, 0), + MCP320X_VOLTAGE_CHANNEL_DIFF(10, 2, 3), + MCP320X_VOLTAGE_CHANNEL_DIFF(11, 3, 2), + MCP320X_VOLTAGE_CHANNEL_DIFF(12, 4, 5), + MCP320X_VOLTAGE_CHANNEL_DIFF(13, 5, 4), + MCP320X_VOLTAGE_CHANNEL_DIFF(14, 6, 7), + MCP320X_VOLTAGE_CHANNEL_DIFF(15, 7, 6), }; =20 static const struct iio_info mcp320x_info =3D { @@ -390,6 +409,41 @@ static const struct mcp320x_chip_info mcp320x_chip_inf= os[] =3D { }, }; =20 +static irqreturn_t mcp320x_buffer_trigger_handler(int irq, void *pollfunc) +{ + struct iio_poll_func *pf =3D pollfunc; + struct iio_dev *indio_dev =3D pf->indio_dev; + struct mcp320x *adc =3D iio_priv(indio_dev); + s32 data[ARRAY_SIZE(mcp3208_channels)]; + int i =3D 0; + int chan; + + mutex_lock(&adc->lock); + + for_each_set_bit(chan, indio_dev->active_scan_mask, indio_dev->masklength= ) { + const struct iio_chan_spec *spec =3D &indio_dev->channels[chan]; + int ret, val; + + ret =3D mcp320x_adc_conversion(adc, spec, &val); + if (ret < 0) { + dev_err_ratelimited(&adc->spi->dev, "Failed to read data: %d\n", + ret); + goto out; + } + + data[i++] =3D val; + } + + iio_push_to_buffers(indio_dev, data); + +out: + mutex_unlock(&adc->lock); + + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + static void mcp320x_reg_disable(void *reg) { regulator_disable(reg); @@ -471,6 +525,12 @@ static int mcp320x_probe(struct spi_device *spi) =20 mutex_init(&adc->lock); =20 + ret =3D devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL, + mcp320x_buffer_trigger_handler, + NULL); + if (ret) + return ret; + return devm_iio_device_register(&spi->dev, indio_dev); } =20 --=20 2.34.1