diff options
Diffstat (limited to 'sound/pci/emu10k1/io.c')
-rw-r--r-- | sound/pci/emu10k1/io.c | 36 |
1 files changed, 36 insertions, 0 deletions
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; |