aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorSteve Pfetsch <spfetsch@google.com>2016-05-03 12:49:49 -0700
committerSteve Pfetsch <spfetsch@google.com>2016-05-03 12:49:49 -0700
commit42408dde031eb14e0ebfa2a27993f01422f7de53 (patch)
tree99fa5fe0fee21d0edfbe44c9d31686e46299fb38 /sound
parent703c92069d9571adfc77eb3646654d3333d2c434 (diff)
parent452dd7ba0b1179321d1bea5b5a800d956378c05b (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.c90
-rw-r--r--sound/soc/codecs/msm8x16-wcd.c48
-rw-r--r--sound/soc/codecs/wcd9335.c119
-rw-r--r--sound/soc/codecs/wsa881x-analog.c24
-rw-r--r--sound/soc/codecs/wsa881x.c8
-rw-r--r--sound/soc/msm/msm8952-dai-links.c2
-rw-r--r--sound/soc/msm/msm8996.c9
-rw-r--r--sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c24
-rwxr-xr-xsound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c64
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h10
-rw-r--r--sound/usb/card.c2
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);