static int snddev_mi2s_close(struct msm_snddev_info *dev_info) { struct snddev_mi2s_drv_state *drv = &snddev_mi2s_drv; int dir; struct snddev_mi2s_data *snddev_mi2s_data = dev_info->private_data; if (!dev_info) { MM_ERR("%s: msm_snddev_info is null \n", __func__); return -EINVAL; } if (!dev_info->opened) { MM_ERR(" %s: calling close device with out opening the" " device \n", __func__); return -EIO; } mutex_lock(&drv->lock); drv->sd_lines_used &= ~snddev_mi2s_data->sd_lines; MM_DBG("%s: sd_lines in use = 0x%x\n", __func__, drv->sd_lines_used); if (snddev_mi2s_data->capability & SNDDEV_CAP_RX) { dir = DIR_RX; afe_disable(AFE_HW_PATH_MI2S_RX); } else { dir = DIR_TX; afe_disable(AFE_HW_PATH_MI2S_TX); } mi2s_unconfig_data_gpio(dir, snddev_mi2s_data->sd_lines); if (!drv->sd_lines_used) { clk_disable_unprepare(drv->sclk); clk_disable_unprepare(drv->mclk); drv->clocks_enabled = 0; mi2s_unconfig_clk_gpio(); } /* Disable audio path */ if (snddev_mi2s_data->deroute) snddev_mi2s_data->deroute(); mutex_unlock(&drv->lock); return 0; }
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; }
static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; wake_lock(&drv->tx_idlelock); 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); /* Reuse pamp_off for TX platform-specific setup */ if (icodec->data->pamp_on) icodec->data->pamp_on(0); icodec->enabled = 0; wake_unlock(&drv->tx_idlelock); return 0; }
static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct snddev_icodec_data *data = icodec->data; wake_lock(&drv->rx_idlelock); /* Disable power amplifier */ if (icodec->data->pamp_on) icodec->data->pamp_on(0); if (!support_aic3254) { if (support_adie) { /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } } else { /* Restore default id for A3254 */ if (data->aic3254_id != data->default_aic3254_id) data->aic3254_id = data->default_aic3254_id; /* Disable External Codec A3254 */ if (aic3254_ops->aic3254_set_mode) aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX, DOWNLINK_OFF); } afe_disable(AFE_HW_PATH_CODEC_RX); /* Enable qtr headset amplifier */ if (icodec->data->pre_pamp_on) icodec->data->pre_pamp_on(0); /* 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 */ //HTC_CSP_START #ifndef CONFIG_CODEC_AIC3008 clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); #endif //HTC_CSP_END icodec->enabled = 0; wake_unlock(&drv->rx_idlelock); return 0; }
static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) { int err; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; pm_qos_update_request(&drv->rx_pm_qos_req, msm_cpuidle_get_deep_idle_latency()); /* Remove the vote for SMPS mode*/ err = pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_DONTCARE); if (err != 0) MM_ERR("pmapp_smps_mode_vote error %d\n", err); /* Disable power amplifier */ if (icodec->data->pamp_off) icodec->data->pamp_off(); /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; afe_disable(AFE_HW_PATH_CODEC_RX); if (icodec->data->voltage_off) icodec->data->voltage_off(); /* Disable LPA Sub system */ lpa_cmd_enable_codec(drv->lpa, 0); lpa_put(drv->lpa); /* Disable LPA clocks */ clk_disable_unprepare(drv->lpa_p_clk); clk_disable_unprepare(drv->lpa_codec_clk); clk_disable_unprepare(drv->lpa_core_clk); /* Disable MI2S RX master block */ /* Disable MI2S RX bit clock */ clk_disable_unprepare(drv->rx_sclk); clk_disable_unprepare(drv->rx_mclk); icodec->enabled = 0; pm_qos_update_request(&drv->rx_pm_qos_req, PM_QOS_DEFAULT_VALUE); return 0; }
static int snddev_ecodec_close_tx(struct snddev_ecodec_state *ecodec) { struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; /* free GPIO */ if (!drv->rx_active) { aux_pcm_gpios_free(); clk_disable(drv->ecodec_clk); } /* disable AFE */ afe_disable(AFE_HW_PATH_AUXPCM_TX); ecodec->enabled = 0; return 0; }
static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct snddev_icodec_data *data = icodec->data; wake_lock(&drv->tx_idlelock); afe_disable(AFE_HW_PATH_CODEC_TX); if (support_adie) { /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } if (support_aic3254) { /* Restore default id for A3254 */ if (data->aic3254_id != data->default_aic3254_id) data->aic3254_id = data->default_aic3254_id; /* Disable External Codec A3254 */ if (aic3254_ops->aic3254_set_mode) aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_TX, UPLINK_OFF); } /* 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 /* Reuse pamp_off for TX platform-specific setup */ if (icodec->data->pamp_on) icodec->data->pamp_on(0); icodec->enabled = 0; wake_unlock(&drv->tx_idlelock); return 0; }
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 int snddev_ecodec_close_rx(struct snddev_ecodec_state *ecodec) { struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; MM_INFO("snddev_ecodec_close_rx : name = %s\n", ecodec->data->name); /* free GPIO */ if (!drv->tx_active) { aux_pcm_gpios_free(); clk_disable(drv->ecodec_clk); } /* disable AFE */ afe_disable(AFE_HW_PATH_AUXPCM_RX); ecodec->enabled = 0; return 0; }
static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; wake_lock(&drv->rx_idlelock); /* Disable power amplifier */ if (icodec->data->pamp_on) icodec->data->pamp_on(0); if (!support_aic3254 || !strcmp(icodec->data->name, "usb_headset_stereo_rx")) { /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; } 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); if (!support_aic3254) clk_disable(drv->rx_mclk); icodec->enabled = 0; wake_unlock(&drv->rx_idlelock); return 0; }
static int snddev_icodec_close_rx(struct snddev_icodec_state *icodec) { struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; /* Disable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_OFF); adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; afe_disable(AFE_HW_PATH_CODEC_RX); /* Disable MI2S RX master block */ /* Disable MI2S RX bit clock */ clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); 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; }
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"); } }
static void bt_sco_set_loopback_mode(u32 loop) { int trc; struct msm_afe_config afe_config; struct snddev_ecodec_drv_state *drv = &snddev_ecodec_drv; MM_INFO("[BTUI] bt_sco_set_loopback_mode : %d \n", loop); if(loop & 1) { /********************************************************** * Aux PCM Common set up ***********************************************************/ /* request GPIO */ trc = aux_pcm_gpios_request(); if (trc) { MM_ERR("[BTUI] ###### GPIO enable failed\n"); } /* config clocks */ clk_enable(drv->lpa_core_clk); /* enable ecodec clk */ clk_enable(drv->ecodec_clk); /* let ADSP confiure AUX PCM regs */ aux_codec_adsp_codec_ctl_en(ADSP_CTL); /* let adsp configure pcm path */ aux_codec_pcm_path_ctl_en(ADSP_CTL); /* choose ADSP_A */ audio_interct_aux_regsel(AUDIO_ADSP_A); audio_interct_tpcm_source(AUDIO_ADSP_A); audio_interct_rpcm_source(AUDIO_ADSP_A); clk_disable(drv->lpa_core_clk); /* send AUX_CODEC_CONFIG to AFE */ trc = afe_config_aux_codec(TESTMODE_HANDSET_PCM_CTL_VAL,TESTMODE_AUX_CODEC_INTF,TESTMODE_DATA_FORMAT_PADDING); if (IS_ERR_VALUE(trc)) { MM_ERR("[BTUI] ###### afe_config_aux_codec failed\n"); } /********************************************************** * Aux PCM Rx path set up ***********************************************************/ /* send CODEC CONFIG to AFE */ afe_config.sample_rate = 8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_AUXPCM_RX, &afe_config); if (IS_ERR_VALUE(trc)){ MM_ERR("[BTUI] ###### afe_enable failed\n"); } /********************************************************** * Aux PCM Tx path set up ***********************************************************/ /* send CODEC CONFIG to AFE */ afe_config.sample_rate = 8; afe_config.channel_mode = 1; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_AUXPCM_TX, &afe_config); if (IS_ERR_VALUE(trc)) { MM_ERR("[BTUI] ###### afe_enable tx failed\n"); } /************************************************************************************ * Start LoopBack *************************************************************************************/ /* Set the volume level to non unity, to avoid loopback effect */ afe_device_volume_ctrl(AFE_HW_PATH_AUXPCM_RX, 0x0500); lb_status = loop; MM_INFO("[BTUI] bt_sco_set_loopback_mode : [ENABLED] \n"); afe_config_ext_pcm_loopback(0xFFFF); } else { /*release GPIOs*/ aux_pcm_gpios_free(); afe_config_ext_pcm_loopback(0x0); /*disable clocks*/ clk_disable(drv->ecodec_clk); /*Disable afe configuration */ afe_disable(AFE_HW_PATH_AUXPCM_RX); afe_disable(AFE_HW_PATH_AUXPCM_TX); lb_status = 0; MM_INFO("[BTUI] bt_sco_set_loopback_mode : [DISABLED] \n"); } }