GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / sound / isa / gus / gus_io.c
blobe839be38b47f5605d1d77c869d332cde3bffaba9
1 /*
2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 * I/O routines for GF1/InterWave synthesizer chips
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/delay.h>
23 #include <linux/time.h>
24 #include <sound/core.h>
25 #include <sound/gus.h>
27 void snd_gf1_delay(struct snd_gus_card * gus)
29 int i;
31 for (i = 0; i < 6; i++) {
32 mb();
33 inb(GUSP(gus, DRAM));
38 * =======================================================================
42 * ok.. stop of control registers (wave & ramp) need some special things..
43 * big UltraClick (tm) elimination...
46 static inline void __snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
48 unsigned char value;
50 outb(reg | 0x80, gus->gf1.reg_regsel);
51 mb();
52 value = inb(gus->gf1.reg_data8);
53 mb();
54 outb(reg, gus->gf1.reg_regsel);
55 mb();
56 outb((value | 0x03) & ~(0x80 | 0x20), gus->gf1.reg_data8);
57 mb();
60 static inline void __snd_gf1_write8(struct snd_gus_card * gus,
61 unsigned char reg,
62 unsigned char data)
64 outb(reg, gus->gf1.reg_regsel);
65 mb();
66 outb(data, gus->gf1.reg_data8);
67 mb();
70 static inline unsigned char __snd_gf1_look8(struct snd_gus_card * gus,
71 unsigned char reg)
73 outb(reg, gus->gf1.reg_regsel);
74 mb();
75 return inb(gus->gf1.reg_data8);
78 static inline void __snd_gf1_write16(struct snd_gus_card * gus,
79 unsigned char reg, unsigned int data)
81 outb(reg, gus->gf1.reg_regsel);
82 mb();
83 outw((unsigned short) data, gus->gf1.reg_data16);
84 mb();
87 static inline unsigned short __snd_gf1_look16(struct snd_gus_card * gus,
88 unsigned char reg)
90 outb(reg, gus->gf1.reg_regsel);
91 mb();
92 return inw(gus->gf1.reg_data16);
95 static inline void __snd_gf1_adlib_write(struct snd_gus_card * gus,
96 unsigned char reg, unsigned char data)
98 outb(reg, gus->gf1.reg_timerctrl);
99 inb(gus->gf1.reg_timerctrl);
100 inb(gus->gf1.reg_timerctrl);
101 outb(data, gus->gf1.reg_timerdata);
102 inb(gus->gf1.reg_timerctrl);
103 inb(gus->gf1.reg_timerctrl);
106 static inline void __snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
107 unsigned int addr, int w_16bit)
109 if (gus->gf1.enh_mode) {
110 if (w_16bit)
111 addr = ((addr >> 1) & ~0x0000000f) | (addr & 0x0000000f);
112 __snd_gf1_write8(gus, SNDRV_GF1_VB_UPPER_ADDRESS, (unsigned char) ((addr >> 26) & 0x03));
113 } else if (w_16bit)
114 addr = (addr & 0x00c0000f) | ((addr & 0x003ffff0) >> 1);
115 __snd_gf1_write16(gus, reg, (unsigned short) (addr >> 11));
116 __snd_gf1_write16(gus, reg + 1, (unsigned short) (addr << 5));
119 static inline unsigned int __snd_gf1_read_addr(struct snd_gus_card * gus,
120 unsigned char reg, short w_16bit)
122 unsigned int res;
124 res = ((unsigned int) __snd_gf1_look16(gus, reg | 0x80) << 11) & 0xfff800;
125 res |= ((unsigned int) __snd_gf1_look16(gus, (reg + 1) | 0x80) >> 5) & 0x0007ff;
126 if (gus->gf1.enh_mode) {
127 res |= (unsigned int) __snd_gf1_look8(gus, SNDRV_GF1_VB_UPPER_ADDRESS | 0x80) << 26;
128 if (w_16bit)
129 res = ((res << 1) & 0xffffffe0) | (res & 0x0000000f);
130 } else if (w_16bit)
131 res = ((res & 0x001ffff0) << 1) | (res & 0x00c0000f);
132 return res;
137 * =======================================================================
140 void snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
142 __snd_gf1_ctrl_stop(gus, reg);
145 void snd_gf1_write8(struct snd_gus_card * gus,
146 unsigned char reg,
147 unsigned char data)
149 __snd_gf1_write8(gus, reg, data);
152 unsigned char snd_gf1_look8(struct snd_gus_card * gus, unsigned char reg)
154 return __snd_gf1_look8(gus, reg);
157 void snd_gf1_write16(struct snd_gus_card * gus,
158 unsigned char reg,
159 unsigned int data)
161 __snd_gf1_write16(gus, reg, data);
164 unsigned short snd_gf1_look16(struct snd_gus_card * gus, unsigned char reg)
166 return __snd_gf1_look16(gus, reg);
169 void snd_gf1_adlib_write(struct snd_gus_card * gus,
170 unsigned char reg,
171 unsigned char data)
173 __snd_gf1_adlib_write(gus, reg, data);
176 void snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
177 unsigned int addr, short w_16bit)
179 __snd_gf1_write_addr(gus, reg, addr, w_16bit);
182 unsigned int snd_gf1_read_addr(struct snd_gus_card * gus,
183 unsigned char reg,
184 short w_16bit)
186 return __snd_gf1_read_addr(gus, reg, w_16bit);
193 void snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
195 unsigned long flags;
197 spin_lock_irqsave(&gus->reg_lock, flags);
198 __snd_gf1_ctrl_stop(gus, reg);
199 spin_unlock_irqrestore(&gus->reg_lock, flags);
202 void snd_gf1_i_write8(struct snd_gus_card * gus,
203 unsigned char reg,
204 unsigned char data)
206 unsigned long flags;
208 spin_lock_irqsave(&gus->reg_lock, flags);
209 __snd_gf1_write8(gus, reg, data);
210 spin_unlock_irqrestore(&gus->reg_lock, flags);
213 unsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg)
215 unsigned long flags;
216 unsigned char res;
218 spin_lock_irqsave(&gus->reg_lock, flags);
219 res = __snd_gf1_look8(gus, reg);
220 spin_unlock_irqrestore(&gus->reg_lock, flags);
221 return res;
224 void snd_gf1_i_write16(struct snd_gus_card * gus,
225 unsigned char reg,
226 unsigned int data)
228 unsigned long flags;
230 spin_lock_irqsave(&gus->reg_lock, flags);
231 __snd_gf1_write16(gus, reg, data);
232 spin_unlock_irqrestore(&gus->reg_lock, flags);
235 unsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg)
237 unsigned long flags;
238 unsigned short res;
240 spin_lock_irqsave(&gus->reg_lock, flags);
241 res = __snd_gf1_look16(gus, reg);
242 spin_unlock_irqrestore(&gus->reg_lock, flags);
243 return res;
247 #ifdef CONFIG_SND_DEBUG
248 static unsigned int snd_gf1_i_read_addr(struct snd_gus_card * gus,
249 unsigned char reg, short w_16bit)
251 unsigned int res;
252 unsigned long flags;
254 spin_lock_irqsave(&gus->reg_lock, flags);
255 res = __snd_gf1_read_addr(gus, reg, w_16bit);
256 spin_unlock_irqrestore(&gus->reg_lock, flags);
257 return res;
259 #endif
265 void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr)
267 outb(0x43, gus->gf1.reg_regsel);
268 mb();
269 outw((unsigned short) addr, gus->gf1.reg_data16);
270 mb();
271 outb(0x44, gus->gf1.reg_regsel);
272 mb();
273 outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
274 mb();
277 void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data)
279 unsigned long flags;
281 spin_lock_irqsave(&gus->reg_lock, flags);
282 outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
283 mb();
284 outw((unsigned short) addr, gus->gf1.reg_data16);
285 mb();
286 outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
287 mb();
288 outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
289 mb();
290 outb(data, gus->gf1.reg_dram);
291 spin_unlock_irqrestore(&gus->reg_lock, flags);
294 unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr)
296 unsigned long flags;
297 unsigned char res;
299 spin_lock_irqsave(&gus->reg_lock, flags);
300 outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
301 mb();
302 outw((unsigned short) addr, gus->gf1.reg_data16);
303 mb();
304 outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
305 mb();
306 outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
307 mb();
308 res = inb(gus->gf1.reg_dram);
309 spin_unlock_irqrestore(&gus->reg_lock, flags);
310 return res;
314 void snd_gf1_select_active_voices(struct snd_gus_card * gus)
316 unsigned short voices;
318 static unsigned short voices_tbl[32 - 14 + 1] =
320 44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, 28063, 26843,
321 25725, 24696, 23746, 22866, 22050, 21289, 20580, 19916, 19293
324 voices = gus->gf1.active_voices;
325 if (voices > 32)
326 voices = 32;
327 if (voices < 14)
328 voices = 14;
329 if (gus->gf1.enh_mode)
330 voices = 32;
331 gus->gf1.active_voices = voices;
332 gus->gf1.playback_freq =
333 gus->gf1.enh_mode ? 44100 : voices_tbl[voices - 14];
334 if (!gus->gf1.enh_mode) {
335 snd_gf1_i_write8(gus, SNDRV_GF1_GB_ACTIVE_VOICES, 0xc0 | (voices - 1));
336 udelay(100);
340 #ifdef CONFIG_SND_DEBUG
342 void snd_gf1_print_voice_registers(struct snd_gus_card * gus)
344 unsigned char mode;
345 int voice, ctrl;
347 voice = gus->gf1.active_voice;
348 printk(KERN_INFO " -%i- GF1 voice ctrl, ramp ctrl = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
349 printk(KERN_INFO " -%i- GF1 frequency = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
350 printk(KERN_INFO " -%i- GF1 loop start, end = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
351 printk(KERN_INFO " -%i- GF1 ramp start, end, rate = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
352 printk(KERN_INFO" -%i- GF1 volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
353 printk(KERN_INFO " -%i- GF1 position = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
354 if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) { /* enhanced mode */
355 mode = snd_gf1_i_read8(gus, 0x15);
356 printk(KERN_INFO " -%i- GFA1 mode = 0x%x\n", voice, mode);
357 if (mode & 0x01) { /* Effect processor */
358 printk(KERN_INFO " -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
359 printk(KERN_INFO " -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
360 printk(KERN_INFO " -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
361 printk(KERN_INFO " -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
363 if (mode & 0x20) {
364 printk(KERN_INFO " -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
365 printk(KERN_INFO " -%i- GFA1 left offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
366 printk(KERN_INFO " -%i- GFA1 right offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
367 printk(KERN_INFO " -%i- GFA1 right offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
368 } else
369 printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
370 } else
371 printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
375 #endif