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