aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/soc/codecs/rt1011.c
diff options
context:
space:
mode:
authorShuming Fan <shumingf@realtek.com>2019-08-26 17:00:52 +0800
committerMark Brown <broonie@kernel.org>2019-08-27 20:38:42 +0100
commite9e897d5fdba9bda3a8c80ea39761413725f198c (patch)
treeb50e9407ffd79683ecddca91d1cdd7cf3c046229 /sound/soc/codecs/rt1011.c
parentASoC: es8316: fix inverted L/R of headphone mixer volume (diff)
downloadwireguard-linux-e9e897d5fdba9bda3a8c80ea39761413725f198c.tar.xz
wireguard-linux-e9e897d5fdba9bda3a8c80ea39761413725f198c.zip
ASoC: rt1011: add mutex protection to set_fmt/set_tdm_slot
The calibration process at booting will reset registers and bypass cache to make sure the calibration is done. We add mutex protection to avoid unexpected settings while the registration process and calibration are interleaved. Signed-off-by: Shuming Fan <shumingf@realtek.com> Link: https://lore.kernel.org/r/20190826090052.1875-1-shumingf@realtek.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/rt1011.c')
-rw-r--r--sound/soc/codecs/rt1011.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c
index 0a6ff13d76e1..ed28250d5e34 100644
--- a/sound/soc/codecs/rt1011.c
+++ b/sound/soc/codecs/rt1011.c
@@ -1619,14 +1619,18 @@ static int rt1011_hw_params(struct snd_pcm_substream *substream,
static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_component *component = dai->component;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_component_get_dapm(component);
unsigned int reg_val = 0, reg_bclk_inv = 0;
+ int ret = 0;
+ snd_soc_dapm_mutex_lock(dapm);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
reg_val |= RT1011_I2S_TDM_MS_S;
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -1636,7 +1640,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
reg_bclk_inv |= RT1011_TDM_INV_BCLK;
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1652,7 +1656,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
reg_val |= RT1011_I2S_TDM_DF_PCM_B;
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
switch (dai->id) {
@@ -1667,9 +1671,11 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
break;
default:
dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
- return -EINVAL;
+ ret = -EINVAL;
}
- return 0;
+
+ snd_soc_dapm_mutex_unlock(dapm);
+ return ret;
}
static int rt1011_set_component_sysclk(struct snd_soc_component *component,
@@ -1788,8 +1794,12 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{
struct snd_soc_component *component = dai->component;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_component_get_dapm(component);
unsigned int val = 0, tdm_en = 0;
+ int ret = 0;
+ snd_soc_dapm_mutex_lock(dapm);
if (rx_mask || tx_mask)
tdm_en = RT1011_TDM_I2S_DOCK_EN_1;
@@ -1809,7 +1819,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
case 2:
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
switch (slot_width) {
@@ -1828,7 +1838,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
case 16:
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
}
snd_soc_component_update_bits(component, RT1011_TDM1_SET_1,
@@ -1845,7 +1855,8 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
RT1011_ADCDAT1_PIN_CONFIG | RT1011_ADCDAT2_PIN_CONFIG,
RT1011_ADCDAT1_OUTPUT | RT1011_ADCDAT2_OUTPUT);
- return 0;
+ snd_soc_dapm_mutex_unlock(dapm);
+ return ret;
}
static int rt1011_probe(struct snd_soc_component *component)