summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/tegra/tegra_pcm_rpc.c99
-rw-r--r--sound/soc/tegra/tegra_transport.c18
-rw-r--r--sound/soc/tegra/tegra_transport.h7
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);