Loading sound/soc/codecs/rt5640.c +7 −0 Original line number Diff line number Diff line Loading @@ -2432,6 +2432,13 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); /* * soc_remove_component() force-disables jack and thus rt5640->jack * could be NULL at the time of driver's module unloading. */ if (!rt5640->jack) return; disable_irq(rt5640->irq); rt5640_cancel_work(rt5640); Loading sound/soc/intel/boards/bytcht_es8316.c +2 −1 Original line number Diff line number Diff line Loading @@ -445,7 +445,8 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"), DMI_MATCH(DMI_PRODUCT_NAME, "NB41"), }, .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP .driver_data = (void *)(BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP | BYT_CHT_ES8316_JD_INVERTED), }, { /* Teclast X98 Plus II */ Loading sound/soc/intel/boards/cml_rt1011_rt5682.c +0 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ #include <linux/clk.h> #include <linux/dmi.h> #include <linux/slab.h> #include <asm/cpu_device_id.h> #include <linux/acpi.h> #include <sound/core.h> #include <sound/jack.h> Loading sound/soc/soc-component.c +3 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,9 @@ void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd) struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_component *component; if (!rtd->pcm) return; for_each_rtd_components(rtd, rtdcom, component) if (component->driver->pcm_destruct) component->driver->pcm_destruct(component, rtd->pcm); Loading sound/soc/stm/stm32_sai_sub.c +140 −54 Original line number Diff line number Diff line Loading @@ -184,6 +184,56 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg) } } static int stm32_sai_sub_reg_up(struct stm32_sai_sub_data *sai, unsigned int reg, unsigned int mask, unsigned int val) { int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; ret = regmap_update_bits(sai->regmap, reg, mask, val); clk_disable(sai->pdata->pclk); return ret; } static int stm32_sai_sub_reg_wr(struct stm32_sai_sub_data *sai, unsigned int reg, unsigned int mask, unsigned int val) { int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; ret = regmap_write_bits(sai->regmap, reg, mask, val); clk_disable(sai->pdata->pclk); return ret; } static int stm32_sai_sub_reg_rd(struct stm32_sai_sub_data *sai, unsigned int reg, unsigned int *val) { int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; ret = regmap_read(sai->regmap, reg, val); clk_disable(sai->pdata->pclk); return ret; } static const struct regmap_config stm32_sai_sub_regmap_config_f4 = { .reg_bits = 32, .reg_stride = 4, Loading Loading @@ -295,7 +345,7 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai, mask = SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version)); cr1 = SAI_XCR1_MCKDIV_SET(div); ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, mask, cr1); ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, mask, cr1); if (ret < 0) dev_err(&sai->pdev->dev, "Failed to update CR1 register\n"); Loading Loading @@ -372,7 +422,7 @@ static int stm32_sai_mclk_enable(struct clk_hw *hw) dev_dbg(&sai->pdev->dev, "Enable master clock\n"); return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, SAI_XCR1_MCKEN); } Loading @@ -383,7 +433,7 @@ static void stm32_sai_mclk_disable(struct clk_hw *hw) dev_dbg(&sai->pdev->dev, "Disable master clock\n"); regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0); stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0); } static const struct clk_ops mclk_ops = { Loading Loading @@ -446,14 +496,14 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid) unsigned int sr, imr, flags; snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING; regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr); regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr); stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr); stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr); flags = sr & imr; if (!flags) return IRQ_NONE; regmap_write_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, SAI_XCLRFR_MASK); if (!sai->substream) { Loading Loading @@ -503,7 +553,7 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, int ret; if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, freq ? 0 : SAI_XCR1_NODIV); if (ret < 0) Loading Loading @@ -583,7 +633,7 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, slotr_mask |= SAI_XSLOTR_SLOTEN_MASK; regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, slotr_mask, slotr); stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, slotr_mask, slotr); sai->slot_width = slot_width; sai->slots = slots; Loading Loading @@ -665,7 +715,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) cr1_mask |= SAI_XCR1_CKSTR; frcr_mask |= SAI_XFRCR_FSPOL; regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr); stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr); /* DAI clock master masks */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { Loading Loading @@ -693,7 +743,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) cr1_mask |= SAI_XCR1_SLAVE; conf_update: ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1); ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1); if (ret < 0) { dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); return ret; Loading Loading @@ -730,12 +780,12 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, } /* Enable ITs */ regmap_write_bits(sai->regmap, STM_SAI_CLRFR_REGX, stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, SAI_XCLRFR_MASK); imr = SAI_XIMR_OVRUDRIE; if (STM_SAI_IS_CAPTURE(sai)) { regmap_read(sai->regmap, STM_SAI_CR2_REGX, &cr2); stm32_sai_sub_reg_rd(sai, STM_SAI_CR2_REGX, &cr2); if (cr2 & SAI_XCR2_MUTECNT_MASK) imr |= SAI_XIMR_MUTEDETIE; } Loading @@ -745,7 +795,7 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, else imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE; regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, imr); return 0; Loading @@ -763,7 +813,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai, * SAI fifo threshold is set to half fifo, to keep enough space * for DMA incoming bursts. */ regmap_write_bits(sai->regmap, STM_SAI_CR2_REGX, stm32_sai_sub_reg_wr(sai, STM_SAI_CR2_REGX, SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK, SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF)); Loading Loading @@ -795,7 +845,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai, if ((sai->slots == 2) && (params_channels(params) == 1)) cr1 |= SAI_XCR1_MONO; ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1); ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1); if (ret < 0) { dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); return ret; Loading @@ -809,7 +859,7 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai) struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); int slotr, slot_sz; regmap_read(sai->regmap, STM_SAI_SLOTR_REGX, &slotr); stm32_sai_sub_reg_rd(sai, STM_SAI_SLOTR_REGX, &slotr); /* * If SLOTSZ is set to auto in SLOTR, align slot width on data size Loading @@ -831,14 +881,14 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai) sai->slots = 2; /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/ regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, SAI_XSLOTR_NBSLOT_MASK, SAI_XSLOTR_NBSLOT_SET((sai->slots - 1))); /* Set default slots mask if not already set from DT */ if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) { sai->slot_mask = (1 << sai->slots) - 1; regmap_update_bits(sai->regmap, stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK, SAI_XSLOTR_SLOTEN_SET(sai->slot_mask)); } Loading Loading @@ -870,12 +920,12 @@ static void stm32_sai_set_frame(struct snd_soc_dai *cpu_dai) dev_dbg(cpu_dai->dev, "Frame length %d, frame active %d\n", sai->fs_length, fs_active); regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr); stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr); if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) { offset = sai->slot_width - sai->data_size; regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, SAI_XSLOTR_FBOFF_MASK, SAI_XSLOTR_FBOFF_SET(offset)); } Loading Loading @@ -994,7 +1044,7 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, return -EINVAL; } regmap_update_bits(sai->regmap, stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_OSR, cr1); Loading Loading @@ -1058,11 +1108,11 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n"); regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_DMAEN, SAI_XCR1_DMAEN); /* Enable SAI */ ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_SAIEN, SAI_XCR1_SAIEN); if (ret < 0) dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); Loading @@ -1072,14 +1122,14 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n"); regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_SAIEN, (unsigned int)~SAI_XCR1_SAIEN); ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_DMAEN, (unsigned int)~SAI_XCR1_DMAEN); if (ret < 0) Loading @@ -1101,7 +1151,7 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); unsigned long flags; regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); clk_disable_unprepare(sai->sai_ck); Loading Loading @@ -1169,7 +1219,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) cr1_mask |= SAI_XCR1_SYNCEN_MASK; cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync); return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1); return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1); } static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = { Loading Loading @@ -1322,8 +1372,13 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai)) sai->regmap_config = &stm32_sai_sub_regmap_config_h7; sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "sai_ck", base, sai->regmap_config); /* * Do not manage peripheral clock through regmap framework as this * can lead to circular locking issue with sai master clock provider. * Manage peripheral clock directly in driver instead. */ sai->regmap = devm_regmap_init_mmio(&pdev->dev, base, sai->regmap_config); if (IS_ERR(sai->regmap)) { dev_err(&pdev->dev, "Failed to initialize MMIO\n"); return PTR_ERR(sai->regmap); Loading Loading @@ -1420,6 +1475,10 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, return PTR_ERR(sai->sai_ck); } ret = clk_prepare(sai->pdata->pclk); if (ret < 0) return ret; if (STM_SAI_IS_F4(sai->pdata)) return 0; Loading Loading @@ -1501,22 +1560,48 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) return 0; } static int stm32_sai_sub_remove(struct platform_device *pdev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev); clk_unprepare(sai->pdata->pclk); return 0; } #ifdef CONFIG_PM_SLEEP static int stm32_sai_sub_suspend(struct device *dev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(dev); int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; regcache_cache_only(sai->regmap, true); regcache_mark_dirty(sai->regmap); clk_disable(sai->pdata->pclk); return 0; } static int stm32_sai_sub_resume(struct device *dev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(dev); int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; regcache_cache_only(sai->regmap, false); return regcache_sync(sai->regmap); ret = regcache_sync(sai->regmap); clk_disable(sai->pdata->pclk); return ret; } #endif /* CONFIG_PM_SLEEP */ Loading @@ -1531,6 +1616,7 @@ static struct platform_driver stm32_sai_sub_driver = { .pm = &stm32_sai_sub_pm_ops, }, .probe = stm32_sai_sub_probe, .remove = stm32_sai_sub_remove, }; module_platform_driver(stm32_sai_sub_driver); Loading Loading
sound/soc/codecs/rt5640.c +7 −0 Original line number Diff line number Diff line Loading @@ -2432,6 +2432,13 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); /* * soc_remove_component() force-disables jack and thus rt5640->jack * could be NULL at the time of driver's module unloading. */ if (!rt5640->jack) return; disable_irq(rt5640->irq); rt5640_cancel_work(rt5640); Loading
sound/soc/intel/boards/bytcht_es8316.c +2 −1 Original line number Diff line number Diff line Loading @@ -445,7 +445,8 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"), DMI_MATCH(DMI_PRODUCT_NAME, "NB41"), }, .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP .driver_data = (void *)(BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP | BYT_CHT_ES8316_JD_INVERTED), }, { /* Teclast X98 Plus II */ Loading
sound/soc/intel/boards/cml_rt1011_rt5682.c +0 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ #include <linux/clk.h> #include <linux/dmi.h> #include <linux/slab.h> #include <asm/cpu_device_id.h> #include <linux/acpi.h> #include <sound/core.h> #include <sound/jack.h> Loading
sound/soc/soc-component.c +3 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,9 @@ void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd) struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_component *component; if (!rtd->pcm) return; for_each_rtd_components(rtd, rtdcom, component) if (component->driver->pcm_destruct) component->driver->pcm_destruct(component, rtd->pcm); Loading
sound/soc/stm/stm32_sai_sub.c +140 −54 Original line number Diff line number Diff line Loading @@ -184,6 +184,56 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg) } } static int stm32_sai_sub_reg_up(struct stm32_sai_sub_data *sai, unsigned int reg, unsigned int mask, unsigned int val) { int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; ret = regmap_update_bits(sai->regmap, reg, mask, val); clk_disable(sai->pdata->pclk); return ret; } static int stm32_sai_sub_reg_wr(struct stm32_sai_sub_data *sai, unsigned int reg, unsigned int mask, unsigned int val) { int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; ret = regmap_write_bits(sai->regmap, reg, mask, val); clk_disable(sai->pdata->pclk); return ret; } static int stm32_sai_sub_reg_rd(struct stm32_sai_sub_data *sai, unsigned int reg, unsigned int *val) { int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; ret = regmap_read(sai->regmap, reg, val); clk_disable(sai->pdata->pclk); return ret; } static const struct regmap_config stm32_sai_sub_regmap_config_f4 = { .reg_bits = 32, .reg_stride = 4, Loading Loading @@ -295,7 +345,7 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai, mask = SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version)); cr1 = SAI_XCR1_MCKDIV_SET(div); ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, mask, cr1); ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, mask, cr1); if (ret < 0) dev_err(&sai->pdev->dev, "Failed to update CR1 register\n"); Loading Loading @@ -372,7 +422,7 @@ static int stm32_sai_mclk_enable(struct clk_hw *hw) dev_dbg(&sai->pdev->dev, "Enable master clock\n"); return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, SAI_XCR1_MCKEN); } Loading @@ -383,7 +433,7 @@ static void stm32_sai_mclk_disable(struct clk_hw *hw) dev_dbg(&sai->pdev->dev, "Disable master clock\n"); regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0); stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0); } static const struct clk_ops mclk_ops = { Loading Loading @@ -446,14 +496,14 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid) unsigned int sr, imr, flags; snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING; regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr); regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr); stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr); stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr); flags = sr & imr; if (!flags) return IRQ_NONE; regmap_write_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, SAI_XCLRFR_MASK); if (!sai->substream) { Loading Loading @@ -503,7 +553,7 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, int ret; if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, freq ? 0 : SAI_XCR1_NODIV); if (ret < 0) Loading Loading @@ -583,7 +633,7 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, slotr_mask |= SAI_XSLOTR_SLOTEN_MASK; regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, slotr_mask, slotr); stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, slotr_mask, slotr); sai->slot_width = slot_width; sai->slots = slots; Loading Loading @@ -665,7 +715,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) cr1_mask |= SAI_XCR1_CKSTR; frcr_mask |= SAI_XFRCR_FSPOL; regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr); stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr); /* DAI clock master masks */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { Loading Loading @@ -693,7 +743,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) cr1_mask |= SAI_XCR1_SLAVE; conf_update: ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1); ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1); if (ret < 0) { dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); return ret; Loading Loading @@ -730,12 +780,12 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, } /* Enable ITs */ regmap_write_bits(sai->regmap, STM_SAI_CLRFR_REGX, stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK, SAI_XCLRFR_MASK); imr = SAI_XIMR_OVRUDRIE; if (STM_SAI_IS_CAPTURE(sai)) { regmap_read(sai->regmap, STM_SAI_CR2_REGX, &cr2); stm32_sai_sub_reg_rd(sai, STM_SAI_CR2_REGX, &cr2); if (cr2 & SAI_XCR2_MUTECNT_MASK) imr |= SAI_XIMR_MUTEDETIE; } Loading @@ -745,7 +795,7 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, else imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE; regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, imr); return 0; Loading @@ -763,7 +813,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai, * SAI fifo threshold is set to half fifo, to keep enough space * for DMA incoming bursts. */ regmap_write_bits(sai->regmap, STM_SAI_CR2_REGX, stm32_sai_sub_reg_wr(sai, STM_SAI_CR2_REGX, SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK, SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF)); Loading Loading @@ -795,7 +845,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai, if ((sai->slots == 2) && (params_channels(params) == 1)) cr1 |= SAI_XCR1_MONO; ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1); ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1); if (ret < 0) { dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); return ret; Loading @@ -809,7 +859,7 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai) struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); int slotr, slot_sz; regmap_read(sai->regmap, STM_SAI_SLOTR_REGX, &slotr); stm32_sai_sub_reg_rd(sai, STM_SAI_SLOTR_REGX, &slotr); /* * If SLOTSZ is set to auto in SLOTR, align slot width on data size Loading @@ -831,14 +881,14 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai) sai->slots = 2; /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/ regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, SAI_XSLOTR_NBSLOT_MASK, SAI_XSLOTR_NBSLOT_SET((sai->slots - 1))); /* Set default slots mask if not already set from DT */ if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) { sai->slot_mask = (1 << sai->slots) - 1; regmap_update_bits(sai->regmap, stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK, SAI_XSLOTR_SLOTEN_SET(sai->slot_mask)); } Loading Loading @@ -870,12 +920,12 @@ static void stm32_sai_set_frame(struct snd_soc_dai *cpu_dai) dev_dbg(cpu_dai->dev, "Frame length %d, frame active %d\n", sai->fs_length, fs_active); regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr); stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr); if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) { offset = sai->slot_width - sai->data_size; regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, SAI_XSLOTR_FBOFF_MASK, SAI_XSLOTR_FBOFF_SET(offset)); } Loading Loading @@ -994,7 +1044,7 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, return -EINVAL; } regmap_update_bits(sai->regmap, stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_OSR, cr1); Loading Loading @@ -1058,11 +1108,11 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n"); regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_DMAEN, SAI_XCR1_DMAEN); /* Enable SAI */ ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_SAIEN, SAI_XCR1_SAIEN); if (ret < 0) dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); Loading @@ -1072,14 +1122,14 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_STOP: dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n"); regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_SAIEN, (unsigned int)~SAI_XCR1_SAIEN); ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_DMAEN, (unsigned int)~SAI_XCR1_DMAEN); if (ret < 0) Loading @@ -1101,7 +1151,7 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai); unsigned long flags; regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); clk_disable_unprepare(sai->sai_ck); Loading Loading @@ -1169,7 +1219,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) cr1_mask |= SAI_XCR1_SYNCEN_MASK; cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync); return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1); return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1); } static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = { Loading Loading @@ -1322,8 +1372,13 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai)) sai->regmap_config = &stm32_sai_sub_regmap_config_h7; sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "sai_ck", base, sai->regmap_config); /* * Do not manage peripheral clock through regmap framework as this * can lead to circular locking issue with sai master clock provider. * Manage peripheral clock directly in driver instead. */ sai->regmap = devm_regmap_init_mmio(&pdev->dev, base, sai->regmap_config); if (IS_ERR(sai->regmap)) { dev_err(&pdev->dev, "Failed to initialize MMIO\n"); return PTR_ERR(sai->regmap); Loading Loading @@ -1420,6 +1475,10 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, return PTR_ERR(sai->sai_ck); } ret = clk_prepare(sai->pdata->pclk); if (ret < 0) return ret; if (STM_SAI_IS_F4(sai->pdata)) return 0; Loading Loading @@ -1501,22 +1560,48 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) return 0; } static int stm32_sai_sub_remove(struct platform_device *pdev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev); clk_unprepare(sai->pdata->pclk); return 0; } #ifdef CONFIG_PM_SLEEP static int stm32_sai_sub_suspend(struct device *dev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(dev); int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; regcache_cache_only(sai->regmap, true); regcache_mark_dirty(sai->regmap); clk_disable(sai->pdata->pclk); return 0; } static int stm32_sai_sub_resume(struct device *dev) { struct stm32_sai_sub_data *sai = dev_get_drvdata(dev); int ret; ret = clk_enable(sai->pdata->pclk); if (ret < 0) return ret; regcache_cache_only(sai->regmap, false); return regcache_sync(sai->regmap); ret = regcache_sync(sai->regmap); clk_disable(sai->pdata->pclk); return ret; } #endif /* CONFIG_PM_SLEEP */ Loading @@ -1531,6 +1616,7 @@ static struct platform_driver stm32_sai_sub_driver = { .pm = &stm32_sai_sub_pm_ops, }, .probe = stm32_sai_sub_probe, .remove = stm32_sai_sub_remove, }; module_platform_driver(stm32_sai_sub_driver); Loading