fsl_asrc_m2m.c 19 KB

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