Commit 679e28ee authored by Ville Syrjala's avatar Ville Syrjala Committed by Jaroslav Kysela

[ALSA] es1968: Fix hw volume

Fix maestro2 hardware volume control. Tested on a Dell Inspiron 7000.
Signed-off-by: default avatarVille Syrjala <syrjala@sci.fi>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent bd25b7ca
...@@ -1905,7 +1905,7 @@ static void es1968_update_hw_volume(unsigned long private_data) ...@@ -1905,7 +1905,7 @@ static void es1968_update_hw_volume(unsigned long private_data)
/* Figure out which volume control button was pushed, /* Figure out which volume control button was pushed,
based on differences from the default register based on differences from the default register
values. */ values. */
x = inb(chip->io_port + 0x1c); x = inb(chip->io_port + 0x1c) & 0xee;
/* Reset the volume control registers. */ /* Reset the volume control registers. */
outb(0x88, chip->io_port + 0x1c); outb(0x88, chip->io_port + 0x1c);
outb(0x88, chip->io_port + 0x1d); outb(0x88, chip->io_port + 0x1d);
...@@ -1921,7 +1921,8 @@ static void es1968_update_hw_volume(unsigned long private_data) ...@@ -1921,7 +1921,8 @@ static void es1968_update_hw_volume(unsigned long private_data)
/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */ /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
spin_lock_irqsave(&chip->ac97_lock, flags); spin_lock_irqsave(&chip->ac97_lock, flags);
val = chip->ac97->regs[AC97_MASTER]; val = chip->ac97->regs[AC97_MASTER];
if (x & 1) { switch (x) {
case 0x88:
/* mute */ /* mute */
val ^= 0x8000; val ^= 0x8000;
chip->ac97->regs[AC97_MASTER] = val; chip->ac97->regs[AC97_MASTER] = val;
...@@ -1929,26 +1930,31 @@ static void es1968_update_hw_volume(unsigned long private_data) ...@@ -1929,26 +1930,31 @@ static void es1968_update_hw_volume(unsigned long private_data)
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX); outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->master_switch->id); &chip->master_switch->id);
} else { break;
val &= 0x7fff; case 0xaa:
if (((x>>1) & 7) > 4) { /* volume up */
/* volume up */ if ((val & 0x7f) > 0)
if ((val & 0xff) > 0) val--;
val--; if ((val & 0x7f00) > 0)
if ((val & 0xff00) > 0) val -= 0x0100;
val -= 0x0100; chip->ac97->regs[AC97_MASTER] = val;
} else { outw(val, chip->io_port + ESM_AC97_DATA);
/* volume down */ outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
if ((val & 0xff) < 0x1f) snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
val++; &chip->master_volume->id);
if ((val & 0xff00) < 0x1f00) break;
val += 0x0100; case 0x66:
} /* volume down */
if ((val & 0x7f) < 0x1f)
val++;
if ((val & 0x7f00) < 0x1f00)
val += 0x0100;
chip->ac97->regs[AC97_MASTER] = val; chip->ac97->regs[AC97_MASTER] = val;
outw(val, chip->io_port + ESM_AC97_DATA); outw(val, chip->io_port + ESM_AC97_DATA);
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX); outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&chip->master_volume->id); &chip->master_volume->id);
break;
} }
spin_unlock_irqrestore(&chip->ac97_lock, flags); spin_unlock_irqrestore(&chip->ac97_lock, flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment