diff options
author | Takashi Iwai <tiwai@suse.de> | 2020-08-03 09:10:08 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2020-08-03 09:10:08 +0300 |
commit | 3b5d1afd1f13bcab85eaa28223ad396694f929e3 (patch) | |
tree | 02983e414b3d918114c15b8410ab46c245a07a29 /sound/pci/hda/patch_realtek.c | |
parent | f1ec5be17b9aafbc5f573da023850566b43d8e5e (diff) | |
parent | 2ac82e20e2377fb0b63ce40bba56558f2df7cd3e (diff) | |
download | linux-3b5d1afd1f13bcab85eaa28223ad396694f929e3.tar.xz |
Merge branch 'for-next' into for-linus
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 230 |
1 files changed, 109 insertions, 121 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 417c8e17d839..2477f3ed7237 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -67,6 +67,13 @@ struct alc_customize_define { unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ }; +struct alc_coef_led { + unsigned int idx; + unsigned int mask; + unsigned int on; + unsigned int off; +}; + struct alc_spec { struct hda_gen_spec gen; /* must be at head */ @@ -80,7 +87,7 @@ struct alc_spec { unsigned int gpio_data; bool gpio_write_delay; /* add a delay before writing gpio_data */ - /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ + /* mute LED for HP laptops, see vref_mute_led_set() */ int mute_led_polarity; int micmute_led_polarity; hda_nid_t mute_led_nid; @@ -88,14 +95,8 @@ struct alc_spec { unsigned int gpio_mute_led_mask; unsigned int gpio_mic_led_mask; - unsigned int mute_led_coef_idx; - unsigned int mute_led_coefbit_mask; - unsigned int mute_led_coefbit_on; - unsigned int mute_led_coefbit_off; - unsigned int mic_led_coef_idx; - unsigned int mic_led_coefbit_mask; - unsigned int mic_led_coefbit_on; - unsigned int mic_led_coefbit_off; + struct alc_coef_led mute_led_coef; + struct alc_coef_led mic_led_coef; hda_nid_t headset_mic_pin; hda_nid_t headphone_mic_pin; @@ -287,6 +288,13 @@ static void alc_fixup_gpio4(struct hda_codec *codec, alc_fixup_gpio(codec, action, 0x04); } +static void alc_fixup_micmute_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PROBE) + snd_hda_gen_add_micmute_led_cdev(codec, NULL); +} + /* * Fix hardware PLL issue * On some codecs, the analog PLL gating control must be off while @@ -374,7 +382,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) case 0x10ec0295: case 0x10ec0299: alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); - /* fallthrough */ + fallthrough; case 0x10ec0215: case 0x10ec0233: case 0x10ec0235: @@ -1070,7 +1078,7 @@ static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid, return 0; } -static const struct snd_pci_quirk beep_white_list[] = { +static const struct snd_pci_quirk beep_allow_list[] = { SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), @@ -1080,7 +1088,7 @@ static const struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), - /* blacklist -- no beep available */ + /* denylist -- no beep available */ SND_PCI_QUIRK(0x17aa, 0x309e, "Lenovo ThinkCentre M73", 0), SND_PCI_QUIRK(0x17aa, 0x30a3, "Lenovo ThinkCentre M93", 0), {} @@ -1090,7 +1098,7 @@ static inline int has_cdefine_beep(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; const struct snd_pci_quirk *q; - q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); + q = snd_pci_quirk_lookup(codec->bus->pci, beep_allow_list); if (q) return q->value; return spec->cdefine.enable_pcbeep; @@ -3982,25 +3990,34 @@ static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, } } +static void alc_update_vref_led(struct hda_codec *codec, hda_nid_t pin, + bool polarity, bool on) +{ + unsigned int pinval; + + if (!pin) + return; + if (polarity) + on = !on; + pinval = snd_hda_codec_get_pin_target(codec, pin); + pinval &= ~AC_PINCTL_VREFEN; + pinval |= on ? AC_PINCTL_VREF_80 : AC_PINCTL_VREF_HIZ; + /* temporarily power up/down for setting VREF */ + snd_hda_power_up_pm(codec); + snd_hda_set_pin_ctl_cache(codec, pin, pinval); + snd_hda_power_down_pm(codec); +} /* update mute-LED according to the speaker mute state via mic VREF pin */ -static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) +static int vref_mute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { - struct hda_codec *codec = private_data; + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); struct alc_spec *spec = codec->spec; - unsigned int pinval; - if (spec->mute_led_polarity) - enabled = !enabled; - pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); - pinval &= ~AC_PINCTL_VREFEN; - pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; - if (spec->mute_led_nid) { - /* temporarily power up/down for setting VREF */ - snd_hda_power_up_pm(codec); - snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); - snd_hda_power_down_pm(codec); - } + alc_update_vref_led(codec, spec->mute_led_nid, + spec->mute_led_polarity, brightness); + return 0; } /* Make sure the led works even in runtime suspend */ @@ -4038,8 +4055,7 @@ static void alc269_fixup_hp_mute_led(struct hda_codec *codec, break; spec->mute_led_polarity = pol; spec->mute_led_nid = pin - 0x0a + 0x18; - spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; - spec->gen.vmaster_mute_enum = 1; + snd_hda_gen_add_mute_led_cdev(codec, vref_mute_led_set); codec->power_filter = led_power_filter; codec_dbg(codec, "Detected mute LED for %x:%d\n", spec->mute_led_nid, @@ -4057,8 +4073,7 @@ static void alc269_fixup_hp_mute_led_micx(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->mute_led_polarity = 0; spec->mute_led_nid = pin; - spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; - spec->gen.vmaster_mute_enum = 1; + snd_hda_gen_add_mute_led_cdev(codec, vref_mute_led_set); codec->power_filter = led_power_filter; } } @@ -4091,26 +4106,18 @@ static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, } /* turn on/off mute LED via GPIO per vmaster hook */ -static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) +static int gpio_mute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { - struct hda_codec *codec = private_data; + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); struct alc_spec *spec = codec->spec; alc_update_gpio_led(codec, spec->gpio_mute_led_mask, - spec->mute_led_polarity, enabled); + spec->mute_led_polarity, !brightness); + return 0; } /* turn on/off mic-mute LED via GPIO per capture hook */ -static void alc_gpio_micmute_update(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - alc_update_gpio_led(codec, spec->gpio_mic_led_mask, - spec->micmute_led_polarity, - spec->gen.micmute_led.led_value); -} - -#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO) static int micmute_led_set(struct led_classdev *led_cdev, enum led_brightness brightness) { @@ -4122,14 +4129,6 @@ static int micmute_led_set(struct led_classdev *led_cdev, return 0; } -static struct led_classdev micmute_led_cdev = { - .name = "hda::micmute", - .max_brightness = 1, - .brightness_set_blocking = micmute_led_set, - .default_trigger = "audio-micmute", -}; -#endif - /* setup mute and mic-mute GPIO bits, add hooks appropriately */ static void alc_fixup_hp_gpio_led(struct hda_codec *codec, int action, @@ -4137,9 +4136,6 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec, unsigned int micmute_mask) { struct alc_spec *spec = codec->spec; -#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO) - int err; -#endif alc_fixup_gpio(codec, action, mute_mask | micmute_mask); @@ -4147,18 +4143,11 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec, return; if (mute_mask) { spec->gpio_mute_led_mask = mute_mask; - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; + snd_hda_gen_add_mute_led_cdev(codec, gpio_mute_led_set); } if (micmute_mask) { spec->gpio_mic_led_mask = micmute_mask; - snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update); - -#if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO) - micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); - err = devm_led_classdev_register(&codec->core.dev, &micmute_led_cdev); - if (err) - codec_warn(codec, "failed to register micmute LED\n"); -#endif + snd_hda_gen_add_micmute_led_cdev(codec, micmute_led_set); } } @@ -4184,21 +4173,16 @@ static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20); } -/* turn on/off mic-mute LED per capture hook */ -static void alc_cap_micmute_update(struct hda_codec *codec) +/* turn on/off mic-mute LED per capture hook via VREF change */ +static int vref_micmute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); struct alc_spec *spec = codec->spec; - unsigned int pinval; - if (!spec->cap_mute_led_nid) - return; - pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid); - pinval &= ~AC_PINCTL_VREFEN; - if (spec->gen.micmute_led.led_value) - pinval |= AC_PINCTL_VREF_80; - else - pinval |= AC_PINCTL_VREF_HIZ; - snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval); + alc_update_vref_led(codec, spec->cap_mute_led_nid, + spec->micmute_led_polarity, brightness); + return 0; } static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, @@ -4214,7 +4198,7 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, spec->gpio_mask |= 0x10; spec->gpio_dir |= 0x10; spec->cap_mute_led_nid = 0x18; - snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); + snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set); codec->power_filter = led_power_filter; } } @@ -4227,25 +4211,32 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, alc_fixup_hp_gpio_led(codec, action, 0x08, 0); if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->cap_mute_led_nid = 0x18; - snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); + snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set); codec->power_filter = led_power_filter; } } +static void alc_update_coef_led(struct hda_codec *codec, + struct alc_coef_led *led, + bool polarity, bool on) +{ + if (polarity) + on = !on; + /* temporarily power up/down for setting COEF bit */ + alc_update_coef_idx(codec, led->idx, led->mask, + on ? led->on : led->off); +} + /* update mute-LED according to the speaker mute state via COEF bit */ -static void alc_fixup_mute_led_coefbit_hook(void *private_data, int enabled) +static int coef_mute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { - struct hda_codec *codec = private_data; + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); struct alc_spec *spec = codec->spec; - if (spec->mute_led_polarity) - enabled = !enabled; - - /* temporarily power up/down for setting COEF bit */ - enabled ? alc_update_coef_idx(codec, spec->mute_led_coef_idx, - spec->mute_led_coefbit_mask, spec->mute_led_coefbit_off) : - alc_update_coef_idx(codec, spec->mute_led_coef_idx, - spec->mute_led_coefbit_mask, spec->mute_led_coefbit_on); + alc_update_coef_led(codec, &spec->mute_led_coef, + spec->mute_led_polarity, brightness); + return 0; } static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec, @@ -4256,12 +4247,11 @@ static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->mute_led_polarity = 0; - spec->mute_led_coef_idx = 0x0b; - spec->mute_led_coefbit_mask = 1<<3; - spec->mute_led_coefbit_on = 1<<3; - spec->mute_led_coefbit_off = 0; - spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook; - spec->gen.vmaster_mute_enum = 1; + spec->mute_led_coef.idx = 0x0b; + spec->mute_led_coef.mask = 1 << 3; + spec->mute_led_coef.on = 1 << 3; + spec->mute_led_coef.off = 0; + snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set); } } @@ -4273,26 +4263,24 @@ static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->mute_led_polarity = 0; - spec->mute_led_coef_idx = 0x34; - spec->mute_led_coefbit_mask = 1<<5; - spec->mute_led_coefbit_on = 0; - spec->mute_led_coefbit_off = 1<<5; - spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook; - spec->gen.vmaster_mute_enum = 1; + spec->mute_led_coef.idx = 0x34; + spec->mute_led_coef.mask = 1 << 5; + spec->mute_led_coef.on = 0; + spec->mute_led_coef.off = 1 << 5; + snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set); } } /* turn on/off mic-mute LED per capture hook by coef bit */ -static void alc_hp_cap_micmute_update(struct hda_codec *codec) +static int coef_micmute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { + struct hda_codec *codec = dev_to_hda_codec(led_cdev->dev->parent); struct alc_spec *spec = codec->spec; - if (spec->gen.micmute_led.led_value) - alc_update_coef_idx(codec, spec->mic_led_coef_idx, - spec->mic_led_coefbit_mask, spec->mic_led_coefbit_on); - else - alc_update_coef_idx(codec, spec->mic_led_coef_idx, - spec->mic_led_coefbit_mask, spec->mic_led_coefbit_off); + alc_update_coef_led(codec, &spec->mic_led_coef, + spec->micmute_led_polarity, brightness); + return 0; } static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec, @@ -4301,11 +4289,11 @@ static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec, struct alc_spec *spec = codec->spec; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->mic_led_coef_idx = 0x19; - spec->mic_led_coefbit_mask = 1<<13; - spec->mic_led_coefbit_on = 1<<13; - spec->mic_led_coefbit_off = 0; - snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update); + spec->mic_led_coef.idx = 0x19; + spec->mic_led_coef.mask = 1 << 13; + spec->mic_led_coef.on = 1 << 13; + spec->mic_led_coef.off = 0; + snd_hda_gen_add_micmute_led_cdev(codec, coef_micmute_led_set); } } @@ -4315,11 +4303,11 @@ static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec, struct alc_spec *spec = codec->spec; if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->mic_led_coef_idx = 0x35; - spec->mic_led_coefbit_mask = 3<<2; - spec->mic_led_coefbit_on = 2<<2; - spec->mic_led_coefbit_off = 1<<2; - snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update); + spec->mic_led_coef.idx = 0x35; + spec->mic_led_coef.mask = 3 << 2; + spec->mic_led_coef.on = 2 << 2; + spec->mic_led_coef.off = 1 << 2; + snd_hda_gen_add_micmute_led_cdev(codec, coef_micmute_led_set); } } @@ -4459,7 +4447,7 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a); if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->cap_mute_led_nid = 0x18; - snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); + snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set); } } @@ -4710,7 +4698,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, break; case 0x10ec0867: alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14); - /* fallthru */ + fallthrough; case 0x10ec0221: case 0x10ec0662: snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); @@ -6711,7 +6699,7 @@ static const struct hda_fixup alc269_fixups[] = { }, [ALC255_FIXUP_MIC_MUTE_LED] = { .type = HDA_FIXUP_FUNC, - .v.func = snd_hda_gen_fixup_micmute_led, + .v.func = alc_fixup_micmute_led, }, [ALC282_FIXUP_ASPIRE_V5_PINS] = { .type = HDA_FIXUP_PINS, @@ -6814,7 +6802,7 @@ static const struct hda_fixup alc269_fixups[] = { }, [ALC292_FIXUP_DELL_E7X] = { .type = HDA_FIXUP_FUNC, - .v.func = snd_hda_gen_fixup_micmute_led, + .v.func = alc_fixup_micmute_led, /* micmute fixup must be applied at last */ .chained_before = true, .chain_id = ALC292_FIXUP_DELL_E7X_AAMIX, |