diff options
-rw-r--r-- | include/sound/emu10k1.h | 3 | ||||
-rw-r--r-- | sound/pci/emu10k1/emu10k1_main.c | 28 | ||||
-rw-r--r-- | sound/pci/emu10k1/io.c | 36 |
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 | |||
1203 | void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); | 1205 | void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); |
1204 | unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn); | 1206 | unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn); |
1205 | void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); | 1207 | void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data); |
1208 | int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data); | ||
1206 | unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc); | 1209 | unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc); |
1207 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb); | 1210 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb); |
1208 | void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb); | 1211 | void 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 | ||
33 | unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) | 34 | unsigned 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 | ||
127 | int 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 | |||
126 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) | 162 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) |
127 | { | 163 | { |
128 | unsigned long flags; | 164 | unsigned long flags; |