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