diff options
author | Matthew Garrett <mjg59@srcf.ucam.org> | 2005-12-06 07:59:12 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:30:29 -0500 |
commit | a0faefedf7d81b6ead6a33e5576a6439606d7ed5 (patch) | |
tree | eb940eeb51219da24673036423a3e80fe6a08a06 /sound/pci/ac97/ac97_codec.c | |
parent | e12229b4d2b7863b1baaeca759aa87703bf9fdf8 (diff) |
[ALSA] Add a new quirk for mute-LED and HP-only.
Modules: AC97 Codec,ATIIXP driver,Intel8x0 driver
This patch adds a new quirk for ac97 hardware that combines the existing
AC97_TUNE_MUTE_LED and AC97_TUNE_HP_ONLY quirks. This is needed for several
current HP laptops. Additionally, it adds the HP nx6125 to the
AC97_TUNE_MUTE_LED list.
Fixed for the latest version of ALSA by Takashi Iwai <tiwai@suse.de>.
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 33d7a1fc2f9f..3020ca2b602b 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -2457,6 +2457,41 @@ static int tune_mute_led(struct snd_ac97 *ac97) | |||
2457 | return 0; | 2457 | return 0; |
2458 | } | 2458 | } |
2459 | 2459 | ||
2460 | static int hp_master_mute_sw_put(struct snd_kcontrol *kcontrol, | ||
2461 | struct snd_ctl_elem_value *ucontrol) | ||
2462 | { | ||
2463 | int err = bind_hp_volsw_put(kcontrol, ucontrol); | ||
2464 | if (err > 0) { | ||
2465 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | ||
2466 | int shift = (kcontrol->private_value >> 8) & 0x0f; | ||
2467 | int rshift = (kcontrol->private_value >> 12) & 0x0f; | ||
2468 | unsigned short mask; | ||
2469 | if (shift != rshift) | ||
2470 | mask = 0x8080; | ||
2471 | else | ||
2472 | mask = 0x8000; | ||
2473 | snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, | ||
2474 | (ac97->regs[AC97_MASTER] & mask) == mask ? | ||
2475 | 0x8000 : 0); | ||
2476 | } | ||
2477 | return err; | ||
2478 | } | ||
2479 | |||
2480 | static int tune_hp_mute_led(struct snd_ac97 *ac97) | ||
2481 | { | ||
2482 | struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL); | ||
2483 | struct snd_kcontrol *mvol = ctl_find(ac97, "Master Playback Volume", NULL); | ||
2484 | if (! msw || ! mvol) | ||
2485 | return -ENOENT; | ||
2486 | msw->put = hp_master_mute_sw_put; | ||
2487 | mvol->put = bind_hp_volsw_put; | ||
2488 | snd_ac97_remove_ctl(ac97, "External Amplifier", NULL); | ||
2489 | snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch"); | ||
2490 | snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume"); | ||
2491 | snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */ | ||
2492 | return 0; | ||
2493 | } | ||
2494 | |||
2460 | struct quirk_table { | 2495 | struct quirk_table { |
2461 | const char *name; | 2496 | const char *name; |
2462 | int (*func)(struct snd_ac97 *); | 2497 | int (*func)(struct snd_ac97 *); |
@@ -2471,6 +2506,7 @@ static struct quirk_table applicable_quirks[] = { | |||
2471 | { "alc_jack", tune_alc_jack }, | 2506 | { "alc_jack", tune_alc_jack }, |
2472 | { "inv_eapd", tune_inv_eapd }, | 2507 | { "inv_eapd", tune_inv_eapd }, |
2473 | { "mute_led", tune_mute_led }, | 2508 | { "mute_led", tune_mute_led }, |
2509 | { "hp_mute_led", tune_hp_mute_led }, | ||
2474 | }; | 2510 | }; |
2475 | 2511 | ||
2476 | /* apply the quirk with the given type */ | 2512 | /* apply the quirk with the given type */ |