Created attachment 184561 [details]
I attached ALSA logs from two kernels 4.0.8 and 4.1.3 in both plugged and unplugged status of headsets.
I'm using Fedora 22, kernel 4.1.3-200.fc22.x86_64 on my laptop Lenovo M30-70.
On the system's start the internal microphone works well, even if I plug in the headset at first time it works fine too.
But if I unplug the headset then the internal microphone stops working at all. The the same also happens for headset microphone if I try to plug it in back.
Once I connect and disconnect the headset both microphones are just producing a white noise.
I tested it with several headsets with the same result.
However with the kernel 4.0.8 everything works just fine.
Could you give the states where
- built-in mic works
- built-in mic broken (after unplugging the headset)
on 4.1.x kernel?
The high suspect is the widget power-saving. Try to disable it like below:
- Create /lib/firmware/alsa/hda containing the following
0x10ec0233 0x17aa3802 0
power_save_node = false
- Create /etc/modprobe.d/50-hda.conf containing the following line:
options snd-hda-intel patch=,alsa/hda
(The comma after "patch=" is no typo; we need to pass it to the second instance.)
Created attachment 184621 [details]
internal microphone works
Created attachment 184631 [details]
internal microphone is broken
I think you were right guessing the core of the issue.
After I added two above files with disabling of power saving widget having made the system's restart, the problem with microphones didn't appear anymore.
Let me know if logs are insufficient/incorrect or you need more ones.
P.S. note that I wrote both logs before adding those files.
The obvious difference is that NID 0x12 gets powered down in the broken case. But this should have been powered up at starting the stream again.
How did you check the mic? Did you record or check the loopback?
Please try the following:
- After a boot, start recording, and confirm that the built-in mic is working.
Keep recording and get the alsa-info.sh output once.
- While keeping recording, plug / unplug the headset.
Is the buit-in mic broken? If yes, take alsa-info.sh output at this point, too.
Created attachment 184881 [details]
built mic works on kernel 4.1.4
Created attachment 184891 [details]
built mic is broken on kernel 4.1.4
Created attachment 184901 [details]
record with broken mic
As you can hear from it there's the same voice that's returning back to itself in recursion.
Created attachment 184911 [details]
live histogram with broken mic
as you can see from histogram there's returning loop that you can hear as a result in the attached above sound record
During my test I used a simple sound recorder App with a live histogram.
So in the beginning after boot everything worked fine and I was able to see histogram changes as a reaction on my voice.
Then I simply plugged a headset and it was enough for mic to get broken.
Note that for the test I removed both files from you first comment in this thread.
In the alsa-info.sh output in comment 7 indicates that "Mic Jack" = true, i.e. the mic jack is detected. Are you sure that this is the state without mic plugged?
I think it was wrong log. "Mic Jack" = true happens only when the headset is plugged in.
BTW in my last test it was enough to plug in the headset only at once after system's start to brake the microphone.
In my opinion the issue happens when the system reacts connection or disconnection with a headset and tries to switch between built in microphone and the headset's one.
Please see bellow logs.
Created attachment 185281 [details]
built in mic is broken on kernel 4.1.5
Created attachment 185291 [details]
headset mic is broken on kernel 4.1.5
OK, then the next step is to confirm who turns off (and doesn't turn on) the expected NIDs (0x11 and 0x12). To see this, try the following as root:
- After boot, confirm that the built-in mic is working:
arecord -vv foo.wav
This will show you a VU meter while recording on foo.wav.
- Keep this recording, and run like:
echo 1 > /sys/kernel/debug/tracing/events/hda/enable
This will enable the tracing of HD-audio events.
- Plug the headset (the arecord is still running), and confirm that headset mic is working (see VU meter).
- At this moment (mic still working), get the trace snapshot:
cat /sys/kernel/debug/tracing/trace > mic-working
- Get alsa-info.sh snapshot once
- Clear the trace buffer once:
echo > /sys/kernel/debug/tracing/trace
- Unplug the headset (keeping arecord running), and confirm that build-int mic is broken (see VU meter).
- At this moment of breakage, get the trace snapshot again:
cat /sys/kernel/debug/tracing/trace > mic-broken
- Get alsa-info.sh snapshot again.
- Stop arecord, and disable tracing
echo 0 > /sys/kernel/debug/tracing/events/hda/enable
- Attach both trace logs and alsa-info.sh outputs.
Since in order to break microphone on kernel 4.1.5 it's enough to plug the headset only one time after system's start, my scenario of tests was a little bit different:
- arecord -vv foo.wav (built-in mic is working)
- echo 1 > /sys/kernel/debug/tracing/events/hda/enable
- cat /sys/kernel/debug/tracing/trace > mic-working
- writing "alsa_built_in_mic_working_4.1.5.log" file (on this stage the built-in mic is working and the headset isn't plugged yet)
- echo > /sys/kernel/debug/tracing/trace
- I'm plugging the headset (on this stage arecord is running but the headset mic is already broken and I can see that on VU meter)
- cat /sys/kernel/debug/tracing/trace > mic-broken
- writing "alsa_headset_mic_broken_4.1.5.log" file
- unplugging the headset
- writing "alsa_built_in_mic_broken_4.1.5.log" file (on this stage the built-in mic is broken as well and arecord is still running)
- stopping arecord
- echo 0 > /sys/kernel/debug/tracing/events/hda/enable
Created attachment 185361 [details]
alsa built in mic working on kernel 4.1.5
Created attachment 185371 [details]
alsa headset mic broken on kernel 4.1.5
Created attachment 185381 [details]
alsa built in mic broken on kernel 4.1.5
Thanks but the most important pieces are missing: the contents of /sys/debug/kernel/tracing/trace at each state. Do like following:
- echo 1 > /sys/debug/kernel/tracing/events/hda/enable
- Plug the headset
- cat /sys/debug/kernel/tracing > headset-plugged
- echo > /sys/debug/kernel/tracing
- Unplug the headset
- cat /sys/debug/kernel/tracing > headset-unplugged
- echo 0 > /sys/debug/kernel/tracing/events/hda/enable
And attach both headset-plugged and headset-unplugged files.
Created attachment 185411 [details]
trace headset plugged
Sure, you're welcome.
Created attachment 185421 [details]
trace headset unplugged
Thanks. I think I spotted out the culprit.
Could you try two patches below?
Created attachment 185601 [details]
Fix patch #1
Created attachment 185611 [details]
Fix patch #2
Hi and sorry for the delay.
Should I build a new kernel module with a patched version of hda_generic.c source file?
I recently succeeded to build a new module file with "ko" extension using your source "hda_generic.c".
Then I tried to load this module by running command:
sudo modprobe -v hda_generic
Its ouptput was as following:
modprobe: ERROR: could not insert 'hda_generic': Unknown symbol in module, or unknown parameter (see dmesg).
When I was looking on dmesg I found related error message:
[ 912.104583] hda_generic: exports duplicate symbol hda_extra_out_badness (owned by snd_hda_codec_generic)
As far I as I understand it appears to be a conflict with an existing kernel module "snd_hda_codec_generic".
When I attempted to unload this module I got an error telling "modprobe: FATAL: Module snd_hda_codec_generic is in use."
I'd appreciate if you share your thoughts of it.
Likely you built a module wrongly.
In anyway, the patches have already landed to the upstream tree, and will be backported to stable kernels later. So, just wait for a while. It may take some time until it reaches to stable tree, as usually there are many patches pending at the beginning of merge window.
Just wanted to thank you.
Since version of kernel 4.1.7 the problem does not appear any more.