aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@srcf.ucam.org>2005-12-06 07:59:12 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:30:29 -0500
commita0faefedf7d81b6ead6a33e5576a6439606d7ed5 (patch)
treeeb940eeb51219da24673036423a3e80fe6a08a06
parente12229b4d2b7863b1baaeca759aa87703bf9fdf8 (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>
-rw-r--r--include/sound/ac97_codec.h1
-rw-r--r--sound/pci/ac97/ac97_codec.c36
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/intel8x0.c24
4 files changed, 67 insertions, 0 deletions
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index a1814cd95491..b0b3ea7b365e 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -541,6 +541,7 @@ enum {
541 AC97_TUNE_ALC_JACK, /* for Realtek, enable JACK detection */ 541 AC97_TUNE_ALC_JACK, /* for Realtek, enable JACK detection */
542 AC97_TUNE_INV_EAPD, /* inverted EAPD implementation */ 542 AC97_TUNE_INV_EAPD, /* inverted EAPD implementation */
543 AC97_TUNE_MUTE_LED, /* EAPD bit works as mute LED */ 543 AC97_TUNE_MUTE_LED, /* EAPD bit works as mute LED */
544 AC97_TUNE_HP_MUTE_LED, /* EAPD bit works as mute LED, use headphone control as master */
544}; 545};
545 546
546struct ac97_quirk { 547struct ac97_quirk {
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
2460static 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
2480static 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
2460struct quirk_table { 2495struct 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 */
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 33e0664a1925..b7217adaf1d7 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1353,6 +1353,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1353 .name = "HP Pavilion ZV5030US", 1353 .name = "HP Pavilion ZV5030US",
1354 .type = AC97_TUNE_MUTE_LED 1354 .type = AC97_TUNE_MUTE_LED
1355 }, 1355 },
1356 {
1357 .subvendor = 0x103c,
1358 .subdevice = 0x308b,
1359 .name = "HP nx6125",
1360 .type = AC97_TUNE_MUTE_LED
1361 },
1356 { } /* terminator */ 1362 { } /* terminator */
1357}; 1363};
1358 1364
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index d3a4e5e8e044..5466b1fa0cd5 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1859,6 +1859,30 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1859 }, 1859 },
1860 { 1860 {
1861 .subvendor = 0x103c, 1861 .subvendor = 0x103c,
1862 .subdevice = 0x0938,
1863 .name = "HP nc4200",
1864 .type = AC97_TUNE_HP_MUTE_LED
1865 },
1866 {
1867 .subvendor = 0x103c,
1868 .subdevice = 0x099c,
1869 .name = "HP nc6120",
1870 .type = AC97_TUNE_HP_MUTE_LED
1871 },
1872 {
1873 .subvendor = 0x103c,
1874 .subdevice = 0x0944,
1875 .name = "HP nc6220",
1876 .type = AC97_TUNE_HP_MUTE_LED
1877 },
1878 {
1879 .subvendor = 0x103c,
1880 .subdevice = 0x0934,
1881 .name = "HP nc8220",
1882 .type = AC97_TUNE_HP_MUTE_LED
1883 },
1884 {
1885 .subvendor = 0x103c,
1862 .subdevice = 0x12f1, 1886 .subdevice = 0x12f1,
1863 .name = "HP xw8200", /* AD1981B*/ 1887 .name = "HP xw8200", /* AD1981B*/
1864 .type = AC97_TUNE_HP_ONLY 1888 .type = AC97_TUNE_HP_ONLY