Bug 151521

Summary: Sound not working on Acer Chromebook R11 (CYAN) braswell / cherryview / cherry trail
Product: Drivers Reporter: Timo Jyrinki (timo.jyrinki)
Component: Sound(ALSA)Assignee: Jaroslav Kysela (perex)
Status: NEW ---    
Severity: normal CC: bryan.quigley+bugs, darethehair, ian, mildred-bug.kernel, pierre-louis.bossart, reynhout, t.jp, t.powa, tiwai, vinod.koul
Priority: P1    
Hardware: x86-64   
OS: Linux   
Kernel Version: 4.7 Subsystem:
Regression: No Bisected commit-id:
Attachments: dmesg
dmidecode
lshw
lspci
dmesg 4.8rc1
Possible fix
ACPI support
logs to show race condition
Fix I2S configs and remove useless code
solve NULL dereference
UCM file

Description Timo Jyrinki 2016-08-05 07:04:52 UTC
Created attachment 227601 [details]
dmesg

It's a Braswell 14nm platform with Coreboot and SeaBIOS as a payload to boot Ubuntu 16.10 (+ mainline 4.7 kernel). Sound does not work and the UIs don't show any devices either since pulseaudio fails so start with "failed to detect any sound hardware".

According to Chromebook community person, there might be some required initialization missing that the ChromeOS payload ("depthcharge") is usually responsible for.

alsa-info at: http://www.alsa-project.org/db/?f=c193a12f53608b68d259f574b4791d18a522a000

dmesg, dmidecode, lshw, lspci as attachments.
Comment 1 Timo Jyrinki 2016-08-05 07:05:21 UTC
Created attachment 227611 [details]
dmidecode
Comment 2 Timo Jyrinki 2016-08-05 07:05:44 UTC
Created attachment 227621 [details]
lshw
Comment 3 Timo Jyrinki 2016-08-05 07:06:03 UTC
Created attachment 227631 [details]
lspci
Comment 4 Timo Jyrinki 2016-08-08 14:06:46 UTC
It seems these should get merged?

https://github.com/plbossart/sound/branches/all?query=byt-cht
Comment 5 Takashi Iwai 2016-08-09 20:03:04 UTC
The relevant codes have been already merged to upstream recently.
Could you try 4.8-rc1?
Comment 6 Timo Jyrinki 2016-08-10 13:57:03 UTC
Created attachment 228161 [details]
dmesg 4.8rc1

