lkml.org 
[lkml]   [2022]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 1/5] iio: adc: mcp320x: use callbacks for RX conversion
    Date
    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
    \
     
     \ /
      Last update: 2022-08-31 12:06    [W:2.280 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site