[PATCH v1] staging: iio: ad7816: add iio interface

From: JuenKit Yip
Date: Sat Jul 08 2023 - 12:30:38 EST


add iio interface for 4 channels, replacing the previous sysfs
interface

Signed-off-by: JuenKit Yip <JuenKit_Yip@xxxxxxxxxxx>
---
drivers/staging/iio/adc/ad7816.c | 122 +++++++++++++++----------------
1 file changed, 59 insertions(+), 63 deletions(-)

diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 6c14d7bcdd67..8af117b6ae11 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -162,64 +162,17 @@ static ssize_t ad7816_show_available_modes(struct device *dev,
static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
NULL, 0);

-static ssize_t ad7816_show_channel(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int ad7816_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7816_chip_info *chip = iio_priv(indio_dev);
-
- return sprintf(buf, "%d\n", chip->channel_id);
-}
-
-static ssize_t ad7816_store_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7816_chip_info *chip = iio_priv(indio_dev);
- unsigned long data;
- int ret;
-
- ret = kstrtoul(buf, 10, &data);
- if (ret)
- return ret;
-
- if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
- dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
- data, indio_dev->name);
- return -EINVAL;
- } else if (strcmp(indio_dev->name, "ad7818") == 0 && data > 1) {
- dev_err(&chip->spi_dev->dev,
- "Invalid channel id %lu for ad7818.\n", data);
- return -EINVAL;
- } else if (strcmp(indio_dev->name, "ad7816") == 0 && data > 0) {
- dev_err(&chip->spi_dev->dev,
- "Invalid channel id %lu for ad7816.\n", data);
- return -EINVAL;
- }
-
- chip->channel_id = data;
-
- return len;
-}
-
-static IIO_DEVICE_ATTR(channel, 0644,
- ad7816_show_channel,
- ad7816_store_channel,
- 0);
-
-static ssize_t ad7816_show_value(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7816_chip_info *chip = iio_priv(indio_dev);
u16 data;
- s8 value;
int ret;

+ chip->channel_id = (u8)chan->channel;
ret = ad7816_spi_read(chip, &data);
if (ret)
return -EIO;
@@ -227,22 +180,21 @@ static ssize_t ad7816_show_value(struct device *dev,
data >>= AD7816_VALUE_OFFSET;

if (chip->channel_id == 0) {
- value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
- data &= AD7816_TEMP_FLOAT_MASK;
- if (value < 0)
- data = BIT(AD7816_TEMP_FLOAT_OFFSET) - data;
- return sprintf(buf, "%d.%.2d\n", value, data * 25);
+ *val = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103);
+ *val2 = (data & AD7816_TEMP_FLOAT_MASK) * 25;
+ if (*val < 0)
+ *val2 = BIT(AD7816_TEMP_FLOAT_OFFSET) - *val2;
+ return IIO_VAL_INT_PLUS_MICRO;
}
- return sprintf(buf, "%u\n", data);
-}

-static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
+ *val = data;
+
+ return IIO_VAL_INT;
+}

static struct attribute *ad7816_attributes[] = {
&iio_dev_attr_available_modes.dev_attr.attr,
&iio_dev_attr_mode.dev_attr.attr,
- &iio_dev_attr_channel.dev_attr.attr,
- &iio_dev_attr_value.dev_attr.attr,
NULL,
};

@@ -341,10 +293,47 @@ static const struct attribute_group ad7816_event_attribute_group = {
};

static const struct iio_info ad7816_info = {
+ .read_raw = ad7816_read_raw,
.attrs = &ad7816_attribute_group,
.event_attrs = &ad7816_event_attribute_group,
};

+static const struct iio_chan_spec ad7816_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .indexed = 1,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+};
+
+static const struct iio_chan_spec ad7817_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .indexed = 1,
+ .channel = 0,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .indexed = 1,
+ .channel = 1,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .indexed = 1,
+ .channel = 2,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .indexed = 1,
+ .channel = 3,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+};
+
/*
* device probe and remove
*/
@@ -367,6 +356,13 @@ static int ad7816_probe(struct spi_device *spi_dev)
chip->oti_data[i] = 203;

chip->id = spi_get_device_id(spi_dev)->driver_data;
+ if (chip->id == ID_AD7816) {
+ indio_dev->channels = ad7816_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ad7816_channels);
+ } else {
+ indio_dev->channels = ad7817_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ad7817_channels);
+ }
chip->rdwr_pin = devm_gpiod_get(&spi_dev->dev, "rdwr", GPIOD_OUT_HIGH);
if (IS_ERR(chip->rdwr_pin)) {
ret = PTR_ERR(chip->rdwr_pin);
--
2.39.2