No change, no sound and cht-bsw-max98090 cht-bsw-max98090: snd_soc_register_card failed -517
Comment 7 Vinod Koul 2016-08-22 09:49:19 UTC
(In reply to Timo Jyrinki from comment #6)
> Created attachment 228161 [details]
> dmesg 4.8rc1
> 
> No change, no sound and cht-bsw-max98090 cht-bsw-max98090:
> snd_soc_register_card failed -517

SST driver seems to initialze well. This i2c seems to fail..

[   19.972195] cht-bsw-max98090 cht-bsw-max98090: ASoC: i2c-104C227E:00 not registered
[   19.972207] cht-bsw-max98090 cht-bsw-max98090: snd_soc_register_card failed -517

I will check the codec on this device, if you know please do let me know...
Comment 8 Vinod Koul 2016-08-24 08:21:35 UTC
okay I checked. With coreboot this seems to work fine.

Cna you check the SeaBIOS used and get it to create the I2C device 104C227E so codec can be loaded thus completing the sound card
Comment 9 Timo Jyrinki 2016-08-24 09:27:31 UTC
Thank you, sounds like a very useful bit of information. I've passed on the info to the G+ coreboot on Chromebooks community where the people creating the SeaBIOS images are.
Comment 10 Timo Jyrinki 2016-08-24 10:51:23 UTC
And copy-pasting here (from https://plus.google.com/u/0/+TimoJyrinki/posts/R1AqYCSPru8 ):

"SeaBIOS doesn't do hardware initialisation, that's down to coreboot, so no, I can't. Obviously, the sound hardware works under the ChromeOS kernel so I would guess they need to figure out what the ChromeOS kernel is doing that upstream isn't."
Comment 11 Timo Jyrinki 2016-08-26 09:07:20 UTC
From the discussion over there it sounds to me that Coreboot itself does no sound initialization, but the 'depthcharge' payload started from Coreboot when booting to ChromeOS does do a codec init.

However SeaBIOS payload doesn't do anything sound initialization related so it'd be wished that the kernel would do that instead if it wasn't done by the Coreboot and its payload.
Comment 13 Mildred 2017-02-08 08:36:54 UTC
It seems that the chromeos driver does some things differently depending on ACPI (which mainline doesn't). In above link for sound/soc/codecs/ts3a227e.c contains:




#ifdef CONFIG_ACPI
static struct acpi_device_id ts3a227e_acpi_match[] = {
	{ "104C227E", 0 },
	{},
};
MODULE_DEVICE_TABLE(acpi, ts3a227e_acpi_match);
#endif

static struct i2c_driver ts3a227e_driver = {
	.driver = {
                ...
		.acpi_match_table = ACPI_PTR(ts3a227e_acpi_match),
	},





sound/soc/intel/boards/cht_bsw_max98090_ti.c in mainline kernel seems to already be able to detect the correct device:




static int snd_cht_mc_probe(struct platform_device *pdev)
{
	...
	drv->ts3a227e_present = acpi_dev_found("104C227E");
Comment 14 Mildred 2017-02-08 10:24:46 UTC
Created attachment 254591 [details]
Possible fix

This patch comes directly from the chromium tree.
Comment 15 reynhout 2017-02-09 03:42:58 UTC
Kernel 4.9 with patch from https://bugzilla.kernel.org/show_bug.cgi?id=151521#c14 yields some new log messages.

Excerpted here: https://paste.debian.net/913490

Definite progress, now it looks like jack detection is not set up properly (causing null pointer deref). The module loads, but the device is not visible.
Comment 16 Mildred 2017-02-15 13:03:22 UTC
There is a null pointer in ts3a227e_enable_jack_detect. The function looks like this in sound/soc/codecs/ts3a227e.c:

int ts3a227e_enable_jack_detect(struct snd_soc_component *component,
				struct snd_soc_jack *jack)
{
	struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component);

	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);

	ts3a227e->jack = jack;
	ts3a227e_jack_report(ts3a227e);

	return 0;
}

Given the calling context in from sound/soc/intel/boards/cht_bsw_max98090_ti.c:

static int cht_max98090_headset_init(struct snd_soc_component *component)
{
	struct snd_soc_card *card = component->card;
	struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card);

	return ts3a227e_enable_jack_detect(component, &ctx->jack);
}

And the driverdata struct:

struct cht_mc_private {
	struct snd_soc_jack jack;
	bool ts3a227e_present;
};

Unless ctx in cht_max98090_headset_init is null, &ctx->jack cannot be null, and the jack variable in ts3a227e_enable_jack_detect cannot be null. Tho options here:

- either the snd_soc_card driver data is null (card not initialized?)
- or ts3a227e_enable_jack_detect crashes because ts3a227e is null, which is the snd_soc_component driver data (component not initialized?)
- or ts3a227e_enable_jack_detect crashes because there is another pointer that is null. It doesn't look so...


The snd_soc_card driver data is initialized here:


static int snd_cht_mc_probe(struct platform_device *pdev)
{
	int ret_val = 0;
	struct cht_mc_private *drv;

	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
	if (!drv)
		return -ENOMEM;

	drv->ts3a227e_present = acpi_dev_found("104C227E");
	if (!drv->ts3a227e_present) {
		/* no need probe TI jack detection chip */
		snd_soc_card_cht.aux_dev = NULL;
		snd_soc_card_cht.num_aux_devs = 0;
	}

	/* register the soc card */
	snd_soc_card_cht.dev = &pdev->dev;
	snd_soc_card_set_drvdata(&snd_soc_card_cht, drv);
	ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
	if (ret_val) {
		dev_err(&pdev->dev,
			"snd_soc_register_card failed %d\n", ret_val);
		return ret_val;
	}
	platform_set_drvdata(pdev, &snd_soc_card_cht);
	return ret_val;
}

Which is referenced in the platform driver:

static struct platform_driver snd_cht_mc_driver = {
	.driver = {
		.name = "cht-bsw-max98090",
	},
	.probe = snd_cht_mc_probe,
};

module_platform_driver(snd_cht_mc_driver)

I didn't see where snd_soc_component_set_drvdata was called...
Comment 17 Pierre Bossart 2017-02-21 02:45:23 UTC
The kernel oops is caused by a race condition, see logs below:

[    7.109294] CHT_MAX98090_HEADSET_INIT 
[    7.109312] jack is NULL, detection not enabled 
[    7.109434] cht-bsw-max98090 cht-bsw-max98090: snd-soc-dummy-dai <-> media-cpu-dai mapping ok
[    7.109499] cht-bsw-max98090 cht-bsw-max98090: snd-soc-dummy-dai <-> deepbuffer-cpu-dai mapping ok
[    7.109542] compress asoc: snd-soc-dummy-dai <-> compress-cpu-dai mapping ok
[    7.109549] CHT_CODEC_INIT 
[    7.112443] cht-bsw-max98090 cht-bsw-max98090: HiFi <-> ssp2-port mapping ok

Basically the ..init = cht_max98090_headset_init is called before .init = cht_codec_init, but the latter initializes the jack.

I think the soc-core framework should have a notion that an aux_dev should be initialized after the codec DAIs? The ChromeOs code is pre-component so it's really hard to figure out what needs to be done here.

Vinod, any thoughts?
Comment 18 Pierre Bossart 2017-02-21 02:46:29 UTC
Created attachment 254845 [details]
ACPI support
Comment 19 Pierre Bossart 2017-02-21 02:46:58 UTC
Created attachment 254847 [details]
logs to show race condition
Comment 20 Vinod Koul 2017-02-21 20:03:13 UTC
(In reply to Pierre Bossart from comment #17)
> The kernel oops is caused by a race condition, see logs below:
> 
> [    7.109294] CHT_MAX98090_HEADSET_INIT 
> [    7.109312] jack is NULL, detection not enabled 
> [    7.109434] cht-bsw-max98090 cht-bsw-max98090: snd-soc-dummy-dai <->
> media-cpu-dai mapping ok
> [    7.109499] cht-bsw-max98090 cht-bsw-max98090: snd-soc-dummy-dai <->
> deepbuffer-cpu-dai mapping ok
> [    7.109542] compress asoc: snd-soc-dummy-dai <-> compress-cpu-dai mapping
> ok
> [    7.109549] CHT_CODEC_INIT 
> [    7.112443] cht-bsw-max98090 cht-bsw-max98090: HiFi <-> ssp2-port mapping
> ok
> 
> Basically the ..init = cht_max98090_headset_init is called before .init =
> cht_codec_init, but the latter initializes the jack.
> 
> I think the soc-core framework should have a notion that an aux_dev should
> be initialized after the codec DAIs? The ChromeOs code is pre-component so
> it's really hard to figure out what needs to be done here.
> 
> Vinod, any thoughts?


Use late_probe?

This seems to be called after all DAIs are init, That will guarantee
that aux codecs are init too :)
Comment 21 Vinod Koul 2017-02-21 20:04:51 UTC
On Tue, 2017-02-21 at 02:45 +0000, bugzilla-daemon@bugzilla.kernel.org
wrote:
> https://bugzilla.kernel.org/show_bug.cgi?id=151521
> 
> --- Comment #17 from Pierre Bossart (pierre-louis.bossart@linux.intel.
> com) ---

> Basically the ..init = cht_max98090_headset_init is called before
> .init =
> cht_codec_init, but the latter initializes the jack.
> 
> I think the soc-core framework should have a notion that an aux_dev
> should be
> initialized after the codec DAIs? The ChromeOs code is pre-component
> so it's
> really hard to figure out what needs to be done here.
> 
> Vinod, any thoughts?

Use late_probe?

This seems to be called after all DAIs are init, That will guarantee
that aux codecs are init too :)
Comment 22 Pierre Bossart 2017-02-21 21:39:43 UTC
In soc-core.c, the aux_dev are probed before the dailinks, so there is an intrinsic issue here. the aux_dev.init() can't do anything that depends on something else really.

