1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * ALSA SoC using the QUICC Multichannel Controller (QMC)
4 *
5 * Copyright 2022 CS GROUP France
6 *
7 * Author: Herve Codina <[email protected]>
8 */
9
10 #include <linux/dma-mapping.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_platform.h>
14 #include <linux/platform_device.h>
15 #include <linux/slab.h>
16 #include <soc/fsl/qe/qmc.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19
20 struct qmc_dai_chan {
21 struct qmc_dai_prtd *prtd_tx;
22 struct qmc_dai_prtd *prtd_rx;
23 struct qmc_chan *qmc_chan;
24 };
25
26 struct qmc_dai {
27 char *name;
28 int id;
29 struct device *dev;
30 unsigned int nb_tx_ts;
31 unsigned int nb_rx_ts;
32
33 unsigned int nb_chans_avail;
34 unsigned int nb_chans_used_tx;
35 unsigned int nb_chans_used_rx;
36 struct qmc_dai_chan *chans;
37 };
38
39 struct qmc_audio {
40 struct device *dev;
41 unsigned int num_dais;
42 struct qmc_dai *dais;
43 struct snd_soc_dai_driver *dai_drivers;
44 };
45
46 struct qmc_dai_prtd {
47 struct qmc_dai *qmc_dai;
48
49 snd_pcm_uframes_t buffer_ended;
50 snd_pcm_uframes_t buffer_size;
51 snd_pcm_uframes_t period_size;
52
53 dma_addr_t ch_dma_addr_start;
54 dma_addr_t ch_dma_addr_current;
55 dma_addr_t ch_dma_addr_end;
56 size_t ch_dma_size;
57 size_t ch_dma_offset;
58
59 unsigned int channels;
60 DECLARE_BITMAP(chans_pending, 64);
61 struct snd_pcm_substream *substream;
62 };
63
qmc_audio_pcm_construct(struct snd_soc_component * component,struct snd_soc_pcm_runtime * rtd)64 static int qmc_audio_pcm_construct(struct snd_soc_component *component,
65 struct snd_soc_pcm_runtime *rtd)
66 {
67 struct snd_card *card = rtd->card->snd_card;
68 int ret;
69
70 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
71 if (ret)
72 return ret;
73
74 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, card->dev,
75 64 * 1024, 64 * 1024);
76 return 0;
77 }
78
qmc_audio_access_is_interleaved(snd_pcm_access_t access)79 static bool qmc_audio_access_is_interleaved(snd_pcm_access_t access)
80 {
81 switch (access) {
82 case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED:
83 case SNDRV_PCM_ACCESS_RW_INTERLEAVED:
84 return true;
85 default:
86 break;
87 }
88 return false;
89 }
90
qmc_audio_pcm_hw_params(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)91 static int qmc_audio_pcm_hw_params(struct snd_soc_component *component,
92 struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params)
94 {
95 struct snd_pcm_runtime *runtime = substream->runtime;
96 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
97
98 /*
99 * In interleaved mode, the driver uses one QMC channel for all audio
100 * channels whereas in non-interleaved mode, it uses one QMC channel per
101 * audio channel.
102 */
103 prtd->channels = qmc_audio_access_is_interleaved(params_access(params)) ?
104 1 : params_channels(params);
105
106 prtd->substream = substream;
107
108 prtd->buffer_ended = 0;
109 prtd->buffer_size = params_buffer_size(params);
110 prtd->period_size = params_period_size(params);
111
112 prtd->ch_dma_addr_start = runtime->dma_addr;
113 prtd->ch_dma_offset = params_buffer_bytes(params) / prtd->channels;
114 prtd->ch_dma_addr_end = runtime->dma_addr + prtd->ch_dma_offset;
115 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
116 prtd->ch_dma_size = params_period_bytes(params) / prtd->channels;
117
118 return 0;
119 }
120
121 static void qmc_audio_pcm_write_complete(void *context);
122
qmc_audio_pcm_write_submit(struct qmc_dai_prtd * prtd)123 static int qmc_audio_pcm_write_submit(struct qmc_dai_prtd *prtd)
124 {
125 unsigned int i;
126 int ret;
127
128 for (i = 0; i < prtd->channels; i++) {
129 bitmap_set(prtd->chans_pending, i, 1);
130
131 ret = qmc_chan_write_submit(prtd->qmc_dai->chans[i].qmc_chan,
132 prtd->ch_dma_addr_current + i * prtd->ch_dma_offset,
133 prtd->ch_dma_size,
134 qmc_audio_pcm_write_complete,
135 &prtd->qmc_dai->chans[i]);
136 if (ret) {
137 dev_err(prtd->qmc_dai->dev, "write_submit %u failed %d\n",
138 i, ret);
139 bitmap_clear(prtd->chans_pending, i, 1);
140 return ret;
141 }
142 }
143
144 return 0;
145 }
146
qmc_audio_pcm_write_complete(void * context)147 static void qmc_audio_pcm_write_complete(void *context)
148 {
149 struct qmc_dai_chan *chan = context;
150 struct qmc_dai_prtd *prtd;
151
152 prtd = chan->prtd_tx;
153
154 /* Mark the current channel as completed */
155 bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1);
156
157 /*
158 * All QMC channels involved must have completed their transfer before
159 * submitting a new one.
160 */
161 if (!bitmap_empty(prtd->chans_pending, 64))
162 return;
163
164 prtd->buffer_ended += prtd->period_size;
165 if (prtd->buffer_ended >= prtd->buffer_size)
166 prtd->buffer_ended = 0;
167
168 prtd->ch_dma_addr_current += prtd->ch_dma_size;
169 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
170 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
171
172 qmc_audio_pcm_write_submit(prtd);
173
174 snd_pcm_period_elapsed(prtd->substream);
175 }
176
177 static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned int flags);
178
qmc_audio_pcm_read_submit(struct qmc_dai_prtd * prtd)179 static int qmc_audio_pcm_read_submit(struct qmc_dai_prtd *prtd)
180 {
181 unsigned int i;
182 int ret;
183
184 for (i = 0; i < prtd->channels; i++) {
185 bitmap_set(prtd->chans_pending, i, 1);
186
187 ret = qmc_chan_read_submit(prtd->qmc_dai->chans[i].qmc_chan,
188 prtd->ch_dma_addr_current + i * prtd->ch_dma_offset,
189 prtd->ch_dma_size,
190 qmc_audio_pcm_read_complete,
191 &prtd->qmc_dai->chans[i]);
192 if (ret) {
193 dev_err(prtd->qmc_dai->dev, "read_submit %u failed %d\n",
194 i, ret);
195 bitmap_clear(prtd->chans_pending, i, 1);
196 return ret;
197 }
198 }
199
200 return 0;
201 }
202
qmc_audio_pcm_read_complete(void * context,size_t length,unsigned int flags)203 static void qmc_audio_pcm_read_complete(void *context, size_t length, unsigned int flags)
204 {
205 struct qmc_dai_chan *chan = context;
206 struct qmc_dai_prtd *prtd;
207
208 prtd = chan->prtd_rx;
209
210 /* Mark the current channel as completed */
211 bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1);
212
213 if (length != prtd->ch_dma_size) {
214 dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n",
215 length, prtd->ch_dma_size);
216 }
217
218 /*
219 * All QMC channels involved must have completed their transfer before
220 * submitting a new one.
221 */
222 if (!bitmap_empty(prtd->chans_pending, 64))
223 return;
224
225 prtd->buffer_ended += prtd->period_size;
226 if (prtd->buffer_ended >= prtd->buffer_size)
227 prtd->buffer_ended = 0;
228
229 prtd->ch_dma_addr_current += prtd->ch_dma_size;
230 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
231 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
232
233 qmc_audio_pcm_read_submit(prtd);
234
235 snd_pcm_period_elapsed(prtd->substream);
236 }
237
qmc_audio_pcm_trigger(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)238 static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
239 struct snd_pcm_substream *substream, int cmd)
240 {
241 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
242 unsigned int i;
243 int ret;
244
245 if (!prtd->qmc_dai) {
246 dev_err(component->dev, "qmc_dai is not set\n");
247 return -EINVAL;
248 }
249
250 switch (cmd) {
251 case SNDRV_PCM_TRIGGER_START:
252 bitmap_zero(prtd->chans_pending, 64);
253 prtd->buffer_ended = 0;
254 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
255
256 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
257 for (i = 0; i < prtd->channels; i++)
258 prtd->qmc_dai->chans[i].prtd_tx = prtd;
259
260 /* Submit first chunk ... */
261 ret = qmc_audio_pcm_write_submit(prtd);
262 if (ret)
263 return ret;
264
265 /* ... prepare next one ... */
266 prtd->ch_dma_addr_current += prtd->ch_dma_size;
267 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
268 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
269
270 /* ... and send it */
271 ret = qmc_audio_pcm_write_submit(prtd);
272 if (ret)
273 return ret;
274 } else {
275 for (i = 0; i < prtd->channels; i++)
276 prtd->qmc_dai->chans[i].prtd_rx = prtd;
277
278 /* Submit first chunk ... */
279 ret = qmc_audio_pcm_read_submit(prtd);
280 if (ret)
281 return ret;
282
283 /* ... prepare next one ... */
284 prtd->ch_dma_addr_current += prtd->ch_dma_size;
285 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
286 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
287
288 /* ... and send it */
289 ret = qmc_audio_pcm_read_submit(prtd);
290 if (ret)
291 return ret;
292 }
293 break;
294
295 case SNDRV_PCM_TRIGGER_RESUME:
296 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
297 break;
298
299 case SNDRV_PCM_TRIGGER_STOP:
300 case SNDRV_PCM_TRIGGER_SUSPEND:
301 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
302 break;
303
304 default:
305 return -EINVAL;
306 }
307
308 return 0;
309 }
310
qmc_audio_pcm_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)311 static snd_pcm_uframes_t qmc_audio_pcm_pointer(struct snd_soc_component *component,
312 struct snd_pcm_substream *substream)
313 {
314 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
315
316 return prtd->buffer_ended;
317 }
318
qmc_audio_of_xlate_dai_name(struct snd_soc_component * component,const struct of_phandle_args * args,const char ** dai_name)319 static int qmc_audio_of_xlate_dai_name(struct snd_soc_component *component,
320 const struct of_phandle_args *args,
321 const char **dai_name)
322 {
323 struct qmc_audio *qmc_audio = dev_get_drvdata(component->dev);
324 struct snd_soc_dai_driver *dai_driver;
325 int id = args->args[0];
326 int i;
327
328 for (i = 0; i < qmc_audio->num_dais; i++) {
329 dai_driver = qmc_audio->dai_drivers + i;
330 if (dai_driver->id == id) {
331 *dai_name = dai_driver->name;
332 return 0;
333 }
334 }
335
336 return -EINVAL;
337 }
338
339 static const struct snd_pcm_hardware qmc_audio_pcm_hardware = {
340 .info = SNDRV_PCM_INFO_MMAP |
341 SNDRV_PCM_INFO_MMAP_VALID |
342 SNDRV_PCM_INFO_INTERLEAVED |
343 SNDRV_PCM_INFO_NONINTERLEAVED |
344 SNDRV_PCM_INFO_PAUSE,
345 .period_bytes_min = 32,
346 .period_bytes_max = 64 * 1024,
347 .periods_min = 2,
348 .periods_max = 2 * 1024,
349 .buffer_bytes_max = 64 * 1024,
350 };
351
qmc_audio_pcm_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)352 static int qmc_audio_pcm_open(struct snd_soc_component *component,
353 struct snd_pcm_substream *substream)
354 {
355 struct snd_pcm_runtime *runtime = substream->runtime;
356 struct qmc_dai_prtd *prtd;
357 int ret;
358
359 snd_soc_set_runtime_hwparams(substream, &qmc_audio_pcm_hardware);
360
361 /* ensure that buffer size is a multiple of period size */
362 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
363 if (ret < 0)
364 return ret;
365
366 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
367 if (!prtd)
368 return -ENOMEM;
369
370 runtime->private_data = prtd;
371
372 return 0;
373 }
374
qmc_audio_pcm_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)375 static int qmc_audio_pcm_close(struct snd_soc_component *component,
376 struct snd_pcm_substream *substream)
377 {
378 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
379
380 kfree(prtd);
381 return 0;
382 }
383
384 static const struct snd_soc_component_driver qmc_audio_soc_platform = {
385 .open = qmc_audio_pcm_open,
386 .close = qmc_audio_pcm_close,
387 .hw_params = qmc_audio_pcm_hw_params,
388 .trigger = qmc_audio_pcm_trigger,
389 .pointer = qmc_audio_pcm_pointer,
390 .pcm_construct = qmc_audio_pcm_construct,
391 .of_xlate_dai_name = qmc_audio_of_xlate_dai_name,
392 };
393
qmc_dai_get_index(struct snd_soc_dai * dai)394 static unsigned int qmc_dai_get_index(struct snd_soc_dai *dai)
395 {
396 struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
397
398 return dai->driver - qmc_audio->dai_drivers;
399 }
400
qmc_dai_get_data(struct snd_soc_dai * dai)401 static struct qmc_dai *qmc_dai_get_data(struct snd_soc_dai *dai)
402 {
403 struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
404 unsigned int index;
405
406 index = qmc_dai_get_index(dai);
407 if (index > qmc_audio->num_dais)
408 return NULL;
409
410 return qmc_audio->dais + index;
411 }
412
413 /*
414 * The constraints for format/channel is to match with the number of 8bit
415 * time-slots available.
416 */
qmc_dai_hw_rule_channels_by_format(struct qmc_dai * qmc_dai,struct snd_pcm_hw_params * params,unsigned int nb_ts)417 static int qmc_dai_hw_rule_channels_by_format(struct qmc_dai *qmc_dai,
418 struct snd_pcm_hw_params *params,
419 unsigned int nb_ts)
420 {
421 struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
422 snd_pcm_format_t format = params_format(params);
423 struct snd_interval ch = {0};
424
425 switch (snd_pcm_format_physical_width(format)) {
426 case 8:
427 ch.max = nb_ts;
428 break;
429 case 16:
430 ch.max = nb_ts / 2;
431 break;
432 case 32:
433 ch.max = nb_ts / 4;
434 break;
435 case 64:
436 ch.max = nb_ts / 8;
437 break;
438 default:
439 dev_err(qmc_dai->dev, "format physical width %u not supported\n",
440 snd_pcm_format_physical_width(format));
441 return -EINVAL;
442 }
443
444 ch.min = ch.max ? 1 : 0;
445
446 return snd_interval_refine(c, &ch);
447 }
448
qmc_dai_hw_rule_playback_channels_by_format(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)449 static int qmc_dai_hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params,
450 struct snd_pcm_hw_rule *rule)
451 {
452 struct qmc_dai *qmc_dai = rule->private;
453
454 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_tx_ts);
455 }
456
qmc_dai_hw_rule_capture_channels_by_format(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)457 static int qmc_dai_hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params,
458 struct snd_pcm_hw_rule *rule)
459 {
460 struct qmc_dai *qmc_dai = rule->private;
461
462 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_rx_ts);
463 }
464
qmc_dai_hw_rule_format_by_channels(struct qmc_dai * qmc_dai,struct snd_pcm_hw_params * params,unsigned int nb_ts)465 static int qmc_dai_hw_rule_format_by_channels(struct qmc_dai *qmc_dai,
466 struct snd_pcm_hw_params *params,
467 unsigned int nb_ts)
468 {
469 struct snd_mask *f_old = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
470 unsigned int channels = params_channels(params);
471 unsigned int slot_width;
472 snd_pcm_format_t format;
473 struct snd_mask f_new;
474
475 if (!channels || channels > nb_ts) {
476 dev_err(qmc_dai->dev, "channels %u not supported\n",
477 nb_ts);
478 return -EINVAL;
479 }
480
481 slot_width = (nb_ts / channels) * 8;
482
483 snd_mask_none(&f_new);
484 pcm_for_each_format(format) {
485 if (snd_mask_test_format(f_old, format)) {
486 if (snd_pcm_format_physical_width(format) <= slot_width)
487 snd_mask_set_format(&f_new, format);
488 }
489 }
490
491 return snd_mask_refine(f_old, &f_new);
492 }
493
qmc_dai_hw_rule_playback_format_by_channels(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)494 static int qmc_dai_hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params,
495 struct snd_pcm_hw_rule *rule)
496 {
497 struct qmc_dai *qmc_dai = rule->private;
498
499 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_tx_ts);
500 }
501
qmc_dai_hw_rule_capture_format_by_channels(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)502 static int qmc_dai_hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params,
503 struct snd_pcm_hw_rule *rule)
504 {
505 struct qmc_dai *qmc_dai = rule->private;
506
507 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_rx_ts);
508 }
509
qmc_dai_constraints_interleaved(struct snd_pcm_substream * substream,struct qmc_dai * qmc_dai)510 static int qmc_dai_constraints_interleaved(struct snd_pcm_substream *substream,
511 struct qmc_dai *qmc_dai)
512 {
513 snd_pcm_hw_rule_func_t hw_rule_channels_by_format;
514 snd_pcm_hw_rule_func_t hw_rule_format_by_channels;
515 unsigned int frame_bits;
516 u64 access;
517 int ret;
518
519 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
520 hw_rule_channels_by_format = qmc_dai_hw_rule_capture_channels_by_format;
521 hw_rule_format_by_channels = qmc_dai_hw_rule_capture_format_by_channels;
522 frame_bits = qmc_dai->nb_rx_ts * 8;
523 } else {
524 hw_rule_channels_by_format = qmc_dai_hw_rule_playback_channels_by_format;
525 hw_rule_format_by_channels = qmc_dai_hw_rule_playback_format_by_channels;
526 frame_bits = qmc_dai->nb_tx_ts * 8;
527 }
528
529 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
530 hw_rule_channels_by_format, qmc_dai,
531 SNDRV_PCM_HW_PARAM_FORMAT, -1);
532 if (ret) {
533 dev_err(qmc_dai->dev, "Failed to add channels rule (%d)\n", ret);
534 return ret;
535 }
536
537 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
538 hw_rule_format_by_channels, qmc_dai,
539 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
540 if (ret) {
541 dev_err(qmc_dai->dev, "Failed to add format rule (%d)\n", ret);
542 return ret;
543 }
544
545 ret = snd_pcm_hw_constraint_single(substream->runtime,
546 SNDRV_PCM_HW_PARAM_FRAME_BITS,
547 frame_bits);
548 if (ret < 0) {
549 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
550 return ret;
551 }
552
553 access = 1ULL << (__force int)SNDRV_PCM_ACCESS_MMAP_INTERLEAVED |
554 1ULL << (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED;
555 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS,
556 access);
557 if (ret) {
558 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret);
559 return ret;
560 }
561
562 return 0;
563 }
564
qmc_dai_constraints_noninterleaved(struct snd_pcm_substream * substream,struct qmc_dai * qmc_dai)565 static int qmc_dai_constraints_noninterleaved(struct snd_pcm_substream *substream,
566 struct qmc_dai *qmc_dai)
567 {
568 unsigned int frame_bits;
569 u64 access;
570 int ret;
571
572 frame_bits = (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ?
573 qmc_dai->nb_rx_ts * 8 : qmc_dai->nb_tx_ts * 8;
574 ret = snd_pcm_hw_constraint_single(substream->runtime,
575 SNDRV_PCM_HW_PARAM_FRAME_BITS,
576 frame_bits);
577 if (ret < 0) {
578 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
579 return ret;
580 }
581
582 access = 1ULL << (__force int)SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED |
583 1ULL << (__force int)SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
584 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS,
585 access);
586 if (ret) {
587 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret);
588 return ret;
589 }
590
591 return 0;
592 }
593
qmc_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)594 static int qmc_dai_startup(struct snd_pcm_substream *substream,
595 struct snd_soc_dai *dai)
596 {
597 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
598 struct qmc_dai *qmc_dai;
599
600 qmc_dai = qmc_dai_get_data(dai);
601 if (!qmc_dai) {
602 dev_err(dai->dev, "Invalid dai\n");
603 return -EINVAL;
604 }
605
606 prtd->qmc_dai = qmc_dai;
607
608 return qmc_dai->nb_chans_avail > 1 ?
609 qmc_dai_constraints_noninterleaved(substream, qmc_dai) :
610 qmc_dai_constraints_interleaved(substream, qmc_dai);
611 }
612
qmc_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)613 static int qmc_dai_hw_params(struct snd_pcm_substream *substream,
614 struct snd_pcm_hw_params *params,
615 struct snd_soc_dai *dai)
616 {
617 struct qmc_chan_param chan_param = {0};
618 unsigned int nb_chans_used;
619 struct qmc_dai *qmc_dai;
620 unsigned int i;
621 int ret;
622
623 qmc_dai = qmc_dai_get_data(dai);
624 if (!qmc_dai) {
625 dev_err(dai->dev, "Invalid dai\n");
626 return -EINVAL;
627 }
628
629 /*
630 * In interleaved mode, the driver uses one QMC channel for all audio
631 * channels whereas in non-interleaved mode, it uses one QMC channel per
632 * audio channel.
633 */
634 nb_chans_used = qmc_audio_access_is_interleaved(params_access(params)) ?
635 1 : params_channels(params);
636
637 if (nb_chans_used > qmc_dai->nb_chans_avail) {
638 dev_err(dai->dev, "Not enough qmc_chans. Need %u, avail %u\n",
639 nb_chans_used, qmc_dai->nb_chans_avail);
640 return -EINVAL;
641 }
642
643 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
644 chan_param.mode = QMC_TRANSPARENT;
645 chan_param.transp.max_rx_buf_size = params_period_bytes(params) / nb_chans_used;
646 for (i = 0; i < nb_chans_used; i++) {
647 ret = qmc_chan_set_param(qmc_dai->chans[i].qmc_chan, &chan_param);
648 if (ret) {
649 dev_err(dai->dev, "chans[%u], set param failed %d\n",
650 i, ret);
651 return ret;
652 }
653 }
654 qmc_dai->nb_chans_used_rx = nb_chans_used;
655 } else {
656 qmc_dai->nb_chans_used_tx = nb_chans_used;
657 }
658
659 return 0;
660 }
661
qmc_dai_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)662 static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
663 struct snd_soc_dai *dai)
664 {
665 unsigned int nb_chans_used;
666 struct qmc_dai *qmc_dai;
667 unsigned int i;
668 int direction;
669 int ret = 0;
670 int ret_tmp;
671
672 qmc_dai = qmc_dai_get_data(dai);
673 if (!qmc_dai) {
674 dev_err(dai->dev, "Invalid dai\n");
675 return -EINVAL;
676 }
677
678 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
679 direction = QMC_CHAN_WRITE;
680 nb_chans_used = qmc_dai->nb_chans_used_tx;
681 } else {
682 direction = QMC_CHAN_READ;
683 nb_chans_used = qmc_dai->nb_chans_used_rx;
684 }
685
686 switch (cmd) {
687 case SNDRV_PCM_TRIGGER_START:
688 case SNDRV_PCM_TRIGGER_RESUME:
689 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
690 for (i = 0; i < nb_chans_used; i++) {
691 ret = qmc_chan_start(qmc_dai->chans[i].qmc_chan, direction);
692 if (ret)
693 goto err_stop;
694 }
695 break;
696
697 case SNDRV_PCM_TRIGGER_STOP:
698 /* Stop and reset all QMC channels and return the first error encountered */
699 for (i = 0; i < nb_chans_used; i++) {
700 ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
701 if (!ret)
702 ret = ret_tmp;
703 if (ret_tmp)
704 continue;
705
706 ret_tmp = qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction);
707 if (!ret)
708 ret = ret_tmp;
709 }
710 if (ret)
711 return ret;
712 break;
713
714 case SNDRV_PCM_TRIGGER_SUSPEND:
715 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
716 /* Stop all QMC channels and return the first error encountered */
717 for (i = 0; i < nb_chans_used; i++) {
718 ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
719 if (!ret)
720 ret = ret_tmp;
721 }
722 if (ret)
723 return ret;
724 break;
725
726 default:
727 return -EINVAL;
728 }
729
730 return 0;
731
732 err_stop:
733 while (i--) {
734 qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
735 qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction);
736 }
737 return ret;
738 }
739
740 static const struct snd_soc_dai_ops qmc_dai_ops = {
741 .startup = qmc_dai_startup,
742 .trigger = qmc_dai_trigger,
743 .hw_params = qmc_dai_hw_params,
744 };
745
qmc_audio_formats(u8 nb_ts,bool is_noninterleaved)746 static u64 qmc_audio_formats(u8 nb_ts, bool is_noninterleaved)
747 {
748 unsigned int format_width;
749 unsigned int chan_width;
750 snd_pcm_format_t format;
751 u64 formats_mask;
752
753 if (!nb_ts)
754 return 0;
755
756 formats_mask = 0;
757 chan_width = nb_ts * 8;
758 pcm_for_each_format(format) {
759 /*
760 * Support format other than little-endian (ie big-endian or
761 * without endianness such as 8bit formats)
762 */
763 if (snd_pcm_format_little_endian(format) == 1)
764 continue;
765
766 /* Support physical width multiple of 8bit */
767 format_width = snd_pcm_format_physical_width(format);
768 if (format_width == 0 || format_width % 8)
769 continue;
770
771 /*
772 * And support physical width that can fit N times in the
773 * channel
774 */
775 if (format_width > chan_width || chan_width % format_width)
776 continue;
777
778 /*
779 * In non interleaved mode, we can only support formats that
780 * can fit only 1 time in the channel
781 */
782 if (is_noninterleaved && format_width != chan_width)
783 continue;
784
785 formats_mask |= pcm_format_to_bits(format);
786 }
787 return formats_mask;
788 }
789
qmc_audio_dai_parse(struct qmc_audio * qmc_audio,struct device_node * np,struct qmc_dai * qmc_dai,struct snd_soc_dai_driver * qmc_soc_dai_driver)790 static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *np,
791 struct qmc_dai *qmc_dai,
792 struct snd_soc_dai_driver *qmc_soc_dai_driver)
793 {
794 struct qmc_chan_info info;
795 unsigned long rx_fs_rate;
796 unsigned long tx_fs_rate;
797 unsigned int nb_tx_ts;
798 unsigned int nb_rx_ts;
799 unsigned int i;
800 int count;
801 u32 val;
802 int ret;
803
804 qmc_dai->dev = qmc_audio->dev;
805
806 ret = of_property_read_u32(np, "reg", &val);
807 if (ret) {
808 dev_err(qmc_audio->dev, "%pOF: failed to read reg\n", np);
809 return ret;
810 }
811 qmc_dai->id = val;
812
813 qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d",
814 np->parent->name, qmc_dai->id);
815 if (!qmc_dai->name)
816 return -ENOMEM;
817
818 count = qmc_chan_count_phandles(np, "fsl,qmc-chan");
819 if (count < 0)
820 return dev_err_probe(qmc_audio->dev, count,
821 "dai %d get number of QMC channel failed\n", qmc_dai->id);
822 if (!count)
823 return dev_err_probe(qmc_audio->dev, -EINVAL,
824 "dai %d no QMC channel defined\n", qmc_dai->id);
825
826 qmc_dai->chans = devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->chans), GFP_KERNEL);
827 if (!qmc_dai->chans)
828 return -ENOMEM;
829
830 for (i = 0; i < count; i++) {
831 qmc_dai->chans[i].qmc_chan = devm_qmc_chan_get_byphandles_index(qmc_audio->dev, np,
832 "fsl,qmc-chan", i);
833 if (IS_ERR(qmc_dai->chans[i].qmc_chan)) {
834 return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->chans[i].qmc_chan),
835 "dai %d get QMC channel %d failed\n", qmc_dai->id, i);
836 }
837
838 ret = qmc_chan_get_info(qmc_dai->chans[i].qmc_chan, &info);
839 if (ret) {
840 dev_err(qmc_audio->dev, "dai %d get QMC %d channel info failed %d\n",
841 qmc_dai->id, i, ret);
842 return ret;
843 }
844
845 if (info.mode != QMC_TRANSPARENT) {
846 dev_err(qmc_audio->dev, "dai %d QMC chan %d mode %d is not QMC_TRANSPARENT\n",
847 qmc_dai->id, i, info.mode);
848 return -EINVAL;
849 }
850
851 /*
852 * All channels must have the same number of Tx slots and the
853 * same numbers of Rx slots.
854 */
855 if (i == 0) {
856 nb_tx_ts = info.nb_tx_ts;
857 nb_rx_ts = info.nb_rx_ts;
858 tx_fs_rate = info.tx_fs_rate;
859 rx_fs_rate = info.rx_fs_rate;
860 } else {
861 if (nb_tx_ts != info.nb_tx_ts) {
862 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Tx timeslots (%u instead of %u)\n",
863 qmc_dai->id, i, info.nb_tx_ts, nb_tx_ts);
864 return -EINVAL;
865 }
866 if (nb_rx_ts != info.nb_rx_ts) {
867 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Rx timeslots (%u instead of %u)\n",
868 qmc_dai->id, i, info.nb_rx_ts, nb_rx_ts);
869 return -EINVAL;
870 }
871 if (tx_fs_rate != info.tx_fs_rate) {
872 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Tx frame sample rate (%lu instead of %lu)\n",
873 qmc_dai->id, i, info.tx_fs_rate, tx_fs_rate);
874 return -EINVAL;
875 }
876 if (rx_fs_rate != info.rx_fs_rate) {
877 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Rx frame sample rate (%lu instead of %lu)\n",
878 qmc_dai->id, i, info.rx_fs_rate, rx_fs_rate);
879 return -EINVAL;
880 }
881 }
882 }
883
884 qmc_dai->nb_chans_avail = count;
885 qmc_dai->nb_tx_ts = nb_tx_ts * count;
886 qmc_dai->nb_rx_ts = nb_rx_ts * count;
887
888 qmc_soc_dai_driver->id = qmc_dai->id;
889 qmc_soc_dai_driver->name = qmc_dai->name;
890
891 qmc_soc_dai_driver->playback.channels_min = 0;
892 qmc_soc_dai_driver->playback.channels_max = 0;
893 if (nb_tx_ts) {
894 qmc_soc_dai_driver->playback.channels_min = 1;
895 qmc_soc_dai_driver->playback.channels_max = count > 1 ? count : nb_tx_ts;
896 }
897 qmc_soc_dai_driver->playback.formats = qmc_audio_formats(nb_tx_ts,
898 count > 1 ? true : false);
899
900 qmc_soc_dai_driver->capture.channels_min = 0;
901 qmc_soc_dai_driver->capture.channels_max = 0;
902 if (nb_rx_ts) {
903 qmc_soc_dai_driver->capture.channels_min = 1;
904 qmc_soc_dai_driver->capture.channels_max = count > 1 ? count : nb_rx_ts;
905 }
906 qmc_soc_dai_driver->capture.formats = qmc_audio_formats(nb_rx_ts,
907 count > 1 ? true : false);
908
909 qmc_soc_dai_driver->playback.rates = snd_pcm_rate_to_rate_bit(tx_fs_rate);
910 qmc_soc_dai_driver->playback.rate_min = tx_fs_rate;
911 qmc_soc_dai_driver->playback.rate_max = tx_fs_rate;
912 qmc_soc_dai_driver->capture.rates = snd_pcm_rate_to_rate_bit(rx_fs_rate);
913 qmc_soc_dai_driver->capture.rate_min = rx_fs_rate;
914 qmc_soc_dai_driver->capture.rate_max = rx_fs_rate;
915
916 qmc_soc_dai_driver->ops = &qmc_dai_ops;
917
918 return 0;
919 }
920
qmc_audio_probe(struct platform_device * pdev)921 static int qmc_audio_probe(struct platform_device *pdev)
922 {
923 struct device_node *np = pdev->dev.of_node;
924 struct qmc_audio *qmc_audio;
925 struct device_node *child;
926 unsigned int i;
927 int ret;
928
929 qmc_audio = devm_kzalloc(&pdev->dev, sizeof(*qmc_audio), GFP_KERNEL);
930 if (!qmc_audio)
931 return -ENOMEM;
932
933 qmc_audio->dev = &pdev->dev;
934
935 qmc_audio->num_dais = of_get_available_child_count(np);
936 if (qmc_audio->num_dais) {
937 qmc_audio->dais = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
938 sizeof(*qmc_audio->dais),
939 GFP_KERNEL);
940 if (!qmc_audio->dais)
941 return -ENOMEM;
942
943 qmc_audio->dai_drivers = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
944 sizeof(*qmc_audio->dai_drivers),
945 GFP_KERNEL);
946 if (!qmc_audio->dai_drivers)
947 return -ENOMEM;
948 }
949
950 i = 0;
951 for_each_available_child_of_node(np, child) {
952 ret = qmc_audio_dai_parse(qmc_audio, child,
953 qmc_audio->dais + i,
954 qmc_audio->dai_drivers + i);
955 if (ret) {
956 of_node_put(child);
957 return ret;
958 }
959 i++;
960 }
961
962 platform_set_drvdata(pdev, qmc_audio);
963
964 ret = devm_snd_soc_register_component(qmc_audio->dev,
965 &qmc_audio_soc_platform,
966 qmc_audio->dai_drivers,
967 qmc_audio->num_dais);
968 if (ret)
969 return ret;
970
971 return 0;
972 }
973
974 static const struct of_device_id qmc_audio_id_table[] = {
975 { .compatible = "fsl,qmc-audio" },
976 {} /* sentinel */
977 };
978 MODULE_DEVICE_TABLE(of, qmc_audio_id_table);
979
980 static struct platform_driver qmc_audio_driver = {
981 .driver = {
982 .name = "fsl-qmc-audio",
983 .of_match_table = of_match_ptr(qmc_audio_id_table),
984 },
985 .probe = qmc_audio_probe,
986 };
987 module_platform_driver(qmc_audio_driver);
988
989 MODULE_AUTHOR("Herve Codina <[email protected]>");
990 MODULE_DESCRIPTION("CPM/QE QMC audio driver");
991 MODULE_LICENSE("GPL");
992