Commit | Line | Data |
---|---|---|
b3af341b SP |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * AD7124 SPI ADC driver | |
4 | * | |
5 | * Copyright 2018 Analog Devices Inc. | |
6 | */ | |
7 | #include <linux/bitfield.h> | |
7b8d045e | 8 | #include <linux/bitops.h> |
b3af341b SP |
9 | #include <linux/clk.h> |
10 | #include <linux/delay.h> | |
11 | #include <linux/device.h> | |
12 | #include <linux/err.h> | |
da4d3d6b | 13 | #include <linux/interrupt.h> |
b3af341b | 14 | #include <linux/kernel.h> |
7b8d045e | 15 | #include <linux/kfifo.h> |
b3af341b | 16 | #include <linux/module.h> |
951ad470 | 17 | #include <linux/of_device.h> |
b3af341b SP |
18 | #include <linux/regulator/consumer.h> |
19 | #include <linux/spi/spi.h> | |
20 | ||
21 | #include <linux/iio/iio.h> | |
22 | #include <linux/iio/adc/ad_sigma_delta.h> | |
23 | #include <linux/iio/sysfs.h> | |
24 | ||
25 | /* AD7124 registers */ | |
26 | #define AD7124_COMMS 0x00 | |
27 | #define AD7124_STATUS 0x00 | |
28 | #define AD7124_ADC_CONTROL 0x01 | |
29 | #define AD7124_DATA 0x02 | |
30 | #define AD7124_IO_CONTROL_1 0x03 | |
31 | #define AD7124_IO_CONTROL_2 0x04 | |
32 | #define AD7124_ID 0x05 | |
33 | #define AD7124_ERROR 0x06 | |
34 | #define AD7124_ERROR_EN 0x07 | |
35 | #define AD7124_MCLK_COUNT 0x08 | |
36 | #define AD7124_CHANNEL(x) (0x09 + (x)) | |
37 | #define AD7124_CONFIG(x) (0x19 + (x)) | |
38 | #define AD7124_FILTER(x) (0x21 + (x)) | |
39 | #define AD7124_OFFSET(x) (0x29 + (x)) | |
40 | #define AD7124_GAIN(x) (0x31 + (x)) | |
41 | ||
42 | /* AD7124_STATUS */ | |
43 | #define AD7124_STATUS_POR_FLAG_MSK BIT(4) | |
44 | ||
45 | /* AD7124_ADC_CONTROL */ | |
5cfe8a1c AT |
46 | #define AD7124_ADC_STATUS_EN_MSK BIT(10) |
47 | #define AD7124_ADC_STATUS_EN(x) FIELD_PREP(AD7124_ADC_STATUS_EN_MSK, x) | |
11d7c8d3 MC |
48 | #define AD7124_ADC_CTRL_REF_EN_MSK BIT(8) |
49 | #define AD7124_ADC_CTRL_REF_EN(x) FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x) | |
b3af341b SP |
50 | #define AD7124_ADC_CTRL_PWR_MSK GENMASK(7, 6) |
51 | #define AD7124_ADC_CTRL_PWR(x) FIELD_PREP(AD7124_ADC_CTRL_PWR_MSK, x) | |
52 | #define AD7124_ADC_CTRL_MODE_MSK GENMASK(5, 2) | |
53 | #define AD7124_ADC_CTRL_MODE(x) FIELD_PREP(AD7124_ADC_CTRL_MODE_MSK, x) | |
54 | ||
951ad470 AA |
55 | /* AD7124 ID */ |
56 | #define AD7124_DEVICE_ID_MSK GENMASK(7, 4) | |
57 | #define AD7124_DEVICE_ID_GET(x) FIELD_GET(AD7124_DEVICE_ID_MSK, x) | |
58 | #define AD7124_SILICON_REV_MSK GENMASK(3, 0) | |
59 | #define AD7124_SILICON_REV_GET(x) FIELD_GET(AD7124_SILICON_REV_MSK, x) | |
60 | ||
61 | #define CHIPID_AD7124_4 0x0 | |
62 | #define CHIPID_AD7124_8 0x1 | |
63 | ||
b3af341b SP |
64 | /* AD7124_CHANNEL_X */ |
65 | #define AD7124_CHANNEL_EN_MSK BIT(15) | |
66 | #define AD7124_CHANNEL_EN(x) FIELD_PREP(AD7124_CHANNEL_EN_MSK, x) | |
67 | #define AD7124_CHANNEL_SETUP_MSK GENMASK(14, 12) | |
68 | #define AD7124_CHANNEL_SETUP(x) FIELD_PREP(AD7124_CHANNEL_SETUP_MSK, x) | |
69 | #define AD7124_CHANNEL_AINP_MSK GENMASK(9, 5) | |
70 | #define AD7124_CHANNEL_AINP(x) FIELD_PREP(AD7124_CHANNEL_AINP_MSK, x) | |
71 | #define AD7124_CHANNEL_AINM_MSK GENMASK(4, 0) | |
72 | #define AD7124_CHANNEL_AINM(x) FIELD_PREP(AD7124_CHANNEL_AINM_MSK, x) | |
73 | ||
74 | /* AD7124_CONFIG_X */ | |
75 | #define AD7124_CONFIG_BIPOLAR_MSK BIT(11) | |
76 | #define AD7124_CONFIG_BIPOLAR(x) FIELD_PREP(AD7124_CONFIG_BIPOLAR_MSK, x) | |
77 | #define AD7124_CONFIG_REF_SEL_MSK GENMASK(4, 3) | |
78 | #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) | |
79 | #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) | |
80 | #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) | |
0e33d15f | 81 | #define AD7124_CONFIG_IN_BUFF_MSK GENMASK(6, 5) |
0eaecea6 | 82 | #define AD7124_CONFIG_IN_BUFF(x) FIELD_PREP(AD7124_CONFIG_IN_BUFF_MSK, x) |
b3af341b SP |
83 | |
84 | /* AD7124_FILTER_X */ | |
85 | #define AD7124_FILTER_FS_MSK GENMASK(10, 0) | |
86 | #define AD7124_FILTER_FS(x) FIELD_PREP(AD7124_FILTER_FS_MSK, x) | |
cef27609 AT |
87 | #define AD7124_FILTER_TYPE_MSK GENMASK(23, 21) |
88 | #define AD7124_FILTER_TYPE_SEL(x) FIELD_PREP(AD7124_FILTER_TYPE_MSK, x) | |
89 | ||
90 | #define AD7124_SINC3_FILTER 2 | |
91 | #define AD7124_SINC4_FILTER 0 | |
b3af341b | 92 | |
7b8d045e AT |
93 | #define AD7124_CONF_ADDR_OFFSET 20 |
94 | #define AD7124_MAX_CONFIGS 8 | |
95 | #define AD7124_MAX_CHANNELS 16 | |
96 | ||
b3af341b SP |
97 | enum ad7124_ids { |
98 | ID_AD7124_4, | |
99 | ID_AD7124_8, | |
100 | }; | |
101 | ||
102 | enum ad7124_ref_sel { | |
103 | AD7124_REFIN1, | |
104 | AD7124_REFIN2, | |
105 | AD7124_INT_REF, | |
106 | AD7124_AVDD_REF, | |
107 | }; | |
108 | ||
109 | enum ad7124_power_mode { | |
110 | AD7124_LOW_POWER, | |
111 | AD7124_MID_POWER, | |
112 | AD7124_FULL_POWER, | |
113 | }; | |
114 | ||
115 | static const unsigned int ad7124_gain[8] = { | |
116 | 1, 2, 4, 8, 16, 32, 64, 128 | |
117 | }; | |
118 | ||
1d8690fe MC |
119 | static const unsigned int ad7124_reg_size[] = { |
120 | 1, 2, 3, 3, 2, 1, 3, 3, 1, 2, 2, 2, 2, | |
121 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
122 | 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, | |
123 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |
124 | 3, 3, 3, 3, 3 | |
125 | }; | |
126 | ||
b3af341b SP |
127 | static const int ad7124_master_clk_freq_hz[3] = { |
128 | [AD7124_LOW_POWER] = 76800, | |
129 | [AD7124_MID_POWER] = 153600, | |
130 | [AD7124_FULL_POWER] = 614400, | |
131 | }; | |
132 | ||
133 | static const char * const ad7124_ref_names[] = { | |
134 | [AD7124_REFIN1] = "refin1", | |
135 | [AD7124_REFIN2] = "refin2", | |
136 | [AD7124_INT_REF] = "int", | |
137 | [AD7124_AVDD_REF] = "avdd", | |
138 | }; | |
139 | ||
140 | struct ad7124_chip_info { | |
951ad470 AA |
141 | const char *name; |
142 | unsigned int chip_id; | |
b3af341b SP |
143 | unsigned int num_inputs; |
144 | }; | |
145 | ||
146 | struct ad7124_channel_config { | |
7b8d045e AT |
147 | bool live; |
148 | unsigned int cfg_slot; | |
b3af341b SP |
149 | enum ad7124_ref_sel refsel; |
150 | bool bipolar; | |
0eaecea6 MC |
151 | bool buf_positive; |
152 | bool buf_negative; | |
b3af341b SP |
153 | unsigned int vref_mv; |
154 | unsigned int pga_bits; | |
155 | unsigned int odr; | |
7b8d045e | 156 | unsigned int odr_sel_bits; |
cef27609 | 157 | unsigned int filter_type; |
b3af341b SP |
158 | }; |
159 | ||
7b8d045e AT |
160 | struct ad7124_channel { |
161 | unsigned int nr; | |
162 | struct ad7124_channel_config cfg; | |
163 | unsigned int ain; | |
164 | unsigned int slot; | |
165 | }; | |
166 | ||
b3af341b SP |
167 | struct ad7124_state { |
168 | const struct ad7124_chip_info *chip_info; | |
169 | struct ad_sigma_delta sd; | |
7b8d045e | 170 | struct ad7124_channel *channels; |
b3af341b SP |
171 | struct regulator *vref[4]; |
172 | struct clk *mclk; | |
173 | unsigned int adc_control; | |
174 | unsigned int num_channels; | |
7b8d045e AT |
175 | struct mutex cfgs_lock; /* lock for configs access */ |
176 | unsigned long cfg_slots_status; /* bitmap with slot status (1 means it is used) */ | |
177 | DECLARE_KFIFO(live_cfgs_fifo, struct ad7124_channel_config *, AD7124_MAX_CONFIGS); | |
b3af341b SP |
178 | }; |
179 | ||
180 | static const struct iio_chan_spec ad7124_channel_template = { | |
181 | .type = IIO_VOLTAGE, | |
182 | .indexed = 1, | |
183 | .differential = 1, | |
184 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | |
185 | BIT(IIO_CHAN_INFO_SCALE) | | |
186 | BIT(IIO_CHAN_INFO_OFFSET) | | |
cef27609 AT |
187 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | |
188 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), | |
b3af341b SP |
189 | .scan_type = { |
190 | .sign = 'u', | |
191 | .realbits = 24, | |
192 | .storagebits = 32, | |
b3af341b SP |
193 | .endianness = IIO_BE, |
194 | }, | |
195 | }; | |
196 | ||
197 | static struct ad7124_chip_info ad7124_chip_info_tbl[] = { | |
198 | [ID_AD7124_4] = { | |
62fe3e42 | 199 | .name = "ad7124-4", |
951ad470 | 200 | .chip_id = CHIPID_AD7124_4, |
b3af341b SP |
201 | .num_inputs = 8, |
202 | }, | |
203 | [ID_AD7124_8] = { | |
62fe3e42 | 204 | .name = "ad7124-8", |
951ad470 | 205 | .chip_id = CHIPID_AD7124_8, |
b3af341b SP |
206 | .num_inputs = 16, |
207 | }, | |
208 | }; | |
209 | ||
210 | static int ad7124_find_closest_match(const int *array, | |
211 | unsigned int size, int val) | |
212 | { | |
213 | int i, idx; | |
214 | unsigned int diff_new, diff_old; | |
215 | ||
216 | diff_old = U32_MAX; | |
217 | idx = 0; | |
218 | ||
219 | for (i = 0; i < size; i++) { | |
220 | diff_new = abs(val - array[i]); | |
221 | if (diff_new < diff_old) { | |
222 | diff_old = diff_new; | |
223 | idx = i; | |
224 | } | |
225 | } | |
226 | ||
227 | return idx; | |
228 | } | |
229 | ||
230 | static int ad7124_spi_write_mask(struct ad7124_state *st, | |
231 | unsigned int addr, | |
232 | unsigned long mask, | |
233 | unsigned int val, | |
234 | unsigned int bytes) | |
235 | { | |
236 | unsigned int readval; | |
237 | int ret; | |
238 | ||
239 | ret = ad_sd_read_reg(&st->sd, addr, bytes, &readval); | |
240 | if (ret < 0) | |
241 | return ret; | |
242 | ||
243 | readval &= ~mask; | |
244 | readval |= val; | |
245 | ||
246 | return ad_sd_write_reg(&st->sd, addr, bytes, readval); | |
247 | } | |
248 | ||
249 | static int ad7124_set_mode(struct ad_sigma_delta *sd, | |
250 | enum ad_sigma_delta_mode mode) | |
251 | { | |
252 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | |
253 | ||
254 | st->adc_control &= ~AD7124_ADC_CTRL_MODE_MSK; | |
255 | st->adc_control |= AD7124_ADC_CTRL_MODE(mode); | |
256 | ||
257 | return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control); | |
258 | } | |
259 | ||
7b8d045e | 260 | static void ad7124_set_channel_odr(struct ad7124_state *st, unsigned int channel, unsigned int odr) |
b3af341b SP |
261 | { |
262 | unsigned int fclk, odr_sel_bits; | |
b3af341b SP |
263 | |
264 | fclk = clk_get_rate(st->mclk); | |
265 | /* | |
266 | * FS[10:0] = fCLK / (fADC x 32) where: | |
267 | * fADC is the output data rate | |
268 | * fCLK is the master clock frequency | |
269 | * FS[10:0] are the bits in the filter register | |
270 | * FS[10:0] can have a value from 1 to 2047 | |
271 | */ | |
272 | odr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * 32); | |
273 | if (odr_sel_bits < 1) | |
274 | odr_sel_bits = 1; | |
275 | else if (odr_sel_bits > 2047) | |
276 | odr_sel_bits = 2047; | |
277 | ||
7b8d045e AT |
278 | if (odr_sel_bits != st->channels[channel].cfg.odr_sel_bits) |
279 | st->channels[channel].cfg.live = false; | |
b3af341b | 280 | |
7b8d045e AT |
281 | /* fADC = fCLK / (FS[10:0] x 32) */ |
282 | st->channels[channel].cfg.odr = DIV_ROUND_CLOSEST(fclk, odr_sel_bits * 32); | |
283 | st->channels[channel].cfg.odr_sel_bits = odr_sel_bits; | |
b3af341b SP |
284 | } |
285 | ||
cef27609 AT |
286 | static int ad7124_get_3db_filter_freq(struct ad7124_state *st, |
287 | unsigned int channel) | |
288 | { | |
289 | unsigned int fadc; | |
290 | ||
7b8d045e | 291 | fadc = st->channels[channel].cfg.odr; |
cef27609 | 292 | |
7b8d045e | 293 | switch (st->channels[channel].cfg.filter_type) { |
cef27609 AT |
294 | case AD7124_SINC3_FILTER: |
295 | return DIV_ROUND_CLOSEST(fadc * 230, 1000); | |
296 | case AD7124_SINC4_FILTER: | |
297 | return DIV_ROUND_CLOSEST(fadc * 262, 1000); | |
298 | default: | |
299 | return -EINVAL; | |
300 | } | |
301 | } | |
302 | ||
7b8d045e AT |
303 | static void ad7124_set_3db_filter_freq(struct ad7124_state *st, unsigned int channel, |
304 | unsigned int freq) | |
cef27609 AT |
305 | { |
306 | unsigned int sinc4_3db_odr; | |
307 | unsigned int sinc3_3db_odr; | |
308 | unsigned int new_filter; | |
309 | unsigned int new_odr; | |
310 | ||
311 | sinc4_3db_odr = DIV_ROUND_CLOSEST(freq * 1000, 230); | |
312 | sinc3_3db_odr = DIV_ROUND_CLOSEST(freq * 1000, 262); | |
313 | ||
314 | if (sinc4_3db_odr > sinc3_3db_odr) { | |
315 | new_filter = AD7124_SINC3_FILTER; | |
316 | new_odr = sinc4_3db_odr; | |
317 | } else { | |
318 | new_filter = AD7124_SINC4_FILTER; | |
319 | new_odr = sinc3_3db_odr; | |
320 | } | |
321 | ||
7b8d045e AT |
322 | if (new_odr != st->channels[channel].cfg.odr) |
323 | st->channels[channel].cfg.live = false; | |
cef27609 | 324 | |
7b8d045e AT |
325 | st->channels[channel].cfg.filter_type = new_filter; |
326 | st->channels[channel].cfg.odr = new_odr; | |
327 | } | |
328 | ||
329 | static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_state *st, | |
330 | struct ad7124_channel_config *cfg) | |
331 | { | |
332 | struct ad7124_channel_config *cfg_aux; | |
333 | ptrdiff_t cmp_size; | |
334 | int i; | |
335 | ||
336 | cmp_size = (u8 *)&cfg->live - (u8 *)cfg; | |
337 | for (i = 0; i < st->num_channels; i++) { | |
338 | cfg_aux = &st->channels[i].cfg; | |
339 | ||
340 | if (cfg_aux->live && !memcmp(cfg, cfg_aux, cmp_size)) | |
341 | return cfg_aux; | |
342 | } | |
343 | ||
344 | return NULL; | |
345 | } | |
346 | ||
347 | static int ad7124_find_free_config_slot(struct ad7124_state *st) | |
348 | { | |
349 | unsigned int free_cfg_slot; | |
350 | ||
b5c7e7ec | 351 | free_cfg_slot = find_first_zero_bit(&st->cfg_slots_status, AD7124_MAX_CONFIGS); |
7b8d045e AT |
352 | if (free_cfg_slot == AD7124_MAX_CONFIGS) |
353 | return -1; | |
354 | ||
355 | return free_cfg_slot; | |
356 | } | |
357 | ||
358 | static int ad7124_init_config_vref(struct ad7124_state *st, struct ad7124_channel_config *cfg) | |
359 | { | |
360 | unsigned int refsel = cfg->refsel; | |
361 | ||
362 | switch (refsel) { | |
363 | case AD7124_REFIN1: | |
364 | case AD7124_REFIN2: | |
365 | case AD7124_AVDD_REF: | |
366 | if (IS_ERR(st->vref[refsel])) { | |
367 | dev_err(&st->sd.spi->dev, | |
368 | "Error, trying to use external voltage reference without a %s regulator.\n", | |
369 | ad7124_ref_names[refsel]); | |
370 | return PTR_ERR(st->vref[refsel]); | |
371 | } | |
372 | cfg->vref_mv = regulator_get_voltage(st->vref[refsel]); | |
373 | /* Conversion from uV to mV */ | |
374 | cfg->vref_mv /= 1000; | |
375 | return 0; | |
376 | case AD7124_INT_REF: | |
377 | cfg->vref_mv = 2500; | |
378 | st->adc_control &= ~AD7124_ADC_CTRL_REF_EN_MSK; | |
379 | st->adc_control |= AD7124_ADC_CTRL_REF_EN(1); | |
380 | return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, | |
381 | 2, st->adc_control); | |
382 | default: | |
383 | dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel); | |
384 | return -EINVAL; | |
cef27609 | 385 | } |
7b8d045e AT |
386 | } |
387 | ||
388 | static int ad7124_write_config(struct ad7124_state *st, struct ad7124_channel_config *cfg, | |
389 | unsigned int cfg_slot) | |
390 | { | |
391 | unsigned int tmp; | |
392 | unsigned int val; | |
393 | int ret; | |
394 | ||
395 | cfg->cfg_slot = cfg_slot; | |
396 | ||
397 | tmp = (cfg->buf_positive << 1) + cfg->buf_negative; | |
398 | val = AD7124_CONFIG_BIPOLAR(cfg->bipolar) | AD7124_CONFIG_REF_SEL(cfg->refsel) | | |
399 | AD7124_CONFIG_IN_BUFF(tmp); | |
400 | ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(cfg->cfg_slot), 2, val); | |
401 | if (ret < 0) | |
402 | return ret; | |
403 | ||
404 | tmp = AD7124_FILTER_TYPE_SEL(cfg->filter_type); | |
405 | ret = ad7124_spi_write_mask(st, AD7124_FILTER(cfg->cfg_slot), AD7124_FILTER_TYPE_MSK, | |
406 | tmp, 3); | |
407 | if (ret < 0) | |
408 | return ret; | |
409 | ||
410 | ret = ad7124_spi_write_mask(st, AD7124_FILTER(cfg->cfg_slot), AD7124_FILTER_FS_MSK, | |
411 | AD7124_FILTER_FS(cfg->odr_sel_bits), 3); | |
412 | if (ret < 0) | |
413 | return ret; | |
cef27609 | 414 | |
7b8d045e AT |
415 | return ad7124_spi_write_mask(st, AD7124_CONFIG(cfg->cfg_slot), AD7124_CONFIG_PGA_MSK, |
416 | AD7124_CONFIG_PGA(cfg->pga_bits), 2); | |
cef27609 AT |
417 | } |
418 | ||
7b8d045e AT |
419 | static struct ad7124_channel_config *ad7124_pop_config(struct ad7124_state *st) |
420 | { | |
421 | struct ad7124_channel_config *lru_cfg; | |
422 | struct ad7124_channel_config *cfg; | |
423 | int ret; | |
424 | int i; | |
425 | ||
426 | /* | |
427 | * Pop least recently used config from the fifo | |
428 | * in order to make room for the new one | |
429 | */ | |
430 | ret = kfifo_get(&st->live_cfgs_fifo, &lru_cfg); | |
431 | if (ret <= 0) | |
432 | return NULL; | |
433 | ||
434 | lru_cfg->live = false; | |
435 | ||
436 | /* mark slot as free */ | |
437 | assign_bit(lru_cfg->cfg_slot, &st->cfg_slots_status, 0); | |
438 | ||
439 | /* invalidate all other configs that pointed to this one */ | |
440 | for (i = 0; i < st->num_channels; i++) { | |
441 | cfg = &st->channels[i].cfg; | |
442 | ||
443 | if (cfg->cfg_slot == lru_cfg->cfg_slot) | |
444 | cfg->live = false; | |
445 | } | |
446 | ||
447 | return lru_cfg; | |
448 | } | |
449 | ||
450 | static int ad7124_push_config(struct ad7124_state *st, struct ad7124_channel_config *cfg) | |
451 | { | |
452 | struct ad7124_channel_config *lru_cfg; | |
453 | int free_cfg_slot; | |
454 | ||
455 | free_cfg_slot = ad7124_find_free_config_slot(st); | |
456 | if (free_cfg_slot >= 0) { | |
457 | /* push the new config in configs queue */ | |
458 | kfifo_put(&st->live_cfgs_fifo, cfg); | |
459 | } else { | |
460 | /* pop one config to make room for the new one */ | |
461 | lru_cfg = ad7124_pop_config(st); | |
462 | if (!lru_cfg) | |
463 | return -EINVAL; | |
464 | ||
465 | /* push the new config in configs queue */ | |
466 | free_cfg_slot = lru_cfg->cfg_slot; | |
467 | kfifo_put(&st->live_cfgs_fifo, cfg); | |
468 | } | |
469 | ||
470 | /* mark slot as used */ | |
471 | assign_bit(free_cfg_slot, &st->cfg_slots_status, 1); | |
472 | ||
473 | return ad7124_write_config(st, cfg, free_cfg_slot); | |
474 | } | |
475 | ||
476 | static int ad7124_enable_channel(struct ad7124_state *st, struct ad7124_channel *ch) | |
477 | { | |
478 | ch->cfg.live = true; | |
479 | return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(ch->nr), 2, ch->ain | | |
480 | AD7124_CHANNEL_SETUP(ch->cfg.cfg_slot) | AD7124_CHANNEL_EN(1)); | |
481 | } | |
482 | ||
483 | static int ad7124_prepare_read(struct ad7124_state *st, int address) | |
484 | { | |
485 | struct ad7124_channel_config *cfg = &st->channels[address].cfg; | |
486 | struct ad7124_channel_config *live_cfg; | |
487 | ||
488 | /* | |
489 | * Before doing any reads assign the channel a configuration. | |
490 | * Check if channel's config is on the device | |
491 | */ | |
492 | if (!cfg->live) { | |
493 | /* check if config matches another one */ | |
494 | live_cfg = ad7124_find_similar_live_cfg(st, cfg); | |
495 | if (!live_cfg) | |
496 | ad7124_push_config(st, cfg); | |
497 | else | |
498 | cfg->cfg_slot = live_cfg->cfg_slot; | |
499 | } | |
500 | ||
501 | /* point channel to the config slot and enable */ | |
502 | return ad7124_enable_channel(st, &st->channels[address]); | |
503 | } | |
504 | ||
5cfe8a1c AT |
505 | static int __ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) |
506 | { | |
507 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | |
508 | ||
509 | return ad7124_prepare_read(st, channel); | |
510 | } | |
511 | ||
7b8d045e AT |
512 | static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) |
513 | { | |
514 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | |
515 | int ret; | |
516 | ||
517 | mutex_lock(&st->cfgs_lock); | |
5cfe8a1c | 518 | ret = __ad7124_set_channel(sd, channel); |
7b8d045e AT |
519 | mutex_unlock(&st->cfgs_lock); |
520 | ||
521 | return ret; | |
522 | } | |
523 | ||
5cfe8a1c AT |
524 | static int ad7124_append_status(struct ad_sigma_delta *sd, bool append) |
525 | { | |
526 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | |
527 | unsigned int adc_control = st->adc_control; | |
528 | int ret; | |
529 | ||
530 | adc_control &= ~AD7124_ADC_STATUS_EN_MSK; | |
531 | adc_control |= AD7124_ADC_STATUS_EN(append); | |
532 | ||
533 | ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, adc_control); | |
534 | if (ret < 0) | |
535 | return ret; | |
536 | ||
537 | st->adc_control = adc_control; | |
538 | ||
539 | return 0; | |
540 | } | |
541 | ||
542 | static int ad7124_disable_all(struct ad_sigma_delta *sd) | |
543 | { | |
544 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | |
545 | int ret; | |
546 | int i; | |
547 | ||
548 | for (i = 0; i < st->num_channels; i++) { | |
549 | ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK, 0, 2); | |
550 | if (ret < 0) | |
551 | return ret; | |
552 | } | |
553 | ||
554 | return 0; | |
555 | } | |
556 | ||
7b8d045e AT |
557 | static const struct ad_sigma_delta_info ad7124_sigma_delta_info = { |
558 | .set_channel = ad7124_set_channel, | |
5cfe8a1c AT |
559 | .append_status = ad7124_append_status, |
560 | .disable_all = ad7124_disable_all, | |
7b8d045e AT |
561 | .set_mode = ad7124_set_mode, |
562 | .has_registers = true, | |
563 | .addr_shift = 0, | |
564 | .read_mask = BIT(6), | |
5cfe8a1c | 565 | .status_ch_mask = GENMASK(3, 0), |
7b8d045e | 566 | .data_reg = AD7124_DATA, |
5cfe8a1c AT |
567 | .num_slots = 8, |
568 | .irq_flags = IRQF_TRIGGER_FALLING, | |
7b8d045e AT |
569 | }; |
570 | ||
b3af341b SP |
571 | static int ad7124_read_raw(struct iio_dev *indio_dev, |
572 | struct iio_chan_spec const *chan, | |
573 | int *val, int *val2, long info) | |
574 | { | |
575 | struct ad7124_state *st = iio_priv(indio_dev); | |
576 | int idx, ret; | |
577 | ||
578 | switch (info) { | |
579 | case IIO_CHAN_INFO_RAW: | |
580 | ret = ad_sigma_delta_single_conversion(indio_dev, chan, val); | |
581 | if (ret < 0) | |
582 | return ret; | |
583 | ||
584 | /* After the conversion is performed, disable the channel */ | |
7b8d045e AT |
585 | ret = ad_sd_write_reg(&st->sd, AD7124_CHANNEL(chan->address), 2, |
586 | st->channels[chan->address].ain | AD7124_CHANNEL_EN(0)); | |
b3af341b SP |
587 | if (ret < 0) |
588 | return ret; | |
589 | ||
590 | return IIO_VAL_INT; | |
591 | case IIO_CHAN_INFO_SCALE: | |
7b8d045e AT |
592 | mutex_lock(&st->cfgs_lock); |
593 | ||
594 | idx = st->channels[chan->address].cfg.pga_bits; | |
595 | *val = st->channels[chan->address].cfg.vref_mv; | |
596 | if (st->channels[chan->address].cfg.bipolar) | |
b3af341b SP |
597 | *val2 = chan->scan_type.realbits - 1 + idx; |
598 | else | |
599 | *val2 = chan->scan_type.realbits + idx; | |
600 | ||
7b8d045e | 601 | mutex_unlock(&st->cfgs_lock); |
b3af341b SP |
602 | return IIO_VAL_FRACTIONAL_LOG2; |
603 | case IIO_CHAN_INFO_OFFSET: | |
7b8d045e AT |
604 | mutex_lock(&st->cfgs_lock); |
605 | if (st->channels[chan->address].cfg.bipolar) | |
b3af341b SP |
606 | *val = -(1 << (chan->scan_type.realbits - 1)); |
607 | else | |
608 | *val = 0; | |
609 | ||
7b8d045e | 610 | mutex_unlock(&st->cfgs_lock); |
b3af341b SP |
611 | return IIO_VAL_INT; |
612 | case IIO_CHAN_INFO_SAMP_FREQ: | |
7b8d045e AT |
613 | mutex_lock(&st->cfgs_lock); |
614 | *val = st->channels[chan->address].cfg.odr; | |
615 | mutex_unlock(&st->cfgs_lock); | |
b3af341b | 616 | |
cef27609 AT |
617 | return IIO_VAL_INT; |
618 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | |
7b8d045e | 619 | mutex_lock(&st->cfgs_lock); |
cef27609 | 620 | *val = ad7124_get_3db_filter_freq(st, chan->scan_index); |
7b8d045e AT |
621 | mutex_unlock(&st->cfgs_lock); |
622 | ||
b3af341b SP |
623 | return IIO_VAL_INT; |
624 | default: | |
625 | return -EINVAL; | |
626 | } | |
627 | } | |
628 | ||
629 | static int ad7124_write_raw(struct iio_dev *indio_dev, | |
630 | struct iio_chan_spec const *chan, | |
631 | int val, int val2, long info) | |
632 | { | |
633 | struct ad7124_state *st = iio_priv(indio_dev); | |
634 | unsigned int res, gain, full_scale, vref; | |
7b8d045e AT |
635 | int ret = 0; |
636 | ||
637 | mutex_lock(&st->cfgs_lock); | |
b3af341b SP |
638 | |
639 | switch (info) { | |
640 | case IIO_CHAN_INFO_SAMP_FREQ: | |
7b8d045e AT |
641 | if (val2 != 0) { |
642 | ret = -EINVAL; | |
643 | break; | |
644 | } | |
b3af341b | 645 | |
7b8d045e AT |
646 | ad7124_set_channel_odr(st, chan->address, val); |
647 | break; | |
b3af341b | 648 | case IIO_CHAN_INFO_SCALE: |
7b8d045e AT |
649 | if (val != 0) { |
650 | ret = -EINVAL; | |
651 | break; | |
652 | } | |
b3af341b | 653 | |
7b8d045e | 654 | if (st->channels[chan->address].cfg.bipolar) |
b3af341b SP |
655 | full_scale = 1 << (chan->scan_type.realbits - 1); |
656 | else | |
657 | full_scale = 1 << chan->scan_type.realbits; | |
658 | ||
7b8d045e | 659 | vref = st->channels[chan->address].cfg.vref_mv * 1000000LL; |
b3af341b SP |
660 | res = DIV_ROUND_CLOSEST(vref, full_scale); |
661 | gain = DIV_ROUND_CLOSEST(res, val2); | |
7b8d045e | 662 | res = ad7124_find_closest_match(ad7124_gain, ARRAY_SIZE(ad7124_gain), gain); |
b3af341b | 663 | |
7b8d045e AT |
664 | if (st->channels[chan->address].cfg.pga_bits != res) |
665 | st->channels[chan->address].cfg.live = false; | |
666 | ||
667 | st->channels[chan->address].cfg.pga_bits = res; | |
668 | break; | |
cef27609 | 669 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
7b8d045e AT |
670 | if (val2 != 0) { |
671 | ret = -EINVAL; | |
672 | break; | |
673 | } | |
cef27609 | 674 | |
7b8d045e AT |
675 | ad7124_set_3db_filter_freq(st, chan->address, val); |
676 | break; | |
b3af341b | 677 | default: |
7b8d045e | 678 | ret = -EINVAL; |
b3af341b | 679 | } |
7b8d045e AT |
680 | |
681 | mutex_unlock(&st->cfgs_lock); | |
682 | return ret; | |
b3af341b SP |
683 | } |
684 | ||
1d8690fe MC |
685 | static int ad7124_reg_access(struct iio_dev *indio_dev, |
686 | unsigned int reg, | |
687 | unsigned int writeval, | |
688 | unsigned int *readval) | |
689 | { | |
690 | struct ad7124_state *st = iio_priv(indio_dev); | |
691 | int ret; | |
692 | ||
693 | if (reg >= ARRAY_SIZE(ad7124_reg_size)) | |
694 | return -EINVAL; | |
695 | ||
696 | if (readval) | |
697 | ret = ad_sd_read_reg(&st->sd, reg, ad7124_reg_size[reg], | |
698 | readval); | |
699 | else | |
700 | ret = ad_sd_write_reg(&st->sd, reg, ad7124_reg_size[reg], | |
701 | writeval); | |
702 | ||
703 | return ret; | |
704 | } | |
705 | ||
b3af341b SP |
706 | static IIO_CONST_ATTR(in_voltage_scale_available, |
707 | "0.000001164 0.000002328 0.000004656 0.000009313 0.000018626 0.000037252 0.000074505 0.000149011 0.000298023"); | |
708 | ||
709 | static struct attribute *ad7124_attributes[] = { | |
710 | &iio_const_attr_in_voltage_scale_available.dev_attr.attr, | |
711 | NULL, | |
712 | }; | |
713 | ||
714 | static const struct attribute_group ad7124_attrs_group = { | |
715 | .attrs = ad7124_attributes, | |
716 | }; | |
717 | ||
fd5ba89e AT |
718 | static int ad7124_update_scan_mode(struct iio_dev *indio_dev, |
719 | const unsigned long *scan_mask) | |
720 | { | |
721 | struct ad7124_state *st = iio_priv(indio_dev); | |
722 | bool bit_set; | |
723 | int ret; | |
724 | int i; | |
725 | ||
5cfe8a1c | 726 | mutex_lock(&st->cfgs_lock); |
fd5ba89e AT |
727 | for (i = 0; i < st->num_channels; i++) { |
728 | bit_set = test_bit(i, scan_mask); | |
5cfe8a1c AT |
729 | if (bit_set) |
730 | ret = __ad7124_set_channel(&st->sd, i); | |
731 | else | |
732 | ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK, | |
733 | 0, 2); | |
734 | if (ret < 0) { | |
735 | mutex_unlock(&st->cfgs_lock); | |
736 | ||
fd5ba89e | 737 | return ret; |
5cfe8a1c | 738 | } |
fd5ba89e | 739 | } |
5cfe8a1c AT |
740 | |
741 | mutex_unlock(&st->cfgs_lock); | |
742 | ||
fd5ba89e AT |
743 | return 0; |
744 | } | |
745 | ||
b3af341b SP |
746 | static const struct iio_info ad7124_info = { |
747 | .read_raw = ad7124_read_raw, | |
748 | .write_raw = ad7124_write_raw, | |
1d8690fe | 749 | .debugfs_reg_access = &ad7124_reg_access, |
b3af341b | 750 | .validate_trigger = ad_sd_validate_trigger, |
fd5ba89e | 751 | .update_scan_mode = ad7124_update_scan_mode, |
b3af341b SP |
752 | .attrs = &ad7124_attrs_group, |
753 | }; | |
754 | ||
755 | static int ad7124_soft_reset(struct ad7124_state *st) | |
756 | { | |
757 | unsigned int readval, timeout; | |
758 | int ret; | |
759 | ||
760 | ret = ad_sd_reset(&st->sd, 64); | |
761 | if (ret < 0) | |
762 | return ret; | |
763 | ||
764 | timeout = 100; | |
765 | do { | |
766 | ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval); | |
767 | if (ret < 0) | |
768 | return ret; | |
769 | ||
770 | if (!(readval & AD7124_STATUS_POR_FLAG_MSK)) | |
771 | return 0; | |
772 | ||
773 | /* The AD7124 requires typically 2ms to power up and settle */ | |
774 | usleep_range(100, 2000); | |
775 | } while (--timeout); | |
776 | ||
777 | dev_err(&st->sd.spi->dev, "Soft reset failed\n"); | |
778 | ||
779 | return -EIO; | |
780 | } | |
781 | ||
951ad470 AA |
782 | static int ad7124_check_chip_id(struct ad7124_state *st) |
783 | { | |
784 | unsigned int readval, chip_id, silicon_rev; | |
785 | int ret; | |
786 | ||
787 | ret = ad_sd_read_reg(&st->sd, AD7124_ID, 1, &readval); | |
788 | if (ret < 0) | |
789 | return ret; | |
790 | ||
791 | chip_id = AD7124_DEVICE_ID_GET(readval); | |
792 | silicon_rev = AD7124_SILICON_REV_GET(readval); | |
793 | ||
794 | if (chip_id != st->chip_info->chip_id) { | |
795 | dev_err(&st->sd.spi->dev, | |
796 | "Chip ID mismatch: expected %u, got %u\n", | |
797 | st->chip_info->chip_id, chip_id); | |
798 | return -ENODEV; | |
799 | } | |
800 | ||
801 | if (silicon_rev == 0) { | |
802 | dev_err(&st->sd.spi->dev, | |
803 | "Silicon revision empty. Chip may not be present\n"); | |
804 | return -ENODEV; | |
805 | } | |
806 | ||
807 | return 0; | |
808 | } | |
809 | ||
b3af341b SP |
810 | static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, |
811 | struct device_node *np) | |
812 | { | |
813 | struct ad7124_state *st = iio_priv(indio_dev); | |
7b8d045e AT |
814 | struct ad7124_channel_config *cfg; |
815 | struct ad7124_channel *channels; | |
b3af341b SP |
816 | struct device_node *child; |
817 | struct iio_chan_spec *chan; | |
818 | unsigned int ain[2], channel = 0, tmp; | |
819 | int ret; | |
820 | ||
821 | st->num_channels = of_get_available_child_count(np); | |
822 | if (!st->num_channels) { | |
823 | dev_err(indio_dev->dev.parent, "no channel children\n"); | |
824 | return -ENODEV; | |
825 | } | |
826 | ||
827 | chan = devm_kcalloc(indio_dev->dev.parent, st->num_channels, | |
828 | sizeof(*chan), GFP_KERNEL); | |
829 | if (!chan) | |
830 | return -ENOMEM; | |
831 | ||
7b8d045e AT |
832 | channels = devm_kcalloc(indio_dev->dev.parent, st->num_channels, sizeof(*channels), |
833 | GFP_KERNEL); | |
834 | if (!channels) | |
1478a388 MC |
835 | return -ENOMEM; |
836 | ||
b3af341b SP |
837 | indio_dev->channels = chan; |
838 | indio_dev->num_channels = st->num_channels; | |
7b8d045e | 839 | st->channels = channels; |
b3af341b SP |
840 | |
841 | for_each_available_child_of_node(np, child) { | |
7b8d045e AT |
842 | cfg = &st->channels[channel].cfg; |
843 | ||
b3af341b SP |
844 | ret = of_property_read_u32(child, "reg", &channel); |
845 | if (ret) | |
846 | goto err; | |
847 | ||
f2a772c5 JC |
848 | if (channel >= indio_dev->num_channels) { |
849 | dev_err(indio_dev->dev.parent, | |
850 | "Channel index >= number of channels\n"); | |
851 | ret = -EINVAL; | |
852 | goto err; | |
853 | } | |
854 | ||
b3af341b SP |
855 | ret = of_property_read_u32_array(child, "diff-channels", |
856 | ain, 2); | |
857 | if (ret) | |
858 | goto err; | |
859 | ||
7b8d045e AT |
860 | st->channels[channel].nr = channel; |
861 | st->channels[channel].ain = AD7124_CHANNEL_AINP(ain[0]) | | |
b3af341b | 862 | AD7124_CHANNEL_AINM(ain[1]); |
7b8d045e AT |
863 | |
864 | cfg->bipolar = of_property_read_bool(child, "bipolar"); | |
b3af341b SP |
865 | |
866 | ret = of_property_read_u32(child, "adi,reference-select", &tmp); | |
867 | if (ret) | |
7b8d045e | 868 | cfg->refsel = AD7124_INT_REF; |
b3af341b | 869 | else |
7b8d045e | 870 | cfg->refsel = tmp; |
b3af341b | 871 | |
7b8d045e AT |
872 | cfg->buf_positive = of_property_read_bool(child, "adi,buffered-positive"); |
873 | cfg->buf_negative = of_property_read_bool(child, "adi,buffered-negative"); | |
0eaecea6 | 874 | |
d7857e4e AT |
875 | chan[channel] = ad7124_channel_template; |
876 | chan[channel].address = channel; | |
877 | chan[channel].scan_index = channel; | |
878 | chan[channel].channel = ain[0]; | |
879 | chan[channel].channel2 = ain[1]; | |
b3af341b SP |
880 | } |
881 | ||
882 | return 0; | |
883 | err: | |
884 | of_node_put(child); | |
885 | ||
886 | return ret; | |
887 | } | |
888 | ||
889 | static int ad7124_setup(struct ad7124_state *st) | |
890 | { | |
7b8d045e AT |
891 | unsigned int fclk, power_mode; |
892 | int i, ret; | |
b3af341b SP |
893 | |
894 | fclk = clk_get_rate(st->mclk); | |
895 | if (!fclk) | |
896 | return -EINVAL; | |
897 | ||
898 | /* The power mode changes the master clock frequency */ | |
899 | power_mode = ad7124_find_closest_match(ad7124_master_clk_freq_hz, | |
900 | ARRAY_SIZE(ad7124_master_clk_freq_hz), | |
901 | fclk); | |
902 | if (fclk != ad7124_master_clk_freq_hz[power_mode]) { | |
903 | ret = clk_set_rate(st->mclk, fclk); | |
904 | if (ret) | |
905 | return ret; | |
906 | } | |
907 | ||
908 | /* Set the power mode */ | |
909 | st->adc_control &= ~AD7124_ADC_CTRL_PWR_MSK; | |
910 | st->adc_control |= AD7124_ADC_CTRL_PWR(power_mode); | |
911 | ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control); | |
912 | if (ret < 0) | |
913 | return ret; | |
914 | ||
7b8d045e AT |
915 | mutex_init(&st->cfgs_lock); |
916 | INIT_KFIFO(st->live_cfgs_fifo); | |
b3af341b | 917 | for (i = 0; i < st->num_channels; i++) { |
b3af341b | 918 | |
7b8d045e | 919 | ret = ad7124_init_config_vref(st, &st->channels[i].cfg); |
b3af341b SP |
920 | if (ret < 0) |
921 | return ret; | |
922 | ||
b3af341b SP |
923 | /* |
924 | * 9.38 SPS is the minimum output data rate supported | |
925 | * regardless of the selected power mode. Round it up to 10 and | |
7b8d045e | 926 | * set all channels to this default value. |
b3af341b | 927 | */ |
7b8d045e | 928 | ad7124_set_channel_odr(st, i, 10); |
b3af341b SP |
929 | } |
930 | ||
931 | return ret; | |
932 | } | |
933 | ||
45734723 JC |
934 | static void ad7124_reg_disable(void *r) |
935 | { | |
936 | regulator_disable(r); | |
937 | } | |
938 | ||
b3af341b SP |
939 | static int ad7124_probe(struct spi_device *spi) |
940 | { | |
951ad470 | 941 | const struct ad7124_chip_info *info; |
b3af341b SP |
942 | struct ad7124_state *st; |
943 | struct iio_dev *indio_dev; | |
944 | int i, ret; | |
945 | ||
951ad470 | 946 | info = of_device_get_match_data(&spi->dev); |
3a258747 WY |
947 | if (!info) |
948 | info = (void *)spi_get_device_id(spi)->driver_data; | |
951ad470 AA |
949 | if (!info) |
950 | return -ENODEV; | |
951 | ||
b3af341b SP |
952 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
953 | if (!indio_dev) | |
954 | return -ENOMEM; | |
955 | ||
956 | st = iio_priv(indio_dev); | |
957 | ||
951ad470 | 958 | st->chip_info = info; |
b3af341b | 959 | |
951ad470 | 960 | indio_dev->name = st->chip_info->name; |
b3af341b SP |
961 | indio_dev->modes = INDIO_DIRECT_MODE; |
962 | indio_dev->info = &ad7124_info; | |
963 | ||
5cfe8a1c AT |
964 | ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info); |
965 | if (ret < 0) | |
966 | return ret; | |
967 | ||
b3af341b SP |
968 | ret = ad7124_of_parse_channel_config(indio_dev, spi->dev.of_node); |
969 | if (ret < 0) | |
970 | return ret; | |
971 | ||
972 | for (i = 0; i < ARRAY_SIZE(st->vref); i++) { | |
973 | if (i == AD7124_INT_REF) | |
974 | continue; | |
975 | ||
976 | st->vref[i] = devm_regulator_get_optional(&spi->dev, | |
977 | ad7124_ref_names[i]); | |
978 | if (PTR_ERR(st->vref[i]) == -ENODEV) | |
979 | continue; | |
980 | else if (IS_ERR(st->vref[i])) | |
981 | return PTR_ERR(st->vref[i]); | |
982 | ||
983 | ret = regulator_enable(st->vref[i]); | |
984 | if (ret) | |
985 | return ret; | |
45734723 JC |
986 | |
987 | ret = devm_add_action_or_reset(&spi->dev, ad7124_reg_disable, | |
988 | st->vref[i]); | |
989 | if (ret) | |
990 | return ret; | |
b3af341b SP |
991 | } |
992 | ||
8bbce095 | 993 | st->mclk = devm_clk_get_enabled(&spi->dev, "mclk"); |
45734723 JC |
994 | if (IS_ERR(st->mclk)) |
995 | return PTR_ERR(st->mclk); | |
b3af341b | 996 | |
b3af341b SP |
997 | ret = ad7124_soft_reset(st); |
998 | if (ret < 0) | |
c066ca14 | 999 | return ret; |
b3af341b | 1000 | |
951ad470 AA |
1001 | ret = ad7124_check_chip_id(st); |
1002 | if (ret) | |
c066ca14 | 1003 | return ret; |
951ad470 | 1004 | |
b3af341b SP |
1005 | ret = ad7124_setup(st); |
1006 | if (ret < 0) | |
c066ca14 | 1007 | return ret; |
b3af341b | 1008 | |
c066ca14 | 1009 | ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev); |
b3af341b | 1010 | if (ret < 0) |
c066ca14 | 1011 | return ret; |
b3af341b | 1012 | |
c066ca14 | 1013 | return devm_iio_device_register(&spi->dev, indio_dev); |
b3af341b | 1014 | |
b3af341b SP |
1015 | } |
1016 | ||
b3af341b | 1017 | static const struct of_device_id ad7124_of_match[] = { |
951ad470 AA |
1018 | { .compatible = "adi,ad7124-4", |
1019 | .data = &ad7124_chip_info_tbl[ID_AD7124_4], }, | |
1020 | { .compatible = "adi,ad7124-8", | |
1021 | .data = &ad7124_chip_info_tbl[ID_AD7124_8], }, | |
b3af341b SP |
1022 | { }, |
1023 | }; | |
1024 | MODULE_DEVICE_TABLE(of, ad7124_of_match); | |
1025 | ||
3a258747 WY |
1026 | static const struct spi_device_id ad71124_ids[] = { |
1027 | { "ad7124-4", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_4] }, | |
1028 | { "ad7124-8", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_8] }, | |
1029 | {} | |
1030 | }; | |
1031 | MODULE_DEVICE_TABLE(spi, ad71124_ids); | |
1032 | ||
b3af341b SP |
1033 | static struct spi_driver ad71124_driver = { |
1034 | .driver = { | |
1035 | .name = "ad7124", | |
1036 | .of_match_table = ad7124_of_match, | |
1037 | }, | |
1038 | .probe = ad7124_probe, | |
3a258747 | 1039 | .id_table = ad71124_ids, |
b3af341b SP |
1040 | }; |
1041 | module_spi_driver(ad71124_driver); | |
1042 | ||
1043 | MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); | |
1044 | MODULE_DESCRIPTION("Analog Devices AD7124 SPI driver"); | |
1045 | MODULE_LICENSE("GPL"); | |
ef807729 | 1046 | MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); |