aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c28
-rw-r--r--sound/pci/emu10k1/io.c36
2 files changed, 63 insertions, 1 deletions
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index f8e2ccd50d60a..eb093700fa71a 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)
tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
outl(tmp, emu->port + A_IOCFG);
}
-
+ if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
+ u32 tmp;
+ tmp = snd_emu10k1_spi_write(emu, 0x00ff);
+ tmp = snd_emu10k1_spi_write(emu, 0x02ff);
+ tmp = snd_emu10k1_spi_write(emu, 0x0400);
+ tmp = snd_emu10k1_spi_write(emu, 0x0520);
+ tmp = snd_emu10k1_spi_write(emu, 0x0600);
+ tmp = snd_emu10k1_spi_write(emu, 0x08ff);
+ tmp = snd_emu10k1_spi_write(emu, 0x0aff);
+ tmp = snd_emu10k1_spi_write(emu, 0x0cff);
+ tmp = snd_emu10k1_spi_write(emu, 0x0eff);
+ tmp = snd_emu10k1_spi_write(emu, 0x10ff);
+ tmp = snd_emu10k1_spi_write(emu, 0x1200);
+ tmp = snd_emu10k1_spi_write(emu, 0x1400);
+ tmp = snd_emu10k1_spi_write(emu, 0x1480);
+ tmp = snd_emu10k1_spi_write(emu, 0x1800);
+ tmp = snd_emu10k1_spi_write(emu, 0x1aff);
+ tmp = snd_emu10k1_spi_write(emu, 0x1cff);
+ tmp = snd_emu10k1_spi_write(emu, 0x1e00);
+ tmp = snd_emu10k1_spi_write(emu, 0x0530);
+ tmp = snd_emu10k1_spi_write(emu, 0x0602);
+ tmp = snd_emu10k1_spi_write(emu, 0x0622);
+ tmp = snd_emu10k1_spi_write(emu, 0x1400);
+ snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
+ }
+
snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
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[] = {
.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 5d116dd7403be..7d0cb9db42804 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(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
{
@@ -123,6 +124,41 @@ void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu,
spin_unlock_irqrestore(&emu->emu_lock, flags);
}
+int snd_emu10k1_spi_write(struct snd_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 {
+ return 1; /* For other cards types the SPI register is currently unknown. */
+ }
+ if (data > 0xffff) return 1; /* Only 16bit values allowed */
+
+ 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) return 1; /* Timed out */
+ 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(struct snd_emu10k1 *emu, unsigned int intrenb)
{
unsigned long flags;