|
11 | 11 | */ |
12 | 12 |
|
13 | 13 | #include <linux/acpi.h> |
| 14 | +#include <linux/cleanup.h> |
14 | 15 | #include <linux/init.h> |
15 | 16 | #include <linux/delay.h> |
16 | 17 | #include <linux/slab.h> |
17 | 18 | #include <linux/pci.h> |
18 | 19 | #include <linux/dmi.h> |
19 | 20 | #include <linux/module.h> |
| 21 | +#include <linux/i2c.h> |
20 | 22 | #include <linux/input.h> |
21 | 23 | #include <linux/leds.h> |
22 | 24 | #include <linux/ctype.h> |
| 25 | +#include <linux/spi/spi.h> |
23 | 26 | #include <sound/core.h> |
24 | 27 | #include <sound/jack.h> |
25 | 28 | #include <sound/hda_codec.h> |
@@ -583,7 +586,6 @@ static void alc_shutup_pins(struct hda_codec *codec) |
583 | 586 | switch (codec->core.vendor_id) { |
584 | 587 | case 0x10ec0236: |
585 | 588 | case 0x10ec0256: |
586 | | - case 0x10ec0257: |
587 | 589 | case 0x19e58326: |
588 | 590 | case 0x10ec0283: |
589 | 591 | case 0x10ec0285: |
@@ -6856,6 +6858,86 @@ static void comp_generic_fixup(struct hda_codec *cdc, int action, const char *bu |
6856 | 6858 | } |
6857 | 6859 | } |
6858 | 6860 |
|
| 6861 | +static void cs35lxx_autodet_fixup(struct hda_codec *cdc, |
| 6862 | + const struct hda_fixup *fix, |
| 6863 | + int action) |
| 6864 | +{ |
| 6865 | + struct device *dev = hda_codec_dev(cdc); |
| 6866 | + struct acpi_device *adev; |
| 6867 | + struct fwnode_handle *fwnode __free(fwnode_handle) = NULL; |
| 6868 | + const char *bus = NULL; |
| 6869 | + static const struct { |
| 6870 | + const char *hid; |
| 6871 | + const char *name; |
| 6872 | + } acpi_ids[] = {{ "CSC3554", "cs35l54-hda" }, |
| 6873 | + { "CSC3556", "cs35l56-hda" }, |
| 6874 | + { "CSC3557", "cs35l57-hda" }}; |
| 6875 | + char *match; |
| 6876 | + int i, count = 0, count_devindex = 0; |
| 6877 | + |
| 6878 | + switch (action) { |
| 6879 | + case HDA_FIXUP_ACT_PRE_PROBE: |
| 6880 | + for (i = 0; i < ARRAY_SIZE(acpi_ids); ++i) { |
| 6881 | + adev = acpi_dev_get_first_match_dev(acpi_ids[i].hid, NULL, -1); |
| 6882 | + if (adev) |
| 6883 | + break; |
| 6884 | + } |
| 6885 | + if (!adev) { |
| 6886 | + dev_err(dev, "Failed to find ACPI entry for a Cirrus Amp\n"); |
| 6887 | + return; |
| 6888 | + } |
| 6889 | + |
| 6890 | + count = i2c_acpi_client_count(adev); |
| 6891 | + if (count > 0) { |
| 6892 | + bus = "i2c"; |
| 6893 | + } else { |
| 6894 | + count = acpi_spi_count_resources(adev); |
| 6895 | + if (count > 0) |
| 6896 | + bus = "spi"; |
| 6897 | + } |
| 6898 | + |
| 6899 | + fwnode = fwnode_handle_get(acpi_fwnode_handle(adev)); |
| 6900 | + acpi_dev_put(adev); |
| 6901 | + |
| 6902 | + if (!bus) { |
| 6903 | + dev_err(dev, "Did not find any buses for %s\n", acpi_ids[i].hid); |
| 6904 | + return; |
| 6905 | + } |
| 6906 | + |
| 6907 | + if (!fwnode) { |
| 6908 | + dev_err(dev, "Could not get fwnode for %s\n", acpi_ids[i].hid); |
| 6909 | + return; |
| 6910 | + } |
| 6911 | + |
| 6912 | + /* |
| 6913 | + * When available the cirrus,dev-index property is an accurate |
| 6914 | + * count of the amps in a system and is used in preference to |
| 6915 | + * the count of bus devices that can contain additional address |
| 6916 | + * alias entries. |
| 6917 | + */ |
| 6918 | + count_devindex = fwnode_property_count_u32(fwnode, "cirrus,dev-index"); |
| 6919 | + if (count_devindex > 0) |
| 6920 | + count = count_devindex; |
| 6921 | + |
| 6922 | + match = devm_kasprintf(dev, GFP_KERNEL, "-%%s:00-%s.%%d", acpi_ids[i].name); |
| 6923 | + if (!match) |
| 6924 | + return; |
| 6925 | + dev_info(dev, "Found %d %s on %s (%s)\n", count, acpi_ids[i].hid, bus, match); |
| 6926 | + comp_generic_fixup(cdc, action, bus, acpi_ids[i].hid, match, count); |
| 6927 | + |
| 6928 | + break; |
| 6929 | + case HDA_FIXUP_ACT_FREE: |
| 6930 | + /* |
| 6931 | + * Pass the action on to comp_generic_fixup() so that |
| 6932 | + * hda_component_manager functions can be called in just once |
| 6933 | + * place. In this context the bus, hid, match_str or count |
| 6934 | + * values do not need to be calculated. |
| 6935 | + */ |
| 6936 | + comp_generic_fixup(cdc, action, NULL, NULL, NULL, 0); |
| 6937 | + break; |
| 6938 | + } |
| 6939 | +} |
| 6940 | + |
6859 | 6941 | static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action) |
6860 | 6942 | { |
6861 | 6943 | comp_generic_fixup(cdc, action, "i2c", "CSC3551", "-%s:00-cs35l41-hda.%d", 2); |
@@ -7528,6 +7610,7 @@ enum { |
7528 | 7610 | ALC256_FIXUP_CHROME_BOOK, |
7529 | 7611 | ALC287_FIXUP_LENOVO_14ARP8_LEGION_IAH7, |
7530 | 7612 | ALC287_FIXUP_LENOVO_SSID_17AA3820, |
| 7613 | + ALCXXX_FIXUP_CS35LXX, |
7531 | 7614 | }; |
7532 | 7615 |
|
7533 | 7616 | /* A special fixup for Lenovo C940 and Yoga Duet 7; |
@@ -9857,6 +9940,10 @@ static const struct hda_fixup alc269_fixups[] = { |
9857 | 9940 | .type = HDA_FIXUP_FUNC, |
9858 | 9941 | .v.func = alc287_fixup_lenovo_ssid_17aa3820, |
9859 | 9942 | }, |
| 9943 | + [ALCXXX_FIXUP_CS35LXX] = { |
| 9944 | + .type = HDA_FIXUP_FUNC, |
| 9945 | + .v.func = cs35lxx_autodet_fixup, |
| 9946 | + }, |
9860 | 9947 | }; |
9861 | 9948 |
|
9862 | 9949 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -10271,6 +10358,17 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
10271 | 10358 | SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), |
10272 | 10359 | SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), |
10273 | 10360 | SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), |
| 10361 | + SND_PCI_QUIRK(0x103c, 0x8d01, "HP ZBook Power 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10362 | + SND_PCI_QUIRK(0x103c, 0x8d08, "HP EliteBook 1045 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10363 | + SND_PCI_QUIRK(0x103c, 0x8d85, "HP EliteBook 1040 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10364 | + SND_PCI_QUIRK(0x103c, 0x8d86, "HP Elite x360 1040 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10365 | + SND_PCI_QUIRK(0x103c, 0x8d8c, "HP EliteBook 830 13 G12", ALCXXX_FIXUP_CS35LXX), |
| 10366 | + SND_PCI_QUIRK(0x103c, 0x8d8d, "HP Elite x360 830 13 G12", ALCXXX_FIXUP_CS35LXX), |
| 10367 | + SND_PCI_QUIRK(0x103c, 0x8d8e, "HP EliteBook 840 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10368 | + SND_PCI_QUIRK(0x103c, 0x8d8f, "HP EliteBook 840 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10369 | + SND_PCI_QUIRK(0x103c, 0x8d90, "HP EliteBook 860 16 G12", ALCXXX_FIXUP_CS35LXX), |
| 10370 | + SND_PCI_QUIRK(0x103c, 0x8d91, "HP ZBook Firefly 14 G12", ALCXXX_FIXUP_CS35LXX), |
| 10371 | + SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALCXXX_FIXUP_CS35LXX), |
10274 | 10372 | SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), |
10275 | 10373 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
10276 | 10374 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
|
0 commit comments