aio-compress.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Socionext UniPhier AIO Compress Audio driver.
  4. //
  5. // Copyright (c) 2017-2018 Socionext Inc.
  6. #include <linux/bitfield.h>
  7. #include <linux/circ_buf.h>
  8. #include <linux/dma-mapping.h>
  9. #include <linux/errno.h>
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <sound/core.h>
  13. #include <sound/pcm.h>
  14. #include <sound/soc.h>
  15. #include "aio.h"
  16. static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream);
  17. static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream);
  18. static int uniphier_aio_comprdma_new(struct snd_soc_pcm_runtime *rtd)
  19. {
  20. struct snd_compr *compr = rtd->compr;
  21. struct device *dev = compr->card->dev;
  22. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  23. struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
  24. size_t size = AUD_RING_SIZE;
  25. int dma_dir = DMA_FROM_DEVICE, ret;
  26. ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
  27. if (ret)
  28. return ret;
  29. sub->compr_area = kzalloc(size, GFP_KERNEL);
  30. if (!sub->compr_area)
  31. return -ENOMEM;
  32. if (sub->swm->dir == PORT_DIR_OUTPUT)
  33. dma_dir = DMA_TO_DEVICE;
  34. sub->compr_addr = dma_map_single(dev, sub->compr_area, size, dma_dir);
  35. if (dma_mapping_error(dev, sub->compr_addr)) {
  36. kfree(sub->compr_area);
  37. sub->compr_area = NULL;
  38. return -ENOMEM;
  39. }
  40. sub->compr_bytes = size;
  41. return 0;
  42. }
  43. static int uniphier_aio_comprdma_free(struct snd_soc_pcm_runtime *rtd)
  44. {
  45. struct snd_compr *compr = rtd->compr;
  46. struct device *dev = compr->card->dev;
  47. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  48. struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
  49. int dma_dir = DMA_FROM_DEVICE;
  50. if (sub->swm->dir == PORT_DIR_OUTPUT)
  51. dma_dir = DMA_TO_DEVICE;
  52. dma_unmap_single(dev, sub->compr_addr, sub->compr_bytes, dma_dir);
  53. kfree(sub->compr_area);
  54. sub->compr_area = NULL;
  55. return 0;
  56. }
  57. static int uniphier_aio_compr_open(struct snd_compr_stream *cstream)
  58. {
  59. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  60. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  61. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  62. int ret;
  63. if (sub->cstream)
  64. return -EBUSY;
  65. sub->cstream = cstream;
  66. sub->pass_through = 1;
  67. sub->use_mmap = false;
  68. ret = uniphier_aio_comprdma_new(rtd);
  69. if (ret)
  70. return ret;
  71. ret = aio_init(sub);
  72. if (ret)
  73. return ret;
  74. return 0;
  75. }
  76. static int uniphier_aio_compr_free(struct snd_compr_stream *cstream)
  77. {
  78. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  79. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  80. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  81. int ret;
  82. ret = uniphier_aio_compr_hw_free(cstream);
  83. if (ret)
  84. return ret;
  85. ret = uniphier_aio_comprdma_free(rtd);
  86. if (ret)
  87. return ret;
  88. sub->cstream = NULL;
  89. return 0;
  90. }
  91. static int uniphier_aio_compr_get_params(struct snd_compr_stream *cstream,
  92. struct snd_codec *params)
  93. {
  94. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  95. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  96. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  97. *params = sub->cparams.codec;
  98. return 0;
  99. }
  100. static int uniphier_aio_compr_set_params(struct snd_compr_stream *cstream,
  101. struct snd_compr_params *params)
  102. {
  103. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  104. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  105. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  106. struct device *dev = &aio->chip->pdev->dev;
  107. int ret;
  108. if (params->codec.id != SND_AUDIOCODEC_IEC61937) {
  109. dev_err(dev, "Codec ID is not supported(%d)\n",
  110. params->codec.id);
  111. return -EINVAL;
  112. }
  113. if (params->codec.profile != SND_AUDIOPROFILE_IEC61937_SPDIF) {
  114. dev_err(dev, "Codec profile is not supported(%d)\n",
  115. params->codec.profile);
  116. return -EINVAL;
  117. }
  118. /* IEC frame type will be changed after received valid data */
  119. sub->iec_pc = IEC61937_PC_AAC;
  120. sub->cparams = *params;
  121. sub->setting = 1;
  122. aio_port_reset(sub);
  123. aio_src_reset(sub);
  124. ret = uniphier_aio_compr_prepare(cstream);
  125. if (ret)
  126. return ret;
  127. return 0;
  128. }
  129. static int uniphier_aio_compr_hw_free(struct snd_compr_stream *cstream)
  130. {
  131. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  132. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  133. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  134. sub->setting = 0;
  135. return 0;
  136. }
  137. static int uniphier_aio_compr_prepare(struct snd_compr_stream *cstream)
  138. {
  139. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  140. struct snd_compr_runtime *runtime = cstream->runtime;
  141. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  142. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  143. int bytes = runtime->fragment_size;
  144. unsigned long flags;
  145. int ret;
  146. ret = aiodma_ch_set_param(sub);
  147. if (ret)
  148. return ret;
  149. spin_lock_irqsave(&sub->lock, flags);
  150. ret = aiodma_rb_set_buffer(sub, sub->compr_addr,
  151. sub->compr_addr + sub->compr_bytes,
  152. bytes);
  153. spin_unlock_irqrestore(&sub->lock, flags);
  154. if (ret)
  155. return ret;
  156. ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
  157. if (ret)
  158. return ret;
  159. ret = aio_oport_set_stream_type(sub, sub->iec_pc);
  160. if (ret)
  161. return ret;
  162. aio_port_set_enable(sub, 1);
  163. ret = aio_if_set_param(sub, sub->pass_through);
  164. if (ret)
  165. return ret;
  166. return 0;
  167. }
  168. static int uniphier_aio_compr_trigger(struct snd_compr_stream *cstream,
  169. int cmd)
  170. {
  171. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  172. struct snd_compr_runtime *runtime = cstream->runtime;
  173. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  174. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  175. struct device *dev = &aio->chip->pdev->dev;
  176. int bytes = runtime->fragment_size, ret = 0;
  177. unsigned long flags;
  178. spin_lock_irqsave(&sub->lock, flags);
  179. switch (cmd) {
  180. case SNDRV_PCM_TRIGGER_START:
  181. aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
  182. aiodma_ch_set_enable(sub, 1);
  183. sub->running = 1;
  184. break;
  185. case SNDRV_PCM_TRIGGER_STOP:
  186. sub->running = 0;
  187. aiodma_ch_set_enable(sub, 0);
  188. break;
  189. default:
  190. dev_warn(dev, "Unknown trigger(%d)\n", cmd);
  191. ret = -EINVAL;
  192. }
  193. spin_unlock_irqrestore(&sub->lock, flags);
  194. return ret;
  195. }
  196. static int uniphier_aio_compr_pointer(struct snd_compr_stream *cstream,
  197. struct snd_compr_tstamp *tstamp)
  198. {
  199. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  200. struct snd_compr_runtime *runtime = cstream->runtime;
  201. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  202. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  203. int bytes = runtime->fragment_size;
  204. unsigned long flags;
  205. u32 pos;
  206. spin_lock_irqsave(&sub->lock, flags);
  207. aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
  208. if (sub->swm->dir == PORT_DIR_OUTPUT) {
  209. pos = sub->rd_offs;
  210. /* Size of AIO output format is double of IEC61937 */
  211. tstamp->copied_total = sub->rd_total / 2;
  212. } else {
  213. pos = sub->wr_offs;
  214. tstamp->copied_total = sub->rd_total;
  215. }
  216. tstamp->byte_offset = pos;
  217. spin_unlock_irqrestore(&sub->lock, flags);
  218. return 0;
  219. }
  220. static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub,
  221. char __user *buf, size_t dstsize)
  222. {
  223. u32 __user *srcbuf = (u32 __user *)buf;
  224. u32 *dstbuf = (u32 *)(sub->compr_area + sub->wr_offs);
  225. int src = 0, dst = 0, ret;
  226. u32 frm, frm_a, frm_b;
  227. while (dstsize > 0) {
  228. ret = get_user(frm, srcbuf + src);
  229. if (ret)
  230. return ret;
  231. src++;
  232. frm_a = frm & 0xffff;
  233. frm_b = (frm >> 16) & 0xffff;
  234. if (frm == IEC61937_HEADER_SIGN) {
  235. frm_a |= 0x01000000;
  236. /* Next data is Pc and Pd */
  237. sub->iec_header = true;
  238. } else {
  239. u16 pc = be16_to_cpu((__be16)frm_a);
  240. if (sub->iec_header && sub->iec_pc != pc) {
  241. /* Force overwrite IEC frame type */
  242. sub->iec_pc = pc;
  243. ret = aio_oport_set_stream_type(sub, pc);
  244. if (ret)
  245. return ret;
  246. }
  247. sub->iec_header = false;
  248. }
  249. dstbuf[dst++] = frm_a;
  250. dstbuf[dst++] = frm_b;
  251. dstsize -= sizeof(u32) * 2;
  252. }
  253. return 0;
  254. }
  255. static int uniphier_aio_compr_copy(struct snd_compr_stream *cstream,
  256. char __user *buf, size_t count)
  257. {
  258. struct snd_soc_pcm_runtime *rtd = cstream->private_data;
  259. struct snd_compr_runtime *runtime = cstream->runtime;
  260. struct device *carddev = rtd->compr->card->dev;
  261. struct uniphier_aio *aio = uniphier_priv(rtd->cpu_dai);
  262. struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
  263. size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2);
  264. int bytes = runtime->fragment_size;
  265. unsigned long flags;
  266. size_t s;
  267. int ret;
  268. if (cnt < sizeof(u32))
  269. return 0;
  270. if (sub->swm->dir == PORT_DIR_OUTPUT) {
  271. dma_addr_t dmapos = sub->compr_addr + sub->wr_offs;
  272. /* Size of AIO output format is double of IEC61937 */
  273. s = cnt * 2;
  274. dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE);
  275. ret = aio_compr_send_to_hw(sub, buf, s);
  276. dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE);
  277. } else {
  278. dma_addr_t dmapos = sub->compr_addr + sub->rd_offs;
  279. s = cnt;
  280. dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE);
  281. ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s);
  282. dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE);
  283. }
  284. if (ret)
  285. return -EFAULT;
  286. spin_lock_irqsave(&sub->lock, flags);
  287. sub->threshold = 2 * bytes;
  288. aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes);
  289. if (sub->swm->dir == PORT_DIR_OUTPUT) {
  290. sub->wr_offs += s;
  291. if (sub->wr_offs >= sub->compr_bytes)
  292. sub->wr_offs -= sub->compr_bytes;
  293. } else {
  294. sub->rd_offs += s;
  295. if (sub->rd_offs >= sub->compr_bytes)
  296. sub->rd_offs -= sub->compr_bytes;
  297. }
  298. aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
  299. spin_unlock_irqrestore(&sub->lock, flags);
  300. return cnt;
  301. }
  302. static int uniphier_aio_compr_get_caps(struct snd_compr_stream *cstream,
  303. struct snd_compr_caps *caps)
  304. {
  305. caps->num_codecs = 1;
  306. caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE;
  307. caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE;
  308. caps->min_fragments = AUD_MIN_FRAGMENT;
  309. caps->max_fragments = AUD_MAX_FRAGMENT;
  310. caps->codecs[0] = SND_AUDIOCODEC_IEC61937;
  311. return 0;
  312. }
  313. static const struct snd_compr_codec_caps caps_iec = {
  314. .num_descriptors = 1,
  315. .descriptor[0].max_ch = 8,
  316. .descriptor[0].num_sample_rates = 0,
  317. .descriptor[0].num_bitrates = 0,
  318. .descriptor[0].profiles = SND_AUDIOPROFILE_IEC61937_SPDIF,
  319. .descriptor[0].modes = SND_AUDIOMODE_IEC_AC3 |
  320. SND_AUDIOMODE_IEC_MPEG1 |
  321. SND_AUDIOMODE_IEC_MP3 |
  322. SND_AUDIOMODE_IEC_DTS,
  323. .descriptor[0].formats = 0,
  324. };
  325. static int uniphier_aio_compr_get_codec_caps(struct snd_compr_stream *stream,
  326. struct snd_compr_codec_caps *codec)
  327. {
  328. if (codec->codec == SND_AUDIOCODEC_IEC61937)
  329. *codec = caps_iec;
  330. else
  331. return -EINVAL;
  332. return 0;
  333. }
  334. const struct snd_compr_ops uniphier_aio_compr_ops = {
  335. .open = uniphier_aio_compr_open,
  336. .free = uniphier_aio_compr_free,
  337. .get_params = uniphier_aio_compr_get_params,
  338. .set_params = uniphier_aio_compr_set_params,
  339. .trigger = uniphier_aio_compr_trigger,
  340. .pointer = uniphier_aio_compr_pointer,
  341. .copy = uniphier_aio_compr_copy,
  342. .get_caps = uniphier_aio_compr_get_caps,
  343. .get_codec_caps = uniphier_aio_compr_get_codec_caps,
  344. };