static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; if (spk_amp_gpio == BOTTOM_SPK_PAMP_GPIO) { ret = gpio_request(BOTTOM_SPK_PAMP_GPIO, "BOTTOM_SPK_AMP"); if (ret) { pr_aud_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n", __func__, BOTTOM_SPK_PAMP_GPIO); return; } ret = pm8xxx_gpio_config(BOTTOM_SPK_PAMP_GPIO, ¶m); if (ret) pr_aud_err("%s: Failed to configure Bottom Spk Ampl" " gpio %u\n", __func__, BOTTOM_SPK_PAMP_GPIO); else { pr_debug("%s: enable spkr amp gpio\n", __func__); gpio_direction_output(BOTTOM_SPK_PAMP_GPIO, 1); } } else if (spk_amp_gpio == TOP_SPK_PAMP_GPIO) { ret = gpio_request(TOP_SPK_PAMP_GPIO, "TOP_SPK_AMP"); if (ret) { pr_aud_err("%s: Error requesting GPIO %d\n", __func__, TOP_SPK_PAMP_GPIO); return; } ret = pm8xxx_gpio_config(TOP_SPK_PAMP_GPIO, ¶m); if (ret) pr_aud_err("%s: Failed to configure Top Spk Ampl" " gpio %u\n", __func__, TOP_SPK_PAMP_GPIO); else { pr_debug("%s: enable hac amp gpio\n", __func__); gpio_direction_output(TOP_SPK_PAMP_GPIO, 1); } } else if (spk_amp_gpio == DOCK_SPK_PAMP_GPIO) { ret = gpio_request(DOCK_SPK_PAMP_GPIO, "DOCK_SPK_AMP"); if (ret) { pr_aud_err("%s: Error requesting GPIO %d\n", __func__, DOCK_SPK_PAMP_GPIO); return; } ret = pm8xxx_gpio_config(DOCK_SPK_PAMP_GPIO, ¶m); if (ret) pr_aud_err("%s: Failed to configure Dock Spk Ampl" " gpio %u\n", __func__, DOCK_SPK_PAMP_GPIO); else { pr_debug("%s: enable dock amp gpio\n", __func__); gpio_direction_output(DOCK_SPK_PAMP_GPIO, 1); } ret = gpio_request(USB_ID_ADC_GPIO, "USB_ID_ADC"); if (ret) { pr_aud_err("%s: Error requesting USB_ID_ADC PMIC GPIO %u\n", __func__, USB_ID_ADC_GPIO); return; } ret = pm8xxx_gpio_config(USB_ID_ADC_GPIO, ¶m); if (ret) pr_aud_err("%s: Failed to configure USB_ID_ADC PMIC" " gpio %u\n", __func__, USB_ID_ADC_GPIO); } else { pr_aud_err("%s: ERROR : Invalid External Speaker Ampl GPIO." " gpio = %u\n", __func__, spk_amp_gpio); return; } } static void msm8960_ext_spk_power_amp_on(u32 spk) { #ifdef CONFIG_AUDIO_USAGE_FOR_POWER_CONSUMPTION g_spk_flag = 1; g_spk_start_time = current_kernel_time(); #endif if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_bottom_spk_pamp |= spk; if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(BOTTOM_SPK_PAMP_GPIO); pr_debug("%s: slepping 4 ms after turning on external " " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_top_spk_pamp |= spk; if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(TOP_SPK_PAMP_GPIO); pr_debug("%s: sleeping 4 ms after turning on " " external HAC Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) { mutex_lock(&audio_notifier_lock); if ((msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) && (msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) { pr_debug("%s() External Dock Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_dock_spk_pamp |= spk; if ((msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) && (msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(DOCK_SPK_PAMP_GPIO); pr_debug("%s: sleeping 4 ms after turning on " " external DOCK Ampl\n", __func__); usleep_range(4000, 4000); } mutex_unlock(&audio_notifier_lock); } else { pr_aud_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } }
static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; if (spk_amp_gpio == bottom_spk_pamp_gpio) { ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP"); if (ret) { pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n", __func__, bottom_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Bottom Spk Ampl" " gpio %u\n", __func__, bottom_spk_pamp_gpio); else { pr_debug("%s: enable Bottom spkr amp gpio\n", __func__); gpio_direction_output(bottom_spk_pamp_gpio, 1); } } else if (spk_amp_gpio == top_spk_pamp_gpio) { ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, top_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(top_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Top Spk Ampl" " gpio %u\n", __func__, top_spk_pamp_gpio); else { pr_debug("%s: enable Top spkr amp gpio\n", __func__); gpio_direction_output(top_spk_pamp_gpio, 1); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO." " gpio = %u\n", __func__, spk_amp_gpio); return; } } static void msm8960_ext_spk_power_amp_on(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_bottom_spk_pamp |= spk; if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio); pr_debug("%s: slepping 4 ms after turning on external " " Bottom Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_top_spk_pamp |= spk; if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio); pr_debug("%s: sleeping 4 ms after turning on " " external Top Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_spk_power_amp_off(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if (!msm8960_ext_bottom_spk_pamp) return; gpio_direction_output(bottom_spk_pamp_gpio, 0); gpio_free(bottom_spk_pamp_gpio); msm8960_ext_bottom_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Bottom" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if (!msm8960_ext_top_spk_pamp) return; gpio_direction_output(top_spk_pamp_gpio, 0); gpio_free(top_spk_pamp_gpio); msm8960_ext_top_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Top" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_control(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = &codec->dapm; #ifdef CONFIG_PANTECH_SND // Qualcomm Case 00850482 : fixed issue crashed in dapm_generic_check_power while boot up mutex_lock(&dapm->codec->mutex); #endif pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); if (msm8960_spk_control == MSM8960_SPK_ON) { snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); } else { snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg"); } snd_soc_dapm_sync(dapm); #ifdef CONFIG_PANTECH_SND // Qualcomm Case 00850482 : fixed issue crashed in dapm_generic_check_power while boot up mutex_unlock(&dapm->codec->mutex); #endif } static int msm8960_get_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); ucontrol->value.integer.value[0] = msm8960_spk_control; return 0; }
static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; if (spk_amp_gpio == bottom_spk_pamp_gpio) { ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP"); if (ret) { pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n", __func__, bottom_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Bottom Spk Ampl" " gpio %u\n", __func__, bottom_spk_pamp_gpio); else { pr_info("%s: enable Bottom spkr amp gpio\n", __func__); gpio_direction_output(bottom_spk_pamp_gpio, 1); } } else if (spk_amp_gpio == top_spk_pamp_gpio) { ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, top_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(top_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Top Spk Ampl" " gpio %u\n", __func__, top_spk_pamp_gpio); else { pr_info("%s: enable Top spkr amp gpio\n", __func__); gpio_direction_output(top_spk_pamp_gpio, 1); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO." " gpio = %u\n", __func__, spk_amp_gpio); return; } } static void msm8960_ext_spk_power_amp_on(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_bottom_spk_pamp |= spk; if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio); pr_debug("%s: slepping 4 ms after turning on external " " Bottom Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_top_spk_pamp |= spk; if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio); pr_debug("%s: sleeping 4 ms after turning on " " external HAC Ampl\n", __func__); usleep_range(4000, 4000); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_spk_power_amp_off(u32 spk) { pr_info("%s, spk = %d\n", __func__, spk); if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if (!msm8960_ext_bottom_spk_pamp) return; gpio_direction_output(bottom_spk_pamp_gpio, 0); gpio_free(bottom_spk_pamp_gpio); msm8960_ext_bottom_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Bottom" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if (!msm8960_ext_top_spk_pamp) return; gpio_direction_output(top_spk_pamp_gpio, 0); gpio_free(top_spk_pamp_gpio); msm8960_ext_top_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Top" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n", __func__, spk); return; } }