[ALSA] emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2
authorTakashi Iwai <tiwai@suse.de>
Mon, 2 Jun 2008 09:45:53 +0000 (11:45 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 2 Jun 2008 09:45:53 +0000 (11:45 +0200)
On Audigy2 Platinum, the Analog/Digital mixer switch is inverted.
https://bugzilla.novell.com/show_bug.cgi?id=396204

The patch adds a simple workaround.

There might be another device requiring a similar fix, too (or fix for
audigy2 generically), but right now I fix only the known broken one.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/emu10k1.h
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/emumixer.c

index 7b7b9b1..10ee28e 100644 (file)
@@ -1670,6 +1670,7 @@ struct snd_emu_chip_details {
        unsigned char spi_dac;      /* SPI interface for DAC */
        unsigned char i2c_adc;      /* I2C interface for ADC */
        unsigned char adc_1361t;    /* Use Philips 1361T ADC */
+       unsigned char invert_shared_spdif; /* analog/digital switch inverted */
        const char *driver;
        const char *name;
        const char *id;         /* for backward compatibility - can be NULL if not needed */
index 548c9cc..2f283ea 100644 (file)
@@ -1528,6 +1528,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
         .ca0151_chip = 1,
         .spk71 = 1,
         .spdif_bug = 1,
+        .invert_shared_spdif = 1,      /* digital/analog switch swapped */
         .adc_1361t = 1,  /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
         .ac97_chip = 1} ,
        {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
index fd22120..f34bbfb 100644 (file)
@@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
                ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
        else
                ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
+       if (emu->card_capabilities->invert_shared_spdif)
+               ucontrol->value.integer.value[0] =
+                       !ucontrol->value.integer.value[0];
+               
        return 0;
 }
 
@@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
 {
        unsigned long flags;
        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
-       unsigned int reg, val;
+       unsigned int reg, val, sw;
        int change = 0;
 
+       sw = ucontrol->value.integer.value[0];
+       if (emu->card_capabilities->invert_shared_spdif)
+               sw = !sw;
        spin_lock_irqsave(&emu->reg_lock, flags);
        if ( emu->card_capabilities->i2c_adc) {
                /* Do nothing for Audigy 2 ZS Notebook */
        } else if (emu->audigy) {
                reg = inl(emu->port + A_IOCFG);
-               val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
+               val = sw ? A_IOCFG_GPOUT0 : 0;
                change = (reg & A_IOCFG_GPOUT0) != val;
                if (change) {
                        reg &= ~A_IOCFG_GPOUT0;
@@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
                }
        }
        reg = inl(emu->port + HCFG);
-       val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
+       val = sw ? HCFG_GPOUT0 : 0;
        change |= (reg & HCFG_GPOUT0) != val;
        if (change) {
                reg &= ~HCFG_GPOUT0;