stm32_adfsdm.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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 <arnaud.pouliquen@st.com>
  7. * Olivier Moysan <olivier.moysan@st.com>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/module.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/slab.h>
  13. #include <linux/iio/iio.h>
  14. #include <linux/iio/consumer.h>
  15. #include <linux/iio/adc/stm32-dfsdm-adc.h>
  16. #include <sound/pcm.h>
  17. #include <sound/soc.h>
  18. #define STM32_ADFSDM_DRV_NAME "stm32-adfsdm"
  19. #define DFSDM_MAX_PERIOD_SIZE (PAGE_SIZE / 2)
  20. #define DFSDM_MAX_PERIODS 6
  21. struct stm32_adfsdm_priv {
  22. struct snd_soc_dai_driver dai_drv;
  23. struct snd_pcm_substream *substream;
  24. struct device *dev;
  25. /* IIO */
  26. struct iio_channel *iio_ch;
  27. struct iio_cb_buffer *iio_cb;
  28. bool iio_active;
  29. /* PCM buffer */
  30. unsigned char *pcm_buff;
  31. unsigned int pos;
  32. };
  33. static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = {
  34. .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  35. SNDRV_PCM_INFO_PAUSE,
  36. .formats = SNDRV_PCM_FMTBIT_S32_LE,
  37. .rate_min = 8000,
  38. .rate_max = 32000,
  39. .channels_min = 1,
  40. .channels_max = 1,
  41. .periods_min = 2,
  42. .periods_max = DFSDM_MAX_PERIODS,
  43. .period_bytes_max = DFSDM_MAX_PERIOD_SIZE,
  44. .buffer_bytes_max = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE
  45. };
  46. static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
  47. struct snd_soc_dai *dai)
  48. {
  49. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
  50. if (priv->iio_active) {
  51. iio_channel_stop_all_cb(priv->iio_cb);
  52. priv->iio_active = false;
  53. }
  54. }
  55. static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
  56. struct snd_soc_dai *dai)
  57. {
  58. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
  59. int ret;
  60. ret = iio_write_channel_attribute(priv->iio_ch,
  61. substream->runtime->rate, 0,
  62. IIO_CHAN_INFO_SAMP_FREQ);
  63. if (ret < 0) {
  64. dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
  65. __func__, substream->runtime->rate);
  66. return ret;
  67. }
  68. if (!priv->iio_active) {
  69. ret = iio_channel_start_all_cb(priv->iio_cb);
  70. if (!ret)
  71. priv->iio_active = true;
  72. else
  73. dev_err(dai->dev, "%s: IIO channel start failed (%d)\n",
  74. __func__, ret);
  75. }
  76. return ret;
  77. }
  78. static int stm32_adfsdm_set_sysclk(struct snd_soc_dai *dai, int clk_id,
  79. unsigned int freq, int dir)
  80. {
  81. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
  82. ssize_t size;
  83. char str_freq[10];
  84. dev_dbg(dai->dev, "%s: Enter for freq %d\n", __func__, freq);
  85. /* Set IIO frequency if CODEC is master as clock comes from SPI_IN */
  86. snprintf(str_freq, sizeof(str_freq), "%d\n", freq);
  87. size = iio_write_channel_ext_info(priv->iio_ch, "spi_clk_freq",
  88. str_freq, sizeof(str_freq));
  89. if (size != sizeof(str_freq)) {
  90. dev_err(dai->dev, "%s: Failed to set SPI clock\n",
  91. __func__);
  92. return -EINVAL;
  93. }
  94. return 0;
  95. }
  96. static const struct snd_soc_dai_ops stm32_adfsdm_dai_ops = {
  97. .shutdown = stm32_adfsdm_shutdown,
  98. .prepare = stm32_adfsdm_dai_prepare,
  99. .set_sysclk = stm32_adfsdm_set_sysclk,
  100. };
  101. static const struct snd_soc_dai_driver stm32_adfsdm_dai = {
  102. .capture = {
  103. .channels_min = 1,
  104. .channels_max = 1,
  105. .formats = SNDRV_PCM_FMTBIT_S32_LE,
  106. .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
  107. SNDRV_PCM_RATE_32000),
  108. },
  109. .ops = &stm32_adfsdm_dai_ops,
  110. };
  111. static const struct snd_soc_component_driver stm32_adfsdm_dai_component = {
  112. .name = "stm32_dfsdm_audio",
  113. };
  114. static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private)
  115. {
  116. struct stm32_adfsdm_priv *priv = private;
  117. struct snd_soc_pcm_runtime *rtd = priv->substream->private_data;
  118. u8 *pcm_buff = priv->pcm_buff;
  119. u8 *src_buff = (u8 *)data;
  120. unsigned int buff_size = snd_pcm_lib_buffer_bytes(priv->substream);
  121. unsigned int period_size = snd_pcm_lib_period_bytes(priv->substream);
  122. unsigned int old_pos = priv->pos;
  123. unsigned int cur_size = size;
  124. dev_dbg(rtd->dev, "%s: buff_add :%pK, pos = %d, size = %zu\n",
  125. __func__, &pcm_buff[priv->pos], priv->pos, size);
  126. if ((priv->pos + size) > buff_size) {
  127. memcpy(&pcm_buff[priv->pos], src_buff, buff_size - priv->pos);
  128. cur_size -= buff_size - priv->pos;
  129. priv->pos = 0;
  130. }
  131. memcpy(&pcm_buff[priv->pos], &src_buff[size - cur_size], cur_size);
  132. priv->pos = (priv->pos + cur_size) % buff_size;
  133. if (cur_size != size || (old_pos && (old_pos % period_size < size)))
  134. snd_pcm_period_elapsed(priv->substream);
  135. return 0;
  136. }
  137. static int stm32_adfsdm_trigger(struct snd_pcm_substream *substream, int cmd)
  138. {
  139. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  140. struct stm32_adfsdm_priv *priv =
  141. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  142. switch (cmd) {
  143. case SNDRV_PCM_TRIGGER_START:
  144. case SNDRV_PCM_TRIGGER_RESUME:
  145. priv->pos = 0;
  146. return stm32_dfsdm_get_buff_cb(priv->iio_ch->indio_dev,
  147. stm32_afsdm_pcm_cb, priv);
  148. case SNDRV_PCM_TRIGGER_SUSPEND:
  149. case SNDRV_PCM_TRIGGER_STOP:
  150. return stm32_dfsdm_release_buff_cb(priv->iio_ch->indio_dev);
  151. }
  152. return -EINVAL;
  153. }
  154. static int stm32_adfsdm_pcm_open(struct snd_pcm_substream *substream)
  155. {
  156. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  157. struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
  158. int ret;
  159. ret = snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw);
  160. if (!ret)
  161. priv->substream = substream;
  162. return ret;
  163. }
  164. static int stm32_adfsdm_pcm_close(struct snd_pcm_substream *substream)
  165. {
  166. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  167. struct stm32_adfsdm_priv *priv =
  168. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  169. snd_pcm_lib_free_pages(substream);
  170. priv->substream = NULL;
  171. return 0;
  172. }
  173. static snd_pcm_uframes_t stm32_adfsdm_pcm_pointer(
  174. struct snd_pcm_substream *substream)
  175. {
  176. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  177. struct stm32_adfsdm_priv *priv =
  178. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  179. return bytes_to_frames(substream->runtime, priv->pos);
  180. }
  181. static int stm32_adfsdm_pcm_hw_params(struct snd_pcm_substream *substream,
  182. struct snd_pcm_hw_params *params)
  183. {
  184. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  185. struct stm32_adfsdm_priv *priv =
  186. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  187. int ret;
  188. ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
  189. if (ret < 0)
  190. return ret;
  191. priv->pcm_buff = substream->runtime->dma_area;
  192. return iio_channel_cb_set_buffer_watermark(priv->iio_cb,
  193. params_period_size(params));
  194. }
  195. static int stm32_adfsdm_pcm_hw_free(struct snd_pcm_substream *substream)
  196. {
  197. snd_pcm_lib_free_pages(substream);
  198. return 0;
  199. }
  200. static struct snd_pcm_ops stm32_adfsdm_pcm_ops = {
  201. .open = stm32_adfsdm_pcm_open,
  202. .close = stm32_adfsdm_pcm_close,
  203. .hw_params = stm32_adfsdm_pcm_hw_params,
  204. .hw_free = stm32_adfsdm_pcm_hw_free,
  205. .trigger = stm32_adfsdm_trigger,
  206. .pointer = stm32_adfsdm_pcm_pointer,
  207. };
  208. static int stm32_adfsdm_pcm_new(struct snd_soc_pcm_runtime *rtd)
  209. {
  210. struct snd_pcm *pcm = rtd->pcm;
  211. struct stm32_adfsdm_priv *priv =
  212. snd_soc_dai_get_drvdata(rtd->cpu_dai);
  213. unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE;
  214. return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
  215. priv->dev, size, size);
  216. }
  217. static void stm32_adfsdm_pcm_free(struct snd_pcm *pcm)
  218. {
  219. struct snd_pcm_substream *substream;
  220. substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
  221. if (substream)
  222. snd_pcm_lib_preallocate_free_for_all(pcm);
  223. }
  224. static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
  225. .ops = &stm32_adfsdm_pcm_ops,
  226. .pcm_new = stm32_adfsdm_pcm_new,
  227. .pcm_free = stm32_adfsdm_pcm_free,
  228. };
  229. static const struct of_device_id stm32_adfsdm_of_match[] = {
  230. {.compatible = "st,stm32h7-dfsdm-dai"},
  231. {}
  232. };
  233. MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match);
  234. static int stm32_adfsdm_probe(struct platform_device *pdev)
  235. {
  236. struct stm32_adfsdm_priv *priv;
  237. int ret;
  238. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  239. if (!priv)
  240. return -ENOMEM;
  241. priv->dev = &pdev->dev;
  242. priv->dai_drv = stm32_adfsdm_dai;
  243. dev_set_drvdata(&pdev->dev, priv);
  244. ret = devm_snd_soc_register_component(&pdev->dev,
  245. &stm32_adfsdm_dai_component,
  246. &priv->dai_drv, 1);
  247. if (ret < 0)
  248. return ret;
  249. /* Associate iio channel */
  250. priv->iio_ch = devm_iio_channel_get_all(&pdev->dev);
  251. if (IS_ERR(priv->iio_ch))
  252. return PTR_ERR(priv->iio_ch);
  253. priv->iio_cb = iio_channel_get_all_cb(&pdev->dev, NULL, NULL);
  254. if (IS_ERR(priv->iio_cb))
  255. return PTR_ERR(priv->iio_cb);
  256. ret = devm_snd_soc_register_component(&pdev->dev,
  257. &stm32_adfsdm_soc_platform,
  258. NULL, 0);
  259. if (ret < 0)
  260. dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
  261. __func__);
  262. return ret;
  263. }
  264. static struct platform_driver stm32_adfsdm_driver = {
  265. .driver = {
  266. .name = STM32_ADFSDM_DRV_NAME,
  267. .of_match_table = stm32_adfsdm_of_match,
  268. },
  269. .probe = stm32_adfsdm_probe,
  270. };
  271. module_platform_driver(stm32_adfsdm_driver);
  272. MODULE_DESCRIPTION("stm32 DFSDM DAI driver");
  273. MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
  274. MODULE_LICENSE("GPL v2");
  275. MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME);