| From d2cd74b158d7214a556226e3312f9fb1de64d7ae Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Mon, 2 Jun 2008 11:45:53 +0200 |
| Subject: ALSA: emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2 |
| |
| From: Takashi Iwai <tiwai@suse.de> |
| |
| commit d2cd74b158d7214a556226e3312f9fb1de64d7ae upstream |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| include/sound/emu10k1.h | 1 + |
| sound/pci/emu10k1/emu10k1_main.c | 1 + |
| sound/pci/emu10k1/emumixer.c | 13 ++++++++++--- |
| 3 files changed, 12 insertions(+), 3 deletions(-) |
| |
| --- a/include/sound/emu10k1.h |
| +++ b/include/sound/emu10k1.h |
| @@ -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 */ |
| --- a/sound/pci/emu10k1/emu10k1_main.c |
| +++ b/sound/pci/emu10k1/emu10k1_main.c |
| @@ -1528,6 +1528,7 @@ static struct snd_emu_chip_details emu_c |
| .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, |
| --- a/sound/pci/emu10k1/emumixer.c |
| +++ b/sound/pci/emu10k1/emumixer.c |
| @@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get( |
| 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( |
| { |
| 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( |
| } |
| } |
| 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; |