summaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/Kconfig1
-rw-r--r--sound/soc/codecs/da7213.c5
-rw-r--r--sound/soc/codecs/da7213.h2
-rw-r--r--sound/soc/codecs/da7219.c10
-rw-r--r--sound/soc/codecs/hdac_hda.c6
-rw-r--r--sound/soc/codecs/hdmi-codec.c6
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c2
-rw-r--r--sound/soc/soc-dapm.c3
-rw-r--r--sound/soc/soc-pcm.c18
-rw-r--r--sound/soc/stm/stm32_sai_sub.c64
10 files changed, 90 insertions, 27 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9981d40ef45b..8f577258080b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1162,6 +1162,7 @@ config SND_SOC_WCD9335
tristate "WCD9335 Codec"
depends on SLIMBUS
select REGMAP_SLIMBUS
+ select REGMAP_IRQ
help
The WCD9335 is a standalone Hi-Fi audio CODEC IC, supports
Qualcomm Technologies, Inc. (QTI) multimedia solutions,
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 92d006a5283e..425c11d63e49 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1305,7 +1305,10 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
/* By default only 64 BCLK per WCLK is supported */
dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_64;
- snd_soc_component_write(component, DA7213_DAI_CLK_MODE, dai_clk_mode);
+ snd_soc_component_update_bits(component, DA7213_DAI_CLK_MODE,
+ DA7213_DAI_BCLKS_PER_WCLK_MASK |
+ DA7213_DAI_CLK_POL_MASK | DA7213_DAI_WCLK_POL_MASK,
+ dai_clk_mode);
snd_soc_component_update_bits(component, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
dai_ctrl);
snd_soc_component_write(component, DA7213_DAI_OFFSET, dai_offset);
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 5a78dba1dcb5..9d31efc3cfe5 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -181,7 +181,9 @@
#define DA7213_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
#define DA7213_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
#define DA7213_DAI_CLK_POL_INV (0x1 << 2)
+#define DA7213_DAI_CLK_POL_MASK (0x1 << 2)
#define DA7213_DAI_WCLK_POL_INV (0x1 << 3)
+#define DA7213_DAI_WCLK_POL_MASK (0x1 << 3)
#define DA7213_DAI_CLK_EN_MASK (0x1 << 7)
/* DA7213_DAI_CTRL = 0x29 */
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index 43c03e7b2f0e..7d9d1f84eed8 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -1673,20 +1673,26 @@ static const struct snd_soc_dai_ops da7219_dai_ops = {
#define DA7219_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+#define DA7219_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000)
+
static struct snd_soc_dai_driver da7219_dai = {
.name = "da7219-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = DA7219_DAI_CH_NUM_MAX,
- .rates = SNDRV_PCM_RATE_8000_96000,
+ .rates = DA7219_RATES,
.formats = DA7219_FORMATS,
},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = DA7219_DAI_CH_NUM_MAX,
- .rates = SNDRV_PCM_RATE_8000_96000,
+ .rates = DA7219_RATES,
.formats = DA7219_FORMATS,
},
.ops = &da7219_dai_ops,
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index f889d94c8e3c..7d4940256914 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -328,6 +328,12 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component)
dev_err(&hdev->dev, "failed to create hda codec %d\n", ret);
goto error_no_pm;
}
+ /*
+ * Overwrite type to HDA_DEV_ASOC since it is a ASoC driver
+ * hda_codec.c will check this flag to determine if unregister
+ * device is needed.
+ */
+ hdev->type = HDA_DEV_ASOC;
/*
* snd_hda_codec_device_new decrements the usage count so call get pm
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index ef6d6959ecc5..39caf19abb0b 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -439,8 +439,12 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
if (!ret) {
ret = snd_pcm_hw_constraint_eld(substream->runtime,
hcp->eld);
- if (ret)
+ if (ret) {
+ mutex_lock(&hcp->current_stream_lock);
+ hcp->current_stream = NULL;
+ mutex_unlock(&hcp->current_stream_lock);
return ret;
+ }
}
/* Select chmap supported */
hdmi_codec_eld_chmap(hcp);
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 7044d8c2b187..879f14257a3e 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -405,7 +405,7 @@ static const struct snd_pcm_hw_constraint_list constraints_dmic_channels = {
};
static const unsigned int dmic_2ch[] = {
- 4,
+ 2,
};
static const struct snd_pcm_hw_constraint_list constraints_dmic_2ch = {
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 65ee0bb5dd0b..81a7a12196ff 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -883,6 +883,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
case snd_soc_dapm_pga:
+ case snd_soc_dapm_effect:
case snd_soc_dapm_out_drv:
wname_in_long_name = true;
kcname_in_long_name = true;
@@ -2370,6 +2371,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt,
case snd_soc_dapm_dac:
case snd_soc_dapm_adc:
case snd_soc_dapm_pga:
+ case snd_soc_dapm_effect:
case snd_soc_dapm_out_drv:
case snd_soc_dapm_mixer:
case snd_soc_dapm_mixer_named_ctl:
@@ -3197,6 +3199,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
dapm_new_mux(w);
break;
case snd_soc_dapm_pga:
+ case snd_soc_dapm_effect:
case snd_soc_dapm_out_drv:
dapm_new_pga(w);
break;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 74695355c1f8..0a4f60c7a188 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -43,8 +43,8 @@ static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
else
codec_stream = &dai->driver->capture;
- /* If the codec specifies any rate at all, it supports the stream. */
- return codec_stream->rates;
+ /* If the codec specifies any channels at all, it supports the stream */
+ return codec_stream->channels_min;
}
/**
@@ -518,8 +518,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
continue;
if (component->driver->module_get_upon_open &&
- !try_module_get(component->dev->driver->owner))
- return -ENODEV;
+ !try_module_get(component->dev->driver->owner)) {
+ ret = -ENODEV;
+ goto module_err;
+ }
ret = component->driver->ops->open(substream);
if (ret < 0) {
@@ -636,7 +638,7 @@ codec_dai_err:
component_err:
soc_pcm_components_close(substream, component);
-
+module_err:
if (cpu_dai->driver->ops->shutdown)
cpu_dai->driver->ops->shutdown(substream, cpu_dai);
out:
@@ -1031,6 +1033,9 @@ interface_err:
codec_err:
for_each_rtd_codec_dai_rollback(rtd, i, codec_dai) {
+ if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
+ continue;
+
if (codec_dai->driver->ops->hw_free)
codec_dai->driver->ops->hw_free(substream, codec_dai);
codec_dai->rate = 0;
@@ -1088,6 +1093,9 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
/* now free hw params for the DAIs */
for_each_rtd_codec_dai(rtd, i, codec_dai) {
+ if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
+ continue;
+
if (codec_dai->driver->ops->hw_free)
codec_dai->driver->ops->hw_free(substream, codec_dai);
}
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index e3b021c9e8d0..2a74ce7c9440 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -70,6 +70,7 @@
#define SAI_IEC60958_STATUS_BYTES 24
#define SAI_MCLK_NAME_LEN 32
+#define SAI_RATE_11K 11025
/**
* struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
@@ -311,6 +312,25 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
return ret;
}
+static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai,
+ unsigned int rate)
+{
+ struct platform_device *pdev = sai->pdev;
+ struct clk *parent_clk = sai->pdata->clk_x8k;
+ int ret;
+
+ if (!(rate % SAI_RATE_11K))
+ parent_clk = sai->pdata->clk_x11k;
+
+ ret = clk_set_parent(sai->sai_ck, parent_clk);
+ if (ret)
+ dev_err(&pdev->dev, " Error %d setting sai_ck parent clock. %s",
+ ret, ret == -EBUSY ?
+ "Active stream rates conflict\n" : "\n");
+
+ return ret;
+}
+
static long stm32_sai_mclk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
@@ -492,25 +512,29 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
- if (dir == SND_SOC_CLOCK_OUT) {
+ if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
SAI_XCR1_NODIV,
(unsigned int)~SAI_XCR1_NODIV);
if (ret < 0)
return ret;
- dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
- sai->mclk_rate = freq;
+ /* If master clock is used, set parent clock now */
+ ret = stm32_sai_set_parent_clock(sai, freq);
+ if (ret)
+ return ret;
- if (sai->sai_mclk) {
- ret = clk_set_rate_exclusive(sai->sai_mclk,
- sai->mclk_rate);
- if (ret) {
- dev_err(cpu_dai->dev,
- "Could not set mclk rate\n");
- return ret;
- }
+ ret = clk_set_rate_exclusive(sai->sai_mclk, freq);
+ if (ret) {
+ dev_err(cpu_dai->dev,
+ ret == -EBUSY ?
+ "Active streams have incompatible rates" :
+ "Could not set mclk rate\n");
+ return ret;
}
+
+ dev_dbg(cpu_dai->dev, "SAI MCLK frequency is %uHz\n", freq);
+ sai->mclk_rate = freq;
}
return 0;
@@ -917,11 +941,13 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
int div = 0, cr1 = 0;
int sai_clk_rate, mclk_ratio, den;
unsigned int rate = params_rate(params);
+ int ret;
- if (!(rate % 11025))
- clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
- else
- clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
+ if (!sai->sai_mclk) {
+ ret = stm32_sai_set_parent_clock(sai, rate);
+ if (ret)
+ return ret;
+ }
sai_clk_rate = clk_get_rate(sai->sai_ck);
if (STM_SAI_IS_F4(sai->pdata)) {
@@ -1080,9 +1106,13 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV,
SAI_XCR1_NODIV);
- clk_disable_unprepare(sai->sai_ck);
+ /* Release mclk rate only if rate was actually set */
+ if (sai->mclk_rate) {
+ clk_rate_exclusive_put(sai->sai_mclk);
+ sai->mclk_rate = 0;
+ }
- clk_rate_exclusive_put(sai->sai_mclk);
+ clk_disable_unprepare(sai->sai_ck);
spin_lock_irqsave(&sai->irq_lock, flags);
sai->substream = NULL;