mpc5200_dma.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. /*
  2. * Freescale MPC5200 PSC DMA
  3. * ALSA SoC Platform driver
  4. *
  5. * Copyright (C) 2008 Secret Lab Technologies Ltd.
  6. * Copyright (C) 2009 Jon Smirl, Digispeaker
  7. */
  8. #include <linux/module.h>
  9. #include <linux/of_device.h>
  10. #include <sound/soc.h>
  11. #include <sysdev/bestcomm/bestcomm.h>
  12. #include <sysdev/bestcomm/gen_bd.h>
  13. #include <asm/mpc52xx_psc.h>
  14. #include "mpc5200_dma.h"
  15. /*
  16. * Interrupt handlers
  17. */
  18. static irqreturn_t psc_dma_status_irq(int irq, void *_psc_dma)
  19. {
  20. struct psc_dma *psc_dma = _psc_dma;
  21. struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
  22. u16 isr;
  23. isr = in_be16(&regs->mpc52xx_psc_isr);
  24. /* Playback underrun error */
  25. if (psc_dma->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP))
  26. psc_dma->stats.underrun_count++;
  27. /* Capture overrun error */
  28. if (psc_dma->capture.active && (isr & MPC52xx_PSC_IMR_ORERR))
  29. psc_dma->stats.overrun_count++;
  30. out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
  31. return IRQ_HANDLED;
  32. }
  33. /**
  34. * psc_dma_bcom_enqueue_next_buffer - Enqueue another audio buffer
  35. * @s: pointer to stream private data structure
  36. *
  37. * Enqueues another audio period buffer into the bestcomm queue.
  38. *
  39. * Note: The routine must only be called when there is space available in
  40. * the queue. Otherwise the enqueue will fail and the audio ring buffer
  41. * will get out of sync
  42. */
  43. static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
  44. {
  45. struct bcom_bd *bd;
  46. /* Prepare and enqueue the next buffer descriptor */
  47. bd = bcom_prepare_next_buffer(s->bcom_task);
  48. bd->status = s->period_bytes;
  49. bd->data[0] = s->period_next_pt;
  50. bcom_submit_next_buffer(s->bcom_task, NULL);
  51. /* Update for next period */
  52. s->period_next_pt += s->period_bytes;
  53. if (s->period_next_pt >= s->period_end)
  54. s->period_next_pt = s->period_start;
  55. }
  56. static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s)
  57. {
  58. if (s->appl_ptr > s->runtime->control->appl_ptr) {
  59. /*
  60. * In this case s->runtime->control->appl_ptr has wrapped around.
  61. * Play the data to the end of the boundary, then wrap our own
  62. * appl_ptr back around.
  63. */
  64. while (s->appl_ptr < s->runtime->boundary) {
  65. if (bcom_queue_full(s->bcom_task))
  66. return;
  67. s->appl_ptr += s->period_size;
  68. psc_dma_bcom_enqueue_next_buffer(s);
  69. }
  70. s->appl_ptr -= s->runtime->boundary;
  71. }
  72. while (s->appl_ptr < s->runtime->control->appl_ptr) {
  73. if (bcom_queue_full(s->bcom_task))
  74. return;
  75. s->appl_ptr += s->period_size;
  76. psc_dma_bcom_enqueue_next_buffer(s);
  77. }
  78. }
  79. /* Bestcomm DMA irq handler */
  80. static irqreturn_t psc_dma_bcom_irq_tx(int irq, void *_psc_dma_stream)
  81. {
  82. struct psc_dma_stream *s = _psc_dma_stream;
  83. spin_lock(&s->psc_dma->lock);
  84. /* For each finished period, dequeue the completed period buffer
  85. * and enqueue a new one in it's place. */
  86. while (bcom_buffer_done(s->bcom_task)) {
  87. bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
  88. s->period_current_pt += s->period_bytes;
  89. if (s->period_current_pt >= s->period_end)
  90. s->period_current_pt = s->period_start;
  91. }
  92. psc_dma_bcom_enqueue_tx(s);
  93. spin_unlock(&s->psc_dma->lock);
  94. /* If the stream is active, then also inform the PCM middle layer
  95. * of the period finished event. */
  96. if (s->active)
  97. snd_pcm_period_elapsed(s->stream);
  98. return IRQ_HANDLED;
  99. }
  100. static irqreturn_t psc_dma_bcom_irq_rx(int irq, void *_psc_dma_stream)
  101. {
  102. struct psc_dma_stream *s = _psc_dma_stream;
  103. spin_lock(&s->psc_dma->lock);
  104. /* For each finished period, dequeue the completed period buffer
  105. * and enqueue a new one in it's place. */
  106. while (bcom_buffer_done(s->bcom_task)) {
  107. bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
  108. s->period_current_pt += s->period_bytes;
  109. if (s->period_current_pt >= s->period_end)
  110. s->period_current_pt = s->period_start;
  111. psc_dma_bcom_enqueue_next_buffer(s);
  112. }
  113. spin_unlock(&s->psc_dma->lock);
  114. /* If the stream is active, then also inform the PCM middle layer
  115. * of the period finished event. */
  116. if (s->active)
  117. snd_pcm_period_elapsed(s->stream);
  118. return IRQ_HANDLED;
  119. }
  120. static int psc_dma_hw_free(struct snd_pcm_substream *substream)
  121. {
  122. snd_pcm_set_runtime_buffer(substream, NULL);
  123. return 0;
  124. }
  125. /**
  126. * psc_dma_trigger: start and stop the DMA transfer.
  127. *
  128. * This function is called by ALSA to start, stop, pause, and resume the DMA
  129. * transfer of data.
  130. */
  131. static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
  132. {
  133. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  134. struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
  135. struct snd_pcm_runtime *runtime = substream->runtime;
  136. struct psc_dma_stream *s;
  137. struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
  138. u16 imr;
  139. unsigned long flags;
  140. int i;
  141. if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
  142. s = &psc_dma->capture;
  143. else
  144. s = &psc_dma->playback;
  145. dev_dbg(psc_dma->dev, "psc_dma_trigger(substream=%p, cmd=%i)"
  146. " stream_id=%i\n",
  147. substream, cmd, substream->pstr->stream);
  148. switch (cmd) {
  149. case SNDRV_PCM_TRIGGER_START:
  150. s->period_bytes = frames_to_bytes(runtime,
  151. runtime->period_size);
  152. s->period_start = virt_to_phys(runtime->dma_area);
  153. s->period_end = s->period_start +
  154. (s->period_bytes * runtime->periods);
  155. s->period_next_pt = s->period_start;
  156. s->period_current_pt = s->period_start;
  157. s->period_size = runtime->period_size;
  158. s->active = 1;
  159. /* track appl_ptr so that we have a better chance of detecting
  160. * end of stream and not over running it.
  161. */
  162. s->runtime = runtime;
  163. s->appl_ptr = s->runtime->control->appl_ptr -
  164. (runtime->period_size * runtime->periods);
  165. /* Fill up the bestcomm bd queue and enable DMA.
  166. * This will begin filling the PSC's fifo.
  167. */
  168. spin_lock_irqsave(&psc_dma->lock, flags);
  169. if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) {
  170. bcom_gen_bd_rx_reset(s->bcom_task);
  171. for (i = 0; i < runtime->periods; i++)
  172. if (!bcom_queue_full(s->bcom_task))
  173. psc_dma_bcom_enqueue_next_buffer(s);
  174. } else {
  175. bcom_gen_bd_tx_reset(s->bcom_task);
  176. psc_dma_bcom_enqueue_tx(s);
  177. }
  178. bcom_enable(s->bcom_task);
  179. spin_unlock_irqrestore(&psc_dma->lock, flags);
  180. out_8(&regs->command, MPC52xx_PSC_RST_ERR_STAT);
  181. break;
  182. case SNDRV_PCM_TRIGGER_STOP:
  183. s->active = 0;
  184. spin_lock_irqsave(&psc_dma->lock, flags);
  185. bcom_disable(s->bcom_task);
  186. if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
  187. bcom_gen_bd_rx_reset(s->bcom_task);
  188. else
  189. bcom_gen_bd_tx_reset(s->bcom_task);
  190. spin_unlock_irqrestore(&psc_dma->lock, flags);
  191. break;
  192. default:
  193. dev_dbg(psc_dma->dev, "invalid command\n");
  194. return -EINVAL;
  195. }
  196. /* Update interrupt enable settings */
  197. imr = 0;
  198. if (psc_dma->playback.active)
  199. imr |= MPC52xx_PSC_IMR_TXEMP;
  200. if (psc_dma->capture.active)
  201. imr |= MPC52xx_PSC_IMR_ORERR;
  202. out_be16(&regs->isr_imr.imr, psc_dma->imr | imr);
  203. return 0;
  204. }
  205. /* ---------------------------------------------------------------------
  206. * The PSC DMA 'ASoC platform' driver
  207. *
  208. * Can be referenced by an 'ASoC machine' driver
  209. * This driver only deals with the audio bus; it doesn't have any
  210. * interaction with the attached codec
  211. */
  212. static const struct snd_pcm_hardware psc_dma_hardware = {
  213. .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
  214. SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  215. SNDRV_PCM_INFO_BATCH,
  216. .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
  217. SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
  218. .rate_min = 8000,
  219. .rate_max = 48000,
  220. .channels_min = 1,
  221. .channels_max = 2,
  222. .period_bytes_max = 1024 * 1024,
  223. .period_bytes_min = 32,
  224. .periods_min = 2,
  225. .periods_max = 256,
  226. .buffer_bytes_max = 2 * 1024 * 1024,
  227. .fifo_size = 512,
  228. };
  229. static int psc_dma_open(struct snd_pcm_substream *substream)
  230. {
  231. struct snd_pcm_runtime *runtime = substream->runtime;
  232. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  233. struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
  234. struct psc_dma_stream *s;
  235. int rc;
  236. dev_dbg(psc_dma->dev, "psc_dma_open(substream=%p)\n", substream);
  237. if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
  238. s = &psc_dma->capture;
  239. else
  240. s = &psc_dma->playback;
  241. snd_soc_set_runtime_hwparams(substream, &psc_dma_hardware);
  242. rc = snd_pcm_hw_constraint_integer(runtime,
  243. SNDRV_PCM_HW_PARAM_PERIODS);
  244. if (rc < 0) {
  245. dev_err(substream->pcm->card->dev, "invalid buffer size\n");
  246. return rc;
  247. }
  248. s->stream = substream;
  249. return 0;
  250. }
  251. static int psc_dma_close(struct snd_pcm_substream *substream)
  252. {
  253. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  254. struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
  255. struct psc_dma_stream *s;
  256. dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream);
  257. if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
  258. s = &psc_dma->capture;
  259. else
  260. s = &psc_dma->playback;
  261. if (!psc_dma->playback.active &&
  262. !psc_dma->capture.active) {
  263. /* Disable all interrupts and reset the PSC */
  264. out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
  265. out_8(&psc_dma->psc_regs->command, 4 << 4); /* reset error */
  266. }
  267. s->stream = NULL;
  268. return 0;
  269. }
  270. static snd_pcm_uframes_t
  271. psc_dma_pointer(struct snd_pcm_substream *substream)
  272. {
  273. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  274. struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
  275. struct psc_dma_stream *s;
  276. dma_addr_t count;
  277. if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
  278. s = &psc_dma->capture;
  279. else
  280. s = &psc_dma->playback;
  281. count = s->period_current_pt - s->period_start;
  282. return bytes_to_frames(substream->runtime, count);
  283. }
  284. static int
  285. psc_dma_hw_params(struct snd_pcm_substream *substream,
  286. struct snd_pcm_hw_params *params)
  287. {
  288. snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  289. return 0;
  290. }
  291. static struct snd_pcm_ops psc_dma_ops = {
  292. .open = psc_dma_open,
  293. .close = psc_dma_close,
  294. .hw_free = psc_dma_hw_free,
  295. .ioctl = snd_pcm_lib_ioctl,
  296. .pointer = psc_dma_pointer,
  297. .trigger = psc_dma_trigger,
  298. .hw_params = psc_dma_hw_params,
  299. };
  300. static u64 psc_dma_dmamask = 0xffffffff;
  301. static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
  302. struct snd_pcm *pcm)
  303. {
  304. struct snd_soc_pcm_runtime *rtd = pcm->private_data;
  305. struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
  306. size_t size = psc_dma_hardware.buffer_bytes_max;
  307. int rc = 0;
  308. dev_dbg(rtd->socdev->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
  309. card, dai, pcm);
  310. if (!card->dev->dma_mask)
  311. card->dev->dma_mask = &psc_dma_dmamask;
  312. if (!card->dev->coherent_dma_mask)
  313. card->dev->coherent_dma_mask = 0xffffffff;
  314. if (pcm->streams[0].substream) {
  315. rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  316. size, &pcm->streams[0].substream->dma_buffer);
  317. if (rc)
  318. goto playback_alloc_err;
  319. }
  320. if (pcm->streams[1].substream) {
  321. rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
  322. size, &pcm->streams[1].substream->dma_buffer);
  323. if (rc)
  324. goto capture_alloc_err;
  325. }
  326. if (rtd->socdev->card->codec->ac97)
  327. rtd->socdev->card->codec->ac97->private_data = psc_dma;
  328. return 0;
  329. capture_alloc_err:
  330. if (pcm->streams[0].substream)
  331. snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer);
  332. playback_alloc_err:
  333. dev_err(card->dev, "Cannot allocate buffer(s)\n");
  334. return -ENOMEM;
  335. }
  336. static void psc_dma_free(struct snd_pcm *pcm)
  337. {
  338. struct snd_soc_pcm_runtime *rtd = pcm->private_data;
  339. struct snd_pcm_substream *substream;
  340. int stream;
  341. dev_dbg(rtd->socdev->dev, "psc_dma_free(pcm=%p)\n", pcm);
  342. for (stream = 0; stream < 2; stream++) {
  343. substream = pcm->streams[stream].substream;
  344. if (substream) {
  345. snd_dma_free_pages(&substream->dma_buffer);
  346. substream->dma_buffer.area = NULL;
  347. substream->dma_buffer.addr = 0;
  348. }
  349. }
  350. }
  351. struct snd_soc_platform mpc5200_audio_dma_platform = {
  352. .name = "mpc5200-psc-audio",
  353. .pcm_ops = &psc_dma_ops,
  354. .pcm_new = &psc_dma_new,
  355. .pcm_free = &psc_dma_free,
  356. };
  357. EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform);
  358. int mpc5200_audio_dma_create(struct of_device *op)
  359. {
  360. phys_addr_t fifo;
  361. struct psc_dma *psc_dma;
  362. struct resource res;
  363. int size, irq, rc;
  364. const __be32 *prop;
  365. void __iomem *regs;
  366. int ret;
  367. /* Fetch the registers and IRQ of the PSC */
  368. irq = irq_of_parse_and_map(op->node, 0);
  369. if (of_address_to_resource(op->node, 0, &res)) {
  370. dev_err(&op->dev, "Missing reg property\n");
  371. return -ENODEV;
  372. }
  373. regs = ioremap(res.start, 1 + res.end - res.start);
  374. if (!regs) {
  375. dev_err(&op->dev, "Could not map registers\n");
  376. return -ENODEV;
  377. }
  378. /* Allocate and initialize the driver private data */
  379. psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL);
  380. if (!psc_dma) {
  381. ret = -ENOMEM;
  382. goto out_unmap;
  383. }
  384. /* Get the PSC ID */
  385. prop = of_get_property(op->node, "cell-index", &size);
  386. if (!prop || size < sizeof *prop) {
  387. ret = -ENODEV;
  388. goto out_free;
  389. }
  390. spin_lock_init(&psc_dma->lock);
  391. mutex_init(&psc_dma->mutex);
  392. psc_dma->id = be32_to_cpu(*prop);
  393. psc_dma->irq = irq;
  394. psc_dma->psc_regs = regs;
  395. psc_dma->fifo_regs = regs + sizeof *psc_dma->psc_regs;
  396. psc_dma->dev = &op->dev;
  397. psc_dma->playback.psc_dma = psc_dma;
  398. psc_dma->capture.psc_dma = psc_dma;
  399. snprintf(psc_dma->name, sizeof psc_dma->name, "PSC%u", psc_dma->id);
  400. /* Find the address of the fifo data registers and setup the
  401. * DMA tasks */
  402. fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32);
  403. psc_dma->capture.bcom_task =
  404. bcom_psc_gen_bd_rx_init(psc_dma->id, 10, fifo, 512);
  405. psc_dma->playback.bcom_task =
  406. bcom_psc_gen_bd_tx_init(psc_dma->id, 10, fifo);
  407. if (!psc_dma->capture.bcom_task ||
  408. !psc_dma->playback.bcom_task) {
  409. dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
  410. ret = -ENODEV;
  411. goto out_free;
  412. }
  413. /* Disable all interrupts and reset the PSC */
  414. out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr);
  415. /* reset receiver */
  416. out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_RX);
  417. /* reset transmitter */
  418. out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_TX);
  419. /* reset error */
  420. out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_ERR_STAT);
  421. /* reset mode */
  422. out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_SEL_MODE_REG_1);
  423. /* Set up mode register;
  424. * First write: RxRdy (FIFO Alarm) generates rx FIFO irq
  425. * Second write: register Normal mode for non loopback
  426. */
  427. out_8(&psc_dma->psc_regs->mode, 0);
  428. out_8(&psc_dma->psc_regs->mode, 0);
  429. /* Set the TX and RX fifo alarm thresholds */
  430. out_be16(&psc_dma->fifo_regs->rfalarm, 0x100);
  431. out_8(&psc_dma->fifo_regs->rfcntl, 0x4);
  432. out_be16(&psc_dma->fifo_regs->tfalarm, 0x100);
  433. out_8(&psc_dma->fifo_regs->tfcntl, 0x7);
  434. /* Lookup the IRQ numbers */
  435. psc_dma->playback.irq =
  436. bcom_get_task_irq(psc_dma->playback.bcom_task);
  437. psc_dma->capture.irq =
  438. bcom_get_task_irq(psc_dma->capture.bcom_task);
  439. rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED,
  440. "psc-dma-status", psc_dma);
  441. rc |= request_irq(psc_dma->capture.irq,
  442. &psc_dma_bcom_irq_rx, IRQF_SHARED,
  443. "psc-dma-capture", &psc_dma->capture);
  444. rc |= request_irq(psc_dma->playback.irq,
  445. &psc_dma_bcom_irq_tx, IRQF_SHARED,
  446. "psc-dma-playback", &psc_dma->playback);
  447. if (rc) {
  448. ret = -ENODEV;
  449. goto out_irq;
  450. }
  451. /* Save what we've done so it can be found again later */
  452. dev_set_drvdata(&op->dev, psc_dma);
  453. /* Tell the ASoC OF helpers about it */
  454. return snd_soc_register_platform(&mpc5200_audio_dma_platform);
  455. out_irq:
  456. free_irq(psc_dma->irq, psc_dma);
  457. free_irq(psc_dma->capture.irq, &psc_dma->capture);
  458. free_irq(psc_dma->playback.irq, &psc_dma->playback);
  459. out_free:
  460. kfree(psc_dma);
  461. out_unmap:
  462. iounmap(regs);
  463. return ret;
  464. }
  465. EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
  466. int mpc5200_audio_dma_destroy(struct of_device *op)
  467. {
  468. struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
  469. dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n");
  470. snd_soc_unregister_platform(&mpc5200_audio_dma_platform);
  471. bcom_gen_bd_rx_release(psc_dma->capture.bcom_task);
  472. bcom_gen_bd_tx_release(psc_dma->playback.bcom_task);
  473. /* Release irqs */
  474. free_irq(psc_dma->irq, psc_dma);
  475. free_irq(psc_dma->capture.irq, &psc_dma->capture);
  476. free_irq(psc_dma->playback.irq, &psc_dma->playback);
  477. iounmap(psc_dma->psc_regs);
  478. kfree(psc_dma);
  479. dev_set_drvdata(&op->dev, NULL);
  480. return 0;
  481. }
  482. EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy);
  483. MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
  484. MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
  485. MODULE_LICENSE("GPL");