Attached patches fix the problem, also added some corrections for I2S mode which probably never worked.

The cyan device is still silent for now but at least it's better than it was...
Comment 23 Pierre Bossart 2017-02-21 21:41:04 UTC
Created attachment 254865 [details]
Fix I2S configs and remove useless code
Comment 24 Pierre Bossart 2017-02-21 21:41:47 UTC
Created attachment 254867 [details]
solve NULL dereference
Comment 25 Pierre Bossart 2017-02-21 21:42:39 UTC
Created attachment 254869 [details]
UCM file
Comment 26 Mildred 2017-08-20 18:48:56 UTC
A solution was found at GitHub https://github.com/GalliumOS/galliumos-distro/issues/317#issuecomment-322658720 to make the sound work on CYAN hardware. I tested for my computer and it works.

Basically there is a patch needed to the kernel, sound codec ts3a227e and intel board cht_bsw_max98090_ti:

https://github.com/GalliumOS/galliumos-distro/files/1226989/cyan-audio-driver-fix.patch.txt

(basically there should be nothing new here compared to other patchs posted here previously)

Then ALSA UCM files from ChromiumOS tree should be used:

https://chromium.googlesource.com/chromiumos/third_party/adhd/+/master/ucm-config/cyan/chtmax98090

They should be put in /usr/share/alsa/ucm/chtmax98090/

