示例#1
0
static int msm_loopback_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	struct msm_snddev_info *src_dev_info = NULL; /* TX device */
	struct msm_snddev_info *dst_dev_info = NULL; /* RX device */
	int dst_dev_id = ucontrol->value.integer.value[0];
	int src_dev_id = ucontrol->value.integer.value[1];
	int set = ucontrol->value.integer.value[2];

	pr_debug("%s: dst=%d :src=%d set=%d\n", __func__,
	       dst_dev_id, src_dev_id, set);

	dst_dev_info = audio_dev_ctrl_find_dev(dst_dev_id);
	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;
	}
	if (!(dst_dev_info->capability & SNDDEV_CAP_RX)) {
		pr_err("Destination device %d is not RX device\n",
			dst_dev_id);
		return -EFAULT;
	}

	src_dev_info = audio_dev_ctrl_find_dev(src_dev_id);
	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 (!(src_dev_info->capability & SNDDEV_CAP_TX)) {
		pr_err("Source device %d is not TX device\n", src_dev_id);
		return -EFAULT;
	}

	if (set) {
		pr_debug("%s:%d:Enabling AFE_Loopback\n", __func__, __LINE__);
		src_dev = src_dev_id;
		dst_dev = dst_dev_id;
		loopback_status = 1;
		if ((dst_dev_info->opened) && (src_dev_info->opened))
			rc = afe_loopback(LOOPBACK_ENABLE,
				       dst_dev_info->copp_id,
				       src_dev_info->copp_id);
	} else {
		pr_debug("%s:%d:Disabling AFE_Loopback\n", __func__, __LINE__);
		src_dev = DEVICE_IGNORE;
		dst_dev = DEVICE_IGNORE;
		loopback_status = 0;
		rc = afe_loopback(LOOPBACK_DISABLE,
			       dst_dev_info->copp_id,
			       src_dev_info->copp_id);
	}
	return rc;
}
示例#2
0
static void fm_audio_listner(u32 evt_id, union auddev_evt_data *evt_payload,
			void *private_data)
{
	struct audio *audio = (struct audio *) private_data;
	switch (evt_id) {
	case AUDDEV_EVT_DEV_RDY:
		pr_info("%s :AUDDEV_EVT_DEV_RDY\n", __func__);
		if (evt_payload->routing_id == FM_COPP) {
			audio->fm_source = 1;
			audio->fm_src_copp_id = FM_COPP;
		} else {
			audio->fm_dest = 1;
			audio->fm_dst_copp_id = evt_payload->routing_id;
		}

		if (audio->enabled &&
			audio->fm_dest &&
			audio->fm_source) {

			afe_loopback_gain(audio->fm_src_copp_id,
						audio->volume);
			afe_loopback(FM_ENABLE, audio->fm_dst_copp_id,
						audio->fm_src_copp_id);
			audio->running = 1;
		}
		break;
	case AUDDEV_EVT_DEV_RLS:
		pr_info("%s: AUDDEV_EVT_DEV_RLS\n", __func__);
		if (evt_payload->routing_id == audio->fm_src_copp_id)
			audio->fm_source = 0;
		else
			audio->fm_dest = 0;
		if (audio->running
			&& (!audio->fm_dest || !audio->fm_source)) {
			afe_loopback(FM_DISABLE, audio->fm_dst_copp_id,
						audio->fm_src_copp_id);
			audio->running = 0;
		} else {
			pr_err("%s: device switch happened\n", __func__);
		}
		break;
	case AUDDEV_EVT_STREAM_VOL_CHG:
		pr_debug("%s: AUDDEV_EVT_STREAM_VOL_CHG\n", __func__);
		if (audio->fm_source) {
			audio->volume = evt_payload->session_vol;
			afe_loopback_gain(audio->fm_src_copp_id,
					audio->volume);
		}
		break;

	default:
		pr_err("%s: ERROR:wrong event %08x\n", __func__, evt_id);
		break;
	}
}
示例#3
0
文件: q6afe.c 项目: lolhi/No.5-Kernel
static ssize_t afe_debug_write(struct file *filp,
	const char __user *ubuf, size_t cnt, loff_t *ppos)
{
	char *lb_str = filp->private_data;
	char lbuf[32];
	int rc;
	unsigned long param[5];

	if (cnt > sizeof(lbuf) - 1)
		return -EINVAL;

	rc = copy_from_user(lbuf, ubuf, cnt);
	if (rc)
		return -EFAULT;

	lbuf[cnt] = '\0';

	if (!strcmp(lb_str, "afe_loopback")) {
		rc = afe_get_parameters(lbuf, param, 3);
		if (!rc) {
			pr_info("%s %lu %lu %lu\n", lb_str, param[0], param[1],
				param[2]);

			if ((param[0] != AFE_LOOPBACK_ON) && (param[0] !=
				AFE_LOOPBACK_OFF)) {
				pr_err("%s: Error, parameter 0 incorrect\n",
					__func__);
				rc = -EINVAL;
				goto afe_error;
			}
#ifdef CONFIG_RECINCALL
			if ((afe_validate_port(param[1]) < 0) ||
				(afe_validate_port(param[2])) < 0) 
#else
			if ((param[1] >= AFE_MAX_PORTS) || (param[2] >=
				AFE_MAX_PORTS))
#endif
			{
				pr_err("%s: Error, invalid afe port\n",
					__func__);
			}
			if (this_afe.apr == NULL) {
				pr_err("%s: Error, AFE not opened\n", __func__);
				rc = -EINVAL;
			} else {
				rc = afe_loopback(param[0], param[1], param[2]);
			}
		} else {
			pr_err("%s: Error, invalid parameters\n", __func__);
			rc = -EINVAL;
		}
	}
afe_error:
	if (rc == 0)
		rc = cnt;
	else
		pr_err("%s: rc = %d\n", __func__, rc);

	return rc;
}
示例#4
0
static int audio_disable(struct audio *audio)
{

	/* break the AFE loopback here */
	afe_loopback(FM_DISABLE, audio->fm_dst_copp_id, audio->fm_src_copp_id);
	return 0;
}
示例#5
0
static int fm_audio_disable(struct audio *audio)
{

	
	afe_loopback(FM_DISABLE, audio->fm_dst_copp_id, audio->fm_src_copp_id);
	return 0;
}
示例#6
0
static int audio_disable(struct audio *audio)
{

	/* break the AFE loopback here */
	afe_loopback(FM_DISABLE, audio->fm_dest, audio->fm_source);
	return 0;
}
示例#7
0
static void fm_listner(u32 evt_id, union auddev_evt_data *evt_payload,
			void *private_data)
{
	struct audio *audio = (struct audio *) private_data;
	switch (evt_id) {
	case AUDDEV_EVT_DEV_RDY:
		pr_info(":AUDDEV_EVT_DEV_RDY\n");
		if (evt_payload->routing_id == FM_COPP) {
			audio->fm_source = 1;
			audio->fm_src_copp_id = FM_COPP;
		} else {
			audio->fm_dest = 1;
			audio->fm_dst_copp_id = evt_payload->routing_id;
		}

		if (audio->enabled &&
			audio->fm_dest &&
			audio->fm_source) {

			afe_loopback(FM_ENABLE, audio->fm_dest,
						audio->fm_source);
			audio->running = 1;
		}
		break;
	case AUDDEV_EVT_DEV_RLS:
		pr_info(":AUDDEV_EVT_DEV_RLS\n");
		if (evt_payload->routing_id == audio->fm_source)
			audio->fm_source = 0;
		if (evt_payload->routing_id == audio->fm_dest)
			audio->fm_dest = 0;

		if (audio->running
			&& (!audio->fm_dest || !audio->fm_source)) {
			afe_loopback(FM_DISABLE, audio->fm_dest,
						audio->fm_source);
			audio->running = 0;
		}
		break;
	default:
		pr_err(":ERROR:wrong event\n");
		break;
	}
}
static ssize_t afe_debug_write(struct file *filp,
	const char __user *ubuf, size_t cnt, loff_t *ppos)
{
	char *lb_str = filp->private_data;
	char cmd;

	if (get_user(cmd, ubuf))
		return -EFAULT;

	MM_INFO("%s %c\n", lb_str, cmd);

	if (!strcmp(lb_str, "afe_loopback")) {
		switch (cmd) {
		case '1':
			afe_loopback(1);
			break;
		case '0':
			afe_loopback(0);
			break;
		}
	}

	return cnt;
}
示例#9
0
void afe_ext_loopback(int enable, int rx_copp_id, int tx_copp_id)
{
	struct afe_cmd_ext_loopback cmd;
	struct msm_afe_state *afe;

	afe = &the_afe_state;
	MM_DBG("enable %d\n", enable);
	if ((rx_copp_id == 0) && (tx_copp_id == 0)) {
		afe_loopback(enable);
	} else {
		memset(&cmd, 0, sizeof(cmd));
		cmd.cmd_id = AFE_CMD_EXT_LOOPBACK;
		cmd.source_id = tx_copp_id;
		cmd.dst_id = rx_copp_id;
		if (enable)
			cmd.enable_flag = AFE_LOOPBACK_ENABLE_COMMAND;

		afe_send_queue(afe, &cmd, sizeof(cmd));
	}
}
示例#10
0
static int fm_audio_enable(struct audio *audio)
{
	if (audio->enabled)
		return 0;

	pr_info("%s: fm dest= %08x fm_source = %08x\n", __func__,
		audio->fm_dst_copp_id, audio->fm_src_copp_id);

	

	if (audio->fm_dest && audio->fm_source) {
		if (afe_loopback(FM_ENABLE, audio->fm_dst_copp_id,
					audio->fm_src_copp_id) < 0) {
			pr_err("%s: afe_loopback failed\n", __func__);
		}

		audio->running = 1;
	}

	audio->enabled = 1;
	return 0;
}
示例#11
0
static int audio_enable(struct audio *audio)
{
	if (audio->enabled)
		return 0;

	pr_info("fm dest= %08x fm_source = %08x\n",
			audio->fm_dst_copp_id, audio->fm_src_copp_id);

	/* do afe loopback here */

	if (audio->fm_dest && audio->fm_source) {
		if (afe_loopback(FM_ENABLE, audio->fm_dst_copp_id,
					audio->fm_src_copp_id) < 0) {
			pr_err("afe_loopback failed\n");
		}

		audio->running = 1;
	}

	audio->enabled = 1;
	return 0;
}
示例#12
0
static ssize_t afe_debug_write(struct file *filp,
	const char __user *ubuf, size_t cnt, loff_t *ppos)
{
	char *lb_str = filp->private_data;
	char lbuf[32];
	int rc;
	unsigned long param[5];

	if (cnt > sizeof(lbuf) - 1)
		return -EINVAL;

	rc = copy_from_user(lbuf, ubuf, cnt);
	if (rc)
		return -EFAULT;

	lbuf[cnt] = '\0';

	if (!strcmp(lb_str, "afe_loopback")) {
		rc = afe_get_parameters(lbuf, param, 3);
		if (!rc) {
			pr_info("%s %lu %lu %lu\n", lb_str, param[0], param[1],
				param[2]);

			if ((param[0] != AFE_LOOPBACK_ON) && (param[0] !=
				AFE_LOOPBACK_OFF)) {
				pr_err("%s: Error, parameter 0 incorrect\n",
					__func__);
				rc = -EINVAL;
				goto afe_error;
			}
			if ((afe_validate_port(param[1]) < 0) ||
			    (afe_validate_port(param[2])) < 0) {
				pr_err("%s: Error, invalid afe port\n",
					__func__);
			}
			if (this_afe.apr == NULL) {
				pr_err("%s: Error, AFE not opened\n", __func__);
				rc = -EINVAL;
			} else {
				rc = afe_loopback(param[0], param[1], param[2]);
			}
		} else {
			pr_err("%s: Error, invalid parameters\n", __func__);
			rc = -EINVAL;
		}

	} else if (!strcmp(lb_str, "afe_loopback_gain")) {
		rc = afe_get_parameters(lbuf, param, 2);
		if (!rc) {
			pr_info("%s %lu %lu\n", lb_str, param[0], param[1]);

			if (afe_validate_port(param[0]) < 0) {
				pr_err("%s: Error, invalid afe port\n",
					__func__);
				rc = -EINVAL;
				goto afe_error;
			}

			if (param[1] < 0 || param[1] > 100) {
				pr_err("%s: Error, volume shoud be 0 to 100"
					" percentage param = %lu\n",
					__func__, param[1]);
				rc = -EINVAL;
				goto afe_error;
			}

			param[1] = (Q6AFE_MAX_VOLUME * param[1]) / 100;

			if (this_afe.apr == NULL) {
				pr_err("%s: Error, AFE not opened\n", __func__);
				rc = -EINVAL;
			} else {
				rc = afe_loopback_gain(param[0], param[1]);
			}
		} else {
			pr_err("%s: Error, invalid parameters\n", __func__);
			rc = -EINVAL;
		}
	}

afe_error:
	if (rc == 0)
		rc = cnt;
	else
		pr_err("%s: rc = %d\n", __func__, rc);

	return rc;
}
示例#13
0
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)) {
		pr_err("%s:pass invalid dev_id\n", __func__);
		rc = PTR_ERR(dev_info);
		return rc;
	}
	pr_info("%s:device %s(%d) set %d : opened_dev(%d,%d)\n", __func__, dev_info->name, route_cfg.dev_id, set, opened_dev1, opened_dev2);

	if (set) {
		pr_info("Device %s Opened = %d\n", dev_info->name, dev_info->opened);
		if (!dev_info->opened) {
#if defined(CONFIG_USA_MODEL_SGH_T989 ) || defined(CONFIG_USA_MODEL_SGH_I727) \
   || defined(CONFIG_USA_MODEL_SGH_I757)|| defined (CONFIG_USA_MODEL_SGH_T769)\
 || defined(CONFIG_USA_MODEL_SGH_I577)
			if(!strcmp(dev_info->name, "dualmic_handset_ef_tx"))
			{
				pr_debug("%s : dualmic_enabled\n",__func__);
				dualmic_enabled = 1;
			}
#endif
			set_freq = dev_info->sample_rate;
			if (!msm_device_is_voice(route_cfg.dev_id)) {
				msm_get_voc_freq(&tx_freq, &rx_freq);
				if (dev_info->capability & SNDDEV_CAP_TX)
					set_freq = tx_freq;

				if (set_freq == 0)
					set_freq = dev_info->sample_rate;
			} else
				set_freq = dev_info->sample_rate;


			pr_err("%s:device freq =%d\n", __func__, set_freq);
			rc = dev_info->dev_ops.set_freq(dev_info, set_freq);
			if (rc < 0) {
				pr_err("%s:device freq failed!\n", __func__);
				return rc;
			}
			dev_info->set_sample_rate = rc;
			rc = 0;
			pr_info("Device trying to open : %s\n", dev_info->name);
			rc = dev_info->dev_ops.open(dev_info);
			if (rc < 0) {
/*[[Safeguard code for device open issue -START //balaji.k	
     This fix would work incase of EBUSY error when device is being opened & previous instance of device is not closed */
				if(rc == -EBUSY)
				{
				
					struct msm_snddev_info * last_dev_info = NULL;
					int closing_dev = -1;
					pr_err("DEV_BUSY: Ebusy Error %s : route_cfg.dev_id 1: %d\n",  __func__, route_cfg.dev_id);
//Closing the last active device after sending the broadcast
					if (dev_info->capability & SNDDEV_CAP_TX)
					{
						last_dev_info = audio_dev_ctrl_find_dev(last_active_tx_opened_dev);
						closing_dev = last_active_tx_opened_dev;
					}
					if (dev_info->capability & SNDDEV_CAP_RX)
					{
						last_dev_info = audio_dev_ctrl_find_dev(last_active_rx_opened_dev);
						closing_dev = last_active_rx_opened_dev;
					}

					// to fix exception error
					if (IS_ERR(last_dev_info)) {
						pr_err("last_dev:%s:pass invalid dev_id\n", __func__);
						rc = PTR_ERR(last_dev_info);
						return rc;
					}
						
					broadcast_event(AUDDEV_EVT_REL_PENDING,
						closing_dev,
						SESSION_IGNORE);
					pr_err("DEV_BUSY:closing Last active Open dev (%d)\n",  closing_dev);
					rc = dev_info->dev_ops.close(last_dev_info);
					pr_err("DEV_BUSY: %s : route_cfg.dev_id 2: %d\n", __func__, route_cfg.dev_id);
					
					if (rc < 0) {
						pr_err("DEV_BUSY  : %s:Snd device failed close!\n", __func__);
						return rc;
					}
					else
					{
					//Device close is successful, so broadcasting release event. 
						//if(opened_dev1 == route_cfg.dev_id)    // Commented these as here we are closing the previous device 
							opened_dev1 = -1;
						//else if(opened_dev2 == route_cfg.dev_id)
							opened_dev2 = -1;
						last_dev_info->opened= 0;
						broadcast_event(AUDDEV_EVT_DEV_RLS,
							closing_dev,
							SESSION_IGNORE);
					}
					
					dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
					if (IS_ERR(dev_info)) {
						pr_err("DEV_BUSY: %s:pass invalid dev_id\n", __func__);
						rc = PTR_ERR(dev_info);
						return rc;
					}

					pr_err("DEV_BUSY: Opening the Device Now %s : route_cfg.dev_id : %d\n", __func__, route_cfg.dev_id);
					
					rc = dev_info->dev_ops.open(dev_info); //Opening the intended device

					if(rc < 0)
					{
						pr_err("DEV_BUSY: %s, Device %d:Enabling %s failed\n", __func__, rc, dev_info->name);
						return rc;
					}
					else
					{
						// Maintaining the last Opened device- reqd for closing if EBUSY is encountered.
						if (dev_info->capability & SNDDEV_CAP_TX)
							last_active_tx_opened_dev = route_cfg.dev_id;
						else if(dev_info->capability & SNDDEV_CAP_RX)
							last_active_rx_opened_dev =  route_cfg.dev_id;

						printk("Last active Open Txdev (%d) and Rxdev(%d)\n", last_active_tx_opened_dev,  last_active_rx_opened_dev);
					}
				}
				else
				{
					pr_err("%s:Enabling %s failed\n",
						__func__, dev_info->name);
					return rc;
				}

			
		}
		else
		{
			 // Maintaining the last Opened device- reqd for closing if EBUSY is encountered.
			if (dev_info->capability & SNDDEV_CAP_TX)
				last_active_tx_opened_dev = route_cfg.dev_id;
			else if(dev_info->capability & SNDDEV_CAP_RX)
			 	last_active_rx_opened_dev =  route_cfg.dev_id;
			
			printk("Last active Open Txdev (%d) and Rxdev(%d)\n", last_active_tx_opened_dev,  last_active_rx_opened_dev);
		}
//Safeguard code for device open issue -END]] //balaji.k		
			if(opened_dev1 == -1)
				opened_dev1 = route_cfg.dev_id;
			else
				opened_dev2 = route_cfg.dev_id;
			pr_info("%s:open done : opened_dev(%d,%d)\n", __func__, opened_dev1, opened_dev2);

			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) {
#if defined(CONFIG_USA_MODEL_SGH_T989 ) || defined(CONFIG_USA_MODEL_SGH_I727) \
   || defined(CONFIG_USA_MODEL_SGH_I757)|| defined (CONFIG_USA_MODEL_SGH_T769) || defined (CONFIG_USA_MODEL_SGH_I577)
			if((!strcmp(dev_info->name,"dualmic_handset_ef_tx"))&&(!strcmp(dev_info->name,"handset_call_rx")))
			{			
				pr_debug("%s : dualmic_disabled\n",__func__);
				dualmic_enabled = 0;
			}
#endif
			broadcast_event(AUDDEV_EVT_REL_PENDING,
						route_cfg.dev_id,
						SESSION_IGNORE);
			printk("%s : Device trying to close : %s\n",__func__, dev_info->name);			
			rc = dev_info->dev_ops.close(dev_info);
			if (rc < 0) {
				pr_err("%s:Snd device failed close!\n",
					__func__);
				return rc;
			} else {
				if(opened_dev1 == route_cfg.dev_id)
					opened_dev1 = -1;
				else if(opened_dev2 == route_cfg.dev_id)
					opened_dev2 = -1;
				pr_info("%s:close done : opened_dev(%d,%d)\n", __func__, opened_dev1, opened_dev2);

				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;
}
示例#14
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 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;
}
示例#16
0
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)) {
		pr_err("%s:pass invalid dev_id\n", __func__);
		rc = PTR_ERR(dev_info);
		return rc;
	}
	pr_info("%s:device %s set %d\n", __func__, dev_info->name, set);

	if (set) {
		if (!dev_info->opened) {
			set_freq = dev_info->sample_rate;
			if (!msm_device_is_voice(route_cfg.dev_id)) {
				msm_get_voc_freq(&tx_freq, &rx_freq);
				if (dev_info->capability & SNDDEV_CAP_TX)
					set_freq = tx_freq;

				if (set_freq == 0)
					set_freq = dev_info->sample_rate;
			} else
				set_freq = dev_info->sample_rate;


			pr_err("%s:device freq =%d\n", __func__, set_freq);
			rc = dev_info->dev_ops.set_freq(dev_info, set_freq);
			if (rc < 0) {
				pr_err("%s:device freq failed!\n", __func__);
				return rc;
			}
			dev_info->set_sample_rate = rc;
			rc = 0;
			rc = dev_info->dev_ops.open(dev_info);
			if (rc < 0) {
				pr_err("%s:Enabling %s failed\n",
					__func__, 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;
				}
			}
#if defined(CONFIG_MFD_WM8994)
			if (configure_wm_hw(dev_info))
				pr_err("%s: Could not configure wolfson hw properly!", __func__);
#endif
		}
	} 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) {
				pr_err("%s:Snd device failed close!\n",
					__func__);
				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;
}