Original author: Hongyan Xia Got it from: https://raw.githubusercontent.com/Jerryxia32/envy_x360_fix/d08b7efb1beed4d835745a14b72e9d7183113750/0001-Cirrus-hack.patch diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -1623,7 +1623,7 @@ property = "cirrus,dev-index"; ret = device_property_count_u32(physdev, property); if (ret <= 0) - goto err; + goto no_acpi_dsd; if (ret > ARRAY_SIZE(values)) { ret = -EINVAL; @@ -1733,6 +1733,87 @@ 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: + // 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); + + // 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 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9900,6 +9900,7 @@ SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), + SND_PCI_QUIRK(0x103c, 0x8a28, "HP Spectre x360 13-bf0xxx", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),