Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save levihuayuzhang/6137ae4ae46301a355fd37c63e0d876a to your computer and use it in GitHub Desktop.
Save levihuayuzhang/6137ae4ae46301a355fd37c63e0d876a to your computer and use it in GitHub Desktop.
Workaround for Lenovo Thinkbook 16p Gen4 IRH sound issue (Should be fixed in Linux v6.8 or later)
From 86d1cc3e8e024c6776424f09108030fabe67cf5f Mon Sep 17 00:00:00 2001
From: Huayu Zhang <xxxxxxxxx@qq.com>
Date: Thu, 11 Jan 2024 16:18:29 +0800
Subject: [PATCH] add _DSD for SSID 0x17aa38a9 and 38ab (ThinkBook 16p G4 IRH)
the dmseg has following output after patching:
[ 4.401426] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: Cirrus Logic CS35L41 (35a40), Revision: B2
[ 4.455038] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Cirrus Logic CS35L41 (35a40), Revision: B2
[ 6.362589] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: CS35L41 Bound - SSID: 17AA38A9, BST: 1, VSPK: 1, CH: L, FW EN: 1, SPKID: 0
[ 6.862707] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: CS35L41 Bound - SSID: 17AA38A9, BST: 1, VSPK: 1, CH: R, FW EN: 1, SPKID: 0
And the system volumn control only affect the upfacing speakers nor the
downfacing bass speakers.
Signed-off-by: Huayu Zhang <xxxxxxxxx@qq.com>
---
sound/pci/hda/cs35l41_hda_property.c | 4 ++++
sound/pci/hda/patch_realtek.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index 35277ce890a4..30fb638f5240 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -93,6 +93,8 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
{ "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+ { "17AA38A9", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
+ { "17AA38AB", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
{ "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
@@ -427,6 +429,8 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431F12", generic_dsd_config },
{ "CSC3551", "10431F1F", generic_dsd_config },
{ "CSC3551", "10431F62", generic_dsd_config },
+ { "CSC3551", "17AA38A9", generic_dsd_config },
+ { "CSC3551", "17AA38AB", generic_dsd_config },
{ "CSC3551", "17AA38B4", generic_dsd_config },
{ "CSC3551", "17AA38B5", generic_dsd_config },
{ "CSC3551", "17AA38B6", generic_dsd_config },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1dcfba27e075..97388c170837 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10256,6 +10256,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38a9, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x38ab, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b4, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b5, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b6, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
--
2.34.1
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index f7815ee24f83..93d86c5a9d53 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -1270,6 +1270,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
size_t nval;
int i, ret;
+ printk("CSC3551: probing %s\n", hid);
+
adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
if (!adev) {
dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid);
@@ -1287,8 +1289,9 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
property = "cirrus,dev-index";
ret = device_property_count_u32(physdev, property);
if (ret <= 0) {
- ret = cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid);
- goto err_put_physdev;
+ //ret = cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid);
+ //goto err_put_physdev;
+ goto no_acpi_dsd;
}
if (ret > ARRAY_SIZE(values)) {
ret = -EINVAL;
@@ -1383,6 +1386,92 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
put_device(physdev);
return ret;
+
+no_acpi_dsd:
+ /*
+ * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work.
+ * And devices created by i2c-multi-instantiate don't have their device struct pointing to
+ * the correct fwnode, so acpi_dev must be used here.
+ * And devm functions expect that the device requesting the resource has the correct
+ * fwnode.
+ */
+
+ printk("CSC3551: no_acpi_dsd: %s\n", hid);
+
+ /* TODO: This is a hack. */
+ if (strncmp(hid, "CSC3551", 7) == 0) {
+ goto csc3551;
+ }
+
+ if (strncmp(hid, "CLSA0100", 8) != 0)
+ return -EINVAL;
+
+ /* check I2C address to assign the index */
+ cs35l41->index = id == 0x40 ? 0 : 1;
+ cs35l41->hw_cfg.spk_pos = cs35l41->index;
+ cs35l41->channel_index = 0;
+ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
+ cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
+ hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN;
+ hw_cfg->gpio2.valid = true;
+ cs35l41->hw_cfg.valid = true;
+ put_device(physdev);
+
+ return 0;
+
+ csc3551:
+
+ printk("CSC3551: id == 0x%x\n", id);
+
+ // cirrus,dev-index
+ if(id == 0x40)
+ cs35l41->index = 0;
+ else
+ cs35l41->index = 1;
+
+ cs35l41->channel_index = 0;
+
+ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, cs35l41->index, GPIOD_OUT_LOW);
+
+ printk("CS3551: reset_gpio == 0x%x\n", cs35l41->reset_gpio);
+
+ // cirrus,speaker-position
+ if(cs35l41->index == 0)
+ hw_cfg->spk_pos = 0;
+ else
+ hw_cfg->spk_pos = 1;
+
+ // cirrus,gpio1-func
+ hw_cfg->gpio1.func = 1;
+ hw_cfg->gpio1.valid = true;
+
+ // cirrus,gpio2-func
+ hw_cfg->gpio2.func = 0x02;
+ hw_cfg->gpio2.valid = true;
+
+ // cirrus,boost-peak-milliamp
+ hw_cfg->bst_ipk = -1;
+
+ // cirrus,boost-ind-nanohenry
+ hw_cfg->bst_ind = -1;
+
+ // cirrus,boost-cap-microfarad
+ hw_cfg->bst_cap = -1;
+
+ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1);
+
+ if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0)
+ hw_cfg->bst_type = CS35L41_INT_BOOST;
+ else
+ hw_cfg->bst_type = CS35L41_EXT_BOOST;
+
+ hw_cfg->valid = true;
+
+ put_device(physdev);
+
+ printk("CSC3551: Done.\n");
+
+ return 0;
}
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e103bb3693c0..8ec2b0f99d8c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9734,6 +9734,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
+ SND_PCI_QUIRK(0x17aa, 0x38a9, "Lenovo ThinkBook 16p Gen4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
From 124161547483109cbb491a8e39d1b5ef0973cd80 Mon Sep 17 00:00:00 2001
From: Huayu Zhang <zhanghuayu.dev@gmail.com>
Date: Mon, 9 Oct 2023 00:59:56 +0800
Subject: [PATCH] thinkbook 16p gen4 sound fix
---
sound/pci/hda/cs35l41_hda_property.c | 41 ++++++++++++++++++++++++++++
sound/pci/hda/patch_realtek.c | 1 +
2 files changed, 42 insertions(+)
diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c
index b62a4e6968e2..af359fbeb671 100644
--- a/sound/pci/hda/cs35l41_hda_property.c
+++ b/sound/pci/hda/cs35l41_hda_property.c
@@ -74,6 +74,46 @@ static int hp_vision_acpi_fix(struct cs35l41_hda *cs35l41, struct device *physde
return 0;
}
+static int lenovo_thinkbook16pgen4_no_acpi(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
+ const char *hid)
+{
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
+
+ dev_info(cs35l41->dev, "Adding DSD properties for %s\n", cs35l41->acpi_subsystem_id);
+
+ printk("CSC3551: id == 0x%x\n", id);
+
+ // cirrus,dev-index
+ cs35l41->index = id == 0x40 ? 0 : 1;
+ cs35l41->channel_index = 0;
+
+ // cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, cs35l41->index, GPIOD_OUT_LOW);
+ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
+ printk("CS3551: reset_gpio == 0x%x\n", cs35l41->reset_gpio);
+
+ // cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1);
+ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
+
+ // cirrus,speaker-position
+ hw_cfg->spk_pos = cs35l41->index;
+
+ // cirrus,gpio1-func
+ hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
+ hw_cfg->gpio1.valid = true;
+
+ // cirrus,gpio2-func
+ hw_cfg->gpio2.func = CS35L41_INTERRUPT;
+ hw_cfg->gpio2.valid = true;
+
+ hw_cfg->bst_type = CS35L41_EXT_BOOST;
+ hw_cfg->valid = true;
+
+ put_device(physdev);
+ printk("CSC3551: Done.\n");
+
+ return 0;
+}
+
struct cs35l41_prop_model {
const char *hid;
const char *ssid;
@@ -85,6 +125,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CLSA0100", NULL, lenovo_legion_no_acpi },
{ "CLSA0101", NULL, lenovo_legion_no_acpi },
{ "CSC3551", "103C89C6", hp_vision_acpi_fix },
+ { "CSC3551", "17AA38A9", lenovo_thinkbook16pgen4_no_acpi },
{}
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 751783f3a15c..fc884fdcec5f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10031,6 +10031,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x17aa, 0x38a9, "Lenovo ThinkBook 16p Gen 4", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),
--
2.42.0
From b7cb3f0b49270d631362da5bab871e2e8910a073 Mon Sep 17 00:00:00 2001
From: Huayu Zhang <zhanghuayu1233@qq.com>
Date: Sat, 13 Apr 2024 19:26:24 +0800
Subject: [PATCH] Fix volumn control of ThinkBook 16P Gen4
change HDA & AMP configuration from ALC287_FIXUP_CS35L41_I2C_2 to
ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD for ThinkBook 16P Gen4 models to fix volumn
control issue (cannot fully mute).
Signed-off-by: Huayu Zhang <zhanghuayu1233@qq.com>
---
sound/pci/hda/patch_realtek.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index d6940bc4ec39..1aef223307bb 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10396,8 +10396,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
- SND_PCI_QUIRK(0x17aa, 0x38a9, "Thinkbook 16P", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x17aa, 0x38ab, "Thinkbook 16P", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x17aa, 0x38a9, "Thinkbook 16P", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
+ SND_PCI_QUIRK(0x17aa, 0x38ab, "Thinkbook 16P", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38b4, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b5, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x17aa, 0x38b6, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2),
--
2.34.1
@wenqihuang
Copy link

Hi Huayu,

thank you for your suggestion! I'll report this bug once I've gathered enough information and keep using windows as dual boot.

Best wishes

@TheCherry
Copy link

does this patch work for 6.2.0-39 too? I have a ubuntu 22.04.3

@levihuayuzhang
Copy link
Author

levihuayuzhang commented Jan 8, 2024

does this patch work for 6.2.0-39 too? I have a ubuntu 22.04.3

Haven't tried that yet (My Ubuntu is now perform as a server not desktop). Even it "works", that only means you will have sounds both from up facing and down facing speakers. In my case, the volumn adjusting is actually changing the frequency division.

Please refer to this bugzilla thread for more details (some guys have patch for older kernel but I never got chance to verify it).

@levihuayuzhang
Copy link
Author

Hi Huayu,

thank you for sharing this patch! I've tried both to modify the 6.6.0-rc4 patch for kernel 6.6.9/6.6.8 and directly use the patch for 6.6.0-rc4, but failed. I checked dmesg, the patched kernels all have the same errors:

[    7.783195] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.0: error -EINVAL: Platform not supported
[    7.783251] cs35l41-hda: probe of i2c-CSC3551:00-cs35l41-hda.0 failed with error -22
[    7.783571] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: Failed property cirrus,dev-index: -22
[    7.783574] cs35l41-hda i2c-CSC3551:00-cs35l41-hda.1: error -EINVAL: Platform not supported
[    7.783590] cs35l41-hda: probe of i2c-CSC3551:00-cs35l41-hda.1 failed with error -22

Do you have any idea on the cause or how to fix it? Many thank!

Hi, you guys may try this. I've just add some new fix for the fresh release of 6.7.0-rc2(from linux-sound team).

And you may need to apply this patch with the source from linux sound team, because some sound fix haven't applied to the main line source tree that maintained by Torvalds.

Again, use at your own risk. Check the know issues I've mentioned before. If the patch not work, please double check the output from your alsa-info script and modify the patch before applying (my zh-CN blog recorded the process). Enjoy~

@wenqihuang
Copy link

wenqihuang commented Jan 11, 2024

Hi Huayu,

Thank you very much! I've make it work for mainline linux 6.7 with some issues. Attached is my patch based on your 6.7.0-rc2 patch. A critical thing is to use the right subsystem id in the patch. For my laptop it's 17AA38AB instead of 17AA38A9, and I guess that's why the patches didn't work in my previous attempts. For those who failed to use this patch, maybe have a look at the subsystem id in your alsa-info ;D

Codec: Realtek ALC287    # Make sure it's the id under Realtek codec
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec0287
Subsystem Id: 0x17aa38ab   # this might be a different number

However, the sound quality is still not on par with that on Windows. The volume control is also not working properly (currently I use alsamixer to adjust the volume). I've also posted the bug on Red Hat Bugzilla (https://bugzilla.redhat.com/show_bug.cgi?id=2257789). Hope it can be fixed soon :)

Patch:

diff -rupN linux/sound/pci/hda/cs36l41_hda_property.c linux-fix/sound/pci/hda/cs35l41_hda_property.c
--- linux/sound/pci/hda/cs35l41_hda_property.c  2024-01-11 10:18:18.080011950 +0800
+++ linux-fix/sound/pci/hda/cs35l41_hda_property.c      2024-01-11 10:32:18.314511561 +0800
@@ -71,6 +71,10 @@ static const struct cs35l41_config cs35l
        { "10431F12", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
        { "10431F1F", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
        { "10431F62", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       { "17AA38AB", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+       // { "17AA38A9", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
        {}
 };

@@ -375,6 +379,10 @@ static const struct cs35l41_prop_model c
        { "CSC3551", "10431F12", generic_dsd_config },
        { "CSC3551", "10431F1F", generic_dsd_config },
        { "CSC3551", "10431F62", generic_dsd_config },
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       { "CSC3551", "17AA38AB", generic_dsd_config },
+       // { "CSC3551", "17AA38A9", generic_dsd_config },
        {}
 };

diff -rupN linux/sound/pci/hda/patch_realtek.c linux-fix/sound/pci/hda/patch_realtek.c
--- linux/sound/pci/hda/patch_realtek.c 2024-01-11 10:18:18.087012007 +0800
+++ linux-fix/sound/pci/hda/patch_realtek.c     2024-01-11 10:36:02.484219966 +0800
@@ -10229,6 +10229,10 @@ static const struct snd_pci_quirk alc269
        SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       SND_PCI_QUIRK(0x17aa, 0x38ab, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
+       // SND_PCI_QUIRK(0x17aa, 0x38a9, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),

@levihuayuzhang
Copy link
Author

levihuayuzhang commented Jan 11, 2024

Hi Huayu,

Thank you very much! I've make it work for mainline linux 6.7 with some issues. Attached is my patch based on your 6.7.0-rc2 patch. A critical thing is to use the right subsystem id in the patch. For my laptop it's 17AA38AB instead of 17AA38A9, and I guess that's why the patches didn't work in my previous attempts. For those who failed to use this patch, maybe have a look at the subsystem id in your alsa-info ;D

Codec: Realtek ALC287    # Make sure it's the id under Realtek codec
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec0287
Subsystem Id: 0x17aa38ab   # this might be a different number

However, the sound quality is still not on par with that on Windows. The volume control is also not working properly (currently I use alsamixer to adjust the volume). I've also posted the bug on Red Hat Bugzilla (https://bugzilla.redhat.com/show_bug.cgi?id=2257789). Hope it can be fixed soon :)

Patch:

diff -rupN linux/sound/pci/hda/cs36l41_hda_property.c linux-fix/sound/pci/hda/cs35l41_hda_property.c
--- linux/sound/pci/hda/cs35l41_hda_property.c  2024-01-11 10:18:18.080011950 +0800
+++ linux-fix/sound/pci/hda/cs35l41_hda_property.c      2024-01-11 10:32:18.314511561 +0800
@@ -71,6 +71,10 @@ static const struct cs35l41_config cs35l
        { "10431F12", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
        { "10431F1F", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
        { "10431F62", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       { "17AA38AB", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+       // { "17AA38A9", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
        {}
 };

@@ -375,6 +379,10 @@ static const struct cs35l41_prop_model c
        { "CSC3551", "10431F12", generic_dsd_config },
        { "CSC3551", "10431F1F", generic_dsd_config },
        { "CSC3551", "10431F62", generic_dsd_config },
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       { "CSC3551", "17AA38AB", generic_dsd_config },
+       // { "CSC3551", "17AA38A9", generic_dsd_config },
        {}
 };

diff -rupN linux/sound/pci/hda/patch_realtek.c linux-fix/sound/pci/hda/patch_realtek.c
--- linux/sound/pci/hda/patch_realtek.c 2024-01-11 10:18:18.087012007 +0800
+++ linux-fix/sound/pci/hda/patch_realtek.c     2024-01-11 10:36:02.484219966 +0800
@@ -10229,6 +10229,10 @@ static const struct snd_pci_quirk alc269
        SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       SND_PCI_QUIRK(0x17aa, 0x38ab, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
+       // SND_PCI_QUIRK(0x17aa, 0x38a9, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),

Yes, you guys can get and verify your own SSID by running the alsa-info script and use acpidump to check the detailed info. The output of my acpidump does showing the 0x38ab and 0x38a9, but my alsa-info output only contains 0x38a9, so I guess we've fund two SSIDs for this laptop model. And I've send a patch to linux-sound team in ealier days, but still no response though. Maybe they just took 'fix' but not 'workaround' ^_^.

Wondering alsamixer can also change the bass volumn? In my case, the system volumnn control from DE only change the up-facing two speakers, the bass speakers (the down-facing two) seem not affected.

@levihuayuzhang
Copy link
Author

levihuayuzhang commented Jan 11, 2024

Thanks for wenqi's verify, the patch for v6.7 has been updated. (BTW, another guy I was met in bugzilla also have the same SSID of 0x38ab LOL.)

@levihuayuzhang
Copy link
Author

levihuayuzhang commented Jan 30, 2024

reported on kernel bugzilla.

@levihuayuzhang
Copy link
Author

levihuayuzhang commented Apr 12, 2024

The fix code made by Cirrus team has been merged by Linux Sound Team. Please feel free to try the new kernel (v6.8 maybe). The merge commit is here tiwai/sound@37d9d5f.

@levihuayuzhang
Copy link
Author

levihuayuzhang commented Apr 22, 2024

Hi Huayu,

Thank you very much! I've make it work for mainline linux 6.7 with some issues. Attached is my patch based on your 6.7.0-rc2 patch. A critical thing is to use the right subsystem id in the patch. For my laptop it's 17AA38AB instead of 17AA38A9, and I guess that's why the patches didn't work in my previous attempts. For those who failed to use this patch, maybe have a look at the subsystem id in your alsa-info ;D

Codec: Realtek ALC287    # Make sure it's the id under Realtek codec
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec0287
Subsystem Id: 0x17aa38ab   # this might be a different number

However, the sound quality is still not on par with that on Windows. The volume control is also not working properly (currently I use alsamixer to adjust the volume). I've also posted the bug on Red Hat Bugzilla (https://bugzilla.redhat.com/show_bug.cgi?id=2257789). Hope it can be fixed soon :)

Patch:

diff -rupN linux/sound/pci/hda/cs36l41_hda_property.c linux-fix/sound/pci/hda/cs35l41_hda_property.c
--- linux/sound/pci/hda/cs35l41_hda_property.c  2024-01-11 10:18:18.080011950 +0800
+++ linux-fix/sound/pci/hda/cs35l41_hda_property.c      2024-01-11 10:32:18.314511561 +0800
@@ -71,6 +71,10 @@ static const struct cs35l41_config cs35l
        { "10431F12", I2C, 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
        { "10431F1F", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 },
        { "10431F62", SPI, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       { "17AA38AB", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+       // { "17AA38A9", I2C, 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
        {}
 };

@@ -375,6 +379,10 @@ static const struct cs35l41_prop_model c
        { "CSC3551", "10431F12", generic_dsd_config },
        { "CSC3551", "10431F1F", generic_dsd_config },
        { "CSC3551", "10431F62", generic_dsd_config },
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       { "CSC3551", "17AA38AB", generic_dsd_config },
+       // { "CSC3551", "17AA38A9", generic_dsd_config },
        {}
 };

diff -rupN linux/sound/pci/hda/patch_realtek.c linux-fix/sound/pci/hda/patch_realtek.c
--- linux/sound/pci/hda/patch_realtek.c 2024-01-11 10:18:18.087012007 +0800
+++ linux-fix/sound/pci/hda/patch_realtek.c     2024-01-11 10:36:02.484219966 +0800
@@ -10229,6 +10229,10 @@ static const struct snd_pci_quirk alc269
        SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
+       // Please check your Subsystem ID before adding your device to this list
+       // Subsystem Id: 0x17aa38ab or 0x17aa38a9
+       SND_PCI_QUIRK(0x17aa, 0x38ab, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
+       // SND_PCI_QUIRK(0x17aa, 0x38a9, "ThinkBook 16p G4 IRH", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),

Thanks for Stefan's helps, the volumn control has been fix by this patch for v6.9-rc5.

But the sound level is relatively lower compare to Windows (I think the Windows one is not good. In the earlier version of BIOS and sound firmware for windows, Thinkbook 16P may met some issue).

As for the sound quality, it may be adjusted by EQ programs (like Dolby on Windows).

@isbest
Copy link

isbest commented May 26, 2024

Hi Huayu, I have the same issue on my Thinkbook 16P 2024. After attempting the patch, my laptop no longer has kernel errors, but it seems that only the upper low-frequency speaker is working, while the lower high-frequency speaker is not working. Do you have any information or help regarding this?

@levihuayuzhang
Copy link
Author

levihuayuzhang commented May 27, 2024

Hi Huayu, I have the same issue on my Thinkbook 16P 2024. After attempting the patch, my laptop no longer has kernel errors, but it seems that only the upper low-frequency speaker is working, while the lower high-frequency speaker is not working. Do you have any information or help regarding this?

看到兄弟的提交了。估计会排期解决的。加油。(有用Gen5型号的朋友可以去跟帖汇报哈)(可以关注linux sound邮件组,Cirrus的几位佬)

然后估计CS35L41的驱动已经写好了。兄弟可以考虑把没打patch的kernel报错给发一下,alsa-info好像看不到amp型号,还有acpidump的输出可以重定向为文本,发给Bugzilla。(有可能是其他型号的amp,新型号或其他厂家的(比如德州仪器之类的))。

@isbest
Copy link

isbest commented May 27, 2024

Hi Huayu, I have the same issue on my Thinkbook 16P 2024. After attempting the patch, my laptop no longer has kernel errors, but it seems that only the upper low-frequency speaker is working, while the lower high-frequency speaker is not working. Do you have any information or help regarding this?

看到兄弟的提交了。估计会排期解决的。加油。(有用Gen5型号的朋友可以去跟帖汇报哈)(可以关注linux sound邮件组,Cirrus的几位佬)

然后估计CS35L41的驱动已经写好了。兄弟可以考虑把没打patch的kernel报错给发一下,alsa-info好像看不到amp型号,还有acpidump的输出可以重定向为文本,发给Bugzilla。(有可能是其他型号的amp,新型号或其他厂家的(比如德州仪器之类的))。

我刚刚跟新了bug的描述。希望能被大佬看到。在我电脑上6.8的内核,低频的Speaker是有声音的不过超级小,高频的Speaker不work

@levihuayuzhang
Copy link
Author

levihuayuzhang commented May 27, 2024

Hi Huayu, I have the same issue on my Thinkbook 16P 2024. After attempting the patch, my laptop no longer has kernel errors, but it seems that only the upper low-frequency speaker is working, while the lower high-frequency speaker is not working. Do you have any information or help regarding this?

看到兄弟的提交了。估计会排期解决的。加油。(有用Gen5型号的朋友可以去跟帖汇报哈)(可以关注linux sound邮件组,Cirrus的几位佬)
然后估计CS35L41的驱动已经写好了。兄弟可以考虑把没打patch的kernel报错给发一下,alsa-info好像看不到amp型号,还有acpidump的输出可以重定向为文本,发给Bugzilla。(有可能是其他型号的amp,新型号或其他厂家的(比如德州仪器之类的))。

我刚刚跟新了bug的描述。希望能被大佬看到。在我电脑上6.8的内核,低频的Speaker是有声音的不过超级小,高频的Speaker不work

那应该就是cs35l41了。估计是配置问题。我当时就是上边音量还可以,并且可以调整大小。下面也有声音,但小,且无法和上方一起协同调整音量。这种情况就是解码器可以解码,amp也在工作,但估计之间的连接配置没写对。

我当时是试了几个不同的配置,其中一个刚好可以用。有几个配置在sound/pci/hda/patch_realtek.c里是写好的(可以ctrl+f搜搜看)。不过也可以在邮件组问问Stefan,之前都是这位大佬在对接这个芯片的相关事项。(如果确实是配置的问题,之前 Stefan说要去找Realtek的人问,或者自己尝试用已有的配置or自己写😂)。祝顺利。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment