int msm_reset_all_device(void)
{
	int rc = 0;
	int dev_id = 0;
	struct msm_snddev_info *dev_info = NULL;

	for (dev_id = 0; dev_id < audio_dev_ctrl.num_dev; dev_id++) {
		dev_info = audio_dev_ctrl_find_dev(dev_id);
		if (IS_ERR(dev_info)) {
			MM_ERR("pass invalid dev_id %d\n", dev_id);
			rc = PTR_ERR(dev_info);
			return rc;
		}
		if (!dev_info->opened)
			continue;
		MM_DBG("Resetting device %d active on COPP %d"
			"with  0x%08x as routing\n",
			dev_id, dev_info->copp_id, dev_info->sessions);
		broadcast_event(AUDDEV_EVT_REL_PENDING,
				dev_id,
				SESSION_IGNORE);
		rc = dev_info->dev_ops.close(dev_info);
		if (rc < 0) {
			MM_ERR("Snd device %d failed close!\n", dev_id);
			return rc;
		} else {
			dev_info->opened = 0;
			broadcast_event(AUDDEV_EVT_DEV_RLS,
				        dev_id,
				        SESSION_IGNORE);
		}
		dev_info->sessions = 0;
	}
	return 0;
}
Exemple #2
0
static int pcm_route_put_rx(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int session_id = 0;
	int set = 0;
	struct msm_audio_route_config route_cfg;
	struct msm_snddev_info *dev_info;
	u64 session_mask = 0;

	/*
	 * session id is incremented by one and stored as session id 0
	 * is being used by dsp currently. whereas user space would use
	 * subdevice number as session id.
	 */
	session_id = ucontrol->value.integer.value[0];
	route_cfg.dev_id = ucontrol->value.integer.value[1];
	set = ucontrol->value.integer.value[2];

	dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
	if (IS_ERR(dev_info)) {
		pr_err("pass invalid dev_id %d\n", route_cfg.dev_id);
		return PTR_ERR(dev_info);
	}
	if (!(dev_info->capability & SNDDEV_CAP_RX))
			return -EINVAL;
	session_mask =
		(((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
			((int)AUDDEV_CLNT_DEC-1));
	if (!set) {
		session_route.playback_session[session_id][dev_info->copp_id]
			= DEVICE_IGNORE;
		broadcast_event(AUDDEV_EVT_DEV_RLS,
				route_cfg.dev_id,
				session_mask);
		dev_info->sessions &= ~(session_mask);
		return 0;
	}
	pr_debug("%s:Routing playback session %d to %s\n",
				 __func__, (session_id),
				dev_info->name);
	session_route.playback_session[session_id][dev_info->copp_id] =
							dev_info->copp_id;
	if (dev_info->opened) {
		dev_info->sessions = dev_info->sessions | session_mask;
		broadcast_event(AUDDEV_EVT_DEV_RDY,
				route_cfg.dev_id,
				session_mask);
	} else {
		broadcast_event(AUDDEV_EVT_DEV_RLS,
				route_cfg.dev_id,
				session_mask);
		dev_info->sessions &= ~(session_mask);
	}
	return 0;
}
Exemple #3
0
static int msm_v_call_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int start = ucontrol->value.integer.value[0];
	if (start)
		broadcast_event(AUDDEV_EVT_START_VOICE, DEVICE_IGNORE,
							SESSION_IGNORE);
	else
		broadcast_event(AUDDEV_EVT_END_VOICE, DEVICE_IGNORE,
							SESSION_IGNORE);
	return 0;
}
Exemple #4
0
static int msm_v_loopback_put(struct snd_kcontrol *kcontrol,
                              struct snd_ctl_elem_value *ucontrol)
{
    int start = ucontrol->value.integer.value[0];
    printk(KERN_ERR "[MyTag]msm_v_loopback_put(%d)\n", start);
    if (start)
        broadcast_event(AUDDEV_EVT_AUDIO_LP_START, DEVICE_IGNORE,
                        SESSION_IGNORE);
    else
        broadcast_event(AUDDEV_EVT_AUDIO_LP_END, DEVICE_IGNORE,
                        SESSION_IGNORE);
    return 0;
}
Exemple #5
0
static int pcm_route_put_tx(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int session_id = 0;
	int set = 0;
	struct msm_audio_route_config route_cfg;
	struct msm_snddev_info *dev_info;
	u64 session_mask = 0;

	session_id = ucontrol->value.integer.value[0];
	route_cfg.dev_id = ucontrol->value.integer.value[1];
	set = ucontrol->value.integer.value[2];

	dev_info = audio_dev_ctrl_find_dev(route_cfg.dev_id);
	if (IS_ERR(dev_info)) {
		pr_err("pass invalid dev_id %d\n", route_cfg.dev_id);
		return PTR_ERR(dev_info);
	}
	pr_debug("%s:Routing capture session %d to %s\n", __func__,
					session_id,
					dev_info->name);
	if (!(dev_info->capability & SNDDEV_CAP_TX))
			return -EINVAL;
	session_mask =
		(((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
			((int)AUDDEV_CLNT_ENC-1));
	if (!set) {
		session_route.capture_session[session_id][dev_info->copp_id]
			= DEVICE_IGNORE;
		broadcast_event(AUDDEV_EVT_DEV_RLS,
				route_cfg.dev_id,
				session_mask);
		dev_info->sessions &= ~(session_mask);
		return 0;
	}

	session_route.capture_session[session_id][dev_info->copp_id] =
							dev_info->copp_id;
	if (dev_info->opened) {
		dev_info->sessions = dev_info->sessions | session_mask;
		broadcast_event(AUDDEV_EVT_DEV_RDY,
				route_cfg.dev_id,
				session_mask);
	} else {
		broadcast_event(AUDDEV_EVT_DEV_RLS,
				route_cfg.dev_id,
				session_mask);
		dev_info->sessions &= ~(session_mask);
	}
	return 0;
}
int msm_set_voice_mute(int dir, int mute)
{
	MM_AUD_INFO("dir %x mute %x\n", dir, mute);
	if (dir == DIR_TX) {
		routing_info.tx_mute = mute;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_tx_dev_id, SESSION_IGNORE);
	} else{
		routing_info.rx_mute = mute;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_rx_dev_id, SESSION_IGNORE);
	}
	return 0;
}
Exemple #7
0
static int msm_v_call_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int start = ucontrol->value.integer.value[0];
	if (start) {
		pr_aud_info("[ALSA] msm_start_voice");
		broadcast_event(AUDDEV_EVT_START_VOICE, DEVICE_IGNORE,
							SESSION_IGNORE);
	} else {
		pr_aud_info("[ALSA] msm_end_voice");
		broadcast_event(AUDDEV_EVT_END_VOICE, DEVICE_IGNORE,
							SESSION_IGNORE);
	}
	return 0;
}
static int msm_volume_put(struct snd_kcontrol *kcontrol,
                          struct snd_ctl_elem_value *ucontrol)
{
    int ret = 0;
    int session_id = ucontrol->value.integer.value[0];
    int volume = ucontrol->value.integer.value[1];
    int factor = ucontrol->value.integer.value[2];
    u32 session_mask = 0;


