1 | // SPDX-License-Identifier: GPL-2.0 |
---|---|
2 | /* |
3 | * This file is the ADC part of the STM32 DFSDM driver |
4 | * |
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved |
6 | * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>. |
7 | */ |
8 | |
9 | #include <linux/dmaengine.h> |
10 | #include <linux/dma-mapping.h> |
11 | #include <linux/iio/adc/stm32-dfsdm-adc.h> |
12 | #include <linux/iio/backend.h> |
13 | #include <linux/iio/buffer.h> |
14 | #include <linux/iio/hw-consumer.h> |
15 | #include <linux/iio/sysfs.h> |
16 | #include <linux/iio/timer/stm32-lptim-trigger.h> |
17 | #include <linux/iio/timer/stm32-timer-trigger.h> |
18 | #include <linux/iio/trigger.h> |
19 | #include <linux/iio/trigger_consumer.h> |
20 | #include <linux/iio/triggered_buffer.h> |
21 | #include <linux/interrupt.h> |
22 | #include <linux/module.h> |
23 | #include <linux/of.h> |
24 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> |
26 | #include <linux/regmap.h> |
27 | #include <linux/slab.h> |
28 | |
29 | #include "stm32-dfsdm.h" |
30 | |
31 | #define DFSDM_DMA_BUFFER_SIZE (4 * PAGE_SIZE) |
32 | |
33 | /* Conversion timeout */ |
34 | #define DFSDM_TIMEOUT_US 100000 |
35 | #define DFSDM_TIMEOUT (msecs_to_jiffies(DFSDM_TIMEOUT_US / 1000)) |
36 | |
37 | /* Oversampling attribute default */ |
38 | #define DFSDM_DEFAULT_OVERSAMPLING 100 |
39 | |
40 | /* Oversampling max values */ |
41 | #define DFSDM_MAX_INT_OVERSAMPLING 256 |
42 | #define DFSDM_MAX_FL_OVERSAMPLING 1024 |
43 | |
44 | /* Limit filter output resolution to 31 bits. (i.e. sample range is +/-2^30) */ |
45 | #define DFSDM_DATA_MAX BIT(30) |
46 | /* |
47 | * Data are output as two's complement data in a 24 bit field. |
48 | * Data from filters are in the range +/-2^(n-1) |
49 | * 2^(n-1) maximum positive value cannot be coded in 2's complement n bits |
50 | * An extra bit is required to avoid wrap-around of the binary code for 2^(n-1) |
51 | * So, the resolution of samples from filter is actually limited to 23 bits |
52 | */ |
53 | #define DFSDM_DATA_RES 24 |
54 | |
55 | /* Filter configuration */ |
56 | #define DFSDM_CR1_CFG_MASK (DFSDM_CR1_RCH_MASK | DFSDM_CR1_RCONT_MASK | \ |
57 | DFSDM_CR1_RSYNC_MASK | DFSDM_CR1_JSYNC_MASK | \ |
58 | DFSDM_CR1_JSCAN_MASK) |
59 | |
60 | enum sd_converter_type { |
61 | DFSDM_AUDIO, |
62 | DFSDM_IIO, |
63 | }; |
64 | |
65 | struct stm32_dfsdm_dev_data { |
66 | int type; |
67 | int (*init)(struct device *dev, struct iio_dev *indio_dev); |
68 | unsigned int num_channels; |
69 | const struct regmap_config *regmap_cfg; |
70 | }; |
71 | |
72 | struct stm32_dfsdm_adc { |
73 | struct stm32_dfsdm *dfsdm; |
74 | const struct stm32_dfsdm_dev_data *dev_data; |
75 | unsigned int fl_id; |
76 | unsigned int nconv; |
77 | unsigned long smask; |
78 | |
79 | /* ADC specific */ |
80 | unsigned int oversamp; |
81 | struct iio_hw_consumer *hwc; |
82 | struct iio_backend **backend; |
83 | struct completion completion; |
84 | u32 *buffer; |
85 | |
86 | /* Audio specific */ |
87 | unsigned int spi_freq; /* SPI bus clock frequency */ |
88 | unsigned int sample_freq; /* Sample frequency after filter decimation */ |
89 | int (*cb)(const void *data, size_t size, void *cb_priv); |
90 | void *cb_priv; |
91 | |
92 | /* DMA */ |
93 | u8 *rx_buf; |
94 | unsigned int bufi; /* Buffer current position */ |
95 | unsigned int buf_sz; /* Buffer size */ |
96 | struct dma_chan *dma_chan; |
97 | dma_addr_t dma_buf; |
98 | }; |
99 | |
100 | struct stm32_dfsdm_str2field { |
101 | const char *name; |
102 | unsigned int val; |
103 | }; |
104 | |
105 | /* DFSDM channel serial interface type */ |
106 | static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_type[] = { |
107 | { "SPI_R", 0 }, /* SPI with data on rising edge */ |
108 | { "SPI_F", 1 }, /* SPI with data on falling edge */ |
109 | { "MANCH_R", 2 }, /* Manchester codec, rising edge = logic 0 */ |
110 | { "MANCH_F", 3 }, /* Manchester codec, falling edge = logic 1 */ |
111 | { } |
112 | }; |
113 | |
114 | /* DFSDM channel clock source */ |
115 | static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_src[] = { |
116 | /* External SPI clock (CLKIN x) */ |
117 | { "CLKIN", DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL }, |
118 | /* Internal SPI clock (CLKOUT) */ |
119 | { "CLKOUT", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL }, |
120 | /* Internal SPI clock divided by 2 (falling edge) */ |
121 | { "CLKOUT_F", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING }, |
122 | /* Internal SPI clock divided by 2 (falling edge) */ |
123 | { "CLKOUT_R", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING }, |
124 | { } |
125 | }; |
126 | |
127 | static int stm32_dfsdm_str2val(const char *str, |
128 | const struct stm32_dfsdm_str2field *list) |
129 | { |
130 | const struct stm32_dfsdm_str2field *p = list; |
131 | |
132 | for (p = list; p && p->name; p++) |
133 | if (!strcmp(p->name, str)) |
134 | return p->val; |
135 | |
136 | return -EINVAL; |
137 | } |
138 | |
139 | /** |
140 | * struct stm32_dfsdm_trig_info - DFSDM trigger info |
141 | * @name: name of the trigger, corresponding to its source |
142 | * @jextsel: trigger signal selection |
143 | */ |
144 | struct stm32_dfsdm_trig_info { |
145 | const char *name; |
146 | unsigned int jextsel; |
147 | }; |
148 | |
149 | /* hardware injected trigger enable, edge selection */ |
150 | enum stm32_dfsdm_jexten { |
151 | STM32_DFSDM_JEXTEN_DISABLED, |
152 | STM32_DFSDM_JEXTEN_RISING_EDGE, |
153 | STM32_DFSDM_JEXTEN_FALLING_EDGE, |
154 | STM32_DFSDM_EXTEN_BOTH_EDGES, |
155 | }; |
156 | |
157 | static const struct stm32_dfsdm_trig_info stm32_dfsdm_trigs[] = { |
158 | { TIM1_TRGO, 0 }, |
159 | { TIM1_TRGO2, 1 }, |
160 | { TIM8_TRGO, 2 }, |
161 | { TIM8_TRGO2, 3 }, |
162 | { TIM3_TRGO, 4 }, |
163 | { TIM4_TRGO, 5 }, |
164 | { TIM16_OC1, 6 }, |
165 | { TIM6_TRGO, 7 }, |
166 | { TIM7_TRGO, 8 }, |
167 | { LPTIM1_OUT, 26 }, |
168 | { LPTIM2_OUT, 27 }, |
169 | { LPTIM3_OUT, 28 }, |
170 | { } |
171 | }; |
172 | |
173 | static int stm32_dfsdm_get_jextsel(struct iio_dev *indio_dev, |
174 | struct iio_trigger *trig) |
175 | { |
176 | int i; |
177 | |
178 | /* lookup triggers registered by stm32 timer trigger driver */ |
179 | for (i = 0; stm32_dfsdm_trigs[i].name; i++) { |
180 | /** |
181 | * Checking both stm32 timer trigger type and trig name |
182 | * should be safe against arbitrary trigger names. |
183 | */ |
184 | if ((is_stm32_timer_trigger(trig) || |
185 | is_stm32_lptim_trigger(trig)) && |
186 | !strcmp(stm32_dfsdm_trigs[i].name, trig->name)) { |
187 | return stm32_dfsdm_trigs[i].jextsel; |
188 | } |
189 | } |
190 | |
191 | return -EINVAL; |
192 | } |
193 | |
194 | static int stm32_dfsdm_compute_osrs(struct stm32_dfsdm_filter *fl, |
195 | unsigned int fast, unsigned int oversamp) |
196 | { |
197 | unsigned int i, d, fosr, iosr; |
198 | u64 res, max; |
199 | int bits, shift; |
200 | unsigned int m = 1; /* multiplication factor */ |
201 | unsigned int p = fl->ford; /* filter order (ford) */ |
202 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fast]; |
203 | |
204 | pr_debug("Requested oversampling: %d\n", oversamp); |
205 | /* |
206 | * This function tries to compute filter oversampling and integrator |
207 | * oversampling, base on oversampling ratio requested by user. |
208 | * |
209 | * Decimation d depends on the filter order and the oversampling ratios. |
210 | * ford: filter order |
211 | * fosr: filter over sampling ratio |
212 | * iosr: integrator over sampling ratio |
213 | */ |
214 | if (fl->ford == DFSDM_FASTSINC_ORDER) { |
215 | m = 2; |
216 | p = 2; |
217 | } |
218 | |
219 | /* |
220 | * Look for filter and integrator oversampling ratios which allows |
221 | * to maximize data output resolution. |
222 | */ |
223 | for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) { |
224 | for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) { |
225 | if (fast) |
226 | d = fosr * iosr; |
227 | else if (fl->ford == DFSDM_FASTSINC_ORDER) |
228 | d = fosr * (iosr + 3) + 2; |
229 | else |
230 | d = fosr * (iosr - 1 + p) + p; |
231 | |
232 | if (d > oversamp) |
233 | break; |
234 | else if (d != oversamp) |
235 | continue; |
236 | /* |
237 | * Check resolution (limited to signed 32 bits) |
238 | * res <= 2^31 |
239 | * Sincx filters: |
240 | * res = m * fosr^p x iosr (with m=1, p=ford) |
241 | * FastSinc filter |
242 | * res = m * fosr^p x iosr (with m=2, p=2) |
243 | */ |
244 | res = fosr; |
245 | for (i = p - 1; i > 0; i--) { |
246 | res = res * (u64)fosr; |
247 | if (res > DFSDM_DATA_MAX) |
248 | break; |
249 | } |
250 | if (res > DFSDM_DATA_MAX) |
251 | continue; |
252 | |
253 | res = res * (u64)m * (u64)iosr; |
254 | if (res > DFSDM_DATA_MAX) |
255 | continue; |
256 | |
257 | if (res >= flo->res) { |
258 | flo->res = res; |
259 | flo->fosr = fosr; |
260 | flo->iosr = iosr; |
261 | |
262 | bits = fls(x: flo->res); |
263 | /* 8 LBSs in data register contain chan info */ |
264 | max = flo->res << 8; |
265 | |
266 | /* if resolution is not a power of two */ |
267 | if (flo->res > BIT(bits - 1)) |
268 | bits++; |
269 | else |
270 | max--; |
271 | |
272 | shift = DFSDM_DATA_RES - bits; |
273 | /* |
274 | * Compute right/left shift |
275 | * Right shift is performed by hardware |
276 | * when transferring samples to data register. |
277 | * Left shift is done by software on buffer |
278 | */ |
279 | if (shift > 0) { |
280 | /* Resolution is lower than 24 bits */ |
281 | flo->rshift = 0; |
282 | flo->lshift = shift; |
283 | } else { |
284 | /* |
285 | * If resolution is 24 bits or more, |
286 | * max positive value may be ambiguous |
287 | * (equal to max negative value as sign |
288 | * bit is dropped). |
289 | * Reduce resolution to 23 bits (rshift) |
290 | * to keep the sign on bit 23 and treat |
291 | * saturation before rescaling on 24 |
292 | * bits (lshift). |
293 | */ |
294 | flo->rshift = 1 - shift; |
295 | flo->lshift = 1; |
296 | max >>= flo->rshift; |
297 | } |
298 | flo->max = (s32)max; |
299 | flo->bits = bits; |
300 | |
301 | pr_debug("fast %d, fosr %d, iosr %d, res 0x%llx/%d bits, rshift %d, lshift %d\n", |
302 | fast, flo->fosr, flo->iosr, |
303 | flo->res, bits, flo->rshift, |
304 | flo->lshift); |
305 | } |
306 | } |
307 | } |
308 | |
309 | if (!flo->res) |
310 | return -EINVAL; |
311 | |
312 | return 0; |
313 | } |
314 | |
315 | static int stm32_dfsdm_compute_all_osrs(struct iio_dev *indio_dev, |
316 | unsigned int oversamp) |
317 | { |
318 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
319 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; |
320 | int ret0, ret1; |
321 | |
322 | memset(&fl->flo[0], 0, sizeof(fl->flo[0])); |
323 | memset(&fl->flo[1], 0, sizeof(fl->flo[1])); |
324 | |
325 | ret0 = stm32_dfsdm_compute_osrs(fl, fast: 0, oversamp); |
326 | ret1 = stm32_dfsdm_compute_osrs(fl, fast: 1, oversamp); |
327 | if (ret0 < 0 && ret1 < 0) { |
328 | dev_err(&indio_dev->dev, |
329 | "Filter parameters not found: errors %d/%d\n", |
330 | ret0, ret1); |
331 | return -EINVAL; |
332 | } |
333 | |
334 | return 0; |
335 | } |
336 | |
337 | static int stm32_dfsdm_start_channel(struct iio_dev *indio_dev) |
338 | { |
339 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
340 | struct regmap *regmap = adc->dfsdm->regmap; |
341 | const struct iio_chan_spec *chan; |
342 | unsigned int bit; |
343 | int ret; |
344 | |
345 | for_each_set_bit(bit, &adc->smask, sizeof(adc->smask) * BITS_PER_BYTE) { |
346 | chan = indio_dev->channels + bit; |
347 | ret = regmap_update_bits(map: regmap, DFSDM_CHCFGR1(chan->channel), |
348 | DFSDM_CHCFGR1_CHEN_MASK, |
349 | DFSDM_CHCFGR1_CHEN(1)); |
350 | if (ret < 0) |
351 | return ret; |
352 | } |
353 | |
354 | return 0; |
355 | } |
356 | |
357 | static void stm32_dfsdm_stop_channel(struct iio_dev *indio_dev) |
358 | { |
359 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
360 | struct regmap *regmap = adc->dfsdm->regmap; |
361 | const struct iio_chan_spec *chan; |
362 | unsigned int bit; |
363 | |
364 | for_each_set_bit(bit, &adc->smask, sizeof(adc->smask) * BITS_PER_BYTE) { |
365 | chan = indio_dev->channels + bit; |
366 | regmap_update_bits(map: regmap, DFSDM_CHCFGR1(chan->channel), |
367 | DFSDM_CHCFGR1_CHEN_MASK, |
368 | DFSDM_CHCFGR1_CHEN(0)); |
369 | } |
370 | } |
371 | |
372 | static int stm32_dfsdm_chan_configure(struct stm32_dfsdm *dfsdm, |
373 | struct stm32_dfsdm_channel *ch) |
374 | { |
375 | unsigned int id = ch->id; |
376 | struct regmap *regmap = dfsdm->regmap; |
377 | int ret; |
378 | |
379 | ret = regmap_update_bits(map: regmap, DFSDM_CHCFGR1(id), |
380 | DFSDM_CHCFGR1_SITP_MASK, |
381 | DFSDM_CHCFGR1_SITP(ch->type)); |
382 | if (ret < 0) |
383 | return ret; |
384 | ret = regmap_update_bits(map: regmap, DFSDM_CHCFGR1(id), |
385 | DFSDM_CHCFGR1_SPICKSEL_MASK, |
386 | DFSDM_CHCFGR1_SPICKSEL(ch->src)); |
387 | if (ret < 0) |
388 | return ret; |
389 | return regmap_update_bits(map: regmap, DFSDM_CHCFGR1(id), |
390 | DFSDM_CHCFGR1_CHINSEL_MASK, |
391 | DFSDM_CHCFGR1_CHINSEL(ch->alt_si)); |
392 | } |
393 | |
394 | static int stm32_dfsdm_start_filter(struct stm32_dfsdm_adc *adc, |
395 | unsigned int fl_id, |
396 | struct iio_trigger *trig) |
397 | { |
398 | struct stm32_dfsdm *dfsdm = adc->dfsdm; |
399 | int ret; |
400 | |
401 | /* Enable filter */ |
402 | ret = regmap_update_bits(map: dfsdm->regmap, DFSDM_CR1(fl_id), |
403 | DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(1)); |
404 | if (ret < 0) |
405 | return ret; |
406 | |
407 | /* Nothing more to do for injected (scan mode/triggered) conversions */ |
408 | if (adc->nconv > 1 || trig) |
409 | return 0; |
410 | |
411 | /* Software start (single or continuous) regular conversion */ |
412 | return regmap_update_bits(map: dfsdm->regmap, DFSDM_CR1(fl_id), |
413 | DFSDM_CR1_RSWSTART_MASK, |
414 | DFSDM_CR1_RSWSTART(1)); |
415 | } |
416 | |
417 | static void stm32_dfsdm_stop_filter(struct stm32_dfsdm *dfsdm, |
418 | unsigned int fl_id) |
419 | { |
420 | /* Disable conversion */ |
421 | regmap_update_bits(map: dfsdm->regmap, DFSDM_CR1(fl_id), |
422 | DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(0)); |
423 | } |
424 | |
425 | static int stm32_dfsdm_filter_set_trig(struct iio_dev *indio_dev, |
426 | unsigned int fl_id, |
427 | struct iio_trigger *trig) |
428 | { |
429 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
430 | struct regmap *regmap = adc->dfsdm->regmap; |
431 | u32 jextsel = 0, jexten = STM32_DFSDM_JEXTEN_DISABLED; |
432 | int ret; |
433 | |
434 | if (trig) { |
435 | ret = stm32_dfsdm_get_jextsel(indio_dev, trig); |
436 | if (ret < 0) |
437 | return ret; |
438 | |
439 | /* set trigger source and polarity (default to rising edge) */ |
440 | jextsel = ret; |
441 | jexten = STM32_DFSDM_JEXTEN_RISING_EDGE; |
442 | } |
443 | |
444 | ret = regmap_update_bits(map: regmap, DFSDM_CR1(fl_id), |
445 | DFSDM_CR1_JEXTSEL_MASK | DFSDM_CR1_JEXTEN_MASK, |
446 | DFSDM_CR1_JEXTSEL(jextsel) | |
447 | DFSDM_CR1_JEXTEN(jexten)); |
448 | if (ret < 0) |
449 | return ret; |
450 | |
451 | return 0; |
452 | } |
453 | |
454 | static int stm32_dfsdm_channels_configure(struct iio_dev *indio_dev, |
455 | unsigned int fl_id, |
456 | struct iio_trigger *trig) |
457 | { |
458 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
459 | struct regmap *regmap = adc->dfsdm->regmap; |
460 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id]; |
461 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[0]; |
462 | const struct iio_chan_spec *chan; |
463 | unsigned int bit; |
464 | int ret; |
465 | |
466 | fl->fast = 0; |
467 | |
468 | /* |
469 | * In continuous mode, use fast mode configuration, |
470 | * if it provides a better resolution. |
471 | */ |
472 | if (adc->nconv == 1 && !trig && iio_buffer_enabled(indio_dev)) { |
473 | if (fl->flo[1].res >= fl->flo[0].res) { |
474 | fl->fast = 1; |
475 | flo = &fl->flo[1]; |
476 | } |
477 | } |
478 | |
479 | if (!flo->res) |
480 | return -EINVAL; |
481 | |
482 | dev_dbg(&indio_dev->dev, "Samples actual resolution: %d bits", |
483 | min(flo->bits, (u32)DFSDM_DATA_RES - 1)); |
484 | |
485 | for_each_set_bit(bit, &adc->smask, |
486 | sizeof(adc->smask) * BITS_PER_BYTE) { |
487 | chan = indio_dev->channels + bit; |
488 | |
489 | ret = regmap_update_bits(map: regmap, |
490 | DFSDM_CHCFGR2(chan->channel), |
491 | DFSDM_CHCFGR2_DTRBS_MASK, |
492 | DFSDM_CHCFGR2_DTRBS(flo->rshift)); |
493 | if (ret) |
494 | return ret; |
495 | } |
496 | |
497 | return 0; |
498 | } |
499 | |
500 | static int stm32_dfsdm_filter_configure(struct iio_dev *indio_dev, |
501 | unsigned int fl_id, |
502 | struct iio_trigger *trig) |
503 | { |
504 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
505 | struct regmap *regmap = adc->dfsdm->regmap; |
506 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id]; |
507 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast]; |
508 | u32 cr1; |
509 | const struct iio_chan_spec *chan; |
510 | unsigned int bit, jchg = 0; |
511 | int ret; |
512 | |
513 | /* Average integrator oversampling */ |
514 | ret = regmap_update_bits(map: regmap, DFSDM_FCR(fl_id), DFSDM_FCR_IOSR_MASK, |
515 | DFSDM_FCR_IOSR(flo->iosr - 1)); |
516 | if (ret) |
517 | return ret; |
518 | |
519 | /* Filter order and Oversampling */ |
520 | ret = regmap_update_bits(map: regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FOSR_MASK, |
521 | DFSDM_FCR_FOSR(flo->fosr - 1)); |
522 | if (ret) |
523 | return ret; |
524 | |
525 | ret = regmap_update_bits(map: regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FORD_MASK, |
526 | DFSDM_FCR_FORD(fl->ford)); |
527 | if (ret) |
528 | return ret; |
529 | |
530 | ret = stm32_dfsdm_filter_set_trig(indio_dev, fl_id, trig); |
531 | if (ret) |
532 | return ret; |
533 | |
534 | ret = regmap_update_bits(map: regmap, DFSDM_CR1(fl_id), |
535 | DFSDM_CR1_FAST_MASK, |
536 | DFSDM_CR1_FAST(fl->fast)); |
537 | if (ret) |
538 | return ret; |
539 | |
540 | /* |
541 | * DFSDM modes configuration W.R.T audio/iio type modes |
542 | * ---------------------------------------------------------------- |
543 | * Modes | regular | regular | injected | injected | |
544 | * | | continuous | | + scan | |
545 | * --------------|---------|--------------|----------|------------| |
546 | * single conv | x | | | | |
547 | * (1 chan) | | | | | |
548 | * --------------|---------|--------------|----------|------------| |
549 | * 1 Audio chan | | sample freq | | | |
550 | * | | or sync_mode | | | |
551 | * --------------|---------|--------------|----------|------------| |
552 | * 1 IIO chan | | sample freq | trigger | | |
553 | * | | or sync_mode | | | |
554 | * --------------|---------|--------------|----------|------------| |
555 | * 2+ IIO chans | | | | trigger or | |
556 | * | | | | sync_mode | |
557 | * ---------------------------------------------------------------- |
558 | */ |
559 | if (adc->nconv == 1 && !trig) { |
560 | bit = __ffs(adc->smask); |
561 | chan = indio_dev->channels + bit; |
562 | |
563 | /* Use regular conversion for single channel without trigger */ |
564 | cr1 = DFSDM_CR1_RCH(chan->channel); |
565 | |
566 | /* Continuous conversions triggered by SPI clk in buffer mode */ |
567 | if (iio_buffer_enabled(indio_dev)) |
568 | cr1 |= DFSDM_CR1_RCONT(1); |
569 | |
570 | cr1 |= DFSDM_CR1_RSYNC(fl->sync_mode); |
571 | } else { |
572 | /* Use injected conversion for multiple channels */ |
573 | for_each_set_bit(bit, &adc->smask, |
574 | sizeof(adc->smask) * BITS_PER_BYTE) { |
575 | chan = indio_dev->channels + bit; |
576 | jchg |= BIT(chan->channel); |
577 | } |
578 | ret = regmap_write(map: regmap, DFSDM_JCHGR(fl_id), val: jchg); |
579 | if (ret < 0) |
580 | return ret; |
581 | |
582 | /* Use scan mode for multiple channels */ |
583 | cr1 = DFSDM_CR1_JSCAN((adc->nconv > 1) ? 1 : 0); |
584 | |
585 | /* |
586 | * Continuous conversions not supported in injected mode, |
587 | * either use: |
588 | * - conversions in sync with filter 0 |
589 | * - triggered conversions |
590 | */ |
591 | if (!fl->sync_mode && !trig) |
592 | return -EINVAL; |
593 | cr1 |= DFSDM_CR1_JSYNC(fl->sync_mode); |
594 | } |
595 | |
596 | return regmap_update_bits(map: regmap, DFSDM_CR1(fl_id), DFSDM_CR1_CFG_MASK, |
597 | val: cr1); |
598 | } |
599 | |
600 | static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm, |
601 | struct iio_dev *indio_dev, |
602 | struct iio_chan_spec *ch) |
603 | { |
604 | struct stm32_dfsdm_channel *df_ch; |
605 | const char *of_str; |
606 | int chan_idx = ch->scan_index; |
607 | int ret, val; |
608 | |
609 | ret = of_property_read_u32_index(np: indio_dev->dev.of_node, |
610 | propname: "st,adc-channels", index: chan_idx, |
611 | out_value: &ch->channel); |
612 | if (ret < 0) { |
613 | dev_err(&indio_dev->dev, |
614 | " Error parsing 'st,adc-channels' for idx %d\n", |
615 | chan_idx); |
616 | return ret; |
617 | } |
618 | if (ch->channel >= dfsdm->num_chs) { |
619 | dev_err(&indio_dev->dev, |
620 | " Error bad channel number %d (max = %d)\n", |
621 | ch->channel, dfsdm->num_chs); |
622 | return -EINVAL; |
623 | } |
624 | |
625 | ret = of_property_read_string_index(np: indio_dev->dev.of_node, |
626 | propname: "st,adc-channel-names", index: chan_idx, |
627 | output: &ch->datasheet_name); |
628 | if (ret < 0) { |
629 | dev_err(&indio_dev->dev, |
630 | " Error parsing 'st,adc-channel-names' for idx %d\n", |
631 | chan_idx); |
632 | return ret; |
633 | } |
634 | |
635 | df_ch = &dfsdm->ch_list[ch->channel]; |
636 | df_ch->id = ch->channel; |
637 | |
638 | ret = of_property_read_string_index(np: indio_dev->dev.of_node, |
639 | propname: "st,adc-channel-types", index: chan_idx, |
640 | output: &of_str); |
641 | if (!ret) { |
642 | val = stm32_dfsdm_str2val(str: of_str, list: stm32_dfsdm_chan_type); |
643 | if (val < 0) |
644 | return val; |
645 | } else { |
646 | val = 0; |
647 | } |
648 | df_ch->type = val; |
649 | |
650 | ret = of_property_read_string_index(np: indio_dev->dev.of_node, |
651 | propname: "st,adc-channel-clk-src", index: chan_idx, |
652 | output: &of_str); |
653 | if (!ret) { |
654 | val = stm32_dfsdm_str2val(str: of_str, list: stm32_dfsdm_chan_src); |
655 | if (val < 0) |
656 | return val; |
657 | } else { |
658 | val = 0; |
659 | } |
660 | df_ch->src = val; |
661 | |
662 | ret = of_property_read_u32_index(np: indio_dev->dev.of_node, |
663 | propname: "st,adc-alt-channel", index: chan_idx, |
664 | out_value: &df_ch->alt_si); |
665 | if (ret < 0) |
666 | df_ch->alt_si = 0; |
667 | |
668 | return 0; |
669 | } |
670 | |
671 | static int stm32_dfsdm_generic_channel_parse_of(struct stm32_dfsdm *dfsdm, |
672 | struct iio_dev *indio_dev, |
673 | struct iio_chan_spec *ch, |
674 | struct fwnode_handle *node) |
675 | { |
676 | struct stm32_dfsdm_channel *df_ch; |
677 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
678 | struct iio_backend *backend; |
679 | const char *of_str; |
680 | int ret, val; |
681 | |
682 | ret = fwnode_property_read_u32(fwnode: node, propname: "reg", val: &ch->channel); |
683 | if (ret < 0) { |
684 | dev_err(&indio_dev->dev, "Missing channel index %d\n", ret); |
685 | return ret; |
686 | } |
687 | |
688 | if (ch->channel >= dfsdm->num_chs) { |
689 | dev_err(&indio_dev->dev, " Error bad channel number %d (max = %d)\n", |
690 | ch->channel, dfsdm->num_chs); |
691 | return -EINVAL; |
692 | } |
693 | |
694 | if (fwnode_property_present(fwnode: node, propname: "label")) { |
695 | /* label is optional */ |
696 | ret = fwnode_property_read_string(fwnode: node, propname: "label", val: &ch->datasheet_name); |
697 | if (ret < 0) { |
698 | dev_err(&indio_dev->dev, |
699 | " Error parsing 'label' for idx %d\n", ch->channel); |
700 | return ret; |
701 | } |
702 | } |
703 | |
704 | df_ch = &dfsdm->ch_list[ch->channel]; |
705 | df_ch->id = ch->channel; |
706 | |
707 | ret = fwnode_property_read_string(fwnode: node, propname: "st,adc-channel-type", val: &of_str); |
708 | if (!ret) { |
709 | val = stm32_dfsdm_str2val(str: of_str, list: stm32_dfsdm_chan_type); |
710 | if (val < 0) |
711 | return val; |
712 | } else { |
713 | val = 0; |
714 | } |
715 | df_ch->type = val; |
716 | |
717 | ret = fwnode_property_read_string(fwnode: node, propname: "st,adc-channel-clk-src", val: &of_str); |
718 | if (!ret) { |
719 | val = stm32_dfsdm_str2val(str: of_str, list: stm32_dfsdm_chan_src); |
720 | if (val < 0) |
721 | return val; |
722 | } else { |
723 | val = 0; |
724 | } |
725 | df_ch->src = val; |
726 | |
727 | ret = fwnode_property_read_u32(fwnode: node, propname: "st,adc-alt-channel", val: &df_ch->alt_si); |
728 | if (ret != -EINVAL) |
729 | df_ch->alt_si = 0; |
730 | |
731 | if (adc->dev_data->type == DFSDM_IIO) { |
732 | backend = devm_iio_backend_fwnode_get(dev: &indio_dev->dev, NULL, fwnode: node); |
733 | if (IS_ERR(ptr: backend)) |
734 | return dev_err_probe(dev: &indio_dev->dev, err: PTR_ERR(ptr: backend), |
735 | fmt: "Failed to get backend\n"); |
736 | adc->backend[ch->scan_index] = backend; |
737 | } |
738 | |
739 | return 0; |
740 | } |
741 | |
742 | static ssize_t dfsdm_adc_audio_get_spiclk(struct iio_dev *indio_dev, |
743 | uintptr_t priv, |
744 | const struct iio_chan_spec *chan, |
745 | char *buf) |
746 | { |
747 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
748 | |
749 | return snprintf(buf, PAGE_SIZE, fmt: "%d\n", adc->spi_freq); |
750 | } |
751 | |
752 | static int dfsdm_adc_set_samp_freq(struct iio_dev *indio_dev, |
753 | unsigned int sample_freq, |
754 | unsigned int spi_freq) |
755 | { |
756 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
757 | unsigned int oversamp; |
758 | int ret; |
759 | |
760 | oversamp = DIV_ROUND_CLOSEST(spi_freq, sample_freq); |
761 | if (spi_freq % sample_freq) |
762 | dev_dbg(&indio_dev->dev, |
763 | "Rate not accurate. requested (%u), actual (%u)\n", |
764 | sample_freq, spi_freq / oversamp); |
765 | |
766 | ret = stm32_dfsdm_compute_all_osrs(indio_dev, oversamp); |
767 | if (ret < 0) |
768 | return ret; |
769 | |
770 | adc->sample_freq = spi_freq / oversamp; |
771 | adc->oversamp = oversamp; |
772 | |
773 | return 0; |
774 | } |
775 | |
776 | static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev, |
777 | uintptr_t priv, |
778 | const struct iio_chan_spec *chan, |
779 | const char *buf, size_t len) |
780 | { |
781 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
782 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; |
783 | unsigned int sample_freq = adc->sample_freq; |
784 | unsigned int spi_freq; |
785 | int ret; |
786 | |
787 | dev_err(&indio_dev->dev, "enter %s\n", __func__); |
788 | /* If DFSDM is master on SPI, SPI freq can not be updated */ |
789 | if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) |
790 | return -EPERM; |
791 | |
792 | ret = kstrtoint(s: buf, base: 0, res: &spi_freq); |
793 | if (ret) |
794 | return ret; |
795 | |
796 | if (!spi_freq) |
797 | return -EINVAL; |
798 | |
799 | if (sample_freq) { |
800 | ret = dfsdm_adc_set_samp_freq(indio_dev, sample_freq, spi_freq); |
801 | if (ret < 0) |
802 | return ret; |
803 | } |
804 | adc->spi_freq = spi_freq; |
805 | |
806 | return len; |
807 | } |
808 | |
809 | static int stm32_dfsdm_start_conv(struct iio_dev *indio_dev, |
810 | struct iio_trigger *trig) |
811 | { |
812 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
813 | struct regmap *regmap = adc->dfsdm->regmap; |
814 | int ret; |
815 | |
816 | ret = stm32_dfsdm_channels_configure(indio_dev, fl_id: adc->fl_id, trig); |
817 | if (ret < 0) |
818 | return ret; |
819 | |
820 | ret = stm32_dfsdm_start_channel(indio_dev); |
821 | if (ret < 0) |
822 | return ret; |
823 | |
824 | ret = stm32_dfsdm_filter_configure(indio_dev, fl_id: adc->fl_id, trig); |
825 | if (ret < 0) |
826 | goto stop_channels; |
827 | |
828 | ret = stm32_dfsdm_start_filter(adc, fl_id: adc->fl_id, trig); |
829 | if (ret < 0) |
830 | goto filter_unconfigure; |
831 | |
832 | return 0; |
833 | |
834 | filter_unconfigure: |
835 | regmap_clear_bits(map: regmap, DFSDM_CR1(adc->fl_id), DFSDM_CR1_CFG_MASK); |
836 | stop_channels: |
837 | stm32_dfsdm_stop_channel(indio_dev); |
838 | |
839 | return ret; |
840 | } |
841 | |
842 | static void stm32_dfsdm_stop_conv(struct iio_dev *indio_dev) |
843 | { |
844 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
845 | struct regmap *regmap = adc->dfsdm->regmap; |
846 | |
847 | stm32_dfsdm_stop_filter(dfsdm: adc->dfsdm, fl_id: adc->fl_id); |
848 | |
849 | regmap_clear_bits(map: regmap, DFSDM_CR1(adc->fl_id), DFSDM_CR1_CFG_MASK); |
850 | |
851 | stm32_dfsdm_stop_channel(indio_dev); |
852 | } |
853 | |
854 | static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev, |
855 | unsigned int val) |
856 | { |
857 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
858 | unsigned int watermark = DFSDM_DMA_BUFFER_SIZE / 2; |
859 | unsigned int rx_buf_sz = DFSDM_DMA_BUFFER_SIZE; |
860 | |
861 | /* |
862 | * DMA cyclic transfers are used, buffer is split into two periods. |
863 | * There should be : |
864 | * - always one buffer (period) DMA is working on |
865 | * - one buffer (period) driver pushed to ASoC side. |
866 | */ |
867 | watermark = min(watermark, val * (unsigned int)(sizeof(u32))); |
868 | adc->buf_sz = min(rx_buf_sz, watermark * 2 * adc->nconv); |
869 | |
870 | return 0; |
871 | } |
872 | |
873 | static unsigned int stm32_dfsdm_adc_dma_residue(struct stm32_dfsdm_adc *adc) |
874 | { |
875 | struct dma_tx_state state; |
876 | enum dma_status status; |
877 | |
878 | status = dmaengine_tx_status(chan: adc->dma_chan, |
879 | cookie: adc->dma_chan->cookie, |
880 | state: &state); |
881 | if (status == DMA_IN_PROGRESS) { |
882 | /* Residue is size in bytes from end of buffer */ |
883 | unsigned int i = adc->buf_sz - state.residue; |
884 | unsigned int size; |
885 | |
886 | /* Return available bytes */ |
887 | if (i >= adc->bufi) |
888 | size = i - adc->bufi; |
889 | else |
890 | size = adc->buf_sz + i - adc->bufi; |
891 | |
892 | return size; |
893 | } |
894 | |
895 | return 0; |
896 | } |
897 | |
898 | static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc, |
899 | s32 *buffer) |
900 | { |
901 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; |
902 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast]; |
903 | unsigned int i = adc->nconv; |
904 | s32 *ptr = buffer; |
905 | |
906 | while (i--) { |
907 | /* Mask 8 LSB that contains the channel ID */ |
908 | *ptr &= 0xFFFFFF00; |
909 | /* Convert 2^(n-1) sample to 2^(n-1)-1 to avoid wrap-around */ |
910 | if (*ptr > flo->max) |
911 | *ptr -= 1; |
912 | /* |
913 | * Samples from filter are retrieved with 23 bits resolution |
914 | * or less. Shift left to align MSB on 24 bits. |
915 | */ |
916 | *ptr <<= flo->lshift; |
917 | |
918 | ptr++; |
919 | } |
920 | } |
921 | |
922 | static void stm32_dfsdm_dma_buffer_done(void *data) |
923 | { |
924 | struct iio_dev *indio_dev = data; |
925 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
926 | int available = stm32_dfsdm_adc_dma_residue(adc); |
927 | size_t old_pos; |
928 | |
929 | /* |
930 | * FIXME: In Kernel interface does not support cyclic DMA buffer,and |
931 | * offers only an interface to push data samples per samples. |
932 | * For this reason IIO buffer interface is not used and interface is |
933 | * bypassed using a private callback registered by ASoC. |
934 | * This should be a temporary solution waiting a cyclic DMA engine |
935 | * support in IIO. |
936 | */ |
937 | |
938 | dev_dbg(&indio_dev->dev, "pos = %d, available = %d\n", |
939 | adc->bufi, available); |
940 | old_pos = adc->bufi; |
941 | |
942 | while (available >= indio_dev->scan_bytes) { |
943 | s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi]; |
944 | |
945 | stm32_dfsdm_process_data(adc, buffer); |
946 | |
947 | available -= indio_dev->scan_bytes; |
948 | adc->bufi += indio_dev->scan_bytes; |
949 | if (adc->bufi >= adc->buf_sz) { |
950 | if (adc->cb) |
951 | adc->cb(&adc->rx_buf[old_pos], |
952 | adc->buf_sz - old_pos, adc->cb_priv); |
953 | adc->bufi = 0; |
954 | old_pos = 0; |
955 | } |
956 | /* |
957 | * In DMA mode the trigger services of IIO are not used |
958 | * (e.g. no call to iio_trigger_poll). |
959 | * Calling irq handler associated to the hardware trigger is not |
960 | * relevant as the conversions have already been done. Data |
961 | * transfers are performed directly in DMA callback instead. |
962 | * This implementation avoids to call trigger irq handler that |
963 | * may sleep, in an atomic context (DMA irq handler context). |
964 | */ |
965 | if (adc->dev_data->type == DFSDM_IIO) |
966 | iio_push_to_buffers(indio_dev, data: buffer); |
967 | } |
968 | if (adc->cb) |
969 | adc->cb(&adc->rx_buf[old_pos], adc->bufi - old_pos, |
970 | adc->cb_priv); |
971 | } |
972 | |
973 | static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev) |
974 | { |
975 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
976 | /* |
977 | * The DFSDM supports half-word transfers. However, for 16 bits record, |
978 | * 4 bytes buswidth is kept, to avoid losing samples LSBs when left |
979 | * shift is required. |
980 | */ |
981 | struct dma_slave_config config = { |
982 | .src_addr = (dma_addr_t)adc->dfsdm->phys_base, |
983 | .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, |
984 | }; |
985 | struct dma_async_tx_descriptor *desc; |
986 | dma_cookie_t cookie; |
987 | int ret; |
988 | |
989 | if (!adc->dma_chan) |
990 | return -EINVAL; |
991 | |
992 | dev_dbg(&indio_dev->dev, "size=%d watermark=%d\n", |
993 | adc->buf_sz, adc->buf_sz / 2); |
994 | |
995 | if (adc->nconv == 1 && !indio_dev->trig) |
996 | config.src_addr += DFSDM_RDATAR(adc->fl_id); |
997 | else |
998 | config.src_addr += DFSDM_JDATAR(adc->fl_id); |
999 | ret = dmaengine_slave_config(chan: adc->dma_chan, config: &config); |
1000 | if (ret) |
1001 | return ret; |
1002 | |
1003 | /* Prepare a DMA cyclic transaction */ |
1004 | desc = dmaengine_prep_dma_cyclic(chan: adc->dma_chan, |
1005 | buf_addr: adc->dma_buf, |
1006 | buf_len: adc->buf_sz, period_len: adc->buf_sz / 2, |
1007 | dir: DMA_DEV_TO_MEM, |
1008 | flags: DMA_PREP_INTERRUPT); |
1009 | if (!desc) |
1010 | return -EBUSY; |
1011 | |
1012 | desc->callback = stm32_dfsdm_dma_buffer_done; |
1013 | desc->callback_param = indio_dev; |
1014 | |
1015 | cookie = dmaengine_submit(desc); |
1016 | ret = dma_submit_error(cookie); |
1017 | if (ret) |
1018 | goto err_stop_dma; |
1019 | |
1020 | /* Issue pending DMA requests */ |
1021 | dma_async_issue_pending(chan: adc->dma_chan); |
1022 | |
1023 | if (adc->nconv == 1 && !indio_dev->trig) { |
1024 | /* Enable regular DMA transfer*/ |
1025 | ret = regmap_set_bits(map: adc->dfsdm->regmap, |
1026 | DFSDM_CR1(adc->fl_id), |
1027 | DFSDM_CR1_RDMAEN_MASK); |
1028 | } else { |
1029 | /* Enable injected DMA transfer*/ |
1030 | ret = regmap_set_bits(map: adc->dfsdm->regmap, |
1031 | DFSDM_CR1(adc->fl_id), |
1032 | DFSDM_CR1_JDMAEN_MASK); |
1033 | } |
1034 | |
1035 | if (ret < 0) |
1036 | goto err_stop_dma; |
1037 | |
1038 | return 0; |
1039 | |
1040 | err_stop_dma: |
1041 | dmaengine_terminate_all(chan: adc->dma_chan); |
1042 | |
1043 | return ret; |
1044 | } |
1045 | |
1046 | static void stm32_dfsdm_adc_dma_stop(struct iio_dev *indio_dev) |
1047 | { |
1048 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1049 | |
1050 | if (!adc->dma_chan) |
1051 | return; |
1052 | |
1053 | regmap_clear_bits(map: adc->dfsdm->regmap, DFSDM_CR1(adc->fl_id), |
1054 | DFSDM_CR1_RDMAEN_MASK | DFSDM_CR1_JDMAEN_MASK); |
1055 | dmaengine_terminate_all(chan: adc->dma_chan); |
1056 | } |
1057 | |
1058 | static int stm32_dfsdm_update_scan_mode(struct iio_dev *indio_dev, |
1059 | const unsigned long *scan_mask) |
1060 | { |
1061 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1062 | |
1063 | adc->nconv = bitmap_weight(src: scan_mask, nbits: iio_get_masklength(indio_dev)); |
1064 | adc->smask = *scan_mask; |
1065 | |
1066 | dev_dbg(&indio_dev->dev, "nconv=%d mask=%lx\n", adc->nconv, *scan_mask); |
1067 | |
1068 | return 0; |
1069 | } |
1070 | |
1071 | static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) |
1072 | { |
1073 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1074 | int i = 0; |
1075 | int ret; |
1076 | |
1077 | /* Reset adc buffer index */ |
1078 | adc->bufi = 0; |
1079 | |
1080 | if (adc->hwc) { |
1081 | ret = iio_hw_consumer_enable(hwc: adc->hwc); |
1082 | if (ret < 0) |
1083 | return ret; |
1084 | } |
1085 | |
1086 | if (adc->backend) { |
1087 | while (adc->backend[i]) { |
1088 | ret = iio_backend_enable(back: adc->backend[i]); |
1089 | if (ret < 0) |
1090 | return ret; |
1091 | i++; |
1092 | } |
1093 | } |
1094 | |
1095 | ret = stm32_dfsdm_start_dfsdm(dfsdm: adc->dfsdm); |
1096 | if (ret < 0) |
1097 | goto err_stop_hwc; |
1098 | |
1099 | ret = stm32_dfsdm_adc_dma_start(indio_dev); |
1100 | if (ret) { |
1101 | dev_err(&indio_dev->dev, "Can't start DMA\n"); |
1102 | goto stop_dfsdm; |
1103 | } |
1104 | |
1105 | ret = stm32_dfsdm_start_conv(indio_dev, trig: indio_dev->trig); |
1106 | if (ret) { |
1107 | dev_err(&indio_dev->dev, "Can't start conversion\n"); |
1108 | goto err_stop_dma; |
1109 | } |
1110 | |
1111 | return 0; |
1112 | |
1113 | err_stop_dma: |
1114 | stm32_dfsdm_adc_dma_stop(indio_dev); |
1115 | stop_dfsdm: |
1116 | stm32_dfsdm_stop_dfsdm(dfsdm: adc->dfsdm); |
1117 | err_stop_hwc: |
1118 | if (adc->hwc) |
1119 | iio_hw_consumer_disable(hwc: adc->hwc); |
1120 | |
1121 | return ret; |
1122 | } |
1123 | |
1124 | static int stm32_dfsdm_predisable(struct iio_dev *indio_dev) |
1125 | { |
1126 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1127 | int i = 0; |
1128 | |
1129 | stm32_dfsdm_stop_conv(indio_dev); |
1130 | |
1131 | stm32_dfsdm_adc_dma_stop(indio_dev); |
1132 | |
1133 | stm32_dfsdm_stop_dfsdm(dfsdm: adc->dfsdm); |
1134 | |
1135 | if (adc->backend) { |
1136 | while (adc->backend[i]) { |
1137 | iio_backend_disable(back: adc->backend[i]); |
1138 | i++; |
1139 | } |
1140 | } |
1141 | |
1142 | if (adc->hwc) |
1143 | iio_hw_consumer_disable(hwc: adc->hwc); |
1144 | |
1145 | return 0; |
1146 | } |
1147 | |
1148 | static const struct iio_buffer_setup_ops stm32_dfsdm_buffer_setup_ops = { |
1149 | .postenable = &stm32_dfsdm_postenable, |
1150 | .predisable = &stm32_dfsdm_predisable, |
1151 | }; |
1152 | |
1153 | /** |
1154 | * stm32_dfsdm_get_buff_cb() - register a callback that will be called when |
1155 | * DMA transfer period is achieved. |
1156 | * |
1157 | * @iio_dev: Handle to IIO device. |
1158 | * @cb: Pointer to callback function: |
1159 | * - data: pointer to data buffer |
1160 | * - size: size in byte of the data buffer |
1161 | * - private: pointer to consumer private structure. |
1162 | * @private: Pointer to consumer private structure. |
1163 | */ |
1164 | int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev, |
1165 | int (*cb)(const void *data, size_t size, |
1166 | void *private), |
1167 | void *private) |
1168 | { |
1169 | struct stm32_dfsdm_adc *adc; |
1170 | |
1171 | if (!iio_dev) |
1172 | return -EINVAL; |
1173 | adc = iio_priv(indio_dev: iio_dev); |
1174 | |
1175 | adc->cb = cb; |
1176 | adc->cb_priv = private; |
1177 | |
1178 | return 0; |
1179 | } |
1180 | EXPORT_SYMBOL_GPL(stm32_dfsdm_get_buff_cb); |
1181 | |
1182 | /** |
1183 | * stm32_dfsdm_release_buff_cb - unregister buffer callback |
1184 | * |
1185 | * @iio_dev: Handle to IIO device. |
1186 | */ |
1187 | int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev) |
1188 | { |
1189 | struct stm32_dfsdm_adc *adc; |
1190 | |
1191 | if (!iio_dev) |
1192 | return -EINVAL; |
1193 | adc = iio_priv(indio_dev: iio_dev); |
1194 | |
1195 | adc->cb = NULL; |
1196 | adc->cb_priv = NULL; |
1197 | |
1198 | return 0; |
1199 | } |
1200 | EXPORT_SYMBOL_GPL(stm32_dfsdm_release_buff_cb); |
1201 | |
1202 | static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev, |
1203 | const struct iio_chan_spec *chan, int *res) |
1204 | { |
1205 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1206 | long time_left; |
1207 | int ret; |
1208 | |
1209 | reinit_completion(x: &adc->completion); |
1210 | |
1211 | adc->buffer = res; |
1212 | |
1213 | ret = stm32_dfsdm_start_dfsdm(dfsdm: adc->dfsdm); |
1214 | if (ret < 0) |
1215 | return ret; |
1216 | |
1217 | ret = regmap_update_bits(map: adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), |
1218 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(1)); |
1219 | if (ret < 0) |
1220 | goto stop_dfsdm; |
1221 | |
1222 | adc->nconv = 1; |
1223 | adc->smask = BIT(chan->scan_index); |
1224 | ret = stm32_dfsdm_start_conv(indio_dev, NULL); |
1225 | if (ret < 0) { |
1226 | regmap_update_bits(map: adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), |
1227 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); |
1228 | goto stop_dfsdm; |
1229 | } |
1230 | |
1231 | time_left = wait_for_completion_interruptible_timeout(x: &adc->completion, |
1232 | DFSDM_TIMEOUT); |
1233 | |
1234 | /* Mask IRQ for regular conversion achievement*/ |
1235 | regmap_update_bits(map: adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), |
1236 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); |
1237 | |
1238 | if (time_left == 0) |
1239 | ret = -ETIMEDOUT; |
1240 | else if (time_left < 0) |
1241 | ret = time_left; |
1242 | else |
1243 | ret = IIO_VAL_INT; |
1244 | |
1245 | stm32_dfsdm_stop_conv(indio_dev); |
1246 | |
1247 | stm32_dfsdm_process_data(adc, buffer: res); |
1248 | |
1249 | stop_dfsdm: |
1250 | stm32_dfsdm_stop_dfsdm(dfsdm: adc->dfsdm); |
1251 | |
1252 | return ret; |
1253 | } |
1254 | |
1255 | static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev, |
1256 | struct iio_chan_spec const *chan, |
1257 | int val, int val2, long mask) |
1258 | { |
1259 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1260 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; |
1261 | unsigned int spi_freq; |
1262 | int ret = -EINVAL; |
1263 | |
1264 | switch (ch->src) { |
1265 | case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL: |
1266 | spi_freq = adc->dfsdm->spi_master_freq; |
1267 | break; |
1268 | case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING: |
1269 | case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING: |
1270 | spi_freq = adc->dfsdm->spi_master_freq / 2; |
1271 | break; |
1272 | default: |
1273 | spi_freq = adc->spi_freq; |
1274 | } |
1275 | |
1276 | switch (mask) { |
1277 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
1278 | if (!iio_device_claim_direct(indio_dev)) |
1279 | return -EBUSY; |
1280 | |
1281 | ret = stm32_dfsdm_compute_all_osrs(indio_dev, oversamp: val); |
1282 | if (!ret) { |
1283 | dev_dbg(&indio_dev->dev, |
1284 | "Sampling rate changed from (%u) to (%u)\n", |
1285 | adc->sample_freq, spi_freq / val); |
1286 | adc->oversamp = val; |
1287 | adc->sample_freq = spi_freq / val; |
1288 | } |
1289 | iio_device_release_direct(indio_dev); |
1290 | return ret; |
1291 | |
1292 | case IIO_CHAN_INFO_SAMP_FREQ: |
1293 | if (!val) |
1294 | return -EINVAL; |
1295 | |
1296 | if (!iio_device_claim_direct(indio_dev)) |
1297 | return -EBUSY; |
1298 | |
1299 | ret = dfsdm_adc_set_samp_freq(indio_dev, sample_freq: val, spi_freq); |
1300 | iio_device_release_direct(indio_dev); |
1301 | return ret; |
1302 | } |
1303 | |
1304 | return -EINVAL; |
1305 | } |
1306 | |
1307 | static int __stm32_dfsdm_read_info_raw(struct iio_dev *indio_dev, |
1308 | struct iio_chan_spec const *chan, |
1309 | int *val) |
1310 | { |
1311 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1312 | int ret = 0; |
1313 | |
1314 | if (adc->hwc) |
1315 | ret = iio_hw_consumer_enable(hwc: adc->hwc); |
1316 | if (adc->backend) |
1317 | ret = iio_backend_enable(back: adc->backend[chan->scan_index]); |
1318 | if (ret < 0) { |
1319 | dev_err(&indio_dev->dev, |
1320 | "%s: IIO enable failed (channel %d)\n", |
1321 | __func__, chan->channel); |
1322 | return ret; |
1323 | } |
1324 | ret = stm32_dfsdm_single_conv(indio_dev, chan, res: val); |
1325 | if (adc->hwc) |
1326 | iio_hw_consumer_disable(hwc: adc->hwc); |
1327 | if (adc->backend) |
1328 | iio_backend_disable(back: adc->backend[chan->scan_index]); |
1329 | if (ret < 0) { |
1330 | dev_err(&indio_dev->dev, |
1331 | "%s: Conversion failed (channel %d)\n", |
1332 | __func__, chan->channel); |
1333 | return ret; |
1334 | } |
1335 | |
1336 | return 0; |
1337 | } |
1338 | |
1339 | static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev, |
1340 | struct iio_chan_spec const *chan, int *val, |
1341 | int *val2, long mask) |
1342 | { |
1343 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1344 | |
1345 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; |
1346 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast]; |
1347 | u32 max = flo->max << (flo->lshift - chan->scan_type.shift); |
1348 | int idx = chan->scan_index; |
1349 | int ret; |
1350 | |
1351 | if (flo->lshift < chan->scan_type.shift) |
1352 | max = flo->max >> (chan->scan_type.shift - flo->lshift); |
1353 | |
1354 | switch (mask) { |
1355 | case IIO_CHAN_INFO_RAW: |
1356 | if (!iio_device_claim_direct(indio_dev)) |
1357 | return -EBUSY; |
1358 | |
1359 | ret = __stm32_dfsdm_read_info_raw(indio_dev, chan, val); |
1360 | iio_device_release_direct(indio_dev); |
1361 | if (ret) |
1362 | return ret; |
1363 | return IIO_VAL_INT; |
1364 | |
1365 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
1366 | *val = adc->oversamp; |
1367 | |
1368 | return IIO_VAL_INT; |
1369 | |
1370 | case IIO_CHAN_INFO_SAMP_FREQ: |
1371 | *val = adc->sample_freq; |
1372 | |
1373 | return IIO_VAL_INT; |
1374 | |
1375 | case IIO_CHAN_INFO_SCALE: |
1376 | /* |
1377 | * Scale is expressed in mV. |
1378 | * When fast mode is disabled, actual resolution may be lower |
1379 | * than 2^n, where n = realbits - 1. |
1380 | * This leads to underestimating the input voltage. |
1381 | * To compensate this deviation, the voltage reference can be |
1382 | * corrected with a factor = realbits resolution / actual max |
1383 | */ |
1384 | if (adc->backend) { |
1385 | ret = iio_backend_read_scale(back: adc->backend[idx], chan, val, NULL); |
1386 | if (ret < 0) |
1387 | return ret; |
1388 | |
1389 | *val = div_u64(dividend: (u64)*val * (u64)BIT(DFSDM_DATA_RES - 1), divisor: max); |
1390 | *val2 = chan->scan_type.realbits; |
1391 | if (chan->differential) |
1392 | *val *= 2; |
1393 | } |
1394 | return IIO_VAL_FRACTIONAL_LOG2; |
1395 | |
1396 | case IIO_CHAN_INFO_OFFSET: |
1397 | /* |
1398 | * DFSDM output data are in the range [-2^n, 2^n], |
1399 | * with n = realbits - 1. |
1400 | * - Differential modulator: |
1401 | * Offset correspond to SD modulator offset. |
1402 | * - Single ended modulator: |
1403 | * Input is in [0V, Vref] range, |
1404 | * where 0V corresponds to -2^n, and Vref to 2^n. |
1405 | * Add 2^n to offset. (i.e. middle of input range) |
1406 | * offset = offset(sd) * vref / res(sd) * max / vref. |
1407 | */ |
1408 | if (adc->backend) { |
1409 | ret = iio_backend_read_offset(back: adc->backend[idx], chan, val, NULL); |
1410 | if (ret < 0) |
1411 | return ret; |
1412 | |
1413 | *val = div_u64(dividend: (u64)max * *val, BIT(*val2 - 1)); |
1414 | if (!chan->differential) |
1415 | *val += max; |
1416 | } |
1417 | return IIO_VAL_INT; |
1418 | } |
1419 | |
1420 | return -EINVAL; |
1421 | } |
1422 | |
1423 | static int stm32_dfsdm_validate_trigger(struct iio_dev *indio_dev, |
1424 | struct iio_trigger *trig) |
1425 | { |
1426 | return stm32_dfsdm_get_jextsel(indio_dev, trig) < 0 ? -EINVAL : 0; |
1427 | } |
1428 | |
1429 | static const struct iio_info stm32_dfsdm_info_audio = { |
1430 | .hwfifo_set_watermark = stm32_dfsdm_set_watermark, |
1431 | .read_raw = stm32_dfsdm_read_raw, |
1432 | .write_raw = stm32_dfsdm_write_raw, |
1433 | .update_scan_mode = stm32_dfsdm_update_scan_mode, |
1434 | }; |
1435 | |
1436 | static const struct iio_info stm32_dfsdm_info_adc = { |
1437 | .hwfifo_set_watermark = stm32_dfsdm_set_watermark, |
1438 | .read_raw = stm32_dfsdm_read_raw, |
1439 | .write_raw = stm32_dfsdm_write_raw, |
1440 | .update_scan_mode = stm32_dfsdm_update_scan_mode, |
1441 | .validate_trigger = stm32_dfsdm_validate_trigger, |
1442 | }; |
1443 | |
1444 | static irqreturn_t stm32_dfsdm_irq(int irq, void *arg) |
1445 | { |
1446 | struct iio_dev *indio_dev = arg; |
1447 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1448 | struct regmap *regmap = adc->dfsdm->regmap; |
1449 | unsigned int status, int_en; |
1450 | |
1451 | regmap_read(map: regmap, DFSDM_ISR(adc->fl_id), val: &status); |
1452 | regmap_read(map: regmap, DFSDM_CR2(adc->fl_id), val: &int_en); |
1453 | |
1454 | if (status & DFSDM_ISR_REOCF_MASK) { |
1455 | /* Read the data register clean the IRQ status */ |
1456 | regmap_read(map: regmap, DFSDM_RDATAR(adc->fl_id), val: adc->buffer); |
1457 | complete(&adc->completion); |
1458 | } |
1459 | |
1460 | if (status & DFSDM_ISR_ROVRF_MASK) { |
1461 | if (int_en & DFSDM_CR2_ROVRIE_MASK) |
1462 | dev_warn(&indio_dev->dev, "Overrun detected\n"); |
1463 | regmap_set_bits(map: regmap, DFSDM_ICR(adc->fl_id), |
1464 | DFSDM_ICR_CLRROVRF_MASK); |
1465 | } |
1466 | |
1467 | return IRQ_HANDLED; |
1468 | } |
1469 | |
1470 | /* |
1471 | * Define external info for SPI Frequency and audio sampling rate that can be |
1472 | * configured by ASoC driver through consumer.h API |
1473 | */ |
1474 | static const struct iio_chan_spec_ext_info dfsdm_adc_audio_ext_info[] = { |
1475 | /* spi_clk_freq : clock freq on SPI/manchester bus used by channel */ |
1476 | { |
1477 | .name = "spi_clk_freq", |
1478 | .shared = IIO_SHARED_BY_TYPE, |
1479 | .read = dfsdm_adc_audio_get_spiclk, |
1480 | .write = dfsdm_adc_audio_set_spiclk, |
1481 | }, |
1482 | { } |
1483 | }; |
1484 | |
1485 | static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev) |
1486 | { |
1487 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1488 | |
1489 | if (adc->dma_chan) { |
1490 | dma_free_coherent(dev: adc->dma_chan->device->dev, |
1491 | DFSDM_DMA_BUFFER_SIZE, |
1492 | cpu_addr: adc->rx_buf, dma_handle: adc->dma_buf); |
1493 | dma_release_channel(chan: adc->dma_chan); |
1494 | } |
1495 | } |
1496 | |
1497 | static int stm32_dfsdm_dma_request(struct device *dev, |
1498 | struct iio_dev *indio_dev) |
1499 | { |
1500 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1501 | |
1502 | adc->dma_chan = dma_request_chan(dev, name: "rx"); |
1503 | if (IS_ERR(ptr: adc->dma_chan)) { |
1504 | int ret = PTR_ERR(ptr: adc->dma_chan); |
1505 | |
1506 | adc->dma_chan = NULL; |
1507 | return ret; |
1508 | } |
1509 | |
1510 | adc->rx_buf = dma_alloc_coherent(dev: adc->dma_chan->device->dev, |
1511 | DFSDM_DMA_BUFFER_SIZE, |
1512 | dma_handle: &adc->dma_buf, GFP_KERNEL); |
1513 | if (!adc->rx_buf) { |
1514 | dma_release_channel(chan: adc->dma_chan); |
1515 | return -ENOMEM; |
1516 | } |
1517 | |
1518 | indio_dev->modes |= INDIO_BUFFER_SOFTWARE; |
1519 | indio_dev->setup_ops = &stm32_dfsdm_buffer_setup_ops; |
1520 | |
1521 | return 0; |
1522 | } |
1523 | |
1524 | static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, struct iio_chan_spec *ch, |
1525 | struct fwnode_handle *child) |
1526 | { |
1527 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1528 | int ret; |
1529 | |
1530 | if (child) |
1531 | ret = stm32_dfsdm_generic_channel_parse_of(dfsdm: adc->dfsdm, indio_dev, ch, node: child); |
1532 | else /* Legacy binding */ |
1533 | ret = stm32_dfsdm_channel_parse_of(dfsdm: adc->dfsdm, indio_dev, ch); |
1534 | if (ret < 0) |
1535 | return dev_err_probe(dev: &indio_dev->dev, err: ret, fmt: "Failed to parse channel\n"); |
1536 | |
1537 | ch->type = IIO_VOLTAGE; |
1538 | ch->indexed = 1; |
1539 | |
1540 | /* |
1541 | * IIO_CHAN_INFO_RAW: used to compute regular conversion |
1542 | * IIO_CHAN_INFO_OVERSAMPLING_RATIO: used to set oversampling |
1543 | */ |
1544 | if (child) { |
1545 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
1546 | BIT(IIO_CHAN_INFO_SCALE) | |
1547 | BIT(IIO_CHAN_INFO_OFFSET); |
1548 | } else { |
1549 | /* Legacy. Scaling not supported */ |
1550 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); |
1551 | } |
1552 | |
1553 | ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | |
1554 | BIT(IIO_CHAN_INFO_SAMP_FREQ); |
1555 | |
1556 | if (adc->dev_data->type == DFSDM_AUDIO) { |
1557 | ch->ext_info = dfsdm_adc_audio_ext_info; |
1558 | ch->scan_index = 0; |
1559 | } else { |
1560 | ch->scan_type.shift = 8; |
1561 | } |
1562 | ch->scan_type.sign = 's'; |
1563 | ch->scan_type.realbits = 24; |
1564 | ch->scan_type.storagebits = 32; |
1565 | |
1566 | return stm32_dfsdm_chan_configure(dfsdm: adc->dfsdm, |
1567 | ch: &adc->dfsdm->ch_list[ch->channel]); |
1568 | } |
1569 | |
1570 | static int stm32_dfsdm_chan_init(struct iio_dev *indio_dev, struct iio_chan_spec *channels) |
1571 | { |
1572 | int num_ch = indio_dev->num_channels; |
1573 | int chan_idx = 0; |
1574 | int ret; |
1575 | |
1576 | for (chan_idx = 0; chan_idx < num_ch; chan_idx++) { |
1577 | channels[chan_idx].scan_index = chan_idx; |
1578 | ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch: &channels[chan_idx], NULL); |
1579 | if (ret < 0) |
1580 | return dev_err_probe(dev: &indio_dev->dev, err: ret, fmt: "Channels init failed\n"); |
1581 | } |
1582 | |
1583 | return 0; |
1584 | } |
1585 | |
1586 | static int stm32_dfsdm_generic_chan_init(struct iio_dev *indio_dev, struct iio_chan_spec *channels) |
1587 | { |
1588 | int chan_idx = 0, ret; |
1589 | |
1590 | device_for_each_child_node_scoped(&indio_dev->dev, child) { |
1591 | /* Skip DAI node in DFSDM audio nodes */ |
1592 | if (fwnode_property_present(fwnode: child, propname: "compatible")) |
1593 | continue; |
1594 | |
1595 | channels[chan_idx].scan_index = chan_idx; |
1596 | ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch: &channels[chan_idx], child); |
1597 | if (ret < 0) |
1598 | return dev_err_probe(dev: &indio_dev->dev, err: ret, fmt: "Channels init failed\n"); |
1599 | |
1600 | chan_idx++; |
1601 | } |
1602 | |
1603 | return chan_idx; |
1604 | } |
1605 | |
1606 | static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev) |
1607 | { |
1608 | struct iio_chan_spec *ch; |
1609 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1610 | struct stm32_dfsdm_channel *d_ch; |
1611 | bool legacy = false; |
1612 | int num_ch, ret; |
1613 | |
1614 | /* If st,adc-channels is defined legacy binding is used. Else assume generic binding. */ |
1615 | num_ch = of_property_count_u32_elems(np: indio_dev->dev.of_node, propname: "st,adc-channels"); |
1616 | if (num_ch == 1) |
1617 | legacy = true; |
1618 | |
1619 | ch = devm_kzalloc(dev: &indio_dev->dev, size: sizeof(*ch), GFP_KERNEL); |
1620 | if (!ch) |
1621 | return -ENOMEM; |
1622 | |
1623 | indio_dev->num_channels = 1; |
1624 | indio_dev->channels = ch; |
1625 | |
1626 | if (legacy) |
1627 | ret = stm32_dfsdm_chan_init(indio_dev, channels: ch); |
1628 | else |
1629 | ret = stm32_dfsdm_generic_chan_init(indio_dev, channels: ch); |
1630 | |
1631 | if (ret < 0) { |
1632 | dev_err(&indio_dev->dev, "Channels init failed\n"); |
1633 | return ret; |
1634 | } |
1635 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ); |
1636 | |
1637 | d_ch = &adc->dfsdm->ch_list[ch->channel]; |
1638 | if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) |
1639 | adc->spi_freq = adc->dfsdm->spi_master_freq; |
1640 | |
1641 | return stm32_dfsdm_dma_request(dev, indio_dev); |
1642 | } |
1643 | |
1644 | static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev) |
1645 | { |
1646 | struct iio_chan_spec *ch; |
1647 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1648 | int num_ch, ret; |
1649 | bool legacy = false; |
1650 | |
1651 | adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING; |
1652 | ret = stm32_dfsdm_compute_all_osrs(indio_dev, oversamp: adc->oversamp); |
1653 | if (ret < 0) |
1654 | return ret; |
1655 | |
1656 | num_ch = device_get_child_node_count(dev: &indio_dev->dev); |
1657 | if (!num_ch) { |
1658 | /* No channels nodes found. Assume legacy binding */ |
1659 | num_ch = of_property_count_u32_elems(np: indio_dev->dev.of_node, propname: "st,adc-channels"); |
1660 | if (num_ch < 0) { |
1661 | dev_err(&indio_dev->dev, "Bad st,adc-channels\n"); |
1662 | return num_ch; |
1663 | } |
1664 | |
1665 | legacy = true; |
1666 | } |
1667 | |
1668 | if (num_ch > adc->dfsdm->num_chs) { |
1669 | dev_err(&indio_dev->dev, "Number of channel [%d] exceeds [%d]\n", |
1670 | num_ch, adc->dfsdm->num_chs); |
1671 | return -EINVAL; |
1672 | } |
1673 | indio_dev->num_channels = num_ch; |
1674 | |
1675 | if (legacy) { |
1676 | /* Bind to SD modulator IIO device. */ |
1677 | adc->hwc = devm_iio_hw_consumer_alloc(dev: &indio_dev->dev); |
1678 | if (IS_ERR(ptr: adc->hwc)) |
1679 | return dev_err_probe(dev: &indio_dev->dev, err: -EPROBE_DEFER, |
1680 | fmt: "waiting for SD modulator\n"); |
1681 | } else { |
1682 | /* Generic binding. SD modulator IIO device not used. Use SD modulator backend. */ |
1683 | adc->hwc = NULL; |
1684 | |
1685 | adc->backend = devm_kcalloc(dev: &indio_dev->dev, n: num_ch, size: sizeof(*adc->backend), |
1686 | GFP_KERNEL); |
1687 | if (!adc->backend) |
1688 | return -ENOMEM; |
1689 | } |
1690 | |
1691 | ch = devm_kcalloc(dev: &indio_dev->dev, n: num_ch, size: sizeof(*ch), GFP_KERNEL); |
1692 | if (!ch) |
1693 | return -ENOMEM; |
1694 | indio_dev->channels = ch; |
1695 | |
1696 | if (legacy) |
1697 | ret = stm32_dfsdm_chan_init(indio_dev, channels: ch); |
1698 | else |
1699 | ret = stm32_dfsdm_generic_chan_init(indio_dev, channels: ch); |
1700 | if (ret < 0) |
1701 | return ret; |
1702 | |
1703 | init_completion(x: &adc->completion); |
1704 | |
1705 | /* Optionally request DMA */ |
1706 | ret = stm32_dfsdm_dma_request(dev, indio_dev); |
1707 | if (ret) { |
1708 | if (ret != -ENODEV) |
1709 | return dev_err_probe(dev, err: ret, |
1710 | fmt: "DMA channel request failed with\n"); |
1711 | |
1712 | dev_dbg(dev, "No DMA support\n"); |
1713 | return 0; |
1714 | } |
1715 | |
1716 | ret = iio_triggered_buffer_setup(indio_dev, |
1717 | &iio_pollfunc_store_time, NULL, |
1718 | &stm32_dfsdm_buffer_setup_ops); |
1719 | if (ret) { |
1720 | stm32_dfsdm_dma_release(indio_dev); |
1721 | dev_err(&indio_dev->dev, "buffer setup failed\n"); |
1722 | return ret; |
1723 | } |
1724 | |
1725 | /* lptimer/timer hardware triggers */ |
1726 | indio_dev->modes |= INDIO_HARDWARE_TRIGGERED; |
1727 | |
1728 | return 0; |
1729 | } |
1730 | |
1731 | static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_adc_data = { |
1732 | .type = DFSDM_IIO, |
1733 | .init = stm32_dfsdm_adc_init, |
1734 | }; |
1735 | |
1736 | static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_audio_data = { |
1737 | .type = DFSDM_AUDIO, |
1738 | .init = stm32_dfsdm_audio_init, |
1739 | }; |
1740 | |
1741 | static const struct of_device_id stm32_dfsdm_adc_match[] = { |
1742 | { |
1743 | .compatible = "st,stm32-dfsdm-adc", |
1744 | .data = &stm32h7_dfsdm_adc_data, |
1745 | }, |
1746 | { |
1747 | .compatible = "st,stm32-dfsdm-dmic", |
1748 | .data = &stm32h7_dfsdm_audio_data, |
1749 | }, |
1750 | { } |
1751 | }; |
1752 | MODULE_DEVICE_TABLE(of, stm32_dfsdm_adc_match); |
1753 | |
1754 | static int stm32_dfsdm_adc_probe(struct platform_device *pdev) |
1755 | { |
1756 | struct device *dev = &pdev->dev; |
1757 | struct stm32_dfsdm_adc *adc; |
1758 | struct device_node *np = dev->of_node; |
1759 | const struct stm32_dfsdm_dev_data *dev_data; |
1760 | struct iio_dev *iio; |
1761 | char *name; |
1762 | int ret, irq, val; |
1763 | |
1764 | dev_data = of_device_get_match_data(dev); |
1765 | iio = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*adc)); |
1766 | if (!iio) { |
1767 | dev_err(dev, "%s: Failed to allocate IIO\n", __func__); |
1768 | return -ENOMEM; |
1769 | } |
1770 | |
1771 | adc = iio_priv(indio_dev: iio); |
1772 | adc->dfsdm = dev_get_drvdata(dev: dev->parent); |
1773 | |
1774 | iio->dev.of_node = np; |
1775 | iio->modes = INDIO_DIRECT_MODE; |
1776 | |
1777 | platform_set_drvdata(pdev, data: iio); |
1778 | |
1779 | ret = of_property_read_u32(np: dev->of_node, propname: "reg", out_value: &adc->fl_id); |
1780 | if (ret != 0 || adc->fl_id >= adc->dfsdm->num_fls) { |
1781 | dev_err(dev, "Missing or bad reg property\n"); |
1782 | return -EINVAL; |
1783 | } |
1784 | |
1785 | name = devm_kzalloc(dev, size: sizeof("dfsdm-adc0"), GFP_KERNEL); |
1786 | if (!name) |
1787 | return -ENOMEM; |
1788 | if (dev_data->type == DFSDM_AUDIO) { |
1789 | iio->info = &stm32_dfsdm_info_audio; |
1790 | snprintf(buf: name, size: sizeof("dfsdm-pdm0"), fmt: "dfsdm-pdm%d", adc->fl_id); |
1791 | } else { |
1792 | iio->info = &stm32_dfsdm_info_adc; |
1793 | snprintf(buf: name, size: sizeof("dfsdm-adc0"), fmt: "dfsdm-adc%d", adc->fl_id); |
1794 | } |
1795 | iio->name = name; |
1796 | |
1797 | /* |
1798 | * In a first step IRQs generated for channels are not treated. |
1799 | * So IRQ associated to filter instance 0 is dedicated to the Filter 0. |
1800 | */ |
1801 | irq = platform_get_irq(pdev, 0); |
1802 | if (irq < 0) |
1803 | return irq; |
1804 | |
1805 | ret = devm_request_irq(dev, irq, handler: stm32_dfsdm_irq, |
1806 | irqflags: 0, devname: pdev->name, dev_id: iio); |
1807 | if (ret < 0) { |
1808 | dev_err(dev, "Failed to request IRQ\n"); |
1809 | return ret; |
1810 | } |
1811 | |
1812 | ret = of_property_read_u32(np: dev->of_node, propname: "st,filter-order", out_value: &val); |
1813 | if (ret < 0) { |
1814 | dev_err(dev, "Failed to set filter order\n"); |
1815 | return ret; |
1816 | } |
1817 | |
1818 | adc->dfsdm->fl_list[adc->fl_id].ford = val; |
1819 | |
1820 | ret = of_property_read_u32(np: dev->of_node, propname: "st,filter0-sync", out_value: &val); |
1821 | if (!ret) |
1822 | adc->dfsdm->fl_list[adc->fl_id].sync_mode = val; |
1823 | |
1824 | adc->dev_data = dev_data; |
1825 | ret = dev_data->init(dev, iio); |
1826 | if (ret < 0) |
1827 | return ret; |
1828 | |
1829 | ret = iio_device_register(iio); |
1830 | if (ret < 0) |
1831 | goto err_cleanup; |
1832 | |
1833 | if (dev_data->type == DFSDM_AUDIO) { |
1834 | ret = of_platform_populate(root: np, NULL, NULL, parent: dev); |
1835 | if (ret < 0) { |
1836 | dev_err(dev, "Failed to find an audio DAI\n"); |
1837 | goto err_unregister; |
1838 | } |
1839 | } |
1840 | |
1841 | return 0; |
1842 | |
1843 | err_unregister: |
1844 | iio_device_unregister(indio_dev: iio); |
1845 | err_cleanup: |
1846 | stm32_dfsdm_dma_release(indio_dev: iio); |
1847 | |
1848 | return ret; |
1849 | } |
1850 | |
1851 | static void stm32_dfsdm_adc_remove(struct platform_device *pdev) |
1852 | { |
1853 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); |
1854 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1855 | |
1856 | if (adc->dev_data->type == DFSDM_AUDIO) |
1857 | of_platform_depopulate(parent: &pdev->dev); |
1858 | iio_device_unregister(indio_dev); |
1859 | stm32_dfsdm_dma_release(indio_dev); |
1860 | } |
1861 | |
1862 | static int stm32_dfsdm_adc_suspend(struct device *dev) |
1863 | { |
1864 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1865 | |
1866 | if (iio_buffer_enabled(indio_dev)) |
1867 | stm32_dfsdm_predisable(indio_dev); |
1868 | |
1869 | return 0; |
1870 | } |
1871 | |
1872 | static int stm32_dfsdm_adc_resume(struct device *dev) |
1873 | { |
1874 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
1875 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1876 | const struct iio_chan_spec *chan; |
1877 | struct stm32_dfsdm_channel *ch; |
1878 | int i, ret; |
1879 | |
1880 | /* restore channels configuration */ |
1881 | for (i = 0; i < indio_dev->num_channels; i++) { |
1882 | chan = indio_dev->channels + i; |
1883 | ch = &adc->dfsdm->ch_list[chan->channel]; |
1884 | ret = stm32_dfsdm_chan_configure(dfsdm: adc->dfsdm, ch); |
1885 | if (ret) |
1886 | return ret; |
1887 | } |
1888 | |
1889 | if (iio_buffer_enabled(indio_dev)) |
1890 | stm32_dfsdm_postenable(indio_dev); |
1891 | |
1892 | return 0; |
1893 | } |
1894 | |
1895 | static DEFINE_SIMPLE_DEV_PM_OPS(stm32_dfsdm_adc_pm_ops, |
1896 | stm32_dfsdm_adc_suspend, |
1897 | stm32_dfsdm_adc_resume); |
1898 | |
1899 | static struct platform_driver stm32_dfsdm_adc_driver = { |
1900 | .driver = { |
1901 | .name = "stm32-dfsdm-adc", |
1902 | .of_match_table = stm32_dfsdm_adc_match, |
1903 | .pm = pm_sleep_ptr(&stm32_dfsdm_adc_pm_ops), |
1904 | }, |
1905 | .probe = stm32_dfsdm_adc_probe, |
1906 | .remove = stm32_dfsdm_adc_remove, |
1907 | }; |
1908 | module_platform_driver(stm32_dfsdm_adc_driver); |
1909 | |
1910 | MODULE_DESCRIPTION("STM32 sigma delta ADC"); |
1911 | MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); |
1912 | MODULE_LICENSE("GPL v2"); |
1913 | MODULE_IMPORT_NS("IIO_BACKEND"); |
1914 |
Definitions
- sd_converter_type
- stm32_dfsdm_dev_data
- stm32_dfsdm_adc
- stm32_dfsdm_str2field
- stm32_dfsdm_chan_type
- stm32_dfsdm_chan_src
- stm32_dfsdm_str2val
- stm32_dfsdm_trig_info
- stm32_dfsdm_jexten
- stm32_dfsdm_trigs
- stm32_dfsdm_get_jextsel
- stm32_dfsdm_compute_osrs
- stm32_dfsdm_compute_all_osrs
- stm32_dfsdm_start_channel
- stm32_dfsdm_stop_channel
- stm32_dfsdm_chan_configure
- stm32_dfsdm_start_filter
- stm32_dfsdm_stop_filter
- stm32_dfsdm_filter_set_trig
- stm32_dfsdm_channels_configure
- stm32_dfsdm_filter_configure
- stm32_dfsdm_channel_parse_of
- stm32_dfsdm_generic_channel_parse_of
- dfsdm_adc_audio_get_spiclk
- dfsdm_adc_set_samp_freq
- dfsdm_adc_audio_set_spiclk
- stm32_dfsdm_start_conv
- stm32_dfsdm_stop_conv
- stm32_dfsdm_set_watermark
- stm32_dfsdm_adc_dma_residue
- stm32_dfsdm_process_data
- stm32_dfsdm_dma_buffer_done
- stm32_dfsdm_adc_dma_start
- stm32_dfsdm_adc_dma_stop
- stm32_dfsdm_update_scan_mode
- stm32_dfsdm_postenable
- stm32_dfsdm_predisable
- stm32_dfsdm_buffer_setup_ops
- stm32_dfsdm_get_buff_cb
- stm32_dfsdm_release_buff_cb
- stm32_dfsdm_single_conv
- stm32_dfsdm_write_raw
- __stm32_dfsdm_read_info_raw
- stm32_dfsdm_read_raw
- stm32_dfsdm_validate_trigger
- stm32_dfsdm_info_audio
- stm32_dfsdm_info_adc
- stm32_dfsdm_irq
- dfsdm_adc_audio_ext_info
- stm32_dfsdm_dma_release
- stm32_dfsdm_dma_request
- stm32_dfsdm_adc_chan_init_one
- stm32_dfsdm_chan_init
- stm32_dfsdm_generic_chan_init
- stm32_dfsdm_audio_init
- stm32_dfsdm_adc_init
- stm32h7_dfsdm_adc_data
- stm32h7_dfsdm_audio_data
- stm32_dfsdm_adc_match
- stm32_dfsdm_adc_probe
- stm32_dfsdm_adc_remove
- stm32_dfsdm_adc_suspend
- stm32_dfsdm_adc_resume
- stm32_dfsdm_adc_pm_ops
Improve your Profiling and Debugging skills
Find out more