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 <herve.codina@bootlin.com>
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 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
254 for (i = 0; i < prtd->channels; i++)
255 prtd->qmc_dai->chans[i].prtd_tx = prtd;
256
257 /* Submit first chunk ... */
258 ret = qmc_audio_pcm_write_submit(prtd);
259 if (ret)
260 return ret;
261
262 /* ... prepare next one ... */
263 prtd->ch_dma_addr_current += prtd->ch_dma_size;
264 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
265 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
266
267 /* ... and send it */
268 ret = qmc_audio_pcm_write_submit(prtd);
269 if (ret)
270 return ret;
271 } else {
272 for (i = 0; i < prtd->channels; i++)
273 prtd->qmc_dai->chans[i].prtd_rx = prtd;
274
275 /* Submit first chunk ... */
276 ret = qmc_audio_pcm_read_submit(prtd);
277 if (ret)
278 return ret;
279
280 /* ... prepare next one ... */
281 prtd->ch_dma_addr_current += prtd->ch_dma_size;
282 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
283 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
284
285 /* ... and send it */
286 ret = qmc_audio_pcm_read_submit(prtd);
287 if (ret)
288 return ret;
289 }
290 break;
291
292 case SNDRV_PCM_TRIGGER_RESUME:
293 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
294 break;
295
296 case SNDRV_PCM_TRIGGER_STOP:
297 case SNDRV_PCM_TRIGGER_SUSPEND:
298 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
299 break;
300
301 default:
302 return -EINVAL;
303 }
304
305 return 0;
306 }
307
qmc_audio_pcm_pointer(struct snd_soc_component * component,struct snd_pcm_substream * substream)308 static snd_pcm_uframes_t qmc_audio_pcm_pointer(struct snd_soc_component *component,
309 struct snd_pcm_substream *substream)
310 {
311 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
312
313 return prtd->buffer_ended;
314 }
315
qmc_audio_of_xlate_dai_name(struct snd_soc_component * component,const struct of_phandle_args * args,const char ** dai_name)316 static int qmc_audio_of_xlate_dai_name(struct snd_soc_component *component,
317 const struct of_phandle_args *args,
318 const char **dai_name)
319 {
320 struct qmc_audio *qmc_audio = dev_get_drvdata(component->dev);
321 struct snd_soc_dai_driver *dai_driver;
322 int id = args->args[0];
323 int i;
324
325 for (i = 0; i < qmc_audio->num_dais; i++) {
326 dai_driver = qmc_audio->dai_drivers + i;
327 if (dai_driver->id == id) {
328 *dai_name = dai_driver->name;
329 return 0;
330 }
331 }
332
333 return -EINVAL;
334 }
335
336 static const struct snd_pcm_hardware qmc_audio_pcm_hardware = {
337 .info = SNDRV_PCM_INFO_MMAP |
338 SNDRV_PCM_INFO_MMAP_VALID |
339 SNDRV_PCM_INFO_INTERLEAVED |
340 SNDRV_PCM_INFO_NONINTERLEAVED |
341 SNDRV_PCM_INFO_PAUSE,
342 .period_bytes_min = 32,
343 .period_bytes_max = 64 * 1024,
344 .periods_min = 2,
345 .periods_max = 2 * 1024,
346 .buffer_bytes_max = 64 * 1024,
347 };
348
qmc_audio_pcm_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)349 static int qmc_audio_pcm_open(struct snd_soc_component *component,
350 struct snd_pcm_substream *substream)
351 {
352 struct snd_pcm_runtime *runtime = substream->runtime;
353 struct qmc_dai_prtd *prtd;
354 int ret;
355
356 snd_soc_set_runtime_hwparams(substream, &qmc_audio_pcm_hardware);
357
358 /* ensure that buffer size is a multiple of period size */
359 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
360 if (ret < 0)
361 return ret;
362
363 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
364 if (!prtd)
365 return -ENOMEM;
366
367 runtime->private_data = prtd;
368
369 return 0;
370 }
371
qmc_audio_pcm_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)372 static int qmc_audio_pcm_close(struct snd_soc_component *component,
373 struct snd_pcm_substream *substream)
374 {
375 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
376
377 kfree(prtd);
378 return 0;
379 }
380
381 static const struct snd_soc_component_driver qmc_audio_soc_platform = {
382 .open = qmc_audio_pcm_open,
383 .close = qmc_audio_pcm_close,
384 .hw_params = qmc_audio_pcm_hw_params,
385 .trigger = qmc_audio_pcm_trigger,
386 .pointer = qmc_audio_pcm_pointer,
387 .pcm_construct = qmc_audio_pcm_construct,
388 .of_xlate_dai_name = qmc_audio_of_xlate_dai_name,
389 };
390
qmc_dai_get_index(struct snd_soc_dai * dai)391 static unsigned int qmc_dai_get_index(struct snd_soc_dai *dai)
392 {
393 struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
394
395 return dai->driver - qmc_audio->dai_drivers;
396 }
397
qmc_dai_get_data(struct snd_soc_dai * dai)398 static struct qmc_dai *qmc_dai_get_data(struct snd_soc_dai *dai)
399 {
400 struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
401 unsigned int index;
402
403 index = qmc_dai_get_index(dai);
404 if (index > qmc_audio->num_dais)
405 return NULL;
406
407 return qmc_audio->dais + index;
408 }
409
410 /*
411 * The constraints for format/channel is to match with the number of 8bit
412 * time-slots available.
413 */
qmc_dai_hw_rule_channels_by_format(struct qmc_dai * qmc_dai,struct snd_pcm_hw_params * params,unsigned int nb_ts)414 static int qmc_dai_hw_rule_channels_by_format(struct qmc_dai *qmc_dai,
415 struct snd_pcm_hw_params *params,
416 unsigned int nb_ts)
417 {
418 struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
419 snd_pcm_format_t format = params_format(params);
420 struct snd_interval ch = {0};
421
422 switch (snd_pcm_format_physical_width(format)) {
423 case 8:
424 ch.max = nb_ts;
425 break;
426 case 16:
427 ch.max = nb_ts / 2;
428 break;
429 case 32:
430 ch.max = nb_ts / 4;
431 break;
432 case 64:
433 ch.max = nb_ts / 8;
434 break;
435 default:
436 dev_err(qmc_dai->dev, "format physical width %u not supported\n",
437 snd_pcm_format_physical_width(format));
438 return -EINVAL;
439 }
440
441 ch.min = ch.max ? 1 : 0;
442
443 return snd_interval_refine(c, &ch);
444 }
445
qmc_dai_hw_rule_playback_channels_by_format(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)446 static int qmc_dai_hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params,
447 struct snd_pcm_hw_rule *rule)
448 {
449 struct qmc_dai *qmc_dai = rule->private;
450
451 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_tx_ts);
452 }
453
qmc_dai_hw_rule_capture_channels_by_format(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)454 static int qmc_dai_hw_rule_capture_channels_by_format(struct snd_pcm_hw_params *params,
455 struct snd_pcm_hw_rule *rule)
456 {
457 struct qmc_dai *qmc_dai = rule->private;
458
459 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_rx_ts);
460 }
461
qmc_dai_hw_rule_format_by_channels(struct qmc_dai * qmc_dai,struct snd_pcm_hw_params * params,unsigned int nb_ts)462 static int qmc_dai_hw_rule_format_by_channels(struct qmc_dai *qmc_dai,
463 struct snd_pcm_hw_params *params,
464 unsigned int nb_ts)
465 {
466 struct snd_mask *f_old = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
467 unsigned int channels = params_channels(params);
468 unsigned int slot_width;
469 snd_pcm_format_t format;
470 struct snd_mask f_new;
471
472 if (!channels || channels > nb_ts) {
473 dev_err(qmc_dai->dev, "channels %u not supported\n",
474 nb_ts);
475 return -EINVAL;
476 }
477
478 slot_width = (nb_ts / channels) * 8;
479
480 snd_mask_none(&f_new);
481 pcm_for_each_format(format) {
482 if (snd_mask_test_format(f_old, format)) {
483 if (snd_pcm_format_physical_width(format) <= slot_width)
484 snd_mask_set_format(&f_new, format);
485 }
486 }
487
488 return snd_mask_refine(f_old, &f_new);
489 }
490
qmc_dai_hw_rule_playback_format_by_channels(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)491 static int qmc_dai_hw_rule_playback_format_by_channels(struct snd_pcm_hw_params *params,
492 struct snd_pcm_hw_rule *rule)
493 {
494 struct qmc_dai *qmc_dai = rule->private;
495
496 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_tx_ts);
497 }
498
qmc_dai_hw_rule_capture_format_by_channels(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)499 static int qmc_dai_hw_rule_capture_format_by_channels(struct snd_pcm_hw_params *params,
500 struct snd_pcm_hw_rule *rule)
501 {
502 struct qmc_dai *qmc_dai = rule->private;
503
504 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_rx_ts);
505 }
506
qmc_dai_constraints_interleaved(struct snd_pcm_substream * substream,struct qmc_dai * qmc_dai)507 static int qmc_dai_constraints_interleaved(struct snd_pcm_substream *substream,
508 struct qmc_dai *qmc_dai)
509 {
510 snd_pcm_hw_rule_func_t hw_rule_channels_by_format;
511 snd_pcm_hw_rule_func_t hw_rule_format_by_channels;
512 unsigned int frame_bits;
513 u64 access;
514 int ret;
515
516 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
517 hw_rule_channels_by_format = qmc_dai_hw_rule_capture_channels_by_format;
518 hw_rule_format_by_channels = qmc_dai_hw_rule_capture_format_by_channels;
519 frame_bits = qmc_dai->nb_rx_ts * 8;
520 } else {
521 hw_rule_channels_by_format = qmc_dai_hw_rule_playback_channels_by_format;
522 hw_rule_format_by_channels = qmc_dai_hw_rule_playback_format_by_channels;
523 frame_bits = qmc_dai->nb_tx_ts * 8;
524 }
525
526 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
527 hw_rule_channels_by_format, qmc_dai,
528 SNDRV_PCM_HW_PARAM_FORMAT, -1);
529 if (ret) {
530 dev_err(qmc_dai->dev, "Failed to add channels rule (%d)\n", ret);
531 return ret;
532 }
533
534 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
535 hw_rule_format_by_channels, qmc_dai,
536 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
537 if (ret) {
538 dev_err(qmc_dai->dev, "Failed to add format rule (%d)\n", ret);
539 return ret;
540 }
541
542 ret = snd_pcm_hw_constraint_single(substream->runtime,
543 SNDRV_PCM_HW_PARAM_FRAME_BITS,
544 frame_bits);
545 if (ret < 0) {
546 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
547 return ret;
548 }
549
550 access = 1ULL << (__force int)SNDRV_PCM_ACCESS_MMAP_INTERLEAVED |
551 1ULL << (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED;
552 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS,
553 access);
554 if (ret) {
555 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret);
556 return ret;
557 }
558
559 return 0;
560 }
561
qmc_dai_constraints_noninterleaved(struct snd_pcm_substream * substream,struct qmc_dai * qmc_dai)562 static int qmc_dai_constraints_noninterleaved(struct snd_pcm_substream *substream,
563 struct qmc_dai *qmc_dai)
564 {
565 unsigned int frame_bits;
566 u64 access;
567 int ret;
568
569 frame_bits = (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ?
570 qmc_dai->nb_rx_ts * 8 : qmc_dai->nb_tx_ts * 8;
571 ret = snd_pcm_hw_constraint_single(substream->runtime,
572 SNDRV_PCM_HW_PARAM_FRAME_BITS,
573 frame_bits);
574 if (ret < 0) {
575 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
576 return ret;
577 }
578
579 access = 1ULL << (__force int)SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED |
580 1ULL << (__force int)SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
581 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS,
582 access);
583 if (ret) {
584 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret);
585 return ret;
586 }
587
588 return 0;
589 }
590
qmc_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)591 static int qmc_dai_startup(struct snd_pcm_substream *substream,
592 struct snd_soc_dai *dai)
593 {
594 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
595 struct qmc_dai *qmc_dai;
596
597 qmc_dai = qmc_dai_get_data(dai);
598 if (!qmc_dai) {
599 dev_err(dai->dev, "Invalid dai\n");
600 return -EINVAL;
601 }
602
603 prtd->qmc_dai = qmc_dai;
604
605 return qmc_dai->nb_chans_avail > 1 ?
606 qmc_dai_constraints_noninterleaved(substream, qmc_dai) :
607 qmc_dai_constraints_interleaved(substream, qmc_dai);
608 }
609
qmc_dai_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)610 static int qmc_dai_hw_params(struct snd_pcm_substream *substream,
611 struct snd_pcm_hw_params *params,
612 struct snd_soc_dai *dai)
613 {
614 struct qmc_chan_param chan_param = {0};
615 unsigned int nb_chans_used;
616 struct qmc_dai *qmc_dai;
617 unsigned int i;
618 int ret;
619
620 qmc_dai = qmc_dai_get_data(dai);
621 if (!qmc_dai) {
622 dev_err(dai->dev, "Invalid dai\n");
623 return -EINVAL;
624 }
625
626 /*
627 * In interleaved mode, the driver uses one QMC channel for all audio
628 * channels whereas in non-interleaved mode, it uses one QMC channel per
629 * audio channel.
630 */
631 nb_chans_used = qmc_audio_access_is_interleaved(params_access(params)) ?
632 1 : params_channels(params);
633
634 if (nb_chans_used > qmc_dai->nb_chans_avail) {
635 dev_err(dai->dev, "Not enough qmc_chans. Need %u, avail %u\n",
636 nb_chans_used, qmc_dai->nb_chans_avail);
637 return -EINVAL;
638 }
639
640 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
641 chan_param.mode = QMC_TRANSPARENT;
642 chan_param.transp.max_rx_buf_size = params_period_bytes(params) / nb_chans_used;
643 for (i = 0; i < nb_chans_used; i++) {
644 ret = qmc_chan_set_param(qmc_dai->chans[i].qmc_chan, &chan_param);
645 if (ret) {
646 dev_err(dai->dev, "chans[%u], set param failed %d\n",
647 i, ret);
648 return ret;
649 }
650 }
651 qmc_dai->nb_chans_used_rx = nb_chans_used;
652 } else {
653 qmc_dai->nb_chans_used_tx = nb_chans_used;
654 }
655
656 return 0;
657 }
658
qmc_dai_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)659 static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
660 struct snd_soc_dai *dai)
661 {
662 unsigned int nb_chans_used;
663 struct qmc_dai *qmc_dai;
664 unsigned int i;
665 int direction;
666 int ret = 0;
667 int ret_tmp;
668
669 qmc_dai = qmc_dai_get_data(dai);
670 if (!qmc_dai) {
671 dev_err(dai->dev, "Invalid dai\n");
672 return -EINVAL;
673 }
674
675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
676 direction = QMC_CHAN_WRITE;
677 nb_chans_used = qmc_dai->nb_chans_used_tx;
678 } else {
679 direction = QMC_CHAN_READ;
680 nb_chans_used = qmc_dai->nb_chans_used_rx;
681 }
682
683 switch (cmd) {
684 case SNDRV_PCM_TRIGGER_START:
685 case SNDRV_PCM_TRIGGER_RESUME:
686 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
687 for (i = 0; i < nb_chans_used; i++) {
688 ret = qmc_chan_start(qmc_dai->chans[i].qmc_chan, direction);
689 if (ret)
690 goto err_stop;
691 }
692 break;
693
694 case SNDRV_PCM_TRIGGER_STOP:
695 /* Stop and reset all QMC channels and return the first error encountered */
696 for (i = 0; i < nb_chans_used; i++) {
697 ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
698 if (!ret)
699 ret = ret_tmp;
700 if (ret_tmp)
701 continue;
702
703 ret_tmp = qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction);
704 if (!ret)
705 ret = ret_tmp;
706 }
707 if (ret)
708 return ret;
709 break;
710
711 case SNDRV_PCM_TRIGGER_SUSPEND:
712 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
713 /* Stop all QMC channels and return the first error encountered */
714 for (i = 0; i < nb_chans_used; i++) {
715 ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
716 if (!ret)
717 ret = ret_tmp;
718 }
719 if (ret)
720 return ret;
721 break;
722
723 default:
724 return -EINVAL;
725 }
726
727 return 0;
728
729 err_stop:
730 while (i--) {
731 qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction);
732 qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction);
733 }
734 return ret;
735 }
736
737 static const struct snd_soc_dai_ops qmc_dai_ops = {
738 .startup = qmc_dai_startup,
739 .trigger = qmc_dai_trigger,
740 .hw_params = qmc_dai_hw_params,
741 };
742
qmc_audio_formats(u8 nb_ts,bool is_noninterleaved)743 static u64 qmc_audio_formats(u8 nb_ts, bool is_noninterleaved)
744 {
745 unsigned int format_width;
746 unsigned int chan_width;
747 snd_pcm_format_t format;
748 u64 formats_mask;
749
750 if (!nb_ts)
751 return 0;
752
753 formats_mask = 0;
754 chan_width = nb_ts * 8;
755 pcm_for_each_format(format) {
756 /*
757 * Support format other than little-endian (ie big-endian or
758 * without endianness such as 8bit formats)
759 */
760 if (snd_pcm_format_little_endian(format) == 1)
761 continue;
762
763 /* Support physical width multiple of 8bit */
764 format_width = snd_pcm_format_physical_width(format);
765 if (format_width == 0 || format_width % 8)
766 continue;
767
768 /*
769 * And support physical width that can fit N times in the
770 * channel
771 */
772 if (format_width > chan_width || chan_width % format_width)
773 continue;
774
775 /*
776 * In non interleaved mode, we can only support formats that
777 * can fit only 1 time in the channel
778 */
779 if (is_noninterleaved && format_width != chan_width)
780 continue;
781
782 formats_mask |= pcm_format_to_bits(format);
783 }
784 return formats_mask;
785 }
786
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)787 static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *np,
788 struct qmc_dai *qmc_dai,
789 struct snd_soc_dai_driver *qmc_soc_dai_driver)
790 {
791 struct qmc_chan_info info;
792 unsigned long rx_fs_rate;
793 unsigned long tx_fs_rate;
794 unsigned int nb_tx_ts;
795 unsigned int nb_rx_ts;
796 unsigned int i;
797 int count;
798 u32 val;
799 int ret;
800
801 qmc_dai->dev = qmc_audio->dev;
802
803 ret = of_property_read_u32(np, "reg", &val);
804 if (ret) {
805 dev_err(qmc_audio->dev, "%pOF: failed to read reg\n", np);
806 return ret;
807 }
808 qmc_dai->id = val;
809
810 qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d",
811 np->parent->name, qmc_dai->id);
812 if (!qmc_dai->name)
813 return -ENOMEM;
814
815 count = qmc_chan_count_phandles(np, "fsl,qmc-chan");
816 if (count < 0)
817 return dev_err_probe(qmc_audio->dev, count,
818 "dai %d get number of QMC channel failed\n", qmc_dai->id);
819 if (!count)
820 return dev_err_probe(qmc_audio->dev, -EINVAL,
821 "dai %d no QMC channel defined\n", qmc_dai->id);
822
823 qmc_dai->chans = devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->chans), GFP_KERNEL);
824 if (!qmc_dai->chans)
825 return -ENOMEM;
826
827 for (i = 0; i < count; i++) {
828 qmc_dai->chans[i].qmc_chan = devm_qmc_chan_get_byphandles_index(qmc_audio->dev, np,
829 "fsl,qmc-chan", i);
830 if (IS_ERR(qmc_dai->chans[i].qmc_chan)) {
831 return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->chans[i].qmc_chan),
832 "dai %d get QMC channel %d failed\n", qmc_dai->id, i);
833 }
834
835 ret = qmc_chan_get_info(qmc_dai->chans[i].qmc_chan, &info);
836 if (ret) {
837 dev_err(qmc_audio->dev, "dai %d get QMC %d channel info failed %d\n",
838 qmc_dai->id, i, ret);
839 return ret;
840 }
841 dev_info(qmc_audio->dev, "dai %d QMC channel %d mode %d, nb_tx_ts %u, nb_rx_ts %u\n",
842 qmc_dai->id, i, info.mode, info.nb_tx_ts, info.nb_rx_ts);
843
844 if (info.mode != QMC_TRANSPARENT) {
845 dev_err(qmc_audio->dev, "dai %d QMC chan %d mode %d is not QMC_TRANSPARENT\n",
846 qmc_dai->id, i, info.mode);
847 return -EINVAL;
848 }
849
850 /*
851 * All channels must have the same number of Tx slots and the
852 * same numbers of Rx slots.
853 */
854 if (i == 0) {
855 nb_tx_ts = info.nb_tx_ts;
856 nb_rx_ts = info.nb_rx_ts;
857 tx_fs_rate = info.tx_fs_rate;
858 rx_fs_rate = info.rx_fs_rate;
859 } else {
860 if (nb_tx_ts != info.nb_tx_ts) {
861 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Tx timeslots (%u instead of %u)\n",
862 qmc_dai->id, i, info.nb_tx_ts, nb_tx_ts);
863 return -EINVAL;
864 }
865 if (nb_rx_ts != info.nb_rx_ts) {
866 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Rx timeslots (%u instead of %u)\n",
867 qmc_dai->id, i, info.nb_rx_ts, nb_rx_ts);
868 return -EINVAL;
869 }
870 if (tx_fs_rate != info.tx_fs_rate) {
871 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Tx frame sample rate (%lu instead of %lu)\n",
872 qmc_dai->id, i, info.tx_fs_rate, tx_fs_rate);
873 return -EINVAL;
874 }
875 if (rx_fs_rate != info.rx_fs_rate) {
876 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Rx frame sample rate (%lu instead of %lu)\n",
877 qmc_dai->id, i, info.rx_fs_rate, rx_fs_rate);
878 return -EINVAL;
879 }
880 }
881 }
882
883 qmc_dai->nb_chans_avail = count;
884 qmc_dai->nb_tx_ts = nb_tx_ts * count;
885 qmc_dai->nb_rx_ts = nb_rx_ts * count;
886
887 qmc_soc_dai_driver->id = qmc_dai->id;
888 qmc_soc_dai_driver->name = qmc_dai->name;
889
890 qmc_soc_dai_driver->playback.channels_min = 0;
891 qmc_soc_dai_driver->playback.channels_max = 0;
892 if (nb_tx_ts) {
893 qmc_soc_dai_driver->playback.channels_min = 1;
894 qmc_soc_dai_driver->playback.channels_max = count > 1 ? count : nb_tx_ts;
895 }
896 qmc_soc_dai_driver->playback.formats = qmc_audio_formats(nb_tx_ts,
897 count > 1 ? true : false);
898
899 qmc_soc_dai_driver->capture.channels_min = 0;
900 qmc_soc_dai_driver->capture.channels_max = 0;
901 if (nb_rx_ts) {
902 qmc_soc_dai_driver->capture.channels_min = 1;
903 qmc_soc_dai_driver->capture.channels_max = count > 1 ? count : nb_rx_ts;
904 }
905 qmc_soc_dai_driver->capture.formats = qmc_audio_formats(nb_rx_ts,
906 count > 1 ? true : false);
907
908 qmc_soc_dai_driver->playback.rates = snd_pcm_rate_to_rate_bit(tx_fs_rate);
909 qmc_soc_dai_driver->playback.rate_min = tx_fs_rate;
910 qmc_soc_dai_driver->playback.rate_max = tx_fs_rate;
911 qmc_soc_dai_driver->capture.rates = snd_pcm_rate_to_rate_bit(rx_fs_rate);
912 qmc_soc_dai_driver->capture.rate_min = rx_fs_rate;
913 qmc_soc_dai_driver->capture.rate_max = rx_fs_rate;
914
915 qmc_soc_dai_driver->ops = &qmc_dai_ops;
916
917 return 0;
918 }
919
qmc_audio_probe(struct platform_device * pdev)920 static int qmc_audio_probe(struct platform_device *pdev)
921 {
922 struct device_node *np = pdev->dev.of_node;
923 struct qmc_audio *qmc_audio;
924 struct device_node *child;
925 unsigned int i;
926 int ret;
927
928 qmc_audio = devm_kzalloc(&pdev->dev, sizeof(*qmc_audio), GFP_KERNEL);
929 if (!qmc_audio)
930 return -ENOMEM;
931
932 qmc_audio->dev = &pdev->dev;
933
934 qmc_audio->num_dais = of_get_available_child_count(np);
935 if (qmc_audio->num_dais) {
936 qmc_audio->dais = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
937 sizeof(*qmc_audio->dais),
938 GFP_KERNEL);
939 if (!qmc_audio->dais)
940 return -ENOMEM;
941
942 qmc_audio->dai_drivers = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
943 sizeof(*qmc_audio->dai_drivers),
944 GFP_KERNEL);
945 if (!qmc_audio->dai_drivers)
946 return -ENOMEM;
947 }
948
949 i = 0;
950 for_each_available_child_of_node(np, child) {
951 ret = qmc_audio_dai_parse(qmc_audio, child,
952 qmc_audio->dais + i,
953 qmc_audio->dai_drivers + i);
954 if (ret) {
955 of_node_put(child);
956 return ret;
957 }
958 i++;
959 }
960
961 platform_set_drvdata(pdev, qmc_audio);
962
963 ret = devm_snd_soc_register_component(qmc_audio->dev,
964 &qmc_audio_soc_platform,
965 qmc_audio->dai_drivers,
966 qmc_audio->num_dais);
967 if (ret)
968 return ret;
969
970 return 0;
971 }
972
973 static const struct of_device_id qmc_audio_id_table[] = {
974 { .compatible = "fsl,qmc-audio" },
975 {} /* sentinel */
976 };
977 MODULE_DEVICE_TABLE(of, qmc_audio_id_table);
978
979 static struct platform_driver qmc_audio_driver = {
980 .driver = {
981 .name = "fsl-qmc-audio",
982 .of_match_table = of_match_ptr(qmc_audio_id_table),
983 },
984 .probe = qmc_audio_probe,
985 };
986 module_platform_driver(qmc_audio_driver);
987
988 MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
989 MODULE_DESCRIPTION("CPM/QE QMC audio driver");
990 MODULE_LICENSE("GPL");
991