aio-compress.c 12 KB

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