Loading sound/soc/codecs/wcd-mbhc-v2.c +29 −20 Original line number Diff line number Diff line Loading @@ -61,6 +61,33 @@ "%s: BCL should have acquired\n", __func__); \ } static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc) { struct wcd_mbhc_btn_detect_cfg *btn_det; struct snd_soc_codec *codec = mbhc->codec; struct snd_soc_card *card = codec->card; u16 i; u32 course, fine, reg_val; u16 reg_addr = MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL; if (mbhc->mbhc_cfg->calibration == NULL) { dev_err(card->dev, "%s: calibration data is NULL\n", __func__); return; } btn_det = WCD_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration); for (i = 0; i < btn_det->num_btn; i++) { course = (btn_det->_v_btn_high[i] / 100); fine = ((btn_det->_v_btn_high[i] % 100) / 12); reg_val = (course << 5) | (fine << 2); snd_soc_update_bits(codec, reg_addr, 0xFC, reg_val); pr_debug("%s: course: %d fine: %d reg_addr: %x reg_val: %x\n", __func__, course, fine, reg_addr, reg_val); reg_addr++; } } static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask) { Loading Loading @@ -597,26 +624,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x20, 0x00); /* * Set button ref values actually the values * should be taken from the config data through * ACDB */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL, 0xFC, 0x08); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL, 0xFC, 0x10); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL, 0xFC, 0x18); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL, 0xFC, 0x24); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL, 0xFC, 0x2C); /* Enable HW FSM and current source */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, Loading Loading @@ -909,6 +916,8 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x08, 0x08); /* Program Button threshold registers */ wcd_program_btn_threshold(mbhc); /* enable the WCD MBHC IRQ's */ wcd9xxx_enable_irq(mbhc->intr_ids->mbhc_sw_intr); wcd9xxx_enable_irq(mbhc->intr_ids->mbhc_btn_press_intr); Loading sound/soc/codecs/wcd-mbhc-v2.h +16 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define TOMBAK_MBHC_NC 0 #define TOMBAK_MBHC_NO 1 #define WCD_MBHC_DEF_BUTTONS 5 enum wcd_mbhc_plug_type { PLUG_TYPE_INVALID = -1, Loading @@ -31,6 +32,17 @@ enum pa_dac_ack_flags { WCD_MBHC_HPHR_PA_OFF_ACK, }; enum wcd_mbhc_btn_det_mem { WCD_MBHC_BTN_DET_V_BTN_LOW, WCD_MBHC_BTN_DET_V_BTN_HIGH }; struct wcd_mbhc_btn_detect_cfg { u8 num_btn; s16 _v_btn_low[WCD_MBHC_DEF_BUTTONS]; s16 _v_btn_high[WCD_MBHC_DEF_BUTTONS]; } __packed; struct wcd_mbhc_config { bool read_fw_bin; void *calibration; Loading Loading @@ -81,6 +93,10 @@ struct wcd_mbhc { /* Holds codec specific interrupt mapping */ const struct wcd_mbhc_intr *intr_ids; }; #define WCD_MBHC_CAL_BTN_DET_PTR(cali) ( \ (struct wcd_mbhc_btn_detect_cfg *) cali) int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg); void wcd_mbhc_stop(struct wcd_mbhc *mbhc); Loading sound/soc/msm/msm8x16.c +42 −2 Original line number Diff line number Diff line Loading @@ -495,13 +495,45 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) return ret; } static void *def_msm8x16_wcd_mbhc_cal(void) { void *msm8x16_wcd_cal; struct wcd_mbhc_btn_detect_cfg *btn_cfg; u16 *btn_low, *btn_high; msm8x16_wcd_cal = kzalloc(sizeof(struct wcd_mbhc_btn_detect_cfg), GFP_KERNEL); if (!msm8x16_wcd_cal) { pr_err("%s: out of memory\n", __func__); return NULL; } btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm8x16_wcd_cal); btn_cfg->num_btn = WCD_MBHC_DEF_BUTTONS; btn_low = btn_cfg->_v_btn_low; btn_high = btn_cfg->_v_btn_high; btn_low[0] = 0; btn_high[0] = 25; btn_low[1] = 25; btn_high[1] = 50; btn_low[2] = 50; btn_high[2] = 75; btn_low[3] = 75; btn_high[3] = 112; btn_low[4] = 112; btn_high[4] = 137; return msm8x16_wcd_cal; } static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; int ret = -ENOMEM; pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); Loading @@ -528,7 +560,15 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); mbhc_cfg.calibration = def_msm8x16_wcd_mbhc_cal(); if (mbhc_cfg.calibration) { ret = msm8x16_wcd_hs_detect(codec, &mbhc_cfg); if (ret) { pr_err("%s: msm8x16_wcd_hs_detect failed\n", __func__); kfree(mbhc_cfg.calibration); return ret; } } return ret; } Loading Loading
sound/soc/codecs/wcd-mbhc-v2.c +29 −20 Original line number Diff line number Diff line Loading @@ -61,6 +61,33 @@ "%s: BCL should have acquired\n", __func__); \ } static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc) { struct wcd_mbhc_btn_detect_cfg *btn_det; struct snd_soc_codec *codec = mbhc->codec; struct snd_soc_card *card = codec->card; u16 i; u32 course, fine, reg_val; u16 reg_addr = MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL; if (mbhc->mbhc_cfg->calibration == NULL) { dev_err(card->dev, "%s: calibration data is NULL\n", __func__); return; } btn_det = WCD_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration); for (i = 0; i < btn_det->num_btn; i++) { course = (btn_det->_v_btn_high[i] / 100); fine = ((btn_det->_v_btn_high[i] % 100) / 12); reg_val = (course << 5) | (fine << 2); snd_soc_update_bits(codec, reg_addr, 0xFC, reg_val); pr_debug("%s: course: %d fine: %d reg_addr: %x reg_val: %x\n", __func__, course, fine, reg_addr, reg_val); reg_addr++; } } static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask) { Loading Loading @@ -597,26 +624,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN, 0x20, 0x00); /* * Set button ref values actually the values * should be taken from the config data through * ACDB */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL, 0xFC, 0x08); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL, 0xFC, 0x10); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL, 0xFC, 0x18); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL, 0xFC, 0x24); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL, 0xFC, 0x2C); /* Enable HW FSM and current source */ snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL, Loading Loading @@ -909,6 +916,8 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) snd_soc_update_bits(codec, MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL, 0x08, 0x08); /* Program Button threshold registers */ wcd_program_btn_threshold(mbhc); /* enable the WCD MBHC IRQ's */ wcd9xxx_enable_irq(mbhc->intr_ids->mbhc_sw_intr); wcd9xxx_enable_irq(mbhc->intr_ids->mbhc_btn_press_intr); Loading
sound/soc/codecs/wcd-mbhc-v2.h +16 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #define TOMBAK_MBHC_NC 0 #define TOMBAK_MBHC_NO 1 #define WCD_MBHC_DEF_BUTTONS 5 enum wcd_mbhc_plug_type { PLUG_TYPE_INVALID = -1, Loading @@ -31,6 +32,17 @@ enum pa_dac_ack_flags { WCD_MBHC_HPHR_PA_OFF_ACK, }; enum wcd_mbhc_btn_det_mem { WCD_MBHC_BTN_DET_V_BTN_LOW, WCD_MBHC_BTN_DET_V_BTN_HIGH }; struct wcd_mbhc_btn_detect_cfg { u8 num_btn; s16 _v_btn_low[WCD_MBHC_DEF_BUTTONS]; s16 _v_btn_high[WCD_MBHC_DEF_BUTTONS]; } __packed; struct wcd_mbhc_config { bool read_fw_bin; void *calibration; Loading Loading @@ -81,6 +93,10 @@ struct wcd_mbhc { /* Holds codec specific interrupt mapping */ const struct wcd_mbhc_intr *intr_ids; }; #define WCD_MBHC_CAL_BTN_DET_PTR(cali) ( \ (struct wcd_mbhc_btn_detect_cfg *) cali) int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg); void wcd_mbhc_stop(struct wcd_mbhc *mbhc); Loading
sound/soc/msm/msm8x16.c +42 −2 Original line number Diff line number Diff line Loading @@ -495,13 +495,45 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) return ret; } static void *def_msm8x16_wcd_mbhc_cal(void) { void *msm8x16_wcd_cal; struct wcd_mbhc_btn_detect_cfg *btn_cfg; u16 *btn_low, *btn_high; msm8x16_wcd_cal = kzalloc(sizeof(struct wcd_mbhc_btn_detect_cfg), GFP_KERNEL); if (!msm8x16_wcd_cal) { pr_err("%s: out of memory\n", __func__); return NULL; } btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm8x16_wcd_cal); btn_cfg->num_btn = WCD_MBHC_DEF_BUTTONS; btn_low = btn_cfg->_v_btn_low; btn_high = btn_cfg->_v_btn_high; btn_low[0] = 0; btn_high[0] = 25; btn_low[1] = 25; btn_high[1] = 50; btn_low[2] = 50; btn_high[2] = 75; btn_low[3] = 75; btn_high[3] = 112; btn_low[4] = 112; btn_high[4] = 137; return msm8x16_wcd_cal; } static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; int ret = -ENOMEM; pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); Loading @@ -528,7 +560,15 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); mbhc_cfg.calibration = def_msm8x16_wcd_mbhc_cal(); if (mbhc_cfg.calibration) { ret = msm8x16_wcd_hs_detect(codec, &mbhc_cfg); if (ret) { pr_err("%s: msm8x16_wcd_hs_detect failed\n", __func__); kfree(mbhc_cfg.calibration); return ret; } } return ret; } Loading