void holiday_imic_pamp_on_with_audience(int en)
{
	int ret, call_state=0;
	pr_aud_info("%s %d\n", __func__, en);

	call_state = msm_get_call_state();
	if (en) {
		ret = pm8058_micbias_enable(OTHC_MICBIAS_0, OTHC_SIGNAL_ALWAYS_ON);
		if (ret)
			pr_aud_err("%s: Enabling int mic power failed\n", __func__);

		/* select internal mic path */
		if (call_state) {
			gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 0);
			ret = pm8058_micbias_enable(OTHC_MICBIAS_1, OTHC_SIGNAL_ALWAYS_ON);
			if (ret)
				pr_aud_err("%s: Enabling back mic power failed\n", __func__);
		} else {
			if (!force_a1026_on)
				gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 1);
		}
	} else {
		ret = pm8058_micbias_enable(OTHC_MICBIAS_0, OTHC_SIGNAL_OFF);
		if (ret)
			pr_aud_err("%s: Enabling int mic power failed\n", __func__);
		if (call_state) {
			ret = pm8058_micbias_enable(OTHC_MICBIAS_1, OTHC_SIGNAL_OFF);
			if (ret)
				pr_aud_err("%s: Enabling back mic power failed\n", __func__);
		}
	}
}
void holiday_snddev_emic_pamp_on(int en)
{
	int call_state = 0;

	pr_aud_info("%s (support_audience, en)=(%d, %d)\n",
		__func__, support_audience, en);

	call_state = msm_get_call_state();
	/*
	external micbias should be controlled by headset driver with HOLIDAY_mic_enable
	turn on with headset plugged in and turn off when headset unplugged.
	*/
	if (en) {
		/* select internal mic path */
		gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL1), 1);
		if (support_audience) {
			if (call_state)
				gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 0);
			else
				gpio_set_value(PM8058_GPIO_PM_TO_SYS(HOLIDAY_AUD_MIC_SEL2), 1);
		}
	}
}
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;
}
示例#4
0
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;

	printk("%s(): +++\n", __func__);
	wake_lock(&drv->tx_idlelock);

	/* Reuse pamp_on for TX platform-specific setup  */
	if (icodec->data->pamp_on)
		icodec->data->pamp_on(1);
//HTC_AUD_START
#ifndef  CONFIG_CODEC_AIC3008
//HTC_AUD_END
	/* 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);
//HTC_AUD_START
#endif
//HTC_AUD_END
	/* 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);

	/* Enable External Codec A3254 */
	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) {
		/* 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);
		if (adie_codec_proceed_stage(icodec->adie_path,
				ADIE_CODEC_DIGITAL_READY)) {
/*			icodec->adie_path->profile = NULL; */
			goto error_adie;
		}
		if (adie_codec_proceed_stage(icodec->adie_path,
				ADIE_CODEC_DIGITAL_ANALOG_READY)) {
/*			icodec->adie_path->profile = NULL; */
			goto error_adie;
		}
	}

	/* 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);
	printk("%s(): ---\n", __func__);
	return 0;

error_afe:
	if (support_adie) {
		adie_codec_close(icodec->adie_path);
		icodec->adie_path = NULL;
	}
error_adie:


//HTC_CSP_START
#ifndef CONFIG_CODEC_AIC3008
	clk_disable(drv->tx_sclk);
	clk_disable(drv->tx_mclk);
#endif
//HTC_CSP_END
//HTC_AUD_START
#ifndef CONFIG_CODEC_AIC3008
//HTC_AUD_END
error_invalid_freq:

	if (icodec->data->pamp_on)
		icodec->data->pamp_on(0);

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

	wake_unlock(&drv->tx_idlelock);
	printk("%s(): ---\n", __func__);
//HTC_AUD_START
#endif
//HTC_AUD_END
	return -ENODEV;
}
示例#5
0
static int snddev_icodec_open_rx(struct snddev_icodec_state *icodec)
{
	int trc;
	struct msm_afe_config afe_config;
	struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;
	struct lpa_codec_config lpa_config;

	printk("%s(): +++\n", __func__);
	wake_lock(&drv->rx_idlelock);
//HTC_AUD_START
#ifndef  CONFIG_CODEC_AIC3008
//HTC_AUD_END
	/* enable MI2S RX master block */
	/* enable MI2S RX bit clock */
	trc = clk_set_rate(drv->rx_mclk,
			SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate));
	if (IS_ERR_VALUE(trc))
		goto error_invalid_freq;

	clk_enable(drv->rx_mclk);
	clk_enable(drv->rx_sclk);
