diff options
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1af917f58a70..3c29a558e7db 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -96,6 +96,8 @@ struct alc_spec { | |||
96 | hda_nid_t cap_mute_led_nid; | 96 | hda_nid_t cap_mute_led_nid; |
97 | 97 | ||
98 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | 98 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ |
99 | unsigned int gpio_mute_led_mask; | ||
100 | unsigned int gpio_mic_led_mask; | ||
99 | 101 | ||
100 | hda_nid_t headset_mic_pin; | 102 | hda_nid_t headset_mic_pin; |
101 | hda_nid_t headphone_mic_pin; | 103 | hda_nid_t headphone_mic_pin; |
@@ -3235,41 +3237,45 @@ static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | |||
3235 | } | 3237 | } |
3236 | } | 3238 | } |
3237 | 3239 | ||
3238 | /* turn on/off mute LED per vmaster hook */ | 3240 | /* update LED status via GPIO */ |
3239 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | 3241 | static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, |
3242 | bool enabled) | ||
3240 | { | 3243 | { |
3241 | struct hda_codec *codec = private_data; | ||
3242 | struct alc_spec *spec = codec->spec; | 3244 | struct alc_spec *spec = codec->spec; |
3243 | unsigned int oldval = spec->gpio_led; | 3245 | unsigned int oldval = spec->gpio_led; |
3244 | 3246 | ||
3247 | if (spec->mute_led_polarity) | ||
3248 | enabled = !enabled; | ||
3249 | |||
3245 | if (enabled) | 3250 | if (enabled) |
3246 | spec->gpio_led &= ~0x08; | 3251 | spec->gpio_led &= ~mask; |
3247 | else | 3252 | else |
3248 | spec->gpio_led |= 0x08; | 3253 | spec->gpio_led |= mask; |
3249 | if (spec->gpio_led != oldval) | 3254 | if (spec->gpio_led != oldval) |
3250 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3255 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3251 | spec->gpio_led); | 3256 | spec->gpio_led); |
3252 | } | 3257 | } |
3253 | 3258 | ||
3254 | /* turn on/off mic-mute LED per capture hook */ | 3259 | /* turn on/off mute LED via GPIO per vmaster hook */ |
3255 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | 3260 | static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) |
3256 | struct snd_kcontrol *kcontrol, | ||
3257 | struct snd_ctl_elem_value *ucontrol) | ||
3258 | { | 3261 | { |
3262 | struct hda_codec *codec = private_data; | ||
3259 | struct alc_spec *spec = codec->spec; | 3263 | struct alc_spec *spec = codec->spec; |
3260 | unsigned int oldval = spec->gpio_led; | ||
3261 | 3264 | ||
3262 | if (!ucontrol) | 3265 | alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); |
3263 | return; | 3266 | } |
3264 | 3267 | ||
3265 | if (ucontrol->value.integer.value[0] || | 3268 | /* turn on/off mic-mute LED via GPIO per capture hook */ |
3266 | ucontrol->value.integer.value[1]) | 3269 | static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec, |
3267 | spec->gpio_led &= ~0x10; | 3270 | struct snd_kcontrol *kcontrol, |
3268 | else | 3271 | struct snd_ctl_elem_value *ucontrol) |
3269 | spec->gpio_led |= 0x10; | 3272 | { |
3270 | if (spec->gpio_led != oldval) | 3273 | struct alc_spec *spec = codec->spec; |
3271 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3274 | |
3272 | spec->gpio_led); | 3275 | if (ucontrol) |
3276 | alc_update_gpio_led(codec, spec->gpio_mic_led_mask, | ||
3277 | ucontrol->value.integer.value[0] || | ||
3278 | ucontrol->value.integer.value[1]); | ||
3273 | } | 3279 | } |
3274 | 3280 | ||
3275 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | 3281 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, |
@@ -3283,9 +3289,12 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | |||
3283 | }; | 3289 | }; |
3284 | 3290 | ||
3285 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3291 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3286 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3292 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
3287 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | 3293 | spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; |
3288 | spec->gpio_led = 0; | 3294 | spec->gpio_led = 0; |
3295 | spec->mute_led_polarity = 0; | ||
3296 | spec->gpio_mute_led_mask = 0x08; | ||
3297 | spec->gpio_mic_led_mask = 0x10; | ||
3289 | snd_hda_add_verbs(codec, gpio_init); | 3298 | snd_hda_add_verbs(codec, gpio_init); |
3290 | } | 3299 | } |
3291 | } | 3300 | } |
@@ -3327,9 +3336,11 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, | |||
3327 | }; | 3336 | }; |
3328 | 3337 | ||
3329 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3338 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3330 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3339 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
3331 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; | 3340 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; |
3332 | spec->gpio_led = 0; | 3341 | spec->gpio_led = 0; |
3342 | spec->mute_led_polarity = 0; | ||
3343 | spec->gpio_mute_led_mask = 0x08; | ||
3333 | spec->cap_mute_led_nid = 0x18; | 3344 | spec->cap_mute_led_nid = 0x18; |
3334 | snd_hda_add_verbs(codec, gpio_init); | 3345 | snd_hda_add_verbs(codec, gpio_init); |
3335 | codec->power_filter = led_power_filter; | 3346 | codec->power_filter = led_power_filter; |
@@ -3348,9 +3359,11 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, | |||
3348 | }; | 3359 | }; |
3349 | 3360 | ||
3350 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3361 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3351 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3362 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
3352 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; | 3363 | spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; |
3353 | spec->gpio_led = 0; | 3364 | spec->gpio_led = 0; |
3365 | spec->mute_led_polarity = 0; | ||
3366 | spec->gpio_mute_led_mask = 0x08; | ||
3354 | spec->cap_mute_led_nid = 0x18; | 3367 | spec->cap_mute_led_nid = 0x18; |
3355 | snd_hda_add_verbs(codec, gpio_init); | 3368 | snd_hda_add_verbs(codec, gpio_init); |
3356 | codec->power_filter = led_power_filter; | 3369 | codec->power_filter = led_power_filter; |
@@ -5624,22 +5637,6 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec, | |||
5624 | } | 5637 | } |
5625 | } | 5638 | } |
5626 | 5639 | ||
5627 | /* turn on/off mute LED per vmaster hook */ | ||
5628 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) | ||
5629 | { | ||
5630 | struct hda_codec *codec = private_data; | ||
5631 | struct alc_spec *spec = codec->spec; | ||
5632 | unsigned int oldval = spec->gpio_led; | ||
5633 | |||
5634 | if (enabled) | ||
5635 | spec->gpio_led |= 0x01; | ||
5636 | else | ||
5637 | spec->gpio_led &= ~0x01; | ||
5638 | if (spec->gpio_led != oldval) | ||
5639 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
5640 | spec->gpio_led); | ||
5641 | } | ||
5642 | |||
5643 | /* avoid D3 for keeping GPIO up */ | 5640 | /* avoid D3 for keeping GPIO up */ |
5644 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, | 5641 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, |
5645 | hda_nid_t nid, | 5642 | hda_nid_t nid, |
@@ -5662,8 +5659,10 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec, | |||
5662 | }; | 5659 | }; |
5663 | 5660 | ||
5664 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5661 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5665 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; | 5662 | spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; |
5666 | spec->gpio_led = 0; | 5663 | spec->gpio_led = 0; |
5664 | spec->mute_led_polarity = 1; | ||
5665 | spec->gpio_mute_led_mask = 0x01; | ||
5667 | snd_hda_add_verbs(codec, gpio_init); | 5666 | snd_hda_add_verbs(codec, gpio_init); |
5668 | codec->power_filter = gpio_led_power_filter; | 5667 | codec->power_filter = gpio_led_power_filter; |
5669 | } | 5668 | } |