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), ®); 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 int 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 = 0; 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 ret = -EINVAL; 219 goto end; 220 } 221 222 /* dma config for output dma channel */ 223 ret = asrc_dmaconfig(pair, 224 pair->dma_chan[IN], 225 fifo_addr, 226 src_buf->addr, 227 in_buf_len, IN, width); 228 if (ret) { 229 dev_err(dev, "out dma config error\n"); 230 goto end; 231 } 232 233 width = snd_pcm_format_physical_width(pair->sample_format[OUT]); 234 fifo_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index); 235 out_dma_len = asrc->m2m_calc_out_len(pair, in_buf_len); 236 if (out_dma_len > 0 && out_dma_len <= ASRC_M2M_BUFFER_SIZE) { 237 /* dma config for capture dma channel */ 238 ret = asrc_dmaconfig(pair, 239 pair->dma_chan[OUT], 240 fifo_addr, 241 dst_buf->addr, 242 out_dma_len, OUT, width); 243 if (ret) { 244 dev_err(dev, "cap dma config error\n"); 245 goto end; 246 } 247 } else if (out_dma_len > ASRC_M2M_BUFFER_SIZE) { 248 dev_err(dev, "cap buffer size error\n"); 249 ret = -EINVAL; 250 goto end; 251 } 252 253 reinit_completion(&pair->complete[IN]); 254 reinit_completion(&pair->complete[OUT]); 255 256 /* Submit DMA request */ 257 dmaengine_submit(pair->desc[IN]); 258 dma_async_issue_pending(pair->desc[IN]->chan); 259 if (out_dma_len > 0) { 260 dmaengine_submit(pair->desc[OUT]); 261 dma_async_issue_pending(pair->desc[OUT]->chan); 262 } 263 264 asrc->m2m_start(pair); 265 266 if (!wait_for_completion_interruptible_timeout(&pair->complete[IN], 10 * HZ)) { 267 dev_err(dev, "out DMA task timeout\n"); 268 ret = -ETIMEDOUT; 269 goto end; 270 } 271 272 if (out_dma_len > 0) { 273 if (!wait_for_completion_interruptible_timeout(&pair->complete[OUT], 10 * HZ)) { 274 dev_err(dev, "cap DMA task timeout\n"); 275 ret = -ETIMEDOUT; 276 goto end; 277 } 278 } 279 280 /* read the last words from FIFO */ 281 asrc_read_last_fifo(pair, dst_buf->area, &out_dma_len); 282 /* update payload length for capture */ 283 task->output_size = out_dma_len; 284 end: 285 return ret; 286 } 287 288 static int fsl_asrc_m2m_comp_open(struct snd_compr_stream *stream) 289 { 290 struct fsl_asrc *asrc = stream->private_data; 291 struct snd_compr_runtime *runtime = stream->runtime; 292 struct device *dev = &asrc->pdev->dev; 293 struct fsl_asrc_pair *pair; 294 int size, ret; 295 296 pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL); 297 if (!pair) 298 return -ENOMEM; 299 300 pair->private = (void *)pair + sizeof(struct fsl_asrc_pair); 301 pair->asrc = asrc; 302 303 init_completion(&pair->complete[IN]); 304 init_completion(&pair->complete[OUT]); 305 306 runtime->private_data = pair; 307 308 size = ASRC_M2M_BUFFER_SIZE; 309 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &pair->dma_buffer[IN]); 310 if (ret) 311 goto error_alloc_in_buf; 312 313 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, &pair->dma_buffer[OUT]); 314 if (ret) 315 goto error_alloc_out_buf; 316 317 ret = pm_runtime_get_sync(dev); 318 if (ret < 0) { 319 dev_err(dev, "Failed to power up asrc\n"); 320 goto err_pm_runtime; 321 } 322 323 return 0; 324 325 err_pm_runtime: 326 snd_dma_free_pages(&pair->dma_buffer[OUT]); 327 error_alloc_out_buf: 328 snd_dma_free_pages(&pair->dma_buffer[IN]); 329 error_alloc_in_buf: 330 kfree(pair); 331 return ret; 332 } 333 334 static int fsl_asrc_m2m_comp_release(struct snd_compr_stream *stream) 335 { 336 struct fsl_asrc *asrc = stream->private_data; 337 struct snd_compr_runtime *runtime = stream->runtime; 338 struct fsl_asrc_pair *pair = runtime->private_data; 339 struct device *dev = &asrc->pdev->dev; 340 341 pm_runtime_put_sync(dev); 342 343 snd_dma_free_pages(&pair->dma_buffer[IN]); 344 snd_dma_free_pages(&pair->dma_buffer[OUT]); 345 346 kfree(runtime->private_data); 347 348 return 0; 349 } 350 351 static int fsl_asrc_m2m_comp_set_params(struct snd_compr_stream *stream, 352 struct snd_compr_params *params) 353 { 354 struct fsl_asrc *asrc = stream->private_data; 355 struct snd_compr_runtime *runtime = stream->runtime; 356 struct fsl_asrc_pair *pair = runtime->private_data; 357 struct fsl_asrc_m2m_cap cap; 358 int ret, i; 359 360 ret = asrc->m2m_get_cap(&cap); 361 if (ret) 362 return -EINVAL; 363 364 if (pcm_format_to_bits((__force snd_pcm_format_t)params->codec.format) & cap.fmt_in) 365 pair->sample_format[IN] = (__force snd_pcm_format_t)params->codec.format; 366 else 367 return -EINVAL; 368 369 if (pcm_format_to_bits((__force snd_pcm_format_t)params->codec.pcm_format) & cap.fmt_out) 370 pair->sample_format[OUT] = (__force snd_pcm_format_t)params->codec.pcm_format; 371 else 372 return -EINVAL; 373 374 /* check input rate is in scope */ 375 for (i = 0; i < cap.rate_in_count; i++) 376 if (params->codec.sample_rate == cap.rate_in[i]) { 377 pair->rate[IN] = params->codec.sample_rate; 378 break; 379 } 380 if (i == cap.rate_in_count) 381 return -EINVAL; 382 383 /* check output rate is in scope */ 384 for (i = 0; i < cap.rate_out_count; i++) 385 if (params->codec.options.src_d.out_sample_rate == cap.rate_out[i]) { 386 pair->rate[OUT] = params->codec.options.src_d.out_sample_rate; 387 break; 388 } 389 if (i == cap.rate_out_count) 390 return -EINVAL; 391 392 if (params->codec.ch_in != params->codec.ch_out || 393 params->codec.ch_in < cap.chan_min || 394 params->codec.ch_in > cap.chan_max) 395 return -EINVAL; 396 397 pair->channels = params->codec.ch_in; 398 pair->buf_len[IN] = params->buffer.fragment_size; 399 pair->buf_len[OUT] = params->buffer.fragment_size; 400 401 return 0; 402 } 403 404 static int fsl_asrc_m2m_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) 405 { 406 struct snd_dma_buffer *dmab = dmabuf->priv; 407 408 return snd_dma_buffer_mmap(dmab, vma); 409 } 410 411 static struct sg_table *fsl_asrc_m2m_map_dma_buf(struct dma_buf_attachment *attachment, 412 enum dma_data_direction direction) 413 { 414 struct snd_dma_buffer *dmab = attachment->dmabuf->priv; 415 struct sg_table *sgt; 416 417 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); 418 if (!sgt) 419 return NULL; 420 421 if (dma_get_sgtable(attachment->dev, sgt, dmab->area, dmab->addr, dmab->bytes) < 0) 422 goto free; 423 424 if (dma_map_sgtable(attachment->dev, sgt, direction, 0)) 425 goto free; 426 427 return sgt; 428 429 free: 430 sg_free_table(sgt); 431 kfree(sgt); 432 return NULL; 433 } 434 435 static void fsl_asrc_m2m_unmap_dma_buf(struct dma_buf_attachment *attachment, 436 struct sg_table *table, 437 enum dma_data_direction direction) 438 { 439 dma_unmap_sgtable(attachment->dev, table, direction, 0); 440 } 441 442 static void fsl_asrc_m2m_release(struct dma_buf *dmabuf) 443 { 444 /* buffer is released by fsl_asrc_m2m_comp_release() */ 445 } 446 447 static const struct dma_buf_ops fsl_asrc_m2m_dma_buf_ops = { 448 .mmap = fsl_asrc_m2m_mmap, 449 .map_dma_buf = fsl_asrc_m2m_map_dma_buf, 450 .unmap_dma_buf = fsl_asrc_m2m_unmap_dma_buf, 451 .release = fsl_asrc_m2m_release, 452 }; 453 454 static int fsl_asrc_m2m_comp_task_create(struct snd_compr_stream *stream, 455 struct snd_compr_task_runtime *task) 456 { 457 DEFINE_DMA_BUF_EXPORT_INFO(exp_info_in); 458 DEFINE_DMA_BUF_EXPORT_INFO(exp_info_out); 459 struct fsl_asrc *asrc = stream->private_data; 460 struct snd_compr_runtime *runtime = stream->runtime; 461 struct fsl_asrc_pair *pair = runtime->private_data; 462 struct device *dev = &asrc->pdev->dev; 463 int ret; 464 465 exp_info_in.ops = &fsl_asrc_m2m_dma_buf_ops; 466 exp_info_in.size = ASRC_M2M_BUFFER_SIZE; 467 exp_info_in.flags = O_RDWR; 468 exp_info_in.priv = &pair->dma_buffer[IN]; 469 task->input = dma_buf_export(&exp_info_in); 470 if (IS_ERR(task->input)) { 471 ret = PTR_ERR(task->input); 472 return ret; 473 } 474 475 exp_info_out.ops = &fsl_asrc_m2m_dma_buf_ops; 476 exp_info_out.size = ASRC_M2M_BUFFER_SIZE; 477 exp_info_out.flags = O_RDWR; 478 exp_info_out.priv = &pair->dma_buffer[OUT]; 479 task->output = dma_buf_export(&exp_info_out); 480 if (IS_ERR(task->output)) { 481 ret = PTR_ERR(task->output); 482 return ret; 483 } 484 485 /* Request asrc pair/context */ 486 ret = asrc->request_pair(pair->channels, pair); 487 if (ret) { 488 dev_err(dev, "failed to request pair: %d\n", ret); 489 goto err_request_pair; 490 } 491 492 ret = asrc->m2m_prepare(pair); 493 if (ret) { 494 dev_err(dev, "failed to start pair part one: %d\n", ret); 495 goto err_start_part_one; 496 } 497 498 /* Request dma channels */ 499 pair->dma_chan[IN] = asrc->get_dma_channel(pair, IN); 500 if (!pair->dma_chan[IN]) { 501 dev_err(dev, "[ctx%d] failed to get input DMA channel\n", pair->index); 502 ret = -EBUSY; 503 goto err_dma_channel_in; 504 } 505 506 pair->dma_chan[OUT] = asrc->get_dma_channel(pair, OUT); 507 if (!pair->dma_chan[OUT]) { 508 dev_err(dev, "[ctx%d] failed to get output DMA channel\n", pair->index); 509 ret = -EBUSY; 510 goto err_dma_channel_out; 511 } 512 513 return 0; 514 515 err_dma_channel_out: 516 dma_release_channel(pair->dma_chan[IN]); 517 err_dma_channel_in: 518 if (asrc->m2m_unprepare) 519 asrc->m2m_unprepare(pair); 520 err_start_part_one: 521 asrc->release_pair(pair); 522 err_request_pair: 523 return ret; 524 } 525 526 static int fsl_asrc_m2m_comp_task_start(struct snd_compr_stream *stream, 527 struct snd_compr_task_runtime *task) 528 { 529 struct snd_compr_runtime *runtime = stream->runtime; 530 struct fsl_asrc_pair *pair = runtime->private_data; 531 532 return asrc_m2m_device_run(pair, task); 533 } 534 535 static int fsl_asrc_m2m_comp_task_stop(struct snd_compr_stream *stream, 536 struct snd_compr_task_runtime *task) 537 { 538 return 0; 539 } 540 541 static int fsl_asrc_m2m_comp_task_free(struct snd_compr_stream *stream, 542 struct snd_compr_task_runtime *task) 543 { 544 struct fsl_asrc *asrc = stream->private_data; 545 struct snd_compr_runtime *runtime = stream->runtime; 546 struct fsl_asrc_pair *pair = runtime->private_data; 547 548 /* Stop & release pair/context */ 549 if (asrc->m2m_stop) 550 asrc->m2m_stop(pair); 551 552 if (asrc->m2m_unprepare) 553 asrc->m2m_unprepare(pair); 554 asrc->release_pair(pair); 555 556 /* Release dma channel */ 557 if (pair->dma_chan[IN]) 558 dma_release_channel(pair->dma_chan[IN]); 559 if (pair->dma_chan[OUT]) 560 dma_release_channel(pair->dma_chan[OUT]); 561 562 return 0; 563 } 564 565 static int fsl_asrc_m2m_get_caps(struct snd_compr_stream *cstream, 566 struct snd_compr_caps *caps) 567 { 568 caps->num_codecs = 1; 569 caps->min_fragment_size = 4096; 570 caps->max_fragment_size = 4096; 571 caps->min_fragments = 1; 572 caps->max_fragments = 1; 573 caps->codecs[0] = SND_AUDIOCODEC_PCM; 574 575 return 0; 576 } 577 578 static int fsl_asrc_m2m_fill_codec_caps(struct fsl_asrc *asrc, 579 struct snd_compr_codec_caps *codec) 580 { 581 struct fsl_asrc_m2m_cap cap; 582 snd_pcm_format_t k; 583 int j = 0; 584 int ret; 585 586 ret = asrc->m2m_get_cap(&cap); 587 if (ret) 588 return -EINVAL; 589 590 pcm_for_each_format(k) { 591 if (pcm_format_to_bits(k) & cap.fmt_in) { 592 codec->descriptor[j].max_ch = cap.chan_max; 593 memcpy(codec->descriptor[j].sample_rates, 594 cap.rate_in, 595 cap.rate_in_count * sizeof(__u32)); 596 codec->descriptor[j].num_sample_rates = cap.rate_in_count; 597 codec->descriptor[j].formats = (__force __u32)k; 598 codec->descriptor[j].pcm_formats = cap.fmt_out; 599 codec->descriptor[j].src.out_sample_rate_min = cap.rate_out[0]; 600 codec->descriptor[j].src.out_sample_rate_max = 601 cap.rate_out[cap.rate_out_count - 1]; 602 j++; 603 } 604 } 605 606 codec->codec = SND_AUDIOCODEC_PCM; 607 codec->num_descriptors = j; 608 return 0; 609 } 610 611 static int fsl_asrc_m2m_get_codec_caps(struct snd_compr_stream *stream, 612 struct snd_compr_codec_caps *codec) 613 { 614 struct fsl_asrc *asrc = stream->private_data; 615 616 return fsl_asrc_m2m_fill_codec_caps(asrc, codec); 617 } 618 619 static struct snd_compr_ops fsl_asrc_m2m_compr_ops = { 620 .open = fsl_asrc_m2m_comp_open, 621 .free = fsl_asrc_m2m_comp_release, 622 .set_params = fsl_asrc_m2m_comp_set_params, 623 .get_caps = fsl_asrc_m2m_get_caps, 624 .get_codec_caps = fsl_asrc_m2m_get_codec_caps, 625 .task_create = fsl_asrc_m2m_comp_task_create, 626 .task_start = fsl_asrc_m2m_comp_task_start, 627 .task_stop = fsl_asrc_m2m_comp_task_stop, 628 .task_free = fsl_asrc_m2m_comp_task_free, 629 }; 630 631 int fsl_asrc_m2m_suspend(struct fsl_asrc *asrc) 632 { 633 struct fsl_asrc_pair *pair; 634 int i; 635 636 for (i = 0; i < PAIR_CTX_NUM; i++) { 637 pair = asrc->pair[i]; 638 if (!pair || !pair->dma_buffer[IN].area || !pair->dma_buffer[OUT].area) 639 continue; 640 if (!completion_done(&pair->complete[IN])) { 641 if (pair->dma_chan[IN]) 642 dmaengine_terminate_all(pair->dma_chan[IN]); 643 asrc_input_dma_callback((void *)pair); 644 } 645 if (!completion_done(&pair->complete[OUT])) { 646 if (pair->dma_chan[OUT]) 647 dmaengine_terminate_all(pair->dma_chan[OUT]); 648 asrc_output_dma_callback((void *)pair); 649 } 650 651 if (asrc->m2m_pair_suspend) 652 asrc->m2m_pair_suspend(pair); 653 } 654 655 return 0; 656 } 657 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_suspend); 658 659 int fsl_asrc_m2m_resume(struct fsl_asrc *asrc) 660 { 661 struct fsl_asrc_pair *pair; 662 int i; 663 664 for (i = 0; i < PAIR_CTX_NUM; i++) { 665 pair = asrc->pair[i]; 666 if (!pair) 667 continue; 668 if (asrc->m2m_pair_resume) 669 asrc->m2m_pair_resume(pair); 670 } 671 672 return 0; 673 } 674 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_resume); 675 676 int fsl_asrc_m2m_init(struct fsl_asrc *asrc) 677 { 678 struct device *dev = &asrc->pdev->dev; 679 struct snd_card *card; 680 struct snd_compr *compr; 681 int ret; 682 683 ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 684 THIS_MODULE, 0, &card); 685 if (ret < 0) 686 return ret; 687 688 strscpy(card->driver, "fsl-asrc-m2m", sizeof(card->driver)); 689 strscpy(card->shortname, "ASRC-M2M", sizeof(card->shortname)); 690 strscpy(card->longname, "ASRC-M2M", sizeof(card->shortname)); 691 692 asrc->card = card; 693 694 compr = devm_kzalloc(dev, sizeof(*compr), GFP_KERNEL); 695 if (!compr) { 696 ret = -ENOMEM; 697 goto err; 698 } 699 700 compr->ops = &fsl_asrc_m2m_compr_ops; 701 compr->private_data = asrc; 702 703 ret = snd_compress_new(card, 0, SND_COMPRESS_ACCEL, "ASRC M2M", compr); 704 if (ret < 0) 705 goto err; 706 707 ret = snd_card_register(card); 708 if (ret < 0) 709 goto err; 710 711 return 0; 712 err: 713 snd_card_free(card); 714 return ret; 715 } 716 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_init); 717 718 void fsl_asrc_m2m_exit(struct fsl_asrc *asrc) 719 { 720 struct snd_card *card = asrc->card; 721 722 snd_card_free(card); 723 } 724 EXPORT_SYMBOL_GPL(fsl_asrc_m2m_exit); 725 726 MODULE_IMPORT_NS("DMA_BUF"); 727 MODULE_AUTHOR("Shengjiu Wang <Shengjiu.Wang@nxp.com>"); 728 MODULE_DESCRIPTION("Freescale ASRC M2M driver"); 729 MODULE_LICENSE("GPL"); 730