Loading sound/soc/codecs/wcd-mbhc-v2.c +35 −0 Original line number Diff line number Diff line Loading @@ -329,6 +329,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* Disable micbias, pullup & enable cs */ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); mutex_unlock(&mbhc->hphl_pa_lock); clear_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); break; case WCD_EVENT_PRE_HPHR_PA_OFF: mutex_lock(&mbhc->hphr_pa_lock); Loading @@ -346,6 +347,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* Disable micbias, pullup & enable cs */ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); mutex_unlock(&mbhc->hphr_pa_lock); clear_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); break; case WCD_EVENT_PRE_HPHL_PA_ON: set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); Loading Loading @@ -439,6 +441,25 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) __func__); usleep_range(wg_time * 1000, wg_time * 1000 + 50); } if (test_and_clear_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state)) { usleep_range(20000, 20100); pr_debug("%s: HPHL ANC clear flag and enable ANC_EN\n", __func__); if (mbhc->mbhc_cb->update_anc_state) mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 0); } if (test_and_clear_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state)) { usleep_range(20000, 20100); pr_debug("%s: HPHR ANC clear flag and enable ANC_EN\n", __func__); if (mbhc->mbhc_cb->update_anc_state) mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 1); } } static bool wcd_mbhc_is_hph_pa_on(struct wcd_mbhc *mbhc) Loading Loading @@ -471,6 +492,20 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc) } WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 0); usleep_range(wg_time * 1000, wg_time * 1000 + 50); if (mbhc->mbhc_cb->is_anc_on && mbhc->mbhc_cb->is_anc_on(mbhc)) { usleep_range(20000, 20100); pr_debug("%s ANC is on, setting ANC_OFF_ACK\n", __func__); set_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); set_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); if (mbhc->mbhc_cb->update_anc_state) { mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 0); mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 1); } else { pr_debug("%s ANC is off\n", __func__); } } } int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, Loading sound/soc/codecs/wcd-mbhc-v2.h +9 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,11 @@ enum pa_dac_ack_flags { WCD_MBHC_HPHR_PA_OFF_ACK, }; enum anc_ack_flags { WCD_MBHC_ANC0_OFF_ACK = 0, WCD_MBHC_ANC1_OFF_ACK, }; enum wcd_mbhc_btn_det_mem { WCD_MBHC_BTN_DET_V_BTN_LOW, WCD_MBHC_BTN_DET_V_BTN_HIGH Loading Loading @@ -482,6 +487,9 @@ struct wcd_mbhc_cb { void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool); void (*mbhc_moisture_config)(struct wcd_mbhc *); bool (*hph_register_recovery)(struct wcd_mbhc *); void (*update_anc_state)(struct snd_soc_codec *codec, bool enable, int anc_num); bool (*is_anc_on)(struct wcd_mbhc *mbhc); }; struct wcd_mbhc_fn { Loading Loading @@ -532,6 +540,7 @@ struct wcd_mbhc { /* track PA/DAC state to sync with userspace */ unsigned long hph_pa_dac_state; unsigned long hph_anc_state; unsigned long event_state; unsigned long jiffies_atreport; Loading sound/soc/codecs/wcd9335.c +28 −0 Original line number Diff line number Diff line Loading @@ -2014,6 +2014,32 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref); } static void tasha_update_anc_state(struct snd_soc_codec *codec, bool enable, int anc_num) { if (enable) snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x10); else snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x00); } static bool tasha_is_anc_on(struct wcd_mbhc *mbhc) { bool anc_on = false; u16 ancl, ancr; ancl = (snd_soc_read(mbhc->codec, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = (snd_soc_read(mbhc->codec, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); return anc_on; } static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tasha_mbhc_request_irq, .irq_control = tasha_mbhc_irq_control, Loading @@ -2036,6 +2062,8 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl, .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = tasha_mbhc_moisture_config, .update_anc_state = tasha_update_anc_state, .is_anc_on = tasha_is_anc_on, }; static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol, Loading sound/soc/codecs/wcd934x/wcd934x-mbhc.c +28 −0 Original line number Diff line number Diff line Loading @@ -829,6 +829,32 @@ static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc) return wcd934x_mbhc->is_hph_recover; } static void tavil_update_anc_state(struct snd_soc_codec *codec, bool enable, int anc_num) { if (enable) snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x10); else snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x00); } static bool tavil_is_anc_on(struct wcd_mbhc *mbhc) { bool anc_on = false; u16 ancl, ancr; ancl = (snd_soc_read(mbhc->codec, WCD934X_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = (snd_soc_read(mbhc->codec, WCD934X_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); return anc_on; } static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tavil_mbhc_request_irq, .irq_control = tavil_mbhc_irq_control, Loading @@ -852,6 +878,8 @@ static const struct wcd_mbhc_cb mbhc_cb = { .hph_pull_down_ctrl = tavil_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = tavil_mbhc_moisture_config, .hph_register_recovery = tavil_hph_register_recovery, .update_anc_state = tavil_update_anc_state, .is_anc_on = tavil_is_anc_on, }; static struct regulator *tavil_codec_find_ondemand_regulator( Loading Loading
sound/soc/codecs/wcd-mbhc-v2.c +35 −0 Original line number Diff line number Diff line Loading @@ -329,6 +329,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* Disable micbias, pullup & enable cs */ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); mutex_unlock(&mbhc->hphl_pa_lock); clear_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); break; case WCD_EVENT_PRE_HPHR_PA_OFF: mutex_lock(&mbhc->hphr_pa_lock); Loading @@ -346,6 +347,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val, /* Disable micbias, pullup & enable cs */ wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS); mutex_unlock(&mbhc->hphr_pa_lock); clear_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); break; case WCD_EVENT_PRE_HPHL_PA_ON: set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state); Loading Loading @@ -439,6 +441,25 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc) __func__); usleep_range(wg_time * 1000, wg_time * 1000 + 50); } if (test_and_clear_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state)) { usleep_range(20000, 20100); pr_debug("%s: HPHL ANC clear flag and enable ANC_EN\n", __func__); if (mbhc->mbhc_cb->update_anc_state) mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 0); } if (test_and_clear_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state)) { usleep_range(20000, 20100); pr_debug("%s: HPHR ANC clear flag and enable ANC_EN\n", __func__); if (mbhc->mbhc_cb->update_anc_state) mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 1); } } static bool wcd_mbhc_is_hph_pa_on(struct wcd_mbhc *mbhc) Loading Loading @@ -471,6 +492,20 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc) } WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 0); usleep_range(wg_time * 1000, wg_time * 1000 + 50); if (mbhc->mbhc_cb->is_anc_on && mbhc->mbhc_cb->is_anc_on(mbhc)) { usleep_range(20000, 20100); pr_debug("%s ANC is on, setting ANC_OFF_ACK\n", __func__); set_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state); set_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state); if (mbhc->mbhc_cb->update_anc_state) { mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 0); mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 1); } else { pr_debug("%s ANC is off\n", __func__); } } } int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, Loading
sound/soc/codecs/wcd-mbhc-v2.h +9 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,11 @@ enum pa_dac_ack_flags { WCD_MBHC_HPHR_PA_OFF_ACK, }; enum anc_ack_flags { WCD_MBHC_ANC0_OFF_ACK = 0, WCD_MBHC_ANC1_OFF_ACK, }; enum wcd_mbhc_btn_det_mem { WCD_MBHC_BTN_DET_V_BTN_LOW, WCD_MBHC_BTN_DET_V_BTN_HIGH Loading Loading @@ -482,6 +487,9 @@ struct wcd_mbhc_cb { void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool); void (*mbhc_moisture_config)(struct wcd_mbhc *); bool (*hph_register_recovery)(struct wcd_mbhc *); void (*update_anc_state)(struct snd_soc_codec *codec, bool enable, int anc_num); bool (*is_anc_on)(struct wcd_mbhc *mbhc); }; struct wcd_mbhc_fn { Loading Loading @@ -532,6 +540,7 @@ struct wcd_mbhc { /* track PA/DAC state to sync with userspace */ unsigned long hph_pa_dac_state; unsigned long hph_anc_state; unsigned long event_state; unsigned long jiffies_atreport; Loading
sound/soc/codecs/wcd9335.c +28 −0 Original line number Diff line number Diff line Loading @@ -2014,6 +2014,32 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref); } static void tasha_update_anc_state(struct snd_soc_codec *codec, bool enable, int anc_num) { if (enable) snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x10); else snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x00); } static bool tasha_is_anc_on(struct wcd_mbhc *mbhc) { bool anc_on = false; u16 ancl, ancr; ancl = (snd_soc_read(mbhc->codec, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = (snd_soc_read(mbhc->codec, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); return anc_on; } static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tasha_mbhc_request_irq, .irq_control = tasha_mbhc_irq_control, Loading @@ -2036,6 +2062,8 @@ static const struct wcd_mbhc_cb mbhc_cb = { .mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl, .hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = tasha_mbhc_moisture_config, .update_anc_state = tasha_update_anc_state, .is_anc_on = tasha_is_anc_on, }; static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol, Loading
sound/soc/codecs/wcd934x/wcd934x-mbhc.c +28 −0 Original line number Diff line number Diff line Loading @@ -829,6 +829,32 @@ static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc) return wcd934x_mbhc->is_hph_recover; } static void tavil_update_anc_state(struct snd_soc_codec *codec, bool enable, int anc_num) { if (enable) snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x10); else snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 + (20 * anc_num), 0x10, 0x00); } static bool tavil_is_anc_on(struct wcd_mbhc *mbhc) { bool anc_on = false; u16 ancl, ancr; ancl = (snd_soc_read(mbhc->codec, WCD934X_CDC_RX1_RX_PATH_CFG0)) & 0x10; ancr = (snd_soc_read(mbhc->codec, WCD934X_CDC_RX2_RX_PATH_CFG0)) & 0x10; anc_on = !!(ancl | ancr); return anc_on; } static const struct wcd_mbhc_cb mbhc_cb = { .request_irq = tavil_mbhc_request_irq, .irq_control = tavil_mbhc_irq_control, Loading @@ -852,6 +878,8 @@ static const struct wcd_mbhc_cb mbhc_cb = { .hph_pull_down_ctrl = tavil_mbhc_hph_pull_down_ctrl, .mbhc_moisture_config = tavil_mbhc_moisture_config, .hph_register_recovery = tavil_hph_register_recovery, .update_anc_state = tavil_update_anc_state, .is_anc_on = tavil_is_anc_on, }; static struct regulator *tavil_codec_find_ondemand_regulator( Loading