diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/maestro3.c | 42 |
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 | ||
2430 | static void | ||
2431 | snd_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 | |||
2430 | static int | 2453 | static int |
2431 | snd_m3_chip_init(struct snd_m3 *chip) | 2454 | snd_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, |