| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * HD audio interface patch for Conexant HDA audio codec |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com> |
|---|
| 5 | 6 | * Takashi Iwai <tiwai@suse.de> |
|---|
| 6 | 7 | * Tobin Davis <tdavis@dsl-only.net> |
|---|
| 7 | | - * |
|---|
| 8 | | - * This driver is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This driver is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 21 | 8 | */ |
|---|
| 22 | 9 | |
|---|
| 23 | 10 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 27 | 14 | #include <sound/core.h> |
|---|
| 28 | 15 | #include <sound/jack.h> |
|---|
| 29 | 16 | |
|---|
| 30 | | -#include "hda_codec.h" |
|---|
| 17 | +#include <sound/hda_codec.h> |
|---|
| 31 | 18 | #include "hda_local.h" |
|---|
| 32 | 19 | #include "hda_auto_parser.h" |
|---|
| 33 | 20 | #include "hda_beep.h" |
|---|
| .. | .. |
|---|
| 129 | 116 | } |
|---|
| 130 | 117 | |
|---|
| 131 | 118 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, |
|---|
| 132 | | - hda_nid_t *pins, bool on) |
|---|
| 119 | + const hda_nid_t *pins, bool on) |
|---|
| 133 | 120 | { |
|---|
| 134 | 121 | int i; |
|---|
| 135 | 122 | for (i = 0; i < num_pins; i++) { |
|---|
| .. | .. |
|---|
| 150 | 137 | } |
|---|
| 151 | 138 | |
|---|
| 152 | 139 | /* turn on/off EAPD according to Master switch (inversely!) for mute LED */ |
|---|
| 153 | | -static void cx_auto_vmaster_hook_mute_led(void *private_data, int enabled) |
|---|
| 140 | +static int cx_auto_vmaster_mute_led(struct led_classdev *led_cdev, |
|---|
| 141 | + enum led_brightness brightness) |
|---|
| 154 | 142 | { |
|---|
| 155 | | - struct hda_codec *codec = private_data; |
|---|
| 143 | + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); |
|---|
| 156 | 144 | struct conexant_spec *spec = codec->spec; |
|---|
| 157 | 145 | |
|---|
| 158 | 146 | snd_hda_codec_write(codec, spec->mute_led_eapd, 0, |
|---|
| 159 | 147 | AC_VERB_SET_EAPD_BTLENABLE, |
|---|
| 160 | | - enabled ? 0x00 : 0x02); |
|---|
| 148 | + brightness ? 0x02 : 0x00); |
|---|
| 149 | + return 0; |
|---|
| 150 | +} |
|---|
| 151 | + |
|---|
| 152 | +static void cxt_init_gpio_led(struct hda_codec *codec) |
|---|
| 153 | +{ |
|---|
| 154 | + struct conexant_spec *spec = codec->spec; |
|---|
| 155 | + unsigned int mask = spec->gpio_mute_led_mask | spec->gpio_mic_led_mask; |
|---|
| 156 | + |
|---|
| 157 | + if (mask) { |
|---|
| 158 | + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, |
|---|
| 159 | + mask); |
|---|
| 160 | + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, |
|---|
| 161 | + mask); |
|---|
| 162 | + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
|---|
| 163 | + spec->gpio_led); |
|---|
| 164 | + } |
|---|
| 161 | 165 | } |
|---|
| 162 | 166 | |
|---|
| 163 | 167 | static int cx_auto_init(struct hda_codec *codec) |
|---|
| .. | .. |
|---|
| 167 | 171 | if (!spec->dynamic_eapd) |
|---|
| 168 | 172 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); |
|---|
| 169 | 173 | |
|---|
| 174 | + cxt_init_gpio_led(codec); |
|---|
| 170 | 175 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); |
|---|
| 171 | 176 | |
|---|
| 172 | 177 | return 0; |
|---|
| .. | .. |
|---|
| 210 | 215 | CXT_PINCFG_LEMOTE_A1205, |
|---|
| 211 | 216 | CXT_PINCFG_COMPAQ_CQ60, |
|---|
| 212 | 217 | CXT_FIXUP_STEREO_DMIC, |
|---|
| 218 | + CXT_PINCFG_LENOVO_NOTEBOOK, |
|---|
| 213 | 219 | CXT_FIXUP_INC_MIC_BOOST, |
|---|
| 214 | 220 | CXT_FIXUP_HEADPHONE_MIC_PIN, |
|---|
| 215 | 221 | CXT_FIXUP_HEADPHONE_MIC, |
|---|
| .. | .. |
|---|
| 226 | 232 | CXT_FIXUP_HP_SPECTRE, |
|---|
| 227 | 233 | CXT_FIXUP_HP_GATE_MIC, |
|---|
| 228 | 234 | CXT_FIXUP_MUTE_LED_GPIO, |
|---|
| 235 | + CXT_FIXUP_HP_ZBOOK_MUTE_LED, |
|---|
| 229 | 236 | CXT_FIXUP_HEADSET_MIC, |
|---|
| 230 | 237 | CXT_FIXUP_HP_MIC_NO_PRESENCE, |
|---|
| 231 | 238 | }; |
|---|
| .. | .. |
|---|
| 579 | 586 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
|---|
| 580 | 587 | spec->mute_led_eapd = 0x1b; |
|---|
| 581 | 588 | spec->dynamic_eapd = 1; |
|---|
| 582 | | - spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook_mute_led; |
|---|
| 589 | + snd_hda_gen_add_mute_led_cdev(codec, cx_auto_vmaster_mute_led); |
|---|
| 583 | 590 | } |
|---|
| 584 | 591 | } |
|---|
| 585 | 592 | |
|---|
| .. | .. |
|---|
| 644 | 651 | } |
|---|
| 645 | 652 | |
|---|
| 646 | 653 | /* turn on/off mute LED via GPIO per vmaster hook */ |
|---|
| 647 | | -static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled) |
|---|
| 654 | +static int cxt_gpio_mute_update(struct led_classdev *led_cdev, |
|---|
| 655 | + enum led_brightness brightness) |
|---|
| 648 | 656 | { |
|---|
| 649 | | - struct hda_codec *codec = private_data; |
|---|
| 657 | + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); |
|---|
| 650 | 658 | struct conexant_spec *spec = codec->spec; |
|---|
| 651 | | - /* muted -> LED on */ |
|---|
| 652 | | - cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, !enabled); |
|---|
| 659 | + |
|---|
| 660 | + cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, brightness); |
|---|
| 661 | + return 0; |
|---|
| 653 | 662 | } |
|---|
| 654 | 663 | |
|---|
| 655 | 664 | /* turn on/off mic-mute LED via GPIO per capture hook */ |
|---|
| 656 | | -static void cxt_gpio_micmute_update(struct hda_codec *codec) |
|---|
| 665 | +static int cxt_gpio_micmute_update(struct led_classdev *led_cdev, |
|---|
| 666 | + enum led_brightness brightness) |
|---|
| 667 | +{ |
|---|
| 668 | + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); |
|---|
| 669 | + struct conexant_spec *spec = codec->spec; |
|---|
| 670 | + |
|---|
| 671 | + cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, brightness); |
|---|
| 672 | + return 0; |
|---|
| 673 | +} |
|---|
| 674 | + |
|---|
| 675 | +static void cxt_setup_mute_led(struct hda_codec *codec, |
|---|
| 676 | + unsigned int mute, unsigned int mic_mute) |
|---|
| 657 | 677 | { |
|---|
| 658 | 678 | struct conexant_spec *spec = codec->spec; |
|---|
| 659 | 679 | |
|---|
| 660 | | - cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, |
|---|
| 661 | | - spec->gen.micmute_led.led_value); |
|---|
| 680 | + spec->gpio_led = 0; |
|---|
| 681 | + spec->mute_led_polarity = 0; |
|---|
| 682 | + if (mute) { |
|---|
| 683 | + snd_hda_gen_add_mute_led_cdev(codec, cxt_gpio_mute_update); |
|---|
| 684 | + spec->gpio_mute_led_mask = mute; |
|---|
| 685 | + } |
|---|
| 686 | + if (mic_mute) { |
|---|
| 687 | + snd_hda_gen_add_micmute_led_cdev(codec, cxt_gpio_micmute_update); |
|---|
| 688 | + spec->gpio_mic_led_mask = mic_mute; |
|---|
| 689 | + } |
|---|
| 662 | 690 | } |
|---|
| 663 | | - |
|---|
| 664 | 691 | |
|---|
| 665 | 692 | static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, |
|---|
| 666 | 693 | const struct hda_fixup *fix, int action) |
|---|
| 667 | 694 | { |
|---|
| 668 | | - struct conexant_spec *spec = codec->spec; |
|---|
| 669 | | - static const struct hda_verb gpio_init[] = { |
|---|
| 670 | | - { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 }, |
|---|
| 671 | | - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 }, |
|---|
| 672 | | - {} |
|---|
| 673 | | - }; |
|---|
| 674 | | - |
|---|
| 675 | | - if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
|---|
| 676 | | - spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook; |
|---|
| 677 | | - spec->gpio_led = 0; |
|---|
| 678 | | - spec->mute_led_polarity = 0; |
|---|
| 679 | | - spec->gpio_mute_led_mask = 0x01; |
|---|
| 680 | | - spec->gpio_mic_led_mask = 0x02; |
|---|
| 681 | | - snd_hda_gen_add_micmute_led(codec, cxt_gpio_micmute_update); |
|---|
| 682 | | - } |
|---|
| 683 | | - snd_hda_add_verbs(codec, gpio_init); |
|---|
| 684 | | - if (spec->gpio_led) |
|---|
| 685 | | - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
|---|
| 686 | | - spec->gpio_led); |
|---|
| 695 | + if (action == HDA_FIXUP_ACT_PRE_PROBE) |
|---|
| 696 | + cxt_setup_mute_led(codec, 0x01, 0x02); |
|---|
| 687 | 697 | } |
|---|
| 688 | 698 | |
|---|
| 699 | +static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec, |
|---|
| 700 | + const struct hda_fixup *fix, int action) |
|---|
| 701 | +{ |
|---|
| 702 | + if (action == HDA_FIXUP_ACT_PRE_PROBE) |
|---|
| 703 | + cxt_setup_mute_led(codec, 0x10, 0x20); |
|---|
| 704 | +} |
|---|
| 689 | 705 | |
|---|
| 690 | 706 | /* ThinkPad X200 & co with cxt5051 */ |
|---|
| 691 | 707 | static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { |
|---|
| .. | .. |
|---|
| 749 | 765 | [CXT_FIXUP_STEREO_DMIC] = { |
|---|
| 750 | 766 | .type = HDA_FIXUP_FUNC, |
|---|
| 751 | 767 | .v.func = cxt_fixup_stereo_dmic, |
|---|
| 768 | + }, |
|---|
| 769 | + [CXT_PINCFG_LENOVO_NOTEBOOK] = { |
|---|
| 770 | + .type = HDA_FIXUP_PINS, |
|---|
| 771 | + .v.pins = (const struct hda_pintbl[]) { |
|---|
| 772 | + { 0x1a, 0x05d71030 }, |
|---|
| 773 | + { } |
|---|
| 774 | + }, |
|---|
| 775 | + .chain_id = CXT_FIXUP_STEREO_DMIC, |
|---|
| 752 | 776 | }, |
|---|
| 753 | 777 | [CXT_FIXUP_INC_MIC_BOOST] = { |
|---|
| 754 | 778 | .type = HDA_FIXUP_FUNC, |
|---|
| .. | .. |
|---|
| 846 | 870 | .type = HDA_FIXUP_FUNC, |
|---|
| 847 | 871 | .v.func = cxt_fixup_mute_led_gpio, |
|---|
| 848 | 872 | }, |
|---|
| 873 | + [CXT_FIXUP_HP_ZBOOK_MUTE_LED] = { |
|---|
| 874 | + .type = HDA_FIXUP_FUNC, |
|---|
| 875 | + .v.func = cxt_fixup_hp_zbook_mute_led, |
|---|
| 876 | + }, |
|---|
| 849 | 877 | [CXT_FIXUP_HEADSET_MIC] = { |
|---|
| 850 | 878 | .type = HDA_FIXUP_FUNC, |
|---|
| 851 | 879 | .v.func = cxt_fixup_headset_mic, |
|---|
| .. | .. |
|---|
| 918 | 946 | SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), |
|---|
| 919 | 947 | SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
|---|
| 920 | 948 | SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
|---|
| 949 | + SND_PCI_QUIRK(0x103c, 0x82b4, "HP ProDesk 600 G3", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
|---|
| 921 | 950 | SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO), |
|---|
| 922 | 951 | SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO), |
|---|
| 923 | 952 | SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK), |
|---|
| 924 | 953 | SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), |
|---|
| 925 | 954 | SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), |
|---|
| 926 | 955 | SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO), |
|---|
| 956 | + SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED), |
|---|
| 957 | + SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED), |
|---|
| 927 | 958 | SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
|---|
| 928 | 959 | SND_PCI_QUIRK(0x103c, 0x8456, "HP Z2 G4 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
|---|
| 929 | 960 | SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE), |
|---|
| .. | .. |
|---|
| 942 | 973 | SND_PCI_QUIRK(0x17aa, 0x3905, "Lenovo G50-30", CXT_FIXUP_STEREO_DMIC), |
|---|
| 943 | 974 | SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC), |
|---|
| 944 | 975 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), |
|---|
| 976 | + /* NOTE: we'd need to extend the quirk for 17aa:3977 as the same |
|---|
| 977 | + * PCI SSID is used on multiple Lenovo models |
|---|
| 978 | + */ |
|---|
| 945 | 979 | SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), |
|---|
| 946 | 980 | SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC), |
|---|
| 947 | 981 | SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), |
|---|
| .. | .. |
|---|
| 963 | 997 | { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, |
|---|
| 964 | 998 | { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, |
|---|
| 965 | 999 | { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, |
|---|
| 1000 | + { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" }, |
|---|
| 966 | 1001 | { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, |
|---|
| 1002 | + { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, |
|---|
| 967 | 1003 | {} |
|---|
| 968 | 1004 | }; |
|---|
| 969 | 1005 | |
|---|
| .. | .. |
|---|
| 973 | 1009 | static void add_cx5051_fake_mutes(struct hda_codec *codec) |
|---|
| 974 | 1010 | { |
|---|
| 975 | 1011 | struct conexant_spec *spec = codec->spec; |
|---|
| 976 | | - static hda_nid_t out_nids[] = { |
|---|
| 1012 | + static const hda_nid_t out_nids[] = { |
|---|
| 977 | 1013 | 0x10, 0x11, 0 |
|---|
| 978 | 1014 | }; |
|---|
| 979 | | - hda_nid_t *p; |
|---|
| 1015 | + const hda_nid_t *p; |
|---|
| 980 | 1016 | |
|---|
| 981 | 1017 | for (p = out_nids; *p; p++) |
|---|
| 982 | 1018 | snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT, |
|---|
| .. | .. |
|---|
| 1001 | 1037 | |
|---|
| 1002 | 1038 | cx_auto_parse_eapd(codec); |
|---|
| 1003 | 1039 | spec->gen.own_eapd_ctl = 1; |
|---|
| 1004 | | - if (spec->dynamic_eapd) |
|---|
| 1005 | | - spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook; |
|---|
| 1006 | 1040 | |
|---|
| 1007 | 1041 | switch (codec->core.vendor_id) { |
|---|
| 1008 | 1042 | case 0x14f15045: |
|---|
| .. | .. |
|---|
| 1025 | 1059 | snd_hda_pick_fixup(codec, cxt5051_fixup_models, |
|---|
| 1026 | 1060 | cxt5051_fixups, cxt_fixups); |
|---|
| 1027 | 1061 | break; |
|---|
| 1062 | + case 0x14f15098: |
|---|
| 1063 | + codec->pin_amp_workaround = 1; |
|---|
| 1064 | + spec->gen.mixer_nid = 0x22; |
|---|
| 1065 | + spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO; |
|---|
| 1066 | + snd_hda_pick_fixup(codec, cxt5066_fixup_models, |
|---|
| 1067 | + cxt5066_fixups, cxt_fixups); |
|---|
| 1068 | + break; |
|---|
| 1028 | 1069 | case 0x14f150f2: |
|---|
| 1029 | 1070 | codec->power_save_node = 1; |
|---|
| 1030 | | - /* Fall through */ |
|---|
| 1071 | + fallthrough; |
|---|
| 1031 | 1072 | default: |
|---|
| 1032 | 1073 | codec->pin_amp_workaround = 1; |
|---|
| 1033 | 1074 | snd_hda_pick_fixup(codec, cxt5066_fixup_models, |
|---|
| .. | .. |
|---|
| 1035 | 1076 | break; |
|---|
| 1036 | 1077 | } |
|---|
| 1037 | 1078 | |
|---|
| 1038 | | - /* Show mute-led control only on HP laptops |
|---|
| 1039 | | - * This is a sort of white-list: on HP laptops, EAPD corresponds |
|---|
| 1040 | | - * only to the mute-LED without actualy amp function. Meanwhile, |
|---|
| 1041 | | - * others may use EAPD really as an amp switch, so it might be |
|---|
| 1042 | | - * not good to expose it blindly. |
|---|
| 1043 | | - */ |
|---|
| 1044 | | - switch (codec->core.subsystem_id >> 16) { |
|---|
| 1045 | | - case 0x103c: |
|---|
| 1046 | | - spec->gen.vmaster_mute_enum = 1; |
|---|
| 1047 | | - break; |
|---|
| 1048 | | - } |
|---|
| 1079 | + if (!spec->gen.vmaster_mute.hook && spec->dynamic_eapd) |
|---|
| 1080 | + spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook; |
|---|
| 1049 | 1081 | |
|---|
| 1050 | 1082 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
|---|
| 1051 | 1083 | |
|---|
| .. | .. |
|---|
| 1054 | 1086 | if (err < 0) |
|---|
| 1055 | 1087 | goto error; |
|---|
| 1056 | 1088 | |
|---|
| 1057 | | - err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
|---|
| 1089 | + err = cx_auto_parse_beep(codec); |
|---|
| 1058 | 1090 | if (err < 0) |
|---|
| 1059 | 1091 | goto error; |
|---|
| 1060 | 1092 | |
|---|
| 1061 | | - err = cx_auto_parse_beep(codec); |
|---|
| 1093 | + err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); |
|---|
| 1062 | 1094 | if (err < 0) |
|---|
| 1063 | 1095 | goto error; |
|---|
| 1064 | 1096 | |
|---|
| .. | .. |
|---|
| 1089 | 1121 | HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto), |
|---|
| 1090 | 1122 | HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto), |
|---|
| 1091 | 1123 | HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto), |
|---|
| 1124 | + HDA_CODEC_ENTRY(0x14f120d1, "SN6180", patch_conexant_auto), |
|---|
| 1092 | 1125 | HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto), |
|---|
| 1093 | 1126 | HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto), |
|---|
| 1094 | 1127 | HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto), |
|---|