Loading sound/soc/codecs/msm8x16-wcd.c +53 −8 Original line number Diff line number Diff line Loading @@ -187,6 +187,8 @@ static void msm8x16_wcd_set_micb_v(struct snd_soc_codec *codec); static void msm8x16_wcd_set_boost_v(struct snd_soc_codec *codec); static void msm8x16_wcd_set_auto_zeroing(struct snd_soc_codec *codec, bool enable); static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec, bool micbias1, bool micbias2); struct msm8x16_wcd_spmi msm8x16_wcd_modules[MAX_MSM8X16_WCD_DEVICE]; Loading Loading @@ -243,6 +245,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .set_micbias_value = msm8x16_wcd_set_micb_v, .set_auto_zeroing = msm8x16_wcd_set_auto_zeroing, .get_hwdep_fw_cal = msm8x16_wcd_get_hwdep_fw_cal, .set_cap_mode = msm8x16_wcd_configure_cap, }; static const uint32_t wcd_imped_val[] = {4, 8, 12, 16, Loading Loading @@ -1391,9 +1394,6 @@ static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = { MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL, 0, -84, 40, digital_gain), SOC_SINGLE("MICBIAS CAPLESS Switch", MSM8X16_WCD_A_ANALOG_MICB_1_EN, 6, 1, 0), SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), Loading Loading @@ -2187,6 +2187,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, char *internal2_text = "Internal2"; char *internal3_text = "Internal3"; char *external2_text = "External2"; char *external_text = "External"; bool micbias2; dev_dbg(codec->dev, "%s %d\n", __func__, event); switch (w->reg) { Loading @@ -2201,6 +2203,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, return -EINVAL; } micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (strnstr(w->name, internal1_text, 30)) { Loading @@ -2211,6 +2214,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, } else if (strnstr(w->name, internal3_text, 30)) { snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2); } if (!strnstr(w->name, external_text, 30)) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x05, 0x04); Loading @@ -2229,6 +2233,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, msm8x16_notifier_call(codec, WCD_EVENT_PRE_MICBIAS_2_ON); } if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN) msm8x16_wcd_configure_cap(codec, true, micbias2); break; case SND_SOC_DAPM_POST_PMD: if (strnstr(w->name, internal1_text, 30)) { Loading @@ -2247,8 +2253,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, WCD_EVENT_PRE_MICBIAS_2_OFF); break; } snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x44, 0x00); if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN) msm8x16_wcd_configure_cap(codec, false, micbias2); break; } return 0; Loading Loading @@ -3457,8 +3463,10 @@ static const struct snd_soc_dapm_widget msm8x16_wcd_dapm_widgets[] = { SND_SOC_DAPM_VIRT_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), SND_SOC_DAPM_MICBIAS("MIC BIAS External", MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0), SND_SOC_DAPM_MICBIAS_E("MIC BIAS External", MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0, msm8x16_wcd_codec_enable_micbias, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MICBIAS_E("MIC BIAS External2", MSM8X16_WCD_A_ANALOG_MICB_2_EN, 7, 0, Loading Loading @@ -3683,6 +3691,7 @@ static int msm8x16_wcd_device_up(struct snd_soc_codec *codec) msm8x16_wcd_set_boost_v(codec); msm8x16_wcd_set_micb_v(codec); msm8x16_wcd_configure_cap(codec, false, false); wcd_mbhc_stop(&msm8x16_wcd_priv->mbhc); wcd_mbhc_start(&msm8x16_wcd_priv->mbhc, msm8x16_wcd_priv->mbhc.mbhc_cfg); Loading Loading @@ -3778,6 +3787,40 @@ static void msm8x16_wcd_set_boost_v(struct snd_soc_codec *codec) 0x1F, msm8x16_wcd_priv->boost_voltage); } static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec, bool micbias1, bool micbias2) { struct msm8916_asoc_mach_data *pdata = NULL; pdata = snd_soc_card_get_drvdata(codec->card); pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, micbias2); if (micbias1 && micbias2) { if ((pdata->micbias1_cap_mode == MICBIAS_EXT_BYP_CAP) || (pdata->micbias2_cap_mode == MICBIAS_EXT_BYP_CAP)) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_EXT_BYP_CAP << 6)); else snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); } else if (micbias2) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (pdata->micbias2_cap_mode << 6)); } else if (micbias1) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (pdata->micbias1_cap_mode << 6)); } else { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, 0x00); } } static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec) { struct msm8x16_wcd_priv *msm8x16_wcd_priv; Loading Loading @@ -3879,6 +3922,8 @@ static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec) /* Set initial MICBIAS voltage level */ msm8x16_wcd_set_micb_v(codec); /* Set initial cap mode */ msm8x16_wcd_configure_cap(codec, false, false); registered_codec = codec; modem_state_notifier = subsys_notif_register_notifier("modem", Loading sound/soc/codecs/msm8x16-wcd.h +2 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,8 @@ struct msm8916_asoc_mach_data { int us_euro_gpio; int mclk_freq; int lb_mode; u8 micbias1_cap_mode; u8 micbias2_cap_mode; atomic_t mclk_rsc_ref; atomic_t mclk_enabled; struct mutex cdc_mclk_mutex; Loading sound/soc/codecs/wcd-mbhc-v2.c +21 −48 Original line number Diff line number Diff line Loading @@ -85,36 +85,6 @@ enum wcd_mbhc_cs_mb_en_flag { WCD_MBHC_EN_NONE, }; static void wcd_configure_cap(struct wcd_mbhc *mbhc, bool micbias2) { u16 micbias1; struct snd_soc_codec *codec = mbhc->codec; micbias1 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN); pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, micbias2); if ((micbias1 & 0x80) && micbias2) { if ((mbhc->micbias1_cap_mode == MICBIAS_EXT_BYP_CAP) || (mbhc->micbias2_cap_mode == MICBIAS_EXT_BYP_CAP)) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_EXT_BYP_CAP << 6)); else snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); } else if (micbias2) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (mbhc->micbias2_cap_mode << 6)); } else if (micbias1 & 0x80) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (mbhc->micbias1_cap_mode << 6)); } else { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, 0x00); } } static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask) { Loading Loading @@ -272,10 +242,12 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); struct wcd_mbhc *mbhc = &msm8x16_wcd->mbhc; enum wcd_notify_event event = (enum wcd_notify_event)val; u16 micbias2; bool micbias2; bool micbias1; pr_debug("%s: event %d\n", __func__, event); micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); switch (event) { /* MICBIAS usage change */ case WCD_EVENT_PRE_MICBIAS_2_ON: Loading @@ -301,7 +273,8 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); mbhc->is_hs_recording = true; /* configure cap settings properly when micbias is enabled */ wcd_configure_cap(mbhc, true); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); break; /* MICBIAS usage change */ case WCD_EVENT_PRE_MICBIAS_2_OFF: Loading @@ -321,7 +294,8 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); /* configure cap settings properly when micbias is disabled */ wcd_configure_cap(mbhc, false); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); break; case WCD_EVENT_POST_HPHL_PA_OFF: if (mbhc->hph_status & SND_JACK_OC_HPHL) Loading Loading @@ -963,7 +937,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) bool wrk_complete = false; int pt_gnd_mic_swap_cnt = 0; bool is_pa_on; u16 micbias2; bool micbias2; bool micbias1; pr_debug("%s: enter\n", __func__); Loading Loading @@ -1133,8 +1108,10 @@ report: wcd_mbhc_find_plug_and_report(mbhc, plug_type); WCD_MBHC_RSC_UNLOCK(mbhc); exit: micbias2 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN); wcd_configure_cap(mbhc, (micbias2 & 0x80)); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, micbias2); wcd9xxx_spmi_unlock_sleep(); pr_debug("%s: leave\n", __func__); } Loading @@ -1147,14 +1124,17 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) enum wcd_mbhc_plug_type plug_type; int timeout_result; u16 result1, result2; bool micbias1; bool cross_conn; int try = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); wcd_configure_cap(mbhc, true); /* * Wait for 50msec for FSM to complete its task. * wakeup if btn pres intr occurs Loading Loading @@ -1234,8 +1214,8 @@ exit: static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) { bool detection_type; bool micbias1; struct snd_soc_codec *codec = mbhc->codec; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); Loading @@ -1257,6 +1237,7 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->current_plug, detection_type); wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); if ((mbhc->current_plug == MBHC_PLUG_TYPE_NONE) && detection_type) { /* Make sure MASTER_BIAS_CTL is enabled */ Loading Loading @@ -1300,7 +1281,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x04, 0x00); wcd_configure_cap(mbhc, false); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); mbhc->btn_press_intr = false; if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE); Loading Loading @@ -1987,8 +1969,6 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, struct snd_soc_card *card = codec->card; const char *hph_switch = "qcom,msm-mbhc-hphl-swh"; const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; pr_debug("%s: enter\n", __func__); Loading @@ -2005,13 +1985,6 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, "%s: missing %s in dt node\n", __func__, gnd_switch); goto err; } mbhc->micbias1_cap_mode = (of_property_read_bool(card->dev->of_node, ext1_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); mbhc->micbias2_cap_mode = (of_property_read_bool(card->dev->of_node, ext2_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); mbhc->in_swch_irq_handler = false; mbhc->current_plug = MBHC_PLUG_TYPE_NONE; Loading sound/soc/codecs/wcd-mbhc-v2.h +1 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ struct wcd_mbhc_cb { void (*set_auto_zeroing) (struct snd_soc_codec *, bool); struct firmware_cal * (*get_hwdep_fw_cal)(struct snd_soc_codec *, enum wcd_cal_type); void (*set_cap_mode)(struct snd_soc_codec *, bool, bool); }; struct wcd_mbhc { Loading sound/soc/msm/msm8x16.c +18 −0 Original line number Diff line number Diff line Loading @@ -1932,6 +1932,23 @@ static int msm8x16_setup_hs_jack(struct platform_device *pdev, return 0; } static void msm8x16_dt_parse_cap_info(struct platform_device *pdev, struct msm8916_asoc_mach_data *pdata) { const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; pdata->micbias1_cap_mode = (of_property_read_bool(pdev->dev.of_node, ext1_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); pdata->micbias2_cap_mode = (of_property_read_bool(pdev->dev.of_node, ext2_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); return; } int get_cdc_gpio_lines(struct pinctrl *pinctrl, int ext_pa) { pr_debug("%s\n", __func__); Loading Loading @@ -2279,6 +2296,7 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) pdata->lb_mode = false; msm8x16_setup_hs_jack(pdev, pdata); msm8x16_dt_parse_cap_info(pdev, pdata); card->dev = &pdev->dev; platform_set_drvdata(pdev, card); Loading Loading
sound/soc/codecs/msm8x16-wcd.c +53 −8 Original line number Diff line number Diff line Loading @@ -187,6 +187,8 @@ static void msm8x16_wcd_set_micb_v(struct snd_soc_codec *codec); static void msm8x16_wcd_set_boost_v(struct snd_soc_codec *codec); static void msm8x16_wcd_set_auto_zeroing(struct snd_soc_codec *codec, bool enable); static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec, bool micbias1, bool micbias2); struct msm8x16_wcd_spmi msm8x16_wcd_modules[MAX_MSM8X16_WCD_DEVICE]; Loading Loading @@ -243,6 +245,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .set_micbias_value = msm8x16_wcd_set_micb_v, .set_auto_zeroing = msm8x16_wcd_set_auto_zeroing, .get_hwdep_fw_cal = msm8x16_wcd_get_hwdep_fw_cal, .set_cap_mode = msm8x16_wcd_configure_cap, }; static const uint32_t wcd_imped_val[] = {4, 8, 12, 16, Loading Loading @@ -1391,9 +1394,6 @@ static const struct snd_kcontrol_new msm8x16_wcd_snd_controls[] = { MSM8X16_WCD_A_CDC_IIR2_GAIN_B1_CTL, 0, -84, 40, digital_gain), SOC_SINGLE("MICBIAS CAPLESS Switch", MSM8X16_WCD_A_ANALOG_MICB_1_EN, 6, 1, 0), SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), Loading Loading @@ -2187,6 +2187,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, char *internal2_text = "Internal2"; char *internal3_text = "Internal3"; char *external2_text = "External2"; char *external_text = "External"; bool micbias2; dev_dbg(codec->dev, "%s %d\n", __func__, event); switch (w->reg) { Loading @@ -2201,6 +2203,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, return -EINVAL; } micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80); switch (event) { case SND_SOC_DAPM_PRE_PMU: if (strnstr(w->name, internal1_text, 30)) { Loading @@ -2211,6 +2214,7 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, } else if (strnstr(w->name, internal3_text, 30)) { snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2); } if (!strnstr(w->name, external_text, 30)) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x05, 0x04); Loading @@ -2229,6 +2233,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, msm8x16_notifier_call(codec, WCD_EVENT_PRE_MICBIAS_2_ON); } if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN) msm8x16_wcd_configure_cap(codec, true, micbias2); break; case SND_SOC_DAPM_POST_PMD: if (strnstr(w->name, internal1_text, 30)) { Loading @@ -2247,8 +2253,8 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w, WCD_EVENT_PRE_MICBIAS_2_OFF); break; } snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x44, 0x00); if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN) msm8x16_wcd_configure_cap(codec, false, micbias2); break; } return 0; Loading Loading @@ -3457,8 +3463,10 @@ static const struct snd_soc_dapm_widget msm8x16_wcd_dapm_widgets[] = { SND_SOC_DAPM_VIRT_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux), SND_SOC_DAPM_MICBIAS("MIC BIAS External", MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0), SND_SOC_DAPM_MICBIAS_E("MIC BIAS External", MSM8X16_WCD_A_ANALOG_MICB_1_EN, 7, 0, msm8x16_wcd_codec_enable_micbias, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MICBIAS_E("MIC BIAS External2", MSM8X16_WCD_A_ANALOG_MICB_2_EN, 7, 0, Loading Loading @@ -3683,6 +3691,7 @@ static int msm8x16_wcd_device_up(struct snd_soc_codec *codec) msm8x16_wcd_set_boost_v(codec); msm8x16_wcd_set_micb_v(codec); msm8x16_wcd_configure_cap(codec, false, false); wcd_mbhc_stop(&msm8x16_wcd_priv->mbhc); wcd_mbhc_start(&msm8x16_wcd_priv->mbhc, msm8x16_wcd_priv->mbhc.mbhc_cfg); Loading Loading @@ -3778,6 +3787,40 @@ static void msm8x16_wcd_set_boost_v(struct snd_soc_codec *codec) 0x1F, msm8x16_wcd_priv->boost_voltage); } static void msm8x16_wcd_configure_cap(struct snd_soc_codec *codec, bool micbias1, bool micbias2) { struct msm8916_asoc_mach_data *pdata = NULL; pdata = snd_soc_card_get_drvdata(codec->card); pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, micbias2); if (micbias1 && micbias2) { if ((pdata->micbias1_cap_mode == MICBIAS_EXT_BYP_CAP) || (pdata->micbias2_cap_mode == MICBIAS_EXT_BYP_CAP)) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_EXT_BYP_CAP << 6)); else snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); } else if (micbias2) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (pdata->micbias2_cap_mode << 6)); } else if (micbias1) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (pdata->micbias1_cap_mode << 6)); } else { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, 0x00); } } static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec) { struct msm8x16_wcd_priv *msm8x16_wcd_priv; Loading Loading @@ -3879,6 +3922,8 @@ static int msm8x16_wcd_codec_probe(struct snd_soc_codec *codec) /* Set initial MICBIAS voltage level */ msm8x16_wcd_set_micb_v(codec); /* Set initial cap mode */ msm8x16_wcd_configure_cap(codec, false, false); registered_codec = codec; modem_state_notifier = subsys_notif_register_notifier("modem", Loading
sound/soc/codecs/msm8x16-wcd.h +2 −0 Original line number Diff line number Diff line Loading @@ -162,6 +162,8 @@ struct msm8916_asoc_mach_data { int us_euro_gpio; int mclk_freq; int lb_mode; u8 micbias1_cap_mode; u8 micbias2_cap_mode; atomic_t mclk_rsc_ref; atomic_t mclk_enabled; struct mutex cdc_mclk_mutex; Loading
sound/soc/codecs/wcd-mbhc-v2.c +21 −48 Original line number Diff line number Diff line Loading @@ -85,36 +85,6 @@ enum wcd_mbhc_cs_mb_en_flag { WCD_MBHC_EN_NONE, }; static void wcd_configure_cap(struct wcd_mbhc *mbhc, bool micbias2) { u16 micbias1; struct snd_soc_codec *codec = mbhc->codec; micbias1 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN); pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1, micbias2); if ((micbias1 & 0x80) && micbias2) { if ((mbhc->micbias1_cap_mode == MICBIAS_EXT_BYP_CAP) || (mbhc->micbias2_cap_mode == MICBIAS_EXT_BYP_CAP)) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_EXT_BYP_CAP << 6)); else snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (MICBIAS_NO_EXT_BYP_CAP << 6)); } else if (micbias2) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (mbhc->micbias2_cap_mode << 6)); } else if (micbias1 & 0x80) { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, (mbhc->micbias1_cap_mode << 6)); } else { snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x40, 0x00); } } static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask) { Loading Loading @@ -272,10 +242,12 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, struct msm8x16_wcd_priv *msm8x16_wcd = snd_soc_codec_get_drvdata(codec); struct wcd_mbhc *mbhc = &msm8x16_wcd->mbhc; enum wcd_notify_event event = (enum wcd_notify_event)val; u16 micbias2; bool micbias2; bool micbias1; pr_debug("%s: event %d\n", __func__, event); micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); switch (event) { /* MICBIAS usage change */ case WCD_EVENT_PRE_MICBIAS_2_ON: Loading @@ -301,7 +273,8 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); mbhc->is_hs_recording = true; /* configure cap settings properly when micbias is enabled */ wcd_configure_cap(mbhc, true); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); break; /* MICBIAS usage change */ case WCD_EVENT_PRE_MICBIAS_2_OFF: Loading @@ -321,7 +294,8 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); /* configure cap settings properly when micbias is disabled */ wcd_configure_cap(mbhc, false); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); break; case WCD_EVENT_POST_HPHL_PA_OFF: if (mbhc->hph_status & SND_JACK_OC_HPHL) Loading Loading @@ -963,7 +937,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) bool wrk_complete = false; int pt_gnd_mic_swap_cnt = 0; bool is_pa_on; u16 micbias2; bool micbias2; bool micbias1; pr_debug("%s: enter\n", __func__); Loading Loading @@ -1133,8 +1108,10 @@ report: wcd_mbhc_find_plug_and_report(mbhc, plug_type); WCD_MBHC_RSC_UNLOCK(mbhc); exit: micbias2 = snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN); wcd_configure_cap(mbhc, (micbias2 & 0x80)); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, micbias2); wcd9xxx_spmi_unlock_sleep(); pr_debug("%s: leave\n", __func__); } Loading @@ -1147,14 +1124,17 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) enum wcd_mbhc_plug_type plug_type; int timeout_result; u16 result1, result2; bool micbias1; bool cross_conn; int try = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, true); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); wcd_configure_cap(mbhc, true); /* * Wait for 50msec for FSM to complete its task. * wakeup if btn pres intr occurs Loading Loading @@ -1234,8 +1214,8 @@ exit: static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) { bool detection_type; bool micbias1; struct snd_soc_codec *codec = mbhc->codec; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); Loading @@ -1257,6 +1237,7 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) mbhc->current_plug, detection_type); wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); micbias1 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN) & 0x80); if ((mbhc->current_plug == MBHC_PLUG_TYPE_NONE) && detection_type) { /* Make sure MASTER_BIAS_CTL is enabled */ Loading Loading @@ -1300,7 +1281,8 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x04, 0x00); wcd_configure_cap(mbhc, false); if (mbhc->mbhc_cb && mbhc->mbhc_cb->set_cap_mode) mbhc->mbhc_cb->set_cap_mode(codec, micbias1, false); mbhc->btn_press_intr = false; if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE) { wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE); Loading Loading @@ -1987,8 +1969,6 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, struct snd_soc_card *card = codec->card; const char *hph_switch = "qcom,msm-mbhc-hphl-swh"; const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; pr_debug("%s: enter\n", __func__); Loading @@ -2005,13 +1985,6 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, "%s: missing %s in dt node\n", __func__, gnd_switch); goto err; } mbhc->micbias1_cap_mode = (of_property_read_bool(card->dev->of_node, ext1_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); mbhc->micbias2_cap_mode = (of_property_read_bool(card->dev->of_node, ext2_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); mbhc->in_swch_irq_handler = false; mbhc->current_plug = MBHC_PLUG_TYPE_NONE; Loading
sound/soc/codecs/wcd-mbhc-v2.h +1 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ struct wcd_mbhc_cb { void (*set_auto_zeroing) (struct snd_soc_codec *, bool); struct firmware_cal * (*get_hwdep_fw_cal)(struct snd_soc_codec *, enum wcd_cal_type); void (*set_cap_mode)(struct snd_soc_codec *, bool, bool); }; struct wcd_mbhc { Loading
sound/soc/msm/msm8x16.c +18 −0 Original line number Diff line number Diff line Loading @@ -1932,6 +1932,23 @@ static int msm8x16_setup_hs_jack(struct platform_device *pdev, return 0; } static void msm8x16_dt_parse_cap_info(struct platform_device *pdev, struct msm8916_asoc_mach_data *pdata) { const char *ext1_cap = "qcom,msm-micbias1-ext-cap"; const char *ext2_cap = "qcom,msm-micbias2-ext-cap"; pdata->micbias1_cap_mode = (of_property_read_bool(pdev->dev.of_node, ext1_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); pdata->micbias2_cap_mode = (of_property_read_bool(pdev->dev.of_node, ext2_cap) ? MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP); return; } int get_cdc_gpio_lines(struct pinctrl *pinctrl, int ext_pa) { pr_debug("%s\n", __func__); Loading Loading @@ -2279,6 +2296,7 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev) pdata->lb_mode = false; msm8x16_setup_hs_jack(pdev, pdata); msm8x16_dt_parse_cap_info(pdev, pdata); card->dev = &pdev->dev; platform_set_drvdata(pdev, card); Loading