Bug 205755 - limited sound on Lenovo Yoga C940
Summary: limited sound on Lenovo Yoga C940
Status: NEW
Alias: None
Product: Drivers
Classification: Unclassified
Component: Sound(ALSA) (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Jaroslav Kysela
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-12-03 17:12 UTC by Peter F. Patel-Schneider
Modified: 2020-06-23 15:38 UTC (History)
13 users (show)

See Also:
Kernel Version: 5.3.12
Tree: Mainline
Regression: No


Attachments
output of alsa-output.sh (50.22 KB, text/plain)
2019-12-03 17:12 UTC, Peter F. Patel-Schneider
Details

Description Peter F. Patel-Schneider 2019-12-03 17:12:38 UTC
Created attachment 286165 [details]
output of alsa-output.sh

The Lenovo Yoga C940 has five speakers (three in a sound bar and two on the bottom front).  Only two or maybe three of these speakers work out of the box.  

The hda sound card is an ALC298.  Probably some quirk is needed to get the extra speakers to work.

I've attached the output of alsa-info.sh

Using hda-analyzer I can confirm that
the speaker path is output 0x03 to mixer 0x0d to soundbar speakers 0x14
and that
the headphone path is output 0x02 to mixer 0x0c to headphones 0x21.

The other output pin complexes are 0x17, 0x1a, and 0x1e.  0x1e can only be connected to output 0x06 which is not amplified so this looks like an unconnected modem path.  I tried to enable 0x17 and 0x1a by connecting them to mixer 0x0d and unmuting them but no sound comes out.

So I'm stumped.  How could the other three (or two) speakers be connected?  Is there anything else I can try with HDA audio?  Or is it that the other speakers are only connected some other capability of the laptop?  (The mic appears to not be connected via HDA audio.)
Comment 1 Peter F. Patel-Schneider 2019-12-03 17:14:40 UTC
This problem probably affects other recent Lenovo laptops such as the Lenovo Yoga C930.  See https://bugzilla.kernel.org/show_bug.cgi?id=203409
Comment 2 Jaroslav Kysela 2019-12-11 16:19:56 UTC
A little info for Lenovo users (Yoga X1, C940): There are some I2S amplifiers on the path to buildin speakers and while they are initialized with some basic values for Carbon X1 in BIOS, the Yoga X1 and C940 has initialization only for two speakers there. I am trying to gather the necessary information to improve the kernel driver to support all speakers and the sound quality.
Comment 3 Peter F. Patel-Schneider 2019-12-11 22:06:30 UTC
Hah!  Finally a cause.  Great work!

Would it be useful to copy the Carbon X1 values over for the other laptops?  Also, I can run my C940 under Windows.  Is there a way to extract the necessary information there?
Comment 4 Jaroslav Kysela 2020-01-08 10:29:34 UTC
Another piece of information: C940 has Ti (Texas Instruments) I2S amplifiers which are different than Realtek amplifers in X1 7th / Yoga X1 7th. The amplifiers for X1 / Yoga X1 are initialized in EC (embedded controller). This initialization is missing for the Ti chip.

Because Windows works on those platforms and I have some little information that the Windows driver is more "brave" and sets those chips also according the usage (profiles), the Windows driver must have the initialization sequence build-in.

The amplifier chips communicate through I2C with the HDA codec, which has the master I2C interface controlled through HDA verbs. Most probably, it's a hidden, undocumented function for the "coefficient" HDA node 0x20 for the Realtek codecs (the node address might differ per the codec variant).

That's everything I have for now.
Comment 5 Peter Vaňušanik 2020-03-31 13:02:43 UTC
Any progress on this issue? I will be getting this laptop soon and it would be awesome if this was fixed :)
Comment 6 Jaroslav Kysela 2020-03-31 13:37:37 UTC
No, it's a bit impossible to get the right information from Lenovo. Many people involved (ThinkPad hardware team is different from the "game" hardware), no real answers. They should fix the BIOS to get things working properly on Linux unless they uncover the full chip specifications, so we can do the proper support.

