stm32_adfsdm.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * This file is part of STM32 DFSDM ASoC DAI driver
  4. *
  5. * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
  6. * Authors: Arnaud Pouliquen <[email protected]>
  7. * Olivier Moysan <[email protected]>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/module.h>
  11. #include <linux/mutex.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/slab.h>
  14. #include <linux/pm_runtime.h>
  15. #include <linux/iio/iio.h>
  16. #include <linux/iio/consumer.h>
  17. #include <linux/iio/adc/stm32-dfsdm-adc.h>
  18. #include <sound/pcm.h>
  19. #include <sound/soc.h>
  20. #define STM32_ADFSDM_DRV_NAME "stm32-adfsdm"
  21. #define DFSDM_MAX_PERIOD_SIZE (PAGE_SIZE / 2)
  22. #define DFSDM_MAX_PERIODS 6
  23. struct stm32_adfsdm_priv {
  24. struct snd_soc_dai_driver dai_drv;
  25. struct snd_pcm_substream *substream;
  26. struct device *dev;
  27. /* IIO */
  28. struct iio_channel *iio_ch;
  29. struct iio_cb_buffer *iio_cb;
  30. bool iio_active;
  31. /* PCM buffer */
  32. unsigned char *pcm_buff;
  33. unsigned int pos;
  34. struct mutex lock; /* protect against race condition on iio state */
  35. };
  36. static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = {
  37. .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  38. SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_PAUSE,
  39. .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
  40. .channels_min = 1,
  41. .channels_max = 1,
  42. .periods_min = 2,
  43. .periods_max = DFSDM_MAX_PERIODS,
  44. .period_bytes_max = DFSDM_MAX_PERIOD_SIZE,
  45. .buffer_bytes_max = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE
  46. };
  47. static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
  48. struct snd_soc_dai *dai)
  49. {
  50. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
  51. mutex_lock(&priv->lock);
  52. if (priv->iio_active) {
  53. iio_channel_stop_all_cb(priv->iio_cb);
  54. priv->iio_active = false;
  55. }
  56. mutex_unlock(&priv->lock);
  57. }
  58. static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
  59. struct snd_soc_dai *dai)
  60. {
  61. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
  62. int ret;
  63. mutex_lock(&priv->lock);
  64. if (priv->iio_active) {
  65. iio_channel_stop_all_cb(priv->iio_cb);
  66. priv->iio_active = false;
  67. }
  68. ret = iio_write_channel_attribute(priv->iio_ch,
  69. substream->runtime->rate, 0,
  70. IIO_CHAN_INFO_SAMP_FREQ);
  71. if (ret < 0) {
  72. dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
  73. __func__, substream->runtime->rate);
  74. goto out;
  75. }
  76. if (!priv->iio_active) {
  77. ret = iio_channel_start_all_cb(priv->iio_cb);
  78. if (!ret)
  79. priv->iio_active = true;
  80. else
  81. dev_err(dai->dev, "%s: IIO channel start failed (%d)\n",
  82. __func__, ret);
  83. }
  84. out:
  85. mutex_unlock(&priv->lock);
  86. return ret;
  87. }
  88. static int stm32_adfsdm_set_sysclk(struct snd_soc_dai *dai, int clk_id,
  89. unsigned int freq, int dir)
  90. {
  91. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
  92. ssize_t size;
  93. char str_freq[10];
  94. dev_dbg(dai->dev, "%s: Enter for freq %d\n", __func__, freq);
  95. /* Set IIO frequency if CODEC is master as clock comes from SPI_IN */
  96. snprintf(str_freq, sizeof(str_freq), "%u\n", freq);
  97. size = iio_write_channel_ext_info(priv->iio_ch, "spi_clk_freq",
  98. str_freq, sizeof(str_freq));
  99. if (size != sizeof(str_freq)) {
  100. dev_err(dai->dev, "%s: Failed to set SPI clock\n",
  101. __func__);
  102. return -EINVAL;
  103. }
  104. return 0;
  105. }
  106. static const struct snd_soc_dai_ops stm32_adfsdm_dai_ops = {
  107. .shutdown = stm32_adfsdm_shutdown,
  108. .prepare = stm32_adfsdm_dai_prepare,
  109. .set_sysclk = stm32_adfsdm_set_sysclk,
  110. };
  111. static const struct snd_soc_dai_driver stm32_adfsdm_dai = {
  112. .capture = {
  113. .channels_min = 1,
  114. .channels_max = 1,
  115. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  116. SNDRV_PCM_FMTBIT_S32_LE,
  117. .rates = SNDRV_PCM_RATE_CONTINUOUS,
  118. .rate_min = 8000,
  119. .rate_max = 48000,
  120. },
  121. .ops = &stm32_adfsdm_dai_ops,
  122. };
  123. static const struct snd_soc_component_driver stm32_adfsdm_dai_component = {
  124. .name = "stm32_dfsdm_audio",
  125. .legacy_dai_naming = 1,
  126. };
  127. static void stm32_memcpy_32to16(void *dest, const void *src, size_t n)
  128. {
  129. unsigned int i = 0;
  130. u16 *d = (u16 *)dest, *s = (u16 *)src;
  131. s++;
  132. for (i = n >> 1; i > 0; i--) {
  133. *d++ = *s++;
  134. s++;
  135. }
  136. }
  137. static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private)
  138. {
  139. struct stm32_adfsdm_priv *priv = private;
  140. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(priv->substream);
  141. u8 *pcm_buff = priv->pcm_buff;
  142. u8 *src_buff = (u8 *)data;
  143. unsigned int old_pos = priv->pos;
  144. size_t buff_size = snd_pcm_lib_buffer_bytes(priv->substream);
  145. size_t period_size = snd_pcm_lib_period_bytes(priv->substream);
  146. size_t cur_size, src_size = size;
  147. snd_pcm_format_t format = priv->substream->runtime->format;
  148. if (format == SNDRV_PCM_FORMAT_S16_LE)
  149. src_size >>= 1;
  150. cur_size = src_size;
  151. dev_dbg(rtd->dev, "%s: buff_add :%pK, pos = %d, size = %zu\n",
  152. __func__, &pcm_buff[priv->pos], priv->pos, src_size);
  153. if ((priv->pos + src_size) > buff_size) {
  154. if (format == SNDRV_PCM_FORMAT_S16_LE)
  155. stm32_memcpy_32to16(&pcm_buff[priv->pos], src_buff,
  156. buff_size - priv->pos);
  157. else
  158. memcpy(&pcm_buff[priv->pos], src_buff,
  159. buff_size - priv->pos);
  160. cur_size -= buff_size - priv->pos;
  161. priv->pos = 0;
  162. }
  163. if (format == SNDRV_PCM_FORMAT_S16_LE)
  164. stm32_memcpy_32to16(&pcm_buff[priv->pos],
  165. &src_buff[src_size - cur_size], cur_size);
  166. else
  167. memcpy(&pcm_buff[priv->pos], &src_buff[src_size - cur_size],
  168. cur_size);
  169. priv->pos = (priv->pos + cur_size) % buff_size;
  170. if (cur_size != src_size || (old_pos && (old_pos % period_size < size)))
  171. snd_pcm_period_elapsed(priv->substream);
  172. return 0;
  173. }
  174. static int stm32_adfsdm_trigger(struct snd_soc_component *component,
  175. struct snd_pcm_substream *substream, int cmd)
  176. {
  177. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  178. struct stm32_adfsdm_priv *priv =
  179. snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
  180. switch (cmd) {
  181. case SNDRV_PCM_TRIGGER_START:
  182. case SNDRV_PCM_TRIGGER_RESUME:
  183. priv->pos = 0;
  184. return stm32_dfsdm_get_buff_cb(priv->iio_ch->indio_dev,
  185. stm32_afsdm_pcm_cb, priv);
  186. case SNDRV_PCM_TRIGGER_SUSPEND:
  187. case SNDRV_PCM_TRIGGER_STOP:
  188. return stm32_dfsdm_release_buff_cb(priv->iio_ch->indio_dev);
  189. }
  190. return -EINVAL;
  191. }
  192. static int stm32_adfsdm_pcm_open(struct snd_soc_component *component,
  193. struct snd_pcm_substream *substream)
  194. {
  195. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  196. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
  197. int ret;
  198. ret = snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw);
  199. if (!ret)
  200. priv->substream = substream;
  201. return ret;
  202. }
  203. static int stm32_adfsdm_pcm_close(struct snd_soc_component *component,
  204. struct snd_pcm_substream *substream)
  205. {
  206. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  207. struct stm32_adfsdm_priv *priv =
  208. snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
  209. priv->substream = NULL;
  210. return 0;
  211. }
  212. static snd_pcm_uframes_t stm32_adfsdm_pcm_pointer(
  213. struct snd_soc_component *component,
  214. struct snd_pcm_substream *substream)
  215. {
  216. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  217. struct stm32_adfsdm_priv *priv =
  218. snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
  219. return bytes_to_frames(substream->runtime, priv->pos);
  220. }
  221. static int stm32_adfsdm_pcm_hw_params(struct snd_soc_component *component,
  222. struct snd_pcm_substream *substream,
  223. struct snd_pcm_hw_params *params)
  224. {
  225. struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
  226. struct stm32_adfsdm_priv *priv =
  227. snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
  228. priv->pcm_buff = substream->runtime->dma_area;
  229. return iio_channel_cb_set_buffer_watermark(priv->iio_cb,
  230. params_period_size(params));
  231. }
  232. static int stm32_adfsdm_pcm_new(struct snd_soc_component *component,
  233. struct snd_soc_pcm_runtime *rtd)
  234. {
  235. struct snd_pcm *pcm = rtd->pcm;
  236. struct stm32_adfsdm_priv *priv =
  237. snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
  238. unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE;
  239. snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
  240. priv->dev, size, size);
  241. return 0;
  242. }
  243. static int stm32_adfsdm_dummy_cb(const void *data, void *private)
  244. {
  245. /*
  246. * This dummy callback is requested by iio_channel_get_all_cb() API,
  247. * but the stm32_dfsdm_get_buff_cb() API is used instead, to optimize
  248. * DMA transfers.
  249. */
  250. return 0;
  251. }
  252. static void stm32_adfsdm_cleanup(void *data)
  253. {
  254. iio_channel_release_all_cb(data);
  255. }
  256. static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
  257. .open = stm32_adfsdm_pcm_open,
  258. .close = stm32_adfsdm_pcm_close,
  259. .hw_params = stm32_adfsdm_pcm_hw_params,
  260. .trigger = stm32_adfsdm_trigger,
  261. .pointer = stm32_adfsdm_pcm_pointer,
  262. .pcm_construct = stm32_adfsdm_pcm_new,
  263. };
  264. static const struct of_device_id stm32_adfsdm_of_match[] = {
  265. {.compatible = "st,stm32h7-dfsdm-dai"},
  266. {}
  267. };
  268. MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match);
  269. static int stm32_adfsdm_probe(struct platform_device *pdev)
  270. {
  271. struct stm32_adfsdm_priv *priv;
  272. struct snd_soc_component *component;
  273. int ret;
  274. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  275. if (!priv)
  276. return -ENOMEM;
  277. priv->dev = &pdev->dev;
  278. priv->dai_drv = stm32_adfsdm_dai;
  279. mutex_init(&priv->lock);
  280. dev_set_drvdata(&pdev->dev, priv);
  281. ret = devm_snd_soc_register_component(&pdev->dev,
  282. &stm32_adfsdm_dai_component,
  283. &priv->dai_drv, 1);
  284. if (ret < 0)
  285. return ret;
  286. /* Associate iio channel */
  287. priv->iio_ch = devm_iio_channel_get_all(&pdev->dev);
  288. if (IS_ERR(priv->iio_ch))
  289. return PTR_ERR(priv->iio_ch);
  290. priv->iio_cb = iio_channel_get_all_cb(&pdev->dev, &stm32_adfsdm_dummy_cb, NULL);
  291. if (IS_ERR(priv->iio_cb))
  292. return PTR_ERR(priv->iio_cb);
  293. ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb);
  294. if (ret < 0) {
  295. dev_err(&pdev->dev, "Unable to add action\n");
  296. return ret;
  297. }
  298. component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
  299. if (!component)
  300. return -ENOMEM;
  301. ret = snd_soc_component_initialize(component,
  302. &stm32_adfsdm_soc_platform,
  303. &pdev->dev);
  304. if (ret < 0)
  305. return ret;
  306. #ifdef CONFIG_DEBUG_FS
  307. component->debugfs_prefix = "pcm";
  308. #endif
  309. ret = snd_soc_add_component(component, NULL, 0);
  310. if (ret < 0) {
  311. dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
  312. __func__);
  313. return ret;
  314. }
  315. pm_runtime_enable(&pdev->dev);
  316. return ret;
  317. }
  318. static int stm32_adfsdm_remove(struct platform_device *pdev)
  319. {
  320. snd_soc_unregister_component(&pdev->dev);
  321. pm_runtime_disable(&pdev->dev);
  322. return 0;
  323. }
  324. static struct platform_driver stm32_adfsdm_driver = {
  325. .driver = {
  326. .name = STM32_ADFSDM_DRV_NAME,
  327. .of_match_table = stm32_adfsdm_of_match,
  328. },
  329. .probe = stm32_adfsdm_probe,
  330. .remove = stm32_adfsdm_remove,
  331. };
  332. module_platform_driver(stm32_adfsdm_driver);
  333. MODULE_DESCRIPTION("stm32 DFSDM DAI driver");
  334. MODULE_AUTHOR("Arnaud Pouliquen <[email protected]>");
  335. MODULE_LICENSE("GPL v2");
  336. MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME);