Commit 23534b19 authored by Mark Brown's avatar Mark Brown

Merge branch 'for-5.5' of...

Merge branch 'for-5.5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-5.6
parents 320b8b0d a14bf98c
...@@ -2432,6 +2432,13 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component) ...@@ -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); 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); disable_irq(rt5640->irq);
rt5640_cancel_work(rt5640); rt5640_cancel_work(rt5640);
......
...@@ -445,7 +445,8 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = { ...@@ -445,7 +445,8 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"), DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"),
DMI_MATCH(DMI_PRODUCT_NAME, "NB41"), 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), | BYT_CHT_ES8316_JD_INVERTED),
}, },
{ /* Teclast X98 Plus II */ { /* Teclast X98 Plus II */
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/cpu_device_id.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/jack.h> #include <sound/jack.h>
......
...@@ -539,6 +539,9 @@ void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd) ...@@ -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_rtdcom_list *rtdcom;
struct snd_soc_component *component; struct snd_soc_component *component;
if (!rtd->pcm)
return;
for_each_rtd_components(rtd, rtdcom, component) for_each_rtd_components(rtd, rtdcom, component)
if (component->driver->pcm_destruct) if (component->driver->pcm_destruct)
component->driver->pcm_destruct(component, rtd->pcm); component->driver->pcm_destruct(component, rtd->pcm);
......
...@@ -184,6 +184,56 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg) ...@@ -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 = { static const struct regmap_config stm32_sai_sub_regmap_config_f4 = {
.reg_bits = 32, .reg_bits = 32,
.reg_stride = 4, .reg_stride = 4,
...@@ -295,7 +345,7 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai, ...@@ -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)); mask = SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version));
cr1 = SAI_XCR1_MCKDIV_SET(div); 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) if (ret < 0)
dev_err(&sai->pdev->dev, "Failed to update CR1 register\n"); dev_err(&sai->pdev->dev, "Failed to update CR1 register\n");
...@@ -372,7 +422,7 @@ static int stm32_sai_mclk_enable(struct clk_hw *hw) ...@@ -372,7 +422,7 @@ static int stm32_sai_mclk_enable(struct clk_hw *hw)
dev_dbg(&sai->pdev->dev, "Enable master clock\n"); 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); SAI_XCR1_MCKEN, SAI_XCR1_MCKEN);
} }
...@@ -383,7 +433,7 @@ static void stm32_sai_mclk_disable(struct clk_hw *hw) ...@@ -383,7 +433,7 @@ static void stm32_sai_mclk_disable(struct clk_hw *hw)
dev_dbg(&sai->pdev->dev, "Disable master clock\n"); 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 = { static const struct clk_ops mclk_ops = {
...@@ -446,14 +496,14 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid) ...@@ -446,14 +496,14 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
unsigned int sr, imr, flags; unsigned int sr, imr, flags;
snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING; snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr); stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr);
regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr); stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr);
flags = sr & imr; flags = sr & imr;
if (!flags) if (!flags)
return IRQ_NONE; 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); SAI_XCLRFR_MASK);
if (!sai->substream) { if (!sai->substream) {
...@@ -503,7 +553,7 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, ...@@ -503,7 +553,7 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
int ret; int ret;
if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { 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, SAI_XCR1_NODIV,
freq ? 0 : SAI_XCR1_NODIV); freq ? 0 : SAI_XCR1_NODIV);
if (ret < 0) if (ret < 0)
...@@ -583,7 +633,7 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, ...@@ -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; 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->slot_width = slot_width;
sai->slots = slots; sai->slots = slots;
...@@ -665,7 +715,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ...@@ -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; cr1_mask |= SAI_XCR1_CKSTR;
frcr_mask |= SAI_XFRCR_FSPOL; 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 */ /* DAI clock master masks */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
...@@ -693,7 +743,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ...@@ -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; cr1_mask |= SAI_XCR1_SLAVE;
conf_update: 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) { if (ret < 0) {
dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
return ret; return ret;
...@@ -730,12 +780,12 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, ...@@ -730,12 +780,12 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream,
} }
/* Enable ITs */ /* 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); SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
imr = SAI_XIMR_OVRUDRIE; imr = SAI_XIMR_OVRUDRIE;
if (STM_SAI_IS_CAPTURE(sai)) { 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) if (cr2 & SAI_XCR2_MUTECNT_MASK)
imr |= SAI_XIMR_MUTEDETIE; imr |= SAI_XIMR_MUTEDETIE;
} }
...@@ -745,7 +795,7 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream, ...@@ -745,7 +795,7 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream,
else else
imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE; 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); SAI_XIMR_MASK, imr);
return 0; return 0;
...@@ -763,7 +813,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai, ...@@ -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 * SAI fifo threshold is set to half fifo, to keep enough space
* for DMA incoming bursts. * 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_MASK,
SAI_XCR2_FFLUSH | SAI_XCR2_FFLUSH |
SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF)); SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
...@@ -795,7 +845,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai, ...@@ -795,7 +845,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
if ((sai->slots == 2) && (params_channels(params) == 1)) if ((sai->slots == 2) && (params_channels(params) == 1))
cr1 |= SAI_XCR1_MONO; 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) { if (ret < 0) {
dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
return ret; return ret;
...@@ -809,7 +859,7 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai) ...@@ -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); struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int slotr, slot_sz; 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 * If SLOTSZ is set to auto in SLOTR, align slot width on data size
...@@ -831,14 +881,14 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai) ...@@ -831,14 +881,14 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai)
sai->slots = 2; sai->slots = 2;
/* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/ /* 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_MASK,
SAI_XSLOTR_NBSLOT_SET((sai->slots - 1))); SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
/* Set default slots mask if not already set from DT */ /* Set default slots mask if not already set from DT */
if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) { if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) {
sai->slot_mask = (1 << sai->slots) - 1; 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, STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
SAI_XSLOTR_SLOTEN_SET(sai->slot_mask)); SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
} }
...@@ -870,12 +920,12 @@ static void stm32_sai_set_frame(struct snd_soc_dai *cpu_dai) ...@@ -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", dev_dbg(cpu_dai->dev, "Frame length %d, frame active %d\n",
sai->fs_length, fs_active); 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) { if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
offset = sai->slot_width - sai->data_size; 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_MASK,
SAI_XSLOTR_FBOFF_SET(offset)); SAI_XSLOTR_FBOFF_SET(offset));
} }
...@@ -994,7 +1044,7 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai, ...@@ -994,7 +1044,7 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
return -EINVAL; return -EINVAL;
} }
regmap_update_bits(sai->regmap, stm32_sai_sub_reg_up(sai,
STM_SAI_CR1_REGX, STM_SAI_CR1_REGX,
SAI_XCR1_OSR, cr1); SAI_XCR1_OSR, cr1);
...@@ -1058,11 +1108,11 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -1058,11 +1108,11 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n"); 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); SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
/* Enable SAI */ /* 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); SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
if (ret < 0) if (ret < 0)
dev_err(cpu_dai->dev, "Failed to update CR1 register\n"); dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
...@@ -1072,14 +1122,14 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -1072,14 +1122,14 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n"); 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); 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, SAI_XCR1_SAIEN,
(unsigned int)~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, SAI_XCR1_DMAEN,
(unsigned int)~SAI_XCR1_DMAEN); (unsigned int)~SAI_XCR1_DMAEN);
if (ret < 0) if (ret < 0)
...@@ -1101,7 +1151,7 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, ...@@ -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); struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
unsigned long flags; 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); clk_disable_unprepare(sai->sai_ck);
...@@ -1169,7 +1219,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) ...@@ -1169,7 +1219,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
cr1_mask |= SAI_XCR1_SYNCEN_MASK; cr1_mask |= SAI_XCR1_SYNCEN_MASK;
cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync); 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 = { static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
...@@ -1322,8 +1372,13 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, ...@@ -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)) if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai))
sai->regmap_config = &stm32_sai_sub_regmap_config_h7; 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)) { if (IS_ERR(sai->regmap)) {
dev_err(&pdev->dev, "Failed to initialize MMIO\n"); dev_err(&pdev->dev, "Failed to initialize MMIO\n");
return PTR_ERR(sai->regmap); return PTR_ERR(sai->regmap);
...@@ -1420,6 +1475,10 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev, ...@@ -1420,6 +1475,10 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
return PTR_ERR(sai->sai_ck); return PTR_ERR(sai->sai_ck);
} }
ret = clk_prepare(sai->pdata->pclk);
if (ret < 0)
return ret;
if (STM_SAI_IS_F4(sai->pdata)) if (STM_SAI_IS_F4(sai->pdata))
return 0; return 0;
...@@ -1501,22 +1560,48 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) ...@@ -1501,22 +1560,48 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
return 0; 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 #ifdef CONFIG_PM_SLEEP
static int stm32_sai_sub_suspend(struct device *dev) static int stm32_sai_sub_suspend(struct device *dev)
{ {
struct stm32_sai_sub_data *sai = dev_get_drvdata(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_cache_only(sai->regmap, true);
regcache_mark_dirty(sai->regmap); regcache_mark_dirty(sai->regmap);
clk_disable(sai->pdata->pclk);
return 0; return 0;
} }
static int stm32_sai_sub_resume(struct device *dev) static int stm32_sai_sub_resume(struct device *dev)
{ {
struct stm32_sai_sub_data *sai = dev_get_drvdata(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); 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 */ #endif /* CONFIG_PM_SLEEP */
...@@ -1531,6 +1616,7 @@ static struct platform_driver stm32_sai_sub_driver = { ...@@ -1531,6 +1616,7 @@ static struct platform_driver stm32_sai_sub_driver = {
.pm = &stm32_sai_sub_pm_ops, .pm = &stm32_sai_sub_pm_ops,
}, },
.probe = stm32_sai_sub_probe, .probe = stm32_sai_sub_probe,
.remove = stm32_sai_sub_remove,
}; };
module_platform_driver(stm32_sai_sub_driver); module_platform_driver(stm32_sai_sub_driver);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment