diff options
Diffstat (limited to 'sound/pci')
43 files changed, 1908 insertions, 382 deletions
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h index de3bedd29d94..8ec656cf8848 100644 --- a/sound/pci/asihpi/hpicmn.h +++ b/sound/pci/asihpi/hpicmn.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* AudioScience HPI driver Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h index a01e8c6092bd..9f1468ed7096 100644 --- a/sound/pci/asihpi/hpidspcd.h +++ b/sound/pci/asihpi/hpidspcd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /***********************************************************************/ -/** +/* AudioScience HPI driver Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> diff --git a/sound/pci/ctxfi/ct20k1reg.h b/sound/pci/ctxfi/ct20k1reg.h index d4bfee499fb1..05bb006c0f4c 100644 --- a/sound/pci/ctxfi/ct20k1reg.h +++ b/sound/pci/ctxfi/ct20k1reg.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. */ diff --git a/sound/pci/ctxfi/ct20k2reg.h b/sound/pci/ctxfi/ct20k2reg.h index af94ea66fdda..02f67828eabe 100644 --- a/sound/pci/ctxfi/ct20k2reg.h +++ b/sound/pci/ctxfi/ct20k2reg.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. */ diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c index d4ff377eb3a3..da6e6350ceaf 100644 --- a/sound/pci/ctxfi/ctamixer.c +++ b/sound/pci/ctxfi/ctamixer.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctamixer.c diff --git a/sound/pci/ctxfi/ctamixer.h b/sound/pci/ctxfi/ctamixer.h index 4fafb397abed..4498e6139d0e 100644 --- a/sound/pci/ctxfi/ctamixer.h +++ b/sound/pci/ctxfi/ctamixer.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctamixer.h diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index f8ac96cf38a4..78f35e88aed6 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctatc.c diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index ac31b32b277b..0bc7b71d910b 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctatc.h diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 4cb47b5a792c..f589da045342 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctdaio.c diff --git a/sound/pci/ctxfi/ctdaio.h b/sound/pci/ctxfi/ctdaio.h index 431583bb0a3e..bd6310f48013 100644 --- a/sound/pci/ctxfi/ctdaio.h +++ b/sound/pci/ctxfi/ctdaio.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctdaio.h diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h index 9e6b83bd432d..f406b626a28c 100644 --- a/sound/pci/ctxfi/cthardware.h +++ b/sound/pci/ctxfi/cthardware.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File cthardware.h diff --git a/sound/pci/ctxfi/cthw20k1.h b/sound/pci/ctxfi/cthw20k1.h index b7cbe82d71bd..ffb019abf651 100644 --- a/sound/pci/ctxfi/cthw20k1.h +++ b/sound/pci/ctxfi/cthw20k1.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File cthw20k1.h diff --git a/sound/pci/ctxfi/cthw20k2.h b/sound/pci/ctxfi/cthw20k2.h index 797b13dcd84c..6993a3d5277a 100644 --- a/sound/pci/ctxfi/cthw20k2.h +++ b/sound/pci/ctxfi/cthw20k2.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File cthw20k2.h diff --git a/sound/pci/ctxfi/ctimap.h b/sound/pci/ctxfi/ctimap.h index 79bc94bce4d5..49b1bb831410 100644 --- a/sound/pci/ctxfi/ctimap.h +++ b/sound/pci/ctxfi/ctimap.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctimap.h diff --git a/sound/pci/ctxfi/ctmixer.h b/sound/pci/ctxfi/ctmixer.h index 770dc18a85e8..e812f6c93b41 100644 --- a/sound/pci/ctxfi/ctmixer.h +++ b/sound/pci/ctxfi/ctmixer.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctmixer.h diff --git a/sound/pci/ctxfi/ctpcm.h b/sound/pci/ctxfi/ctpcm.h index dfa1c62f7d1e..8b39bdd262b4 100644 --- a/sound/pci/ctxfi/ctpcm.h +++ b/sound/pci/ctxfi/ctpcm.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctpcm.h diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c index 6d0a01b189e1..81ad26934518 100644 --- a/sound/pci/ctxfi/ctresource.c +++ b/sound/pci/ctxfi/ctresource.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctresource.c diff --git a/sound/pci/ctxfi/ctresource.h b/sound/pci/ctxfi/ctresource.h index 93e47488a1c1..fdbfd808816d 100644 --- a/sound/pci/ctxfi/ctresource.h +++ b/sound/pci/ctxfi/ctresource.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctresource.h diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index 37c18ce84974..bd4697b44233 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctsrc.c diff --git a/sound/pci/ctxfi/ctsrc.h b/sound/pci/ctxfi/ctsrc.h index 1204962280c8..1124daf50c9b 100644 --- a/sound/pci/ctxfi/ctsrc.h +++ b/sound/pci/ctxfi/ctsrc.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctsrc.h diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index bde28aa9e139..7a805c4a58e1 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctvmem.c diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h index 54818a3c245d..da54cbcdb0be 100644 --- a/sound/pci/ctxfi/ctvmem.h +++ b/sound/pci/ctxfi/ctvmem.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/** +/* * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. * * @File ctvmem.h diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 90759391cbac..c4360cdbc728 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -221,10 +221,8 @@ comment "Set to Y if you want auto-loading the codec driver" config SND_HDA_GENERIC tristate "Enable generic HD-audio codec parser" - select NEW_LEDS if SND_HDA_GENERIC_LEDS + select SND_CTL_LED if SND_HDA_GENERIC_LEDS select LEDS_CLASS if SND_HDA_GENERIC_LEDS - select LEDS_TRIGGERS if SND_HDA_GENERIC_LEDS - select LEDS_TRIGGER_AUDIO if SND_HDA_GENERIC_LEDS help Say Y or M here to enable the generic HD-audio codec parser in snd-hda-intel driver. diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index a22ca0e17a08..df63d66af1ab 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h @@ -27,7 +27,7 @@ enum { }; #define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS -#define AUTO_CFG_MAX_INS 8 +#define AUTO_CFG_MAX_INS 18 struct auto_pin_cfg_item { hda_nid_t pin; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2026f1ccaf5a..a31009afc025 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1938,6 +1938,7 @@ static int add_follower(struct hda_codec *codec, * @followers: follower control names (optional) * @suffix: suffix string to each follower name (optional) * @init_follower_vol: initialize followers to unmute/0dB + * @access: kcontrol access rights * @ctl_ret: store the vmaster kcontrol in return * * Create a virtual master control with the given name. The TLV data @@ -1952,7 +1953,7 @@ static int add_follower(struct hda_codec *codec, int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, unsigned int *tlv, const char * const *followers, const char *suffix, bool init_follower_vol, - struct snd_kcontrol **ctl_ret) + unsigned int access, struct snd_kcontrol **ctl_ret) { struct snd_kcontrol *kctl; int err; @@ -1968,6 +1969,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, kctl = snd_ctl_make_virtual_master(name, tlv); if (!kctl) return -ENOMEM; + kctl->vd[0].access |= access; err = snd_hda_ctl_add(codec, 0, kctl); if (err < 0) return err; @@ -1994,87 +1996,29 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, } EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster); -/* - * mute-LED control using vmaster - */ -static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "On", "Off", "Follow Master" - }; - - return snd_ctl_enum_info(uinfo, 1, 3, texts); -} - -static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = hook->mute_mode; - return 0; -} - -static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol); - unsigned int old_mode = hook->mute_mode; - - hook->mute_mode = ucontrol->value.enumerated.item[0]; - if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER) - hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER; - if (old_mode == hook->mute_mode) - return 0; - snd_hda_sync_vmaster_hook(hook); - return 1; -} - -static const struct snd_kcontrol_new vmaster_mute_mode = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mute-LED Mode", - .info = vmaster_mute_mode_info, - .get = vmaster_mute_mode_get, - .put = vmaster_mute_mode_put, -}; - /* meta hook to call each driver's vmaster hook */ static void vmaster_hook(void *private_data, int enabled) { struct hda_vmaster_mute_hook *hook = private_data; - if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER) - enabled = hook->mute_mode; hook->hook(hook->codec, enabled); } /** - * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED + * snd_hda_add_vmaster_hook - Add a vmaster hw specific hook * @codec: the HDA codec * @hook: the vmaster hook object - * @expose_enum_ctl: flag to create an enum ctl * - * Add a mute-LED hook with the given vmaster switch kctl. - * When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically - * created and associated with the given hook. + * Add a hw specific hook (like EAPD) with the given vmaster switch kctl. */ int snd_hda_add_vmaster_hook(struct hda_codec *codec, - struct hda_vmaster_mute_hook *hook, - bool expose_enum_ctl) + struct hda_vmaster_mute_hook *hook) { - struct snd_kcontrol *kctl; - if (!hook->hook || !hook->sw_kctl) return 0; hook->codec = codec; - hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER; snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook); - if (!expose_enum_ctl) - return 0; - kctl = snd_ctl_new1(&vmaster_mute_mode, hook); - if (!kctl) - return -ENOMEM; - return snd_hda_ctl_add(codec, 0, kctl); + return 0; } EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook); diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index f5cba7afd1c6..3998e1771805 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -981,6 +981,8 @@ add_control(struct hda_gen_spec *spec, int type, const char *name, knew->index = cidx; if (get_amp_nid_(val)) knew->subdevice = HDA_SUBDEV_AMP_FLAG; + if (knew->access == 0) + knew->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; knew->private_value = val; return knew; } @@ -3618,8 +3620,11 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label, amp_val_replace_channels(ctl, chs)); if (!knew) return -ENOMEM; - if (is_switch) + if (is_switch) { knew->put = cap_single_sw_put; + if (spec->mic_mute_led) + knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED; + } if (!inv_dmic) return 0; @@ -3634,8 +3639,11 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label, amp_val_replace_channels(ctl, 2)); if (!knew) return -ENOMEM; - if (is_switch) + if (is_switch) { knew->put = cap_single_sw_put; + if (spec->mic_mute_led) + knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED; + } return 0; } @@ -3676,6 +3684,8 @@ static int create_bind_cap_vol_ctl(struct hda_codec *codec, int idx, knew->index = idx; knew->private_value = sw_ctl; knew->subdevice = HDA_SUBDEV_AMP_FLAG; + if (spec->mic_mute_led) + knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED; } return 0; } @@ -3917,11 +3927,6 @@ static int create_mute_led_cdev(struct hda_codec *codec, return devm_led_classdev_register(&codec->core.dev, cdev); } -static void vmaster_update_mute_led(void *private_data, int enabled) -{ - ledtrig_audio_set(LED_AUDIO_MUTE, enabled ? LED_OFF : LED_ON); -} - /** * snd_hda_gen_add_mute_led_cdev - Create a LED classdev and enable as vmaster mute LED * @codec: the HDA codec @@ -3945,134 +3950,11 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec, if (spec->vmaster_mute.hook) codec_err(codec, "vmaster hook already present before cdev!\n"); - spec->vmaster_mute.hook = vmaster_update_mute_led; - spec->vmaster_mute_enum = 1; + spec->vmaster_mute_led = 1; return 0; } EXPORT_SYMBOL_GPL(snd_hda_gen_add_mute_led_cdev); -/* - * mic mute LED hook helpers - */ -enum { - MICMUTE_LED_ON, - MICMUTE_LED_OFF, - MICMUTE_LED_FOLLOW_CAPTURE, - MICMUTE_LED_FOLLOW_MUTE, -}; - -static void call_micmute_led_update(struct hda_codec *codec) -{ - struct hda_gen_spec *spec = codec->spec; - unsigned int val; - - switch (spec->micmute_led.led_mode) { - case MICMUTE_LED_ON: - val = 1; - break; - case MICMUTE_LED_OFF: - val = 0; - break; - case MICMUTE_LED_FOLLOW_CAPTURE: - val = !!spec->micmute_led.capture; - break; - case MICMUTE_LED_FOLLOW_MUTE: - default: - val = !spec->micmute_led.capture; - break; - } - - if (val == spec->micmute_led.led_value) - return; - spec->micmute_led.led_value = val; - ledtrig_audio_set(LED_AUDIO_MICMUTE, - spec->micmute_led.led_value ? LED_ON : LED_OFF); -} - -static void update_micmute_led(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_gen_spec *spec = codec->spec; - unsigned int mask; - - if (spec->micmute_led.old_hook) - spec->micmute_led.old_hook(codec, kcontrol, ucontrol); - - if (!ucontrol) - return; - mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - if (!strcmp("Capture Switch", ucontrol->id.name)) { - /* TODO: How do I verify if it's a mono or stereo here? */ - if (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]) - spec->micmute_led.capture |= mask; - else - spec->micmute_led.capture &= ~mask; - call_micmute_led_update(codec); - } -} - -static int micmute_led_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static const char * const texts[] = { - "On", "Off", "Follow Capture", "Follow Mute", - }; - - return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); -} - -static int micmute_led_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct hda_gen_spec *spec = codec->spec; - - ucontrol->value.enumerated.item[0] = spec->micmute_led.led_mode; - return 0; -} - -static int micmute_led_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct hda_gen_spec *spec = codec->spec; - unsigned int mode; - - mode = ucontrol->value.enumerated.item[0]; - if (mode > MICMUTE_LED_FOLLOW_MUTE) - mode = MICMUTE_LED_FOLLOW_MUTE; - if (mode == spec->micmute_led.led_mode) - return 0; - spec->micmute_led.led_mode = mode; - call_micmute_led_update(codec); - return 1; -} - -static const struct snd_kcontrol_new micmute_led_mode_ctl = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Mute-LED Mode", - .info = micmute_led_mode_info, - .get = micmute_led_mode_get, - .put = micmute_led_mode_put, -}; - -/* Set up the capture sync hook for controlling the mic-mute LED */ -static int add_micmute_led_hook(struct hda_codec *codec) -{ - struct hda_gen_spec *spec = codec->spec; - - spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE; - spec->micmute_led.capture = 0; - spec->micmute_led.led_value = -1; - spec->micmute_led.old_hook = spec->cap_sync_hook; - spec->cap_sync_hook = update_micmute_led; - if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl)) - return -ENOMEM; - return 0; -} - /** * snd_hda_gen_add_micmute_led_cdev - Create a LED classdev and enable as mic-mute LED * @codec: the HDA codec @@ -4091,6 +3973,7 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec, int (*callback)(struct led_classdev *, enum led_brightness)) { + struct hda_gen_spec *spec = codec->spec; int err; if (callback) { @@ -4101,7 +3984,8 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec, } } - return add_micmute_led_hook(codec); + spec->mic_mute_led = 1; + return 0; } EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led_cdev); #endif /* CONFIG_SND_HDA_GENERIC_LEDS */ @@ -5060,6 +4944,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, parse_user_hints(codec); + if (spec->vmaster_mute_led || spec->mic_mute_led) + snd_ctl_led_request(); + if (spec->mixer_nid && !spec->mixer_merge_nid) spec->mixer_merge_nid = spec->mixer_nid; @@ -5291,7 +5178,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec) !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { err = snd_hda_add_vmaster(codec, "Master Playback Volume", spec->vmaster_tlv, follower_pfxs, - "Playback Volume"); + "Playback Volume", 0); if (err < 0) return err; } @@ -5299,13 +5186,14 @@ int snd_hda_gen_build_controls(struct hda_codec *codec) !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { err = __snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, follower_pfxs, - "Playback Switch", - true, &spec->vmaster_mute.sw_kctl); + "Playback Switch", true, + spec->vmaster_mute_led ? + SNDRV_CTL_ELEM_ACCESS_SPK_LED : 0, + &spec->vmaster_mute.sw_kctl); if (err < 0) return err; if (spec->vmaster_mute.hook) { - snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, - spec->vmaster_mute_enum); + snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute); snd_hda_sync_vmaster_hook(&spec->vmaster_mute); } } diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 0886bc81f40b..d4dd1b8a2e7e 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -84,15 +84,6 @@ struct badness_table { extern const struct badness_table hda_main_out_badness; extern const struct badness_table hda_extra_out_badness; -struct hda_micmute_hook { - unsigned int led_mode; - unsigned int capture; - unsigned int led_value; - void (*old_hook)(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol); -}; - struct hda_gen_spec { char stream_name_analog[32]; /* analog PCM stream */ const struct hda_pcm_stream *stream_analog_playback; @@ -229,7 +220,8 @@ struct hda_gen_spec { unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ unsigned int own_eapd_ctl:1; /* set EAPD by own function */ unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */ - unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */ + unsigned int vmaster_mute_led:1; /* add SPK-LED flag to vmaster mute switch */ + unsigned int mic_mute_led:1; /* add MIC-LED flag to capture mute switch */ unsigned int indep_hp:1; /* independent HP supported */ unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */ unsigned int add_stereo_mix_input:2; /* add aamix as a capture src */ @@ -285,9 +277,6 @@ struct hda_gen_spec { struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); - /* mic mute LED hook; called via cap_sync_hook */ - struct hda_micmute_hook micmute_led; - /* PCM hooks */ void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo, struct hda_codec *codec, diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index ac00866d8032..f29975e3e98d 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -389,6 +389,69 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack); /** + * snd_hda_jack_bind_keymap - bind keys generated from one NID to another jack. + * @codec: the HDA codec + * @key_nid: key event is generated by this pin NID + * @keymap: map of key type and key code + * @jack_nid: key reports to the jack of this pin NID + * + * This function is used in the case of key is generated from one NID while is + * reported to the jack of another NID. + */ +int snd_hda_jack_bind_keymap(struct hda_codec *codec, hda_nid_t key_nid, + const struct hda_jack_keymap *keymap, + hda_nid_t jack_nid) +{ + const struct hda_jack_keymap *map; + struct hda_jack_tbl *key_gen = snd_hda_jack_tbl_get(codec, key_nid); + struct hda_jack_tbl *report_to = snd_hda_jack_tbl_get(codec, jack_nid); + + WARN_ON(codec->dp_mst); + + if (!key_gen || !report_to || !report_to->jack) + return -EINVAL; + + key_gen->key_report_jack = jack_nid; + + if (keymap) + for (map = keymap; map->type; map++) + snd_jack_set_key(report_to->jack, map->type, map->key); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hda_jack_bind_keymap); + +/** + * snd_hda_jack_set_button_state - report button event to the hda_jack_tbl button_state. + * @codec: the HDA codec + * @jack_nid: the button event reports to the jack_tbl of this NID + * @button_state: the button event captured by codec + * + * Codec driver calls this function to report the button event. + */ +void snd_hda_jack_set_button_state(struct hda_codec *codec, hda_nid_t jack_nid, + int button_state) +{ + struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, jack_nid); + + if (!jack) + return; + + if (jack->key_report_jack) { + struct hda_jack_tbl *report_to = + snd_hda_jack_tbl_get(codec, jack->key_report_jack); + + if (report_to) { + report_to->button_state = button_state; + return; + } + } + + jack->button_state = button_state; +} +EXPORT_SYMBOL_GPL(snd_hda_jack_set_button_state); + +/** * snd_hda_jack_report_sync - sync the states of all jacks and report if changed * @codec: the HDA codec */ @@ -651,7 +714,15 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) } if (!event) return; - event->jack_dirty = 1; + + if (event->key_report_jack) { + struct hda_jack_tbl *report_to = + snd_hda_jack_tbl_get_mst(codec, event->key_report_jack, + event->dev_id); + if (report_to) + report_to->jack_dirty = 1; + } else + event->jack_dirty = 1; call_jack_callback(codec, res, event); snd_hda_jack_report_sync(codec); diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 8ceaf0ef5df1..2abf7aac243a 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -40,6 +40,7 @@ struct hda_jack_tbl { unsigned int block_report:1; /* in a transitional state - do not report to userspace */ hda_nid_t gating_jack; /* valid when gating jack plugged */ hda_nid_t gated_jack; /* gated is dependent on this jack */ + hda_nid_t key_report_jack; /* key reports to this jack */ int type; int button_state; struct snd_jack *jack; @@ -99,6 +100,13 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, hda_nid_t gating_nid); +int snd_hda_jack_bind_keymap(struct hda_codec *codec, hda_nid_t key_nid, + const struct hda_jack_keymap *keymap, + hda_nid_t jack_nid); + +void snd_hda_jack_set_button_state(struct hda_codec *codec, hda_nid_t jack_nid, + int button_state); + u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id); /* the jack state returned from snd_hda_jack_detect_state() */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 5beb8aa44ecd..4c5589c10f1d 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -131,21 +131,15 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, unsigned int *tlv, const char * const *followers, const char *suffix, bool init_follower_vol, - struct snd_kcontrol **ctl_ret); -#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix) \ - __snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, NULL) + unsigned int access, struct snd_kcontrol **ctl_ret); +#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix, access) \ + __snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, access, NULL) int snd_hda_codec_reset(struct hda_codec *codec); void snd_hda_codec_register(struct hda_codec *codec); void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec); #define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core) -enum { - HDA_VMUTE_OFF, - HDA_VMUTE_ON, - HDA_VMUTE_FOLLOW_MASTER, -}; - struct hda_vmaster_mute_hook { /* below two fields must be filled by the caller of * snd_hda_add_vmaster_hook() beforehand @@ -153,13 +147,11 @@ struct hda_vmaster_mute_hook { struct snd_kcontrol *sw_kctl; void (*hook)(void *, int); /* below are initialized automatically */ - unsigned int mute_mode; /* HDA_VMUTE_XXX */ struct hda_codec *codec; }; int snd_hda_add_vmaster_hook(struct hda_codec *codec, - struct hda_vmaster_mute_hook *hook, - bool expose_enum_ctl); + struct hda_vmaster_mute_hook *hook); void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook); /* amp value bits */ @@ -180,7 +172,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); /* * input MUX helper */ -#define HDA_MAX_NUM_INPUTS 16 +#define HDA_MAX_NUM_INPUTS 36 struct hda_input_mux_item { char label[32]; unsigned int index; diff --git a/sound/pci/hda/ideapad_s740_helper.c b/sound/pci/hda/ideapad_s740_helper.c new file mode 100644 index 000000000000..564b9086e52d --- /dev/null +++ b/sound/pci/hda/ideapad_s740_helper.c @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Fixes for Lenovo Ideapad S740, to be included from codec driver */ + +static const struct hda_verb alc285_ideapad_s740_coefs[] = { +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x10 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0320 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 }, +{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, +{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, +{} +}; + +static void alc285_fixup_ideapad_s740_coef(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + snd_hda_add_verbs(codec, alc285_ideapad_s740_coefs); + break; + } +} diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index b2b620f6c832..49b4fdd2feab 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -7041,11 +7041,11 @@ static int ca0132_build_controls(struct hda_codec *codec) spec->tlv); snd_hda_add_vmaster(codec, "Master Playback Volume", spec->tlv, ca0132_alt_follower_pfxs, - "Playback Volume"); + "Playback Volume", 0); err = __snd_hda_add_vmaster(codec, "Master Playback Switch", NULL, ca0132_alt_follower_pfxs, "Playback Switch", - true, &spec->vmaster_mute.sw_kctl); + true, 0, &spec->vmaster_mute.sw_kctl); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index f46204ab0b90..726507d0b04c 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -9,6 +9,8 @@ #include <linux/slab.h> #include <linux/module.h> #include <sound/core.h> +#include <linux/mutex.h> +#include <linux/pci.h> #include <sound/tlv.h> #include <sound/hda_codec.h> #include "hda_local.h" @@ -19,6 +21,9 @@ /* */ +#define CS42L42_HP_CH (2U) +#define CS42L42_HS_MIC_CH (1U) + struct cs_spec { struct hda_gen_spec gen; @@ -37,6 +42,18 @@ struct cs_spec { /* for MBP SPDIF control */ int (*spdif_sw_put)(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); + + unsigned int cs42l42_hp_jack_in:1; + unsigned int cs42l42_mic_jack_in:1; + unsigned int cs42l42_volume_init:1; + char cs42l42_hp_volume[CS42L42_HP_CH]; + char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH]; + + struct mutex cs8409_i2c_mux; + + /* verb exec op override */ + int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, + unsigned int flags, unsigned int *res); }; /* available models with CS420x */ @@ -110,7 +127,7 @@ enum { * 1 DAC => HP(sense) / Speakers, * 1 ADC <= LineIn(sense) / MicIn / DMicIn, * 1 SPDIF OUT => SPDIF Trasmitter(sense) -*/ + */ #define CS4210_DAC_NID 0x02 #define CS4210_ADC_NID 0x03 #define CS4210_VENDOR_NID 0x0B @@ -129,6 +146,7 @@ enum { static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) { struct cs_spec *spec = codec->spec; + snd_hda_codec_write(codec, spec->vendor_nid, 0, AC_VERB_SET_COEF_INDEX, idx); return snd_hda_codec_read(codec, spec->vendor_nid, 0, @@ -139,6 +157,7 @@ static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, unsigned int coef) { struct cs_spec *spec = codec->spec; + snd_hda_codec_write(codec, spec->vendor_nid, 0, AC_VERB_SET_COEF_INDEX, idx); snd_hda_codec_write(codec, spec->vendor_nid, 0, @@ -175,6 +194,7 @@ static void cs_automute(struct hda_codec *codec) static bool is_active_pin(struct hda_codec *codec, hda_nid_t nid) { unsigned int val; + val = snd_hda_codec_get_pincfg(codec, nid); return (get_defcfg_connect(val) != AC_JACK_PORT_NONE); } @@ -193,7 +213,7 @@ static void init_input_coef(struct hda_codec *codec) coef |= 1 << 3; /* DMIC1 2 chan on, GPIO0 off * No effect if SPDIF_OUT2 is * selected in IDX_SPDIF_CTL. - */ + */ cs_vendor_coef_set(codec, IDX_BEEP_CFG, coef); } @@ -267,13 +287,6 @@ static const struct hda_verb cs_errata_init_verbs[] = { {0x11, AC_VERB_SET_COEF_INDEX, 0x0001}, {0x11, AC_VERB_SET_PROC_COEF, 0x0008}, {0x11, AC_VERB_SET_PROC_STATE, 0x00}, - -#if 0 /* Don't to set to D3 as we are in power-up sequence */ - {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */ - {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */ - /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */ -#endif - {} /* terminator */ }; @@ -361,8 +374,10 @@ static int cs_parse_auto_config(struct hda_codec *codec) /* keep the ADCs powered up when it's dynamically switchable */ if (spec->gen.dyn_adc_switch) { unsigned int done = 0; + for (i = 0; i < spec->gen.input_mux.num_items; i++) { int idx = spec->gen.dyn_adc_idx[i]; + if (done & (1 << idx)) continue; snd_hda_gen_fix_pin_power(codec, @@ -496,6 +511,7 @@ static void cs420x_fixup_gpio_13(struct hda_codec *codec, { if (action == HDA_FIXUP_ACT_PRE_PROBE) { struct cs_spec *spec = codec->spec; + spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */ spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ spec->gpio_mask = spec->gpio_dir = @@ -508,6 +524,7 @@ static void cs420x_fixup_gpio_23(struct hda_codec *codec, { if (action == HDA_FIXUP_ACT_PRE_PROBE) { struct cs_spec *spec = codec->spec; + spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */ spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ spec->gpio_mask = spec->gpio_dir = @@ -652,6 +669,7 @@ static void cs4208_fixup_gpio0(struct hda_codec *codec, { if (action == HDA_FIXUP_ACT_PRE_PROBE) { struct cs_spec *spec = codec->spec; + spec->gpio_eapd_hp = 0; spec->gpio_eapd_speaker = 1; spec->gpio_mask = spec->gpio_dir = @@ -806,7 +824,7 @@ static int patch_cs4208(struct hda_codec *codec) * 1 DAC => HP(sense) / Speakers, * 1 ADC <= LineIn(sense) / MicIn / DMicIn, * 1 SPDIF OUT => SPDIF Trasmitter(sense) -*/ + */ /* CS4210 board names */ static const struct hda_model_fixup cs421x_models[] = { @@ -849,6 +867,7 @@ static void cs421x_fixup_sense_b(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct cs_spec *spec = codec->spec; + if (action == HDA_FIXUP_ACT_PRE_PROBE) spec->sense_b = 1; } @@ -874,9 +893,9 @@ static const struct hda_verb cs421x_coef_init_verbs[] = { {0x0B, AC_VERB_SET_PROC_STATE, 1}, {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG}, /* - Disable Coefficient Index Auto-Increment(DAI)=1, - PDREF=0 - */ + * Disable Coefficient Index Auto-Increment(DAI)=1, + * PDREF=0 + */ {0x0B, AC_VERB_SET_PROC_COEF, 0x0001 }, {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG}, @@ -963,12 +982,12 @@ static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol, coef &= ~0x0003; coef |= (vol & 0x0003); - if (original_coef == coef) - return 0; - else { + if (original_coef != coef) { cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef); return 1; } + + return 0; } static const struct snd_kcontrol_new cs421x_speaker_boost_ctl = { @@ -1007,8 +1026,8 @@ static void cs4210_pinmux_init(struct hda_codec *codec) is_active_pin(codec, CS421X_DMIC_PIN_NID)) { /* - GPIO or SENSE_B forced - disconnect the DMIC pin. - */ + * GPIO or SENSE_B forced - disconnect the DMIC pin. + */ def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID); def_conf &= ~AC_DEFCFG_PORT_CONN; def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT); @@ -1047,6 +1066,7 @@ static void parse_cs421x_digital(struct hda_codec *codec) for (i = 0; i < cfg->dig_outs; i++) { hda_nid_t nid = cfg->dig_out_pins[i]; + if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { spec->spdif_detect = 1; snd_hda_jack_detect_enable_callback(codec, nid, @@ -1125,9 +1145,9 @@ static int cs421x_parse_auto_config(struct hda_codec *codec) #ifdef CONFIG_PM /* - Manage PDREF, when transitioning to D3hot - (DAC,ADC) -> D3, PDREF=1, AFG->D3 -*/ + * Manage PDREF, when transitioning to D3hot + * (DAC,ADC) -> D3, PDREF=1, AFG->D3 + */ static int cs421x_suspend(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; @@ -1178,10 +1198,10 @@ static int patch_cs4210(struct hda_codec *codec) snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); /* - Update the GPIO/DMIC/SENSE_B pinmux before the configuration - is auto-parsed. If GPIO or SENSE_B is forced, DMIC input - is disabled. - */ + * Update the GPIO/DMIC/SENSE_B pinmux before the configuration + * is auto-parsed. If GPIO or SENSE_B is forced, DMIC input + * is disabled. + */ cs4210_pinmux_init(codec); err = cs421x_parse_auto_config(codec); @@ -1219,6 +1239,1063 @@ static int patch_cs4213(struct hda_codec *codec) return err; } +/* Cirrus Logic CS8409 HDA bridge with + * companion codec CS42L42 + */ +#define CS8409_VENDOR_NID 0x47 + +#define CS8409_CS42L42_HP_PIN_NID 0x24 +#define CS8409_CS42L42_SPK_PIN_NID 0x2c +#define CS8409_CS42L42_AMIC_PIN_NID 0x34 +#define CS8409_CS42L42_DMIC_PIN_NID 0x44 +#define CS8409_CS42L42_DMIC_ADC_PIN_NID 0x22 + +#define CS42L42_HSDET_AUTO_DONE 0x02 +#define CS42L42_HSTYPE_MASK 0x03 + +#define CS42L42_JACK_INSERTED 0x0C +#define CS42L42_JACK_REMOVED 0x00 + +#define GPIO3_INT (1 << 3) +#define GPIO4_INT (1 << 4) +#define GPIO5_INT (1 << 5) + +#define CS42L42_I2C_ADDR (0x48 << 1) + +#define CIR_I2C_ADDR 0x0059 +#define CIR_I2C_DATA 0x005A +#define CIR_I2C_CTRL 0x005B +#define CIR_I2C_STATUS 0x005C +#define CIR_I2C_QWRITE 0x005D +#define CIR_I2C_QREAD 0x005E + +#define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) +#define CS8409_CS42L42_HP_VOL_REAL_MAX (0) +#define CS8409_CS42L42_AMIC_VOL_REAL_MIN (-97) +#define CS8409_CS42L42_AMIC_VOL_REAL_MAX (12) +#define CS8409_CS42L42_REG_HS_VOLUME_CHA (0x2301) +#define CS8409_CS42L42_REG_HS_VOLUME_CHB (0x2303) +#define CS8409_CS42L42_REG_AMIC_VOLUME (0x1D03) + +struct cs8409_i2c_param { + unsigned int addr; + unsigned int reg; +}; + +struct cs8409_cir_param { + unsigned int nid; + unsigned int cir; + unsigned int coeff; +}; + +enum { + CS8409_BULLSEYE, + CS8409_WARLOCK, + CS8409_CYBORG, + CS8409_FIXUPS, +}; + +static void cs8409_cs42l42_fixups(struct hda_codec *codec, + const struct hda_fixup *fix, int action); +static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, + unsigned int cmd, unsigned int flags, unsigned int *res); + +/* Dell Inspiron models with cs8409/cs42l42 */ +static const struct hda_model_fixup cs8409_models[] = { + { .id = CS8409_BULLSEYE, .name = "bullseye" }, + { .id = CS8409_WARLOCK, .name = "warlock" }, + { .id = CS8409_CYBORG, .name = "cyborg" }, + {} +}; + +/* Dell Inspiron platforms + * with cs8409 bridge and cs42l42 codec + */ +static const struct snd_pci_quirk cs8409_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE), + SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK), + SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG), + SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG), + {} /* terminator */ +}; + +static const struct hda_verb cs8409_cs42l42_init_verbs[] = { + { 0x01, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */ + { 0x47, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */ + { 0x47, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */ + { 0x47, AC_VERB_SET_PROC_COEF, 0x0080 }, /* I2C mode */ + { 0x47, AC_VERB_SET_COEF_INDEX, 0x005b }, /* Set I2C bus speed */ + { 0x47, AC_VERB_SET_PROC_COEF, 0x0200 }, /* 100kHz I2C_STO = 2 */ + {} /* terminator */ +}; + +static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { + { 0x24, 0x042120f0 }, /* ASP-1-TX */ + { 0x34, 0x04a12050 }, /* ASP-1-RX */ + { 0x2c, 0x901000f0 }, /* ASP-2-TX */ + { 0x44, 0x90a00090 }, /* DMIC-1 */ + {} /* terminator */ +}; + +static const struct hda_fixup cs8409_fixups[] = { + [CS8409_BULLSEYE] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_WARLOCK] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_CYBORG] = { + .type = HDA_FIXUP_PINS, + .v.pins = cs8409_cs42l42_pincfgs, + .chained = true, + .chain_id = CS8409_FIXUPS, + }, + [CS8409_FIXUPS] = { + .type = HDA_FIXUP_FUNC, + .v.func = cs8409_cs42l42_fixups, + }, +}; + +/* Vendor specific HW configuration for CS42L42 */ +static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = { + { 0x1010, 0xB0 }, + { 0x1D01, 0x00 }, + { 0x1D02, 0x06 }, + { 0x1D03, 0x00 }, + { 0x1107, 0x01 }, + { 0x1009, 0x02 }, + { 0x1007, 0x03 }, + { 0x1201, 0x00 }, + { 0x1208, 0x13 }, + { 0x1205, 0xFF }, + { 0x1206, 0x00 }, + { 0x1207, 0x20 }, + { 0x1202, 0x0D }, + { 0x2A02, 0x02 }, + { 0x2A03, 0x00 }, + { 0x2A04, 0x00 }, + { 0x2A05, 0x02 }, + { 0x2A06, 0x00 }, + { 0x2A07, 0x20 }, + { 0x2A08, 0x02 }, + { 0x2A09, 0x00 }, + { 0x2A0A, 0x80 }, + { 0x2A0B, 0x02 }, + { 0x2A0C, 0x00 }, + { 0x2A0D, 0xA0 }, + { 0x2A01, 0x0C }, + { 0x2902, 0x01 }, + { 0x2903, 0x02 }, + { 0x2904, 0x00 }, + { 0x2905, 0x00 }, + { 0x2901, 0x01 }, + { 0x1101, 0x0A }, + { 0x1102, 0x84 }, + { 0x2301, 0x00 }, + { 0x2303, 0x00 }, + { 0x2302, 0x3f }, + { 0x2001, 0x03 }, + { 0x1B75, 0xB6 }, + { 0x1B73, 0xC2 }, + { 0x1129, 0x01 }, + { 0x1121, 0xF3 }, + { 0x1103, 0x20 }, + { 0x1105, 0x00 }, + { 0x1112, 0xC0 }, + { 0x1113, 0x80 }, + { 0x1C03, 0xC0 }, + { 0x1105, 0x00 }, + { 0x1112, 0xC0 }, + { 0x1101, 0x02 }, + {} /* Terminator */ +}; + +/* Vendor specific hw configuration for CS8409 */ +static const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = { + { 0x47, 0x00, 0xb008 }, /* +PLL1/2_EN, +I2C_EN */ + { 0x47, 0x01, 0x0002 }, /* ASP1/2_EN=0, ASP1_STP=1 */ + { 0x47, 0x02, 0x0a80 }, /* ASP1/2_BUS_IDLE=10, +GPIO_I2C */ + { 0x47, 0x19, 0x0800 }, /* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { 0x47, 0x1a, 0x0820 }, /* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */ + { 0x47, 0x29, 0x0800 }, /* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */ + { 0x47, 0x2a, 0x2800 }, /* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */ + { 0x47, 0x39, 0x0800 }, /* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */ + { 0x47, 0x3a, 0x0800 }, /* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */ + { 0x47, 0x03, 0x8000 }, /* ASP1: LCHI = 00h */ + { 0x47, 0x04, 0x28ff }, /* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */ + { 0x47, 0x05, 0x0062 }, /* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */ + { 0x47, 0x06, 0x801f }, /* ASP2: LCHI=1Fh */ + { 0x47, 0x07, 0x283f }, /* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */ + { 0x47, 0x08, 0x805c }, /* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */ + { 0x47, 0x09, 0x0023 }, /* DMIC1_MO=10b, DMIC1/2_SR=1 */ + { 0x47, 0x0a, 0x0000 }, /* ASP1/2_BEEP=0 */ + { 0x47, 0x01, 0x0062 }, /* ASP1/2_EN=1, ASP1_STP=1 */ + { 0x47, 0x00, 0x9008 }, /* -PLL2_EN */ + { 0x47, 0x68, 0x0000 }, /* TX2.A: pre-scale att.=0 dB */ + { 0x47, 0x82, 0xfc03 }, /* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */ + { 0x47, 0xc0, 0x9999 }, /* test mode on */ + { 0x47, 0xc5, 0x0000 }, /* GPIO hysteresis = 30 us */ + { 0x47, 0xc0, 0x0000 }, /* test mode off */ + {} /* Terminator */ +}; + +static const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = { + { 0x47, 0x65, 0x4000 }, /* EQ_SEL=1, EQ1/2_EN=0 */ + { 0x47, 0x64, 0x4000 }, /* +EQ_ACC */ + { 0x47, 0x65, 0x4010 }, /* +EQ2_EN */ + { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ + { 0x47, 0x64, 0xc0c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */ + { 0x47, 0x63, 0x0647 }, /* EQ_DATA_HI=0x0647 */ + { 0x47, 0x64, 0xc1c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */ + { 0x47, 0x63, 0xf370 }, /* EQ_DATA_HI=0xf370 */ + { 0x47, 0x64, 0xc271 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */ + { 0x47, 0x63, 0x1ef8 }, /* EQ_DATA_HI=0x1ef8 */ + { 0x47, 0x64, 0xc348 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */ + { 0x47, 0x63, 0xc110 }, /* EQ_DATA_HI=0xc110 */ + { 0x47, 0x64, 0xc45a }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */ + { 0x47, 0x63, 0x1f29 }, /* EQ_DATA_HI=0x1f29 */ + { 0x47, 0x64, 0xc574 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */ + { 0x47, 0x63, 0x1d7a }, /* EQ_DATA_HI=0x1d7a */ + { 0x47, 0x64, 0xc653 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */ + { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ + { 0x47, 0x64, 0xc714 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */ + { 0x47, 0x63, 0x1ca3 }, /* EQ_DATA_HI=0x1ca3 */ + { 0x47, 0x64, 0xc8c7 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */ + { 0x47, 0x63, 0xc38c }, /* EQ_DATA_HI=0xc38c */ + { 0x47, 0x64, 0xc914 }, /* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */ + { 0x47, 0x64, 0x0000 }, /* -EQ_ACC, -EQ_WRT */ + {} /* Terminator */ +}; + +/** + * cs8409_enable_i2c_clock - Enable I2C clocks + * @codec: the codec instance + * @enable: Enable or disable I2C clocks + * + * Enable or Disable I2C clocks. + */ +static void cs8409_enable_i2c_clock(struct hda_codec *codec, unsigned int enable) +{ + unsigned int retval; + unsigned int newval; + + retval = cs_vendor_coef_get(codec, 0x0); + newval = (enable) ? (retval | 0x8) : (retval & 0xfffffff7); + cs_vendor_coef_set(codec, 0x0, newval); +} + +/** + * cs8409_i2c_wait_complete - Wait for I2C transaction + * @codec: the codec instance + * + * Wait for I2C transaction to complete. + * Return -1 if transaction wait times out. + */ +static int cs8409_i2c_wait_complete(struct hda_codec *codec) +{ + int repeat = 5; + unsigned int retval; + + do { + retval = cs_vendor_coef_get(codec, CIR_I2C_STATUS); + if ((retval & 0x18) != 0x18) { + usleep_range(2000, 4000); + --repeat; + } else + return 0; + + } while (repeat); + + return -1; +} + +/** + * cs8409_i2c_read - CS8409 I2C Read. + * @codec: the codec instance + * @i2c_address: I2C Address + * @i2c_reg: Register to read + * @paged: Is a paged transaction + * + * CS8409 I2C Read. + * Returns negative on error, otherwise returns read value in bits 0-7. + */ +static int cs8409_i2c_read(struct hda_codec *codec, + unsigned int i2c_address, + unsigned int i2c_reg, + unsigned int paged) +{ + unsigned int i2c_reg_data; + unsigned int read_data; + + cs8409_enable_i2c_clock(codec, 1); + cs_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); + + if (paged) { + cs_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, + "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + } + + i2c_reg_data = (i2c_reg << 8) & 0x0ffff; + cs_vendor_coef_set(codec, CIR_I2C_QREAD, i2c_reg_data); + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + + /* Register in bits 15-8 and the data in 7-0 */ + read_data = cs_vendor_coef_get(codec, CIR_I2C_QREAD); + + cs8409_enable_i2c_clock(codec, 0); + + return read_data & 0x0ff; +} + +/** + * cs8409_i2c_write - CS8409 I2C Write. + * @codec: the codec instance + * @i2c_address: I2C Address + * @i2c_reg: Register to write to + * @i2c_data: Data to write + * @paged: Is a paged transaction + * + * CS8409 I2C Write. + * Returns negative on error, otherwise returns 0. + */ +static int cs8409_i2c_write(struct hda_codec *codec, + unsigned int i2c_address, unsigned int i2c_reg, + unsigned int i2c_data, + unsigned int paged) +{ + unsigned int i2c_reg_data; + + cs8409_enable_i2c_clock(codec, 1); + cs_vendor_coef_set(codec, CIR_I2C_ADDR, i2c_address); + + if (paged) { + cs_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg >> 8); + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, + "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + } + + i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); + cs_vendor_coef_set(codec, CIR_I2C_QWRITE, i2c_reg_data); + + if (cs8409_i2c_wait_complete(codec) < 0) { + codec_err(codec, "%s() Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; + } + + cs8409_enable_i2c_clock(codec, 0); + + return 0; +} + +static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + u16 nid = get_amp_nid(kcontrol); + u8 chs = get_amp_channels(kcontrol); + + codec_dbg(codec, "%s() nid: %d\n", __func__, nid); + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = chs == 3 ? 2 : 1; + uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN; + uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX; + break; + case CS8409_CS42L42_AMIC_PIN_NID: + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = chs == 3 ? 2 : 1; + uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN; + uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX; + break; + default: + break; + } + return 0; +} + +static void cs8409_cs42l42_update_volume(struct hda_codec *codec) +{ + struct cs_spec *spec = codec->spec; + int data; + + mutex_lock(&spec->cs8409_i2c_mux); + data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHA, 1); + if (data >= 0) + spec->cs42l42_hp_volume[0] = -data; + else + spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN; + data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHB, 1); + if (data >= 0) + spec->cs42l42_hp_volume[1] = -data; + else + spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN; + data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_AMIC_VOLUME, 1); + if (data >= 0) + spec->cs42l42_hs_mic_volume[0] = -data; + else + spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN; + mutex_unlock(&spec->cs8409_i2c_mux); + spec->cs42l42_volume_init = 1; +} + +static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct cs_spec *spec = codec->spec; + hda_nid_t nid = get_amp_nid(kcontrol); + int chs = get_amp_channels(kcontrol); + long *valp = ucontrol->value.integer.value; + + if (!spec->cs42l42_volume_init) { + snd_hda_power_up(codec); + cs8409_cs42l42_update_volume(codec); + snd_hda_power_down(codec); + } + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + if (chs & BIT(0)) + *valp++ = spec->cs42l42_hp_volume[0]; + if (chs & BIT(1)) + *valp++ = spec->cs42l42_hp_volume[1]; + break; + case CS8409_CS42L42_AMIC_PIN_NID: + if (chs & BIT(0)) + *valp++ = spec->cs42l42_hs_mic_volume[0]; + break; + default: + break; + } + return 0; +} + +static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct cs_spec *spec = codec->spec; + hda_nid_t nid = get_amp_nid(kcontrol); + int chs = get_amp_channels(kcontrol); + long *valp = ucontrol->value.integer.value; + int change = 0; + char vol; + + snd_hda_power_up(codec); + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + mutex_lock(&spec->cs8409_i2c_mux); + if (chs & BIT(0)) { + vol = -(*valp); + change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1); + valp++; + } + if (chs & BIT(1)) { + vol = -(*valp); + change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1); + } + mutex_unlock(&spec->cs8409_i2c_mux); + break; + case CS8409_CS42L42_AMIC_PIN_NID: + mutex_lock(&spec->cs8409_i2c_mux); + if (chs & BIT(0)) { + change = cs8409_i2c_write( + codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1); + valp++; + } + mutex_unlock(&spec->cs8409_i2c_mux); + break; + default: + break; + } + cs8409_cs42l42_update_volume(codec); + snd_hda_power_down(codec); + return change; +} + +static const DECLARE_TLV_DB_SCALE( + cs8409_cs42l42_hp_db_scale, + CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); + +static const DECLARE_TLV_DB_SCALE( + cs8409_cs42l42_amic_db_scale, + CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); + +static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .name = "Headphone Playback Volume", + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE + | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs8409_cs42l42_hp_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL( + CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) + | HDA_AMP_VAL_MIN_MUTE +}; + +static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .name = "Mic Capture Volume", + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE + | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs8409_cs42l42_amic_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL( + CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) + | HDA_AMP_VAL_MIN_MUTE +}; + +/* Assert/release RTS# line to CS42L42 */ +static void cs8409_cs42l42_reset(struct hda_codec *codec) +{ + struct cs_spec *spec = codec->spec; + + /* Assert RTS# line */ + snd_hda_codec_write(codec, + codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); + /* wait ~10ms */ + usleep_range(10000, 15000); + /* Release RTS# line */ + snd_hda_codec_write(codec, + codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, GPIO5_INT); + /* wait ~10ms */ + usleep_range(10000, 15000); + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); + +} + +/* Configure CS42L42 slave codec for jack autodetect */ +static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) +{ + struct cs_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Set TIP_SENSE_EN for analog front-end of tip sense. */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); + /* Clear WAKE# */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0001, 1); + /* Wait ~2.5ms */ + usleep_range(2500, 3000); + /* Set mode WAKE# output follows the combination logic directly */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x0020, 1); + /* Clear interrupts status */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); + /* Enable interrupt */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0x03, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b79, 0x00, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); +} + +/* Enable and run CS42L42 slave codec jack auto detect */ +static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) +{ + struct cs_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Clear interrupts */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1); + + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0x01, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1); + /* Wait ~110ms*/ + usleep_range(110000, 200000); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0, 1); + /* Wait ~10ms */ + usleep_range(10000, 25000); + + mutex_unlock(&spec->cs8409_i2c_mux); + +} + +static void cs8409_cs42l42_reg_setup(struct hda_codec *codec) +{ + const struct cs8409_i2c_param *seq = cs42l42_init_reg_seq; + struct cs_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + + for (; seq->addr; seq++) + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); + +} + +/* + * In the case of CS8409 we do not have unsolicited events from NID's 0x24 + * and 0x34 where hs mic and hp are connected. Companion codec CS42L42 will + * generate interrupt via gpio 4 to notify jack events. We have to overwrite + * generic snd_hda_jack_unsol_event(), read CS42L42 jack detect status registers + * and then notify status via generic snd_hda_jack_unsol_event() call. + */ +static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct cs_spec *spec = codec->spec; + int status_changed = 0; + int reg_cdc_status; + int reg_hs_status; + int reg_ts_status; + int type; + struct hda_jack_tbl *jk; + + /* jack_unsol_event() will be called every time gpio line changing state. + * In this case gpio4 line goes up as a result of reading interrupt status + * registers in previous cs8409_jack_unsol_event() call. + * We don't need to handle this event, ignoring... + */ + if ((res & (1 << 4))) + return; + + mutex_lock(&spec->cs8409_i2c_mux); + + /* Read jack detect status registers */ + reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); + reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1); + reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + + /* Clear interrupts, by reading interrupt status registers */ + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b7b, 1); + + mutex_unlock(&spec->cs8409_i2c_mux); + + /* If status values are < 0, read error has occurred. */ + if (reg_cdc_status < 0 || reg_hs_status < 0 || reg_ts_status < 0) + return; + + /* HSDET_AUTO_DONE */ + if (reg_cdc_status & CS42L42_HSDET_AUTO_DONE) { + + type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); + /* CS42L42 reports optical jack as type 4 + * We don't handle optical jack + */ + if (type != 4) { + if (!spec->cs42l42_hp_jack_in) { + status_changed = 1; + spec->cs42l42_hp_jack_in = 1; + } + /* type = 3 has no mic */ + if ((!spec->cs42l42_mic_jack_in) && (type != 3)) { + status_changed = 1; + spec->cs42l42_mic_jack_in = 1; + } + } else { + if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { + status_changed = 1; + spec->cs42l42_hp_jack_in = 0; + spec->cs42l42_mic_jack_in = 0; + } + } + + } else { + /* TIP_SENSE INSERT/REMOVE */ + switch (reg_ts_status) { + case CS42L42_JACK_INSERTED: + cs8409_cs42l42_run_jack_detect(codec); + break; + + case CS42L42_JACK_REMOVED: + if (spec->cs42l42_hp_jack_in || spec->cs42l42_mic_jack_in) { + status_changed = 1; + spec->cs42l42_hp_jack_in = 0; + spec->cs42l42_mic_jack_in = 0; + } + break; + + default: + /* jack in transition */ + status_changed = 0; + break; + } + } + + if (status_changed) { + + snd_hda_set_pin_ctl(codec, CS8409_CS42L42_SPK_PIN_NID, + spec->cs42l42_hp_jack_in ? 0 : PIN_OUT); + + /* Report jack*/ + jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_HP_PIN_NID, 0); + if (jk) { + snd_hda_jack_unsol_event(codec, + (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & AC_UNSOL_RES_TAG); + } + /* Report jack*/ + jk = snd_hda_jack_tbl_get_mst(codec, CS8409_CS42L42_AMIC_PIN_NID, 0); + if (jk) { + snd_hda_jack_unsol_event(codec, + (jk->tag << AC_UNSOL_RES_TAG_SHIFT) & AC_UNSOL_RES_TAG); + } + } +} + +#ifdef CONFIG_PM +/* Manage PDREF, when transition to D3hot */ +static int cs8409_suspend(struct hda_codec *codec) +{ + struct cs_spec *spec = codec->spec; + + mutex_lock(&spec->cs8409_i2c_mux); + /* Power down CS42L42 ASP/EQ/MIX/HP */ + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); + mutex_unlock(&spec->cs8409_i2c_mux); + /* Assert CS42L42 RTS# line */ + snd_hda_codec_write(codec, + codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, 0); + + snd_hda_shutup_pins(codec); + + return 0; +} +#endif + +/* Enable/Disable Unsolicited Response for gpio(s) 3,4 */ +static void cs8409_enable_ur(struct hda_codec *codec, int flag) +{ + /* GPIO4 INT# and GPIO3 WAKE# */ + snd_hda_codec_write(codec, codec->core.afg, + 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, + flag ? (GPIO3_INT | GPIO4_INT) : 0); + + snd_hda_codec_write(codec, codec->core.afg, + 0, AC_VERB_SET_UNSOLICITED_ENABLE, + flag ? AC_UNSOL_ENABLED : 0); + +} + +/* Vendor specific HW configuration + * PLL, ASP, I2C, SPI, GPIOs, DMIC etc... + */ +static void cs8409_cs42l42_hw_init(struct hda_codec *codec) +{ + const struct cs8409_cir_param *seq = cs8409_cs42l42_hw_cfg; + const struct cs8409_cir_param *seq_bullseye = cs8409_cs42l42_bullseye_atn; + struct cs_spec *spec = codec->spec; + + if (spec->gpio_mask) { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, + spec->gpio_mask); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION, + spec->gpio_dir); + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, + spec->gpio_data); + } + + for (; seq->nid; seq++) + cs_vendor_coef_set(codec, seq->cir, seq->coeff); + + if (codec->fixup_id == CS8409_BULLSEYE) + for (; seq_bullseye->nid; seq_bullseye++) + cs_vendor_coef_set(codec, seq_bullseye->cir, seq_bullseye->coeff); + + /* Disable Unsolicited Response during boot */ + cs8409_enable_ur(codec, 0); + + /* Reset CS42L42 */ + cs8409_cs42l42_reset(codec); + + /* Initialise CS42L42 companion codec */ + cs8409_cs42l42_reg_setup(codec); + + if (codec->fixup_id == CS8409_WARLOCK || + codec->fixup_id == CS8409_CYBORG) { + /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01, 1); + mutex_unlock(&spec->cs8409_i2c_mux); + /* DMIC1_MO=00b, DMIC1/2_SR=1 */ + cs_vendor_coef_set(codec, 0x09, 0x0003); + } + + /* Restore Volumes after Resume */ + if (spec->cs42l42_volume_init) { + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHA, + -spec->cs42l42_hp_volume[0], + 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_HS_VOLUME_CHB, + -spec->cs42l42_hp_volume[1], + 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, + CS8409_CS42L42_REG_AMIC_VOLUME, + spec->cs42l42_hs_mic_volume[0], + 1); + mutex_unlock(&spec->cs8409_i2c_mux); + } + + cs8409_cs42l42_update_volume(codec); + + cs8409_cs42l42_enable_jack_detect(codec); + + /* Enable Unsolicited Response */ + cs8409_enable_ur(codec, 1); +} + +static int cs8409_cs42l42_init(struct hda_codec *codec) +{ + int ret = snd_hda_gen_init(codec); + + if (!ret) + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); + + return ret; +} + +static const struct hda_codec_ops cs8409_cs42l42_patch_ops = { + .build_controls = cs_build_controls, + .build_pcms = snd_hda_gen_build_pcms, + .init = cs8409_cs42l42_init, + .free = cs_free, + .unsol_event = cs8409_jack_unsol_event, +#ifdef CONFIG_PM + .suspend = cs8409_suspend, +#endif +}; + +static void cs8409_cs42l42_fixups(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct cs_spec *spec = codec->spec; + int caps; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + snd_hda_add_verbs(codec, cs8409_cs42l42_init_verbs); + /* verb exec op override */ + spec->exec_verb = codec->core.exec_verb; + codec->core.exec_verb = cs8409_cs42l42_exec_verb; + + mutex_init(&spec->cs8409_i2c_mux); + + codec->patch_ops = cs8409_cs42l42_patch_ops; + + spec->gen.suppress_auto_mute = 1; + spec->gen.no_primary_hp = 1; + spec->gen.suppress_vmaster = 1; + + /* GPIO 5 out, 3,4 in */ + spec->gpio_dir = GPIO5_INT; + spec->gpio_data = 0; + spec->gpio_mask = 0x03f; + + spec->cs42l42_hp_jack_in = 0; + spec->cs42l42_mic_jack_in = 0; + + /* Basic initial sequence for specific hw configuration */ + snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs); + + /* CS8409 is simple HDA bridge and intended to be used with a remote + * companion codec. Most of input/output PIN(s) have only basic + * capabilities. NID(s) 0x24 and 0x34 have only OUTC and INC + * capabilities and no presence detect capable (PDC) and call to + * snd_hda_gen_build_controls() will mark them as non detectable + * phantom jacks. However, in this configuration companion codec + * CS42L42 is connected to these pins and it has jack detect + * capabilities. We have to override pin capabilities, + * otherwise they will not be created as input devices. + */ + caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_HP_PIN_NID, + AC_PAR_PIN_CAP); + if (caps >= 0) + snd_hdac_override_parm(&codec->core, + CS8409_CS42L42_HP_PIN_NID, AC_PAR_PIN_CAP, + (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT))); + + caps = snd_hdac_read_parm(&codec->core, CS8409_CS42L42_AMIC_PIN_NID, + AC_PAR_PIN_CAP); + if (caps >= 0) + snd_hdac_override_parm(&codec->core, + CS8409_CS42L42_AMIC_PIN_NID, AC_PAR_PIN_CAP, + (caps | (AC_PINCAP_IMP_SENSE | AC_PINCAP_PRES_DETECT))); + + snd_hda_override_wcaps(codec, CS8409_CS42L42_HP_PIN_NID, + (get_wcaps(codec, CS8409_CS42L42_HP_PIN_NID) | AC_WCAP_UNSOL_CAP)); + + snd_hda_override_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID, + (get_wcaps(codec, CS8409_CS42L42_AMIC_PIN_NID) | AC_WCAP_UNSOL_CAP)); + break; + case HDA_FIXUP_ACT_PROBE: + + /* Set initial volume on Bullseye to -26 dB */ + if (codec->fixup_id == CS8409_BULLSEYE) + snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, + HDA_INPUT, 0, 0xff, 0x19); + snd_hda_gen_add_kctl(&spec->gen, + NULL, &cs8409_cs42l42_hp_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, + NULL, &cs8409_cs42l42_amic_volume_mixer); + cs8409_cs42l42_hw_init(codec); + snd_hda_codec_set_name(codec, "CS8409/CS42L42"); + break; + case HDA_FIXUP_ACT_INIT: + cs8409_cs42l42_hw_init(codec); + fallthrough; + case HDA_FIXUP_ACT_BUILD: + /* Run jack auto detect first time on boot + * after controls have been added, to check if jack has + * been already plugged in. + * Run immediately after init. + */ + cs8409_cs42l42_run_jack_detect(codec); + usleep_range(100000, 150000); + break; + default: + break; + } +} + +static int cs8409_cs42l42_exec_verb(struct hdac_device *dev, + unsigned int cmd, unsigned int flags, unsigned int *res) +{ + struct hda_codec *codec = container_of(dev, struct hda_codec, core); + struct cs_spec *spec = codec->spec; + + unsigned int nid = ((cmd >> 20) & 0x07f); + unsigned int verb = ((cmd >> 8) & 0x0fff); + + /* CS8409 pins have no AC_PINSENSE_PRESENCE + * capabilities. We have to intercept 2 calls for pins 0x24 and 0x34 + * and return correct pin sense values for read_pin_sense() call from + * hda_jack based on CS42L42 jack detect status. + */ + switch (nid) { + case CS8409_CS42L42_HP_PIN_NID: + if (verb == AC_VERB_GET_PIN_SENSE) { + *res = (spec->cs42l42_hp_jack_in) ? AC_PINSENSE_PRESENCE : 0; + return 0; + } + break; + + case CS8409_CS42L42_AMIC_PIN_NID: + if (verb == AC_VERB_GET_PIN_SENSE) { + *res = (spec->cs42l42_mic_jack_in) ? AC_PINSENSE_PRESENCE : 0; + return 0; + } + break; + + default: + break; + } + + return spec->exec_verb(dev, cmd, flags, res); +} + +static int patch_cs8409(struct hda_codec *codec) +{ + int err; + + if (!cs_alloc_spec(codec, CS8409_VENDOR_NID)) + return -ENOMEM; + + snd_hda_pick_fixup(codec, + cs8409_models, cs8409_fixup_tbl, cs8409_fixups); + + codec_dbg(codec, "Picked ID=%d, VID=%08x, DEV=%08x\n", + codec->fixup_id, + codec->bus->pci->subsystem_vendor, + codec->bus->pci->subsystem_device); + + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); + + err = cs_parse_auto_config(codec); + if (err < 0) { + cs_free(codec); + return err; + } + + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); + return 0; +} /* * patch entries @@ -1229,6 +2306,7 @@ static const struct hda_device_id snd_hda_id_cirrus[] = { HDA_CODEC_ENTRY(0x10134208, "CS4208", patch_cs4208), HDA_CODEC_ENTRY(0x10134210, "CS4210", patch_cs4210), HDA_CODEC_ENTRY(0x10134213, "CS4213", patch_cs4213), + HDA_CODEC_ENTRY(0x10138409, "CS8409", patch_cs8409), {} /* terminator */ }; MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cirrus); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index dfef9c17e140..d111258c6f45 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -930,18 +930,18 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), - SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO), - SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO), - SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO), + SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO), SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED), diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 45ae845e82df..4b2cc8cb55c4 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1848,16 +1848,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) */ if (spec->intel_hsw_fixup) { /* - * On Intel platforms, device entries number is - * changed dynamically. If there is a DP MST - * hub connected, the device entries number is 3. - * Otherwise, it is 1. - * Here we manually set dev_num to 3, so that - * we can initialize all the device entries when - * bootup statically. + * On Intel platforms, device entries count returned + * by AC_PAR_DEVLIST_LEN is dynamic, and depends on + * the type of receiver that is connected. Allocate pin + * structures based on worst case. */ - dev_num = 3; - spec->dev_num = 3; + dev_num = spec->dev_num; } else if (spec->dyn_pcm_assign && codec->dp_mst) { dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1; /* @@ -2658,7 +2654,7 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id) /* skip notification during system suspend (but not in runtime PM); * the state will be updated at resume */ - if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0) + if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) return; /* ditto during suspend/resume process itself */ if (snd_hdac_is_in_pm(&codec->core)) @@ -2844,7 +2840,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) /* skip notification during system suspend (but not in runtime PM); * the state will be updated at resume */ - if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0) + if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND) return; /* ditto during suspend/resume process itself */ if (snd_hdac_is_in_pm(&codec->core)) @@ -2942,7 +2938,7 @@ static int parse_intel_hdmi(struct hda_codec *codec) /* Intel Haswell and onwards; audio component with eld notifier */ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid, - const int *port_map, int port_num) + const int *port_map, int port_num, int dev_num) { struct hdmi_spec *spec; int err; @@ -2957,6 +2953,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid, spec->port_map = port_map; spec->port_num = port_num; spec->intel_hsw_fixup = true; + spec->dev_num = dev_num; intel_haswell_enable_all_pins(codec, true); intel_haswell_fixup_enable_dp12(codec); @@ -2982,12 +2979,12 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid, static int patch_i915_hsw_hdmi(struct hda_codec *codec) { - return intel_hsw_common_init(codec, 0x08, NULL, 0); + return intel_hsw_common_init(codec, 0x08, NULL, 0, 3); } static int patch_i915_glk_hdmi(struct hda_codec *codec) { - return intel_hsw_common_init(codec, 0x0b, NULL, 0); + return intel_hsw_common_init(codec, 0x0b, NULL, 0, 3); } static int patch_i915_icl_hdmi(struct hda_codec *codec) @@ -2998,7 +2995,7 @@ static int patch_i915_icl_hdmi(struct hda_codec *codec) */ static const int map[] = {0x0, 0x4, 0x6, 0x8, 0xa, 0xb}; - return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map)); + return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 3); } static int patch_i915_tgl_hdmi(struct hda_codec *codec) @@ -3010,7 +3007,7 @@ static int patch_i915_tgl_hdmi(struct hda_codec *codec) static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; int ret; - ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map)); + ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4); if (!ret) { struct hdmi_spec *spec = codec->spec; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a7544b77d3f7..bd7bfd7c9ee7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -292,7 +292,7 @@ static void alc_fixup_gpio4(struct hda_codec *codec, static void alc_fixup_micmute_led(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - if (action == HDA_FIXUP_ACT_PROBE) + if (action == HDA_FIXUP_ACT_PRE_PROBE) snd_hda_gen_add_micmute_led_cdev(codec, NULL); } @@ -2470,13 +2470,13 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", ALC882_FIXUP_ACER_ASPIRE_8930G), + SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", + ALC882_FIXUP_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", ALC882_FIXUP_ACER_ASPIRE_4930G), - SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", - ALC882_FIXUP_ACER_ASPIRE_4930G), - SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), @@ -2489,11 +2489,11 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3), + SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), + SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP), - SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), - SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), /* All Apple entries are in codec SSIDs */ SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), @@ -2536,9 +2536,19 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), + SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950), - SND_PCI_QUIRK(0x1558, 0x950A, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950), + SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x95e3, "Clevo P955[ER]T", ALC1220_FIXUP_CLEVO_P950), @@ -2548,14 +2558,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950), - SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), - SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), @@ -3103,7 +3105,7 @@ static void alc_headset_btn_callback(struct hda_codec *codec, if (jack->unsol_res & (7 << 10)) report |= SND_JACK_BTN_3; - jack->jack->button_state = report; + snd_hda_jack_set_button_state(codec, jack->nid, report); } static void alc_disable_headset_jack_key(struct hda_codec *codec) @@ -3164,16 +3166,23 @@ static void alc_fixup_headset_jack(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; + hda_nid_t hp_pin; switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: spec->has_hs_key = 1; snd_hda_jack_detect_enable_callback(codec, 0x55, alc_headset_btn_callback); - snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false, - SND_JACK_HEADSET, alc_headset_btn_keymap); break; - case HDA_FIXUP_ACT_INIT: + case HDA_FIXUP_ACT_BUILD: + hp_pin = alc_get_hp_pin(spec); + if (!hp_pin || snd_hda_jack_bind_keymap(codec, 0x55, + alc_headset_btn_keymap, + hp_pin)) + snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", + false, SND_JACK_HEADSET, + alc_headset_btn_keymap); + alc_enable_headset_jack_key(codec); break; } @@ -4438,6 +4447,25 @@ static void alc236_fixup_hp_mute_led(struct hda_codec *codec, alc236_fixup_hp_coef_micmute_led(codec, fix, action); } +static void alc236_fixup_hp_micmute_led_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->cap_mute_led_nid = 0x1a; + snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set); + codec->power_filter = led_power_filter; + } +} + +static void alc236_fixup_hp_mute_led_micmute_vref(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc236_fixup_hp_mute_led_coefbit(codec, fix, action); + alc236_fixup_hp_micmute_led_vref(codec, fix, action); +} + #if IS_REACHABLE(CONFIG_INPUT) static void gpio2_mic_hotkey_event(struct hda_codec *codec, struct hda_jack_callback *event) @@ -6232,6 +6260,9 @@ static void alc_fixup_thinkpad_acpi(struct hda_codec *codec, /* for alc295_fixup_hp_top_speakers */ #include "hp_x360_helper.c" +/* for alc285_fixup_ideapad_s740_coef() */ +#include "ideapad_s740_helper.c" + enum { ALC269_FIXUP_GPIO2, ALC269_FIXUP_SONY_VAIO, @@ -6400,6 +6431,7 @@ enum { ALC285_FIXUP_HP_MUTE_LED, ALC236_FIXUP_HP_GPIO_LED, ALC236_FIXUP_HP_MUTE_LED, + ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF, ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, ALC295_FIXUP_ASUS_MIC_NO_PRESENCE, ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS, @@ -6415,6 +6447,8 @@ enum { ALC269_FIXUP_LEMOTE_A1802, ALC269_FIXUP_LEMOTE_A190X, ALC256_FIXUP_INTEL_NUC8_RUGGED, + ALC233_FIXUP_INTEL_NUC8_DMIC, + ALC233_FIXUP_INTEL_NUC8_BOOST, ALC256_FIXUP_INTEL_NUC10, ALC255_FIXUP_XIAOMI_HEADSET_MIC, ALC274_FIXUP_HP_MIC, @@ -6427,6 +6461,8 @@ enum { ALC282_FIXUP_ACER_DISABLE_LINEOUT, ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST, ALC256_FIXUP_ACER_HEADSET_MIC, + ALC285_FIXUP_IDEAPAD_S740_COEF, + ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST, }; static const struct hda_fixup alc269_fixups[] = { @@ -7136,6 +7172,16 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc233_fixup_lenovo_line2_mic_hotkey, }, + [ALC233_FIXUP_INTEL_NUC8_DMIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic, + .chained = true, + .chain_id = ALC233_FIXUP_INTEL_NUC8_BOOST, + }, + [ALC233_FIXUP_INTEL_NUC8_BOOST] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost + }, [ALC255_FIXUP_DELL_SPK_NOISE] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_disable_aamix, @@ -7646,6 +7692,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_mute_led, }, + [ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc236_fixup_hp_mute_led_micmute_vref, + }, [ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -7901,6 +7951,18 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC }, + [ALC285_FIXUP_IDEAPAD_S740_COEF] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_ideapad_s740_coef, + .chained = true, + .chain_id = ALC269_FIXUP_THINKPAD_ACPI, + }, + [ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_limit_int_mic_boost, + .chained = true, + .chain_id = ALC285_FIXUP_HP_MUTE_LED, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -7909,12 +7971,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC), - SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), + SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF), SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE), @@ -7970,8 +8032,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP), SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME), SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), - SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3), SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), + SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3), SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), @@ -7981,8 +8043,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), - SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK), + SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC), @@ -7993,35 +8055,18 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), - SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY), - /* ALC282 */ SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), + SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED), - SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), - SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS), - SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS), - SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M), - SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), - SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), - /* ALC290 */ - SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), - SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), - SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), @@ -8029,28 +8074,45 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY), SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS), SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS), SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), + SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M), + SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), + SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED), SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), - SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC), SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x8077, "HP", ALC256_FIXUP_HP_HEADSET_MIC), + SND_PCI_QUIRK(0x103c, 0x8158, "HP", ALC256_FIXUP_HP_HEADSET_MIC), SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), @@ -8063,6 +8125,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED), @@ -8079,6 +8142,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), @@ -8087,16 +8151,18 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), + SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE), @@ -8109,31 +8175,31 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), + SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), - SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS), SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), - SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX), + SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT), SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), - SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC), + SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), + SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE), SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK), @@ -8143,9 +8209,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), - SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), + SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), @@ -8201,9 +8267,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST), SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), - SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), @@ -8244,9 +8310,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME), + SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF), 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), + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK), @@ -8265,20 +8333,19 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), - SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI), SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101), SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ + SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), + SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), - SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE), - SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), - SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), + SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), @@ -8733,12 +8800,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60130}, {0x19, 0x03a11020}, {0x21, 0x0321101f}), - SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, - {0x14, 0x90170110}, - {0x19, 0x04a11040}, - {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, - {0x12, 0x90a60130}, {0x14, 0x90170110}, {0x19, 0x04a11040}, {0x21, 0x04211020}), @@ -8909,6 +8971,10 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = { SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, {0x19, 0x40000000}, {0x1a, 0x40000000}), + SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, + {0x14, 0x90170110}, + {0x19, 0x04a11040}, + {0x21, 0x04211020}), {} }; @@ -9224,8 +9290,7 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), - SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), - SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), + SND_PCI_QUIRK_VENDOR(0x1584, "Haier/Uniwill", ALC861_FIXUP_AMP_VREF_0F), SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), {} }; @@ -10020,6 +10085,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), + SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS), SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE), SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE), SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), @@ -10036,9 +10102,9 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2), SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50), - SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50), SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751), + SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51), @@ -10058,7 +10124,6 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON), SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26), SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), - SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS), #if 0 /* Below is a quirk table taken from the old code. diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c662431bf13a..3bd592e126a3 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4277,6 +4277,9 @@ static int stac_parse_auto_config(struct hda_codec *codec) spec->gen.automute_hook = stac_update_outputs; + if (spec->gpio_led) + snd_hda_gen_add_mute_led_cdev(codec, stac_vmaster_hook); + err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); if (err < 0) return err; @@ -4318,9 +4321,6 @@ static int stac_parse_auto_config(struct hda_codec *codec) } #endif - if (spec->gpio_led) - snd_hda_gen_add_mute_led_cdev(codec, stac_vmaster_hook); - if (spec->aloopback_ctl && snd_hda_get_bool_hint(codec, "loopback") == 1) { unsigned int wr_verb = diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 6698ae241efc..de4d8deed102 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -18,7 +18,7 @@ static bool is_thinkpad(struct hda_codec *codec) static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - if (action == HDA_FIXUP_ACT_PROBE) { + if (action == HDA_FIXUP_ACT_PRE_PROBE) { if (!is_thinkpad(codec)) return; snd_hda_gen_add_mute_led_cdev(codec, NULL); diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 13dcb2fd0a85..f579f7698bba 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -22,7 +22,8 @@ /** - * wait for a value on a peudo register, exit with a timeout + * mixart_wait_nice_for_register_value - wait for a value on a peudo register, + * exit with a timeout * * @mgr: pointer to miXart manager structure * @offset: unsigned pseudo_register base + offset of value diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 4cf879c42dc4..720297cbdf87 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -5390,7 +5390,8 @@ static int snd_hdsp_free(struct hdsp *hdsp) if (hdsp->port) pci_release_regions(hdsp->pci); - pci_disable_device(hdsp->pci); + if (pci_is_enabled(hdsp->pci)) + pci_disable_device(hdsp->pci); return 0; } diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 8d900c132f0f..97a0bff96b28 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -6883,7 +6883,8 @@ static int snd_hdspm_free(struct hdspm * hdspm) if (hdspm->port) pci_release_regions(hdspm->pci); - pci_disable_device(hdspm->pci); + if (pci_is_enabled(hdspm->pci)) + pci_disable_device(hdspm->pci); return 0; } diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 4df992e846f2..7a4d395abcee 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -1731,7 +1731,8 @@ static int snd_rme9652_free(struct snd_rme9652 *rme9652) if (rme9652->port) pci_release_regions(rme9652->pci); - pci_disable_device(rme9652->pci); + if (pci_is_enabled(rme9652->pci)) + pci_disable_device(rme9652->pci); return 0; } diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index 23d4338dc553..a05537202738 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c @@ -78,7 +78,7 @@ static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg) } /** - * snd_vx_inb - read a byte from the register + * vx2_inb - read a byte from the register * @chip: VX core instance * @offset: register enum */ @@ -88,7 +88,7 @@ static unsigned char vx2_inb(struct vx_core *chip, int offset) } /** - * snd_vx_outb - write a byte on the register + * vx2_outb - write a byte on the register * @chip: VX core instance * @offset: the register offset * @val: the value to write @@ -102,7 +102,7 @@ static void vx2_outb(struct vx_core *chip, int offset, unsigned char val) } /** - * snd_vx_inl - read a 32bit word from the register + * vx2_inl - read a 32bit word from the register * @chip: VX core instance * @offset: register enum */ @@ -112,7 +112,7 @@ static unsigned int vx2_inl(struct vx_core *chip, int offset) } /** - * snd_vx_outl - write a 32bit word on the register + * vx2_outl - write a 32bit word on the register * @chip: VX core instance * @offset: the register enum * @val: the value to write @@ -213,7 +213,7 @@ static int vx2_test_xilinx(struct vx_core *_chip) /** - * vx_setup_pseudo_dma - set up the pseudo dma read/write mode. + * vx2_setup_pseudo_dma - set up the pseudo dma read/write mode. * @chip: VX core instance * @do_write: 0 = read, 1 = set up for DMA write */ |