ux500_pcm.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2012
  3. *
  4. * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
  5. * Roger Nilsson <roger.xr.nilsson@stericsson.com>
  6. * for ST-Ericsson.
  7. *
  8. * License terms:
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as published
  12. * by the Free Software Foundation.
  13. */
  14. #include <asm/page.h>
  15. #include <linux/module.h>
  16. #include <linux/dma-mapping.h>
  17. #include <linux/dmaengine.h>
  18. #include <linux/slab.h>
  19. #include <linux/platform_data/dma-ste-dma40.h>
  20. #include <sound/pcm.h>
  21. #include <sound/pcm_params.h>
  22. #include <sound/soc.h>
  23. #include <sound/dmaengine_pcm.h>
  24. #include "ux500_msp_i2s.h"
  25. #include "ux500_pcm.h"
  26. static struct snd_pcm_hardware ux500_pcm_hw_playback = {
  27. .info = SNDRV_PCM_INFO_INTERLEAVED |
  28. SNDRV_PCM_INFO_MMAP |
  29. SNDRV_PCM_INFO_RESUME |
  30. SNDRV_PCM_INFO_PAUSE,
  31. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  32. SNDRV_PCM_FMTBIT_U16_LE |
  33. SNDRV_PCM_FMTBIT_S16_BE |
  34. SNDRV_PCM_FMTBIT_U16_BE,
  35. .rates = SNDRV_PCM_RATE_KNOT,
  36. .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
  37. .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
  38. .channels_min = UX500_PLATFORM_MIN_CHANNELS,
  39. .channels_max = UX500_PLATFORM_MAX_CHANNELS,
  40. .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
  41. .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
  42. .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
  43. .periods_min = UX500_PLATFORM_PERIODS_MIN,
  44. .periods_max = UX500_PLATFORM_PERIODS_MAX,
  45. };
  46. static struct snd_pcm_hardware ux500_pcm_hw_capture = {
  47. .info = SNDRV_PCM_INFO_INTERLEAVED |
  48. SNDRV_PCM_INFO_MMAP |
  49. SNDRV_PCM_INFO_RESUME |
  50. SNDRV_PCM_INFO_PAUSE,
  51. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  52. SNDRV_PCM_FMTBIT_U16_LE |
  53. SNDRV_PCM_FMTBIT_S16_BE |
  54. SNDRV_PCM_FMTBIT_U16_BE,
  55. .rates = SNDRV_PCM_RATE_KNOT,
  56. .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
  57. .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
  58. .channels_min = UX500_PLATFORM_MIN_CHANNELS,
  59. .channels_max = UX500_PLATFORM_MAX_CHANNELS,
  60. .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
  61. .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
  62. .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
  63. .periods_min = UX500_PLATFORM_PERIODS_MIN,
  64. .periods_max = UX500_PLATFORM_PERIODS_MAX,
  65. };
  66. static void ux500_pcm_dma_hw_free(struct device *dev,
  67. struct snd_pcm_substream *substream)
  68. {
  69. struct snd_pcm_runtime *runtime = substream->runtime;
  70. struct snd_dma_buffer *buf = runtime->dma_buffer_p;
  71. if (runtime->dma_area == NULL)
  72. return;
  73. if (buf != &substream->dma_buffer) {
  74. dma_free_coherent(buf->dev.dev, buf->bytes, buf->area,
  75. buf->addr);
  76. kfree(runtime->dma_buffer_p);
  77. }
  78. snd_pcm_set_runtime_buffer(substream, NULL);
  79. }
  80. static int ux500_pcm_open(struct snd_pcm_substream *substream)
  81. {
  82. int stream_id = substream->pstr->stream;
  83. struct snd_pcm_runtime *runtime = substream->runtime;
  84. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  85. struct snd_soc_dai *dai = rtd->cpu_dai;
  86. struct device *dev = dai->dev;
  87. int ret;
  88. struct ux500_msp_dma_params *dma_params;
  89. u16 per_data_width, mem_data_width;
  90. struct stedma40_chan_cfg *dma_cfg;
  91. dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
  92. snd_pcm_stream_str(substream));
  93. dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
  94. if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
  95. snd_soc_set_runtime_hwparams(substream,
  96. &ux500_pcm_hw_playback);
  97. else
  98. snd_soc_set_runtime_hwparams(substream,
  99. &ux500_pcm_hw_capture);
  100. dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
  101. snd_pcm_stream_str(substream));
  102. runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
  103. ux500_pcm_hw_playback : ux500_pcm_hw_capture;
  104. mem_data_width = STEDMA40_HALFWORD_WIDTH;
  105. dma_params = snd_soc_dai_get_dma_data(dai, substream);
  106. switch (dma_params->data_size) {
  107. case 32:
  108. per_data_width = STEDMA40_WORD_WIDTH;
  109. break;
  110. case 16:
  111. per_data_width = STEDMA40_HALFWORD_WIDTH;
  112. break;
  113. case 8:
  114. per_data_width = STEDMA40_BYTE_WIDTH;
  115. break;
  116. default:
  117. per_data_width = STEDMA40_WORD_WIDTH;
  118. dev_warn(rtd->platform->dev,
  119. "%s: Unknown data-size (%d)! Assuming 32 bits.\n",
  120. __func__, dma_params->data_size);
  121. }
  122. dma_cfg = dma_params->dma_cfg;
  123. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  124. dma_cfg->src_info.data_width = mem_data_width;
  125. dma_cfg->dst_info.data_width = per_data_width;
  126. } else {
  127. dma_cfg->src_info.data_width = per_data_width;
  128. dma_cfg->dst_info.data_width = mem_data_width;
  129. }
  130. ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg);
  131. if (ret) {
  132. dev_dbg(dai->dev,
  133. "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n",
  134. __func__, ret);
  135. return ret;
  136. }
  137. snd_dmaengine_pcm_set_data(substream, dma_cfg);
  138. return 0;
  139. }
  140. static int ux500_pcm_close(struct snd_pcm_substream *substream)
  141. {
  142. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  143. struct snd_soc_dai *dai = rtd->cpu_dai;
  144. dev_dbg(dai->dev, "%s: Enter\n", __func__);
  145. snd_dmaengine_pcm_close(substream);
  146. return 0;
  147. }
  148. static int ux500_pcm_hw_params(struct snd_pcm_substream *substream,
  149. struct snd_pcm_hw_params *hw_params)
  150. {
  151. struct snd_pcm_runtime *runtime = substream->runtime;
  152. struct snd_dma_buffer *buf = runtime->dma_buffer_p;
  153. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  154. int ret = 0;
  155. int size;
  156. dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
  157. size = params_buffer_bytes(hw_params);
  158. if (buf) {
  159. if (buf->bytes >= size)
  160. goto out;
  161. ux500_pcm_dma_hw_free(NULL, substream);
  162. }
  163. if (substream->dma_buffer.area != NULL &&
  164. substream->dma_buffer.bytes >= size) {
  165. buf = &substream->dma_buffer;
  166. } else {
  167. buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
  168. if (!buf)
  169. goto nomem;
  170. buf->dev.type = SNDRV_DMA_TYPE_DEV;
  171. buf->dev.dev = NULL;
  172. buf->area = dma_alloc_coherent(NULL, size, &buf->addr,
  173. GFP_KERNEL);
  174. buf->bytes = size;
  175. buf->private_data = NULL;
  176. if (!buf->area)
  177. goto free;
  178. }
  179. snd_pcm_set_runtime_buffer(substream, buf);
  180. ret = 1;
  181. out:
  182. runtime->dma_bytes = size;
  183. return ret;
  184. free:
  185. kfree(buf);
  186. nomem:
  187. return -ENOMEM;
  188. }
  189. static int ux500_pcm_hw_free(struct snd_pcm_substream *substream)
  190. {
  191. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  192. dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
  193. ux500_pcm_dma_hw_free(NULL, substream);
  194. return 0;
  195. }
  196. static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
  197. struct vm_area_struct *vma)
  198. {
  199. struct snd_pcm_runtime *runtime = substream->runtime;
  200. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  201. dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__);
  202. return dma_mmap_coherent(NULL, vma, runtime->dma_area,
  203. runtime->dma_addr, runtime->dma_bytes);
  204. }
  205. static struct snd_pcm_ops ux500_pcm_ops = {
  206. .open = ux500_pcm_open,
  207. .close = ux500_pcm_close,
  208. .ioctl = snd_pcm_lib_ioctl,
  209. .hw_params = ux500_pcm_hw_params,
  210. .hw_free = ux500_pcm_hw_free,
  211. .trigger = snd_dmaengine_pcm_trigger,
  212. .pointer = snd_dmaengine_pcm_pointer_no_residue,
  213. .mmap = ux500_pcm_mmap
  214. };
  215. int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd)
  216. {
  217. struct snd_pcm *pcm = rtd->pcm;
  218. dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__,
  219. pcm->id);
  220. pcm->info_flags = 0;
  221. return 0;
  222. }
  223. static struct snd_soc_platform_driver ux500_pcm_soc_drv = {
  224. .ops = &ux500_pcm_ops,
  225. .pcm_new = ux500_pcm_new,
  226. };
  227. int ux500_pcm_register_platform(struct platform_device *pdev)
  228. {
  229. int ret;
  230. ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv);
  231. if (ret < 0) {
  232. dev_err(&pdev->dev,
  233. "%s: ERROR: Failed to register platform '%s' (%d)!\n",
  234. __func__, pdev->name, ret);
  235. return ret;
  236. }
  237. return 0;
  238. }
  239. EXPORT_SYMBOL_GPL(ux500_pcm_register_platform);
  240. int ux500_pcm_unregister_platform(struct platform_device *pdev)
  241. {
  242. snd_soc_unregister_platform(&pdev->dev);
  243. return 0;
  244. }
  245. EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform);