diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/codecs/da7213.c | 5 | ||||
-rw-r--r-- | sound/soc/codecs/da7213.h | 2 | ||||
-rw-r--r-- | sound/soc/codecs/da7219.c | 10 | ||||
-rw-r--r-- | sound/soc/codecs/hdac_hda.c | 6 | ||||
-rw-r--r-- | sound/soc/codecs/hdmi-codec.c | 6 | ||||
-rw-r--r-- | sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 18 | ||||
-rw-r--r-- | sound/soc/stm/stm32_sai_sub.c | 64 |
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; |