#define CDC_A_MICB_1_VAL (0xf141)
#define MICB_MIN_VAL 1600
#define MICB_STEP_SIZE 50
----#define MICB_VOLTAGE_REGVAL(v) ((v - MICB_MIN_VAL)/MICB_STEP_SIZE)
++++#define MICB_VOLTAGE_REGVAL(v) (((v - MICB_MIN_VAL)/MICB_STEP_SIZE) << 3)
#define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3)
#define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3)
#define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3)
u16 codec_version;
bool mbhc_btn_enabled;
/* special event to detect accessory type */
--- - bool mbhc_btn0_pressed;
+++ + int mbhc_btn0_released;
bool detect_accessory_type;
struct clk *mclk;
struct snd_soc_codec *codec;
| MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
if (wcd->micbias_mv) {
---- snd_soc_write(codec, CDC_A_MICB_1_VAL,
---- MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
++++ snd_soc_update_bits(codec, CDC_A_MICB_1_VAL,
++++ MICB_1_VAL_MICB_OUT_VAL_MASK,
++++ MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
/*
* Special headset needs MICBIAS as 2.7V so wait for
* 50 msec for the MICBIAS to reach 2.7 volts.
wcd->micbias1_cap_mode);
}
--- -static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
--- -{
--- - struct snd_soc_codec *codec = wcd->codec;
--- - u32 plug_type = 0;
--- - u32 int_en_mask;
--- -
--- - snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
--- - CDC_A_MBHC_DET_CTL_L_DET_EN |
--- - CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
--- - CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
--- - CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN);
--- -
--- - if (wcd->hphl_jack_type_normally_open)
--- - plug_type |= CDC_A_HPHL_PLUG_TYPE_NO;
--- -
--- - if (wcd->gnd_jack_type_normally_open)
--- - plug_type |= CDC_A_GND_PLUG_TYPE_NO;
--- -
--- - snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
--- - CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
--- - CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
--- - plug_type |
--- - CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
--- -
--- -
--- - snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
--- - CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
--- - CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
--- -
--- - /* enable MBHC clock */
--- - snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
--- - DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
--- - DIG_CLK_CTL_D_MBHC_CLK_EN);
--- -
--- - int_en_mask = MBHC_SWITCH_INT;
--- - if (wcd->mbhc_btn_enabled)
--- - int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
--- -
--- - snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
--- - snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
--- - wcd->mbhc_btn0_pressed = false;
--- - wcd->detect_accessory_type = true;
--- -}
--- -
static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
bool micbias2_enabled)
{
return 0;
}
+++ +static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
+++ +{
+++ + struct snd_soc_codec *codec = wcd->codec;
+++ + bool micbias_enabled = false;
+++ + u32 plug_type = 0;
+++ + u32 int_en_mask;
+++ +
+++ + snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
+++ + CDC_A_MBHC_DET_CTL_L_DET_EN |
+++ + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
+++ + CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
+++ + CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN);
+++ +
+++ + if (wcd->hphl_jack_type_normally_open)
+++ + plug_type |= CDC_A_HPHL_PLUG_TYPE_NO;
+++ +
+++ + if (wcd->gnd_jack_type_normally_open)
+++ + plug_type |= CDC_A_GND_PLUG_TYPE_NO;
+++ +
+++ + snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
+++ + CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
+++ + CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
+++ + plug_type |
+++ + CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
+++ +
+++ +
+++ + snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
+++ + CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
+++ + CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
+++ +
+++ + /* enable MBHC clock */
+++ + snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
+++ + DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
+++ + DIG_CLK_CTL_D_MBHC_CLK_EN);
+++ +
+++ + if (snd_soc_read(codec, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
+++ + micbias_enabled = true;
+++ +
+++ + pm8916_mbhc_configure_bias(wcd, micbias_enabled);
+++ +
+++ + int_en_mask = MBHC_SWITCH_INT;
+++ + if (wcd->mbhc_btn_enabled)
+++ + int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
+++ +
+++ + snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
+++ + snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
+++ + wcd->mbhc_btn0_released = false;
+++ + wcd->detect_accessory_type = true;
+++ +}
+++ +
static int pm8916_wcd_analog_enable_micbias_int2(struct
snd_soc_dapm_widget
*w, struct snd_kcontrol
case CDC_A_TX_2_EN:
snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
MICB_1_CTL_CFILT_REF_SEL_MASK, 0);
++++ /* fall through */
case CDC_A_TX_3_EN:
snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
CONN_TX2_SERIAL_TX2_MUX,
/* check if its BTN0 thats released */
if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK))
--- - priv->mbhc_btn0_pressed = false;
+++ + priv->mbhc_btn0_released = true;
} else {
snd_soc_jack_report(priv->jack, 0, btn_mask);
break;
case 0x0:
/* handle BTN_0 specially for type detection */
--- - if (priv->detect_accessory_type)
--- - priv->mbhc_btn0_pressed = true;
--- - else
+++ + if (!priv->detect_accessory_type)
snd_soc_jack_report(priv->jack,
SND_JACK_BTN_0, btn_mask);
break;
* both press and release event received then its
* a headset.
*/
--- - if (priv->mbhc_btn0_pressed)
+++ + if (priv->mbhc_btn0_released)
snd_soc_jack_report(priv->jack,
--- - SND_JACK_HEADPHONE, hs_jack_mask);
+++ + SND_JACK_HEADSET, hs_jack_mask);
else
snd_soc_jack_report(priv->jack,
--- - SND_JACK_HEADSET, hs_jack_mask);
+++ + SND_JACK_HEADPHONE, hs_jack_mask);
priv->detect_accessory_type = false;
} else { /* removal */
snd_soc_jack_report(priv->jack, 0, hs_jack_mask);
priv->detect_accessory_type = true;
--- - priv->mbhc_btn0_pressed = false;
+++ + priv->mbhc_btn0_released = false;
}
return IRQ_HANDLED;
{ }
};
+++ +MODULE_DEVICE_TABLE(of, pm8916_wcd_analog_spmi_match_table);
+++ +
static struct platform_driver pm8916_wcd_analog_spmi_driver = {
.driver = {
.name = "qcom,pm8916-wcd-spmi-codec",