Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: ad7091r: Set device mode through chip_info callback

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>

authored by

Marcelo Schmitt and committed by
Jonathan Cameron
7e3ebda3 6ff545a9

+39 -37
+1 -37
drivers/iio/adc/ad7091r-base.c
··· 20 20 #define AD7091R_REG_RESULT_CH_ID(x) (((x) >> 13) & 0x3) 21 21 #define AD7091R_REG_RESULT_CONV_RESULT(x) ((x) & 0xfff) 22 22 23 - /* AD7091R_REG_CONF */ 24 - #define AD7091R_REG_CONF_ALERT_EN BIT(4) 25 - #define AD7091R_REG_CONF_AUTO BIT(8) 26 - #define AD7091R_REG_CONF_CMD BIT(10) 27 - 28 - #define AD7091R_REG_CONF_MODE_MASK \ 29 - (AD7091R_REG_CONF_AUTO | AD7091R_REG_CONF_CMD) 30 - 31 23 const struct iio_event_spec ad7091r_events[] = { 32 24 { 33 25 .type = IIO_EV_TYPE_THRESH, ··· 40 48 }, 41 49 }; 42 50 EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R); 43 - 44 - static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode) 45 - { 46 - int ret, conf; 47 - 48 - switch (mode) { 49 - case AD7091R_MODE_SAMPLE: 50 - conf = 0; 51 - break; 52 - case AD7091R_MODE_COMMAND: 53 - conf = AD7091R_REG_CONF_CMD; 54 - break; 55 - case AD7091R_MODE_AUTOCYCLE: 56 - conf = AD7091R_REG_CONF_AUTO; 57 - break; 58 - default: 59 - return -EINVAL; 60 - } 61 - 62 - ret = regmap_update_bits(st->map, AD7091R_REG_CONF, 63 - AD7091R_REG_CONF_MODE_MASK, conf); 64 - if (ret) 65 - return ret; 66 - 67 - st->mode = mode; 68 - 69 - return 0; 70 - } 71 51 72 52 static int ad7091r_set_channel(struct ad7091r_state *st, unsigned int channel) 73 53 { ··· 370 406 } 371 407 372 408 /* Use command mode by default to convert only desired channels*/ 373 - ret = ad7091r_set_mode(st, AD7091R_MODE_COMMAND); 409 + ret = st->chip_info->set_mode(st, AD7091R_MODE_COMMAND); 374 410 if (ret) 375 411 return ret; 376 412
+8
drivers/iio/adc/ad7091r-base.h
··· 18 18 #define AD7091R_REG_CH_HIGH_LIMIT(ch) ((ch) * 3 + 5) 19 19 #define AD7091R_REG_CH_HYSTERESIS(ch) ((ch) * 3 + 6) 20 20 21 + /* AD7091R_REG_CONF */ 21 22 #define AD7091R_REG_CONF_INT_VREF BIT(0) 23 + #define AD7091R_REG_CONF_ALERT_EN BIT(4) 24 + #define AD7091R_REG_CONF_AUTO BIT(8) 25 + #define AD7091R_REG_CONF_CMD BIT(10) 26 + 27 + #define AD7091R_REG_CONF_MODE_MASK \ 28 + (AD7091R_REG_CONF_AUTO | AD7091R_REG_CONF_CMD) 22 29 23 30 /* AD7091R_REG_CH_LIMIT */ 24 31 #define AD7091R_HIGH_LIMIT 0xFFF ··· 65 58 unsigned int num_channels; 66 59 const struct iio_chan_spec *channels; 67 60 unsigned int vref_mV; 61 + int (*set_mode)(struct ad7091r_state *st, enum ad7091r_mode mode); 68 62 }; 69 63 70 64 struct ad7091r_init_info {
+30
drivers/iio/adc/ad7091r5.c
··· 26 26 AD7091R_CHANNEL(3, 12, NULL, 0), 27 27 }; 28 28 29 + static int ad7091r5_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode) 30 + { 31 + int ret, conf; 32 + 33 + switch (mode) { 34 + case AD7091R_MODE_SAMPLE: 35 + conf = 0; 36 + break; 37 + case AD7091R_MODE_COMMAND: 38 + conf = AD7091R_REG_CONF_CMD; 39 + break; 40 + case AD7091R_MODE_AUTOCYCLE: 41 + conf = AD7091R_REG_CONF_AUTO; 42 + break; 43 + default: 44 + return -EINVAL; 45 + } 46 + 47 + ret = regmap_update_bits(st->map, AD7091R_REG_CONF, 48 + AD7091R_REG_CONF_MODE_MASK, conf); 49 + if (ret) 50 + return ret; 51 + 52 + st->mode = mode; 53 + 54 + return 0; 55 + } 56 + 29 57 static const struct ad7091r_chip_info ad7091r5_chip_info_irq = { 30 58 .name = "ad7091r-5", 31 59 .channels = ad7091r5_channels_irq, 32 60 .num_channels = ARRAY_SIZE(ad7091r5_channels_irq), 33 61 .vref_mV = 2500, 62 + .set_mode = &ad7091r5_set_mode, 34 63 }; 35 64 36 65 static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = { ··· 67 38 .channels = ad7091r5_channels_noirq, 68 39 .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq), 69 40 .vref_mV = 2500, 41 + .set_mode = &ad7091r5_set_mode, 70 42 }; 71 43 72 44 static const struct regmap_config ad7091r_regmap_config = {