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

iio: adc: ad7091r: Add chip_info callback to get conversion result channel

AD7091R-5 and AD7091R-2/-4/-8 have slightly different register field
layout and due to that require different masks for getting the index of
the channel associated with each read.
Add a callback function so the base driver can get correct channel ID
for each chip variant.

Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
Link: https://lore.kernel.org/r/1f7a40b4839b3a1c3f1a0654a1b329bea870feb6.1703013352.git.marcelo.schmitt1@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Marcelo Schmitt and committed by
Jonathan Cameron
8eb5976a 7e3ebda3

+14 -5
+1 -5
drivers/iio/adc/ad7091r-base.c
··· 16 16 17 17 #include "ad7091r-base.h" 18 18 19 - /* AD7091R_REG_RESULT */ 20 - #define AD7091R_REG_RESULT_CH_ID(x) (((x) >> 13) & 0x3) 21 - #define AD7091R_REG_RESULT_CONV_RESULT(x) ((x) & 0xfff) 22 - 23 19 const struct iio_event_spec ad7091r_events[] = { 24 20 { 25 21 .type = IIO_EV_TYPE_THRESH, ··· 70 74 if (ret) 71 75 return ret; 72 76 73 - if (AD7091R_REG_RESULT_CH_ID(val) != channel) 77 + if (st->chip_info->reg_result_chan_id(val) != channel) 74 78 return -EIO; 75 79 76 80 *read_val = AD7091R_REG_RESULT_CONV_RESULT(val);
+6
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_RESULT */ 22 + #define AD7091R5_REG_RESULT_CH_ID(x) (((x) >> 13) & 0x3) 23 + #define AD7091R8_REG_RESULT_CH_ID(x) (((x) >> 13) & 0x7) 24 + #define AD7091R_REG_RESULT_CONV_RESULT(x) ((x) & 0xfff) 25 + 21 26 /* AD7091R_REG_CONF */ 22 27 #define AD7091R_REG_CONF_INT_VREF BIT(0) 23 28 #define AD7091R_REG_CONF_ALERT_EN BIT(4) ··· 70 65 unsigned int num_channels; 71 66 const struct iio_chan_spec *channels; 72 67 unsigned int vref_mV; 68 + unsigned int (*reg_result_chan_id)(unsigned int val); 73 69 int (*set_mode)(struct ad7091r_state *st, enum ad7091r_mode mode); 74 70 }; 75 71
+7
drivers/iio/adc/ad7091r5.c
··· 54 54 return 0; 55 55 } 56 56 57 + static unsigned int ad7091r5_reg_result_chan_id(unsigned int val) 58 + { 59 + return AD7091R5_REG_RESULT_CH_ID(val); 60 + } 61 + 57 62 static const struct ad7091r_chip_info ad7091r5_chip_info_irq = { 58 63 .name = "ad7091r-5", 59 64 .channels = ad7091r5_channels_irq, 60 65 .num_channels = ARRAY_SIZE(ad7091r5_channels_irq), 61 66 .vref_mV = 2500, 67 + .reg_result_chan_id = &ad7091r5_reg_result_chan_id, 62 68 .set_mode = &ad7091r5_set_mode, 63 69 }; 64 70 ··· 73 67 .channels = ad7091r5_channels_noirq, 74 68 .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq), 75 69 .vref_mV = 2500, 70 + .reg_result_chan_id = &ad7091r5_reg_result_chan_id, 76 71 .set_mode = &ad7091r5_set_mode, 77 72 }; 78 73