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

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: ad7606: wrap channel ranges & scales into struct

With the addition of AD7606C-16,18 which have differential & bipolar
channels (and ranges), which can vary from channel to channel, we'll need
to keep more information about each channel range.

To do that, we'll add a 'struct ad7606_chan_scale' type to hold just
configuration for each channel.
This includes the scales per channel (which can be different with
AD7606C-16,18), as well as the range for each channel.
This driver was already keeping the range value for each channel before,
and since this is couple with the scales, it also makes sense to put them
in the same struct.

Signed-off-by: Alexandru Ardelean <aardelean@baylibre.com>
Link: https://patch.msgid.link/20240919130444.2100447-5-aardelean@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Alexandru Ardelean and committed by
Jonathan Cameron
bbd478f2 e571c190

+34 -17
+18 -11
drivers/iio/adc/ad7606.c
··· 64 64 65 65 static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, int ch) 66 66 { 67 + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; 68 + 67 69 if (!st->sw_mode_en) { 68 70 /* tied to logic low, analog input range is +/- 5V */ 69 - st->range[ch] = 0; 70 - st->scale_avail = ad7606_16bit_hw_scale_avail; 71 - st->num_scales = ARRAY_SIZE(ad7606_16bit_hw_scale_avail); 71 + cs->range = 0; 72 + cs->scale_avail = ad7606_16bit_hw_scale_avail; 73 + cs->num_scales = ARRAY_SIZE(ad7606_16bit_hw_scale_avail); 72 74 return 0; 73 75 } 74 76 75 77 /* Scale of 0.076293 is only available in sw mode */ 76 78 /* After reset, in software mode, ±10 V is set by default */ 77 - st->range[ch] = 2; 78 - st->scale_avail = ad7606_16bit_sw_scale_avail; 79 - st->num_scales = ARRAY_SIZE(ad7606_16bit_sw_scale_avail); 79 + cs->range = 2; 80 + cs->scale_avail = ad7606_16bit_sw_scale_avail; 81 + cs->num_scales = ARRAY_SIZE(ad7606_16bit_sw_scale_avail); 80 82 81 83 return 0; 82 84 } ··· 169 167 { 170 168 int ret, ch = 0; 171 169 struct ad7606_state *st = iio_priv(indio_dev); 170 + struct ad7606_chan_scale *cs; 172 171 173 172 switch (m) { 174 173 case IIO_CHAN_INFO_RAW: ··· 183 180 case IIO_CHAN_INFO_SCALE: 184 181 if (st->sw_mode_en) 185 182 ch = chan->address; 183 + cs = &st->chan_scales[ch]; 186 184 *val = 0; 187 - *val2 = st->scale_avail[st->range[ch]]; 185 + *val2 = cs->scale_avail[cs->range]; 188 186 return IIO_VAL_INT_PLUS_MICRO; 189 187 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 190 188 *val = st->oversampling; ··· 215 211 { 216 212 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 217 213 struct ad7606_state *st = iio_priv(indio_dev); 214 + struct ad7606_chan_scale *cs = &st->chan_scales[0]; 218 215 219 - return ad7606_show_avail(buf, st->scale_avail, st->num_scales, true); 216 + return ad7606_show_avail(buf, cs->scale_avail, cs->num_scales, true); 220 217 } 221 218 222 219 static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); ··· 255 250 long mask) 256 251 { 257 252 struct ad7606_state *st = iio_priv(indio_dev); 253 + struct ad7606_chan_scale *cs; 258 254 int i, ret, ch = 0; 259 255 260 256 guard(mutex)(&st->lock); 261 257 262 258 switch (mask) { 263 259 case IIO_CHAN_INFO_SCALE: 264 - i = find_closest(val2, st->scale_avail, st->num_scales); 265 260 if (st->sw_mode_en) 266 261 ch = chan->address; 262 + cs = &st->chan_scales[ch]; 263 + i = find_closest(val2, cs->scale_avail, cs->num_scales); 267 264 ret = st->write_scale(indio_dev, ch, i); 268 265 if (ret < 0) 269 266 return ret; 270 - st->range[ch] = i; 267 + cs->range = i; 271 268 272 269 return 0; 273 270 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: ··· 714 707 struct ad7606_state *st = iio_priv(indio_dev); 715 708 716 709 if (st->gpio_standby) { 717 - gpiod_set_value(st->gpio_range, st->range[0]); 710 + gpiod_set_value(st->gpio_range, st->chan_scales[0].range); 718 711 gpiod_set_value(st->gpio_standby, 1); 719 712 ad7606_reset(st); 720 713 }
+16 -6
drivers/iio/adc/ad7606.h
··· 8 8 #ifndef IIO_ADC_AD7606_H_ 9 9 #define IIO_ADC_AD7606_H_ 10 10 11 + #define AD760X_MAX_CHANNELS 16 12 + 11 13 #define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) { \ 12 14 .type = IIO_VOLTAGE, \ 13 15 .indexed = 1, \ ··· 69 67 }; 70 68 71 69 /** 70 + * struct ad7606_chan_scale - channel scale configuration 71 + * @scale_avail pointer to the array which stores the available scales 72 + * @num_scales number of elements stored in the scale_avail array 73 + * @range voltage range selection, selects which scale to apply 74 + */ 75 + struct ad7606_chan_scale { 76 + const unsigned int *scale_avail; 77 + unsigned int num_scales; 78 + unsigned int range; 79 + }; 80 + 81 + /** 72 82 * struct ad7606_state - driver instance specific data 73 83 * @dev pointer to kernel device 74 84 * @chip_info entry in the table of chips that describes this device 75 85 * @bops bus operations (SPI or parallel) 76 - * @range voltage range selection, selects which scale to apply 86 + * @chan_scales scale configuration for channels 77 87 * @oversampling oversampling selection 78 88 * @base_address address from where to read data in parallel operation 79 89 * @sw_mode_en software mode enabled 80 - * @scale_avail pointer to the array which stores the available scales 81 - * @num_scales number of elements stored in the scale_avail array 82 90 * @oversampling_avail pointer to the array which stores the available 83 91 * oversampling ratios. 84 92 * @num_os_ratios number of elements stored in oversampling_avail array ··· 112 100 struct device *dev; 113 101 const struct ad7606_chip_info *chip_info; 114 102 const struct ad7606_bus_ops *bops; 115 - unsigned int range[16]; 103 + struct ad7606_chan_scale chan_scales[AD760X_MAX_CHANNELS]; 116 104 unsigned int oversampling; 117 105 void __iomem *base_address; 118 106 bool sw_mode_en; 119 - const unsigned int *scale_avail; 120 - unsigned int num_scales; 121 107 const unsigned int *oversampling_avail; 122 108 unsigned int num_os_ratios; 123 109 int (*write_scale)(struct iio_dev *indio_dev, int ch, int val);