//HTC_AUD_START
#endif
//HTC_AUD_END
	/* clk_set_rate(drv->lpa_codec_clk, 1); */ /* Remove if use pcom */
	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)
		goto error_lpa;
	lpa_config.sample_rate = icodec->sample_rate;
	lpa_config.sample_width = 16;
	lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC;
	lpa_config.num_channels = icodec->data->channel_mode;
	lpa_cmd_codec_config(drv->lpa, &lpa_config);

	/* Set audio interconnect reg to LPA */
	audio_interct_codec(AUDIO_INTERCT_LPA);

	/* Enable qtr headset amplifier */
	if (icodec->data->pre_pamp_on)
		icodec->data->pre_pamp_on(1);

	/* Set MI2S */
	mi2s_set_codec_output_path((icodec->data->channel_mode == 2 ?
	MI2S_CHAN_STEREO : MI2S_CHAN_MONO_PACKED), WT_16_BIT);

	if (!support_aic3254) {
		if (support_adie) {
			/* Configure ADIE */
			trc = adie_codec_open(icodec->data->profile, &icodec->adie_path);
			if (IS_ERR_VALUE(trc))
				goto error_adie;
			/* OSR default to 256, can be changed for power optimization
			If OSR is to be changed, need clock API for setting the divider
			*/
			adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256);
		}
	} else {
		if (aic3254_ops->aic3254_set_mode) {
			if (msm_get_call_state() == 1)
				aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX,
					icodec->data->aic3254_voc_id);
			else
				aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX,
					icodec->data->aic3254_id);
		}
	}

	/* 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_RX, &afe_config);
	if (IS_ERR_VALUE(trc))
		goto error_afe;
	lpa_cmd_enable_codec(drv->lpa, 1);
	if (!support_aic3254) {
		if (support_adie) {
			/* Enable ADIE */
			if (adie_codec_proceed_stage(icodec->adie_path,
						ADIE_CODEC_DIGITAL_READY)) {
/*				icodec->adie_path->profile = NULL; */
				goto error_adie;
			}

			if (adie_codec_proceed_stage(icodec->adie_path,
						ADIE_CODEC_DIGITAL_ANALOG_READY)) {
/*				icodec->adie_path->profile = NULL; */
				goto error_adie;
			}
		}
	}

	/* Enable power amplifier */
	if (icodec->data->pamp_on)
		icodec->data->pamp_on(1);

	icodec->enabled = 1;

	wake_unlock(&drv->rx_idlelock);
	printk("%s(): ---\n", __func__);
	return 0;

error_afe:
	if (!support_aic3254) {
		if (support_adie) {
			adie_codec_close(icodec->adie_path);
			icodec->adie_path = NULL;
		}
	}
error_adie:
	lpa_put(drv->lpa);
error_lpa:
	clk_disable(drv->lpa_p_clk);
	clk_disable(drv->lpa_codec_clk);
	clk_disable(drv->lpa_core_clk);
//HTC_CSP_START
#ifndef CONFIG_CODEC_AIC3008
	clk_disable(drv->rx_sclk);
	clk_disable(drv->rx_mclk);
#endif
//HTC_CSP_END
//HTC_AUD_START
#ifndef CONFIG_CODEC_AIC3008
//HTC_AUD_END
error_invalid_freq:

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

	wake_unlock(&drv->rx_idlelock);
	printk("%s(): ---\n", __func__);
