155da0948SArnaud Pouliquen // SPDX-License-Identifier: GPL-2.0 255da0948SArnaud Pouliquen /* 355da0948SArnaud Pouliquen * This file is part of STM32 DFSDM ASoC DAI driver 455da0948SArnaud Pouliquen * 555da0948SArnaud Pouliquen * Copyright (C) 2017, STMicroelectronics - All Rights Reserved 655da0948SArnaud Pouliquen * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com> 755da0948SArnaud Pouliquen * Olivier Moysan <olivier.moysan@st.com> 855da0948SArnaud Pouliquen */ 955da0948SArnaud Pouliquen 1055da0948SArnaud Pouliquen #include <linux/clk.h> 1155da0948SArnaud Pouliquen #include <linux/module.h> 1255da0948SArnaud Pouliquen #include <linux/platform_device.h> 1355da0948SArnaud Pouliquen #include <linux/slab.h> 1455da0948SArnaud Pouliquen 1555da0948SArnaud Pouliquen #include <linux/iio/iio.h> 1655da0948SArnaud Pouliquen #include <linux/iio/consumer.h> 1755da0948SArnaud Pouliquen #include <linux/iio/adc/stm32-dfsdm-adc.h> 1855da0948SArnaud Pouliquen 1955da0948SArnaud Pouliquen #include <sound/pcm.h> 2055da0948SArnaud Pouliquen #include <sound/soc.h> 2155da0948SArnaud Pouliquen 2255da0948SArnaud Pouliquen #define STM32_ADFSDM_DRV_NAME "stm32-adfsdm" 2355da0948SArnaud Pouliquen 2455da0948SArnaud Pouliquen #define DFSDM_MAX_PERIOD_SIZE (PAGE_SIZE / 2) 2555da0948SArnaud Pouliquen #define DFSDM_MAX_PERIODS 6 2655da0948SArnaud Pouliquen 2755da0948SArnaud Pouliquen struct stm32_adfsdm_priv { 2855da0948SArnaud Pouliquen struct snd_soc_dai_driver dai_drv; 2955da0948SArnaud Pouliquen struct snd_pcm_substream *substream; 3055da0948SArnaud Pouliquen struct device *dev; 3155da0948SArnaud Pouliquen 3255da0948SArnaud Pouliquen /* IIO */ 3355da0948SArnaud Pouliquen struct iio_channel *iio_ch; 3455da0948SArnaud Pouliquen struct iio_cb_buffer *iio_cb; 3555da0948SArnaud Pouliquen bool iio_active; 3655da0948SArnaud Pouliquen 3755da0948SArnaud Pouliquen /* PCM buffer */ 3855da0948SArnaud Pouliquen unsigned char *pcm_buff; 3955da0948SArnaud Pouliquen unsigned int pos; 4055da0948SArnaud Pouliquen }; 4155da0948SArnaud Pouliquen 4255da0948SArnaud Pouliquen static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { 4355da0948SArnaud Pouliquen .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 4455da0948SArnaud Pouliquen SNDRV_PCM_INFO_PAUSE, 4555da0948SArnaud Pouliquen .formats = SNDRV_PCM_FMTBIT_S32_LE, 4655da0948SArnaud Pouliquen 4755da0948SArnaud Pouliquen .rate_min = 8000, 4855da0948SArnaud Pouliquen .rate_max = 32000, 4955da0948SArnaud Pouliquen 5055da0948SArnaud Pouliquen .channels_min = 1, 5155da0948SArnaud Pouliquen .channels_max = 1, 5255da0948SArnaud Pouliquen 5355da0948SArnaud Pouliquen .periods_min = 2, 5455da0948SArnaud Pouliquen .periods_max = DFSDM_MAX_PERIODS, 5555da0948SArnaud Pouliquen 5655da0948SArnaud Pouliquen .period_bytes_max = DFSDM_MAX_PERIOD_SIZE, 5755da0948SArnaud Pouliquen .buffer_bytes_max = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE 5855da0948SArnaud Pouliquen }; 5955da0948SArnaud Pouliquen 6055da0948SArnaud Pouliquen static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream, 6155da0948SArnaud Pouliquen struct snd_soc_dai *dai) 6255da0948SArnaud Pouliquen { 6355da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); 6455da0948SArnaud Pouliquen 6555da0948SArnaud Pouliquen if (priv->iio_active) { 6655da0948SArnaud Pouliquen iio_channel_stop_all_cb(priv->iio_cb); 6755da0948SArnaud Pouliquen priv->iio_active = false; 6855da0948SArnaud Pouliquen } 6955da0948SArnaud Pouliquen } 7055da0948SArnaud Pouliquen 7155da0948SArnaud Pouliquen static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, 7255da0948SArnaud Pouliquen struct snd_soc_dai *dai) 7355da0948SArnaud Pouliquen { 7455da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); 7555da0948SArnaud Pouliquen int ret; 7655da0948SArnaud Pouliquen 7755da0948SArnaud Pouliquen ret = iio_write_channel_attribute(priv->iio_ch, 7855da0948SArnaud Pouliquen substream->runtime->rate, 0, 7955da0948SArnaud Pouliquen IIO_CHAN_INFO_SAMP_FREQ); 8055da0948SArnaud Pouliquen if (ret < 0) { 8155da0948SArnaud Pouliquen dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", 8255da0948SArnaud Pouliquen __func__, substream->runtime->rate); 8355da0948SArnaud Pouliquen return ret; 8455da0948SArnaud Pouliquen } 8555da0948SArnaud Pouliquen 8655da0948SArnaud Pouliquen if (!priv->iio_active) { 8755da0948SArnaud Pouliquen ret = iio_channel_start_all_cb(priv->iio_cb); 8855da0948SArnaud Pouliquen if (!ret) 8955da0948SArnaud Pouliquen priv->iio_active = true; 9055da0948SArnaud Pouliquen else 9155da0948SArnaud Pouliquen dev_err(dai->dev, "%s: IIO channel start failed (%d)\n", 9255da0948SArnaud Pouliquen __func__, ret); 9355da0948SArnaud Pouliquen } 9455da0948SArnaud Pouliquen 9555da0948SArnaud Pouliquen return ret; 9655da0948SArnaud Pouliquen } 9755da0948SArnaud Pouliquen 9855da0948SArnaud Pouliquen static int stm32_adfsdm_set_sysclk(struct snd_soc_dai *dai, int clk_id, 9955da0948SArnaud Pouliquen unsigned int freq, int dir) 10055da0948SArnaud Pouliquen { 10155da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); 10255da0948SArnaud Pouliquen ssize_t size; 10355da0948SArnaud Pouliquen char str_freq[10]; 10455da0948SArnaud Pouliquen 10555da0948SArnaud Pouliquen dev_dbg(dai->dev, "%s: Enter for freq %d\n", __func__, freq); 10655da0948SArnaud Pouliquen 10755da0948SArnaud Pouliquen /* Set IIO frequency if CODEC is master as clock comes from SPI_IN */ 10855da0948SArnaud Pouliquen 10955da0948SArnaud Pouliquen snprintf(str_freq, sizeof(str_freq), "%d\n", freq); 11055da0948SArnaud Pouliquen size = iio_write_channel_ext_info(priv->iio_ch, "spi_clk_freq", 11155da0948SArnaud Pouliquen str_freq, sizeof(str_freq)); 11255da0948SArnaud Pouliquen if (size != sizeof(str_freq)) { 11355da0948SArnaud Pouliquen dev_err(dai->dev, "%s: Failed to set SPI clock\n", 11455da0948SArnaud Pouliquen __func__); 11555da0948SArnaud Pouliquen return -EINVAL; 11655da0948SArnaud Pouliquen } 11755da0948SArnaud Pouliquen return 0; 11855da0948SArnaud Pouliquen } 11955da0948SArnaud Pouliquen 12055da0948SArnaud Pouliquen static const struct snd_soc_dai_ops stm32_adfsdm_dai_ops = { 12155da0948SArnaud Pouliquen .shutdown = stm32_adfsdm_shutdown, 12255da0948SArnaud Pouliquen .prepare = stm32_adfsdm_dai_prepare, 12355da0948SArnaud Pouliquen .set_sysclk = stm32_adfsdm_set_sysclk, 12455da0948SArnaud Pouliquen }; 12555da0948SArnaud Pouliquen 12655da0948SArnaud Pouliquen static const struct snd_soc_dai_driver stm32_adfsdm_dai = { 12755da0948SArnaud Pouliquen .capture = { 12855da0948SArnaud Pouliquen .channels_min = 1, 12955da0948SArnaud Pouliquen .channels_max = 1, 13055da0948SArnaud Pouliquen .formats = SNDRV_PCM_FMTBIT_S32_LE, 13155da0948SArnaud Pouliquen .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 13255da0948SArnaud Pouliquen SNDRV_PCM_RATE_32000), 13355da0948SArnaud Pouliquen }, 13455da0948SArnaud Pouliquen .ops = &stm32_adfsdm_dai_ops, 13555da0948SArnaud Pouliquen }; 13655da0948SArnaud Pouliquen 13755da0948SArnaud Pouliquen static const struct snd_soc_component_driver stm32_adfsdm_dai_component = { 13855da0948SArnaud Pouliquen .name = "stm32_dfsdm_audio", 13955da0948SArnaud Pouliquen }; 14055da0948SArnaud Pouliquen 14155da0948SArnaud Pouliquen static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private) 14255da0948SArnaud Pouliquen { 14355da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = private; 14455da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd = priv->substream->private_data; 14555da0948SArnaud Pouliquen u8 *pcm_buff = priv->pcm_buff; 14655da0948SArnaud Pouliquen u8 *src_buff = (u8 *)data; 14755da0948SArnaud Pouliquen unsigned int buff_size = snd_pcm_lib_buffer_bytes(priv->substream); 14855da0948SArnaud Pouliquen unsigned int period_size = snd_pcm_lib_period_bytes(priv->substream); 14955da0948SArnaud Pouliquen unsigned int old_pos = priv->pos; 15055da0948SArnaud Pouliquen unsigned int cur_size = size; 15155da0948SArnaud Pouliquen 15255da0948SArnaud Pouliquen dev_dbg(rtd->dev, "%s: buff_add :%p, pos = %d, size = %zu\n", 15355da0948SArnaud Pouliquen __func__, &pcm_buff[priv->pos], priv->pos, size); 15455da0948SArnaud Pouliquen 15555da0948SArnaud Pouliquen if ((priv->pos + size) > buff_size) { 15655da0948SArnaud Pouliquen memcpy(&pcm_buff[priv->pos], src_buff, buff_size - priv->pos); 15755da0948SArnaud Pouliquen cur_size -= buff_size - priv->pos; 15855da0948SArnaud Pouliquen priv->pos = 0; 15955da0948SArnaud Pouliquen } 16055da0948SArnaud Pouliquen 16155da0948SArnaud Pouliquen memcpy(&pcm_buff[priv->pos], &src_buff[size - cur_size], cur_size); 16255da0948SArnaud Pouliquen priv->pos = (priv->pos + cur_size) % buff_size; 16355da0948SArnaud Pouliquen 16455da0948SArnaud Pouliquen if (cur_size != size || (old_pos && (old_pos % period_size < size))) 16555da0948SArnaud Pouliquen snd_pcm_period_elapsed(priv->substream); 16655da0948SArnaud Pouliquen 16755da0948SArnaud Pouliquen return 0; 16855da0948SArnaud Pouliquen } 16955da0948SArnaud Pouliquen 17055da0948SArnaud Pouliquen static int stm32_adfsdm_trigger(struct snd_pcm_substream *substream, int cmd) 17155da0948SArnaud Pouliquen { 17255da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd = substream->private_data; 17355da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = 17455da0948SArnaud Pouliquen snd_soc_dai_get_drvdata(rtd->cpu_dai); 17555da0948SArnaud Pouliquen 17655da0948SArnaud Pouliquen switch (cmd) { 17755da0948SArnaud Pouliquen case SNDRV_PCM_TRIGGER_START: 17855da0948SArnaud Pouliquen case SNDRV_PCM_TRIGGER_RESUME: 17955da0948SArnaud Pouliquen priv->pos = 0; 18055da0948SArnaud Pouliquen return stm32_dfsdm_get_buff_cb(priv->iio_ch->indio_dev, 18155da0948SArnaud Pouliquen stm32_afsdm_pcm_cb, priv); 18255da0948SArnaud Pouliquen case SNDRV_PCM_TRIGGER_SUSPEND: 18355da0948SArnaud Pouliquen case SNDRV_PCM_TRIGGER_STOP: 18455da0948SArnaud Pouliquen return stm32_dfsdm_release_buff_cb(priv->iio_ch->indio_dev); 18555da0948SArnaud Pouliquen } 18655da0948SArnaud Pouliquen 18755da0948SArnaud Pouliquen return -EINVAL; 18855da0948SArnaud Pouliquen } 18955da0948SArnaud Pouliquen 19055da0948SArnaud Pouliquen static int stm32_adfsdm_pcm_open(struct snd_pcm_substream *substream) 19155da0948SArnaud Pouliquen { 19255da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd = substream->private_data; 19355da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 19455da0948SArnaud Pouliquen int ret; 19555da0948SArnaud Pouliquen 19655da0948SArnaud Pouliquen ret = snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw); 19755da0948SArnaud Pouliquen if (!ret) 19855da0948SArnaud Pouliquen priv->substream = substream; 19955da0948SArnaud Pouliquen 20055da0948SArnaud Pouliquen return ret; 20155da0948SArnaud Pouliquen } 20255da0948SArnaud Pouliquen 20355da0948SArnaud Pouliquen static int stm32_adfsdm_pcm_close(struct snd_pcm_substream *substream) 20455da0948SArnaud Pouliquen { 20555da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd = substream->private_data; 20655da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = 20755da0948SArnaud Pouliquen snd_soc_dai_get_drvdata(rtd->cpu_dai); 20855da0948SArnaud Pouliquen 20955da0948SArnaud Pouliquen snd_pcm_lib_free_pages(substream); 21055da0948SArnaud Pouliquen priv->substream = NULL; 21155da0948SArnaud Pouliquen 21255da0948SArnaud Pouliquen return 0; 21355da0948SArnaud Pouliquen } 21455da0948SArnaud Pouliquen 21555da0948SArnaud Pouliquen static snd_pcm_uframes_t stm32_adfsdm_pcm_pointer( 21655da0948SArnaud Pouliquen struct snd_pcm_substream *substream) 21755da0948SArnaud Pouliquen { 21855da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd = substream->private_data; 21955da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = 22055da0948SArnaud Pouliquen snd_soc_dai_get_drvdata(rtd->cpu_dai); 22155da0948SArnaud Pouliquen 22255da0948SArnaud Pouliquen return bytes_to_frames(substream->runtime, priv->pos); 22355da0948SArnaud Pouliquen } 22455da0948SArnaud Pouliquen 22555da0948SArnaud Pouliquen static int stm32_adfsdm_pcm_hw_params(struct snd_pcm_substream *substream, 22655da0948SArnaud Pouliquen struct snd_pcm_hw_params *params) 22755da0948SArnaud Pouliquen { 22855da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd = substream->private_data; 22955da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = 23055da0948SArnaud Pouliquen snd_soc_dai_get_drvdata(rtd->cpu_dai); 23155da0948SArnaud Pouliquen int ret; 23255da0948SArnaud Pouliquen 23355da0948SArnaud Pouliquen ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 23455da0948SArnaud Pouliquen if (ret < 0) 23555da0948SArnaud Pouliquen return ret; 23655da0948SArnaud Pouliquen priv->pcm_buff = substream->runtime->dma_area; 23755da0948SArnaud Pouliquen 23855da0948SArnaud Pouliquen return iio_channel_cb_set_buffer_watermark(priv->iio_cb, 23955da0948SArnaud Pouliquen params_period_size(params)); 24055da0948SArnaud Pouliquen } 24155da0948SArnaud Pouliquen 24255da0948SArnaud Pouliquen static int stm32_adfsdm_pcm_hw_free(struct snd_pcm_substream *substream) 24355da0948SArnaud Pouliquen { 24455da0948SArnaud Pouliquen snd_pcm_lib_free_pages(substream); 24555da0948SArnaud Pouliquen 24655da0948SArnaud Pouliquen return 0; 24755da0948SArnaud Pouliquen } 24855da0948SArnaud Pouliquen 24955da0948SArnaud Pouliquen static struct snd_pcm_ops stm32_adfsdm_pcm_ops = { 25055da0948SArnaud Pouliquen .open = stm32_adfsdm_pcm_open, 25155da0948SArnaud Pouliquen .close = stm32_adfsdm_pcm_close, 25255da0948SArnaud Pouliquen .hw_params = stm32_adfsdm_pcm_hw_params, 25355da0948SArnaud Pouliquen .hw_free = stm32_adfsdm_pcm_hw_free, 25455da0948SArnaud Pouliquen .trigger = stm32_adfsdm_trigger, 25555da0948SArnaud Pouliquen .pointer = stm32_adfsdm_pcm_pointer, 25655da0948SArnaud Pouliquen }; 25755da0948SArnaud Pouliquen 25855da0948SArnaud Pouliquen static int stm32_adfsdm_pcm_new(struct snd_soc_pcm_runtime *rtd) 25955da0948SArnaud Pouliquen { 26055da0948SArnaud Pouliquen struct snd_pcm *pcm = rtd->pcm; 26155da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv = 26255da0948SArnaud Pouliquen snd_soc_dai_get_drvdata(rtd->cpu_dai); 26355da0948SArnaud Pouliquen unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE; 26455da0948SArnaud Pouliquen 26555da0948SArnaud Pouliquen return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 26655da0948SArnaud Pouliquen priv->dev, size, size); 26755da0948SArnaud Pouliquen } 26855da0948SArnaud Pouliquen 26955da0948SArnaud Pouliquen static void stm32_adfsdm_pcm_free(struct snd_pcm *pcm) 27055da0948SArnaud Pouliquen { 27155da0948SArnaud Pouliquen struct snd_pcm_substream *substream; 27255da0948SArnaud Pouliquen struct snd_soc_pcm_runtime *rtd; 27355da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv; 27455da0948SArnaud Pouliquen 27555da0948SArnaud Pouliquen substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 27655da0948SArnaud Pouliquen if (substream) { 27755da0948SArnaud Pouliquen rtd = substream->private_data; 27855da0948SArnaud Pouliquen priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 27955da0948SArnaud Pouliquen 28055da0948SArnaud Pouliquen snd_pcm_lib_preallocate_free_for_all(pcm); 28155da0948SArnaud Pouliquen } 28255da0948SArnaud Pouliquen } 28355da0948SArnaud Pouliquen 28466bf428eSKuninori Morimoto static struct snd_soc_component_driver stm32_adfsdm_soc_platform = { 28555da0948SArnaud Pouliquen .ops = &stm32_adfsdm_pcm_ops, 28655da0948SArnaud Pouliquen .pcm_new = stm32_adfsdm_pcm_new, 28755da0948SArnaud Pouliquen .pcm_free = stm32_adfsdm_pcm_free, 28855da0948SArnaud Pouliquen }; 28955da0948SArnaud Pouliquen 29055da0948SArnaud Pouliquen static const struct of_device_id stm32_adfsdm_of_match[] = { 29155da0948SArnaud Pouliquen {.compatible = "st,stm32h7-dfsdm-dai"}, 29255da0948SArnaud Pouliquen {} 29355da0948SArnaud Pouliquen }; 29455da0948SArnaud Pouliquen MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match); 29555da0948SArnaud Pouliquen 29655da0948SArnaud Pouliquen static int stm32_adfsdm_probe(struct platform_device *pdev) 29755da0948SArnaud Pouliquen { 29855da0948SArnaud Pouliquen struct stm32_adfsdm_priv *priv; 29955da0948SArnaud Pouliquen int ret; 30055da0948SArnaud Pouliquen 30155da0948SArnaud Pouliquen priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 30255da0948SArnaud Pouliquen if (!priv) 30355da0948SArnaud Pouliquen return -ENOMEM; 30455da0948SArnaud Pouliquen 30555da0948SArnaud Pouliquen priv->dev = &pdev->dev; 30655da0948SArnaud Pouliquen priv->dai_drv = stm32_adfsdm_dai; 30755da0948SArnaud Pouliquen 30855da0948SArnaud Pouliquen dev_set_drvdata(&pdev->dev, priv); 30955da0948SArnaud Pouliquen 31055da0948SArnaud Pouliquen ret = devm_snd_soc_register_component(&pdev->dev, 31155da0948SArnaud Pouliquen &stm32_adfsdm_dai_component, 31255da0948SArnaud Pouliquen &priv->dai_drv, 1); 31355da0948SArnaud Pouliquen if (ret < 0) 31455da0948SArnaud Pouliquen return ret; 31555da0948SArnaud Pouliquen 31655da0948SArnaud Pouliquen /* Associate iio channel */ 31755da0948SArnaud Pouliquen priv->iio_ch = devm_iio_channel_get_all(&pdev->dev); 31855da0948SArnaud Pouliquen if (IS_ERR(priv->iio_ch)) 31955da0948SArnaud Pouliquen return PTR_ERR(priv->iio_ch); 32055da0948SArnaud Pouliquen 32155da0948SArnaud Pouliquen priv->iio_cb = iio_channel_get_all_cb(&pdev->dev, NULL, NULL); 32255da0948SArnaud Pouliquen if (IS_ERR(priv->iio_cb)) 3236dee6722SWei Yongjun return PTR_ERR(priv->iio_cb); 32455da0948SArnaud Pouliquen 32566bf428eSKuninori Morimoto ret = devm_snd_soc_register_component(&pdev->dev, 32666bf428eSKuninori Morimoto &stm32_adfsdm_soc_platform, 32766bf428eSKuninori Morimoto NULL, 0); 32855da0948SArnaud Pouliquen if (ret < 0) 32955da0948SArnaud Pouliquen dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", 33055da0948SArnaud Pouliquen __func__); 33155da0948SArnaud Pouliquen 33255da0948SArnaud Pouliquen return ret; 33355da0948SArnaud Pouliquen } 33455da0948SArnaud Pouliquen 33555da0948SArnaud Pouliquen static struct platform_driver stm32_adfsdm_driver = { 33655da0948SArnaud Pouliquen .driver = { 33755da0948SArnaud Pouliquen .name = STM32_ADFSDM_DRV_NAME, 33855da0948SArnaud Pouliquen .of_match_table = stm32_adfsdm_of_match, 33955da0948SArnaud Pouliquen }, 34055da0948SArnaud Pouliquen .probe = stm32_adfsdm_probe, 34155da0948SArnaud Pouliquen }; 34255da0948SArnaud Pouliquen 34355da0948SArnaud Pouliquen module_platform_driver(stm32_adfsdm_driver); 34455da0948SArnaud Pouliquen 34555da0948SArnaud Pouliquen MODULE_DESCRIPTION("stm32 DFSDM DAI driver"); 34655da0948SArnaud Pouliquen MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); 34755da0948SArnaud Pouliquen MODULE_LICENSE("GPL v2"); 34855da0948SArnaud Pouliquen MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME); 349