#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#define STM32_SPDIFRX_CR …
#define STM32_SPDIFRX_IMR …
#define STM32_SPDIFRX_SR …
#define STM32_SPDIFRX_IFCR …
#define STM32_SPDIFRX_DR …
#define STM32_SPDIFRX_CSR …
#define STM32_SPDIFRX_DIR …
#define STM32_SPDIFRX_VERR …
#define STM32_SPDIFRX_IDR …
#define STM32_SPDIFRX_SIDR …
#define SPDIFRX_CR_SPDIFEN_SHIFT …
#define SPDIFRX_CR_SPDIFEN_MASK …
#define SPDIFRX_CR_SPDIFENSET(x) …
#define SPDIFRX_CR_RXDMAEN …
#define SPDIFRX_CR_RXSTEO …
#define SPDIFRX_CR_DRFMT_SHIFT …
#define SPDIFRX_CR_DRFMT_MASK …
#define SPDIFRX_CR_DRFMTSET(x) …
#define SPDIFRX_CR_PMSK …
#define SPDIFRX_CR_VMSK …
#define SPDIFRX_CR_CUMSK …
#define SPDIFRX_CR_PTMSK …
#define SPDIFRX_CR_CBDMAEN …
#define SPDIFRX_CR_CHSEL_SHIFT …
#define SPDIFRX_CR_CHSEL …
#define SPDIFRX_CR_NBTR_SHIFT …
#define SPDIFRX_CR_NBTR_MASK …
#define SPDIFRX_CR_NBTRSET(x) …
#define SPDIFRX_CR_WFA …
#define SPDIFRX_CR_INSEL_SHIFT …
#define SPDIFRX_CR_INSEL_MASK …
#define SPDIFRX_CR_INSELSET(x) …
#define SPDIFRX_CR_CKSEN_SHIFT …
#define SPDIFRX_CR_CKSEN …
#define SPDIFRX_CR_CKSBKPEN …
#define SPDIFRX_IMR_RXNEI …
#define SPDIFRX_IMR_CSRNEIE …
#define SPDIFRX_IMR_PERRIE …
#define SPDIFRX_IMR_OVRIE …
#define SPDIFRX_IMR_SBLKIE …
#define SPDIFRX_IMR_SYNCDIE …
#define SPDIFRX_IMR_IFEIE …
#define SPDIFRX_XIMR_MASK …
#define SPDIFRX_SR_RXNE …
#define SPDIFRX_SR_CSRNE …
#define SPDIFRX_SR_PERR …
#define SPDIFRX_SR_OVR …
#define SPDIFRX_SR_SBD …
#define SPDIFRX_SR_SYNCD …
#define SPDIFRX_SR_FERR …
#define SPDIFRX_SR_SERR …
#define SPDIFRX_SR_TERR …
#define SPDIFRX_SR_WIDTH5_SHIFT …
#define SPDIFRX_SR_WIDTH5_MASK …
#define SPDIFRX_SR_WIDTH5SET(x) …
#define SPDIFRX_IFCR_PERRCF …
#define SPDIFRX_IFCR_OVRCF …
#define SPDIFRX_IFCR_SBDCF …
#define SPDIFRX_IFCR_SYNCDCF …
#define SPDIFRX_XIFCR_MASK …
#define SPDIFRX_DR0_DR_SHIFT …
#define SPDIFRX_DR0_DR_MASK …
#define SPDIFRX_DR0_DRSET(x) …
#define SPDIFRX_DR0_PE …
#define SPDIFRX_DR0_V …
#define SPDIFRX_DR0_U …
#define SPDIFRX_DR0_C …
#define SPDIFRX_DR0_PT_SHIFT …
#define SPDIFRX_DR0_PT_MASK …
#define SPDIFRX_DR0_PTSET(x) …
#define SPDIFRX_DR1_PE …
#define SPDIFRX_DR1_V …
#define SPDIFRX_DR1_U …
#define SPDIFRX_DR1_C …
#define SPDIFRX_DR1_PT_SHIFT …
#define SPDIFRX_DR1_PT_MASK …
#define SPDIFRX_DR1_PTSET(x) …
#define SPDIFRX_DR1_DR_SHIFT …
#define SPDIFRX_DR1_DR_MASK …
#define SPDIFRX_DR1_DRSET(x) …
#define SPDIFRX_DR1_DRNL1_SHIFT …
#define SPDIFRX_DR1_DRNL1_MASK …
#define SPDIFRX_DR1_DRNL1SET(x) …
#define SPDIFRX_DR1_DRNL2_SHIFT …
#define SPDIFRX_DR1_DRNL2_MASK …
#define SPDIFRX_DR1_DRNL2SET(x) …
#define SPDIFRX_CSR_USR_SHIFT …
#define SPDIFRX_CSR_USR_MASK …
#define SPDIFRX_CSR_USRGET(x) …
#define SPDIFRX_CSR_CS_SHIFT …
#define SPDIFRX_CSR_CS_MASK …
#define SPDIFRX_CSR_CSGET(x) …
#define SPDIFRX_CSR_SOB …
#define SPDIFRX_DIR_THI_SHIFT …
#define SPDIFRX_DIR_THI_MASK …
#define SPDIFRX_DIR_THI_SET(x) …
#define SPDIFRX_DIR_TLO_SHIFT …
#define SPDIFRX_DIR_TLO_MASK …
#define SPDIFRX_DIR_TLO_SET(x) …
#define SPDIFRX_SPDIFEN_DISABLE …
#define SPDIFRX_SPDIFEN_SYNC …
#define SPDIFRX_SPDIFEN_ENABLE …
#define SPDIFRX_VERR_MIN_MASK …
#define SPDIFRX_VERR_MAJ_MASK …
#define SPDIFRX_IDR_ID_MASK …
#define SPDIFRX_SIDR_SID_MASK …
#define SPDIFRX_IPIDR_NUMBER …
#define SPDIFRX_IN1 …
#define SPDIFRX_IN2 …
#define SPDIFRX_IN3 …
#define SPDIFRX_IN4 …
#define SPDIFRX_IN5 …
#define SPDIFRX_IN6 …
#define SPDIFRX_IN7 …
#define SPDIFRX_IN8 …
#define SPDIFRX_NBTR_NONE …
#define SPDIFRX_NBTR_3 …
#define SPDIFRX_NBTR_15 …
#define SPDIFRX_NBTR_63 …
#define SPDIFRX_DRFMT_RIGHT …
#define SPDIFRX_DRFMT_LEFT …
#define SPDIFRX_DRFMT_PACKED …
#define SPDIFRX_CS_BYTES_NB …
#define SPDIFRX_UB_BYTES_NB …
#define SPDIFRX_CSR_BUF_LENGTH …
struct stm32_spdifrx_data { … };
static void stm32_spdifrx_dma_complete(void *data)
{ … }
static int stm32_spdifrx_dma_ctrl_start(struct stm32_spdifrx_data *spdifrx)
{ … }
static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)
{ … }
static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
{ … }
static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
{ … }
static int stm32_spdifrx_dma_ctrl_register(struct device *dev,
struct stm32_spdifrx_data *spdifrx)
{
int ret;
spdifrx->ctrl_chan = dma_request_chan(dev, "rx-ctrl");
if (IS_ERR(spdifrx->ctrl_chan))
return dev_err_probe(dev, PTR_ERR(spdifrx->ctrl_chan),
"dma_request_slave_channel error\n");
spdifrx->dmab = devm_kzalloc(dev, sizeof(struct snd_dma_buffer),
GFP_KERNEL);
if (!spdifrx->dmab)
return -ENOMEM;
spdifrx->dmab->dev.type = SNDRV_DMA_TYPE_DEV_IRAM;
spdifrx->dmab->dev.dev = dev;
ret = snd_dma_alloc_pages(spdifrx->dmab->dev.type, dev,
SPDIFRX_CSR_BUF_LENGTH, spdifrx->dmab);
if (ret < 0) {
dev_err(dev, "snd_dma_alloc_pages returned error %d\n", ret);
return ret;
}
spdifrx->slave_config.direction = DMA_DEV_TO_MEM;
spdifrx->slave_config.src_addr = (dma_addr_t)(spdifrx->phys_addr +
STM32_SPDIFRX_CSR);
spdifrx->slave_config.dst_addr = spdifrx->dmab->addr;
spdifrx->slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
spdifrx->slave_config.src_maxburst = 1;
ret = dmaengine_slave_config(spdifrx->ctrl_chan,
&spdifrx->slave_config);
if (ret < 0) {
dev_err(dev, "dmaengine_slave_config returned error %d\n", ret);
spdifrx->ctrl_chan = NULL;
}
return ret;
};
static const char * const spdifrx_enum_input[] = …;
static const char * const spdifrx_enum_cs_channel[] = …;
static SOC_ENUM_SINGLE_DECL(ctrl_enum_input,
STM32_SPDIFRX_CR, SPDIFRX_CR_INSEL_SHIFT,
spdifrx_enum_input);
static SOC_ENUM_SINGLE_DECL(ctrl_enum_cs_channel,
STM32_SPDIFRX_CR, SPDIFRX_CR_CHSEL_SHIFT,
spdifrx_enum_cs_channel);
static int stm32_spdifrx_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int stm32_spdifrx_ub_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{ … }
static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
{ … }
static int stm32_spdifrx_capture_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static int stm32_spdif_user_bits_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{ … }
static struct snd_kcontrol_new stm32_spdifrx_iec_ctrls[] = …;
static struct snd_kcontrol_new stm32_spdifrx_ctrls[] = …;
static int stm32_spdifrx_dai_register_ctrls(struct snd_soc_dai *cpu_dai)
{ … }
static int stm32_spdifrx_dai_probe(struct snd_soc_dai *cpu_dai)
{ … }
static bool stm32_spdifrx_readable_reg(struct device *dev, unsigned int reg)
{ … }
static bool stm32_spdifrx_volatile_reg(struct device *dev, unsigned int reg)
{ … }
static bool stm32_spdifrx_writeable_reg(struct device *dev, unsigned int reg)
{ … }
static const struct regmap_config stm32_h7_spdifrx_regmap_conf = …;
static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
{ … }
static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{ … }
static int stm32_spdifrx_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *cpu_dai)
{ … }
static int stm32_spdifrx_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *cpu_dai)
{ … }
static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{ … }
static const struct snd_soc_dai_ops stm32_spdifrx_pcm_dai_ops = …;
static struct snd_soc_dai_driver stm32_spdifrx_dai[] = …;
static const struct snd_pcm_hardware stm32_spdifrx_pcm_hw = …;
static const struct snd_soc_component_driver stm32_spdifrx_component = …;
static const struct snd_dmaengine_pcm_config stm32_spdifrx_pcm_config = …;
static const struct of_device_id stm32_spdifrx_ids[] = …;
static int stm32_spdifrx_parse_of(struct platform_device *pdev,
struct stm32_spdifrx_data *spdifrx)
{ … }
static void stm32_spdifrx_remove(struct platform_device *pdev)
{ … }
static int stm32_spdifrx_probe(struct platform_device *pdev)
{ … }
MODULE_DEVICE_TABLE(of, stm32_spdifrx_ids);
#ifdef CONFIG_PM_SLEEP
static int stm32_spdifrx_suspend(struct device *dev)
{ … }
static int stm32_spdifrx_resume(struct device *dev)
{ … }
#endif
static const struct dev_pm_ops stm32_spdifrx_pm_ops = …;
static struct platform_driver stm32_spdifrx_driver = …;
module_platform_driver(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;
MODULE_ALIAS(…) …;
MODULE_LICENSE(…) …;