aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Courtier-Dutton <James@superbug.co.uk>2005-12-21 09:06:08 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:31:01 -0500
commit27fe864ec9e61041fc0b6f680207ae84f359b502 (patch)
tree19392d34e5f076e47192f8a9acf877ef50adc881
parenta5875159dd6cec0ec743971343aee8dceac281d7 (diff)
[ALSA] snd-emu10k1: Removes some distortion from Audigy 2 ZS Notebook.
Modules: EMU10K1/EMU10K2 driver Description: Part way to fix ALSA bug#927 Add support for the SPI interface on the CA0108 chip. This is used to control the registers on the DAC. Headphone output tested. Other outputs and Capture not tested yet. Note: The red LED does not come on, but sound is still OK. Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
-rw-r--r--include/sound/emu10k1.h3
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c28
-rw-r--r--sound/pci/emu10k1/io.c36
3 files changed, 66 insertions, 1 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 0d6e68c43e63..951e40d720d9 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1062,6 +1062,8 @@ struct snd_emu_chip_details {
1062 unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */ 1062 unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */
1063 unsigned char ecard; /* APS EEPROM */ 1063 unsigned char ecard; /* APS EEPROM */
1064 unsigned char emu1212m; /* EMU 1212m card */ 1064 unsigned char emu1212m; /* EMU 1212m card */
1065 unsigned char spi_dac; /* SPI interface for DAC */
1066 unsigned char i2c_adc; /* I2C interface for ADC */
1065 const char *driver; 1067 const char *driver;
1066 const char *name; 1068 const char *name;
1067 const char *id; /* for backward compatibility - can be NULL if not needed */ 1069 const char *id; /* for backward compatibility - can be NULL if not needed */
@@ -1203,6 +1205,7 @@ unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, un
1203void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); 1205void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
1204unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn); 1206unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
1205void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); 1207void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
1208int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
1206unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc); 1209unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
1207void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb); 1210void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
1208void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb); 1211void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index f8e2ccd50d60..eb093700fa71 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -181,7 +181,32 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
181 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */ 181 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
182 outl(tmp, emu->port + A_IOCFG); 182 outl(tmp, emu->port + A_IOCFG);
183 } 183 }
184 184 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
185 u32 tmp;
186 tmp = snd_emu10k1_spi_write(emu, 0x00ff);
187 tmp = snd_emu10k1_spi_write(emu, 0x02ff);
188 tmp = snd_emu10k1_spi_write(emu, 0x0400);
189 tmp = snd_emu10k1_spi_write(emu, 0x0520);
190 tmp = snd_emu10k1_spi_write(emu, 0x0600);
191 tmp = snd_emu10k1_spi_write(emu, 0x08ff);
192 tmp = snd_emu10k1_spi_write(emu, 0x0aff);
193 tmp = snd_emu10k1_spi_write(emu, 0x0cff);
194 tmp = snd_emu10k1_spi_write(emu, 0x0eff);
195 tmp = snd_emu10k1_spi_write(emu, 0x10ff);
196 tmp = snd_emu10k1_spi_write(emu, 0x1200);
197 tmp = snd_emu10k1_spi_write(emu, 0x1400);
198 tmp = snd_emu10k1_spi_write(emu, 0x1480);
199 tmp = snd_emu10k1_spi_write(emu, 0x1800);
200 tmp = snd_emu10k1_spi_write(emu, 0x1aff);
201 tmp = snd_emu10k1_spi_write(emu, 0x1cff);
202 tmp = snd_emu10k1_spi_write(emu, 0x1e00);
203 tmp = snd_emu10k1_spi_write(emu, 0x0530);
204 tmp = snd_emu10k1_spi_write(emu, 0x0602);
205 tmp = snd_emu10k1_spi_write(emu, 0x0622);
206 tmp = snd_emu10k1_spi_write(emu, 0x1400);
207 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
208 }
209
185 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); 210 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
186 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 211 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
187 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ 212 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
@@ -747,6 +772,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
747 .emu10k2_chip = 1, 772 .emu10k2_chip = 1,
748 .ca0108_chip = 1, 773 .ca0108_chip = 1,
749 .ca_cardbus_chip = 1, 774 .ca_cardbus_chip = 1,
775 .spi_dac = 1,
750 .spk71 = 1} , 776 .spk71 = 1} ,
751 {.vendor = 0x1102, .device = 0x0008, 777 {.vendor = 0x1102, .device = 0x0008,
752 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 778 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 5d116dd7403b..7d0cb9db4280 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -29,6 +29,7 @@
29#include <linux/time.h> 29#include <linux/time.h>
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/emu10k1.h> 31#include <sound/emu10k1.h>
32#include <linux/delay.h>
32 33
33unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) 34unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
34{ 35{
@@ -123,6 +124,41 @@ void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
123 spin_unlock_irqrestore(&emu->emu_lock, flags); 124 spin_unlock_irqrestore(&emu->emu_lock, flags);
124} 125}
125 126
127int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
128 unsigned int data)
129{
130 unsigned int reset, set;
131 unsigned int reg, tmp;
132 int n, result;
133 if (emu->card_capabilities->ca0108_chip) {
134 reg=0x3c; /* PTR20, reg 0x3c */
135 } else {
136 return 1; /* For other cards types the SPI register is currently unknown. */
137 }
138 if (data > 0xffff) return 1; /* Only 16bit values allowed */
139
140 tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
141 reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
142 set = reset | 0x10000; /* Set xxx1xxxx */
143 snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
144 tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
145 snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
146 result = 1;
147 /* Wait for status bit to return to 0 */
148 for (n=0;n<100;n++) {
149 udelay(10);
150 tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
151 if (!(tmp & 0x10000)) {
152 result=0;
153 break;
154 }
155 }
156 if (result) return 1; /* Timed out */
157 snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
158 tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
159 return 0;
160}
161
126void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) 162void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
127{ 163{
128 unsigned long flags; 164 unsigned long flags;