//HTC_AUD_START
#endif
//HTC_AUD_END
	return -ENODEV;
}
static int msm_device_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	int set = 0;
	struct msm_audio_route_config route_cfg;
	struct msm_snddev_info *dev_info;
	struct msm_snddev_info *dst_dev_info;
	struct msm_snddev_info *src_dev_info;
	int tx_freq = 0;
	int rx_freq = 0;
	u32 set_freq = 0;

	set = ucontrol->value.integer.value[0];
	route_cfg.dev_id = ucontrol->id.numid - device_index;
	dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
	if (IS_ERR(dev_info)) {
		MM_AUD_ERR("pass invalid dev_id\n");
		rc = PTR_ERR(dev_info);
		return rc;
	}
	MM_INFO("device %s set %d\n", dev_info->name, set);
	pr_aud_info("[ALSA] msm_en_device (dev %s, id %d, enable %d, opened %d)\n",
		dev_info->name, route_cfg.dev_id, set, dev_info->opened);
	if (set) {
		if (!dev_info->opened) {
			set_freq = dev_info->sample_rate;
			if (!msm_device_is_voice(route_cfg.dev_id) && msm_get_call_state()) {
				msm_get_voc_freq(&tx_freq, &rx_freq);
				if (dev_info->capability & SNDDEV_CAP_TX)
					set_freq = tx_freq;
				if (dev_info->capability & SNDDEV_CAP_RX)
					set_freq = rx_freq;
				if (set_freq == 0)
					set_freq = dev_info->sample_rate;
			} else
				set_freq = dev_info->sample_rate;


			MM_AUD_INFO("device freq =%d\n", set_freq);
			rc = dev_info->dev_ops.set_freq(dev_info, set_freq);
			if (rc < 0) {
				MM_AUD_ERR("device freq failed!\n");
				return rc;
			}
			dev_info->set_sample_rate = rc;
			rc = 0;
			rc = dev_info->dev_ops.open(dev_info);
			if (rc < 0) {
				MM_AUD_ERR("Enabling %s failed", dev_info->name);
				return rc;
			}
			dev_info->opened = 1;
			broadcast_event(AUDDEV_EVT_DEV_RDY, route_cfg.dev_id,
							SESSION_IGNORE);
			if ((route_cfg.dev_id == src_dev) ||
			(route_cfg.dev_id == dst_dev)) {
				dst_dev_info = audio_dev_ctrl_find_dev(
						dst_dev);
				if (IS_ERR(dst_dev_info)) {
					pr_err("dst_dev:%s:pass invalid"
						"dev_id\n", __func__);
					rc = PTR_ERR(dst_dev_info);
					return rc;
				}
				src_dev_info = audio_dev_ctrl_find_dev(
						src_dev);
				if (IS_ERR(src_dev_info)) {
					pr_err("src_dev:%s:pass invalid"
						"dev_id\n", __func__);
					rc = PTR_ERR(src_dev_info);
					return rc;
				}
				if ((dst_dev_info->opened) &&
				(src_dev_info->opened)) {
					pr_debug("%d: Enable afe_loopback\n",
							__LINE__);
					afe_loopback(LOOPBACK_ENABLE,
					       dst_dev_info->copp_id,
					       src_dev_info->copp_id);
					loopback_status = 1;
				}
			}
		}
	} else {
		if (dev_info->opened) {
			broadcast_event(AUDDEV_EVT_REL_PENDING,
						route_cfg.dev_id,
						SESSION_IGNORE);
			rc = dev_info->dev_ops.close(dev_info);
			if (rc < 0) {
				MM_AUD_ERR("Snd device failed close!\n");
				return rc;
			} else {
				dev_info->opened = 0;
				broadcast_event(AUDDEV_EVT_DEV_RLS,
					route_cfg.dev_id,
					SESSION_IGNORE);
			}
			if (loopback_status == 1) {
				if ((route_cfg.dev_id == src_dev) ||
					(route_cfg.dev_id == dst_dev)) {
					dst_dev_info = audio_dev_ctrl_find_dev(
							dst_dev);
					if (IS_ERR(dst_dev_info)) {
						pr_err("dst_dev:%s:pass invalid"
							"dev_id\n", __func__);
						rc = PTR_ERR(dst_dev_info);
						return rc;
					}
					src_dev_info = audio_dev_ctrl_find_dev(
							src_dev);
					if (IS_ERR(src_dev_info)) {
						pr_err("src_dev:%s:pass invalid"
							"dev_id\n", __func__);
						rc = PTR_ERR(src_dev_info);
						return rc;
					}
					pr_debug("%d: Disable afe_loopback\n",
					__LINE__);
					afe_loopback(LOOPBACK_DISABLE,
						dst_dev_info->copp_id,
						src_dev_info->copp_id);
					loopback_status = 0;
				}
			}
		}

	}
	return rc;
}
static int snddev_icodec_open_rx(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->rx_idlelock);

	if (drv->snddev_vreg) {
		if (!strcmp(icodec->data->name, "headset_stereo_rx"))
			vreg_mode_vote(drv->snddev_vreg, 1,
					SNDDEV_LOW_POWER_MODE);
		else
			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_freq;
		}
	} else {
		msm_snddev_rx_mclk_request();

		drv->rx_osrclk = clk_get(0, "i2s_spkr_osr_clk");
		if (IS_ERR(drv->rx_osrclk))
			pr_aud_err("%s master clock Error\n", __func__);

		trc =  clk_set_rate(drv->rx_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->rx_osrclk);
	}

	drv->rx_bitclk = clk_get(0, "i2s_spkr_bit_clk");
	if (IS_ERR(drv->rx_bitclk))
		pr_aud_err("%s clock Error\n", __func__);

	/* ***************************************
	 * 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->rx_bitclk, 0);
	} else
		trc =  clk_set_rate(drv->rx_bitclk, 8);

	if (IS_ERR_VALUE(trc)) {
		pr_aud_err("ERROR setting m clock1\n");
		goto error_adie;
	}
	clk_enable(drv->rx_bitclk);

	if (icodec->data->voltage_on)
		icodec->data->voltage_on(1);

	if (support_aic3254) {
		if (aic3254_ops->aic3254_set_mode) {
			if (msm_get_call_state() == 1)
				aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX,
					icodec->data->aic3254_voc_id);
			else
				aic3254_ops->aic3254_set_mode(AIC3254_CONFIG_RX,
					icodec->data->aic3254_id);
		}
	}
	if (support_adie) {
		/* Configure 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);
		/* OSR default to 256, can be changed for power optimization
		 * If OSR is to be changed, need clock API for setting the divider
		 */
	}

	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 (trc < 0)
		pr_aud_err("%s: afe open failed, trc = %d\n", __func__, trc);

	if (support_adie) {
		/* Enable ADIE */
		if (icodec->adie_path) {
			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);
	}
	/* Enable power amplifier */
	if (icodec->data->pamp_on)
		icodec->data->pamp_on(1);

	icodec->enabled = 1;

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

error_adie:
	clk_disable(drv->rx_bitclk);
	clk_disable(drv->rx_osrclk);
error_invalid_freq:

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

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