[PATCH] [UBUNTU:sound/pci/emu10k1] Remove distortion from Audigy 2 ZS Notebook

crimsun at fungus.sh.nu crimsun at fungus.sh.nu
Fri Jan 27 01:43:05 UTC 2006


Subject: [PATCH] [UBUNTU:sound/pci/emu10k1] Remove distortion from Audigy 2 ZS Notebook

UpstreamStatus: In ALSA 1.0.11rc2

Reference: http://cvs.sourceforge.net/viewcvs.py/alsa/alsa-kernel/pci/emu10k1/emu10k1_main.c , ALSA bug#927

Christian Bjälevik reports that an Audigy 2 ZS Notebook generates only
distorted sound in Dapper. James Courtier-Dutton fixed this in upstream
ALSA 1.0.11rc2. Here is a backported git patch against Dapper's
2.6.15-14.19 of those fixes removing the distortion.

Signed-off-by: Daniel T Chen <crimsun at fungus.sh.nu>

---

 include/sound/emu10k1.h          |    3 ++
 sound/pci/emu10k1/emu10k1_main.c |   61 +++++++++++++++++++++++++++++++++++++-
 sound/pci/emu10k1/io.c           |   39 ++++++++++++++++++++++++
 sound/pci/emu10k1/tina2.h        |   36 ++++++++++++++++++++++
 4 files changed, 137 insertions(+), 2 deletions(-)
 create mode 100644 sound/pci/emu10k1/tina2.h

b73ea4a0d53db01b460ef35f89dadf43e724330b
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 8411c7e..f504356 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1063,6 +1063,8 @@ typedef struct {
 	unsigned char spdif_bug;    /* Has Spdif phasing bug */
 	unsigned char ac97_chip;    /* Has an AC97 chip: 1 = mandatory, 2 = optional */
 	unsigned char ecard;        /* APS EEPROM */
+	unsigned char spi_dac;      /* SPI interface for DAC */
+	unsigned char i2c_adc;      /* I2C interface for ADC */
 	const char *driver;
 	const char *name;
 	const char *id;		/* for backward compatibility - can be NULL if not needed */
@@ -1190,6 +1192,7 @@ unsigned int snd_emu10k1_ptr_read(emu10k
 void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
 unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
 void snd_emu10k1_ptr20_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
+int snd_emu10k1_spi_write(emu10k1 * emu, unsigned int data);
 unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
 void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
 void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 53aeff0..e3fbf71 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -40,6 +40,7 @@
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 #include "p16v.h"
+#include "tina2.h"
 
 #if 0
 MODULE_AUTHOR("Jaroslav Kysela <perex at suse.cz>, Creative Labs, Inc.");
@@ -96,6 +97,30 @@ void snd_emu10k1_voice_init(emu10k1_t * 
 	}
 }
 
+static unsigned int spi_dac_init[] = {
+	0x00ff,
+	0x02ff,
+	0x0400,
+	0x0520,
+	0x0600,
+	0x08ff,
+	0x0aff,
+	0x0cff,
+	0x0eff,
+	0x10ff,
+	0x1200,
+	0x1400,
+	0x1480,
+	0x1800,
+	0x1aff,
+	0x1cff,
+	0x1e00,
+	0x0530,
+	0x0602,
+	0x0622,
+	0x1400,
+};
+
 static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir)
 {
 	int ch, idx, err;
@@ -220,6 +245,27 @@ static int __devinit snd_emu10k1_init(em
 		outl(tmp, emu->port + A_IOCFG);
 	}
 
+	if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
+		int size, n;
+
+		size = ARRAY_SIZE(spi_dac_init);
+		for (n = 0; n < size; n++)
+			snd_emu10k1_spi_write(emu, spi_dac_init[n]);
+
+		snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
+		/* Enable GPIOs
+		 * GPIO0: Unknown
+		 * GPIO1: Speakers-enabled.
+		 * GPIO2: Unknown
+		 * GPIO3: Unknown
+		 * GPIO4: IEC958 Output on.
+		 * GPIO5: Unknown
+		 * GPIO6: Unknown
+		 * GPIO7: Unknown
+		 */
+		outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
+
+	}
 
 	/*
 	 *  Clear page with silence & setup all pointers to this page
@@ -600,6 +646,7 @@ static int __devinit snd_emu10k1_cardbus
 	outl(0x0090007f, special_port);
 	value = inl(special_port);
 
+	snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
 	return 0;
 }
 
@@ -649,14 +696,24 @@ static emu_chip_details_t emu_chip_detai
 	 .spk71 = 1,
 	 .ac97_chip = 1} ,
 	/* Audigy 2 ZS Notebook Cardbus card.*/