A patch is needed in the UCM files:

https://github.com/GalliumOS/galliumos-distro/files/1226991/ucm-mod-to-enable-audio.patch.txt

Then, the hardware is recognized but audio doesn't work. Tweaking the ALSA settings makes it work.

Here:

https://github.com/GalliumOS/galliumos-distro/issues/317#issuecomment-323477943

There is a asound.state file to download to set the mixer settings of the audio card to the correct settings so audio works:

https://github.com/GalliumOS/galliumos-distro/files/1235825/asound.state.txt

Basically: alsactl -f downloaded/asound.state.txt restore 1 (where 1 is the number of the ALSA device) should set the settings required so audio works.

- Speakers are working
- Headset is working (detection does not work)
- Internal mic is working
- the rest is still untested (headset microphone)

Now that it works, what do we need to get this shipped?
Comment 27 darethehair 2018-03-28 19:51:29 UTC
I installed kernel 4.15.0 on my Acer Chromebook R11 running Linux Mint Debian Edition, in hopes that the kernel patches described above had already made it there.

Can anyone confirm that this occurred, or provide a suggestion for me moving forward to get my speaker sound working e.g. wait till 4.16?

Thanks!
Comment 28 darethehair 2018-03-29 14:46:47 UTC
UPDATE: To answer my own question, kernel 4.15 appears to have the necessary kernel patches installed, and the instructions by Mildred just ahead of my own were very useful to get sound *mostly* working on my R11 Chromebook under LMDE.  Two issues were encountered:

