iio: adc: ad7091r: Set device mode through chip_info callback
authorMarcelo Schmitt <marcelo.schmitt@analog.com>
Tue, 19 Dec 2023 20:28:45 +0000 (17:28 -0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Tue, 26 Dec 2023 15:42:01 +0000 (15:42 +0000)
AD7091R-5 devices have a few modes of operation (sample, command,
autocycle) which are set by writing to configuration register fields.
Follow up patches will add support for AD7091R-2/-4/-8 which don't have
those operation modes nor the register fields for setting them.
Make ad7091r_set_mode() a callback function of AD7091R chip_info struct
so the base driver can appropriately handle each design without having
to check which actual chip is connected.

Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
Link: https://lore.kernel.org/r/5140336980f66c2c45f05895c3b68e2f65fba1c2.1703013352.git.marcelo.schmitt1@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7091r-base.c
drivers/iio/adc/ad7091r-base.h
drivers/iio/adc/ad7091r5.c

index 2c65c63db40c5afcd352d1ca94f8ab941d1ce045..a4ca2e21e023b02b18d32087c9405f42eaac78dc 100644 (file)
 #define AD7091R_REG_RESULT_CH_ID(x)        (((x) >> 13) & 0x3)
 #define AD7091R_REG_RESULT_CONV_RESULT(x)   ((x) & 0xfff)
 
-/* AD7091R_REG_CONF */
-#define AD7091R_REG_CONF_ALERT_EN   BIT(4)
-#define AD7091R_REG_CONF_AUTO   BIT(8)
-#define AD7091R_REG_CONF_CMD    BIT(10)
-
-#define AD7091R_REG_CONF_MODE_MASK  \
-       (AD7091R_REG_CONF_AUTO | AD7091R_REG_CONF_CMD)
-
 const struct iio_event_spec ad7091r_events[] = {
        {
                .type = IIO_EV_TYPE_THRESH,
@@ -49,34 +41,6 @@ const struct iio_event_spec ad7091r_events[] = {
 };
 EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R);
 
-static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
-{
-       int ret, conf;
-
-       switch (mode) {
-       case AD7091R_MODE_SAMPLE:
-               conf = 0;
-               break;
-       case AD7091R_MODE_COMMAND:
-               conf = AD7091R_REG_CONF_CMD;
-               break;
-       case AD7091R_MODE_AUTOCYCLE:
-               conf = AD7091R_REG_CONF_AUTO;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
-                                AD7091R_REG_CONF_MODE_MASK, conf);
-       if (ret)
-               return ret;
-
-       st->mode = mode;
-
-       return 0;
-}
-
 static int ad7091r_set_channel(struct ad7091r_state *st, unsigned int channel)
 {
        unsigned int dummy;
@@ -406,7 +370,7 @@ int ad7091r_probe(struct device *dev, const struct ad7091r_init_info *init_info,
        }
 
        /* Use command mode by default to convert only desired channels*/
-       ret = ad7091r_set_mode(st, AD7091R_MODE_COMMAND);
+       ret = st->chip_info->set_mode(st, AD7091R_MODE_COMMAND);
        if (ret)
                return ret;
 
index a57ec36491f582bcf269f3a95df98ffb3111049e..7ba5065a63dd6f53dc4e5980fe3c026d8b1284d4 100644 (file)
 #define AD7091R_REG_CH_HIGH_LIMIT(ch) ((ch) * 3 + 5)
 #define AD7091R_REG_CH_HYSTERESIS(ch) ((ch) * 3 + 6)
 
+/* AD7091R_REG_CONF */
 #define AD7091R_REG_CONF_INT_VREF      BIT(0)
+#define AD7091R_REG_CONF_ALERT_EN      BIT(4)
+#define AD7091R_REG_CONF_AUTO          BIT(8)
+#define AD7091R_REG_CONF_CMD           BIT(10)
+
+#define AD7091R_REG_CONF_MODE_MASK  \
+       (AD7091R_REG_CONF_AUTO | AD7091R_REG_CONF_CMD)
 
 /* AD7091R_REG_CH_LIMIT */
 #define AD7091R_HIGH_LIMIT             0xFFF
@@ -58,6 +65,7 @@ struct ad7091r_chip_info {
        unsigned int num_channels;
        const struct iio_chan_spec *channels;
        unsigned int vref_mV;
+       int (*set_mode)(struct ad7091r_state *st, enum ad7091r_mode mode);
 };
 
 struct ad7091r_init_info {
index cb4c7865f0cc6a812966fb2d19caabe914831d2f..e1163b42609c13ebc0cba0f441a73e0c222ed98f 100644 (file)
@@ -26,11 +26,40 @@ static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
        AD7091R_CHANNEL(3, 12, NULL, 0),
 };
 
+static int ad7091r5_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
+{
+       int ret, conf;
+
+       switch (mode) {
+       case AD7091R_MODE_SAMPLE:
+               conf = 0;
+               break;
+       case AD7091R_MODE_COMMAND:
+               conf = AD7091R_REG_CONF_CMD;
+               break;
+       case AD7091R_MODE_AUTOCYCLE:
+               conf = AD7091R_REG_CONF_AUTO;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
+                                AD7091R_REG_CONF_MODE_MASK, conf);
+       if (ret)
+               return ret;
+
+       st->mode = mode;
+
+       return 0;
+}
+
 static const struct ad7091r_chip_info ad7091r5_chip_info_irq = {
        .name = "ad7091r-5",
        .channels = ad7091r5_channels_irq,
        .num_channels = ARRAY_SIZE(ad7091r5_channels_irq),
        .vref_mV = 2500,
+       .set_mode = &ad7091r5_set_mode,
 };
 
 static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = {
@@ -38,6 +67,7 @@ static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = {
        .channels = ad7091r5_channels_noirq,
        .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq),
        .vref_mV = 2500,
+       .set_mode = &ad7091r5_set_mode,
 };
 
 static const struct regmap_config ad7091r_regmap_config = {