diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-06-02 05:45:53 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-06-02 05:45:53 -0400 |
commit | d2cd74b158d7214a556226e3312f9fb1de64d7ae (patch) | |
tree | 4a03d56c48d3f02446d07de937bd92af192d57f8 | |
parent | a5003fc04113c217370409beac812831cbf6e0ac (diff) |
[ALSA] emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2
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>
-rw-r--r-- | include/sound/emu10k1.h | 1 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 1 | ||||
-rw-r--r-- | sound/pci/emu10k1/emumixer.c | 13 |
3 files changed, 12 insertions, 3 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 7b7b9b13b4dd..10ee28eac018 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -1670,6 +1670,7 @@ struct snd_emu_chip_details { | |||
1670 | unsigned char spi_dac; /* SPI interface for DAC */ | 1670 | unsigned char spi_dac; /* SPI interface for DAC */ |
1671 | unsigned char i2c_adc; /* I2C interface for ADC */ | 1671 | unsigned char i2c_adc; /* I2C interface for ADC */ |
1672 | unsigned char adc_1361t; /* Use Philips 1361T ADC */ | 1672 | unsigned char adc_1361t; /* Use Philips 1361T ADC */ |
1673 | unsigned char invert_shared_spdif; /* analog/digital switch inverted */ | ||
1673 | const char *driver; | 1674 | const char *driver; |
1674 | const char *name; | 1675 | const char *name; |
1675 | const char *id; /* for backward compatibility - can be NULL if not needed */ | 1676 | const char *id; /* for backward compatibility - can be NULL if not needed */ |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 548c9cc81af5..2f283ea6ad9a 100644 --- 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_chip_details[] = { | |||
1528 | .ca0151_chip = 1, | 1528 | .ca0151_chip = 1, |
1529 | .spk71 = 1, | 1529 | .spk71 = 1, |
1530 | .spdif_bug = 1, | 1530 | .spdif_bug = 1, |
1531 | .invert_shared_spdif = 1, /* digital/analog switch swapped */ | ||
1531 | .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ | 1532 | .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ |
1532 | .ac97_chip = 1} , | 1533 | .ac97_chip = 1} , |
1533 | {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, | 1534 | {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index fd221209abcb..f34bbfb705f5 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, | |||
1578 | ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; | 1578 | ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0; |
1579 | else | 1579 | else |
1580 | ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; | 1580 | ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0; |
1581 | if (emu->card_capabilities->invert_shared_spdif) | ||
1582 | ucontrol->value.integer.value[0] = | ||
1583 | !ucontrol->value.integer.value[0]; | ||
1584 | |||
1581 | return 0; | 1585 | return 0; |
1582 | } | 1586 | } |
1583 | 1587 | ||
@@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, | |||
1586 | { | 1590 | { |
1587 | unsigned long flags; | 1591 | unsigned long flags; |
1588 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); | 1592 | struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol); |
1589 | unsigned int reg, val; | 1593 | unsigned int reg, val, sw; |
1590 | int change = 0; | 1594 | int change = 0; |
1591 | 1595 | ||
1596 | sw = ucontrol->value.integer.value[0]; | ||
1597 | if (emu->card_capabilities->invert_shared_spdif) | ||
1598 | sw = !sw; | ||
1592 | spin_lock_irqsave(&emu->reg_lock, flags); | 1599 | spin_lock_irqsave(&emu->reg_lock, flags); |
1593 | if ( emu->card_capabilities->i2c_adc) { | 1600 | if ( emu->card_capabilities->i2c_adc) { |
1594 | /* Do nothing for Audigy 2 ZS Notebook */ | 1601 | /* Do nothing for Audigy 2 ZS Notebook */ |
1595 | } else if (emu->audigy) { | 1602 | } else if (emu->audigy) { |
1596 | reg = inl(emu->port + A_IOCFG); | 1603 | reg = inl(emu->port + A_IOCFG); |
1597 | val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0; | 1604 | val = sw ? A_IOCFG_GPOUT0 : 0; |
1598 | change = (reg & A_IOCFG_GPOUT0) != val; | 1605 | change = (reg & A_IOCFG_GPOUT0) != val; |
1599 | if (change) { | 1606 | if (change) { |
1600 | reg &= ~A_IOCFG_GPOUT0; | 1607 | reg &= ~A_IOCFG_GPOUT0; |
@@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, | |||
1603 | } | 1610 | } |
1604 | } | 1611 | } |
1605 | reg = inl(emu->port + HCFG); | 1612 | reg = inl(emu->port + HCFG); |
1606 | val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0; | 1613 | val = sw ? HCFG_GPOUT0 : 0; |
1607 | change |= (reg & HCFG_GPOUT0) != val; | 1614 | change |= (reg & HCFG_GPOUT0) != val; |
1608 | if (change) { | 1615 | if (change) { |
1609 | reg &= ~HCFG_GPOUT0; | 1616 | reg &= ~HCFG_GPOUT0; |