Another way may be to reverse engineer the Windows driver using qemu (trace PCI I/O) or so. A nice project for an student.
Comment 7 AleksF 2020-04-02 05:46:56 UTC
Any chance that this fix might work?
It's for the yoga c930.

https://github.com/droserasprout/lenovo-yoga-c930-linux
Comment 8 AleksF 2020-04-02 05:48:44 UTC
(In reply to AleksF from comment #7)
> Any chance that this fix might work?
> It's for the yoga c930.
> 
> https://github.com/droserasprout/lenovo-yoga-c930-linux

for comparison, this is the c930 bug report which also has a problem in initialization of the speakers apparently.

https://bugzilla.kernel.org/show_bug.cgi?id=203409
Comment 9 daniel 2020-04-02 12:32:35 UTC
This is a more relevant link for the c940

https://wiki.archlinux.org/index.php/Lenovo_Yoga_c940
Comment 10 AleksF 2020-04-02 20:48:08 UTC
Yes, I actually came to this page from the arch wiki link you posted. In fact, the author says he didn't try to activate the speakers as suggested in the link I posted before, which worked for the C930 and could be working for the c940. 

I don't understand enough to give the following method a try, but it could potentially work.

So the initialization method we need for the c940 should stem from the one that worked for the c930 here:

https://bugzilla.kernel.org/show_bug.cgi?id=203409


If it works, I will update the arch wiki accordingly. Currently the arch wiki is linking to here.
Comment 11 kxchan 2020-04-03 03:56:33 UTC
I don't know if contacting Lenovo after-sales will help, I'm from China. I'll try it this weekend.
Comment 12 Peter Vaňušanik 2020-04-04 08:53:10 UTC
AleksF: I tried that pin override but it did nothing, which is a shame, since with only 2 speakers out of 5 laptop is really quiet
Comment 13 Peter Vaňušanik 2020-04-05 19:27:30 UTC
J. Kysela:

I tried to determine the windows driver process but audio is grouped with southbridge and smbus:

IOMMU Group 11:
	00:1f.0 ISA bridge [0601]: Intel Corporation Ice Lake-LP LPC Controller [8086:3482] (rev 30)
	00:1f.3 Multimedia audio controller [0401]: Intel Corporation Smart Sound Technology Audio Controller [8086:34c8] (rev 30)
	00:1f.4 SMBus [0c05]: Intel Corporation Ice Lake-LP SMBus Controller [8086:34a3] (rev 30)
	00:1f.5 Serial bus controller [0c80]: Intel Corporation Ice Lake-LP SPI Controller [8086:34a4] (rev 30)
Comment 14 Peter Vaňušanik 2020-04-05 19:52:23 UTC
Okay never mind, I lied. I managed to get perfect audio in windows virtualization. Here is the log out of qemu, no idea how to read it though:

https://gist.github.com/Enerccio/57c9b38e2096a87e4f1a67d25952c391

Tell me if you need anything more, Jaroslave ;)
Comment 15 Peter F. Patel-Schneider 2020-04-05 20:09:21 UTC
Wow!  That's a lot of activity.  What are the steps to getting this output?
Comment 16 Peter Vaňušanik 2020-04-05 20:21:34 UTC
Log is bigger because i included playback of youtube audio just to be sure. 

I followed this tutorial: https://digriz.org.uk/tutorials/reversing-pci-drivers
with some changes, ie paths and such. 

For qemu install I followed https://github.com/qemu/qemu/blob/master/docs/devel/tracing.txt simple variant. 

My commands were: for installing windows

