diff options
-rw-r--r-- | sound/soc/tegra/tegra_pcm_rpc.c | 99 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_transport.c | 18 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_transport.h | 7 |
3 files changed, 116 insertions, 8 deletions
diff --git a/sound/soc/tegra/tegra_pcm_rpc.c b/sound/soc/tegra/tegra_pcm_rpc.c index f6cd0861a698..bc532c4c6dfa 100644 --- a/sound/soc/tegra/tegra_pcm_rpc.c +++ b/sound/soc/tegra/tegra_pcm_rpc.c @@ -23,6 +23,7 @@ #include "tegra_transport.h" struct tegra_audio_data* tegra_snd_cx[2]; +struct tegra_audio_state_t tegra_audio_state; static const struct snd_pcm_hardware tegra_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE |\ @@ -453,6 +454,7 @@ static int pcm_common_close(struct snd_pcm_substream *substream) struct tegra_audio_data *ptscx = tegra_snd_cx[pcm->device]; NvAudioFxMessage message; NvError e; + NvAudioFxIoDevice io_device; if (!prtd) snd_printk(KERN_ERR "pcm_close called with prtd = NULL\n"); @@ -490,15 +492,66 @@ static int pcm_common_close(struct snd_pcm_substream *substream) } if (prtd->stdoutpath) { + if (pcm->device == I2S2) { + io_device = NvAudioFxIoDevice_Bluetooth_Sco; + ptscx->xrt_fxn.SetProperty(ptscx->mi2s1, + NvAudioFxIoProperty_OutputDisable, + sizeof(NvAudioFxIoDevice), + &io_device); + } tegra_audiofx_destroy_output(prtd->stdoutpath); kfree(prtd->stdoutpath); } if (prtd->stdinpath) { + if (pcm->device == I2S2) { + io_device = NvAudioFxIoDevice_Bluetooth_Sco; + ptscx->xrt_fxn.SetProperty(ptscx->mi2s1, + NvAudioFxIoProperty_InputDisable, + sizeof(NvAudioFxIoDevice), + &io_device); + } tegra_audiofx_destroy_input(prtd->stdinpath); kfree(prtd->stdinpath); } + if (pcm->device == I2S2) { + ptscx->xrt_fxn.GetProperty(ptscx->mi2s1, + NvAudioFxIoProperty_OutputSelect, + sizeof(NvAudioFxIoDevice), + &io_device); + if (io_device & NvAudioFxIoDevice_Bluetooth_Sco) { + ptscx->xrt_fxn.GetProperty(ptscx->mi2s1, + NvAudioFxIoProperty_InputSelect, + sizeof(NvAudioFxIoDevice), + &io_device); + if (io_device & NvAudioFxIoDevice_Bluetooth_Sco) { + mutex_lock(&tegra_audio_state.mutex_lock); + tegra_audio_state.devices_available &= + ~(NvAudioFxIoDevice_Bluetooth_Sco); + + 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); + + tegra_audio_state.audio_mode &= + ~(NvAudioFxMode_Bluetooth_Sco); + ptscx->xrt_fxn.SetProperty( + (NvAudioFxObjectHandle)ptscx->mixer_handle, + NvAudioFxMixerProperty_ModeSelect, + sizeof(NvAudioFxMode), + &tegra_audio_state.audio_mode); + mutex_unlock(&tegra_audio_state.mutex_lock); + } + } + } + if (prtd) kfree(prtd); @@ -647,6 +700,48 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) 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"); @@ -891,6 +986,10 @@ EXPORT_SYMBOL_GPL(tegra_soc_platform); static int __init tegra_soc_platform_init(void) { + tegra_audio_state.devices_available = NvAudioFxIoDevice_Default; + tegra_audio_state.audio_mode = NvAudioFxMode_Normal; + mutex_init(&tegra_audio_state.mutex_lock); + return snd_soc_register_platform(&tegra_soc_platform); } diff --git a/sound/soc/tegra/tegra_transport.c b/sound/soc/tegra/tegra_transport.c index 038309ac27ef..f5b209641098 100644 --- a/sound/soc/tegra/tegra_transport.c +++ b/sound/soc/tegra/tegra_transport.c @@ -36,6 +36,7 @@ } \ wait_for_completion(&comp); \ +extern struct tegra_audio_state_t tegra_audio_state; static AlsaTransport* atrans = 0; @@ -548,7 +549,6 @@ int tegra_audiofx_init(struct tegra_audio_data* tegra_snd_cx) tegra_snd_cx->mi2s1 = tegra_snd_cx->xrt_fxn.MixerCreateObject( tegra_snd_cx->mixer_handle, NvAudioFxI2s1Id); - tegra_snd_cx->mi2s1_device_available = NvAudioFxIoDevice_Default; tegra_snd_cx->i2s1_play_mix = tegra_snd_cx->xrt_fxn.MixerCreateObject( tegra_snd_cx->mixer_handle, @@ -689,8 +689,11 @@ static void tegra_audiofx_notifier_thread(void *arg) NvAudioFxIoDeviceControlChangeMessage* iccm = (NvAudioFxIoDeviceControlChangeMessage*)message; - audio_context->mi2s1_device_available = iccm->IoDevice; - tegra_audiofx_route(audio_context); + mutex_lock(&tegra_audio_state.mutex_lock); + tegra_audio_state.devices_available = iccm->IoDevice; + mutex_unlock(&tegra_audio_state.mutex_lock); + if (audio_context->device_id == I2S1) + tegra_audiofx_route(audio_context); } } @@ -701,7 +704,8 @@ static void tegra_audiofx_notifier_thread(void *arg) (NvAudioFxIoDeviceControlChangeMessage*)message; audio_context->mspdif_device_available = iccm->IoDevice; - tegra_audiofx_route(audio_context); + if (audio_context->device_id == I2S1) + tegra_audiofx_route(audio_context); } } } @@ -729,16 +733,16 @@ NvError tegra_audiofx_route(struct tegra_audio_data *audio_context) audio_context->spdif_plugin) { spdif_device_select = NvAudioFxIoDevice_Aux; } - else if(audio_context->mi2s1_device_available & + else if(tegra_audio_state.devices_available & NvAudioFxIoDevice_HeadphoneOut) { i2s1_device_select = NvAudioFxIoDevice_HeadphoneOut; } - else if(audio_context->mi2s1_device_available & + else if(tegra_audio_state.devices_available & NvAudioFxIoDevice_BuiltInSpeaker) { i2s1_device_select = NvAudioFxIoDevice_BuiltInSpeaker; } else { - i2s1_device_select = audio_context->mi2s1_device_available; + i2s1_device_select = tegra_audio_state.devices_available; } e = audio_context->xrt_fxn.SetProperty( diff --git a/sound/soc/tegra/tegra_transport.h b/sound/soc/tegra/tegra_transport.h index 7863efbee64d..16a2f2977e6c 100644 --- a/sound/soc/tegra/tegra_transport.h +++ b/sound/soc/tegra/tegra_transport.h @@ -420,7 +420,6 @@ struct tegra_audio_data { NvAudioFxObjectHandle i2s1_rec_split; NvAudioFxObjectHandle i2s2_rec_split; NvAudioFxObjectHandle mroute; - NvAudioFxIoDevice mi2s1_device_available; NvAudioFxIoDevice mspdif_device_available; int spdif_plugin; int i2s1volume; @@ -428,6 +427,12 @@ struct tegra_audio_data { struct mutex lock; }; +struct tegra_audio_state_t { + NvAudioFxIoDevice devices_available; + NvAudioFxMode audio_mode; + struct mutex mutex_lock; +}; + int tegra_audiofx_init(struct tegra_audio_data* tegra_snd_cx); NvError tegra_audiofx_createfx(struct tegra_audio_data *audio_context); void tegra_audiofx_destroyfx(struct tegra_audio_data *audio_context); |