diff options
author | Steve Pfetsch <spfetsch@google.com> | 2016-05-03 12:49:49 -0700 |
---|---|---|
committer | Steve Pfetsch <spfetsch@google.com> | 2016-05-03 12:49:49 -0700 |
commit | 42408dde031eb14e0ebfa2a27993f01422f7de53 (patch) | |
tree | 99fa5fe0fee21d0edfbe44c9d31686e46299fb38 /sound | |
parent | 703c92069d9571adfc77eb3646654d3333d2c434 (diff) | |
parent | 452dd7ba0b1179321d1bea5b5a800d956378c05b (diff) |
Merge AU_LINUX_ANDROID_LA.HB.1.3.9.06.00.01.213.156 into android-msm-marlin-3.18
Conflicts:
arch/arm/mm/mmap.c
drivers/gpu/msm/adreno_a5xx.c
drivers/video/msm/mdss/msm_mdss_io_8974.c
kernel/trace/trace_event_perf.c
sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
Change-Id: I66e83a530e2314ab43fc5a4ed205662853418f98
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/audio-ext-clk.c | 90 | ||||
-rw-r--r-- | sound/soc/codecs/msm8x16-wcd.c | 48 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9335.c | 119 | ||||
-rw-r--r-- | sound/soc/codecs/wsa881x-analog.c | 24 | ||||
-rw-r--r-- | sound/soc/codecs/wsa881x.c | 8 | ||||
-rw-r--r-- | sound/soc/msm/msm8952-dai-links.c | 2 | ||||
-rw-r--r-- | sound/soc/msm/msm8996.c | 9 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c | 24 | ||||
-rwxr-xr-x | sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 64 | ||||
-rw-r--r-- | sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h | 10 | ||||
-rw-r--r-- | sound/usb/card.c | 2 |
11 files changed, 347 insertions, 53 deletions
diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c index 511bea3070e3..013021e08001 100644 --- a/sound/soc/codecs/audio-ext-clk.c +++ b/sound/soc/codecs/audio-ext-clk.c @@ -28,6 +28,7 @@ enum clk_mux { AP_CLK2, LPASS_MCLK, + LPASS_MCLK2, }; struct pinctrl_info { @@ -77,6 +78,15 @@ static const struct afe_clk_cfg lpass_default = { 0, }; +static struct afe_clk_set lpass_default2 = { + Q6AFE_LPASS_CLK_CONFIG_API_VERSION, + Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR, + Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk) { return container_of(clk, struct audio_ext_ap_clk, c); @@ -224,6 +234,58 @@ err: kfree(lpass_clk); } +static int audio_ext_lpass_mclk2_prepare(struct clk *clk) +{ + struct audio_ext_lpass_mclk *audio_lpass_mclk2; + struct pinctrl_info *pnctrl_info; + int ret; + + audio_lpass_mclk2 = container_of(clk, struct audio_ext_lpass_mclk, c); + pnctrl_info = &audio_lpass_mclk2->pnctrl_info; + + if (pnctrl_info->pinctrl) { + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->active); + if (ret) { + pr_err("%s: active state select failed with %d\n", + __func__, ret); + return -EIO; + } + } + + lpass_default2.enable = 1; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default2); + if (ret < 0) { + pr_err("%s: failed to set clock, ret = %d\n", __func__, ret); + return -EINVAL; + } + + return 0; +} + +static void audio_ext_lpass_mclk2_unprepare(struct clk *clk) +{ + struct audio_ext_lpass_mclk *audio_lpass_mclk2; + struct pinctrl_info *pnctrl_info; + int ret; + + audio_lpass_mclk2 = container_of(clk, struct audio_ext_lpass_mclk, c); + pnctrl_info = &audio_lpass_mclk2->pnctrl_info; + + if (pnctrl_info->pinctrl) { + ret = pinctrl_select_state(pnctrl_info->pinctrl, + pnctrl_info->sleep); + if (ret) + pr_err("%s: sleep state select failed with %d\n", + __func__, ret); + } + + lpass_default2.enable = 0; + ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default2); + if (ret < 0) + pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret); +} + static struct clk_ops audio_ext_ap_clk_ops = { .prepare = audio_ext_clk_prepare, .unprepare = audio_ext_clk_unprepare, @@ -239,6 +301,11 @@ static struct clk_ops audio_ext_lpass_mclk_ops = { .unprepare = audio_ext_lpass_mclk_unprepare, }; +static struct clk_ops audio_ext_lpass_mclk2_ops = { + .prepare = audio_ext_lpass_mclk2_prepare, + .unprepare = audio_ext_lpass_mclk2_unprepare, +}; + static struct audio_ext_pmi_clk audio_pmi_clk = { .gpio = -EINVAL, .c = { @@ -273,11 +340,20 @@ static struct audio_ext_lpass_mclk audio_lpass_mclk = { }, }; +static struct audio_ext_lpass_mclk audio_lpass_mclk2 = { + .c = { + .dbg_name = "audio_ext_lpass_mclk2", + .ops = &audio_ext_lpass_mclk2_ops, + CLK_INIT(audio_lpass_mclk2.c), + }, +}; + static struct clk_lookup audio_ref_clock[] = { CLK_LIST(audio_ap_clk), CLK_LIST(audio_pmi_clk), CLK_LIST(audio_ap_clk2), CLK_LIST(audio_lpass_mclk), + CLK_LIST(audio_lpass_mclk2), }; static int audio_get_pinctrl(struct platform_device *pdev, enum clk_mux mux) @@ -293,6 +369,9 @@ static int audio_get_pinctrl(struct platform_device *pdev, enum clk_mux mux) case LPASS_MCLK: pnctrl_info = &audio_lpass_mclk.pnctrl_info; break; + case LPASS_MCLK2: + pnctrl_info = &audio_lpass_mclk2.pnctrl_info; + break; default: dev_err(&pdev->dev, "%s Not a valid MUX ID: %d\n", __func__, mux); @@ -368,6 +447,11 @@ static int audio_ref_clk_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n", __func__, "LPASS_MCLK"); + ret = audio_get_pinctrl(pdev, LPASS_MCLK2); + if (ret) + dev_dbg(&pdev->dev, "%s: Parsing pinctrl %s failed\n", + __func__, "LPASS_MCLK2"); + ret = of_msm_clock_register(pdev->dev.of_node, audio_ref_clock, ARRAY_SIZE(audio_ref_clock)); if (ret) @@ -458,6 +542,12 @@ static int audio_ref_clk_remove(struct platform_device *pdev) pnctrl_info->pinctrl = NULL; } + pnctrl_info = &audio_lpass_mclk2.pnctrl_info; + if (pnctrl_info->pinctrl) { + devm_pinctrl_put(pnctrl_info->pinctrl); + pnctrl_info->pinctrl = NULL; + } + return 0; } diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c index 4fa9be38d2d3..8d7970b01d7a 100644 --- a/sound/soc/codecs/msm8x16-wcd.c +++ b/sound/soc/codecs/msm8x16-wcd.c @@ -2183,6 +2183,51 @@ static int msm8x16_wcd_boost_option_set(struct snd_kcontrol *kcontrol, return 0; } +static int msm8x16_wcd_spk_boost_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + if (msm8x16_wcd->spk_boost_set == false) { + ucontrol->value.integer.value[0] = 0; + } else if (msm8x16_wcd->spk_boost_set == true) { + ucontrol->value.integer.value[0] = 1; + } else { + dev_err(codec->dev, "%s: ERROR: Unsupported Speaker Boost = %d\n", + __func__, msm8x16_wcd->spk_boost_set); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n", __func__, + msm8x16_wcd->spk_boost_set); + return 0; +} + +static int msm8x16_wcd_spk_boost_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", + __func__, ucontrol->value.integer.value[0]); + + switch (ucontrol->value.integer.value[0]) { + case 0: + msm8x16_wcd->spk_boost_set = false; + break; + case 1: + msm8x16_wcd->spk_boost_set = true; + break; + default: + return -EINVAL; + } + dev_dbg(codec->dev, "%s: msm8x16_wcd->spk_boost_set = %d\n", + __func__, msm8x16_wcd->spk_boost_set); + return 0; +} + static int msm8x16_wcd_ext_spk_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2546,6 +2591,9 @@ static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = { SOC_ENUM_EXT("EAR PA Gain", msm8x16_wcd_ear_pa_gain_enum[0], msm8x16_wcd_pa_gain_get, msm8x16_wcd_pa_gain_put), + SOC_ENUM_EXT("Speaker Boost", msm8x16_wcd_spk_boost_ctl_enum[0], + msm8x16_wcd_spk_boost_get, msm8x16_wcd_spk_boost_set), + SOC_ENUM_EXT("Ext Spk Boost", msm8x16_wcd_ext_spk_boost_ctl_enum[0], msm8x16_wcd_ext_spk_boost_get, msm8x16_wcd_ext_spk_boost_set), diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 08a067de9e91..b0ee24d4089d 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -357,6 +357,12 @@ enum { HPH_PA_DELAY, SB_CLK_GEAR, CLASSH_CONFIG, + ANC_MIC_AMIC1, + ANC_MIC_AMIC2, + ANC_MIC_AMIC3, + ANC_MIC_AMIC4, + ANC_MIC_AMIC5, + ANC_MIC_AMIC6, }; enum { @@ -552,6 +558,7 @@ static struct snd_soc_dai_driver tasha_dai[]; static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv); static int tasha_config_compander(struct snd_soc_codec *, int, int); +static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool); /* Hold instance to soundwire platform device */ struct tasha_swr_ctrl_data { @@ -3593,7 +3600,7 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, WCD9335_CDC_ANC0_IIR_COEFF_2_CTL); anc_writes_size = anc_cal_size / 2; snd_soc_update_bits(codec, - WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x38); + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39); } else if (!strcmp(w->name, "RX INT2 DAC") || !strcmp(w->name, "RX INT4 DAC")) { tasha_realign_anc_coeff(codec, @@ -3601,7 +3608,7 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, WCD9335_CDC_ANC1_IIR_COEFF_2_CTL); i = anc_cal_size / 2; snd_soc_update_bits(codec, - WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x38); + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39); } for (; i < anc_writes_size; i++) { @@ -3611,16 +3618,23 @@ static int tasha_codec_enable_anc(struct snd_soc_dapm_widget *w, if (!strcmp(w->name, "RX INT1 DAC") || !strcmp(w->name, "RX INT3 DAC")) { snd_soc_update_bits(codec, - WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x38, 0x00); + WCD9335_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08); } else if (!strcmp(w->name, "RX INT2 DAC") || !strcmp(w->name, "RX INT4 DAC")) { snd_soc_update_bits(codec, - WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x38, 0x00); + WCD9335_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08); } if (!hwdep_cal) release_firmware(fw); break; + case SND_SOC_DAPM_POST_PMU: + /* Remove ANC Rx from reset */ + snd_soc_update_bits(codec, WCD9335_CDC_ANC0_CLK_RESET_CTL, + 0x08, 0x00); + snd_soc_update_bits(codec, WCD9335_CDC_ANC1_CLK_RESET_CTL, + 0x08, 0x00); + break; case SND_SOC_DAPM_POST_PMD: if (!strcmp(w->name, "ANC HPHL PA") || !strcmp(w->name, "ANC EAR PA") || @@ -3660,6 +3674,22 @@ err: return ret; } +static void tasha_codec_clear_anc_tx_hold(struct tasha_priv *tasha) +{ + if (test_and_clear_bit(ANC_MIC_AMIC1, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC1, false); + if (test_and_clear_bit(ANC_MIC_AMIC2, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC2, false); + if (test_and_clear_bit(ANC_MIC_AMIC3, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC3, false); + if (test_and_clear_bit(ANC_MIC_AMIC4, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC4, false); + if (test_and_clear_bit(ANC_MIC_AMIC5, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC5, false); + if (test_and_clear_bit(ANC_MIC_AMIC6, &tasha->status_mask)) + tasha_codec_set_tx_hold(tasha->codec, WCD9335_ANA_AMIC6, false); +} + static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha, int mode, int event) { @@ -3678,6 +3708,13 @@ static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha, scale_val = 0x1; break; } + if (tasha->anc_func) { + /* Clear Tx FE HOLD if both PAs are enabled */ + if ((snd_soc_read(tasha->codec, WCD9335_ANA_HPH) & + 0xC0) == 0xC0) { + tasha_codec_clear_anc_tx_hold(tasha); + } + } break; case SND_SOC_DAPM_PRE_PMD: scale_val = 0x6; @@ -3744,9 +3781,19 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "ANC HPHR PA"))) && + (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); + } set_bit(HPH_PA_DELAY, &tasha->status_mask); break; case SND_SOC_DAPM_POST_PMU: + if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) != 0xC0) + /* If PA_EN is not set (potentially in ANC case) then + * do nothing for POST_PMU and let left channel handle + * everything. + */ + break; /* * 7ms sleep is required after PA is enabled as per * HW requirement @@ -3764,13 +3811,31 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); + + if (!(strcmp(w->name, "ANC HPHR PA"))) { + /* Do everything needed for left channel */ + snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX1_RX_PATH_MIX_CTL, + 0x10, 0x00); + /* Remove ANC Rx from reset */ + ret = tasha_codec_enable_anc(w, kcontrol, event); + } tasha_codec_override(codec, hph_mode, event); break; + case SND_SOC_DAPM_PRE_PMD: blocking_notifier_call_chain(&tasha->notifier, WCD_EVENT_PRE_HPHR_PA_OFF, &tasha->mbhc); tasha_codec_hph_post_pa_config(tasha, hph_mode, event); + if (!(strcmp(w->name, "ANC HPHR PA"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x40, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* 5ms sleep is required after PA is disabled as per @@ -3806,9 +3871,19 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + if ((!(strcmp(w->name, "ANC HPHL PA"))) && + (test_bit(HPH_PA_DELAY, &tasha->status_mask))) { + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0xC0, 0xC0); + } set_bit(HPH_PA_DELAY, &tasha->status_mask); break; case SND_SOC_DAPM_POST_PMU: + if ((snd_soc_read(codec, WCD9335_ANA_HPH) & 0xC0) != 0xC0) + /* If PA_EN is not set (potentially in ANC case) then + * do nothing for POST_PMU and let right channel handle + * everything. + */ + break; /* * 7ms sleep is required after PA is enabled as per * HW requirement @@ -3827,6 +3902,22 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); + + if (!(strcmp(w->name, "ANC HPHL PA"))) { + /* Do everything needed for right channel */ + snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL, + 0x10, 0x00); + /* Remove mix path mute if it is enabled */ + if ((snd_soc_read(codec, + WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & + 0x10) + snd_soc_update_bits(codec, + WCD9335_CDC_RX2_RX_PATH_MIX_CTL, + 0x10, 0x00); + + /* Remove ANC Rx from reset */ + ret = tasha_codec_enable_anc(w, kcontrol, event); + } tasha_codec_override(codec, hph_mode, event); break; case SND_SOC_DAPM_PRE_PMD: @@ -3834,6 +3925,8 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD_EVENT_PRE_HPHL_PA_OFF, &tasha->mbhc); tasha_codec_hph_post_pa_config(tasha, hph_mode, event); + if (!(strcmp(w->name, "ANC HPHL PA"))) + snd_soc_update_bits(codec, WCD9335_ANA_HPH, 0x80, 0x00); break; case SND_SOC_DAPM_POST_PMD: /* 5ms sleep is required after PA is disabled as per @@ -3901,6 +3994,9 @@ static int tasha_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, lineout_mix_vol_reg, 0x10, 0x00); + if (!(strcmp(w->name, "ANC LINEOUT1 PA")) || + !(strcmp(w->name, "ANC LINEOUT2 PA"))) + ret = tasha_codec_enable_anc(w, kcontrol, event); tasha_codec_override(codec, CLS_AB, event); break; case SND_SOC_DAPM_POST_PMD: @@ -5233,8 +5329,8 @@ static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, { int adc_mux_n = w->shift; struct snd_soc_codec *codec = w->codec; + struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); int amic_n; - u16 amic_reg; dev_dbg(codec->dev, "%s: event: %d\n", __func__, event); @@ -5242,8 +5338,13 @@ static int tasha_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: amic_n = tasha_codec_find_amic_input(codec, adc_mux_n); if (amic_n) { - amic_reg = WCD9335_ANA_AMIC1 + amic_n - 1; - tasha_codec_set_tx_hold(codec, amic_reg, false); + /* + * Prevent ANC Rx pop by leaving Tx FE in HOLD + * state until PA is up. Track AMIC being used + * so we can release the HOLD later. + */ + set_bit(ANC_MIC_AMIC1 + amic_n - 1, + &tasha->status_mask); } break; default: @@ -10357,11 +10458,11 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { tasha_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("ANC HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0, + SND_SOC_DAPM_PGA_E("ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0, tasha_codec_enable_hphl_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("ANC HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0, + SND_SOC_DAPM_PGA_E("ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0, tasha_codec_enable_hphr_pa, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), diff --git a/sound/soc/codecs/wsa881x-analog.c b/sound/soc/codecs/wsa881x-analog.c index 04bccb4a8ad2..2bb6cf805926 100644 --- a/sound/soc/codecs/wsa881x-analog.c +++ b/sound/soc/codecs/wsa881x-analog.c @@ -903,7 +903,8 @@ static int wsa881x_startup(struct wsa881x_pdata *pdata) if (pdata->enable_mclk) { ret = pdata->enable_mclk(card, true); if (ret < 0) { - pr_err("%s: mclk enable failed %d\n", + dev_err_ratelimited(codec->dev, + "%s: mclk enable failed %d\n", __func__, ret); return ret; } @@ -966,7 +967,8 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, if (enable) { ret = wsa881x_startup(wsa881x); if (ret < 0) { - pr_err("%s: failed to startup\n", __func__); + dev_err_ratelimited(codec->dev, + "%s: failed to startup\n", __func__); return ret; } } @@ -975,7 +977,8 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, if (!enable) { ret = wsa881x_shutdown(wsa881x); if (ret < 0) - pr_err("%s: failed to shutdown\n", __func__); + dev_err_ratelimited(codec->dev, + "%s: failed to shutdown\n", __func__); } return ret; } @@ -984,12 +987,18 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, struct wsa_temp_register *wsa_temp_reg) { struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec); + int ret = 0; if (!wsa881x) { dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__); return -EINVAL; } - wsa881x_resource_acquire(codec, true); + ret = wsa881x_resource_acquire(codec, true); + if (ret) { + dev_err_ratelimited(codec->dev, + "%s: resource acquire fail\n", __func__); + return ret; + } if (WSA881X_IS_2_0(wsa881x->version)) { snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00); @@ -1007,9 +1016,12 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec, wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3); wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4); - wsa881x_resource_acquire(codec, false); + ret = wsa881x_resource_acquire(codec, false); + if (ret) + dev_err_ratelimited(codec->dev, + "%s: resource release fail\n", __func__); - return 0; + return ret; } static int wsa881x_probe(struct snd_soc_codec *codec) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 4322711376a6..c54957e88b04 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -740,6 +740,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w, wsa881x_boost_ctrl(codec, ENABLE); break; case SND_SOC_DAPM_POST_PMD: + swr_slvdev_datapath_control(wsa881x->swr_slave, + wsa881x->swr_slave->dev_num, + false); if (wsa881x->boost_enable) wsa881x_boost_ctrl(codec, DISABLE); wsa881x_resource_acquire(codec, DISABLE); @@ -805,6 +808,9 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, regmap_multi_reg_write(wsa881x->regmap, wsa881x_pre_pmu_pa, ARRAY_SIZE(wsa881x_pre_pmu_pa)); + swr_slvdev_datapath_control(wsa881x->swr_slave, + wsa881x->swr_slave->dev_num, + true); break; case SND_SOC_DAPM_POST_PMU: if (WSA881X_IS_2_0(wsa881x->version)) { diff --git a/sound/soc/msm/msm8952-dai-links.c b/sound/soc/msm/msm8952-dai-links.c index 2b341beadd06..25ad870ad1ef 100644 --- a/sound/soc/msm/msm8952-dai-links.c +++ b/sound/soc/msm/msm8952-dai-links.c @@ -1512,7 +1512,7 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev) { struct snd_soc_card *card = &snd_soc_card_msm_card; struct snd_soc_dai_link *msm8952_dai_links = NULL; - int num_links, ret, len1, len2, len3, len4; + int num_links, ret, len1, len2, len3, len4 = 0; enum codec_variant codec_ver = 0; const char *tasha_lite[NUM_OF_TASHA_LITE_DEVICE] = { "msm8952-tashalite-snd-card", diff --git a/sound/soc/msm/msm8996.c b/sound/soc/msm/msm8996.c index f06d5d365283..13cfd93bbbef 100644 --- a/sound/soc/msm/msm8996.c +++ b/sound/soc/msm/msm8996.c @@ -2897,7 +2897,14 @@ static int msm8996_wcd93xx_codec_up(struct snd_soc_codec *codec) do { if (!q6core_is_adsp_ready()) { - pr_err("%s: ADSP Audio isn't ready\n", __func__); + pr_err_ratelimited("%s: ADSP Audio isn't ready\n", + __func__); + /* + * ADSP will be coming up after subsystem restart and + * it might not be fully up when the control reaches + * here. So, wait for 50msec before checking ADSP state + */ + msleep(50); } else { pr_debug("%s: ADSP Audio is ready\n", __func__); adsp_ready = 1; diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index e6667cc12439..be30f8f172d6 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -1370,7 +1370,11 @@ static int msm_ds2_dap_handle_commands(u32 cmd, void *arg) int ret = 0, port_id = 0; int32_t data; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; - get_user(data, &dolby_data->data[0]); + if (get_user(data, &dolby_data->data[0])) { + pr_debug("%s error getting data\n", __func__); + ret = -EFAULT; + goto end; + } pr_debug("%s: param_id %d,be_id %d,device_id 0x%x,length %d,data %d\n", __func__, dolby_data->param_id, dolby_data->be_id, @@ -1489,11 +1493,23 @@ static int msm_ds2_dap_set_param(u32 cmd, void *arg) goto end; } + off = ds2_dap_params_offset[idx]; + if ((dolby_data->length <= 0) || + (dolby_data->length > TOTAL_LENGTH_DS2_PARAM - off)) { + pr_err("%s: invalid length %d at idx %d\n", + __func__, dolby_data->length, idx); + rc = -EINVAL; + goto end; + } + /* cache the parameters */ ds2_dap_params[cdev].dap_params_modified[idx] += 1; for (j = 0; j < dolby_data->length; j++) { - off = ds2_dap_params_offset[idx]; - get_user(data, &dolby_data->data[j]); + if (get_user(data, &dolby_data->data[j])) { + pr_debug("%s:error getting data\n", __func__); + rc = -EFAULT; + goto end; + } ds2_dap_params[cdev].params_val[off + j] = data; pr_debug("%s:off %d,val[i/p:o/p]-[%d / %d]\n", __func__, off, data, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 62a315f50a7b..1425e6633ed4 100755 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -86,9 +86,9 @@ static int quat_mi2s_switch_enable; static int fm_pcmrx_switch_enable; static int lsm_mux_slim_port; static int slim0_rx_aanc_fb_port; -static int msm_route_ec_ref_rx = 9; /* NONE */ +static int msm_route_ec_ref_rx; static uint32_t voc_session_id = ALL_SESSION_VSID; -static int msm_route_ext_ec_ref = AFE_PORT_INVALID; +static int msm_route_ext_ec_ref; static bool is_custom_stereo_on; static bool is_ds2_on; @@ -2338,41 +2338,44 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget = wlist->widgets[0]; int mux = ucontrol->value.enumerated.item[0]; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - int ret = 0; - bool state = false; + int ret = 1; + bool state = true; + uint16_t ext_ec_ref_port_id; struct snd_soc_dapm_update *update = NULL; - pr_debug("%s: msm_route_ec_ref_rx = %d value = %ld\n", - __func__, msm_route_ext_ec_ref, - ucontrol->value.integer.value[0]); - mutex_lock(&routing_lock); - switch (ucontrol->value.integer.value[0]) { - case EC_PORT_ID_PRIMARY_MI2S_TX: - msm_route_ext_ec_ref = AFE_PORT_ID_PRIMARY_MI2S_TX; - state = true; + msm_route_ext_ec_ref = ucontrol->value.integer.value[0]; + + switch (msm_route_ext_ec_ref) { + case EXT_EC_REF_PRI_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX; break; - case EC_PORT_ID_SECONDARY_MI2S_TX: - msm_route_ext_ec_ref = AFE_PORT_ID_SECONDARY_MI2S_TX; - state = true; + case EXT_EC_REF_SEC_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX; break; - case EC_PORT_ID_TERTIARY_MI2S_TX: - msm_route_ext_ec_ref = AFE_PORT_ID_TERTIARY_MI2S_TX; - state = true; + case EXT_EC_REF_TERT_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX; break; - case EC_PORT_ID_QUATERNARY_MI2S_TX: - msm_route_ext_ec_ref = AFE_PORT_ID_QUATERNARY_MI2S_TX; - state = true; + case EXT_EC_REF_QUAT_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX; break; - case EC_PORT_ID_SLIMBUS_1_TX: - msm_route_ext_ec_ref = SLIMBUS_1_TX; - state = true; + case EXT_EC_REF_QUIN_MI2S_TX: + ext_ec_ref_port_id = AFE_PORT_ID_QUINARY_MI2S_TX; break; + case EXT_EC_REF_SLIM_1_TX: + ext_ec_ref_port_id = SLIMBUS_1_TX; + break; + case EXT_EC_REF_NONE: default: - msm_route_ext_ec_ref = AFE_PORT_INVALID; + ext_ec_ref_port_id = AFE_PORT_INVALID; + state = false; break; } - if (!voc_set_ext_ec_ref(msm_route_ext_ec_ref, state)) { + + pr_debug("%s: val = %d ext_ec_ref_port_id = 0x%0x state = %d\n", + __func__, msm_route_ext_ec_ref, ext_ec_ref_port_id, state); + + if (!voc_set_ext_ec_ref(ext_ec_ref_port_id, state)) { mutex_unlock(&routing_lock); snd_soc_dapm_mux_update_power(widget->dapm, kcontrol, mux, e, update); } else { @@ -2383,11 +2386,12 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol, } static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX", - "SEC_MI2S_TX", "TERT_MI2S_TX", - "QUAT_MI2S_TX", "SLIM_1_TX"}; + "SEC_MI2S_TX", "TERT_MI2S_TX", + "QUAT_MI2S_TX", "QUIN_MI2S_TX", + "SLIM_1_TX"}; static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = { - SOC_ENUM_SINGLE_EXT(6, ext_ec_ref_rx), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ext_ec_ref_rx), ext_ec_ref_rx), }; static const struct snd_kcontrol_new voc_ext_ec_mux = @@ -8665,7 +8669,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_3_RX", NULL, "SLIMBUS3_DL_HL"}, {"SLIMBUS4_DL_HL", "Switch", "SLIM4_DL_HL"}, {"SLIMBUS_4_RX", NULL, "SLIMBUS4_DL_HL"}, - {"SLIMBUS6_DL_HL", "Switch", "SLIM6_DL_HL"}, + {"SLIMBUS6_DL_HL", "Switch", "SLIM0_DL_HL"}, {"SLIMBUS_6_RX", NULL, "SLIMBUS6_DL_HL"}, {"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"}, {"SLIM1_UL_HL", NULL, "SLIMBUS_1_TX"}, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index e191aba79138..f1ec04dafeb5 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -306,6 +306,16 @@ enum msm_pcm_routing_event { MSM_PCM_RT_EVT_MAX, }; +enum { + EXT_EC_REF_NONE = 0, + EXT_EC_REF_PRI_MI2S_TX, + EXT_EC_REF_SEC_MI2S_TX, + EXT_EC_REF_TERT_MI2S_TX, + EXT_EC_REF_QUAT_MI2S_TX, + EXT_EC_REF_QUIN_MI2S_TX, + EXT_EC_REF_SLIM_1_TX, +}; + #define INVALID_SESSION -1 #define SESSION_TYPE_RX 0 #define SESSION_TYPE_TX 1 diff --git a/sound/usb/card.c b/sound/usb/card.c index 9ca09d2b6c71..339ce6bc8e75 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -675,7 +675,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) int err = -ENODEV; down_read(&chip->shutdown_rwsem); - if (chip->probing && chip->in_pm) + if (chip->probing || chip->in_pm) err = 0; else if (!chip->shutdown) err = usb_autopm_get_interface(chip->pm_intf); |