Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);