aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;