Changing audio output device when plug in headphones

Hello!!

I meet a problem as below:

L4T version : R21.7
Ubuntu version : 14.04

The Ubuntu on TK1 platform does not recognize when headphones are plugged in. But if I go to system setting and switch to “Speakers(tegra-rt5639)” it will works fine. The Ubuntu does not detect them automatically.

I used the below command and added the debug message to rt5639 driver to check the interrupt of headphones. It works well.

$cat /sys/class/gpio/gpio143/value

I type the command “aplay -l” and return :

**** List of PLAYBACK Hardware Devices ****
card 0: Tegra [HDA NVIDIA Tegra], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 0: rt5639 PCM rt5639-aif1-0
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 1: SPDIF PCM dit-hifi-1
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 2: BT SCO PCM dit-hifi-2
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 3: VOICE CALL PCM rt5639-aif1-3
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 4: BT VOICE CALL PCM dit-hifi-4
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 5: offload-pcm (*)
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegrart5639 [tegra-rt5639], device 7: offload-pcm-capture snd-soc-dummy-dai-7
Subdevices: 1/1
Subdevice #0: subdevice #0

We would like to automatically detect headphones on Ubuntu when they are plugged in. How can this be fixed?

Thanks.

Best Regards,
Michael

Hello,

Is there any suggestion?

Best Regards,
Michael

Hi Michael,

By default the ‘Speakers (tegra-rt5639)’ should be the default playback device (as per the configuration in /etc/asound.conf). Regardless of whether anything is connected to the audio jack.

I understand that you wish to use the jack event to set the playback device, however, what I don’t understand is what devices you are trying to switch between? In other words, when there is nothing connected to the audio jack, what do you want the default playback device to be?

One thing that I have observed is that despite the interrupt occurring on insertion/removal, I see that the status or availability is not seen by pulseaudio …

$ pacmd list-sinks
>>> 1 sink(s) available.
  * index: 0
        name: <alsa_output.platform-tegra-snd-rt5639.0.analog-stereo>

  ...

  ports:
        analog-output-speaker: Speakers (priority 10000, latency offset 0 usec, <b>available: unknown)</b>
                properties:
                        device.icon_name = "audio-speakers"
        active port: <analog-output-speaker>

And looking the pulseaudio log at start-up I see …

$ pulseaudio -k ; pulseaudio -vvvv 2>&1 |  grep Jack
E: [pulseaudio] main.c: Failed to kill daemon: No such process
[1]+  Exit 1                  pulseaudio -vvvv
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Front Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Front Mic Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Rear Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Rear Mic Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Dock Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Front Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Rear Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Internal Mic Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Dock Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Dock Mic Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Mic Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Line Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Line Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headset Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headset Mic Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of element 'Mic Jack Mode' succeeded (volume=0, switch=0, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Line Out Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Line Out Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Front Headphone Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Speaker Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Front Headphone Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Front Headphone Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Phantom Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Probe of jack 'Headphone Mic Jack' succeeded (not found)
D: [pulseaudio] alsa-mixer.c: Jack Headphone, alsa_name='Headphone Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Front Headphone, alsa_name='Front Headphone Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Speaker Phantom, alsa_name='Speaker Phantom Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Headphone, alsa_name='Headphone Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Front Headphone, alsa_name='Front Headphone Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Speaker Phantom, alsa_name='Speaker Phantom Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Headphone, alsa_name='Headphone Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Front Headphone, alsa_name='Front Headphone Jack', detection unavailable
D: [pulseaudio] alsa-mixer.c: Jack Speaker Phantom, alsa_name='Speaker Phantom Jack', detection unavailable

Looks like the name is prefixed with the machine driver name so I believe this is ok but I need to check …

$ cat /sys/devices/platform/tegra-snd-rt5639.0/sound/card1/input0/name                                                                                                                                                   
tegra-rt5639 Headphone Jack

The sysfs shows the above input is not ‘enabled’ but enabling it does not appear to have any impact.

I need to check how well the Jack detection works, but if you can let me know exactly what you are trying to do, then we can figure it out.

Regards
Jon

Hello Jon,

Thanks for your reply, because I wish to automatically switch to HDMI audio when unplug the headphones on TK1 platform.

My OS is also Ubuntu 14.04 on my PC and connect the HDMI monitor, I observed that it would show the new audio output’s option “Headphones” in sound setting if the headphones were plugged. Then I could select the headphones as audio output. If unplugged the headphones at this time, the audio output’s option “Headphones” would disappear in sound setting and then it would automatically switch to another audio output.

I would like to the TK1 could do the same thing if selected the headphones as audio output by default, it should automatically switch to the HDMI audio output when unplugged the headphones.

Best Regards,
Michael

Hi Michael,

Thanks for the info, it makes sense what you are trying to do.

So here is what I have found out …

  1. The bad news …

I am guessing that your PC is running a much more recent kernel than v3.10 (which Tegra is running). On these older kernels, the kernel sound drivers did not populate a kcontrol for the jack registered with the sound core. What this means is that pulseaudio is unable detect the jack when it starts up on boot and hence as show above the jack is not found by pulseaudio. On your PC if the you the command ‘pactl info’, connect the headphones and then run ‘pactl info’ again you should see the sink change, however, this is not working on TK1 by default.

Furthermore, although the v3.10 kernel does create an input device for the headphone jack, pulseaudio does not use input devices for detecting headphones [0].

  1. The good news …

Tegra TK1 registers a switch device with the kernel for the headphone/mic jacks. So if you run the following command, you should see the value changing when connecting/disconnecting headphones …

cat /sys/class/switch/h2w/state

Where the value of state is as follows …
‘0’ --> headhphones
‘1’ --> no headhphones

We can use the above switch as a trigger for a udev rule to then change the default sink used by pulseaudio. I was hoping we could use systemd for this [1], but unfortunately ubuntu 14.04 does not use systemd. So what I did was the following …

i). Create the file ‘/etc/init.d/tegra-audio-switch’ with the following contents. Note if you run manually you should see the audio sink switch as you connect/disconnect headphones.

#!/bin/sh

user_name=$(who | awk -v vt=ttyS0 '$0 ~ vt {print $1}')
user_id=$(id -u "$user_name")
tegra_ape_scard="alsa_output.platform-tegra-snd-rt5639.0.analog-stereo"
tegra_hda_scard="alsa_output.platform-tegra30-hda.hdmi-stereo"
PULSE_SERVER="unix:/run/user/"$user_id"/pulse/native"

state="$(cat /sys/class/switch/h2w/state)"

if [ "${state}" -eq "1" ]; then
        audio_output="${tegra_hda_scard}"
else
        audio_output="${tegra_ape_scard}"
fi

echo "selecting output ${audio_output}"
sudo -u "${user_name}" pactl --server "${PULSE_SERVER}" set-default-sink "${audio_output}"

ii). Make the above script executable …

sudo chmod +x /etc/init.d/tegra-audio-switch

iii). Finally create the udev rule ‘/etc/udev/rules.d/99-tegra-soundcard-default.rules’ with the following contents …

KERNEL=="h2w", SUBSYSTEM=="switch", ACTION=="change", RUN+="/usr/sbin/service tegra-audio-switch"

iv). Reload the udev rules

sudo udevadm control --reload

Let me know if this helps.

Jon

[0] https://marc.info/?l=alsa-devel&m=1494740761105115&w=2
[1] https://wiki.archlinux.org/index.php/PulseAudio/Examples#Automatically_switch_audio_to_HDMI

Hello Jon,

Thanks for your reply, that is really helpful.

Best Regards,
Michael