xref: /linux/sound/soc/fsl/fsl_qmc_audio.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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