aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjala <syrjala@sci.fi>2006-09-04 06:28:51 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:45:53 -0400
commit679e28eef835cbd30de78c2f80bf488cba1b7e40 (patch)
tree99eccfb2fd4e89bea16d3c7bcf93b4a982fafa50
parentbd25b7cae1e763b292f359170e16bccd01c7ee5c (diff)
[ALSA] es1968: Fix hw volume
Fix maestro2 hardware volume control. Tested on a Dell Inspiron 7000. Signed-off-by: Ville Syrjala <syrjala@sci.fi> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--sound/pci/es1968.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 3c5ab7c2e72d..f3c40385c87d 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1905,7 +1905,7 @@ static void es1968_update_hw_volume(unsigned long private_data)
1905 /* Figure out which volume control button was pushed, 1905 /* Figure out which volume control button was pushed,
1906 based on differences from the default register 1906 based on differences from the default register
1907 values. */ 1907 values. */
1908 x = inb(chip->io_port + 0x1c); 1908 x = inb(chip->io_port + 0x1c) & 0xee;
1909 /* Reset the volume control registers. */ 1909 /* Reset the volume control registers. */
1910 outb(0x88, chip->io_port + 0x1c); 1910 outb(0x88, chip->io_port + 0x1c);
1911 outb(0x88, chip->io_port + 0x1d); 1911 outb(0x88, chip->io_port + 0x1d);
@@ -1921,7 +1921,8 @@ static void es1968_update_hw_volume(unsigned long private_data)
1921 /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */ 1921 /* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
1922 spin_lock_irqsave(&chip->ac97_lock, flags); 1922 spin_lock_irqsave(&chip->ac97_lock, flags);
1923 val = chip->ac97->regs[AC97_MASTER]; 1923 val = chip->ac97->regs[AC97_MASTER];
1924 if (x & 1) { 1924 switch (x) {
1925 case 0x88:
1925 /* mute */ 1926 /* mute */
1926 val ^= 0x8000; 1927 val ^= 0x8000;
1927 chip->ac97->regs[AC97_MASTER] = val; 1928 chip->ac97->regs[AC97_MASTER] = val;
@@ -1929,26 +1930,31 @@ static void es1968_update_hw_volume(unsigned long private_data)
1929 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX); 1930 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1930 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 1931 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1931 &chip->master_switch->id); 1932 &chip->master_switch->id);
1932 } else { 1933 break;
1933 val &= 0x7fff; 1934 case 0xaa:
1934 if (((x>>1) & 7) > 4) { 1935 /* volume up */
1935 /* volume up */ 1936 if ((val & 0x7f) > 0)
1936 if ((val & 0xff) > 0) 1937 val--;
1937 val--; 1938 if ((val & 0x7f00) > 0)
1938 if ((val & 0xff00) > 0) 1939 val -= 0x0100;
1939 val -= 0x0100; 1940 chip->ac97->regs[AC97_MASTER] = val;
1940 } else { 1941 outw(val, chip->io_port + ESM_AC97_DATA);
1941 /* volume down */ 1942 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1942 if ((val & 0xff) < 0x1f) 1943 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1943 val++; 1944 &chip->master_volume->id);
1944 if ((val & 0xff00) < 0x1f00) 1945 break;
1945 val += 0x0100; 1946 case 0x66:
1946 } 1947 /* volume down */
1948 if ((val & 0x7f) < 0x1f)
1949 val++;
1950 if ((val & 0x7f00) < 0x1f00)
1951 val += 0x0100;
1947 chip->ac97->regs[AC97_MASTER] = val; 1952 chip->ac97->regs[AC97_MASTER] = val;
1948 outw(val, chip->io_port + ESM_AC97_DATA); 1953 outw(val, chip->io_port + ESM_AC97_DATA);
1949 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX); 1954 outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
1950 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, 1955 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1951 &chip->master_volume->id); 1956 &chip->master_volume->id);
1957 break;
1952 } 1958 }
1953 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1959 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1954} 1960}