    if (factor > 10000)
        return -EINVAL;

    if ((volume < 0) || (volume/factor > 100))
        return -EINVAL;

    volume = (MSM_VOLUME_STEP * volume);


    volume = volume/factor;

    if (volume > MSM_MAX_VOLUME)
        volume = MSM_MAX_VOLUME;


    session_mask = (0x1 << (session_id) << (8 * ((int)AUDDEV_CLNT_DEC-1)));
    msm_vol_ctl.volume = volume;
    MM_DBG("session_id %d, volume %d", session_id, volume);
    broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, DEVICE_IGNORE,
                    session_mask);

    return ret;
}
Exemple #9
0
static int msm_volume_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	int session_id = ucontrol->value.integer.value[0];
	int volume = ucontrol->value.integer.value[1];
	int factor = ucontrol->value.integer.value[2];
	u32 session_mask = 0;


	if (factor > 10000)
		return -EINVAL;

	if ((volume < 0) || (volume/factor > 100))
		return -EINVAL;

	volume = (MSM_VOLUME_STEP * volume);

	/* Convert back to original decimal point by removing the 10-base factor
	* and discard the fractional portion
	*/

	volume = volume/factor;

	if (volume > MSM_MAX_VOLUME)
		volume = MSM_MAX_VOLUME;

	/* Only Decoder volume control supported */
	session_mask = (0x1 << (session_id) << (8 * ((int)AUDDEV_CLNT_DEC-1)));
	msm_vol_ctl.volume = volume;
	broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, DEVICE_IGNORE,
							session_mask);

	return ret;
}
Exemple #10
0
static int msm_volume_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	int session_id = ucontrol->value.integer.value[0];
	int volume = ucontrol->value.integer.value[1];
	u32 session_mask = 0;

	pr_aud_info("[ALSA] msm_set_volume: volume %d\n", volume);
	if ((volume < 0) || (volume > 100))
		return -EINVAL;

	volume = (MSM_VOLUME_STEP * volume);

	if (volume > MSM_MAX_VOLUME)
		volume = MSM_MAX_VOLUME;

	/* Only Decoder volume control supported */
	session_mask = (0x1 << (session_id) << (8 * ((int)AUDDEV_CLNT_DEC-1)));
	msm_vol_ctl.volume = volume;
	MM_DBG("session_id %d, volume %d", session_id, volume);
	broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, DEVICE_IGNORE,
							session_mask);

	return ret;
}
int msm_set_voice_vol(int dir, s32 volume)
{
	if (dir == DIR_TX) {
		routing_info.voice_tx_vol = volume;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
					routing_info.voice_tx_dev_id,
					SESSION_IGNORE);
	} else if (dir == DIR_RX) {
		routing_info.voice_rx_vol = volume;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
					routing_info.voice_rx_dev_id,
					SESSION_IGNORE);
	} else
		return -EINVAL;
	return 0;
}
int msm_set_voice_mute(int dir, int mute)
{
	MM_AUD_INFO("dir %x mute %x\n", dir, mute);
        if (!audio_dev_ctrl.voice_rx_dev
                || !audio_dev_ctrl.voice_tx_dev)
                return -EPERM;
	if (dir == DIR_TX) {
		routing_info.tx_mute = mute;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_tx_dev_id, SESSION_IGNORE);
	} else{
		routing_info.rx_mute = mute;
		pr_aud_info("%s, rx_mute=%d\n", __func__, routing_info.rx_mute);
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_rx_dev_id, SESSION_IGNORE);
	}
	return 0;
}
Exemple #13
0
int msm_set_voice_vol(int dir, s32 volume, u32 session_id)
{

	if (!audio_dev_ctrl.voice_rx_dev
                || !audio_dev_ctrl.voice_tx_dev)
              return -EPERM;
	if (dir == DIR_TX) {
		routing_info.voice_tx_vol = volume;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
					routing_info.voice_tx_dev_id,
					session_id);
	} else if (dir == DIR_RX) {
		routing_info.voice_rx_vol = volume;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
					routing_info.voice_rx_dev_id,
					session_id);
	} else
		return -EINVAL;
	return 0;
}
int msm_set_voice_mute(int dir, int mute, u32 session_id)
{
	pr_debug("dir %x mute %x\n", dir, mute);
	if (dir == DIR_TX) {
		routing_info.tx_mute = mute;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_tx_dev_id, session_id);
	} else
		return -EPERM;
	return 0;
}
int msm_set_voice_vol(int dir, s32 volume)
{
#ifdef CONFIG_2WCR
        if (!audio_dev_ctrl.voice_rx_dev
                || !audio_dev_ctrl.voice_tx_dev)
                return -EPERM;
#endif
	if (dir == DIR_TX) {
		routing_info.voice_tx_vol = volume;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
					routing_info.voice_tx_dev_id,
					SESSION_IGNORE);
	} else if (dir == DIR_RX) {
		routing_info.voice_rx_vol = volume;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
					routing_info.voice_rx_dev_id,
					SESSION_IGNORE);
	} else
		return -EINVAL;
	return 0;
}
Exemple #16
0
static int msm_v_call_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int start = ucontrol->value.integer.value[0];
	u32 session_id = ucontrol->value.integer.value[1];

	if ((session_id != 0) &&
	    ((session_id < SESSION_ID_BASE) ||
	     (session_id >= SESSION_ID_BASE + MAX_VOC_SESSIONS))) {
		pr_err("%s: Invalid session_id 0x%x\n", __func__, session_id);

		return -EINVAL;
	}

	if (start)
		broadcast_event(AUDDEV_EVT_START_VOICE, DEVICE_IGNORE,
							session_id);
	else
		broadcast_event(AUDDEV_EVT_END_VOICE, DEVICE_IGNORE,
							session_id);
	return 0;
}
int msm_reset_all_device(void)
{
	int rc = 0;
	int dev_id = 0;
	struct msm_snddev_info *dev_info = NULL;

	for (dev_id = 0; dev_id < audio_dev_ctrl.num_dev; dev_id++) {
		dev_info = audio_dev_ctrl_find_dev(dev_id);
		if (IS_ERR(dev_info)) {
			pr_err("%s:pass invalid dev_id\n", __func__);
			rc = PTR_ERR(dev_info);
			return rc;
		}
		if (!dev_info->opened)
			continue;
		pr_debug("%s:Resetting device %d active on COPP %d"
			"with  %lld as routing\n", __func__,
				dev_id, dev_info->copp_id, dev_info->sessions);
		broadcast_event(AUDDEV_EVT_REL_PENDING,
					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,
				dev_id,
				SESSION_IGNORE);

			if (dev_info->copp_id == VOICE_PLAYBACK_TX)
				voice_start_playback(0);
		}
		dev_info->sessions = 0;
	}
	msm_clear_all_session();
	return 0;
}
int msm_set_voice_mute(int dir, int mute)
{
	MM_DBG("dir %x mute %x\n", dir, mute);
	if (!audio_dev_ctrl.voice_rx_dev
		|| !audio_dev_ctrl.voice_tx_dev)
		return -EPERM;
	if (dir == DIR_TX) {
		routing_info.tx_mute = mute;
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG,
			routing_info.voice_tx_dev_id, SESSION_IGNORE);
	} else
		return -EPERM;
	return 0;
}
void mixer_post_event(u32 evt_id, u32 id)
{

	MM_DBG("evt_id = %d\n", evt_id);
	switch (evt_id) {
	case AUDDEV_EVT_DEV_CHG_VOICE: /* Called from Voice_route */
		broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, id, SESSION_IGNORE);
		break;
	case AUDDEV_EVT_DEV_RDY:
		broadcast_event(AUDDEV_EVT_DEV_RDY, id, SESSION_IGNORE);
		break;
	case AUDDEV_EVT_DEV_RLS:
		broadcast_event(AUDDEV_EVT_DEV_RLS, id, SESSION_IGNORE);
		break;
	case AUDDEV_EVT_REL_PENDING:
		broadcast_event(AUDDEV_EVT_REL_PENDING, id, SESSION_IGNORE);
		break;
	case AUDDEV_EVT_DEVICE_VOL_MUTE_CHG:
		broadcast_event(AUDDEV_EVT_DEVICE_VOL_MUTE_CHG, id,
							SESSION_IGNORE);
		break;
	case AUDDEV_EVT_STREAM_VOL_CHG:
		broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, id,
							SESSION_IGNORE);
		break;
	case AUDDEV_EVT_START_VOICE:
		broadcast_event(AUDDEV_EVT_START_VOICE,
				id, SESSION_IGNORE);
		break;
	case AUDDEV_EVT_END_VOICE:
		broadcast_event(AUDDEV_EVT_END_VOICE,
				id, SESSION_IGNORE);
		break;
	case AUDDEV_EVT_FREQ_CHG:
		broadcast_event(AUDDEV_EVT_FREQ_CHG, id, SESSION_IGNORE);
		break;
	default:
		break;
	}
}
static int msm_volume_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int ret = 0;
	int session_id = ucontrol->value.integer.value[0];
	int volume = ucontrol->value.integer.value[1];
	int factor = ucontrol->value.integer.value[2];
	u64 session_mask = 0;

	pr_aud_info("[ALSA] msm_set_volume: volume %d\n", volume);
	if (factor > 10000)
		return -EINVAL;

	if ((volume < 0) || (volume/factor > 100))
		return -EINVAL;

	volume = (MSM_VOLUME_STEP * volume);

	/* Convert back to original decimal point by removing the 10-base factor
	* and discard the fractional portion
	*/

	volume = volume/factor;

	if (volume > MSM_MAX_VOLUME)
		volume = MSM_MAX_VOLUME;

	/* Only Decoder volume control supported */
	session_mask = (((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
				((int)AUDDEV_CLNT_DEC-1));
	msm_vol_ctl.volume = volume;
	MM_DBG("session_id %d, volume %d", session_id, volume);
	broadcast_event(AUDDEV_EVT_STREAM_VOL_CHG, DEVICE_IGNORE,
							session_mask);

	return ret;
}
Exemple #21
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;
}
Exemple #22
0
static int msm_route_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	int enc_freq = 0;
	int requested_freq = 0;
	struct msm_audio_route_config route_cfg;
	struct msm_snddev_info *dev_info;
	int session_id = ucontrol->value.integer.value[0];
	int set = ucontrol->value.integer.value[2];
	u32 session_mask = 0;
	route_cfg.dev_id = ucontrol->value.integer.value[1];

	pr_aud_info("[ALSA] msm_route_stream: session %d, dev %d, enable %d\n",
		session_id, route_cfg.dev_id, set);
	if (ucontrol->id.numid == 2)
		route_cfg.stream_type =	AUDIO_ROUTE_STREAM_PLAYBACK;
	else
		route_cfg.stream_type =	AUDIO_ROUTE_STREAM_REC;

	MM_DBG("route cfg %d %d type for popp %d\n",
		route_cfg.dev_id, route_cfg.stream_type, session_id);
	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;
	}
	if (route_cfg.stream_type == AUDIO_ROUTE_STREAM_PLAYBACK) {
		rc = msm_snddev_set_dec(session_id, dev_info->copp_id, set);
		session_mask =
			(0x1 << (session_id) << (8 * ((int)AUDDEV_CLNT_DEC-1)));
		if (!set) {
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RLS,
							route_cfg.dev_id,
							session_mask);
			dev_info->sessions &= ~(session_mask);
		} else {
			dev_info->sessions = dev_info->sessions | session_mask;
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RDY,
							route_cfg.dev_id,
							session_mask);
		}
	} else {
		rc = msm_snddev_set_enc(session_id, dev_info->copp_id, set);
		session_mask =
			(0x1 << (session_id)) << (8 * ((int)AUDDEV_CLNT_ENC-1));
		if (!set) {
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RLS,
							route_cfg.dev_id,
							session_mask);
			dev_info->sessions &= ~(session_mask);
		} else {
			dev_info->sessions = dev_info->sessions | session_mask;
			enc_freq = msm_snddev_get_enc_freq(session_id);
			requested_freq = enc_freq;
			if (enc_freq > 0) {
				rc = msm_snddev_request_freq(&enc_freq,
						session_id,
						SNDDEV_CAP_TX,
						AUDDEV_CLNT_ENC);
				MM_DBG("sample rate configured %d"
					"sample rate requested %d \n",
					enc_freq, requested_freq);
				if ((rc <= 0) || (enc_freq != requested_freq)) {
					MM_DBG("msm_snddev_withdraw_freq\n");
					rc = msm_snddev_withdraw_freq
						(session_id,
						SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
					broadcast_event(AUDDEV_EVT_FREQ_CHG,
							route_cfg.dev_id,
							SESSION_IGNORE);
				}
			}
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RDY,
							route_cfg.dev_id,
							session_mask);
		}
	}

	if (rc < 0) {
		MM_AUD_ERR("device could not be assigned!\n");
		return -EFAULT;
	}

	return rc;
}
Exemple #23
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;
	int tx_freq = 0;
	int rx_freq = 0;
	u32 set_freq = 0;
	int retry = 3;

	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_AUD_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_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;


			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;
			do{
				rc = dev_info->dev_ops.open(dev_info);
				retry--;
			} while (rc < 0 && retry);

			if (rc < 0) {
				MM_AUD_ERR("Enabling %s failed, rc=%d\n", dev_info->name, rc);
				return rc;
			}
			dev_info->opened = 1;
			pr_aud_info("set device %s opened as %d\n",
				dev_info->name, dev_info->opened);
			broadcast_event(AUDDEV_EVT_DEV_RDY, route_cfg.dev_id,
							SESSION_IGNORE);
		}
	} 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;
				pr_aud_info("set device %s opened as %d\n",
					dev_info->name, dev_info->opened);
				broadcast_event(AUDDEV_EVT_DEV_RLS,
					route_cfg.dev_id,
					SESSION_IGNORE);
			}
		}

	}
	return rc;
}
Exemple #24
0
static int msm_voice_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	uint32_t rx_dev_id;
	uint32_t tx_dev_id;
	struct msm_snddev_info *rx_dev_info;
	struct msm_snddev_info *tx_dev_info;
	int set = ucontrol->value.integer.value[2];
	u32 session_mask;

	int i = 0, j = 0;
	struct snddev_icodec_state *icodec;
	struct adie_codec_hwsetting_entry *rx_entry;
	struct adie_codec_hwsetting_entry *tx_entry;
	struct timespec ts;
	struct rtc_time tm;

	/* if (!set)
		return -EPERM; */

	pr_aud_info("[ALSA] msm_route_voice: "
		"tx %d, rx %d, set %d\n",
		(int) ucontrol->value.integer.value[1],
		(int) ucontrol->value.integer.value[0],
		set);

	if (set) {
		getnstimeofday(&ts);
		rtc_time_to_tm(ts.tv_sec, &tm);
		pr_aud_info1("[ATS][phonecall_start][successful] at %lld (%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
		ktime_to_ns(ktime_get()),
		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
		tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
	} else {
		getnstimeofday(&ts);
		rtc_time_to_tm(ts.tv_sec, &tm);
		pr_aud_info1("[ATS][phonecall_end][successful] at %lld (%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
		ktime_to_ns(ktime_get()),
		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
		tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
	}

	/* Rx Device Routing */
	rx_dev_id = ucontrol->value.integer.value[0];
	rx_dev_info = audio_dev_ctrl_find_dev(rx_dev_id);

	if (IS_ERR(rx_dev_info)) {
		MM_AUD_ERR("pass invalid dev_id\n");
		rc = PTR_ERR(rx_dev_info);
		return rc;
	}

	if (!(rx_dev_info->capability & SNDDEV_CAP_RX)) {
		MM_AUD_ERR("First Dev is supposed to be RX\n");
		return -EFAULT;
	}

	MM_DBG("route cfg %d STREAM_VOICE_RX type\n",
		rx_dev_id);

	/* replace with Rx voice/media setting for adie */
	if (rx_dev_info->acdb_id != 10 &&
	    (rx_dev_info->acdb_id < 1000)) {
	    icodec = (struct snddev_icodec_state *)rx_dev_info->private_data;
	    rx_entry = icodec->data->profile->settings;
	    j = icodec->data->profile->setting_sz;
	    if (set) {
		for (i = 0; i < j; i++)
		    if (rx_entry[i].voc_action != NULL) {
			rx_entry[i].actions = rx_entry[i].voc_action;
			rx_entry[i].action_sz = rx_entry[i].voc_action_sz;
		    }
	    } else {
		for (i = 0; i < j; i++)
		    if (rx_entry[i].midi_action != NULL) {
			rx_entry[i].actions = rx_entry[i].midi_action;
			rx_entry[i].action_sz = rx_entry[i].midi_action_sz;
		    }
	    }
	}

	msm_set_voc_route(rx_dev_info, AUDIO_ROUTE_STREAM_VOICE_RX,
				rx_dev_id);

	session_mask =	0x1 << (8 * ((int)AUDDEV_CLNT_VOC-1));

	/* Tx Device Routing */
	tx_dev_id = ucontrol->value.integer.value[1];
	tx_dev_info = audio_dev_ctrl_find_dev(tx_dev_id);

	if (IS_ERR(tx_dev_info)) {
		MM_AUD_ERR("pass invalid dev_id\n");
		rc = PTR_ERR(tx_dev_info);
		return rc;
	}

	if (!(tx_dev_info->capability & SNDDEV_CAP_TX)) {
		MM_AUD_ERR("Second Dev is supposed to be Tx\n");
		return -EFAULT;
	}

	MM_DBG("route cfg %d %d type\n",
		tx_dev_id, AUDIO_ROUTE_STREAM_VOICE_TX);
	/* replace with Tx voice/media setting for adie */
	if (tx_dev_info->acdb_id != 9 &&
	    (tx_dev_info->acdb_id < 1000)) {
	    icodec = (struct snddev_icodec_state *)tx_dev_info->private_data;
	    tx_entry = icodec->data->profile->settings;
	    j = icodec->data->profile->setting_sz;
	    if (set) {
		for (i = 0; i < j; i++)
		    if (tx_entry[i].voc_action != NULL) {
			tx_entry[i].actions = tx_entry[i].voc_action;
			tx_entry[i].action_sz = tx_entry[i].voc_action_sz;
		    }
	    } else {
		for (i = 0; i < j; i++)
		    if (tx_entry[i].midi_action != NULL) {
			tx_entry[i].actions = tx_entry[i].midi_action;
			tx_entry[i].action_sz = tx_entry[i].midi_action_sz;
		    }
	    }
	}
	msm_set_voc_route(tx_dev_info, AUDIO_ROUTE_STREAM_VOICE_TX,
				tx_dev_id);

	broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, tx_dev_id, session_mask);

	if (set) {
	if (rx_dev_info->opened)
		broadcast_event(AUDDEV_EVT_DEV_RDY, rx_dev_id,	session_mask);

	if (tx_dev_info->opened)
		broadcast_event(AUDDEV_EVT_DEV_RDY, tx_dev_id, session_mask);
	}

	return rc;
}
int msm_snddev_request_freq(int *freq, u32 session_id,
			u32 capability, u32 clnt_type)
{
	int i = 0;
	int rc = 0;
	struct msm_snddev_info *info;
	u32 set_freq;
	u64 session_mask = 0;
	u64 clnt_type_mask = 0;

	pr_debug(": clnt_type 0x%08x\n", clnt_type);

	if ((clnt_type == AUDDEV_CLNT_VOC) && (session_id != 0))
		return -EINVAL;
	if ((clnt_type == AUDDEV_CLNT_DEC)
			&& (session_id >= MAX_SESSIONS))
		return -EINVAL;
	if ((clnt_type == AUDDEV_CLNT_ENC)
			&& (session_id >= MAX_SESSIONS))
		return -EINVAL;
	session_mask = (((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
				((int)clnt_type-1));
	clnt_type_mask = (0xFFFF << (MAX_BIT_PER_CLIENT * (clnt_type-1)));
	if (!(*freq == 8000) && !(*freq == 11025) &&
		!(*freq == 12000) && !(*freq == 16000) &&
		!(*freq == 22050) && !(*freq == 24000) &&
		!(*freq == 32000) && !(*freq == 44100) &&
		!(*freq == 48000))
		return -EINVAL;

	for (i = 0; i < audio_dev_ctrl.num_dev; i++) {
		info = audio_dev_ctrl.devs[i];
		if ((info->sessions & session_mask)
			&& (info->capability & capability)) {
			rc = 0;
			if ((info->sessions & ~clnt_type_mask)
				&& ((*freq != 8000) && (*freq != 16000)
					&& (*freq != 48000))) {
				if (clnt_type == AUDDEV_CLNT_ENC) {
					routing_info.enc_freq[session_id].freq
							= 0;
					return -EPERM;
				} else if (clnt_type == AUDDEV_CLNT_DEC) {
					routing_info.dec_freq[session_id].freq
							= 0;
					return -EPERM;
				}
			}
			if (*freq == info->set_sample_rate) {
				rc = info->set_sample_rate;
				continue;
			}
			set_freq = MAX(*freq, info->set_sample_rate);


			if (clnt_type == AUDDEV_CLNT_DEC) {
				routing_info.dec_freq[session_id].evt = 1;
				routing_info.dec_freq[session_id].freq
						= set_freq;
			} else if (clnt_type == AUDDEV_CLNT_ENC) {
				routing_info.enc_freq[session_id].evt = 1;
				routing_info.enc_freq[session_id].freq
						= set_freq;
			} else if (capability == SNDDEV_CAP_TX)
				routing_info.voice_tx_sample_rate = set_freq;

			rc = set_freq;
			info->set_sample_rate = set_freq;
			*freq = info->set_sample_rate;

			if (info->opened) {
				broadcast_event(AUDDEV_EVT_FREQ_CHG, i,
							SESSION_IGNORE);
				set_freq = info->dev_ops.set_freq(info,
								set_freq);
				broadcast_event(AUDDEV_EVT_DEV_RDY, i,
							SESSION_IGNORE);
			}
		}
		pr_debug("info->set_sample_rate = %d\n", info->set_sample_rate);
		pr_debug("routing_info.enc_freq.freq = %d\n",
					routing_info.enc_freq[session_id].freq);
	}
	return rc;
}
Exemple #26
0
static int msm_voice_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	uint32_t rx_dev_id;
	uint32_t tx_dev_id;
	struct msm_snddev_info *rx_dev_info;
	struct msm_snddev_info *tx_dev_info;
	int set = ucontrol->value.integer.value[2];
	u64 session_mask;

	if (!set)
		return -EPERM;
	/* Rx Device Routing */
	rx_dev_id = ucontrol->value.integer.value[0];
	rx_dev_info = audio_dev_ctrl_find_dev(rx_dev_id);

	if (IS_ERR(rx_dev_info)) {
		pr_err("%s:pass invalid dev_id\n", __func__);
		rc = PTR_ERR(rx_dev_info);
		return rc;
	}

	if (!(rx_dev_info->capability & SNDDEV_CAP_RX)) {
		pr_err("%s:First Dev is supposed to be RX\n", __func__);
		return -EFAULT;
	}

	pr_debug("%s:route cfg %d STREAM_VOICE_RX type\n",
		__func__, rx_dev_id);

	msm_set_voc_route(rx_dev_info, AUDIO_ROUTE_STREAM_VOICE_RX,
				rx_dev_id);

	session_mask =	((u64)0x1) << (MAX_BIT_PER_CLIENT * \
				((int)AUDDEV_CLNT_VOC-1));

	broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, rx_dev_id, session_mask);


	/* Tx Device Routing */
	tx_dev_id = ucontrol->value.integer.value[1];
	tx_dev_info = audio_dev_ctrl_find_dev(tx_dev_id);

	if (IS_ERR(tx_dev_info)) {
		pr_err("%s:pass invalid dev_id\n", __func__);
		rc = PTR_ERR(tx_dev_info);
		return rc;
	}

	if (!(tx_dev_info->capability & SNDDEV_CAP_TX)) {
		pr_err("%s:Second Dev is supposed to be Tx\n", __func__);
		return -EFAULT;
	}

	pr_debug("%s:route cfg %d %d type\n",
		__func__, tx_dev_id, AUDIO_ROUTE_STREAM_VOICE_TX);

	msm_set_voc_route(tx_dev_info, AUDIO_ROUTE_STREAM_VOICE_TX,
				tx_dev_id);

	broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, tx_dev_id, session_mask);

	if (rx_dev_info->opened)
		broadcast_event(AUDDEV_EVT_DEV_RDY, rx_dev_id,	session_mask);

	if (tx_dev_info->opened)
		broadcast_event(AUDDEV_EVT_DEV_RDY, tx_dev_id, session_mask);

	return rc;
}
Exemple #27
0
static int msm_route_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	int enc_freq = 0;
	int requested_freq = 0;
	struct msm_audio_route_config route_cfg;
	struct msm_snddev_info *dev_info;
	int session_id = ucontrol->value.integer.value[0];
	int set = ucontrol->value.integer.value[2];
	u64 session_mask = 0;
	route_cfg.dev_id = ucontrol->value.integer.value[1];

	if (ucontrol->id.numid == 2)
		route_cfg.stream_type =	AUDIO_ROUTE_STREAM_PLAYBACK;
	else
		route_cfg.stream_type =	AUDIO_ROUTE_STREAM_REC;

	pr_debug("%s:route cfg %d %d type for popp %d\n",
		__func__, route_cfg.dev_id, route_cfg.stream_type, session_id);
	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;
	}
	if (route_cfg.stream_type == AUDIO_ROUTE_STREAM_PLAYBACK) {
		rc = msm_snddev_set_dec(session_id, dev_info->copp_id, set,
				dev_info->sample_rate, dev_info->channel_mode);
		session_mask =
			(((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
				((int)AUDDEV_CLNT_DEC-1));
		if (!set) {
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RLS,
							route_cfg.dev_id,
							session_mask);
			dev_info->sessions &= ~(session_mask);
		} else {
			dev_info->sessions = dev_info->sessions | session_mask;
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RDY,
							route_cfg.dev_id,
							session_mask);
		}
	} else {

		rc = msm_snddev_set_enc(session_id, dev_info->copp_id, set,
				dev_info->sample_rate, dev_info->channel_mode);
		session_mask =
			(((u64)0x1) << session_id) << (MAX_BIT_PER_CLIENT * \
			((int)AUDDEV_CLNT_ENC-1));
		if (!set) {
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RLS,
							route_cfg.dev_id,
							session_mask);
			dev_info->sessions &= ~(session_mask);
		} else {
			dev_info->sessions = dev_info->sessions | session_mask;
			enc_freq = msm_snddev_get_enc_freq(session_id);
			requested_freq = enc_freq;
			if (enc_freq > 0) {
				rc = msm_snddev_request_freq(&enc_freq,
						session_id,
						SNDDEV_CAP_TX,
						AUDDEV_CLNT_ENC);
				pr_debug("%s:sample rate configured %d\
					sample rate requested %d \n",
					__func__, enc_freq, requested_freq);
				if ((rc <= 0) || (enc_freq != requested_freq)) {
					pr_debug("%s:msm_snddev_withdraw_freq\n",
						__func__);
					rc = msm_snddev_withdraw_freq
						(session_id,
						SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
					broadcast_event(AUDDEV_EVT_FREQ_CHG,
							route_cfg.dev_id,
							SESSION_IGNORE);
				}
			}
			if (dev_info->opened)
				broadcast_event(AUDDEV_EVT_DEV_RDY,
							route_cfg.dev_id,
							session_mask);
		}
	}

	if (rc < 0) {
		pr_err("%s:device could not be assigned!\n", __func__);
		return -EFAULT;
	}

	return rc;
}
static int msm_voice_put(struct snd_kcontrol *kcontrol,
			struct snd_ctl_elem_value *ucontrol)
{
	int rc = 0;
	uint32_t rx_dev_id;
	uint32_t tx_dev_id;
	struct msm_snddev_info *rx_dev_info;
	struct msm_snddev_info *tx_dev_info;
	int set = ucontrol->value.integer.value[2];
	u64 session_mask;

