xref: /linux/sound/soc/qcom/qdsp6/q6apm-dai.c (revision 05a54fa773284d1a7923cdfdd8f0c8dabb98bd26)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2021, Linaro Limited
3 
4 #include <linux/init.h>
5 #include <linux/err.h>
6 #include <linux/module.h>
7 #include <linux/of.h>
8 #include <linux/platform_device.h>
9 #include <linux/slab.h>
10 #include <sound/soc.h>
11 #include <sound/soc-dapm.h>
12 #include <linux/spinlock.h>
13 #include <sound/pcm.h>
14 #include <asm/div64.h>
15 #include <asm/dma.h>
16 #include <linux/dma-mapping.h>
17 #include <sound/pcm_params.h>
18 #include "q6apm.h"
19 
20 #define DRV_NAME "q6apm-dai"
21 
22 #define PLAYBACK_MIN_NUM_PERIODS	2
23 #define PLAYBACK_MAX_NUM_PERIODS	8
24 #define PLAYBACK_MAX_PERIOD_SIZE	65536
25 #define PLAYBACK_MIN_PERIOD_SIZE	128
26 #define CAPTURE_MIN_NUM_PERIODS		2
27 #define CAPTURE_MAX_NUM_PERIODS		8
28 #define CAPTURE_MAX_PERIOD_SIZE		65536
29 #define CAPTURE_MIN_PERIOD_SIZE		6144
30 #define BUFFER_BYTES_MAX (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE)
31 #define BUFFER_BYTES_MIN (PLAYBACK_MIN_NUM_PERIODS * PLAYBACK_MIN_PERIOD_SIZE)
32 #define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
33 #define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
34 #define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024)
35 #define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4)
36 #define SID_MASK_DEFAULT	0xF
37 
38 static const struct snd_compr_codec_caps q6apm_compr_caps = {
39 	.num_descriptors = 1,
40 	.descriptor[0].max_ch = 2,
41 	.descriptor[0].sample_rates = {	8000, 11025, 12000, 16000, 22050,
42 					24000, 32000, 44100, 48000, 88200,
43 					96000, 176400, 192000 },
44 	.descriptor[0].num_sample_rates = 13,
45 	.descriptor[0].bit_rate[0] = 320,
46 	.descriptor[0].bit_rate[1] = 128,
47 	.descriptor[0].num_bitrates = 2,
48 	.descriptor[0].profiles = 0,
49 	.descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO,
50 	.descriptor[0].formats = 0,
51 };
52 
53 enum stream_state {
54 	Q6APM_STREAM_IDLE = 0,
55 	Q6APM_STREAM_STOPPED,
56 	Q6APM_STREAM_RUNNING,
57 };
58 
59 struct q6apm_dai_rtd {
60 	struct snd_pcm_substream *substream;
61 	struct snd_compr_stream *cstream;
62 	struct snd_codec codec;
63 	struct snd_compr_params codec_param;
64 	struct snd_dma_buffer dma_buffer;
65 	phys_addr_t phys;
66 	unsigned int pcm_size;
67 	unsigned int pcm_count;
68 	unsigned int periods;
69 	uint64_t bytes_sent;
70 	uint64_t bytes_received;
71 	uint64_t copied_total;
72 	uint16_t bits_per_sample;
73 	snd_pcm_uframes_t queue_ptr;
74 	bool next_track;
75 	enum stream_state state;
76 	struct q6apm_graph *graph;
77 	spinlock_t lock;
78 	bool notify_on_drain;
79 };
80 
81 struct q6apm_dai_data {
82 	long long sid;
83 };
84 
85 static const struct snd_pcm_hardware q6apm_dai_hardware_capture = {
86 	.info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER |
87 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED |
88 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
89 				 SNDRV_PCM_INFO_BATCH),
90 	.formats =              (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE),
91 	.rates =                SNDRV_PCM_RATE_8000_48000,
92 	.rate_min =             8000,
93 	.rate_max =             48000,
94 	.channels_min =         2,
95 	.channels_max =         4,
96 	.buffer_bytes_max =     CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
97 	.period_bytes_min =	CAPTURE_MIN_PERIOD_SIZE,
98 	.period_bytes_max =     CAPTURE_MAX_PERIOD_SIZE,
99 	.periods_min =          CAPTURE_MIN_NUM_PERIODS,
100 	.periods_max =          CAPTURE_MAX_NUM_PERIODS,
101 	.fifo_size =            0,
102 };
103 
104 static const struct snd_pcm_hardware q6apm_dai_hardware_playback = {
105 	.info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER |
106 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED |
107 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
108 				 SNDRV_PCM_INFO_BATCH),
109 	.formats =              (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE),
110 	.rates =                SNDRV_PCM_RATE_8000_192000,
111 	.rate_min =             8000,
112 	.rate_max =             192000,
113 	.channels_min =         2,
114 	.channels_max =         8,
115 	.buffer_bytes_max =     (PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE),
116 	.period_bytes_min =	PLAYBACK_MIN_PERIOD_SIZE,
117 	.period_bytes_max =     PLAYBACK_MAX_PERIOD_SIZE,
118 	.periods_min =          PLAYBACK_MIN_NUM_PERIODS,
119 	.periods_max =          PLAYBACK_MAX_NUM_PERIODS,
120 	.fifo_size =            0,
121 };
122 
123 static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv)
124 {
125 	struct q6apm_dai_rtd *prtd = priv;
126 	struct snd_pcm_substream *substream = prtd->substream;
127 
128 	switch (opcode) {
129 	case APM_CLIENT_EVENT_CMD_EOS_DONE:
130 		prtd->state = Q6APM_STREAM_STOPPED;
131 		break;
132 	case APM_CLIENT_EVENT_DATA_WRITE_DONE:
133 		snd_pcm_period_elapsed(substream);
134 
135 		break;
136 	case APM_CLIENT_EVENT_DATA_READ_DONE:
137 		snd_pcm_period_elapsed(substream);
138 		if (prtd->state == Q6APM_STREAM_RUNNING)
139 			q6apm_read(prtd->graph);
140 
141 		break;
142 	default:
143 		break;
144 	}
145 }
146 
147 static void event_handler_compr(uint32_t opcode, uint32_t token,
148 				void *payload, void *priv)
149 {
150 	struct q6apm_dai_rtd *prtd = priv;
151 	struct snd_compr_stream *substream = prtd->cstream;
152 	unsigned long flags;
153 	uint32_t wflags = 0;
154 	uint64_t avail;
155 	uint32_t bytes_written, bytes_to_write;
156 	bool is_last_buffer = false;
157 
158 	switch (opcode) {
159 	case APM_CLIENT_EVENT_CMD_EOS_DONE:
160 		spin_lock_irqsave(&prtd->lock, flags);
161 		if (prtd->notify_on_drain) {
162 			snd_compr_drain_notify(prtd->cstream);
163 			prtd->notify_on_drain = false;
164 		} else {
165 			prtd->state = Q6APM_STREAM_STOPPED;
166 		}
167 		spin_unlock_irqrestore(&prtd->lock, flags);
168 		break;
169 	case APM_CLIENT_EVENT_DATA_WRITE_DONE:
170 		spin_lock_irqsave(&prtd->lock, flags);
171 		bytes_written = token >> APM_WRITE_TOKEN_LEN_SHIFT;
172 		prtd->copied_total += bytes_written;
173 		snd_compr_fragment_elapsed(substream);
174 
175 		if (prtd->state != Q6APM_STREAM_RUNNING) {
176 			spin_unlock_irqrestore(&prtd->lock, flags);
177 			break;
178 		}
179 
180 		avail = prtd->bytes_received - prtd->bytes_sent;
181 
182 		if (avail > prtd->pcm_count) {
183 			bytes_to_write = prtd->pcm_count;
184 		} else {
185 			if (substream->partial_drain || prtd->notify_on_drain)
186 				is_last_buffer = true;
187 			bytes_to_write = avail;
188 		}
189 
190 		if (bytes_to_write) {
191 			if (substream->partial_drain && is_last_buffer)
192 				wflags |= APM_LAST_BUFFER_FLAG;
193 
194 			q6apm_write_async(prtd->graph,
195 						bytes_to_write, 0, 0, wflags);
196 
197 			prtd->bytes_sent += bytes_to_write;
198 
199 			if (prtd->notify_on_drain && is_last_buffer)
200 				audioreach_shared_memory_send_eos(prtd->graph);
201 		}
202 
203 		spin_unlock_irqrestore(&prtd->lock, flags);
204 		break;
205 	default:
206 		break;
207 	}
208 }
209 
210 static int q6apm_dai_prepare(struct snd_soc_component *component,
211 			     struct snd_pcm_substream *substream)
212 {
213 	struct snd_pcm_runtime *runtime = substream->runtime;
214 	struct q6apm_dai_rtd *prtd = runtime->private_data;
215 	struct audioreach_module_config cfg;
216 	struct device *dev = component->dev;
217 	struct q6apm_dai_data *pdata;
218 	int ret;
219 
220 	pdata = snd_soc_component_get_drvdata(component);
221 	if (!pdata)
222 		return -EINVAL;
223 
224 	if (!prtd || !prtd->graph) {
225 		dev_err(dev, "%s: private data null or audio client freed\n", __func__);
226 		return -EINVAL;
227 	}
228 
229 	cfg.direction = substream->stream;
230 	cfg.sample_rate = runtime->rate;
231 	cfg.num_channels = runtime->channels;
232 	cfg.bit_width = prtd->bits_per_sample;
233 	cfg.fmt = SND_AUDIOCODEC_PCM;
234 	audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
235 
236 	if (prtd->state) {
237 		/* clear the previous setup if any  */
238 		q6apm_graph_stop(prtd->graph);
239 		q6apm_unmap_memory_regions(prtd->graph, substream->stream);
240 	}
241 
242 	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
243 	/* rate and channels are sent to audio driver */
244 	ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
245 	if (ret < 0) {
246 		dev_err(dev, "%s: q6apm_open_write failed\n", __func__);
247 		return ret;
248 	}
249 
250 	ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg);
251 	if (ret < 0)
252 		dev_err(dev, "%s: CMD Format block failed\n", __func__);
253 
254 	ret = q6apm_map_memory_regions(prtd->graph, substream->stream, prtd->phys,
255 				       (prtd->pcm_size / prtd->periods), prtd->periods);
256 
257 	if (ret < 0) {
258 		dev_err(dev, "Audio Start: Buffer Allocation failed rc = %d\n",	ret);
259 		return -ENOMEM;
260 	}
261 
262 	ret = q6apm_graph_prepare(prtd->graph);
263 	if (ret) {
264 		dev_err(dev, "Failed to prepare Graph %d\n", ret);
265 		return ret;
266 	}
267 
268 	ret = q6apm_graph_start(prtd->graph);
269 	if (ret) {
270 		dev_err(dev, "Failed to Start Graph %d\n", ret);
271 		return ret;
272 	}
273 
274 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
275 		int i;
276 		/* Queue the buffers for Capture ONLY after graph is started */
277 		for (i = 0; i < runtime->periods; i++)
278 			q6apm_read(prtd->graph);
279 
280 	}
281 
282 	/* Now that graph as been prepared and started update the internal state accordingly */
283 	prtd->state = Q6APM_STREAM_RUNNING;
284 
285 	return 0;
286 }
287 
288 static int q6apm_dai_ack(struct snd_soc_component *component, struct snd_pcm_substream *substream)
289 {
290 	struct snd_pcm_runtime *runtime = substream->runtime;
291 	struct q6apm_dai_rtd *prtd = runtime->private_data;
292 	int i, ret = 0, avail_periods;
293 
294 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
295 		avail_periods = (runtime->control->appl_ptr - prtd->queue_ptr)/runtime->period_size;
296 		for (i = 0; i < avail_periods; i++) {
297 			ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
298 			if (ret < 0) {
299 				dev_err(component->dev, "Error queuing playback buffer %d\n", ret);
300 				return ret;
301 			}
302 			prtd->queue_ptr += runtime->period_size;
303 		}
304 	}
305 
306 	return ret;
307 }
308 
309 static int q6apm_dai_trigger(struct snd_soc_component *component,
310 			     struct snd_pcm_substream *substream, int cmd)
311 {
312 	struct snd_pcm_runtime *runtime = substream->runtime;
313 	struct q6apm_dai_rtd *prtd = runtime->private_data;
314 	int ret = 0;
315 
316 	switch (cmd) {
317 	case SNDRV_PCM_TRIGGER_START:
318 	case SNDRV_PCM_TRIGGER_RESUME:
319 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
320 		break;
321 	case SNDRV_PCM_TRIGGER_STOP:
322 		/* TODO support be handled via SoftPause Module */
323 		prtd->state = Q6APM_STREAM_STOPPED;
324 		break;
325 	case SNDRV_PCM_TRIGGER_SUSPEND:
326 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
327 		break;
328 	default:
329 		ret = -EINVAL;
330 		break;
331 	}
332 
333 	return ret;
334 }
335 
336 static int q6apm_dai_open(struct snd_soc_component *component,
337 			  struct snd_pcm_substream *substream)
338 {
339 	struct snd_pcm_runtime *runtime = substream->runtime;
340 	struct snd_soc_pcm_runtime *soc_prtd = snd_soc_substream_to_rtd(substream);
341 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0);
342 	struct device *dev = component->dev;
343 	struct q6apm_dai_data *pdata;
344 	struct q6apm_dai_rtd *prtd;
345 	int graph_id, ret;
346 
347 	graph_id = cpu_dai->driver->id;
348 
349 	pdata = snd_soc_component_get_drvdata(component);
350 	if (!pdata) {
351 		dev_err(dev, "Drv data not found ..\n");
352 		return -EINVAL;
353 	}
354 
355 	prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
356 	if (prtd == NULL)
357 		return -ENOMEM;
358 
359 	spin_lock_init(&prtd->lock);
360 	prtd->substream = substream;
361 	prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id);
362 	if (IS_ERR(prtd->graph)) {
363 		dev_err(dev, "%s: Could not allocate memory\n", __func__);
364 		ret = PTR_ERR(prtd->graph);
365 		goto err;
366 	}
367 
368 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
369 		runtime->hw = q6apm_dai_hardware_playback;
370 	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
371 		runtime->hw = q6apm_dai_hardware_capture;
372 
373 	/* Ensure that buffer size is a multiple of period size */
374 	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
375 	if (ret < 0) {
376 		dev_err(dev, "snd_pcm_hw_constraint_integer failed\n");
377 		goto err;
378 	}
379 
380 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
381 		ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
382 						   BUFFER_BYTES_MIN, BUFFER_BYTES_MAX);
383 		if (ret < 0) {
384 			dev_err(dev, "constraint for buffer bytes min max ret = %d\n", ret);
385 			goto err;
386 		}
387 	}
388 
389 	/* setup 10ms latency to accommodate DSP restrictions */
390 	ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 480);
391 	if (ret < 0) {
392 		dev_err(dev, "constraint for period bytes step ret = %d\n", ret);
393 		goto err;
394 	}
395 
396 	ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 480);
397 	if (ret < 0) {
398 		dev_err(dev, "constraint for buffer bytes step ret = %d\n", ret);
399 		goto err;
400 	}
401 
402 	runtime->private_data = prtd;
403 	runtime->dma_bytes = BUFFER_BYTES_MAX;
404 	if (pdata->sid < 0)
405 		prtd->phys = substream->dma_buffer.addr;
406 	else
407 		prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32);
408 
409 	return 0;
410 err:
411 	kfree(prtd);
412 
413 	return ret;
414 }
415 
416 static int q6apm_dai_close(struct snd_soc_component *component,
417 			   struct snd_pcm_substream *substream)
418 {
419 	struct snd_pcm_runtime *runtime = substream->runtime;
420 	struct q6apm_dai_rtd *prtd = runtime->private_data;
421 
422 	if (prtd->state) { /* only stop graph that is started */
423 		q6apm_graph_stop(prtd->graph);
424 		q6apm_unmap_memory_regions(prtd->graph, substream->stream);
425 	}
426 
427 	q6apm_graph_close(prtd->graph);
428 	prtd->graph = NULL;
429 	kfree(prtd);
430 	runtime->private_data = NULL;
431 
432 	return 0;
433 }
434 
435 static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component,
436 					   struct snd_pcm_substream *substream)
437 {
438 	struct snd_pcm_runtime *runtime = substream->runtime;
439 	struct q6apm_dai_rtd *prtd = runtime->private_data;
440 	snd_pcm_uframes_t ptr;
441 
442 	ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size;
443 	if (ptr)
444 		return ptr - 1;
445 
446 	return 0;
447 }
448 
449 static int q6apm_dai_hw_params(struct snd_soc_component *component,
450 			       struct snd_pcm_substream *substream,
451 			       struct snd_pcm_hw_params *params)
452 {
453 	struct snd_pcm_runtime *runtime = substream->runtime;
454 	struct q6apm_dai_rtd *prtd = runtime->private_data;
455 
456 	prtd->pcm_size = params_buffer_bytes(params);
457 	prtd->periods = params_periods(params);
458 
459 	switch (params_format(params)) {
460 	case SNDRV_PCM_FORMAT_S16_LE:
461 		prtd->bits_per_sample = 16;
462 		break;
463 	case SNDRV_PCM_FORMAT_S24_LE:
464 		prtd->bits_per_sample = 24;
465 		break;
466 	default:
467 		return -EINVAL;
468 	}
469 
470 	return 0;
471 }
472 
473 static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd)
474 {
475 	int size = BUFFER_BYTES_MAX;
476 
477 	return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, component->dev, size);
478 }
479 
480 static int q6apm_dai_compr_open(struct snd_soc_component *component,
481 				struct snd_compr_stream *stream)
482 {
483 	struct snd_soc_pcm_runtime *rtd = stream->private_data;
484 	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
485 	struct snd_compr_runtime *runtime = stream->runtime;
486 	struct q6apm_dai_rtd *prtd;
487 	struct q6apm_dai_data *pdata;
488 	struct device *dev = component->dev;
489 	int ret, size;
490 	int graph_id;
491 
492 	graph_id = cpu_dai->driver->id;
493 	pdata = snd_soc_component_get_drvdata(component);
494 	if (!pdata)
495 		return -EINVAL;
496 
497 	prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
498 	if (prtd == NULL)
499 		return -ENOMEM;
500 
501 	prtd->cstream = stream;
502 	prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id);
503 	if (IS_ERR(prtd->graph)) {
504 		ret = PTR_ERR(prtd->graph);
505 		kfree(prtd);
506 		return ret;
507 	}
508 
509 	runtime->private_data = prtd;
510 	runtime->dma_bytes = BUFFER_BYTES_MAX;
511 	size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
512 	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &prtd->dma_buffer);
513 	if (ret)
514 		return ret;
515 
516 	if (pdata->sid < 0)
517 		prtd->phys = prtd->dma_buffer.addr;
518 	else
519 		prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32);
520 
521 	snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer);
522 	spin_lock_init(&prtd->lock);
523 
524 	q6apm_enable_compress_module(dev, prtd->graph, true);
525 	return 0;
526 }
527 
528 static int q6apm_dai_compr_free(struct snd_soc_component *component,
529 				struct snd_compr_stream *stream)
530 {
531 	struct snd_compr_runtime *runtime = stream->runtime;
532 	struct q6apm_dai_rtd *prtd = runtime->private_data;
533 
534 	q6apm_graph_stop(prtd->graph);
535 	q6apm_unmap_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK);
536 	q6apm_graph_close(prtd->graph);
537 	snd_dma_free_pages(&prtd->dma_buffer);
538 	prtd->graph = NULL;
539 	kfree(prtd);
540 	runtime->private_data = NULL;
541 
542 	return 0;
543 }
544 
545 static int q6apm_dai_compr_get_caps(struct snd_soc_component *component,
546 				    struct snd_compr_stream *stream,
547 				    struct snd_compr_caps *caps)
548 {
549 	caps->direction = SND_COMPRESS_PLAYBACK;
550 	caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE;
551 	caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
552 	caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
553 	caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
554 	caps->num_codecs = 4;
555 	caps->codecs[0] = SND_AUDIOCODEC_MP3;
556 	caps->codecs[1] = SND_AUDIOCODEC_AAC;
557 	caps->codecs[2] = SND_AUDIOCODEC_FLAC;
558 	caps->codecs[3] = SND_AUDIOCODEC_OPUS_RAW;
559 
560 	return 0;
561 }
562 
563 static int q6apm_dai_compr_get_codec_caps(struct snd_soc_component *component,
564 					  struct snd_compr_stream *stream,
565 					  struct snd_compr_codec_caps *codec)
566 {
567 	switch (codec->codec) {
568 	case SND_AUDIOCODEC_MP3:
569 		*codec = q6apm_compr_caps;
570 		break;
571 	default:
572 		break;
573 	}
574 
575 	return 0;
576 }
577 
578 static int q6apm_dai_compr_pointer(struct snd_soc_component *component,
579 				   struct snd_compr_stream *stream,
580 				   struct snd_compr_tstamp64 *tstamp)
581 {
582 	struct snd_compr_runtime *runtime = stream->runtime;
583 	struct q6apm_dai_rtd *prtd = runtime->private_data;
584 	unsigned long flags;
585 	uint64_t temp_copied_total;
586 
587 	spin_lock_irqsave(&prtd->lock, flags);
588 	tstamp->copied_total = prtd->copied_total;
589 	temp_copied_total = tstamp->copied_total;
590 	tstamp->byte_offset = do_div(temp_copied_total, prtd->pcm_size);
591 	spin_unlock_irqrestore(&prtd->lock, flags);
592 
593 	return 0;
594 }
595 
596 static int q6apm_dai_compr_trigger(struct snd_soc_component *component,
597 			    struct snd_compr_stream *stream, int cmd)
598 {
599 	struct snd_compr_runtime *runtime = stream->runtime;
600 	struct q6apm_dai_rtd *prtd = runtime->private_data;
601 	int ret = 0;
602 
603 	switch (cmd) {
604 	case SNDRV_PCM_TRIGGER_START:
605 	case SNDRV_PCM_TRIGGER_RESUME:
606 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
607 		ret = q6apm_write_async(prtd->graph, prtd->pcm_count, 0, 0, NO_TIMESTAMP);
608 		break;
609 	case SNDRV_PCM_TRIGGER_STOP:
610 		break;
611 	case SNDRV_PCM_TRIGGER_SUSPEND:
612 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
613 		break;
614 	case SND_COMPR_TRIGGER_NEXT_TRACK:
615 		prtd->next_track = true;
616 		break;
617 	case SND_COMPR_TRIGGER_DRAIN:
618 	case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
619 		prtd->notify_on_drain = true;
620 		break;
621 	default:
622 		ret = -EINVAL;
623 		break;
624 	}
625 
626 	return ret;
627 }
628 
629 static int q6apm_dai_compr_ack(struct snd_soc_component *component, struct snd_compr_stream *stream,
630 			size_t count)
631 {
632 	struct snd_compr_runtime *runtime = stream->runtime;
633 	struct q6apm_dai_rtd *prtd = runtime->private_data;
634 	unsigned long flags;
635 
636 	spin_lock_irqsave(&prtd->lock, flags);
637 	prtd->bytes_received += count;
638 	spin_unlock_irqrestore(&prtd->lock, flags);
639 
640 	return count;
641 }
642 
643 static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
644 				      struct snd_compr_stream *stream,
645 				      struct snd_compr_params *params)
646 {
647 	struct snd_compr_runtime *runtime = stream->runtime;
648 	struct q6apm_dai_rtd *prtd = runtime->private_data;
649 	struct q6apm_dai_data *pdata;
650 	struct audioreach_module_config cfg;
651 	struct snd_codec *codec = &params->codec;
652 	int dir = stream->direction;
653 	int ret;
654 
655 	pdata = snd_soc_component_get_drvdata(component);
656 	if (!pdata)
657 		return -EINVAL;
658 
659 	prtd->periods = runtime->fragments;
660 	prtd->pcm_count = runtime->fragment_size;
661 	prtd->pcm_size = runtime->fragments * runtime->fragment_size;
662 	prtd->bits_per_sample = 16;
663 
664 	if (prtd->next_track != true) {
665 		memcpy(&prtd->codec, codec, sizeof(*codec));
666 
667 		ret = q6apm_set_real_module_id(component->dev, prtd->graph, codec->id);
668 		if (ret)
669 			return ret;
670 
671 		cfg.direction = dir;
672 		cfg.sample_rate = codec->sample_rate;
673 		cfg.num_channels = 2;
674 		cfg.bit_width = prtd->bits_per_sample;
675 		cfg.fmt = codec->id;
676 		audioreach_set_default_channel_mapping(cfg.channel_map,
677 						       cfg.num_channels);
678 		memcpy(&cfg.codec, codec, sizeof(*codec));
679 
680 		ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
681 		if (ret < 0)
682 			return ret;
683 
684 		ret = q6apm_graph_media_format_pcm(prtd->graph, &cfg);
685 		if (ret)
686 			return ret;
687 
688 		ret = q6apm_map_memory_regions(prtd->graph, SNDRV_PCM_STREAM_PLAYBACK,
689 					       prtd->phys, (prtd->pcm_size / prtd->periods),
690 					       prtd->periods);
691 		if (ret < 0)
692 			return -ENOMEM;
693 
694 		ret = q6apm_graph_prepare(prtd->graph);
695 		if (ret)
696 			return ret;
697 
698 		ret = q6apm_graph_start(prtd->graph);
699 		if (ret)
700 			return ret;
701 
702 	} else {
703 		cfg.direction = dir;
704 		cfg.sample_rate = codec->sample_rate;
705 		cfg.num_channels = 2;
706 		cfg.bit_width = prtd->bits_per_sample;
707 		cfg.fmt = codec->id;
708 		memcpy(&cfg.codec, codec, sizeof(*codec));
709 
710 		ret = audioreach_compr_set_param(prtd->graph,  &cfg);
711 		if (ret < 0)
712 			return ret;
713 	}
714 	prtd->state = Q6APM_STREAM_RUNNING;
715 
716 	return 0;
717 }
718 
719 static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
720 					struct snd_compr_stream *stream,
721 					struct snd_compr_metadata *metadata)
722 {
723 	struct snd_compr_runtime *runtime = stream->runtime;
724 	struct q6apm_dai_rtd *prtd = runtime->private_data;
725 	int ret = 0;
726 
727 	switch (metadata->key) {
728 	case SNDRV_COMPRESS_ENCODER_PADDING:
729 		q6apm_remove_trailing_silence(component->dev, prtd->graph,
730 					      metadata->value[0]);
731 		break;
732 	case SNDRV_COMPRESS_ENCODER_DELAY:
733 		q6apm_remove_initial_silence(component->dev, prtd->graph,
734 					     metadata->value[0]);
735 		break;
736 	default:
737 		ret = -EINVAL;
738 		break;
739 	}
740 
741 	return ret;
742 }
743 
744 static int q6apm_dai_compr_mmap(struct snd_soc_component *component,
745 				struct snd_compr_stream *stream,
746 				struct vm_area_struct *vma)
747 {
748 	struct snd_compr_runtime *runtime = stream->runtime;
749 	struct q6apm_dai_rtd *prtd = runtime->private_data;
750 	struct device *dev = component->dev;
751 
752 	return dma_mmap_coherent(dev, vma, prtd->dma_buffer.area, prtd->dma_buffer.addr,
753 				 prtd->dma_buffer.bytes);
754 }
755 
756 static int q6apm_compr_copy(struct snd_soc_component *component,
757 			    struct snd_compr_stream *stream, char __user *buf,
758 			    size_t count)
759 {
760 	struct snd_compr_runtime *runtime = stream->runtime;
761 	struct q6apm_dai_rtd *prtd = runtime->private_data;
762 	void *dstn;
763 	unsigned long flags;
764 	size_t copy;
765 	u32 wflags = 0;
766 	u32 app_pointer;
767 	uint64_t bytes_received;
768 	uint64_t temp_bytes_received;
769 	uint32_t bytes_to_write;
770 	uint64_t avail, bytes_in_flight = 0;
771 
772 	bytes_received = prtd->bytes_received;
773 	temp_bytes_received = bytes_received;
774 
775 	/**
776 	 * Make sure that next track data pointer is aligned at 32 bit boundary
777 	 * This is a Mandatory requirement from DSP data buffers alignment
778 	 */
779 	if (prtd->next_track) {
780 		bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count);
781 		temp_bytes_received = bytes_received;
782 	}
783 
784 	app_pointer = do_div(temp_bytes_received, prtd->pcm_size);
785 	dstn = prtd->dma_buffer.area + app_pointer;
786 
787 	if (count < prtd->pcm_size - app_pointer) {
788 		if (copy_from_user(dstn, buf, count))
789 			return -EFAULT;
790 	} else {
791 		copy = prtd->pcm_size - app_pointer;
792 		if (copy_from_user(dstn, buf, copy))
793 			return -EFAULT;
794 		if (copy_from_user(prtd->dma_buffer.area, buf + copy, count - copy))
795 			return -EFAULT;
796 	}
797 
798 	spin_lock_irqsave(&prtd->lock, flags);
799 	bytes_in_flight = prtd->bytes_received - prtd->copied_total;
800 
801 	if (prtd->next_track) {
802 		prtd->next_track = false;
803 		prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count);
804 		prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count);
805 	}
806 
807 	prtd->bytes_received = bytes_received + count;
808 
809 	/* Kick off the data to dsp if its starving!! */
810 	if (prtd->state == Q6APM_STREAM_RUNNING && (bytes_in_flight == 0)) {
811 		bytes_to_write = prtd->pcm_count;
812 		avail = prtd->bytes_received - prtd->bytes_sent;
813 
814 		if (avail < prtd->pcm_count)
815 			bytes_to_write = avail;
816 
817 		q6apm_write_async(prtd->graph, bytes_to_write, 0, 0, wflags);
818 		prtd->bytes_sent += bytes_to_write;
819 	}
820 
821 	spin_unlock_irqrestore(&prtd->lock, flags);
822 
823 	return count;
824 }
825 
826 static const struct snd_compress_ops q6apm_dai_compress_ops = {
827 	.open		= q6apm_dai_compr_open,
828 	.free		= q6apm_dai_compr_free,
829 	.get_caps	= q6apm_dai_compr_get_caps,
830 	.get_codec_caps	= q6apm_dai_compr_get_codec_caps,
831 	.pointer	= q6apm_dai_compr_pointer,
832 	.trigger	= q6apm_dai_compr_trigger,
833 	.ack		= q6apm_dai_compr_ack,
834 	.set_params	= q6apm_dai_compr_set_params,
835 	.set_metadata	= q6apm_dai_compr_set_metadata,
836 	.mmap		= q6apm_dai_compr_mmap,
837 	.copy		= q6apm_compr_copy,
838 };
839 
840 static const struct snd_soc_component_driver q6apm_fe_dai_component = {
841 	.name		= DRV_NAME,
842 	.open		= q6apm_dai_open,
843 	.close		= q6apm_dai_close,
844 	.prepare	= q6apm_dai_prepare,
845 	.pcm_construct	= q6apm_dai_pcm_new,
846 	.hw_params	= q6apm_dai_hw_params,
847 	.pointer	= q6apm_dai_pointer,
848 	.trigger	= q6apm_dai_trigger,
849 	.ack		= q6apm_dai_ack,
850 	.compress_ops	= &q6apm_dai_compress_ops,
851 	.use_dai_pcm_id = true,
852 };
853 
854 static int q6apm_dai_probe(struct platform_device *pdev)
855 {
856 	struct device *dev = &pdev->dev;
857 	struct device_node *node = dev->of_node;
858 	struct q6apm_dai_data *pdata;
859 	struct of_phandle_args args;
860 	int rc;
861 
862 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
863 	if (!pdata)
864 		return -ENOMEM;
865 
866 	rc = of_parse_phandle_with_fixed_args(node, "iommus", 1, 0, &args);
867 	if (rc < 0)
868 		pdata->sid = -1;
869 	else
870 		pdata->sid = args.args[0] & SID_MASK_DEFAULT;
871 
872 	dev_set_drvdata(dev, pdata);
873 
874 	return devm_snd_soc_register_component(dev, &q6apm_fe_dai_component, NULL, 0);
875 }
876 
877 #ifdef CONFIG_OF
878 static const struct of_device_id q6apm_dai_device_id[] = {
879 	{ .compatible = "qcom,q6apm-dais" },
880 	{},
881 };
882 MODULE_DEVICE_TABLE(of, q6apm_dai_device_id);
883 #endif
884 
885 static struct platform_driver q6apm_dai_platform_driver = {
886 	.driver = {
887 		.name = "q6apm-dai",
888 		.of_match_table = of_match_ptr(q6apm_dai_device_id),
889 	},
890 	.probe = q6apm_dai_probe,
891 };
892 module_platform_driver(q6apm_dai_platform_driver);
893 
894 MODULE_DESCRIPTION("Q6APM dai driver");
895 MODULE_LICENSE("GPL");
896