0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/module.h>
0012 #include <linux/mutex.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/slab.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/iio/iio.h>
0017 #include <linux/iio/consumer.h>
0018 #include <linux/iio/adc/stm32-dfsdm-adc.h>
0019
0020 #include <sound/pcm.h>
0021 #include <sound/soc.h>
0022
0023 #define STM32_ADFSDM_DRV_NAME "stm32-adfsdm"
0024
0025 #define DFSDM_MAX_PERIOD_SIZE (PAGE_SIZE / 2)
0026 #define DFSDM_MAX_PERIODS 6
0027
0028 struct stm32_adfsdm_priv {
0029 struct snd_soc_dai_driver dai_drv;
0030 struct snd_pcm_substream *substream;
0031 struct device *dev;
0032
0033
0034 struct iio_channel *iio_ch;
0035 struct iio_cb_buffer *iio_cb;
0036 bool iio_active;
0037
0038
0039 unsigned char *pcm_buff;
0040 unsigned int pos;
0041
0042 struct mutex lock;
0043 };
0044
0045 static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = {
0046 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
0047 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_PAUSE,
0048 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
0049
0050 .channels_min = 1,
0051 .channels_max = 1,
0052
0053 .periods_min = 2,
0054 .periods_max = DFSDM_MAX_PERIODS,
0055
0056 .period_bytes_max = DFSDM_MAX_PERIOD_SIZE,
0057 .buffer_bytes_max = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE
0058 };
0059
0060 static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
0061 struct snd_soc_dai *dai)
0062 {
0063 struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
0064
0065 mutex_lock(&priv->lock);
0066 if (priv->iio_active) {
0067 iio_channel_stop_all_cb(priv->iio_cb);
0068 priv->iio_active = false;
0069 }
0070 mutex_unlock(&priv->lock);
0071 }
0072
0073 static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
0074 struct snd_soc_dai *dai)
0075 {
0076 struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
0077 int ret;
0078
0079 mutex_lock(&priv->lock);
0080 if (priv->iio_active) {
0081 iio_channel_stop_all_cb(priv->iio_cb);
0082 priv->iio_active = false;
0083 }
0084
0085 ret = iio_write_channel_attribute(priv->iio_ch,
0086 substream->runtime->rate, 0,
0087 IIO_CHAN_INFO_SAMP_FREQ);
0088 if (ret < 0) {
0089 dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
0090 __func__, substream->runtime->rate);
0091 goto out;
0092 }
0093
0094 if (!priv->iio_active) {
0095 ret = iio_channel_start_all_cb(priv->iio_cb);
0096 if (!ret)
0097 priv->iio_active = true;
0098 else
0099 dev_err(dai->dev, "%s: IIO channel start failed (%d)\n",
0100 __func__, ret);
0101 }
0102
0103 out:
0104 mutex_unlock(&priv->lock);
0105
0106 return ret;
0107 }
0108
0109 static int stm32_adfsdm_set_sysclk(struct snd_soc_dai *dai, int clk_id,
0110 unsigned int freq, int dir)
0111 {
0112 struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
0113 ssize_t size;
0114 char str_freq[10];
0115
0116 dev_dbg(dai->dev, "%s: Enter for freq %d\n", __func__, freq);
0117
0118
0119
0120 snprintf(str_freq, sizeof(str_freq), "%u\n", freq);
0121 size = iio_write_channel_ext_info(priv->iio_ch, "spi_clk_freq",
0122 str_freq, sizeof(str_freq));
0123 if (size != sizeof(str_freq)) {
0124 dev_err(dai->dev, "%s: Failed to set SPI clock\n",
0125 __func__);
0126 return -EINVAL;
0127 }
0128 return 0;
0129 }
0130
0131 static const struct snd_soc_dai_ops stm32_adfsdm_dai_ops = {
0132 .shutdown = stm32_adfsdm_shutdown,
0133 .prepare = stm32_adfsdm_dai_prepare,
0134 .set_sysclk = stm32_adfsdm_set_sysclk,
0135 };
0136
0137 static const struct snd_soc_dai_driver stm32_adfsdm_dai = {
0138 .capture = {
0139 .channels_min = 1,
0140 .channels_max = 1,
0141 .formats = SNDRV_PCM_FMTBIT_S16_LE |
0142 SNDRV_PCM_FMTBIT_S32_LE,
0143 .rates = SNDRV_PCM_RATE_CONTINUOUS,
0144 .rate_min = 8000,
0145 .rate_max = 48000,
0146 },
0147 .ops = &stm32_adfsdm_dai_ops,
0148 };
0149
0150 static const struct snd_soc_component_driver stm32_adfsdm_dai_component = {
0151 .name = "stm32_dfsdm_audio",
0152 .legacy_dai_naming = 1,
0153 };
0154
0155 static void stm32_memcpy_32to16(void *dest, const void *src, size_t n)
0156 {
0157 unsigned int i = 0;
0158 u16 *d = (u16 *)dest, *s = (u16 *)src;
0159
0160 s++;
0161 for (i = n >> 1; i > 0; i--) {
0162 *d++ = *s++;
0163 s++;
0164 }
0165 }
0166
0167 static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private)
0168 {
0169 struct stm32_adfsdm_priv *priv = private;
0170 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(priv->substream);
0171 u8 *pcm_buff = priv->pcm_buff;
0172 u8 *src_buff = (u8 *)data;
0173 unsigned int old_pos = priv->pos;
0174 size_t buff_size = snd_pcm_lib_buffer_bytes(priv->substream);
0175 size_t period_size = snd_pcm_lib_period_bytes(priv->substream);
0176 size_t cur_size, src_size = size;
0177 snd_pcm_format_t format = priv->substream->runtime->format;
0178
0179 if (format == SNDRV_PCM_FORMAT_S16_LE)
0180 src_size >>= 1;
0181 cur_size = src_size;
0182
0183 dev_dbg(rtd->dev, "%s: buff_add :%pK, pos = %d, size = %zu\n",
0184 __func__, &pcm_buff[priv->pos], priv->pos, src_size);
0185
0186 if ((priv->pos + src_size) > buff_size) {
0187 if (format == SNDRV_PCM_FORMAT_S16_LE)
0188 stm32_memcpy_32to16(&pcm_buff[priv->pos], src_buff,
0189 buff_size - priv->pos);
0190 else
0191 memcpy(&pcm_buff[priv->pos], src_buff,
0192 buff_size - priv->pos);
0193 cur_size -= buff_size - priv->pos;
0194 priv->pos = 0;
0195 }
0196
0197 if (format == SNDRV_PCM_FORMAT_S16_LE)
0198 stm32_memcpy_32to16(&pcm_buff[priv->pos],
0199 &src_buff[src_size - cur_size], cur_size);
0200 else
0201 memcpy(&pcm_buff[priv->pos], &src_buff[src_size - cur_size],
0202 cur_size);
0203
0204 priv->pos = (priv->pos + cur_size) % buff_size;
0205
0206 if (cur_size != src_size || (old_pos && (old_pos % period_size < size)))
0207 snd_pcm_period_elapsed(priv->substream);
0208
0209 return 0;
0210 }
0211
0212 static int stm32_adfsdm_trigger(struct snd_soc_component *component,
0213 struct snd_pcm_substream *substream, int cmd)
0214 {
0215 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0216 struct stm32_adfsdm_priv *priv =
0217 snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
0218
0219 switch (cmd) {
0220 case SNDRV_PCM_TRIGGER_START:
0221 case SNDRV_PCM_TRIGGER_RESUME:
0222 priv->pos = 0;
0223 return stm32_dfsdm_get_buff_cb(priv->iio_ch->indio_dev,
0224 stm32_afsdm_pcm_cb, priv);
0225 case SNDRV_PCM_TRIGGER_SUSPEND:
0226 case SNDRV_PCM_TRIGGER_STOP:
0227 return stm32_dfsdm_release_buff_cb(priv->iio_ch->indio_dev);
0228 }
0229
0230 return -EINVAL;
0231 }
0232
0233 static int stm32_adfsdm_pcm_open(struct snd_soc_component *component,
0234 struct snd_pcm_substream *substream)
0235 {
0236 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0237 struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
0238 int ret;
0239
0240 ret = snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw);
0241 if (!ret)
0242 priv->substream = substream;
0243
0244 return ret;
0245 }
0246
0247 static int stm32_adfsdm_pcm_close(struct snd_soc_component *component,
0248 struct snd_pcm_substream *substream)
0249 {
0250 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0251 struct stm32_adfsdm_priv *priv =
0252 snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
0253
0254 priv->substream = NULL;
0255
0256 return 0;
0257 }
0258
0259 static snd_pcm_uframes_t stm32_adfsdm_pcm_pointer(
0260 struct snd_soc_component *component,
0261 struct snd_pcm_substream *substream)
0262 {
0263 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0264 struct stm32_adfsdm_priv *priv =
0265 snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
0266
0267 return bytes_to_frames(substream->runtime, priv->pos);
0268 }
0269
0270 static int stm32_adfsdm_pcm_hw_params(struct snd_soc_component *component,
0271 struct snd_pcm_substream *substream,
0272 struct snd_pcm_hw_params *params)
0273 {
0274 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0275 struct stm32_adfsdm_priv *priv =
0276 snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
0277
0278 priv->pcm_buff = substream->runtime->dma_area;
0279
0280 return iio_channel_cb_set_buffer_watermark(priv->iio_cb,
0281 params_period_size(params));
0282 }
0283
0284 static int stm32_adfsdm_pcm_new(struct snd_soc_component *component,
0285 struct snd_soc_pcm_runtime *rtd)
0286 {
0287 struct snd_pcm *pcm = rtd->pcm;
0288 struct stm32_adfsdm_priv *priv =
0289 snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
0290 unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE;
0291
0292 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
0293 priv->dev, size, size);
0294 return 0;
0295 }
0296
0297 static int stm32_adfsdm_dummy_cb(const void *data, void *private)
0298 {
0299
0300
0301
0302
0303
0304 return 0;
0305 }
0306
0307 static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
0308 .open = stm32_adfsdm_pcm_open,
0309 .close = stm32_adfsdm_pcm_close,
0310 .hw_params = stm32_adfsdm_pcm_hw_params,
0311 .trigger = stm32_adfsdm_trigger,
0312 .pointer = stm32_adfsdm_pcm_pointer,
0313 .pcm_construct = stm32_adfsdm_pcm_new,
0314 };
0315
0316 static const struct of_device_id stm32_adfsdm_of_match[] = {
0317 {.compatible = "st,stm32h7-dfsdm-dai"},
0318 {}
0319 };
0320 MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match);
0321
0322 static int stm32_adfsdm_probe(struct platform_device *pdev)
0323 {
0324 struct stm32_adfsdm_priv *priv;
0325 struct snd_soc_component *component;
0326 int ret;
0327
0328 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0329 if (!priv)
0330 return -ENOMEM;
0331
0332 priv->dev = &pdev->dev;
0333 priv->dai_drv = stm32_adfsdm_dai;
0334 mutex_init(&priv->lock);
0335
0336 dev_set_drvdata(&pdev->dev, priv);
0337
0338 pm_runtime_enable(&pdev->dev);
0339
0340 ret = devm_snd_soc_register_component(&pdev->dev,
0341 &stm32_adfsdm_dai_component,
0342 &priv->dai_drv, 1);
0343 if (ret < 0)
0344 return ret;
0345
0346
0347 priv->iio_ch = devm_iio_channel_get_all(&pdev->dev);
0348 if (IS_ERR(priv->iio_ch))
0349 return PTR_ERR(priv->iio_ch);
0350
0351 priv->iio_cb = iio_channel_get_all_cb(&pdev->dev, &stm32_adfsdm_dummy_cb, NULL);
0352 if (IS_ERR(priv->iio_cb))
0353 return PTR_ERR(priv->iio_cb);
0354
0355 component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
0356 if (!component)
0357 return -ENOMEM;
0358
0359 ret = snd_soc_component_initialize(component,
0360 &stm32_adfsdm_soc_platform,
0361 &pdev->dev);
0362 if (ret < 0)
0363 return ret;
0364 #ifdef CONFIG_DEBUG_FS
0365 component->debugfs_prefix = "pcm";
0366 #endif
0367
0368 ret = snd_soc_add_component(component, NULL, 0);
0369 if (ret < 0)
0370 dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
0371 __func__);
0372
0373 return ret;
0374 }
0375
0376 static int stm32_adfsdm_remove(struct platform_device *pdev)
0377 {
0378 snd_soc_unregister_component(&pdev->dev);
0379 pm_runtime_disable(&pdev->dev);
0380
0381 return 0;
0382 }
0383
0384 static struct platform_driver stm32_adfsdm_driver = {
0385 .driver = {
0386 .name = STM32_ADFSDM_DRV_NAME,
0387 .of_match_table = stm32_adfsdm_of_match,
0388 },
0389 .probe = stm32_adfsdm_probe,
0390 .remove = stm32_adfsdm_remove,
0391 };
0392
0393 module_platform_driver(stm32_adfsdm_driver);
0394
0395 MODULE_DESCRIPTION("stm32 DFSDM DAI driver");
0396 MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
0397 MODULE_LICENSE("GPL v2");
0398 MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME);