static int tegra_master_volume_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	int change = 0, val;
	NvAudioFxVolumeDescriptor vd;
	val = ucontrol->value.integer.value[0] & 0xffff;
	vd.LeftVolume = val;
	vd.RightVolume = val;
	if(val) {
		vd.Mute = 0;
	}
	else {
		vd.Mute = 1;
	}

	if (tegra_snd_cx) {
		if (!tegra_audiofx_init(tegra_snd_cx)) {
			if(tegra_snd_cx->i2s1volume != val) {
				tegra_snd_cx->i2s1volume = val;
				tegra_snd_cx->xrt_fxn.SetProperty(
					tegra_snd_cx->mvolume,
					NvAudioFxVolumeProperty_Volume,
					sizeof(NvAudioFxVolumeDescriptor),
					&vd);
				change = 1;
			}
		}
	}

	return change;
}
static int tegra_master_route_get(struct snd_kcontrol *kcontrol,
				  struct snd_ctl_elem_value *ucontrol)
{
	ucontrol->value.integer.value[0] = 0;
	if (tegra_snd_cx) {
		if (!tegra_audiofx_init(tegra_snd_cx)) {
			ucontrol->value.integer.value[0] =
						tegra_snd_cx->spdif_plugin;
		}
	}
	return 0;
}
static int tegra_master_volume_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	int rval = NvAudioFxVolumeDefault;
	int lval = NvAudioFxVolumeDefault;

	if (tegra_snd_cx) {
		if (!tegra_audiofx_init(tegra_snd_cx)) {
			rval = tegra_snd_cx->i2s1volume;
			lval = tegra_snd_cx->i2s1volume;
		}
	}
	ucontrol->value.integer.value[0] = rval;
	ucontrol->value.integer.value[1] = lval;
	return 0;
}
static int tegra_master_route_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	int change = 0, val;
	NvAudioFxIoDevice ioDevice = 0;
	val = ucontrol->value.integer.value[0] & 0xffff;
	if (val) {
		ioDevice = NvAudioFxIoDevice_BuiltInSpeaker;
	}

	if (tegra_snd_cx) {
		if (!tegra_audiofx_init(tegra_snd_cx)) {
			tegra_snd_cx->spdif_plugin = val;
			tegra_snd_cx->xrt_fxn.SetProperty(
				tegra_snd_cx->mroute,
				NvAudioFxIoProperty_OutputSelect,
				sizeof(NvAudioFxIoDevice),
				&ioDevice);
			change = 1;
		}
	}
	return change;
}
Beispiel #5
0
static int tegra_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_pcm *pcm = substream->pcm;
	struct pcm_runtime_data *prtd;
	int ret = 0;
	NvError e = NvSuccess;
	NvAudioFxMessage message;
	NvAudioFxObjectHandle hSource = 0;
	struct tegra_audio_data *ptscx = tegra_snd_cx[pcm->device];

	prtd = kzalloc(sizeof(struct pcm_runtime_data), GFP_KERNEL);
	if (prtd == NULL)
		return -ENOMEM;

	runtime->private_data = prtd;
	snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
	spin_lock_init(&prtd->lock);
	prtd->timeout = INIT_TIMEOUT;
	prtd->stdoutpath = 0;
	prtd->stdinpath = 0;
	prtd->state = NVALSA_INVALID_STATE;
	prtd->stream = substream->stream;

	if (!ptscx->mixer_handle) {
		ret = tegra_audiofx_init(ptscx);
		if (ret)
			goto fail;
	}

	init_completion(&prtd->thread_comp);
	init_waitqueue_head(&prtd->buf_wait);
	sema_init(&prtd->buf_done_sem, 0);
	sema_init(&prtd->stop_done_sem, 0);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
		hSource = ptscx->i2s1_play_mix;
		if (pcm->device == I2S2)
			hSource = ptscx->i2s2_play_mix;

		prtd->mixer_buffer = ptscx->mixer_buffer[0];
		prtd->stdoutpath = (StandardPath*)kzalloc(sizeof(StandardPath),
							  GFP_KERNEL);
		if (prtd->stdoutpath == NULL) {
			snd_printk(KERN_ERR "pcm_open kzalloc failed \n");
			ret = -ENOMEM;
			goto fail;
		}

		e = tegra_audiofx_create_output(ptscx->m_hRm,
						ptscx->mixer_handle,
						prtd->stdoutpath,
						hSource);
		if (e != NvSuccess) {
			snd_printk(KERN_ERR "audiofx_create_output failed \n");
			ret = -EFAULT;
			goto fail;
		}

		memset(&message, 0, sizeof(NvAudioFxMessage));
		message.Event = (NvAudioFxEventBufferDone |
				 NvAudioFxEventStateChange);
		message.hFx = (NvAudioFxHandle)prtd->stdoutpath->Stream;
		message.pContext = prtd;

		e = ptscx->xrt_fxn.SetProperty(
		    (NvAudioFxObjectHandle)ptscx->m_FxNotifier.hNotifier,
		    NvAudioFxIoProperty_AddEvent,
		    sizeof(NvAudioFxMessage),
		    &message);

		if (e != NvSuccess) {
			snd_printk(KERN_ERR "TransportSetProperty failed\n");
			ret = -EFAULT;
			goto fail;
		}

		ptscx->m_FxNotifier.Event |= (NvAudioFxEventBufferDone |
						     NvAudioFxEventStateChange);

		prtd->play_thread = kthread_run(play_thread,
						substream,
						"%sthread",
						"play");
		if (IS_ERR(prtd->play_thread)) {
			snd_printk(KERN_ERR "KTHREAD RUN FAIL\n");
			ret = PTR_ERR(prtd->play_thread);
			goto fail;
		}
	} else {
		hSource = ptscx->i2s1_rec_split;
		if (pcm->device == I2S2)
			hSource = ptscx->i2s2_rec_split;

		prtd->mixer_buffer = ptscx->mixer_buffer[1];
		prtd->stdinpath = (StandardPath*)kzalloc(sizeof(StandardPath),
							  GFP_KERNEL);
		if (prtd->stdinpath == NULL) {
			snd_printk(KERN_ERR "pcm_open kzalloc failed \n");
			ret = -ENOMEM;
			goto fail;
		}
		e = tegra_audiofx_create_input(ptscx->m_hRm,
						ptscx->mixer_handle,
						prtd->stdinpath,
						NvAudioInputSelect_Record,
						hSource);
		if (e != NvSuccess) {
			snd_printk(KERN_ERR "audiofx_create_input failed \n");
			ret = -EFAULT;
			goto fail;
		}

		memset(&message, 0, sizeof(NvAudioFxMessage));
		message.Event = (NvAudioFxEventBufferDone |
				 NvAudioFxEventStateChange);
		message.hFx = (NvAudioFxHandle)prtd->stdinpath->Stream;
		message.pContext = prtd;

		e = ptscx->xrt_fxn.SetProperty(
		    (NvAudioFxObjectHandle)ptscx->m_FxNotifier.hNotifier,
		    NvAudioFxIoProperty_AddEvent,
		    sizeof(NvAudioFxMessage),
		    &message);
		if (e != NvSuccess) {
			snd_printk(KERN_ERR "TransportSetProperty failed\n");
			ret = -EFAULT;
			goto fail;
		}
		ptscx->m_FxNotifier.Event |= (NvAudioFxEventBufferDone |
						     NvAudioFxEventStateChange);

		prtd->rec_thread = kthread_run(rec_thread,
						substream,
						"%sthread",
						"rec" );
		if (IS_ERR(prtd->rec_thread)) {
			snd_printk(KERN_ERR "Kthread Run Fail\n");
			ret = PTR_ERR(prtd->rec_thread);
			goto fail;
		}
	}

	if (pcm->device == I2S2) {
		NvAudioFxIoDevice io_device;

		mutex_lock(&tegra_audio_state.mutex_lock);
		tegra_audio_state.audio_mode |= NvAudioFxMode_Bluetooth_Sco;
		tegra_audio_state.devices_available |=
					NvAudioFxIoDevice_Bluetooth_Sco;
		mutex_unlock(&tegra_audio_state.mutex_lock);

		ptscx->xrt_fxn.SetProperty(
				(NvAudioFxObjectHandle)ptscx->mixer_handle,
				NvAudioFxMixerProperty_ModeSelect,
				sizeof(NvAudioFxMode),
				&tegra_audio_state.audio_mode);

		ptscx->xrt_fxn.SetProperty(ptscx->mi2s1,
				NvAudioFxIoProperty_OutputAvailable,
				sizeof(NvAudioFxIoDevice),
				&tegra_audio_state.devices_available);

		ptscx->xrt_fxn.SetProperty(ptscx->mi2s1,
				NvAudioFxIoProperty_InputAvailable,
				sizeof(NvAudioFxIoDevice),
				&tegra_audio_state.devices_available);

		io_device = NvAudioFxIoDevice_Bluetooth_Sco;

		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			ptscx->xrt_fxn.SetProperty(ptscx->mi2s1,
				NvAudioFxIoProperty_OutputEnable,
				sizeof(NvAudioFxIoDevice),
				&io_device);
		}
		else {
			ptscx->xrt_fxn.SetProperty(ptscx->mi2s1,
				NvAudioFxIoProperty_InputEnable,
				sizeof(NvAudioFxIoDevice),
				&io_device);
		}
	}

	return ret;
fail:
	snd_printk(KERN_ERR "tegra_pcm_open - failed \n");
	pcm_common_close(substream);
	return ret;
}