static int snddev_icodec_close_tx(struct snddev_icodec_state *icodec)
{
	struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;

	pm_qos_update_request(&drv->tx_pm_qos_req,
			      msm_cpuidle_get_deep_idle_latency());

	if (drv->snddev_vreg)
		vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE);

	/* Disable ADIE */
	if (icodec->adie_path) {
		adie_codec_proceed_stage(icodec->adie_path,
					ADIE_CODEC_DIGITAL_OFF);
		adie_codec_close(icodec->adie_path);
		icodec->adie_path = NULL;
	}

	afe_close(icodec->data->copp_id);

	clk_disable_unprepare(drv->tx_bitclk);
	clk_disable_unprepare(drv->tx_osrclk);

	msm_snddev_tx_mclk_free();

	/* 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_icodec_close_tx(struct snddev_icodec_state *icodec)
{
	struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;

	wake_lock(&drv->tx_idlelock);

	if (drv->snddev_vreg)
		vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE);

	/* Disable ADIE */
	if (icodec->adie_path) {
		adie_codec_proceed_stage(icodec->adie_path,
					ADIE_CODEC_DIGITAL_OFF);
		adie_codec_close(icodec->adie_path);
		icodec->adie_path = NULL;
	}

	afe_close(icodec->data->copp_id);

	clk_disable(drv->tx_bitclk);
	clk_disable(drv->tx_osrclk);

	msm_snddev_tx_mclk_free();

	/* Reuse pamp_off for TX platform-specific setup  */
	if (icodec->data->pamp_off)
		icodec->data->pamp_off();

	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;
	struct snddev_icodec_data *data = icodec->data;

	wake_lock(&drv->tx_idlelock);

	if (drv->snddev_vreg)
		vreg_mode_vote(drv->snddev_vreg, 0, SNDDEV_HIGH_POWER_MODE);

	/* Reuse pamp_off for TX platform-specific setup  */
	if (icodec->data->pamp_on)
		icodec->data->pamp_on(0);

	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);
	}
	if (support_adie) {
		/* Disable ADIE */
		if (icodec->adie_path) {
			adie_codec_proceed_stage(icodec->adie_path,
						ADIE_CODEC_DIGITAL_OFF);
			adie_codec_close(icodec->adie_path);
			icodec->adie_path = NULL;
		}
	}
	afe_close(icodec->data->copp_id);

	clk_disable(drv->tx_bitclk);
	clk_disable(drv->tx_osrclk);

	if (support_aic3254_use_mclk)
		snddev_icodec_rxclk_enable(icodec, 0);

	msm_snddev_tx_mclk_free();


	icodec->enabled = 0;

	wake_unlock(&drv->tx_idlelock);
	return 0;
}
static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec)
{
	int trc;
	int rc_clk;
	int afe_channel_mode;
	union afe_port_config afe_config;
	struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;;

	wake_lock(&drv->tx_idlelock);

	if (drv->snddev_vreg)
		vreg_mode_vote(drv->snddev_vreg, 1, SNDDEV_HIGH_POWER_MODE);

	if (support_aic3254_use_mclk) {
		rc_clk = snddev_icodec_rxclk_enable(icodec, 1);
		if (IS_ERR_VALUE(rc_clk)) {
			pr_aud_err("%s Enable RX master clock Error\n", \
					__func__);
			goto error_invalid_osrclk;
		}
	}

	msm_snddev_tx_mclk_request();

	drv->tx_osrclk = clk_get(0, "i2s_mic_osr_clk");
	if (IS_ERR(drv->tx_osrclk)) {
		pr_aud_err("%s master clock Error\n", __func__);
		goto error_invalid_osrclk;
	}

	trc =  clk_set_rate(drv->tx_osrclk,
			SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate));
	if (IS_ERR_VALUE(trc)) {
		pr_aud_err("ERROR setting m clock1\n");
		goto error_invalid_freq;
	}

	clk_enable(drv->tx_osrclk);

	drv->tx_bitclk = clk_get(0, "i2s_mic_bit_clk");
	if (IS_ERR(drv->tx_bitclk)) {
		pr_aud_err("%s clock Error\n", __func__);
		goto error_invalid_bitclk;
	}

	/* ***************************************
	 * 1. CPU MASTER MODE:
	 *     Master clock = Sample Rate * OSR rate bit clock
	 * OSR Rate bit clock = bit/sample * channel master
	 * clock / bit clock = divider value = 8
	 *
	 * 2. CPU SLAVE MODE:
	 *     bitclk = 0
	 * *************************************** */
	if (msm_codec_i2s_slave_mode) {
		pr_debug("%s: configuring bit clock for slave mode\n",
				__func__);
		trc =  clk_set_rate(drv->tx_bitclk, 0);
	} else
		trc =  clk_set_rate(drv->tx_bitclk, 8);

	clk_enable(drv->tx_bitclk);

	if (support_aic3254) {
		if (aic3254_ops->aic3254_set_mode) {
			if (msm_get_call_state() == 1)
				aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_TX,
					icodec->data->aic3254_voc_id);
			else
				aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_TX,
					icodec->data->aic3254_id);
		}
	}
	if (support_adie) {
		/* Enable ADIE */
		trc = adie_codec_open(icodec->data->profile, &icodec->adie_path);
		if (IS_ERR_VALUE(trc))
			pr_aud_err("%s: adie codec open failed\n", __func__);
		else
			adie_codec_setpath(icodec->adie_path,
						icodec->sample_rate, 256);
	}
	switch (icodec->data->channel_mode) {
	case 2:
		afe_channel_mode = MSM_AFE_STEREO;
		break;
	case 1:
	default:
		afe_channel_mode = MSM_AFE_MONO;
		break;
	}
	afe_config.mi2s.channel = afe_channel_mode;
	afe_config.mi2s.bitwidth = 16;
	afe_config.mi2s.line = 1;
	if (msm_codec_i2s_slave_mode)
		afe_config.mi2s.ws = 0;
	else
		afe_config.mi2s.ws = 1;

	trc = afe_open(icodec->data->copp_id, &afe_config, icodec->sample_rate);

	if (icodec->adie_path && support_adie) {
		adie_codec_proceed_stage(icodec->adie_path,
					ADIE_CODEC_DIGITAL_READY);
		adie_codec_proceed_stage(icodec->adie_path,
					ADIE_CODEC_DIGITAL_ANALOG_READY);

		if (msm_codec_i2s_slave_mode)
			adie_codec_set_master_mode(icodec->adie_path, 1);
		else
			adie_codec_set_master_mode(icodec->adie_path, 0);
	}

	/* Reuse pamp_on for TX platform-specific setup  */
	if (icodec->data->pamp_on)
		icodec->data->pamp_on(1);

	icodec->enabled = 1;

	wake_unlock(&drv->tx_idlelock);
	return 0;

error_invalid_bitclk:
	clk_disable(drv->tx_osrclk);
error_invalid_freq:
error_invalid_osrclk:
	if (icodec->data->pamp_on)
		icodec->data->pamp_on(0);
	msm_snddev_tx_mclk_free();

	pr_aud_err("%s: encounter error\n", __func__);

	wake_unlock(&drv->tx_idlelock);
	return -ENODEV;
}