Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2cd74b1 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

[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: default avatarTakashi Iwai <tiwai@suse.de>
parent a5003fc0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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,
+10 −3
Original line number Diff line number Diff line
@@ -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;