ASoC: wcd9xxx: Support earpiece ANC
Added virtual widgets for enabling and disabling earpiece ANC.
Change-Id: Ia235928c34022de89ec0e66dbe533143f4d56684
Signed-off-by: Damir Didjusto <damird@codeaurora.org>
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 5563f63..3405045 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -490,16 +490,24 @@
snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
snd_soc_dapm_enable_pin(dapm, "ANC HEADPHONE");
+ snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC EAR");
snd_soc_dapm_disable_pin(dapm, "HPHR");
snd_soc_dapm_disable_pin(dapm, "HPHL");
snd_soc_dapm_disable_pin(dapm, "HEADPHONE");
+ snd_soc_dapm_disable_pin(dapm, "EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "EAR");
} else {
snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
snd_soc_dapm_disable_pin(dapm, "ANC HEADPHONE");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR");
snd_soc_dapm_enable_pin(dapm, "HPHR");
snd_soc_dapm_enable_pin(dapm, "HPHL");
snd_soc_dapm_enable_pin(dapm, "HEADPHONE");
+ snd_soc_dapm_enable_pin(dapm, "EAR PA");
+ snd_soc_dapm_enable_pin(dapm, "EAR");
}
snd_soc_dapm_sync(dapm);
mutex_unlock(&dapm->codec->mutex);
@@ -1053,7 +1061,7 @@
SOC_SINGLE("MICBIAS2 CAPLESS Switch", TABLA_A_MICB_2_CTL, 4, 1, 1),
SOC_SINGLE("MICBIAS3 CAPLESS Switch", TABLA_A_MICB_3_CTL, 4, 1, 1),
- SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 0, 100, tabla_get_anc_slot,
+ SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tabla_get_anc_slot,
tabla_put_anc_slot),
SOC_ENUM_EXT("ANC Function", tabla_anc_func_enum, tabla_get_anc_func,
tabla_put_anc_func),
@@ -2893,7 +2901,6 @@
u32 *anc_ptr;
u16 reg;
u8 mask, val, old_val;
- u8 mbhc_micb_ctl_val;
pr_debug("%s: DAPM Event %d ANC func is %d\n",
__func__, event, tabla->anc_func);
@@ -2903,14 +2910,6 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- mbhc_micb_ctl_val = snd_soc_read(codec,
- tabla->mbhc_bias_regs.ctl_reg);
-
- if (!(mbhc_micb_ctl_val & 0x80)) {
- TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
- tabla_codec_switch_micbias(codec, 1);
- TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
- }
filename = "wcd9310/wcd9310_anc.bin";
@@ -2977,49 +2976,9 @@
snd_soc_write(codec, reg, (old_val & ~mask) |
(val & mask));
}
- usleep_range(10000, 10000);
- snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x30);
- msleep(30);
release_firmware(fw);
- TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
- /* if MBHC polling is active, set TX7_MBHC_EN bit 7 */
- if (tabla->mbhc_polling_active)
- snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80,
- 0x80);
- TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
- break;
- case SND_SOC_DAPM_POST_PMD:
- /* schedule work is required because at the time HPH PA DAPM
- * event callback is called by DAPM framework, CODEC dapm mutex
- * would have been locked while snd_soc_jack_report also
- * attempts to acquire same lock.
- */
- if (w->shift == 5) {
- clear_bit(TABLA_HPHL_PA_OFF_ACK,
- &tabla->hph_pa_dac_state);
- clear_bit(TABLA_HPHL_DAC_OFF_ACK,
- &tabla->hph_pa_dac_state);
- if (tabla->hph_status & SND_JACK_OC_HPHL)
- schedule_work(&tabla->hphlocp_work);
- } else if (w->shift == 4) {
- clear_bit(TABLA_HPHR_PA_OFF_ACK,
- &tabla->hph_pa_dac_state);
- clear_bit(TABLA_HPHR_DAC_OFF_ACK,
- &tabla->hph_pa_dac_state);
- if (tabla->hph_status & SND_JACK_OC_HPHR)
- schedule_work(&tabla->hphrocp_work);
- }
-
- TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
- tabla_codec_switch_micbias(codec, 0);
- TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
-
break;
case SND_SOC_DAPM_PRE_PMD:
- snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x00);
- msleep(40);
- /* unset TX7_MBHC_EN bit 7 */
- snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80, 0x00);
snd_soc_update_bits(codec, TABLA_A_CDC_ANC1_CTL, 0x01, 0x00);
snd_soc_update_bits(codec, TABLA_A_CDC_ANC2_CTL, 0x01, 0x00);
msleep(20);
@@ -3085,6 +3044,42 @@
return 0;
}
+static int tabla_codec_enable_anc_hph(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret |= tabla_hph_pa_event(w, kcontrol, event);
+ ret |= tabla_codec_enable_anc(w, kcontrol, event);
+ usleep_range(10000, 10000);
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x30);
+ msleep(30);
+ TABLA_ACQUIRE_LOCK(tabla->codec_resource_lock);
+ /* if MBHC polling is active, set TX7_MBHC_EN bit 7 */
+ if (tabla->mbhc_polling_active)
+ snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80,
+ 0x80);
+ TABLA_RELEASE_LOCK(tabla->codec_resource_lock);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret |= tabla_hph_pa_event(w, kcontrol, event);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x00);
+ msleep(40);
+ /* unset TX7_MBHC_EN bit 7 */
+ snd_soc_update_bits(codec, TABLA_A_TX_7_MBHC_EN, 0x80, 0x00);
+ ret |= tabla_codec_enable_anc(w, kcontrol, event);
+ break;
+ }
+ return ret;
+}
+
static void tabla_get_mbhc_micbias_regs(struct snd_soc_codec *codec,
struct mbhc_micbias_regs *micbias_regs)
{
@@ -3188,6 +3183,26 @@
return 0;
}
+static int tabla_codec_enable_anc_ear(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ int ret = 0;
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret |= tabla_codec_enable_anc(w, kcontrol, event);
+ msleep(50);
+ ret |= tabla_ear_pa_event(w, kcontrol, event);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ ret |= tabla_ear_pa_event(w, kcontrol, event);
+ ret |= tabla_codec_enable_anc(w, kcontrol, event);
+ break;
+ }
+ return ret;
+}
+
static const struct snd_soc_dapm_widget tabla_1_x_dapm_widgets[] = {
SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_1_A_MICB_4_CTL, 7,
0, tabla_codec_enable_micbias,
@@ -3311,6 +3326,9 @@
{"EAR_PA_MIXER", NULL, "DAC1"},
{"DAC1", NULL, "CP"},
+ {"ANC EAR", NULL, "ANC EAR PA"},
+ {"ANC EAR PA", NULL, "EAR_PA_MIXER"},
+
{"ANC1 FB MUX", "EAR_HPH_L", "RX1 MIX2"},
{"ANC1 FB MUX", "EAR_LINE_1", "RX2 MIX2"},
@@ -5093,11 +5111,15 @@
SND_SOC_DAPM_OUTPUT("ANC HEADPHONE"),
SND_SOC_DAPM_PGA_E("ANC HPHL", SND_SOC_NOPM, 0, 0, NULL, 0,
- tabla_codec_enable_anc,
+ tabla_codec_enable_anc_hph,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA_E("ANC HPHR", SND_SOC_NOPM, 0, 0, NULL, 0,
- tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU),
+ tabla_codec_enable_anc_hph, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_OUTPUT("ANC EAR"),
+ SND_SOC_DAPM_PGA_E("ANC EAR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ tabla_codec_enable_anc_ear,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),