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