aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/maestro3.c
diff options
context:
space:
mode:
authorVille Syrjälä <syrjala@sci.fi>2008-06-03 13:52:10 -0400
committerTakashi Iwai <tiwai@suse.de>2008-06-06 05:54:18 -0400
commit8b83afe0d21f07145ec34ac006656e4d3edc4bac (patch)
tree307a313a408d914ff1d10cd7e0c595ca39ef3c21 /sound/pci/maestro3.c
parent607d982bbea2a14b5b77cc7689f509d588e1e6da (diff)
[ALSA] maestro3: Fix hw volume on HP OmniBook
Make the hw volume buttons work correctly on some HP OmniBook laptops. The original quirk was apparently applied a bit too early and it was also lacking some critial register writes. This improved sequence was discovered by trial and error (like the original sequence). Tested and found working on OB500 and OB6000 laptops. Signed-off-by: Ville Syrjala <syrjala@sci.fi> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/maestro3.c')
-rw-r--r--sound/pci/maestro3.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index a536c59fbea1..f4788dee05c3 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2427,6 +2427,29 @@ snd_m3_amp_enable(struct snd_m3 *chip, int enable)
2427 outw(0xffff, io + GPIO_MASK); 2427 outw(0xffff, io + GPIO_MASK);
2428} 2428}
2429 2429
2430static void
2431snd_m3_hv_init(struct snd_m3 *chip)
2432{
2433 unsigned long io = chip->iobase;
2434 u16 val = GPI_VOL_DOWN | GPI_VOL_UP;
2435
2436 if (!chip->is_omnibook)
2437 return;
2438
2439 /*
2440 * Volume buttons on some HP OmniBook laptops
2441 * require some GPIO magic to work correctly.
2442 */
2443 outw(0xffff, io + GPIO_MASK);
2444 outw(0x0000, io + GPIO_DATA);
2445
2446 outw(~val, io + GPIO_MASK);
2447 outw(inw(io + GPIO_DIRECTION) & ~val, io + GPIO_DIRECTION);
2448 outw(val, io + GPIO_MASK);
2449
2450 outw(0xffff, io + GPIO_MASK);
2451}
2452
2430static int 2453static int
2431snd_m3_chip_init(struct snd_m3 *chip) 2454snd_m3_chip_init(struct snd_m3 *chip)
2432{ 2455{
@@ -2442,21 +2465,6 @@ snd_m3_chip_init(struct snd_m3 *chip)
2442 DISABLE_LEGACY); 2465 DISABLE_LEGACY);
2443 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w); 2466 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
2444 2467
2445 if (chip->is_omnibook) {
2446 /*
2447 * Volume buttons on some HP OmniBook laptops don't work
2448 * correctly. This makes them work for the most part.
2449 *
2450 * Volume up and down buttons on the laptop side work.
2451 * Fn+cursor_up (volme up) works.
2452 * Fn+cursor_down (volume down) doesn't work.
2453 * Fn+F7 (mute) works acts as volume up.
2454 */
2455 outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK);
2456 outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION);
2457 outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA);
2458 outw(0xffff, io + GPIO_MASK);
2459 }
2460 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); 2468 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
2461 n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD); 2469 n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
2462 n |= chip->hv_config; 2470 n |= chip->hv_config;
@@ -2642,6 +2650,8 @@ static int m3_resume(struct pci_dev *pci)
2642 snd_m3_enable_ints(chip); 2650 snd_m3_enable_ints(chip);
2643 snd_m3_amp_enable(chip, 1); 2651 snd_m3_amp_enable(chip, 1);
2644 2652
2653 snd_m3_hv_init(chip);
2654
2645 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2655 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2646 return 0; 2656 return 0;
2647} 2657}
@@ -2781,6 +2791,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2781 2791
2782 snd_m3_amp_enable(chip, 1); 2792 snd_m3_amp_enable(chip, 1);
2783 2793
2794 snd_m3_hv_init(chip);
2795
2784 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); 2796 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
2785 2797
2786 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, 2798 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,