From 85264632a295af0098574a354bf9b439be02e9a6 Mon Sep 17 00:00:00 2001 From: Andre Date: Thu, 21 Mar 2024 18:34:28 -0400 Subject: [PATCH] AHHHH LENOVO SPEAKERS ARE WORKING --- hosts/Shura/hardware-configuration.nix | 17 ++- .../legion_7i-gen7-16IAX7-sound-6.7.3.patch | 32 ----- ...o-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch | 134 ------------------ hosts/Shura/patches/lenovo-speaker-fix.nix | 38 +++++ .../patches/lenovo_16ARHA7_sound_fix.patch | 33 +++++ 5 files changed, 82 insertions(+), 172 deletions(-) delete mode 100644 hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch delete mode 100644 hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch create mode 100644 hosts/Shura/patches/lenovo-speaker-fix.nix create mode 100644 hosts/Shura/patches/lenovo_16ARHA7_sound_fix.patch diff --git a/hosts/Shura/hardware-configuration.nix b/hosts/Shura/hardware-configuration.nix index da7615a..c1ebc55 100644 --- a/hosts/Shura/hardware-configuration.nix +++ b/hosts/Shura/hardware-configuration.nix @@ -1,6 +1,11 @@ # Lenovo Legion S7 16ARHA7 configuration { config, lib, pkgs, modulesPath, ... }: - +let + lenovo-speaker-fix-module = pkgs.callPackage ./patches/lenovo-speaker-fix.nix { + # Make sure the module targets the same kernel as your system is using. + kernel = config.boot.kernelPackages.kernel; + }; +in { imports = [ (modulesPath + "/installer/scan/not-detected.nix") @@ -32,11 +37,11 @@ ]; # Add kernel patch to enable sound over the speakers. - # This might not be necessary for long - see https://forums.lenovo.com/topic/findpost/27/5258964/6212600 - #kernelPatches = [{ - # name = "legion-speaker-fix"; - # patch = ./patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch; - #}]; + extraModulePackages = [ + (lenovo-speaker-fix-module.overrideAttrs (_: { + patches = [ ./patches/lenovo_16ARHA7_sound_fix.patch ]; + })) + ]; }; fileSystems = { diff --git a/hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch b/hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch deleted file mode 100644 index 5a83bad..0000000 --- a/hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c -index d74cf11eef1e..8a6b484b2184 100644 ---- a/sound/pci/hda/cs35l41_hda_property.c -+++ b/sound/pci/hda/cs35l41_hda_property.c -@@ -95,6 +95,7 @@ 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 }, -+ { "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -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 }, -@@ -431,6 +432,7 @@ 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", "17AA386F", 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 6994c4c5073c..9ebe42f33d27 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -10269,6 +10269,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, 0x3877, "Legion 7 slim 16ARHA7", 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), diff --git a/hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch b/hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch deleted file mode 100644 index 3b87bcb..0000000 --- a/hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch +++ /dev/null @@ -1,134 +0,0 @@ -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 -@@ -9682,6 +9682,11 @@ 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, 0x3874, "Legion 7 16IAX7", ALC287_FIXUP_CS35L41_I2C_2), -+ SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7 16IAX7", ALC287_FIXUP_CS35L41_I2C_2), -+ SND_PCI_QUIRK(0x17aa, 0x3803, "Legion 7i slim 16IAH7", ALC287_FIXUP_CS35L41_I2C_2), -+ SND_PCI_QUIRK(0x17aa, 0x3856, "Yoga Slim 7 Carbon 14ACN6", ALC287_FIXUP_CS35L41_I2C_2), -+ SND_PCI_QUIRK(0x17aa, 0x3877, "Legion 7 slim 16ARHA7", 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), diff --git a/hosts/Shura/patches/lenovo-speaker-fix.nix b/hosts/Shura/patches/lenovo-speaker-fix.nix new file mode 100644 index 0000000..839fd42 --- /dev/null +++ b/hosts/Shura/patches/lenovo-speaker-fix.nix @@ -0,0 +1,38 @@ +{ pkgs +, lib +, kernel ? pkgs.linuxPackages_latest.kernel +}: + +pkgs.stdenv.mkDerivation { + pname = "lenovo-speaker-fix-module"; + inherit (kernel) src version postPatch nativeBuildInputs; + + kernel_dev = kernel.dev; + kernelVersion = kernel.modDirVersion; + + modulePath = "sound/pci/hda/"; + + buildPhase = '' + BUILT_KERNEL=$kernel_dev/lib/modules/$kernelVersion/build + + cp $BUILT_KERNEL/Module.symvers . + cp $BUILT_KERNEL/.config . + cp $kernel_dev/vmlinux . + + make "-j$NIX_BUILD_CORES" modules_prepare + make "-j$NIX_BUILD_CORES" M=$modulePath modules + ''; + + installPhase = '' + make \ + INSTALL_MOD_PATH="$out" \ + XZ="xz -T$NIX_BUILD_CORES" \ + M="$modulePath" \ + modules_install + ''; + + meta = { + description = "Fix to get the speakers working for 16ARHA7"; + license = lib.licenses.gpl3; + }; +} \ No newline at end of file diff --git a/hosts/Shura/patches/lenovo_16ARHA7_sound_fix.patch b/hosts/Shura/patches/lenovo_16ARHA7_sound_fix.patch new file mode 100644 index 0000000..7256533 --- /dev/null +++ b/hosts/Shura/patches/lenovo_16ARHA7_sound_fix.patch @@ -0,0 +1,33 @@ +diff -rupN linux-6.8-9791-ge5eb28f6d1af/sound/pci/hda/cs35l41_hda_property.c linux-6.8-9791-ge5eb28f6d1af-patched/sound/pci/hda/cs35l41_hda_property.c +--- linux-6.8-9791-ge5eb28f6d1af/sound/pci/hda/cs35l41_hda_property.c 2024-03-15 02:03:09.000000000 +0100 ++++ linux-6.8-9791-ge5eb28f6d1af-patched/sound/pci/hda/cs35l41_hda_property.c 2024-03-17 12:23:48.183404375 +0100 +@@ -115,6 +115,8 @@ static const struct cs35l41_config cs35l + { "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 }, + { "17AA38B7", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, ++ { "17AA3877", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, ++ { "17AA3878", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, + {} + }; + +@@ -503,6 +505,8 @@ static const struct cs35l41_prop_model c + { "CSC3551", "17AA38B5", generic_dsd_config }, + { "CSC3551", "17AA38B6", generic_dsd_config }, + { "CSC3551", "17AA38B7", generic_dsd_config }, ++ { "CSC3551", "17AA3877", generic_dsd_config }, ++ { "CSC3551", "17AA3878", generic_dsd_config }, + {} + }; + +diff -rupN linux-6.8-9791-ge5eb28f6d1af/sound/pci/hda/patch_realtek.c linux-6.8-9791-ge5eb28f6d1af-patched/sound/pci/hda/patch_realtek.c +--- linux-6.8-9791-ge5eb28f6d1af/sound/pci/hda/patch_realtek.c 2024-03-15 02:03:09.000000000 +0100 ++++ linux-6.8-9791-ge5eb28f6d1af-patched/sound/pci/hda/patch_realtek.c 2024-03-17 12:18:22.241570472 +0100 +@@ -10263,6 +10263,8 @@ static const struct snd_pci_quirk alc269 + 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), + SND_PCI_QUIRK(0x17aa, 0x38b7, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x3877, "Legion S7 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x3878, "Legion S7 16ARHA7", 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),