sudo qemu-system-x86_64 \
    -machine accel=kvm \
    -cpu host -smp 2 -m 2G \
    -bios /usr/share/ovmf/x64/OVMF_CODE.fd \
    -drive file=/storage/tmp/qemu/mswin10.qcow2,if=virtio,snapshot=off \
    -nic user \
    -device usb-ehci,id=ehci -usbdevice tablet \
    -soundhw hda \
    -rtc base=localtime \
    -drive file=/storage/tmp/Win10_1909_English_x64.iso,media=cdrom \
    -drive file=/usr/share/virtio/virtio-win.iso,media=cdrom \
    -boot once=d

Modprobes:

sudo modprobe -r snd_sof_pci
sudo modprobe -r i2c_i801
sudo modprobe vfio-pci ids=8086:34c8,8086:3482,8086:34a3,8086:34a4

For actual runtime (this was compiled qemu from git): 

sudo qemu/x86_64-softmmu/qemu-system-x86_64 \
    -machine accel=kvm \
    -cpu host -smp 2 -m 2G \
    -bios /usr/share/ovmf/x64/OVMF_CODE.fd \
    -drive file=/storage/tmp/qemu/mswin10.qcow2,if=virtio,snapshot=off \
    -nic user \
    -device usb-ehci,id=ehci -usbdevice tablet \
    -soundhw hda \
    -rtc base=localtime \
    -drive file=/storage/tmp/Win10_1909_English_x64.iso,media=cdrom \
    -drive file=/usr/share/virtio/virtio-win.iso,media=cdrom \
    -device vfio-pci,host=00:1f.3,x-no-mmap=on \
    -trace events=events 2>&1 | tee trace

This was all done on latest manjaro xfce fwiw.
Comment 17 Peter Vaňušanik 2020-04-05 20:23:09 UTC
Also I installed lenovo audio drivers in guest windows 10. It picked it up immediately and playback was great, every speaker worked.
Comment 18 Peter Vaňušanik 2020-04-05 20:25:01 UTC
I forgot the event file which was generated from all events with the sid in the tutorial (tutorial tells to use different file): https://gist.github.com/Enerccio/663c6a1fdba122aa15c5eac497a5b72f
Comment 19 Peter Vaňušanik 2020-04-05 20:35:05 UTC
And just to be extra sure, this is log of only booting the windows and logging in the account, nothing else 

https://gist.github.com/Enerccio/8405ade9b7e9cf03b6673c5dac4eacfa
Comment 20 Peter F. Patel-Schneider 2020-04-09 22:01:27 UTC
Thanks, that at least is shorter.
But I can't see any way of determining which of the writes are to the nodes in the ALC298, so that I can try to figure out what is going on, at least without some documentation, which I don't know how to get.  Does anyone have this documentation?
Comment 21 Peter Vaňušanik 2020-04-10 06:19:45 UTC
I only found this: https://www.hardwaresecrets.com/datasheets/alc269.pdf
Comment 22 Jaroslav Kysela 2020-04-10 08:37:17 UTC
Have you tried something like this to decode this contents?  https://github.com/Conmanx360/QemuHDADump/wiki/Setup-and-usage-of-the-program

We need to collect the HDA verb read/write calls and add missing parts to the Linux driver.

The public codec documentation is incomplete. Realtek codecs have hidden registers (masked as coefficient node). Also it appears that some Realtek codecs has integrated I2C bus controller which can attach and control additional chips like amplifiers.
Comment 23 Peter Vaňušanik 2020-04-10 09:15:32 UTC
I have the raw dumps from those runs, I can upload them somewhere. I will later check more the link you provided.
Comment 24 Peter Vaňušanik 2020-04-10 10:33:53 UTC
@Jaroslav Kysela: Here are the dumps:

https://github.com/Enerccio/lenovo-c940-dumps
Comment 25 Peter Vaňušanik 2020-04-10 10:45:49 UTC
Just to clarify, these are the frame dumps from the link you posted, not my old trace dumps
Comment 26 Peter Vaňušanik 2020-04-21 08:12:06 UTC
Anything else I can do?
Comment 27 Tim Ryder 2020-05-07 22:30:17 UTC
I have the C940, same issue.  Anything that would be helpful from my system?
Also now that Lenovo will be releasing laptops with fedora, any chance fedora can get them to help?
Comment 28 AleksF 2020-05-08 00:05:16 UTC
I also tried connecting the pins with Hda-Jack-retask but had no luck, although I'm not sure I'm doing it right.
Comment 29 Peter F. Patel-Schneider 2020-05-08 00:14:26 UTC
It seems that what is needed is to turn on some amplifiers.   However, there is no documentation on this and the dumps (above) need to be interpreted by someone who knows how to decode them or someone needs to point to a document on how to interpret them.

I expect that Lenovo will only be releasing ThinkPads with Fedora (same as they have done for other Linux distributions) so this IdeaPad will not be covered.

It may even be that no one in Lenovo knows how to turn on the amplifiers as it is very likely that they are turned on by a driver provided by RealTek.
Comment 30 Peter Vaňušanik 2020-05-08 05:34:19 UTC
Maybe we can ask realtek to give us the info?
Comment 31 Jaroslav Kysela 2020-05-08 07:46:25 UTC
(In reply to Tim Ryder from comment #27)
> I have the C940, same issue.  Anything that would be helpful from my system?
> Also now that Lenovo will be releasing laptops with fedora, any chance
> fedora can get them to help?

I am the Fedora guy. It seems that the gaming laptops are developed in another ground than ThinkPads (I was not able to gather the correct information in the two week discussion with various Lenovo people). Also, appearently, the Windows driver code is developed by the chip vendor (Texas Instruments for amplifiers), thus Realtek might not have this info (amplifiers). Lenovo just puts those driver pieces together (Realtek, Texas Instruments).

(In reply to Peter F. Patel-Schneider from comment #29)
> It seems that what is needed is to turn on some amplifiers.   However, there
> is no documentation on this and the dumps (above) need to be interpreted by
> someone who knows how to decode them or someone needs to point to a document
> on how to interpret them.

Right. From the first glance, we may extract something from the dumps and try to reproduce the Windows settings, but it requires a time (and I am working on another things - sorry). It might be a nice project for a student.
Comment 32 Jaroslav Kysela 2020-05-08 07:48:53 UTC
Sorry typo "in another ground than ThinkPads" should be "in another group than ThinkPads".
Comment 33 Nate Graham 2020-05-21 19:42:43 UTC
I got in touch with a Lenovo Linux kernel engineer about this issue and received permission to post the following:




Here is the Ti amp Initial code which may help

w 82 00 00 # Page-0
w 82 7f 00 # Book-0
w 82 01 01 # Software Reset

w 84 00 00 # Page-0
w 84 7f 00 # Book-0
w 84 01 01 # Software Reset

d 01 # 1mS Delay

w 82 00 01 #page 1
w 82 32 e8 # Disable clock halt detection, after clock error is 
detected w 82 00 00 # w 82 3c 11 w 82 0f 42 # TDM TX voltage sense 
transmit enable with slot 2, w 82 10 40 # TDM TX current sense 
transmit enable with slot 0 w 82 03 00 # 11 dB gain w 82 02 00 # power 
up audio playback with I,V enabled

w 84 00 01 #page 1
w 84 32 e8 # Disable clock halt detection, after clock error is 
detected w 84 00 00 # w 84 3c 11 w 84 0f 46 # TDM TX voltage sense 
transmit enable with slot 6, w 84 10 44 # TDM TX current sense 
transmit enable with slot 4 w 84 03 00 # 11 dB gain w 84 02 00 # power 
up audio playback with I,V enabled



Does that help at all?
Comment 34 Tim Ryder 2020-06-16 23:59:48 UTC
Would love to see if there is anyway to use the TI amp Initial code to get this to work, just not sure how to do that.  My son is a programmer and I'm a Linux admin.  Thought maybe the 2 of us together could figure it out if someone could point us in the right direction to start.

Note You need to log in before you can comment on or make changes to this bug.