NvError tegra_audiofx_create_output(NvRmDeviceHandle hRmDevice, NvAudioFxMixerHandle hMixer, StandardPath* pPath, NvAudioFxObjectHandle hSource) { NvError e = NvSuccess; NvAudioFxConnectionDescriptor connection; /* Standard Output [stream]->[SRC]->[Convert]->[Resize]->[Volume]->Default Output */ memset(pPath, 0, sizeof(StandardPath)); audiofx_create_object(pPath->Stream, NvAudioFxStreamId); audiofx_create_object(pPath->Src, NvAudioFxSrcId); audiofx_create_object(pPath->Convert, NvAudioFxConvertId); audiofx_create_object(pPath->Resize, NvAudioFxResizeId); audiofx_create_object(pPath->Volume, NvAudioFxVolumeId); audiofx_path_connect(pPath->Stream, pPath->Src); audiofx_path_connect(pPath->Src, pPath->Convert); audiofx_path_connect(pPath->Convert, pPath->Resize); audiofx_path_connect(pPath->Resize, pPath->Volume); connection.hSource = (NvAudioFxHandle)pPath->Volume; connection.SourcePin = NvAudioFxSourcePin; connection.hSink = (NvAudioFxHandle)hSource; connection.SinkPin = NvAudioFxSinkPin; e = tegra_transport_set_property(pPath->Volume, NvAudioFxProperty_Attach, sizeof(NvAudioFxConnectionDescriptor), &connection); if (e != NvSuccess) { snd_printk(KERN_ERR "tegra_transport_set_property failed!\n"); goto EXIT_WITH_ERROR; } goto EXIT; EXIT_WITH_ERROR: tegra_audiofx_destroy_output(pPath); EXIT: return e; }
static int pcm_common_close(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct pcm_runtime_data *prtd = runtime->private_data; struct snd_pcm *pcm = substream->pcm; 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"); prtd->state = SNDRV_PCM_TRIGGER_STOP; if (completion_done(&prtd->thread_comp) == 0) complete(&prtd->thread_comp); wake_up_all(&prtd->buf_wait); if (prtd->play_thread) kthread_stop(prtd->play_thread); if (prtd->rec_thread) kthread_stop(prtd->rec_thread); if (ptscx->m_FxNotifier.Event) { memset(&message, 0, sizeof(NvAudioFxMessage)); message.Event = NvAudioFxEventAll; message.pContext = NULL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) message.hFx = (NvAudioFxHandle)prtd->stdoutpath->Stream; else message.hFx = (NvAudioFxHandle)prtd->stdinpath->Stream; e = ptscx->xrt_fxn.SetProperty( (NvAudioFxObjectHandle)ptscx->m_FxNotifier.hNotifier, NvAudioFxIoProperty_RemoveEvent, sizeof(NvAudioFxMessage), &message); ptscx->m_FxNotifier.Event &= ~NvAudioFxEventAll; } 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); return 0; }