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: amplifiers: ad8366: prepare for device-tree support

Drop switch case on the enum ID in favor of extended chip info table,
containing:
- gain_step, indicating with sign the start of the code range;
- num_channels, to indicate the number IIO channels;
- pack_code() function to describe how SPI buffer is populated;

Which allowed for a simplified read_raw() and write_raw() callbacks. The
probe() function was adjusted accordingly. The linux/array_size.h include
is removed as number of channels is provided by chip info table.

Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Rodrigo Alencar and committed by
Jonathan Cameron
314b184b ee4f8c56

+44 -90
+44 -90
drivers/iio/amplifiers/ad8366.c
··· 11 11 * Copyright 2012-2019 Analog Devices Inc. 12 12 */ 13 13 14 - #include <linux/array_size.h> 15 14 #include <linux/bitrev.h> 16 15 #include <linux/bits.h> 17 16 #include <linux/dev_printk.h> ··· 25 26 #include <linux/reset.h> 26 27 #include <linux/spi/spi.h> 27 28 #include <linux/types.h> 29 + #include <linux/unaligned.h> 28 30 29 31 #include <linux/iio/iio.h> 30 32 ··· 40 40 struct ad8366_info { 41 41 int gain_min; 42 42 int gain_max; 43 + int gain_step; 44 + size_t num_channels; 45 + size_t (*pack_code)(const unsigned char *code, size_t num_channels, 46 + unsigned char *data); 43 47 }; 44 48 45 49 struct ad8366_state { 46 50 struct spi_device *spi; 47 51 struct mutex lock; /* protect sensor state */ 48 52 unsigned char ch[2]; 49 - enum ad8366_type type; 50 53 const struct ad8366_info *info; 51 54 /* 52 55 * DMA (thus cache coherency maintenance) may require the ··· 58 55 unsigned char data[2] __aligned(IIO_DMA_MINALIGN); 59 56 }; 60 57 58 + static size_t ad8366_pack_code(const unsigned char *code, size_t num_channels, 59 + unsigned char *data) 60 + { 61 + u8 ch_a = bitrev8(code[0]) >> 2; 62 + u8 ch_b = bitrev8(code[1]) >> 2; 63 + 64 + put_unaligned_be16((ch_b << 6) | ch_a, &data[0]); 65 + return sizeof(__be16); 66 + } 67 + 61 68 static const struct ad8366_info ad8366_infos[] = { 62 69 [ID_AD8366] = { 63 70 .gain_min = 4500, 64 71 .gain_max = 20500, 72 + .gain_step = 253, 73 + .num_channels = 2, 74 + .pack_code = ad8366_pack_code, 65 75 }, 66 76 [ID_ADA4961] = { 67 77 .gain_min = -6000, 68 78 .gain_max = 15000, 79 + .gain_step = -1000, 80 + .num_channels = 1, 69 81 }, 70 82 [ID_ADL5240] = { 71 83 .gain_min = -11500, 72 84 .gain_max = 20000, 85 + .gain_step = 500, 86 + .num_channels = 1, 73 87 }, 74 88 [ID_HMC792] = { 75 89 .gain_min = -15750, 76 90 .gain_max = 0, 91 + .gain_step = 250, 92 + .num_channels = 1, 77 93 }, 78 94 [ID_HMC1119] = { 79 95 .gain_min = -31750, 80 96 .gain_max = 0, 97 + .gain_step = -250, 98 + .num_channels = 1, 81 99 }, 82 100 }; 83 101 84 - static int ad8366_write(struct iio_dev *indio_dev, 85 - unsigned char ch_a, unsigned char ch_b) 102 + static int ad8366_write_code(struct ad8366_state *st) 86 103 { 87 - struct ad8366_state *st = iio_priv(indio_dev); 88 - int ret; 104 + const struct ad8366_info *inf = st->info; 105 + size_t len = 1; 89 106 90 - switch (st->type) { 91 - case ID_AD8366: 92 - ch_a = bitrev8(ch_a & 0x3F); 93 - ch_b = bitrev8(ch_b & 0x3F); 107 + if (inf->pack_code) 108 + len = inf->pack_code(st->ch, inf->num_channels, st->data); 109 + else 110 + st->data[0] = st->ch[0]; 94 111 95 - st->data[0] = ch_b >> 4; 96 - st->data[1] = (ch_b << 4) | (ch_a >> 2); 97 - break; 98 - case ID_ADA4961: 99 - st->data[0] = ch_a & 0x1F; 100 - break; 101 - case ID_ADL5240: 102 - st->data[0] = (ch_a & 0x3F); 103 - break; 104 - case ID_HMC792: 105 - case ID_HMC1119: 106 - st->data[0] = ch_a; 107 - break; 108 - } 109 - 110 - ret = spi_write(st->spi, st->data, indio_dev->num_channels); 111 - if (ret < 0) 112 - dev_err(&indio_dev->dev, "write failed (%d)", ret); 113 - 114 - return ret; 112 + return spi_write(st->spi, st->data, len); 115 113 } 116 114 117 115 static int ad8366_read_raw(struct iio_dev *indio_dev, ··· 122 118 long m) 123 119 { 124 120 struct ad8366_state *st = iio_priv(indio_dev); 121 + const struct ad8366_info *inf = st->info; 125 122 int ret; 126 123 int code, gain = 0; 127 124 ··· 130 125 switch (m) { 131 126 case IIO_CHAN_INFO_HARDWAREGAIN: 132 127 code = st->ch[chan->channel]; 133 - 134 - switch (st->type) { 135 - case ID_AD8366: 136 - gain = code * 253 + 4500; 137 - break; 138 - case ID_ADA4961: 139 - gain = 15000 - code * 1000; 140 - break; 141 - case ID_ADL5240: 142 - gain = 20000 - 31500 + code * 500; 143 - break; 144 - case ID_HMC792: 145 - gain = -1 * code * 500; 146 - break; 147 - case ID_HMC1119: 148 - gain = -1 * code * 250; 149 - break; 150 - } 151 - 128 + gain = inf->gain_step > 0 ? inf->gain_min : inf->gain_max; 129 + gain += inf->gain_step * code; 152 130 /* Values in dB */ 153 131 *val = gain / 1000; 154 132 *val2 = (gain % 1000) * 1000; ··· 166 178 if (gain > inf->gain_max || gain < inf->gain_min) 167 179 return -EINVAL; 168 180 169 - switch (st->type) { 170 - case ID_AD8366: 171 - code = (gain - 4500) / 253; 172 - break; 173 - case ID_ADA4961: 174 - code = (15000 - gain) / 1000; 175 - break; 176 - case ID_ADL5240: 177 - code = ((gain - 500 - 20000) / 500) & 0x3F; 178 - break; 179 - case ID_HMC792: 180 - code = (abs(gain) / 500) & 0x3F; 181 - break; 182 - case ID_HMC1119: 183 - code = (abs(gain) / 250) & 0x7F; 184 - break; 185 - } 181 + gain -= inf->gain_step > 0 ? inf->gain_min : inf->gain_max; 182 + code = DIV_ROUND_CLOSEST(gain, inf->gain_step); 186 183 187 184 mutex_lock(&st->lock); 188 185 switch (mask) { 189 186 case IIO_CHAN_INFO_HARDWAREGAIN: 190 187 st->ch[chan->channel] = code; 191 - ret = ad8366_write(indio_dev, st->ch[0], st->ch[1]); 188 + ret = ad8366_write_code(st); 192 189 break; 193 190 default: 194 191 ret = -EINVAL; ··· 214 241 AD8366_CHAN(1), 215 242 }; 216 243 217 - static const struct iio_chan_spec ada4961_channels[] = { 218 - AD8366_CHAN(0), 219 - }; 220 - 221 244 static int ad8366_probe(struct spi_device *spi) 222 245 { 223 246 struct device *dev = &spi->dev; ··· 237 268 return dev_err_probe(dev, ret, "Failed to get regulator\n"); 238 269 239 270 st->spi = spi; 240 - st->type = spi_get_device_id(spi)->driver_data; 241 - 242 - switch (st->type) { 243 - case ID_AD8366: 244 - indio_dev->channels = ad8366_channels; 245 - indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); 246 - break; 247 - case ID_ADA4961: 248 - case ID_ADL5240: 249 - case ID_HMC792: 250 - case ID_HMC1119: 251 - indio_dev->channels = ada4961_channels; 252 - indio_dev->num_channels = ARRAY_SIZE(ada4961_channels); 253 - break; 254 - default: 255 - return dev_err_probe(dev, -EINVAL, "Invalid device ID\n"); 256 - } 271 + st->info = &ad8366_infos[spi_get_device_id(spi)->driver_data]; 257 272 258 273 rstc = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL); 259 274 if (IS_ERR(rstc)) 260 275 return dev_err_probe(dev, PTR_ERR(rstc), 261 276 "Failed to get reset controller\n"); 262 277 263 - st->info = &ad8366_infos[st->type]; 264 278 indio_dev->name = spi_get_device_id(spi)->name; 265 279 indio_dev->info = &ad8366_info; 266 280 indio_dev->modes = INDIO_DIRECT_MODE; 281 + indio_dev->channels = ad8366_channels; 282 + indio_dev->num_channels = st->info->num_channels; 267 283 268 - ret = ad8366_write(indio_dev, 0, 0); 284 + ret = ad8366_write_code(st); 269 285 if (ret < 0) 270 286 return dev_err_probe(dev, ret, "failed to write initial gain\n"); 271 287