	int i = 0, j = 0;
	struct snddev_icodec_state *icodec;
	struct adie_codec_hwsetting_entry *rx_entry;
	struct adie_codec_hwsetting_entry *tx_entry;

	/* if (!set)
		return -EPERM; */

	pr_aud_info("[ALSA] msm_route_voice: "
		"tx %d, rx %d, set %d\n",
		(int) ucontrol->value.integer.value[1],
		(int) ucontrol->value.integer.value[0],
		set);
	/* Rx Device Routing */
	rx_dev_id = ucontrol->value.integer.value[0];
	rx_dev_info = audio_dev_ctrl_find_dev(rx_dev_id);

	if (IS_ERR(rx_dev_info)) {
		MM_AUD_ERR("pass invalid dev_id\n");
		rc = PTR_ERR(rx_dev_info);
		return rc;
	}

	if (!(rx_dev_info->capability & SNDDEV_CAP_RX)) {
		MM_AUD_ERR("First Dev is supposed to be RX\n");
		return -EFAULT;
	}

	MM_DBG("route cfg %d STREAM_VOICE_RX type\n",
		rx_dev_id);

	/* replace with Rx voice/media setting for adie */
	/* only for internal codec */
	if (rx_dev_info->copp_id == PRIMARY_I2S_RX) {
		icodec = (struct snddev_icodec_state *)rx_dev_info->private_data;
		rx_entry = icodec->data->profile->settings;
		j = icodec->data->profile->setting_sz;
		if (set) {
			for (i = 0; i < j; i++)
				if (rx_entry[i].voc_action != NULL) {
					rx_entry[i].actions = rx_entry[i].voc_action;
					rx_entry[i].action_sz = rx_entry[i].voc_action_sz;
			}
		} else {
			for (i = 0; i < j; i++)
				if (rx_entry[i].midi_action != NULL) {
					rx_entry[i].actions = rx_entry[i].midi_action;
					rx_entry[i].action_sz = rx_entry[i].midi_action_sz;
				}
		}
	}

