May 21, 2016 Leave a comment
It is not difficult to find posts on the Web regarding certain models of laptop that no longer produce sound from headphones after resuming from suspension, or no longer produce sound from their speakers or from headphones if you unplug and reconnect the headphones. My Clevo W230SS laptop suffered from these problems and more: sometimes the external microphone socket would no longer work either. I had to reboot the laptop in order to get audio working properly again.
The cause of these problems varies according to the specific hardware and software, and here I will describe a couple of fixes I implemented in Gentoo Linux for my Clevo W230SS laptop. Bear in mind that what works for one model of laptop may not necessarily work for a different model even if the symptoms are the same.
PROBLEM 1: No sound from headphones after resume from suspension
After my laptop resumed from suspension, headphones would no longer work until I rebooted the laptop. Sometimes an external microphone would also stop working until I rebooted. In 2014, Ubuntu user Kiril filed a bug report regarding this problem with the Clevo W230SS: [W230SS, VIA VT1802, Green Headphone Out, Front] No sound after suspend/resume. Actually, his original title for the bug report was: ‘[W230SS, VIA VT1802, Green Headphone Out, Front] No sound after fresh boot’. I didn’t have that problem: the headphone socket of my Clevo W230SS did produce sound after a ‘fresh boot’. Regarding Kiril‘s initial problem, ALSA developer Raymond Yau made several comments, including the following:
driver should not use same audio output for device 0 and device 2
independent headphone should be disabled on notebook by default
for desktop line out and headphone connected to different audio output nodes 0x03 and 0x04
this allow you to play different audio to line out and headphone
but this feature usually should be disabled for notebook
you need to file an upstream bug report to fix this bug in the indep_hp_possible function which should return false when there is no internal mic since some notebook have line out, headphone and Mic jack to support 5.1 or only enabled when headphone at extra front and line out at ext rear
the workaround is use hint to disable the indep_hp=0
Now, Kiril was using Ubuntu 14.04 and ALSA 1.0.27, whereas I’m using Gentoo and ALSA 1.0.29. Furthermore, apart from the two installations using different kernel versions, in Gentoo you configure and build the kernel yourself. So there is quite some difference between the two installations, which might explain why I do not have his original problem of no sound from headphones after a fresh boot. Where we did coincide, though, was that there was no sound from headphones following resumption from suspension.
First attempt at fixing the problem
Even though Independent HP does not stop headphones working after I boot my laptop, I decided to try to remove Independent HP anyway, to see if it would fix the suspend/resume problem with headphones in my case.
The Clevo W230SS has two sound cards:
The HDMI audio card is Card 0, and the analogue HD Audio card is Card 1. ALSAMixer shows an Independent HP (headphone) channel for Card 1:
The kernel documentation for the HD Audio driver explains how to fix the problem using what is called a driver ‘hint’. There is a link to the documentation in the above-mentioned bug report, and you can also find the documentation in the file
/usr/src/<kernel_release>/Documentation/sound/alsa/HD-Audio.txt on your laptop if you have installed the kernel source code. As explained in the documentation, you can remove Independent HP either via the command line:
or by using so-called ‘Early Patching’:
Early Patching ~~~~~~~~~~~~~~ When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a firmware file for modifying the HD-audio setup before initializing the codec. This can work basically like the reconfiguration via sysfs in the above, but it does it before the first codec configuration.
Note that the term ‘patching’ here has nothing to do with patching the driver’s source code; it refers to patching the ALSA driver’s configuration of the VIA chip’s CODEC on the Intel sound card.
The format of this particular patch file containing a ‘hint’ would be as follows:
[codec] <vendor_id> <subsystem_id> <address_of_the_CODEC> [hint] indep_hp = no
The values for
subsystem_id can be found as follows:
(As the driver is used with Card 1, remember to look in directory
hwC1D0 rather than
The required value for
address_of_the_CODEC is zero in this particular case. Therefore the file
/lib/firmware/clevo-hda-patch (you can choose any file name you want) should have the following contents:
[codec] 0x11068446 0x15582300 0 [hint] indep_hp = no
If you built the HA Audio driver as a module, you would need to add the following line to the file
/etc/modprobe.d/alsa.conf in order to apply the patch:
options snd-hda-intel patch=,clevo-hda-patch
Notice the comma after the equals sign. This is required because the patch applies to the second card (Card 1) rather than to the first card (Card 0).
However, I had built the HD Audio driver into the kernel rather than as a module:
Therefore adding the option to
/etc/modprobe.d/alsa.conf would have no effect, as the HD Audio driver is not a module. In this case I could have appended the following parameter to the kernel boot line in the file
The above kernel boot parameter could be appended to the kernel boot line either directly by editing the file
grub.cfg, or indirectly by adding it to the list of boot parameters in the variable
GRUB_CMDLINE_LINUX_DEFAULT="" in the file
/etc/default/grub and then using the command ‘
grub2-mkconfig -o /boot/grub/grub.cfg‘ as root user to regenerate the
grub.cfg file. Remember to mount
/boot first if it is on a different partition.
Now, I tried applying the patch using the appropriate method in each case: HD Audio driver built into the kernel, and HD Audio driver built as a module (it didn’t take me long to modify the kernel configuration and rebuild the kernel). In both cases the following messages were included in the output of the dmesg command:
I’m not sure if the reason for the failure to load the patch is the same in both cases, but certainly the reason in the case of the module is that PulseAudio is already running and using the driver by the time the OS attempts to apply the patch. In the case of the kernel boot parameter, my guess is that the patch would need to be included in an initramfs in order to be able to apply it before PulseAudio starts.
The same situation occurs if you try to apply the ‘hint’ manually from the command line after start-up:
The above error message occurs because PulseAudio is running and using the driver. To apply the hint and refresh the driver in this case, the solution is to stop PulseAudio beforehand:
Now, having to do the above manually every time you boot your machine is impractical. To automate the procedure I did the following…
Make sure the automatic (re)spawning of PulseAudio is disabled in the file
~/.config/pulse/client.conf (you can create the file if it does not exist):
autospawn = no
Create a Bash script in the directory
/etc/local.d/ for the OS to launch automatically at boot, and in that script issue the above two commands first and then start pulseaudio. I named the script ‘
99-clevo-hda-fix.start‘ and made its contents the following:
#!/bin/bash # Fix for Intel HDA problem with Clevo W230SS # See https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1313904 # N.B. Assumes your ~/.config/pulse/client.conf contains # 'autospawn = no' so that PulseAudio is not launched automatically. # # Specify the hint echo "indep_hp = no" > /sys/class/sound/hwC1D0/hints # # Reinitialise the HD Audio driver so it parses the CODEC tree again echo 1 > /sys/class/sound/hwC1D0/reconfig # # Start PulseAudio for my user account su -c "pulseaudio --start" -s /bin/sh fitzcarraldo
Don’t forget to make the script executable:
This method of applying the hint to the HD Audio driver should work irrespectively of whether the driver is a module or built-in. It’s a bit more of a hack compared to the Early Patching approach, but it does the job in my case. After logging in to the Desktop Environment, you can check if the hint has been applied by looking at the contents of
However, this alone does not mean the CODEC was reconfigured after the hint was applied, so you need to check if Independent HP still exists. The ALSAMixer output on my laptop now looked like the following after I implemented the above method (notice that Independent HP no longer exists):
So, what was the result? Well, audio continued to work after I removed Independent HP, but there was still no sound from headphones after resuming from suspension. And neither was there for Kiril, so he changed the title of his bug report to that effect. Fortunately, another user, unrud, commented later in the bug report that he had written init-headphone, a Python script to fix the problem. So I decided to hack his Ubuntu package to get
init-headphone working in my Gentoo Linux installation. Here is how I did it…
Second (successful!) attempt at fixing the problem
1. Download init-headphone-ubuntu-0.11.zip from https://github.com/Unrud/init-headphone-ubuntu/releases
2. Extract the contents to the directory
3. Copy to pm-utils’ hook directory the script that launches
init-headphone upon resuming or thawing:
4. Copy the
init-headphone script itself to the system binaries directory:
init-headphone script requires the
REQUIRED_MODULES = ["i2c_dev", "i2c_i801"]
However, I prefer to build them into the kernel rather than as modules, so I checked to make sure they are already built into the kernel:
Then I commented out the lines in
/usr/local/sbin/init-headphone that check if the two modules are loaded:
6. I created a script
/etc/local.d/99-clevo-hda-fix.start to launch
init-headphone automatically at boot:
#!/bin/bash # Fix for Intel HDA problem with Clevo W230ss # See https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1313904 exec /usr/local/sbin/init-headphone
7. Add the kernel boot parameter ‘
acpi_enforce_resources=lax‘ to the end of the kernel boot line(s) in
/boot/grub/grub.cfg (don’t forget to mount
/boot first if it is on another partition). You can either edit
/boot/grub/grub.cfg directly, or indirectly by adding the parameter to the list of existing parameters in
GRUB_CMDLINE_LINUX_DEFAULT (if any) as shown below and issuing the command ‘
grub2-mkconfig -o /boot/grub/grub.cfg‘ as root user (again, don’t forget to mount
/boot first if it is on another partition):
8. Create a script file
/etc/local.d/99-clevo-hda-fix.start to launch the
init-headphone automatically at boot:
#!/bin/bash # Fix for Intel HDA problem with Clevo W230SS # See https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1313904 exec /usr/local/sbin/init-headphone
9. As my user account does not have a path configured to the system binaries directory, I created a symlink to it from the directory
10. As I no longer needed to stop PulseAudio running at boot, I deleted the file
/home/fitzcarraldo/.config/pulse/client.conf I had created earlier (or you could just change ‘
autospawn = no‘ to ‘
autospawn = yes‘).
You can also use
init-headphone from the command line:
This looks like it has finally solved the problem; now headphones still work after my laptop resumes from suspension. I still don’t need to pass the ‘hint’ to the HD Audio driver, so Independent HP continues to appear in ALSAMixer and apparently does not cause any problems.
A big ‘Thank you’ from me to Unrud for creating
PROBLEM 2: No sound from headphones after re-plug
The other problem I experienced with the Clevo W230SS was that, if I unplugged working headphones, audio switched to the laptop’s speakers as expected, but, if I then plugged-in the headphones again, no more sound came from the headphones. If I again unplugged the headphones, sound would again come from the speakers. If I did all this whilst ALSAMixer was running, then:
- if I unplugged the headphones, as expected the ALSAMixer volume level indicator for the speaker would rise from zero and the volume level indicator for the headphones would drop to zero;
- if I plugged in the headphones, as expected the ALSAMixer volume level indicator for the speaker would drop to zero and the volume level indicator for the headphones would rise from zero.
Now, it is possible that this problem was due to the same thing that caused the loss of audio to headphones when the laptop resumed from suspension. Anyway, before I came across
init-headphone I found the following in the Arch Linux Wiki article on PulseAudio:
Switch on connect
This is a module used to switch the output sound to the newly connected device. For example, if you plug in a USB headset, the output will be switched to that. If you unplug it, the output will be set back to the last device. This used to be quite buggy but got a lot of attention in PulseAudio 8.0 and should work quite well now.
If you just want to test the module then you can load it at runtime by calling:
root # pactl load-module module-switch-on-connect
If you want to make the change persistent you will have to add it to your local pulseaudio settings or to /etc/pulse/default.pa (system wide effect). In either case, add this line:
So, as the file
/etc/pulse/default.pa in my installation did not have that line, I added it:
# Added by fitzcarraldo # https://wiki.archlinux.org/index.php/PulseAudio # The headphone socket no longer worked if I # removed and re-inserted the jack plug. load-module module-switch-on-connect
This seemed to help, but I am not certain
module-switch-on-connect is really having an effect when I plug and unplug headphones, and I have not bothered to disable it to see what happens now that
init-headphone is in use (I’m just happy that audio is all working now, whatever the reason!). ALSA’s Auto-Mute Mode* appears to perform the same role as
module-switch-on-connect: When I unplug the headphones with Auto-Mute Mode enabled in ALSAMixer, there is a noticeable delay before sound starts to come from the laptop’s speakers, whereas there is no such delay when I unplug the headphones with Auto-Mute Mode disabled via ALSAMixer, so presumably
module-switch-on-connect is doing its job.
* The documentation file
/usr/src/<kernel_release>/Documentation/sound/alsa/HD-Audio-Controls.txt explains what Auto-Mute Mode does.
Anyhow, one or both of the two software modifications (
module-switch-on-connect) seem to have cured the problem of no sound from headphones after they are disconnected then reconnected to the laptop.