-	/* Tested by James at superbug.co.uk 30th October 2005 */
-	/* Not working yet, but progressing. */
+	/* Tested by James at superbug.co.uk 22th December 2005 */
+	/* Audio output 7.1/Headphones working.
+	 * Digital output working. (AC3 not checked, only PCM)
+	 * Audio inputs not tested.
+	 */
+	/* DSP: Tiny2
+	 * DAC: Wolfson WM8768/WM8568
+	 * ADC: Wolfson WM8775
+	 * AC97: None
+	 * CA0151: None
+	 */
 	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
 	 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 
 	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0108_chip = 1,
 	 .ca_cardbus_chip = 1,
+	 .spi_dac = 1,
 	 .spk71 = 1} ,
 	{.vendor = 0x1102, .device = 0x0008, 
 	 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index b9d3ae0..b81662c 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -29,6 +29,7 @@
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
+#include <linux/delay.h>
 
 unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn)
 {
@@ -123,6 +124,44 @@ void snd_emu10k1_ptr20_write(emu10k1_t *
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
+int snd_emu10k1_spi_write(emu10k1 * emu, unsigned int data)
+{
+	unsigned int reset, set;
+	unsigned int reg, tmp;
+	int n, result;
+	if (emu->card_capabilities->ca0108_chip)
+		reg = 0x3c; /* PTR20, reg 0x3c */
+	else {
+		/* For other cards types the SPI register
+		 * is currently unknown. */
+		return 1;
+	}
+	if (data > 0xffff) /* Only 16bit values allowed */
+		return 1;
+
+	tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
+	reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
+	set = reset | 0x10000; /* Set xxx1xxxx */
+	snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
+	tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
+	snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
+	result = 1;
+	/* Wait for status bit to return to 0 */
+	for (n = 0; n < 100; n++) {
+		udelay(10);
+		tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
+		if (!(tmp & 0x10000)) {
+			result = 0;
+			break;
+		}
+	}
+	if (result) /* Timed out */
+		return 1;
+	snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
+	tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
+	return 0;
+}
+
 void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb)
 {
 	unsigned long flags;
diff --git a/sound/pci/emu10k1/tina2.h b/sound/pci/emu10k1/tina2.h
new file mode 100644
index 0000000..5c43abf
--- /dev/null
+++ b/sound/pci/emu10k1/tina2.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) by James Courtier-Dutton <James at superbug.demon.co.uk>
+ *  Driver p16v chips
+ *  Version: 0.21
+ *
+ *
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes at nc.rr.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/********************************************************************************************************/
+/* Audigy2 Tina2 (notebook) pointer-offset register set, accessed through the PTR2 and DATA2 registers  */
+/********************************************************************************************************/
+
+#define TINA2_VOLUME	0x71	/* Attenuate playback volume to prevent distortion. */
+				/* The windows driver does not use this register,
+				 * so it must use some other attenuation method.
+				 * Without this, the output is 12dB too loud,
+				 * resulting in distortion.
+				 */
+
-- 
1.1.3


-- 
Daniel T. Chen            crimsun at ubuntu.com
GPG key:   www.sh.nu/~crimsun/pubkey.gpg.asc
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20060126/2271face/attachment.sig>


More information about the kernel-team mailing list