xref: /linux/sound/soc/fsl/fsl_asrc_m2m.c (revision 6b3d638ca897e099fa99bd6d02189d3176f80a47)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
4 // Copyright (C) 2019-2024 NXP
5 //
6 // Freescale ASRC Memory to Memory (M2M) driver
7 
8 #include <linux/dma/imx-dma.h>
9 #include <linux/dma-buf.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/pm_runtime.h>
12 #include <sound/asound.h>
13 #include <sound/dmaengine_pcm.h>
14 #include <sound/initval.h>
15 
16 #include "fsl_asrc_common.h"
17 
18 #define DIR_STR(dir) (dir) == IN ? "in" : "out"
19 
20 #define ASRC_xPUT_DMA_CALLBACK(dir) \
21 	(((dir) == IN) ? asrc_input_dma_callback \
22 	: asrc_output_dma_callback)
23 
24 /* Maximum output and capture buffer size */
25 #define ASRC_M2M_BUFFER_SIZE (512 * 1024)
26 
27 /* Maximum output and capture period size */
28 #define ASRC_M2M_PERIOD_SIZE (48 * 1024)
29 
30 /* dma complete callback */
31 static void asrc_input_dma_callback(void *data)
32 {
33 	struct fsl_asrc_pair *pair = (struct fsl_asrc_pair *)data;
34 
35 	complete(&pair->complete[IN]);
36 }
37 
38 /* dma complete callback */
39 static void asrc_output_dma_callback(void *data)
40 {
41 	struct fsl_asrc_pair *pair = (struct fsl_asrc_pair *)data;
42 
43 	complete(&pair->complete[OUT]);
44 }
45 
46 /**
47  *asrc_read_last_fifo: read all the remaining data from FIFO
48  *@pair: Structure pointer of fsl_asrc_pair
49  *@dma_vaddr: virtual address of capture buffer
50  *@length: payload length of capture buffer
51  */
52 static void asrc_read_last_fifo(struct fsl_asrc_pair *pair, void *dma_vaddr, u32 *length)
53 {
54 	struct fsl_asrc *asrc = pair->asrc;
55 	enum asrc_pair_index index = pair->index;
56 	u32 i, reg, size, t_size = 0, width;
57 	u32 *reg32 = NULL;
58 	u16 *reg16 = NULL;
59 	u8  *reg24 = NULL;
60 
61 	width = snd_pcm_format_physical_width(pair->sample_format[OUT]);
62 	if (width == 32)
63 		reg32 = dma_vaddr + *length;
64 	else if (width == 16)
65 		reg16 = dma_vaddr + *length;
66 	else
67 		reg24 = dma_vaddr + *length;
68 retry:
69 	size = asrc->get_output_fifo_size(pair);
70 	if (size + *length > ASRC_M2M_BUFFER_SIZE)
71 		goto end;
72 
73 	for (i = 0; i < size * pair->channels; i++) {
74 		regmap_read(asrc->regmap, asrc->get_fifo_addr(OUT, index), &reg);
75 		if (reg32) {
76 			*reg32++ = reg;
77 		} else if (reg16) {
78 			*reg16++ = (u16)reg;
79 		} else {
80 			*reg24++ = (u8)reg;
81 			*reg24++ = (u8)(reg >> 8);
82 			*reg24++ = (u8)(reg >> 16);
83 		}
84 	}
85 	t_size += size;
86 
87 	/* In case there is data left in FIFO */
88 	if (size)
89 		goto retry;
90 end:
91 	/* Update payload length */
92 	if (reg32)
93 		*length += t_size * pair->channels * 4;
94 	else if (reg16)
95 		*length += t_size * pair->channels * 2;
96 	else
97 		*length += t_size * pair->channels * 3;
98 }
99 
100 /* config dma channel */
101 static int asrc_dmaconfig(struct fsl_asrc_pair *pair,
102 			  struct dma_chan *chan,
103 			  u32 dma_addr, dma_addr_t buf_addr, u32 buf_len,
104 			  int dir, int width)
105 {
106 	struct fsl_asrc *asrc = pair->asrc;
107 	struct device *dev = &asrc->pdev->dev;
108 	struct dma_slave_config slave_config;
109 	enum dma_slave_buswidth buswidth;
110 	unsigned int sg_len, max_period_size;
111 	struct scatterlist *sg;
112 	int ret, i;
113 
114 	switch (width) {
115 	case 8:
116 		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
117 		break;
118 	case 16:
119 		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
120 		break;
121 	case 24:
122 		buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
123 		break;
124 	case 32:
125 		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
126 		break;
127 	default:
128 		dev_err(dev, "invalid word width\n");
129 		return -EINVAL;
130 	}
131 
132 	memset(&slave_config, 0, sizeof(slave_config));
133 	if (dir == IN) {
134 		slave_config.direction = DMA_MEM_TO_DEV;
135 		slave_config.dst_addr = dma_addr;
136 		slave_config.dst_addr_width = buswidth;
137 		slave_config.dst_maxburst = asrc->m2m_get_maxburst(IN, pair);
138 	} else {
139 		slave_config.direction = DMA_DEV_TO_MEM;
140 		slave_config.src_addr = dma_addr;
141 		slave_config.src_addr_width = buswidth;
142 		slave_config.src_maxburst = asrc->m2m_get_maxburst(OUT, pair);
143 	}
144 
145 	ret = dmaengine_slave_config(chan, &slave_config);
146 	if (ret) {
147 		dev_err(dev, "failed to config dmaengine for %s task: %d\n",
148 			DIR_STR(dir), ret);
149 		return -EINVAL;
150 	}
151 
152 	max_period_size = rounddown(ASRC_M2M_PERIOD_SIZE, width * pair->channels / 8);
153 	/* scatter gather mode */
154 	sg_len = buf_len / max_period_size;
155 	if (buf_len % max_period_size)
156 		sg_len += 1;
157 
158 	sg = kmalloc_array(sg_len, sizeof(*sg), GFP_KERNEL);
159 	if (!sg)
160 		return -ENOMEM;
161 
162 	sg_init_table(sg, sg_len);
163 	for (i = 0; i < (sg_len - 1); i++) {
164 		sg_dma_address(&sg[i]) = buf_addr + i * max_period_size;
165 		sg_dma_len(&sg[i]) = max_period_size;
166 	}
167 	sg_dma_address(&sg[i]) = buf_addr + i * max_period_size;
168 	sg_dma_len(&sg[i]) = buf_len - i * max_period_size;
169 
170 	pair->desc[dir] = dmaengine_prep_slave_sg(chan, sg, sg_len,
171 						  slave_config.direction,
172 						  DMA_PREP_INTERRUPT);
173 	kfree(sg);
174 	if (!pair->desc[dir]) {
175 		dev_err(dev, "failed to prepare dmaengine for %s task\n", DIR_STR(dir));
176 		return -EINVAL;
177 	}
178 
179 	pair->desc[dir]->callback = ASRC_xPUT_DMA_CALLBACK(dir);
180 	pair->desc[dir]->callback_param = pair;
181 
182 	return 0;
183 }
184 
185 /* main function of converter */
186 static void asrc_m2m_device_run(struct fsl_asrc_pair *pair, struct snd_compr_task_runtime *task)
187 {
188 	struct fsl_asrc *asrc = pair->asrc;
189 	struct device *dev = &asrc->pdev->dev;
190 	enum asrc_pair_index index = pair->index;
191 	struct snd_dma_buffer *src_buf, *dst_buf;
192 	unsigned int in_buf_len;
193 	unsigned int out_dma_len;
194 	unsigned int width;
195 	u32 fifo_addr;
196 	int ret;
197 
198 	/* set ratio mod */
199 	if (asrc->m2m_set_ratio_mod) {
200 		if (pair->ratio_mod_flag) {
201 			asrc->m2m_set_ratio_mod(pair, pair->ratio_mod);
202 			pair->ratio_mod_flag = false;
203 		}
204 	}
205 
206 	src_buf = &pair->dma_buffer[IN];
207 	dst_buf = &pair->dma_buffer[OUT];
208 
209 	width = snd_pcm_format_physical_width(pair->sample_format[IN]);
210 	fifo_addr = asrc->paddr + asrc->get_fifo_addr(IN, index);
211 
212 	in_buf_len = task->input_size;
213 
214 	if (in_buf_len < width * pair->channels / 8 ||
215 	    in_buf_len > ASRC_M2M_BUFFER_SIZE ||
216 	    in_buf_len % (width * pair->channels / 8)) {
217 		dev_err(dev, "out buffer size is error: [%d]\n", in_buf_len);
218 		goto end;
219 	}
220 
221 	/* dma config for output dma channel */
222 	ret = asrc_dmaconfig(pair,
223 			     pair->dma_chan[IN],
224 			     fifo_addr,
225 			     src_buf->addr,
226 			     in_buf_len, IN, width);
227 	if (ret) {
228 		dev_err(dev, "out dma config error\n");
229 		goto end;
230 	}
231 
232 	width = snd_pcm_format_physical_width(pair->sample_format[OUT]);
233 	fifo_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index);
234 	out_dma_len = asrc->m2m_calc_out_len(pair, in_buf_len);
235 	if (out_dma_len > 0 && out_dma_len <= ASRC_M2M_BUFFER_SIZE) {
236 		/* dma config for capture dma channel */
237 		ret = asrc_dmaconfig(pair,
238 				     pair->dma_chan[OUT],
239 				     fifo_addr,
240 				     dst_buf->addr,
241 				     out_dma_len, OUT, width);
242 		if (ret) {
243 			dev_err(dev, "cap dma config error\n");
244 			goto end;
245 		}
246 	} else if (out_dma_len > ASRC_M2M_BUFFER_SIZE) {
247 		dev_err(dev, "cap buffer size error\n");
248 		goto end;
249 	}
250 
251 	reinit_completion(&pair->complete[IN]);
252 	reinit_completion(&pair->complete[OUT]);
253 
254 	/* Submit DMA request */
255 	dmaengine_submit(pair->desc[IN]);
256 	dma_async_issue_pending(pair->desc[IN]->chan);
257 	if (out_dma_len > 0) {
258 		dmaengine_submit(pair->desc[OUT]);
259 		dma_async_issue_pending(pair->desc[OUT]->chan);
260 	}
261 
262 	asrc->m2m_start(pair);
263 
264 	if (!wait_for_completion_interruptible_timeout(&pair->complete[IN], 10 * HZ)) {
265 		dev_err(dev, "out DMA task timeout\n");
266 		goto end;
267 	}
268 
269 	if (out_dma_len > 0) {
270 		if (!wait_for_completion_interruptible_timeout(&pair->complete[OUT], 10 * HZ)) {
271 			dev_err(dev, "cap DMA task timeout\n");
272 			goto end;
273 		}
274 	}
275 
276 	/* read the last words from FIFO */
277 	asrc_read_last_fifo(pair, dst_buf->area, &out_dma_len);
278 	/* update payload length for capture */
279 	task->output_size = out_dma_len;
280 end:
281 	return;
282 }
283 
284 static int fsl_asrc_m2m_comp_open(struct snd_compr_stream *stream)
285 {
286 	struct fsl_asrc *asrc = stream->private_data;
287 	struct snd_compr_runtime *runtime = stream->runtime;
288 	struct device *dev = &asrc->pdev->dev;
289 	struct fsl_asrc_pair *pair;
290 	int size, ret;
291 
292 	pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL);
293 	if (!pair)
294 		return -ENOMEM;
295 
296 	pair->private = (void *)pair + sizeof(struct fsl_asrc_pair);
297 	pair->asrc = asrc;
298 
299 	init_completion(&pair->complete[IN]);
300 	init_completion(&pair->complete[OUT]);
301 
302 	runtime->private_data = pair;
303 
304 	size = ASRC_M2M_BUFFER_SIZE;
305 	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &pair->dma_buffer[IN]);
306 	if (ret)
307 		goto error_alloc_in_buf;
308 
309 	ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &pair->dma_buffer[OUT]);
310 	if (ret)
311 		goto error_alloc_out_buf;
312 
313 	ret = pm_runtime_get_sync(dev);
314 	if (ret < 0) {
315 		dev_err(dev, "Failed to power up asrc\n");
316 		goto err_pm_runtime;
317 	}
318 
319 	return 0;
320 
321 err_pm_runtime:
322 	snd_dma_free_pages(&pair->dma_buffer[OUT]);
323 error_alloc_out_buf:
324 	snd_dma_free_pages(&pair->dma_buffer[IN]);
325 error_alloc_in_buf:
326 	kfree(pair);
327 	return ret;
328 }
329 
330 static int fsl_asrc_m2m_comp_release(struct snd_compr_stream *stream)
331 {
332 	struct fsl_asrc *asrc = stream->private_data;
333 	struct snd_compr_runtime *runtime = stream->runtime;
334 	struct fsl_asrc_pair *pair = runtime->private_data;
335 	struct device *dev = &asrc->pdev->dev;
336 
337 	pm_runtime_put_sync(dev);
338 
339 	snd_dma_free_pages(&pair->dma_buffer[IN]);
340 	snd_dma_free_pages(&pair->dma_buffer[OUT]);
341 
342 	kfree(runtime->private_data);
343 
344 	return 0;
345 }
346 
347 static int fsl_asrc_m2m_comp_set_params(struct snd_compr_stream *stream,
348 					struct snd_compr_params *params)
349 {
350 	struct fsl_asrc *asrc = stream->private_data;
351 	struct snd_compr_runtime *runtime = stream->runtime;
352 	struct fsl_asrc_pair *pair = runtime->private_data;
353 	struct fsl_asrc_m2m_cap cap;
354 	int ret, i;
355 
356 	ret = asrc->m2m_get_cap(&cap);
357 	if (ret)
358 		return -EINVAL;
359 
360 	if (pcm_format_to_bits((__force snd_pcm_format_t)params->codec.format) & cap.fmt_in)
361 		pair->sample_format[IN] = (__force snd_pcm_format_t)params->codec.format;
362 	else
363 		return -EINVAL;
364 
365 	if (pcm_format_to_bits((__force snd_pcm_format_t)params->codec.pcm_format) & cap.fmt_out)
366 		pair->sample_format[OUT] = (__force snd_pcm_format_t)params->codec.pcm_format;
367 	else
368 		return -EINVAL;
369 
370 	/* check input rate is in scope */
371 	for (i = 0; i < cap.rate_in_count; i++)
372 		if (params->codec.sample_rate == cap.rate_in[i]) {
373 			pair->rate[IN] = params->codec.sample_rate;
374 			break;
375 		}
376 	if (i == cap.rate_in_count)
377 		return -EINVAL;
378 
379 	/* check output rate is in scope */
380 	for (i = 0; i < cap.rate_out_count; i++)
381 		if (params->codec.options.src_d.out_sample_rate == cap.rate_out[i]) {
382 			pair->rate[OUT] = params->codec.options.src_d.out_sample_rate;
383 			break;
384 		}
385 	if (i == cap.rate_out_count)
386 		return -EINVAL;
387 
388 	if (params->codec.ch_in != params->codec.ch_out ||
389 	    params->codec.ch_in < cap.chan_min ||
390 	    params->codec.ch_in > cap.chan_max)
391 		return -EINVAL;
392 
393 	pair->channels = params->codec.ch_in;
394 	pair->buf_len[IN] = params->buffer.fragment_size;
395 	pair->buf_len[OUT] = params->buffer.fragment_size;
396 
397 	return 0;
398 }
399 
400 static int fsl_asrc_m2m_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
401 {
402 	struct snd_dma_buffer *dmab = dmabuf->priv;
403 
404 	return snd_dma_buffer_mmap(dmab, vma);
405 }
406 
407 static struct sg_table *fsl_asrc_m2m_map_dma_buf(struct dma_buf_attachment *attachment,
408 						 enum dma_data_direction direction)
409 {
410 	struct snd_dma_buffer *dmab = attachment->dmabuf->priv;
411 	struct sg_table *sgt;
412 
413 	sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
414 	if (!sgt)
415 		return NULL;
416 
417 	if (dma_get_sgtable(attachment->dev, sgt, dmab->area, dmab->addr, dmab->bytes) < 0)
418 		goto free;
419 
420 	if (dma_map_sgtable(attachment->dev, sgt, direction, 0))
421 		goto free;
422 
423 	return sgt;
424 
425 free:
426 	sg_free_table(sgt);
427 	kfree(sgt);
428 	return NULL;
429 }
430 
431 static void fsl_asrc_m2m_unmap_dma_buf(struct dma_buf_attachment *attachment,
432 				       struct sg_table *table,
433 				       enum dma_data_direction direction)
434 {
435 	dma_unmap_sgtable(attachment->dev, table, direction, 0);
436 }
437 
438 static void fsl_asrc_m2m_release(struct dma_buf *dmabuf)
439 {
440 	/* buffer is released by fsl_asrc_m2m_comp_release() */
441 }
442 
443 static const struct dma_buf_ops fsl_asrc_m2m_dma_buf_ops = {
444 	.mmap = fsl_asrc_m2m_mmap,
445 	.map_dma_buf = fsl_asrc_m2m_map_dma_buf,
446 	.unmap_dma_buf = fsl_asrc_m2m_unmap_dma_buf,
447 	.release = fsl_asrc_m2m_release,
448 };
449 
450 static int fsl_asrc_m2m_comp_task_create(struct snd_compr_stream *stream,
451 					 struct snd_compr_task_runtime *task)
452 {
453 	DEFINE_DMA_BUF_EXPORT_INFO(exp_info_in);
454 	DEFINE_DMA_BUF_EXPORT_INFO(exp_info_out);
455 	struct fsl_asrc *asrc = stream->private_data;
456 	struct snd_compr_runtime *runtime = stream->runtime;
457 	struct fsl_asrc_pair *pair = runtime->private_data;
458 	struct device *dev = &asrc->pdev->dev;
459 	int ret;
460 
461 	exp_info_in.ops = &fsl_asrc_m2m_dma_buf_ops;
462 	exp_info_in.size = ASRC_M2M_BUFFER_SIZE;
463 	exp_info_in.flags = O_RDWR;
464 	exp_info_in.priv = &pair->dma_buffer[IN];
465 	task->input = dma_buf_export(&exp_info_in);
466 	if (IS_ERR(task->input)) {
467 		ret = PTR_ERR(task->input);
468 		return ret;
469 	}
470 
471 	exp_info_out.ops = &fsl_asrc_m2m_dma_buf_ops;
472 	exp_info_out.size = ASRC_M2M_BUFFER_SIZE;
473 	exp_info_out.flags = O_RDWR;
474 	exp_info_out.priv = &pair->dma_buffer[OUT];
475 	task->output = dma_buf_export(&exp_info_out);
476 	if (IS_ERR(task->output)) {
477 		ret = PTR_ERR(task->output);
478 		return ret;
479 	}
480 
481 	/* Request asrc pair/context */
482 	ret = asrc->request_pair(pair->channels, pair);
483 	if (ret) {
484 		dev_err(dev, "failed to request pair: %d\n", ret);
485 		goto err_request_pair;
486 	}
487 
488 	ret = asrc->m2m_prepare(pair);
489 	if (ret) {
490 		dev_err(dev, "failed to start pair part one: %d\n", ret);
491 		goto err_start_part_one;
492 	}
493 
494 	/* Request dma channels */
495 	pair->dma_chan[IN] = asrc->get_dma_channel(pair, IN);
496 	if (!pair->dma_chan[IN]) {
497 		dev_err(dev, "[ctx%d] failed to get input DMA channel\n", pair->index);
498 		ret = -EBUSY;
499 		goto err_dma_channel_in;
500 	}
501 
502 	pair->dma_chan[OUT] = asrc->get_dma_channel(pair, OUT);
503 	if (!pair->dma_chan[OUT]) {
504 		dev_err(dev, "[ctx%d] failed to get output DMA channel\n", pair->index);
505 		ret = -EBUSY;
506 		goto err_dma_channel_out;
507 	}
508 
509 	return 0;
510 
511 err_dma_channel_out:
512 	dma_release_channel(pair->dma_chan[IN]);
513 err_dma_channel_in:
514 	if (asrc->m2m_unprepare)
515 		asrc->m2m_unprepare(pair);
516 err_start_part_one:
517 	asrc->release_pair(pair);
518 err_request_pair:
519 	return ret;
520 }
521 
522 static int fsl_asrc_m2m_comp_task_start(struct snd_compr_stream *stream,
523 					struct snd_compr_task_runtime *task)
524 {
525 	struct snd_compr_runtime *runtime = stream->runtime;
526 	struct fsl_asrc_pair *pair = runtime->private_data;
527 
528 	asrc_m2m_device_run(pair, task);
529 
530 	return 0;
531 }
532 
533 static int fsl_asrc_m2m_comp_task_stop(struct snd_compr_stream *stream,
534 				       struct snd_compr_task_runtime *task)
535 {
536 	return 0;
537 }
538 
539 static int fsl_asrc_m2m_comp_task_free(struct snd_compr_stream *stream,
540 				       struct snd_compr_task_runtime *task)
541 {
542 	struct fsl_asrc *asrc = stream->private_data;
543 	struct snd_compr_runtime *runtime = stream->runtime;
544 	struct fsl_asrc_pair *pair = runtime->private_data;
545 
546 	/* Stop & release pair/context */
547 	if (asrc->m2m_stop)
548 		asrc->m2m_stop(pair);
549 
550 	if (asrc->m2m_unprepare)
551 		asrc->m2m_unprepare(pair);
552 	asrc->release_pair(pair);
553 
554 	/* Release dma channel */
555 	if (pair->dma_chan[IN])
556 		dma_release_channel(pair->dma_chan[IN]);
557 	if (pair->dma_chan[OUT])
558 		dma_release_channel(pair->dma_chan[OUT]);
559 
560 	return 0;
561 }
562 
563 static int fsl_asrc_m2m_get_caps(struct snd_compr_stream *cstream,
564 				 struct snd_compr_caps *caps)
565 {
566 	caps->num_codecs = 1;
567 	caps->min_fragment_size = 4096;
568 	caps->max_fragment_size = 4096;
569 	caps->min_fragments = 1;
570 	caps->max_fragments = 1;
571 	caps->codecs[0] = SND_AUDIOCODEC_PCM;
572 
573 	return 0;
574 }
575 
576 static int fsl_asrc_m2m_fill_codec_caps(struct fsl_asrc *asrc,
577 					struct snd_compr_codec_caps *codec)
578 {
579 	struct fsl_asrc_m2m_cap cap;
580 	snd_pcm_format_t k;
581 	int j = 0;
582 	int ret;
583 
584 	ret = asrc->m2m_get_cap(&cap);
585 	if (ret)
586 		return -EINVAL;
587 
588 	pcm_for_each_format(k) {
589 		if (pcm_format_to_bits(k) & cap.fmt_in) {
590 			codec->descriptor[j].max_ch = cap.chan_max;
591 			memcpy(codec->descriptor[j].sample_rates,
592 			       cap.rate_in,
593 			       cap.rate_in_count * sizeof(__u32));
594 			codec->descriptor[j].num_sample_rates = cap.rate_in_count;
595 			codec->descriptor[j].formats = (__force __u32)k;
596 			codec->descriptor[j].pcm_formats = cap.fmt_out;
597 			codec->descriptor[j].src.out_sample_rate_min = cap.rate_out[0];
598 			codec->descriptor[j].src.out_sample_rate_max =
599 				cap.rate_out[cap.rate_out_count - 1];
600 			j++;
601 		}
602 	}
603 
604 	codec->codec = SND_AUDIOCODEC_PCM;
605 	codec->num_descriptors = j;
606 	return 0;
607 }
608 
609 static int fsl_asrc_m2m_get_codec_caps(struct snd_compr_stream *stream,
610 				       struct snd_compr_codec_caps *codec)
611 {
612 	struct fsl_asrc *asrc = stream->private_data;
613 
614 	return fsl_asrc_m2m_fill_codec_caps(asrc, codec);
615 }
616 
617 static struct snd_compr_ops fsl_asrc_m2m_compr_ops = {
618 	.open = fsl_asrc_m2m_comp_open,
619 	.free = fsl_asrc_m2m_comp_release,
620 	.set_params = fsl_asrc_m2m_comp_set_params,
621 	.get_caps = fsl_asrc_m2m_get_caps,
622 	.get_codec_caps = fsl_asrc_m2m_get_codec_caps,
623 	.task_create = fsl_asrc_m2m_comp_task_create,
624 	.task_start = fsl_asrc_m2m_comp_task_start,
625 	.task_stop = fsl_asrc_m2m_comp_task_stop,
626 	.task_free = fsl_asrc_m2m_comp_task_free,
627 };
628 
629 int fsl_asrc_m2m_suspend(struct fsl_asrc *asrc)
630 {
631 	struct fsl_asrc_pair *pair;
632 	int i;
633 
634 	for (i = 0; i < PAIR_CTX_NUM; i++) {
635 		pair = asrc->pair[i];
636 		if (!pair)
637 			continue;
638 		if (!completion_done(&pair->complete[IN])) {
639 			if (pair->dma_chan[IN])
640 				dmaengine_terminate_all(pair->dma_chan[IN]);
641 			asrc_input_dma_callback((void *)pair);
642 		}
643 		if (!completion_done(&pair->complete[OUT])) {
644 			if (pair->dma_chan[OUT])
645 				dmaengine_terminate_all(pair->dma_chan[OUT]);
646 			asrc_output_dma_callback((void *)pair);
647 		}
648 
649 		if (asrc->m2m_pair_suspend)
650 			asrc->m2m_pair_suspend(pair);
651 	}
652 
653 	return 0;
654 }
655 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_suspend);
656 
657 int fsl_asrc_m2m_resume(struct fsl_asrc *asrc)
658 {
659 	struct fsl_asrc_pair *pair;
660 	int i;
661 
662 	for (i = 0; i < PAIR_CTX_NUM; i++) {
663 		pair = asrc->pair[i];
664 		if (!pair)
665 			continue;
666 		if (asrc->m2m_pair_resume)
667 			asrc->m2m_pair_resume(pair);
668 	}
669 
670 	return 0;
671 }
672 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_resume);
673 
674 int fsl_asrc_m2m_init(struct fsl_asrc *asrc)
675 {
676 	struct device *dev = &asrc->pdev->dev;
677 	struct snd_card *card;
678 	struct snd_compr *compr;
679 	int ret;
680 
681 	ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
682 			   THIS_MODULE, 0, &card);
683 	if (ret < 0)
684 		return ret;
685 
686 	strscpy(card->driver, "fsl-asrc-m2m", sizeof(card->driver));
687 	strscpy(card->shortname, "ASRC-M2M", sizeof(card->shortname));
688 	strscpy(card->longname, "ASRC-M2M", sizeof(card->shortname));
689 
690 	asrc->card = card;
691 
692 	compr = devm_kzalloc(dev, sizeof(*compr), GFP_KERNEL);
693 	if (!compr) {
694 		ret = -ENOMEM;
695 		goto err;
696 	}
697 
698 	compr->ops = &fsl_asrc_m2m_compr_ops;
699 	compr->private_data = asrc;
700 
701 	ret = snd_compress_new(card, 0, SND_COMPRESS_ACCEL, "ASRC M2M", compr);
702 	if (ret < 0)
703 		goto err;
704 
705 	ret = snd_card_register(card);
706 	if (ret < 0)
707 		goto err;
708 
709 	return 0;
710 err:
711 	snd_card_free(card);
712 	return ret;
713 }
714 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_init);
715 
716 void fsl_asrc_m2m_exit(struct fsl_asrc *asrc)
717 {
718 	struct snd_card *card = asrc->card;
719 
720 	snd_card_free(card);
721 }
722 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_exit);
723 
724 MODULE_IMPORT_NS("DMA_BUF");
725 MODULE_AUTHOR("Shengjiu Wang <Shengjiu.Wang@nxp.com>");
726 MODULE_DESCRIPTION("Freescale ASRC M2M driver");
727 MODULE_LICENSE("GPL");
728