static int msm_pcm_prepare(struct snd_pcm_substream *substream)
{
	int ret = 0;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct msm_voice *prtd = runtime->private_data;
	uint16_t session_id = 0;

	mutex_lock(&prtd->lock);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		ret = msm_pcm_playback_prepare(substream);
	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
		ret = msm_pcm_capture_prepare(substream);

	if (prtd->playback_start && prtd->capture_start) {
		if (is_volte(prtd))
			session_id = voc_get_session_id(VOLTE_SESSION_NAME);
		else if (is_voice2(prtd))
			session_id = voc_get_session_id(VOICE2_SESSION_NAME);
		else
			session_id = voc_get_session_id(VOICE_SESSION_NAME);
		voc_start_voice_call(session_id);
	}
	mutex_unlock(&prtd->lock);

	return ret;
}
Exemplo n.º 2
0
static int msm_pcm_prepare(struct snd_pcm_substream *substream)
{
    int ret = 0;
    struct snd_pcm_runtime *runtime = substream->runtime;
    struct msm_voice *prtd = runtime->private_data;

    mutex_lock(&prtd->lock);

    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
        ret = msm_pcm_playback_prepare(substream);
    else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
        ret = msm_pcm_capture_prepare(substream);

    if (prtd->playback_start && prtd->capture_start)
        voc_start_voice_call();

    mutex_unlock(&prtd->lock);

    return ret;
}
static long sky_direct_adsp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    unsigned long flags;
    void __user *argp = (void __user *)arg;

  	int ret = 0;
	int32_t media_type = 0;
	uint32_t rate_type = 0;
    uint32_t evrc_min_rate_type = 0;
	uint32_t evrc_max_rate_type = 0;

 	SKY_DIRECT_ADSP_DBG_HIGH("sky_direct_adsp_ioctl cmd:%d, arg:%ld ", cmd, arg);

    mutex_lock(&voip_info.lock);

    if(_IOC_TYPE(cmd) != IOCTL_SKY_DIRECT_ADSP_MAGIC)
    {
        SKY_DIRECT_ADSP_ERR("[%s] invalid Magic Char [%c]\n", __func__, _IOC_TYPE(cmd));
        mutex_unlock(&voip_info.lock);
        return -EINVAL;
    }
    
    if(_IOC_NR(cmd) >= IOCTL_SKY_DIRECT_ADSP_MAXNR)
    {
        SKY_DIRECT_ADSP_ERR("[%s] invalid Magic Char [%c]\n", __func__, _IOC_TYPE(cmd));
        mutex_unlock(&voip_info.lock);
        return -EINVAL;
    }

    switch(cmd)
    {
        case IOCTL_SKY_DIRECT_ADSP_START:
            SKY_DIRECT_ADSP_DBG_LOW("sky_direct_adsp_ioctl(), start SKY Direct ADSP!!");
            bUseSKYDirectADSP = true;
            break;
        case IOCTL_SKY_DIRECT_ADSP_STOP:
            SKY_DIRECT_ADSP_DBG_LOW("sky_direct_adsp_ioctl(), stop SKY Direct ADSP!!");
            bUseSKYDirectADSP = false;            
            break;
        case IOCTL_SKY_DIRECT_ADSP_PCM_WB_MODE_SET:
            SKY_DIRECT_ADSP_DBG_LOW("sky_direct_adsp_ioctl(), set ADSP mode PCM-WB");
            MVS_MODE = MODE_PCM;
            if(voip_info.play_samp_rate != 16000 || voip_info.cap_samp_rate != 16000)
            {
       			voip_info.state = VOIP_STOPPED;
        		voc_end_voice_call(
        				voc_get_session_id(VOIP_SESSION_NAME));
        		
                voip_info.play_samp_rate = 16000;
                voip_info.pcm_size = snd_pcm_lib_buffer_bytes(voip_info.playback_substream);
                voip_info.pcm_count = snd_pcm_lib_period_bytes(voip_info.playback_substream);
                voip_info.pcm_playback_irq_pos = 0;
                voip_info.pcm_playback_buf_pos = 0;

                voip_info.cap_samp_rate = 16000;
                voip_info.pcm_capture_size  = snd_pcm_lib_buffer_bytes(voip_info.capture_substream);
                voip_info.pcm_capture_count = snd_pcm_lib_period_bytes(voip_info.capture_substream);
                voip_info.pcm_capture_irq_pos = 0;
                voip_info.pcm_capture_buf_pos = 0;
                    
        		ret = voip_get_rate_type(voip_info.mode,
        					voip_info.rate,
        					&rate_type);
                
        		if (ret < 0) {
        			SKY_DIRECT_ADSP_DBG_HIGH("fail at getting rate_type, set ADSP to default WB 23.85k rate\n");
                    voip_info.rate = 23850;
                    rate_type = AMR_RATE_23850 - AMR_RATE_6600;
        		}

        		voip_info.rate_type = rate_type;
            	ret = voip_get_media_type(voip_info.mode,
            					voip_info.play_samp_rate,
                				&media_type);
                
            	if (ret < 0) {
            		SKY_DIRECT_ADSP_DBG_HIGH("fail at getting media_type\n");
            		ret = -EINVAL;
            	}
                
            	pr_debug(" media_type=%d, rate_type=%d\n", media_type,
            		rate_type);
                
            	if ((voip_info.play_samp_rate == 16000) &&
            				(voip_info.cap_samp_rate == 16000))
                    voc_config_vocoder(media_type, rate_type,
                            VSS_NETWORK_ID_VOIP_WB,
                            voip_info.dtx_mode,
                            evrc_min_rate_type,
                            evrc_max_rate_type);
            	else {
            		SKY_DIRECT_ADSP_DBG_HIGH("%s: Invalid rate playback %d, capture %d\n",
            			 __func__, voip_info.play_samp_rate,
            			 voip_info.cap_samp_rate);
            		ret = -EINVAL;
            	}
                
            	voc_start_voice_call(voc_get_session_id(VOIP_SESSION_NAME));

            	voip_info.state = VOIP_STARTED;
            }
            break;
        case IOCTL_SKY_DIRECT_ADSP_PCM_NB_MODE_SET:
            SKY_DIRECT_ADSP_DBG_LOW("sky_direct_adsp_ioctl(), set ADSP mode PCM-NB");
            MVS_MODE = MODE_PCM;
            if(voip_info.play_samp_rate != 8000 || voip_info.cap_samp_rate != 8000)
            {
       			voip_info.state = VOIP_STOPPED;
        		voc_end_voice_call(
        				voc_get_session_id(VOIP_SESSION_NAME));

                voip_info.play_samp_rate = 8000;
                voip_info.pcm_size = snd_pcm_lib_buffer_bytes(voip_info.playback_substream);
                voip_info.pcm_count = snd_pcm_lib_period_bytes(voip_info.playback_substream);
                voip_info.pcm_playback_irq_pos = 0;
                voip_info.pcm_playback_buf_pos = 0;

                voip_info.cap_samp_rate = 8000;
                voip_info.pcm_capture_size  = snd_pcm_lib_buffer_bytes(voip_info.capture_substream);
                voip_info.pcm_capture_count = snd_pcm_lib_period_bytes(voip_info.capture_substream);
                voip_info.pcm_capture_irq_pos = 0;
                voip_info.pcm_capture_buf_pos = 0;
                    
        		ret = voip_get_rate_type(voip_info.mode,
        					voip_info.rate,
        					&rate_type);
                
        		if (ret < 0) {
        			SKY_DIRECT_ADSP_DBG_HIGH("fail at getting rate_type, set ADSP to default WB 23.85k rate\n");
                    voip_info.rate = 23850;
                    rate_type = AMR_RATE_23850 - AMR_RATE_6600;
        		}

        		voip_info.rate_type = rate_type;
            	ret = voip_get_media_type(voip_info.mode,
            					voip_info.play_samp_rate,
                				&media_type);
                
            	if (ret < 0) {
            		SKY_DIRECT_ADSP_DBG_HIGH("fail at getting media_type\n");
            		ret = -EINVAL;
            	}
                
            	pr_debug(" media_type=%d, rate_type=%d\n", media_type,
            		rate_type);
                
            	if ((voip_info.play_samp_rate == 8000) &&
            				(voip_info.cap_samp_rate == 8000))
                    voc_config_vocoder(media_type, rate_type,
                            VSS_NETWORK_ID_VOIP_NB,
                            voip_info.dtx_mode,
                            evrc_min_rate_type,
                            evrc_max_rate_type);
            	else {
            		SKY_DIRECT_ADSP_DBG_HIGH("%s: Invalid rate playback %d, capture %d\n",
            			 __func__, voip_info.play_samp_rate,
            			 voip_info.cap_samp_rate);
            		ret = -EINVAL;
            	}
                
            	voc_start_voice_call(voc_get_session_id(VOIP_SESSION_NAME));

            	voip_info.state = VOIP_STARTED;
            }
            break;
        case IOCTL_SKY_DIRECT_ADSP_AMR_WB_MODE_SET:
            SKY_DIRECT_ADSP_DBG_HIGH("sky_direct_adsp_ioctl(), set ADSP mode AMR-WB");
            MVS_MODE = MODE_AMR_WB;

            if(copy_from_user(&flags, argp, sizeof(flags)))
            {
                mutex_unlock(&voip_info.lock);
                return -EFAULT;
            }
            else
            {
                voip_info.rate = (uint32_t)flags;
            }

            if(MVS_MODE != voip_info.mode)
            {
                // TODO:  implement restart ADSP routine with new AMR-WB mode setting
                if(voip_info.state == VOIP_STARTED)
                {
                    //stop ADSP
           			voip_info.state = VOIP_STOPPED;
            		voc_end_voice_call(
            				voc_get_session_id(VOIP_SESSION_NAME));
            		//voc_register_mvs_cb(NULL, NULL, voip_info);

                    //restart ASDP
                    voip_info.mode = MODE_AMR_WB;

            		ret = voip_get_rate_type(voip_info.mode,
            					voip_info.rate,
            					&rate_type);
                    
            		if (ret < 0) {
            			pr_err("fail at getting rate_type, set ADSP to default WB 23.85k rate\n");
                        voip_info.rate = 23850;
                        rate_type = AMR_RATE_23850 - AMR_RATE_6600;
            		}

            		voip_info.rate_type = rate_type;
                	ret = voip_get_media_type(voip_info.mode,
                					voip_info.play_samp_rate,
                					&media_type);
                    
                	if (ret < 0) {
                		pr_err("fail at getting media_type\n");
                		ret = -EINVAL;
                	}
                    
                	pr_debug(" media_type=%d, rate_type=%d\n", media_type,
                		rate_type);
                    
                	if ((voip_info.play_samp_rate == 16000) &&
                				(voip_info.cap_samp_rate == 16000))
                        voc_config_vocoder(media_type, rate_type,
                                VSS_NETWORK_ID_VOIP_WB,
                                voip_info.dtx_mode,
                                evrc_min_rate_type,
                                evrc_max_rate_type);
                	else {
                		pr_debug("%s: Invalid rate playback %d, capture %d\n",
                			 __func__, voip_info.play_samp_rate,
                			 voip_info.cap_samp_rate);
                		ret = -EINVAL;
                	}
//                	voc_register_mvs_cb(voip_process_ul_pkt,
//                				voip_process_dl_pkt, voip_info);
                	voc_start_voice_call(voc_get_session_id(VOIP_SESSION_NAME));

                	voip_info.state = VOIP_STARTED;
                }
                else
                {
                    SKY_DIRECT_ADSP_ERR("sky_direct_adsp_ioctl() failed, voip_info.state : %d",voip_info.state);        
                }
            }
            break;
        case IOCTL_SKY_DIRECT_ADSP_AMR_NB_MODE_SET:
            SKY_DIRECT_ADSP_DBG_HIGH("sky_direct_adsp_ioctl(), set ADSP mode AMR-NB");
            MVS_MODE = MODE_AMR;
            
            if(copy_from_user(&flags, argp, sizeof(flags)))
            {
                mutex_unlock(&voip_info.lock);
                return -EFAULT;
            }
            else
            {
                voip_info.rate = (uint32_t)flags;
            }

            if(MVS_MODE != voip_info.mode)
            {
                // TODO:  implement restart ADSP routine with new AMR-NB mode setting
                if(voip_info.state == VOIP_STARTED)
                {
                    //stop ADSP
           			voip_info.state = VOIP_STOPPED;
            		voc_end_voice_call(
            				voc_get_session_id(VOIP_SESSION_NAME));
            		//voc_register_mvs_cb(NULL, NULL, voip_info);

                    //restart ASDP
                    voip_info.mode = MODE_AMR;

            		ret = voip_get_rate_type(voip_info.mode,
            					voip_info.rate,
            					&rate_type);
                    
            		if (ret < 0) {
            			pr_err("fail at getting rate_type, set ADSP to default NB 12.2k rate\n");
                        voip_info.rate = 12200;
                        rate_type = AMR_RATE_12200;
            		}
                    
               		voip_info.rate_type = rate_type;
                	ret = voip_get_media_type(voip_info.mode,
                					voip_info.play_samp_rate,
                					&media_type);
                    
                	if (ret < 0) {
                		pr_err("fail at getting media_type\n");
                		ret = -EINVAL;
                	}
                    
                	pr_debug(" media_type=%d, rate_type=%d\n", media_type,
                		rate_type);
                    
                	if ((voip_info.play_samp_rate == 8000) &&
                				(voip_info.cap_samp_rate == 8000))
                        voc_config_vocoder(media_type, rate_type,
                                VSS_NETWORK_ID_VOIP_NB,
                                voip_info.dtx_mode,
                                evrc_min_rate_type,
                                evrc_max_rate_type);
                	else {
                		pr_debug("%s: Invalid rate playback %d, capture %d\n",
                			 __func__, voip_info.play_samp_rate,
                			 voip_info.cap_samp_rate);
                		ret = -EINVAL;
                	}
//                	voc_register_mvs_cb(voip_process_ul_pkt,
//                				voip_process_dl_pkt, voip_info);
                	voc_start_voice_call(voc_get_session_id(VOIP_SESSION_NAME));

                	voip_info.state = VOIP_STARTED;
                }
                else
                {
                    SKY_DIRECT_ADSP_ERR("sky_direct_adsp_ioctl() failed, voip_info.state : %d",voip_info.state);        
                }
            }
            break;
        default:
            SKY_DIRECT_ADSP_DBG_HIGH("sky_direct_adsp_ioctl(), set ADSP mode PCM");
            MVS_MODE = MODE_PCM;
            break;
    }

    mutex_unlock(&voip_info.lock);

    return ret;
}