- the firmware drivers necessary for this to work were missing from my distro, and I had to manually install the 'firmware-intel-sound' package (that I got from https://packages.debian.org/sid/firmware-intel-sound)

- the 'alsa' commands that I typically use in '.xbindkeysrc' do not change the volume levels -- even though the volume 'slider' display shows the proper usage of these keys, and so I had to supplement them with matching 'pactl set-sink-mute 1...' commands to get interactive volume changes to work.  Even now, I am worried a bit of these commands getting out-of-sync with each other -- perhaps I should ignore alsa entirely (?)

Not that it is really needed by those reading this, but I have documented all of this on my web page (for my own sake).  

Anyone else have similar success and/or advise?
Comment 29 Tim Jester-Pfadt 2018-06-10 08:48:06 UTC
I installed Arch Linux on my Acer R11 today.
Linux archlinux 4.16.13-2-ARCH #1 SMP PREEMPT Fri Jun 1 18:46:11 UTC 2018 x86_64 GNU/Linux

With latest GNOME and Pulseaudio I only had to place the two UCM config files into /usr/share/alsa/ucm/chtmax98090/ and apply the patch to Hifi.conf.
The firmware is installed on Arch Linux by default. I restarted and speakers worked out of the box without messing with alsa configs. Headphones also work when switching the sink manually in GNOME Audio Settings. Unfortunately, the internal mic doesn't work neither does my headset mic work. There is no input source that would let me select the microphones.

Once I map my media keys the media control should work since I can change volume via the GNOME Audio slider.

If I manage to get input audio to work I'll keep this as daily driver. I tried the latest GalliumOS also with acpid, which should enable headphone jack detection but it didn't work for me (the detection, audio worked also input).
Comment 30 Tim Jester-Pfadt 2018-06-10 10:55:24 UTC
Update: Microphone does seem to work even tough it's not listed as an input source. I applied the asound.state file as explained above and first sound came from both headset and speaker. I changed output sinks once to fix this. I tried a Skype Echo Call on web.skype.com and it worked with the headset microphone. Maybe it already would have worked without the asound.state file. Internal micro also registers input in the GNOME Audio settings.

Media keys also work. Only thing left is headphone jack detection. This could probably be handled via a script.
Comment 31 Timo Jyrinki 2019-11-19 08:12:58 UTC
In downstream bug report http://pad.lv/1609750 it was noted that this patch would be needed: https://github.com/torvalds/linux/commit/d5e120422db8808e1c8b1507900ca393a877c58f

However I've tested 5.4rc7 and it does not seem to help. Do people know of other non-upstreamed patches required for the audio to work?
Comment 32 Pierre Bossart 2019-11-19 17:13:22 UTC
if you can recompile a kernel, using Mark Brown's for-next should have have all the latest changes from Google for Cyan.
Comment 33 Bryan Quigley 2020-03-18 21:03:17 UTC
I can get sound to work with a 5.4 kernel - but it's still not great...

I haven't found a UCM file that let's it just work yet. What does work is using the alsactl -f downloaded/asound.state.txt bit and then VLC is able to play sound with Audio device set to chtmax98090, Direct hardware device without any conversions.

Should this just work without any ucm/alsa restore?
Comment 34 Bryan Quigley 2020-03-18 21:39:56 UTC
I spoke to soon, trying out the galliumos-baytrail deb on Lubuntu gave me some better success.

Right now, it appears I have working sound on every reboot with just this file from that package:https://github.com/GalliumOS/galliumos-baytrail/blob/master/etc/pulse/default.pa
(this may depend on having saved asound.state first (or possibly put into /var/lib/alsa/ by package)
Comment 35 dreck 2021-09-25 11:57:54 UTC
Any update on this?  Having issues with sound working for some time, than suddenly stopping with a buzzing sound.  Will attempt to modify patch for most recent kernel, but my understanding is the kernel should already be patched. Works fine on galliumos, but not with any other distro or most recent kernel
Comment 36 Timo Jyrinki 2021-09-27 06:34:20 UTC
I don't have problems running Ubuntu 20.04 LTS with (original, non-HWE kernel) 5.4 series kernel these days. Granted, I've probably indeed modified the default.pa as indicated above, and have had a state file which I've restored - but the kernel is default, and the audio works fine without any manual state restores on every boot and I can switch between internal and HDMI audio fine.

I've mostly used the HDMI audio though in recent years so I cannot say if there would be problems with internal audio in prolonged use.

The reason for not upgrading beyond 5.4 kernel used to be that 5.8 kernel regressed with these low tier Intel graphics, but I recall that was fixed in later ones so the current Ubuntu 20.04 HWE kernel (5.11) that comes on eg 20.04.3 installation media might be worth trying again if wanting excitement to life.

It'd be nice to experiment with out-of-the-box functionality too, which would be likely easiest done with live USB sticks.

Overall, I think there might not be any kernel bug left here, only userspace ones. Although it might have easily regressed in more recent kernels given the low amount of users.
Comment 37 Pierre Bossart 2021-09-27 17:14:06 UTC
if patching the PulseAudio default.pa works, then the initial issue was probably a problem with alsa-ucm-conf not being updated in your distros. There's no reason to use asound.state these days, it's a much better idea to use UCM. my 2 cents.