	msm_set_voc_route(rx_dev_info, AUDIO_ROUTE_STREAM_VOICE_RX,
				rx_dev_id);

	session_mask =	((u64)0x1) << (MAX_BIT_PER_CLIENT * \
				((int)AUDDEV_CLNT_VOC-1));

	broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, rx_dev_id, session_mask);


	/* Tx Device Routing */
	tx_dev_id = ucontrol->value.integer.value[1];
	tx_dev_info = audio_dev_ctrl_find_dev(tx_dev_id);

	if (IS_ERR(tx_dev_info)) {
		MM_AUD_ERR("pass invalid dev_id\n");
		rc = PTR_ERR(tx_dev_info);
		return rc;
	}

	if (!(tx_dev_info->capability & SNDDEV_CAP_TX)) {
		MM_AUD_ERR("Second Dev is supposed to be Tx\n");
		return -EFAULT;
	}

	MM_DBG("route cfg %d %d type\n",
		tx_dev_id, AUDIO_ROUTE_STREAM_VOICE_TX);

	/* replace with Tx voice/media setting for adie */
	/* only for internal codec */
	if (tx_dev_info->copp_id == PRIMARY_I2S_TX) {
		icodec = (struct snddev_icodec_state *)tx_dev_info->private_data;
		tx_entry = icodec->data->profile->settings;
		j = icodec->data->profile->setting_sz;
		if (set) {
			for (i = 0; i < j; i++)
				if (tx_entry[i].voc_action != NULL) {
					tx_entry[i].actions = tx_entry[i].voc_action;
					tx_entry[i].action_sz = tx_entry[i].voc_action_sz;
				}
		} else {
			for (i = 0; i < j; i++)
				if (tx_entry[i].midi_action != NULL) {
					tx_entry[i].actions = tx_entry[i].midi_action;
					tx_entry[i].action_sz = tx_entry[i].midi_action_sz;
				}
		}
	}

	msm_set_voc_route(tx_dev_info, AUDIO_ROUTE_STREAM_VOICE_TX,
				tx_dev_id);

	broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, tx_dev_id, session_mask);

	if (set) {
		if (rx_dev_info->opened)
			broadcast_event(AUDDEV_EVT_DEV_RDY, rx_dev_id,	session_mask);

		if (tx_dev_info->opened)
			broadcast_event(AUDDEV_EVT_DEV_RDY, tx_dev_id, session_mask);
	}

	return rc;
}
static int voice_thread(void *data)
{
    struct voice_data *v = (struct voice_data *)data;
    int rc = 0;

    MM_INFO("voice_thread() start\n");

    while (!kthread_should_stop()) {
        wait_for_completion(&v->complete);
        init_completion(&v->complete);

        MM_DBG(" voc_event=%d, voice state =%d, dev_event=%d\n",
               v->voc_event, v->voc_state, v->dev_event);
        switch (v->voc_event) {
        case VOICE_ACQUIRE_START:
            /* check if dev_state = READY */
            /* if ready, send device_info and acquire_done */
            /* if not ready, block to wait the dev_state = READY */
            if ((v->voc_state == VOICE_INIT) ||
                    (v->voc_state == VOICE_RELEASE)) {
                if (v->dev_state == DEV_READY) {
                    mutex_lock(&voice.voc_lock);
                    voice_change_sample_rate(v);
                    rc = voice_cmd_device_info(v);
                    rc = voice_cmd_acquire_done(v);
                    v->voc_state = VOICE_ACQUIRE;
                    mutex_unlock(&voice.voc_lock);
                    broadcast_event(
                        AUDDEV_EVT_VOICE_STATE_CHG,
                        VOICE_STATE_INCALL, SESSION_IGNORE);
                } else {
                    rc = wait_event_interruptible(
                             v->dev_wait,
                             (v->dev_state == DEV_READY)
                             || (atomic_read(&v->rel_start_flag)
                                 == 1));
                    if (atomic_read(&v->rel_start_flag)
                            == 1) {
                        v->voc_state = VOICE_RELEASE;
                        atomic_dec(&v->rel_start_flag);
                        msm_snddev_withdraw_freq(0,
                                                 SNDDEV_CAP_TX, AUDDEV_CLNT_VOC);
                        broadcast_event(
                            AUDDEV_EVT_VOICE_STATE_CHG,
                            VOICE_STATE_OFFCALL,
                            SESSION_IGNORE);
                    } else {
                        mutex_lock(&voice.voc_lock);
                        voice_change_sample_rate(v);
                        rc = voice_cmd_device_info(v);
                        rc = voice_cmd_acquire_done(v);
                        v->voc_state = VOICE_ACQUIRE;
                        mutex_unlock(&voice.voc_lock);
                        broadcast_event(
                            AUDDEV_EVT_VOICE_STATE_CHG,
                            VOICE_STATE_INCALL,
                            SESSION_IGNORE);
                    }
                }
            } else
                MM_ERR("Get this event at the wrong state\n");
            if (atomic_read(&v->acq_start_flag))
                atomic_dec(&v->acq_start_flag);
            break;
        case VOICE_RELEASE_START:
            MM_DBG("broadcast voice call end\n");
            broadcast_event(AUDDEV_EVT_VOICE_STATE_CHG,
                            VOICE_STATE_OFFCALL, SESSION_IGNORE);
            if ((v->dev_state == DEV_REL_DONE) ||
                    (v->dev_state == DEV_INIT)) {
                v->voc_state = VOICE_RELEASE;
                msm_snddev_withdraw_freq(0, SNDDEV_CAP_TX,
                                         AUDDEV_CLNT_VOC);
            } else {
                /* wait for the dev_state = RELEASE */
                rc = wait_event_interruptible(v->dev_wait,
                                              (v->dev_state == DEV_REL_DONE)
                                              || (atomic_read(&v->acq_start_flag) == 1));
                if (atomic_read(&v->acq_start_flag) == 1)
                    atomic_dec(&v->acq_start_flag);
                v->voc_state = VOICE_RELEASE;
                msm_snddev_withdraw_freq(0, SNDDEV_CAP_TX,
                                         AUDDEV_CLNT_VOC);
            }
            if (atomic_read(&v->rel_start_flag))
                atomic_dec(&v->rel_start_flag);
            break;
        case VOICE_CHANGE_START:
            if (v->voc_state == VOICE_ACQUIRE)
                v->voc_state = VOICE_CHANGE;
            else
                MM_ERR("Get this event at the wrong state\n");
            wake_up(&v->voc_wait);
            if (atomic_read(&v->chg_start_flag))
                atomic_dec(&v->chg_start_flag);
            break;
        case VOICE_NETWORK_RECONFIG:
            if ((v->voc_state == VOICE_ACQUIRE)
                    || (v->voc_state == VOICE_CHANGE)) {
                voice_change_sample_rate(v);
                rc = voice_cmd_device_info(v);
                rc = voice_cmd_acquire_done(v);
            }
            break;
        default:
            break;
        }

        switch (v->dev_event) {
        case DEV_CHANGE_READY:
            if (v->voc_state == VOICE_CHANGE) {
                mutex_lock(&voice.voc_lock);
                msm_snddev_enable_sidetone(v->dev_rx.dev_id,
                                           1);
                /* update voice state */
                v->voc_state = VOICE_ACQUIRE;
                v->dev_event = 0;
                mutex_unlock(&voice.voc_lock);
                broadcast_event(AUDDEV_EVT_VOICE_STATE_CHG,
                                VOICE_STATE_INCALL, SESSION_IGNORE);
            } else {
                mutex_lock(&voice.voc_lock);
                v->dev_event = 0;
                mutex_unlock(&voice.voc_lock);
                MM_ERR("Get this event at the wrong state\n");
            }
            break;
        default:
            mutex_lock(&voice.voc_lock);
            v->dev_event = 0;
            mutex_unlock(&voice.voc_lock);
            break;
        }
    }
    return 0;
}
Exemple #30
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)) {
        MM_ERR("pass invalid dev_id\n");
        rc = PTR_ERR(dev_info);
        return rc;
    }
    MM_INFO("device %s set %d\n", 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;


            MM_ERR("device freq =%d\n", set_freq);
            rc = dev_info->dev_ops.set_freq(dev_info, set_freq);
            if (rc < 0) {
                MM_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_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);
            /* Event to notify client for device info */
            broadcast_event(AUDDEV_EVT_DEVICE_INFO,
                            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_ext_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_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("dst_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_ext_loopback(LOOPBACK_DISABLE,
                                     dst_dev_info->copp_id,
                                     src_dev_info->copp_id);
                    loopback_status = 0;
                }
            }
        }

    }
    return rc;
}