void speedy_snddev_imic_pamp_on(int en) { pr_info("%s: %d\n", __func__, en); if (en) pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); else pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); }
static void debugfs_adie_loopback(u32 loop) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; if (loop) { /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ clk_set_rate(drv->rx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); MM_INFO("configure ADIE RX path\n"); /* Configure ADIE */ adie_codec_open(&debug_rx_profile, &debugfs_rx_adie); adie_codec_setpath(debugfs_rx_adie, 8000, 256); adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); MM_INFO("Enable Handset Mic bias\n"); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); MM_INFO("configure ADIE TX path\n"); /* Configure ADIE */ adie_codec_open(&debug_tx_lb_profile, &debugfs_tx_adie); adie_codec_setpath(debugfs_tx_adie, 8000, 256); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); } else { /* Disable ADIE */ adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_rx_adie); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_tx_adie); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); /* Disable MI2S RX master block */ /* Disable MI2S RX bit clock */ clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); /* Disable MI2S TX master block */ /* Disable MI2S TX bit clock */ clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); } }
void mecha_mic_bias_enable(int en, int shift) { pr_info("%s: %d\n", __func__, en); if (en) pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_ALWAYS); else pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_OFF); }
void runnymede_back_mic_enable(int en) { pr_aud_info("%s %d\n", __func__, en); if (en) { gpio_set_value(runnymede_AUD_MICPATH_SEL, 0); pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_ALWAYS); } else { pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_OFF); } }
void primou_snddev_imic_pamp_on(int en) { pr_aud_info("%s: %d\n", __func__, en); if (en) { pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); mdelay(60); } else { pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); } }
void mecha_snddev_imic_pamp_on(int en) { pr_info("%s %d\n", __func__, en); if (en) { pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); mecha_back_mic_enable(1); } else { pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); mecha_back_mic_enable(0); } }
void mecha_back_mic_enable(int en) { pr_info("%s %d\n", __func__, en); if (en) { gpio_set_value(MECHA_AUD_MICPATH_SEL, 0); pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_ALWAYS); } else { gpio_set_value(MECHA_AUD_MICPATH_SEL, 1); pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_OFF); } }
void kingdom_back_mic_enable(int en) { pr_aud_info("%s %d\n", __func__, en); if (en) { gpio_set_value(PM8058_GPIO_PM_TO_SYS(KINGDOM_AUD_MICPATH_SEL), 0); pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_ALWAYS); } else { pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_OFF); } }
void runnymede_mic_bias_enable(int en, int shift) { pr_aud_info("%s: %d\n", __func__, en); if (en) { runnymede_audio_2v85_enable(en); pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_ALWAYS); } else { pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_OFF); runnymede_audio_2v85_enable(en); } }
void glacier_mic_disable(int mic) { switch (mic) { case 0: /* main mic */ pr_info("%s: disable main mic\n", __func__); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); break; case 1: /* back mic */ pr_info("%s: disable back mic\n", __func__); pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_OFF); break; default: break; } }
void runnymede_snddev_imic_pamp_on(int en) { pr_aud_info("%s: %d\n", __func__, en); if (en) { runnymede_audio_2v85_enable(en); gpio_set_value(PM8058_GPIO_PM_TO_SYS(runnymede_AUD_STEREO_REC), 1); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); runnymede_back_mic_enable(1); } else { runnymede_back_mic_enable(0); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); gpio_set_value(PM8058_GPIO_PM_TO_SYS(runnymede_AUD_STEREO_REC), 0); runnymede_audio_2v85_enable(en); } }
void disable_hsed(void){ #if (BOARD_VER > WS20 ) vreg_disable(vreg_Earjack_GP6); #else pmic_hsed_enable(PM_HSED_CONTROLLER_1, PM_HSED_ENABLE_OFF); //ON MIC BIAS #endif//(BOARD_VER > WS20 ) }
static void remove_headset(void) { #ifdef FEATURE_AUD_HOOK_BTN unsigned long irq_flags; #endif H2W_DBG(""); hi->ignore_btn = 1; /* FIH-SW2-MM-AY-TAP_Tapioca-00746_00 */ pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); /* FIH-SW2-MM-AY-TAP-ControlHSED_BIAS1-01 */ switch_set_state(&hi->sdev, NO_DEVICE); input_sync(hi->hs_input); #ifdef FEATURE_AUD_HOOK_BTN mHeadphone = false; if (bn_irq_enable) { local_irq_save(irq_flags); disable_irq(hi->irq_btn); local_irq_restore(irq_flags); bn_irq_enable=0; irq_set_irq_wake(hi->irq_btn, 0); } if (atomic_read(&hi->btn_state)) button_released(); #endif }
static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; afe_disable(AFE_HW_PATH_CODEC_TX); /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; /* Disable MI2S TX master block */ /* Disable MI2S TX bit clock */ clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); /* Disable mic bias */ pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); vreg_disable(drv->vreg_gp16); vreg_disable(drv->vreg_ncp); vreg_disable(drv->vreg_msme); vreg_disable(drv->vreg_rf2); icodec->enabled = 0; return 0; }
void glacier_snddev_imic_pamp_on(int en) { unsigned int engineerID = glacier_get_engineerid(); pr_info("%s: %d\n", __func__, en); if (en) pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); else pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); /* enable/disable back mic */ if ((engineerID & 0x4) == 0) { if (en) pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_ALWAYS); else pmic_hsed_enable(PM_HSED_CONTROLLER_2, PM_HSED_ENABLE_OFF); } }
void fsa8008_set_headset_mic_bias(int enable) { #ifdef CONFIG_LGE_HEADSET_DETECTION_FSA8008 printk(KERN_INFO "[FSA8008] Set MIC BIAS %d .\n", enable); pmic_hsed_enable(PM_HSED_CONTROLLER_0,(enable ? PM_HSED_ENABLE_ALWAYS : PM_HSED_ENABLE_OFF )); #else if (enable) gpio_set_value(GPIO_EAR_MIC_EN, 1); else gpio_set_value(GPIO_EAR_MIC_EN, 0); #endif }
static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; int i, err; pm_qos_update_request(&drv->tx_pm_qos_req, msm_cpuidle_get_deep_idle_latency()); /* Remove the vote for SMPS mode*/ err = pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); if (err != 0) MM_ERR("pmapp_smps_mode_vote error %d\n", err); afe_disable(AFE_HW_PATH_CODEC_TX); /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; /* Disable MI2S TX master block */ /* Disable MI2S TX bit clock */ clk_disable_unprepare(drv->tx_sclk); clk_disable_unprepare(drv->tx_mclk); /* Disable mic bias */ for (i = 0; i < icodec->data->pmctl_id_sz; i++) { pmic_hsed_enable(icodec->data->pmctl_id[i], PM_HSED_ENABLE_OFF); } /* Reuse pamp_off for TX platform-specific setup */ if (icodec->data->pamp_off) icodec->data->pamp_off(); icodec->enabled = 0; pm_qos_update_request(&drv->tx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return 0; }
static void debugfs_afe_loopback(u32 loop) { int trc; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; if (loop) { /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ trc = clk_set_rate(drv->rx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); if (IS_ERR_VALUE(trc)) MM_AUD_ERR("%s: failed to set clk rate\n", __func__); clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); clk_enable(drv->lpa_codec_clk); clk_enable(drv->lpa_core_clk); clk_enable(drv->lpa_p_clk); /* Set audio interconnect reg to ADSP */ audio_interct_codec(AUDIO_INTERCT_ADSP); /* Set MI2S */ mi2s_set_codec_output_path(0, WT_16_BIT); MM_AUD_INFO("%s: configure ADIE RX path\n", __func__); /* Configure ADIE */ adie_codec_open(&debug_rx_profile, &debugfs_rx_adie); adie_codec_setpath(debugfs_rx_adie, 8000, 256); afe_config.sample_rate = 8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; MM_AUD_INFO("%s: enable afe\n", __func__); trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); if (IS_ERR_VALUE(trc)) MM_AUD_ERR("%s: fail to enable afe rx\n", __func__); adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); MM_AUD_INFO("%s: Enable Handset Mic bias\n", __func__); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); /* Set MI2S */ mi2s_set_codec_input_path(0, WT_16_BIT); MM_AUD_INFO("%s: configure ADIE TX path\n", __func__); /* Configure ADIE */ adie_codec_open(&debug_tx_profile, &debugfs_tx_adie); adie_codec_setpath(debugfs_tx_adie, 8000, 256); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Start AFE */ afe_config.sample_rate = 0x8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) MM_AUD_ERR("%s: failed to enable AFE TX\n", __func__); } else { /* Disable ADIE */ adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_rx_adie); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_tx_adie); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); /* Disable MI2S RX master block */ /* Disable MI2S RX bit clock */ //HTC_CSP_START #ifndef CONFIG_CODEC_AIC3008 clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); #endif //HTC_CSP_END /* Disable MI2S TX master block */ /* Disable MI2S TX bit clock */ //HTC_CSP_START #ifndef CONFIG_CODEC_AIC3008 clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); #endif //HTC_CSP_END } }
static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec) { int trc; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;; pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); /* Voltage regulator voting * Vote GP16, NCP, MSME, RF2 */ vreg_enable(drv->vreg_gp16); vreg_enable(drv->vreg_ncp); vreg_enable(drv->vreg_msme); vreg_enable(drv->vreg_rf2); /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ trc = clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) goto error_invalid_freq; clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); /* Set MI2S */ mi2s_set_codec_input_path((icodec->data->channel_mode == 2 ? 1 : 0), WT_16_BIT); /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) goto error_adie; /* Enable ADIE */ adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Start AFE */ afe_config.sample_rate = icodec->sample_rate / 1000; afe_config.channel_mode = icodec->data->channel_mode; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) goto error_afe; icodec->enabled = 1; return 0; error_afe: adie_codec_close(icodec->adie_path); error_adie: clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); error_invalid_freq: vreg_disable(drv->vreg_gp16); vreg_disable(drv->vreg_ncp); vreg_disable(drv->vreg_msme); vreg_disable(drv->vreg_rf2); pr_err("%s: encounter error\n", __func__); return -ENODEV; }
static void insert_headset(void) { #ifdef FEATURE_AUD_HOOK_BTN unsigned long irq_flags; #endif int voltage = 0; /* FIH-SW2-MM-AY-hsed_type-00 */ H2W_DBG(""); input_sync(hi->hs_input); msleep(100); #ifdef FEATURE_AUD_HOOK_BTN /* On some non-standard headset adapters (usually those without a * button) the btn line is pulled down at the same time as the detect * line. We can check here by sampling the button line, if it is * low then it is probably a bad adapter so ignore the button. * If the button is released then we stop ignoring the button, so that * the user can recover from the situation where a headset is plugged * in with button held down. */ hi->ignore_btn = 1; /* FIH-SW2-MM-AY-TAP_Tapioca-00746_00 */ if (bn_irq_enable==0) { /* Enable button irq */ local_irq_save(irq_flags); enable_irq(hi->irq_btn); local_irq_restore(irq_flags); bn_irq_enable=1; irq_set_irq_wake(hi->irq_btn, 1); } #endif /* FIH-SW2-MM-AY-hsed_type-00 [ */ if (isCTIAheadset) { /* FIH-SW2-MM-AY-hsed_type-03 */ pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); msleep(130); proc_comm_get_hsed_voltage(2, &voltage, 0); //it will get the prior value, not the current value. Should not omit. msleep(70); proc_comm_get_hsed_voltage(2, &voltage, 0); H2W_DBG("aud_hs: voltage is %d\n ", voltage); /* FIH-SW2-MM-AY-hsed_type-01 [ */ if (voltage > 1700) { //do not change state to issue an UEVENT. //it is a earphone jack plug. mHeadphone = false; hi->ignore_btn = 1; pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); /* MM-RC-HEADSET-MULTIBUTTON-DETECT[* */ #ifdef FEATURE_AUD_HOOK_BTN if (bn_irq_enable) { local_irq_save(irq_flags); disable_irq(hi->irq_btn); local_irq_restore(irq_flags); bn_irq_enable=0; irq_set_irq_wake(hi->irq_btn, 0); } #endif /* MM-RC-HEADSET-MULTIBUTTON-DETECT]* */ } else if (voltage > 700 || voltage < 400) { /* FIH-SW2-MM-AY-hsed_type-01 ] *//* SW-MM-RC-CTIA-TTY* */ if (gpio_get_value(hi->cable_in1) == HS_PLUG_IN) { if (gpio_get_value(hi->cable_in2) == BTN_STATE_PRESSED) { switch_set_state(&hi->sdev, NOMIC_HEADSET); mHeadphone=true; hi->ignore_btn = 1; pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); H2W_DBG("aud_hs:HEADPHONE is plugging\n "); } else { switch_set_state(&hi->sdev, HEADSET); mHeadphone=false; #ifdef FEATURE_AUD_HOOK_BTN irq_set_irq_type(hi->irq_btn, IRQF_TRIGGER_BTN_PRESSED); #endif msleep(300); hi->ignore_btn = 0; H2W_DBG("aud_hs:HEADSET is plugging\n "); } } } else { mHeadphone = false; hi->ignore_btn = 1; pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); switch_set_state(&hi->sdev, NOT_SUPPORT); } H2W_DBG("switch_get_state= %d ",switch_get_state(&hi->sdev)); } else { /* FIH-SW2-MM-AY-TAP-ControlHSED_BIAS1-01 [ */ pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_ALWAYS); msleep(130); /* FIH-SW2-MM-AY-Tapioca_SS-00467-00 */ /* FIH-SW2-MM-AY-TAP-ControlHSED_BIAS1-01 ] */ if (gpio_get_value(hi->cable_in1) == HS_PLUG_IN) { /* FIH-SW2-MM-AY-TAP_headset_00 */ if (gpio_get_value(hi->cable_in2) == BTN_STATE_PRESSED) { /* FIH-SW2-MM-AY-TAP_headset_00 */ switch_set_state(&hi->sdev, NOMIC_HEADSET); mHeadphone=true; hi->ignore_btn = 1; /* FIH-SW2-MM-AY-TAP_Tapioca-00746_00 */ H2W_DBG("aud_hs:HEADPHONE is plugging\n "); } else { switch_set_state(&hi->sdev, HEADSET); mHeadphone=false; #ifdef FEATURE_AUD_HOOK_BTN irq_set_irq_type(hi->irq_btn, IRQF_TRIGGER_BTN_PRESSED); #endif msleep(300); /* FIH-SW2-MM-AY-TAP_Tapioca-00746_00 */ hi->ignore_btn = 0; /* FIH-SW2-MM-AY-TAP_Tapioca-00746_00 */ H2W_DBG("aud_hs:HEADSET is plugging\n "); } H2W_DBG("switch_get_state= %d ",switch_get_state(&hi->sdev)); } } /* FIH-SW2-MM-AY-hsed_type-00 ] */ }
static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec) { int trc; int i, err; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;; wake_lock(&drv->tx_idlelock); /* Vote for PWM mode*/ err = pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); if (err != 0) MM_ERR("pmapp_smps_mode_vote error %d\n", err); /* Reuse pamp_on for TX platform-specific setup */ if (icodec->data->pamp_on) icodec->data->pamp_on(); for (i = 0; i < icodec->data->pmctl_id_sz; i++) { pmic_hsed_enable(icodec->data->pmctl_id[i], PM_HSED_ENABLE_PWM_TCXO); } /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ trc = clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) goto error_invalid_freq; clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); /* Set MI2S */ mi2s_set_codec_input_path((icodec->data->channel_mode == REAL_STEREO_CHANNEL_MODE ? MI2S_CHAN_STEREO : (icodec->data->channel_mode == 2 ? MI2S_CHAN_STEREO : MI2S_CHAN_MONO_RAW)), WT_16_BIT); /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) goto error_adie; /* Enable ADIE */ adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Start AFE */ afe_config.sample_rate = icodec->sample_rate / 1000; afe_config.channel_mode = icodec->data->channel_mode; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) goto error_afe; icodec->enabled = 1; wake_unlock(&drv->tx_idlelock); return 0; error_afe: adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; error_adie: clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); error_invalid_freq: /* Disable mic bias */ for (i = 0; i < icodec->data->pmctl_id_sz; i++) { pmic_hsed_enable(icodec->data->pmctl_id[i], PM_HSED_ENABLE_OFF); } if (icodec->data->pamp_off) icodec->data->pamp_off(); MM_ERR("encounter error\n"); wake_unlock(&drv->tx_idlelock); return -ENODEV; }
static void debugfs_afe_loopback(u32 loop) { int trc; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct lpa_codec_config lpa_config; if (loop) { /* Vote for SMPS mode*/ pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ trc = clk_set_rate(drv->rx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); if (IS_ERR_VALUE(trc)) MM_ERR("failed to set clk rate\n"); clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); clk_enable(drv->lpa_p_clk); clk_enable(drv->lpa_codec_clk); clk_enable(drv->lpa_core_clk); /* Enable LPA sub system */ drv->lpa = lpa_get(); if (!drv->lpa) MM_ERR("failed to enable lpa\n"); lpa_config.sample_rate = 8000; lpa_config.sample_width = 16; lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC; lpa_config.num_channels = 1; lpa_cmd_codec_config(drv->lpa, &lpa_config); /* Set audio interconnect reg to LPA */ audio_interct_codec(AUDIO_INTERCT_LPA); mi2s_set_codec_output_path(MI2S_CHAN_MONO_PACKED, WT_16_BIT); MM_INFO("configure ADIE RX path\n"); /* Configure ADIE */ adie_codec_open(&debug_rx_profile, &debugfs_rx_adie); adie_codec_setpath(debugfs_rx_adie, 8000, 256); lpa_cmd_enable_codec(drv->lpa, 1); /* Start AFE for RX */ afe_config.sample_rate = 0x8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; MM_INFO("enable afe\n"); trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); if (IS_ERR_VALUE(trc)) MM_ERR("fail to enable afe RX\n"); adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Vote for PWM mode*/ pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); MM_INFO("Enable Handset Mic bias\n"); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_PWM_TCXO); /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(8000)); clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); /* Set MI2S */ mi2s_set_codec_input_path(MI2S_CHAN_MONO_PACKED, WT_16_BIT); MM_INFO("configure ADIE TX path\n"); /* Configure ADIE */ adie_codec_open(&debug_tx_profile, &debugfs_tx_adie); adie_codec_setpath(debugfs_tx_adie, 8000, 256); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Start AFE for TX */ afe_config.sample_rate = 0x8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) MM_ERR("failed to enable AFE TX\n"); /* Set the volume level to non unity, to avoid loopback effect */ afe_device_volume_ctrl(AFE_HW_PATH_CODEC_RX, 0x0500); /* enable afe loopback */ afe_loopback(1); MM_INFO("AFE loopback enabled\n"); } else { /* disable afe loopback */ afe_loopback(0); /* Remove the vote for SMPS mode*/ pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); /* Disable ADIE */ adie_codec_proceed_stage(debugfs_rx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_rx_adie); /* Disable AFE for RX */ afe_disable(AFE_HW_PATH_CODEC_RX); /* Disable LPA Sub system */ lpa_cmd_enable_codec(drv->lpa, 0); lpa_put(drv->lpa); /* Disable LPA clocks */ clk_disable(drv->lpa_p_clk); clk_disable(drv->lpa_codec_clk); clk_disable(drv->lpa_core_clk); /* Disable MI2S RX master block */ /* Disable MI2S RX bit clock */ clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); /* Disable AFE for TX */ afe_disable(AFE_HW_PATH_CODEC_TX); /* Disable ADIE */ adie_codec_proceed_stage(debugfs_tx_adie, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(debugfs_tx_adie); /* Disable MI2S TX master block */ /* Disable MI2S TX bit clock */ clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); MM_INFO("AFE loopback disabled\n"); } }