summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSumit Bhattacharya <sumitb@nvidia.com>2010-07-27 14:24:52 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2010-07-27 06:15:29 -0700
commit57d003c07d1b8ef664b601b995a479b43ddb9293 (patch)
treeae5691ec9911faa70e74cc5d3aeb2b23e956f5f6
parent683ef11f1b78070740f6e4e611ef3907cbe8e5db (diff)
[ALSA] Fix SPDIF audio routing on LDK
On LDK audio is getting routed to both SPDIF and headset when HDMI is connected. Fix this issue by handling audio routing properly in ALSA. Depending on available output devices ALSA will decide where to route audio. Order of preference is SPDIF->HeadPhone->Speaker. Bug 709951 Change-Id: I76971f6e17cbbd9a14a5c0ca155e765e95badb68 Reviewed-on: http://git-master/r/4452 Tested-by: Sumit Bhattacharya <sumitb@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--sound/soc/tegra/tegra_codec_rpc.c10
-rw-r--r--sound/soc/tegra/tegra_sndfx.h1
-rw-r--r--sound/soc/tegra/tegra_transport.c102
-rw-r--r--sound/soc/tegra/tegra_transport.h3
4 files changed, 58 insertions, 58 deletions
diff --git a/sound/soc/tegra/tegra_codec_rpc.c b/sound/soc/tegra/tegra_codec_rpc.c
index 6868f76afeda..916dc06f8c87 100644
--- a/sound/soc/tegra/tegra_codec_rpc.c
+++ b/sound/soc/tegra/tegra_codec_rpc.c
@@ -127,20 +127,12 @@ 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);
+ tegra_audiofx_route(tegra_snd_cx);
change = 1;
}
}
diff --git a/sound/soc/tegra/tegra_sndfx.h b/sound/soc/tegra/tegra_sndfx.h
index d69c0915d8b5..4794466b4fea 100644
--- a/sound/soc/tegra/tegra_sndfx.h
+++ b/sound/soc/tegra/tegra_sndfx.h
@@ -319,7 +319,6 @@ typedef NvS32 NvAudioFxIoDevice;
#define NvAudioFxIoDevice_Aux (0x10000)
#define NvAudioFxIoDevice_Phone (0x20000)
#define NvAudioFxIoDevice_Radio (0x40000)
-#define NvAudioFxIoDevice_Bluetooth (0x80000)
#define NvAudioFxIoDevice_Bluetooth_Sco (0x80000)
typedef struct NvAudioFxPeqDescriptorRec
diff --git a/sound/soc/tegra/tegra_transport.c b/sound/soc/tegra/tegra_transport.c
index c013908d1dfc..50c30ffc062e 100644
--- a/sound/soc/tegra/tegra_transport.c
+++ b/sound/soc/tegra/tegra_transport.c
@@ -543,10 +543,12 @@ int tegra_audiofx_init(struct tegra_audio_data* tegra_snd_cx)
tegra_snd_cx->mixer_handle,
NvAudioFxSpdifId);
tegra_snd_cx->spdif_plugin = 1;
+ tegra_snd_cx->mspdif_device_available = NvAudioFxIoDevice_Default;
tegra_snd_cx->mi2s1 = tegra_snd_cx->xrt_fxn.MixerCreateObject(
tegra_snd_cx->mixer_handle,
NvAudioFxI2s1Id);
+ tegra_snd_cx->mi2s1_device_available = NvAudioFxIoDevice_Default;
memset(&message, 0, sizeof(NvAudioFxMessage));
message.Event = NvAudioFxEventControlChange;
@@ -663,62 +665,24 @@ static void tegra_audiofx_notifier_thread(void *arg)
(NvAudioFxControlChangeMessage*)message;
if (message->hFx ==
- (NvAudioFxHandle)audio_context->mi2s1)
- {
- if (ccm->Property == NvAudioFxIoProperty_OutputAvailable)
- {
+ (NvAudioFxHandle)audio_context->mi2s1) {
+ if (ccm->Property == NvAudioFxIoProperty_OutputAvailable) {
NvAudioFxIoDeviceControlChangeMessage* iccm =
(NvAudioFxIoDeviceControlChangeMessage*)message;
- NvAudioFxIoDevice device_available = iccm->IoDevice;
- NvAudioFxIoDevice device_select = device_available;
-
- if (device_available &
- NvAudioFxIoDevice_HeadphoneOut)
- {
- device_select = NvAudioFxIoDevice_HeadphoneOut;
- }
- else if (device_available &
- NvAudioFxIoDevice_BuiltInSpeaker)
- {
- device_select = NvAudioFxIoDevice_BuiltInSpeaker;
- }
-
- audio_context->xrt_fxn.SetProperty(
- audio_context->mi2s1,
- NvAudioFxIoProperty_OutputSelect,
- sizeof(NvAudioFxIoDevice),
- &device_select);
+
+ audio_context->mi2s1_device_available = iccm->IoDevice;
+ tegra_audiofx_route(audio_context);
}
}
else if (message->hFx ==
- (NvAudioFxHandle)audio_context->mroute)
- {
- if (ccm->Property == NvAudioFxIoProperty_OutputAvailable)
- {
+ (NvAudioFxHandle)audio_context->mroute) {
+ if (ccm->Property == NvAudioFxIoProperty_OutputAvailable) {
NvAudioFxIoDeviceControlChangeMessage* iccm =
(NvAudioFxIoDeviceControlChangeMessage*)message;
- NvAudioFxIoDevice device_available = iccm->IoDevice;
- NvAudioFxIoDevice device_select = 0;
-
- if ((device_available &
- NvAudioFxIoDevice_Aux) &&
- audio_context->spdif_plugin)
- {
- device_select = NvAudioFxIoDevice_Aux;
- }
- else if ((device_available &
- NvAudioFxIoDevice_BuiltInSpeaker) &&
- audio_context->spdif_plugin)
- {
- device_select = NvAudioFxIoDevice_BuiltInSpeaker;
- }
-
- audio_context->xrt_fxn.SetProperty(
- audio_context->mroute,
- NvAudioFxIoProperty_OutputSelect,
- sizeof(NvAudioFxIoDevice),
- &device_select);
+
+ audio_context->mspdif_device_available = iccm->IoDevice;
+ tegra_audiofx_route(audio_context);
}
}
}
@@ -735,6 +699,48 @@ EXIT:
return;
}
+NvError tegra_audiofx_route(struct tegra_audio_data *audio_context)
+{
+ NvAudioFxIoDevice i2s1_device_select = NvAudioFxIoDevice_Default;
+ NvAudioFxIoDevice spdif_device_select = NvAudioFxIoDevice_Default;
+ NvError e;
+
+ if ((audio_context->mspdif_device_available &
+ NvAudioFxIoDevice_Aux) &&
+ audio_context->spdif_plugin) {
+ spdif_device_select = NvAudioFxIoDevice_Aux;
+ }
+ else if(audio_context->mi2s1_device_available &
+ NvAudioFxIoDevice_HeadphoneOut) {
+ i2s1_device_select = NvAudioFxIoDevice_HeadphoneOut;
+ }
+ else if(audio_context->mi2s1_device_available &
+ NvAudioFxIoDevice_BuiltInSpeaker) {
+ i2s1_device_select = NvAudioFxIoDevice_BuiltInSpeaker;
+ }
+ else {
+ i2s1_device_select = audio_context->mi2s1_device_available;
+ }
+
+ e = audio_context->xrt_fxn.SetProperty(
+ audio_context->mroute,
+ NvAudioFxIoProperty_OutputSelect,
+ sizeof(NvAudioFxIoDevice),
+ &spdif_device_select);
+
+ e |= audio_context->xrt_fxn.SetProperty(
+ audio_context->mi2s1,
+ NvAudioFxIoProperty_OutputSelect,
+ sizeof(NvAudioFxIoDevice),
+ &i2s1_device_select);
+
+ if (e != NvSuccess) {
+ snd_printk(KERN_ERR "SetProperty failed!\n");
+ }
+
+ return e;
+}
+
NvError tegra_audiofx_createfx(struct tegra_audio_data *audio_context)
{
NvAudioFxMixerHandle m_hMixer =
diff --git a/sound/soc/tegra/tegra_transport.h b/sound/soc/tegra/tegra_transport.h
index 129c3bde87c3..824d95f94393 100644
--- a/sound/soc/tegra/tegra_transport.h
+++ b/sound/soc/tegra/tegra_transport.h
@@ -413,6 +413,8 @@ struct tegra_audio_data {
NvAudioFxObjectHandle mvolume;
NvAudioFxObjectHandle mi2s1;
NvAudioFxObjectHandle mroute;
+ NvAudioFxIoDevice mi2s1_device_available;
+ NvAudioFxIoDevice mspdif_device_available;
int spdif_plugin;
int i2s1volume;
struct mutex lock;
@@ -430,6 +432,7 @@ NvError tegra_audiofx_create_input(NvRmDeviceHandle hRmDevice,
StandardPath* pPath,
InputSelection InputSelect);
NvError tegra_audiofx_destroy_input(StandardPath* pPath);
+NvError tegra_audiofx_route(struct tegra_audio_data* tegra_snd_cx);
NvError tegra_transport_init(NvddkAudioFxFxnTable* FxTransportFxFxnTable);
void tegra_transport_deinit(void);