source: GPL/alsa-kernel/isa/gus/interwave.c@ 1

Last change on this file since 1 was 1, checked in by vladest, 20 years ago

initial import

File size: 32.0 KB
Line 
1/*
2 * Driver for AMD InterWave soundcard
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 *
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.
10 *
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.
15 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * 1999/07/22 Erik Inge Bolso <knan@mo.himolde.no>
21 * * mixer group handlers
22 *
23 */
24
25#define SNDRV_MAIN_OBJECT_FILE
26#include <sound/driver.h>
27#include <sound/gus.h>
28#include <sound/cs4231.h>
29#ifdef SNDRV_STB
30#include <sound/tea6330t.h>
31#endif
32#define SNDRV_LEGACY_AUTO_PROBE
33#define SNDRV_LEGACY_FIND_FREE_IRQ
34#define SNDRV_LEGACY_FIND_FREE_DMA
35#define SNDRV_GET_ID
36#include <sound/initval.h>
37
38EXPORT_NO_SYMBOLS;
39#ifndef SNDRV_STB
40MODULE_DESCRIPTION("AMD InterWave");
41MODULE_CLASSES("{sound}");
42MODULE_DEVICES("{{Gravis,UltraSound Plug & Play},"
43 "{STB,SoundRage32},"
44 "{MED,MED3210},"
45 "{Dynasonix,Dynasonix Pro},"
46 "{Panasonic,PCA761AW}}");
47#else
48MODULE_DESCRIPTION("AMD InterWave STB with TEA6330T");
49MODULE_CLASSES("{sound}");
50MODULE_DEVICES("{{AMD,InterWave STB with TEA6330T}}");
51#endif
52
53static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
54static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
55static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
56#ifdef __ISAPNP__
57#ifdef TARGET_OS2
58static int snd_isapnp[SNDRV_CARDS] = {1,1,1,1,1,1,1,1};
59#else
60static int snd_isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
61#endif
62#endif
63static long snd_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x210,0x220,0x230,0x240,0x250,0x260 */
64#ifdef SNDRV_STB
65static long snd_port_tc[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x350,0x360,0x370,0x380 */
66#endif
67static int snd_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */
68static int snd_dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
69static int snd_dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
70#ifdef TARGET_OS2
71static int snd_joystick_dac[SNDRV_CARDS] = {REPEAT_SNDRV(29)};
72 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
73static int snd_midi[SNDRV_CARDS] = {REPEAT_SNDRV(0)};
74static int snd_pcm_channels[SNDRV_CARDS] = {REPEAT_SNDRV(2)};
75static int snd_effect[SNDRV_CARDS] = {REPEAT_SNDRV(0)};
76#else
77static int snd_joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
78 /* 0 to 31, (0.59V-4.52V or 0.389V-2.98V) */
79static int snd_midi[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
80static int snd_pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
81static int snd_effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
82#endif
83
84MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
85MODULE_PARM_DESC(snd_index, "Index value for InterWave soundcard.");
86MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);
87MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
88MODULE_PARM_DESC(snd_id, "ID string for InterWave soundcard.");
89MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
90MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
91MODULE_PARM_DESC(snd_enable, "Enable InterWave soundcard.");
92MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);
93MODULE_PARM(snd_isapnp, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
94MODULE_PARM_DESC(snd_isapnp, "ISA PnP detection for specified soundcard.");
95MODULE_PARM_SYNTAX(snd_isapnp, SNDRV_ISAPNP_DESC);
96MODULE_PARM(snd_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
97MODULE_PARM_DESC(snd_port, "Port # for InterWave driver.");
98MODULE_PARM_SYNTAX(snd_port, SNDRV_ENABLED ",allows:{{0x210,0x260,0x10}},dialog:list");
99#ifdef SNDRV_STB
100MODULE_PARM(snd_port_tc, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
101MODULE_PARM_DESC(snd_port_tc, "Tone control (TEA6330T - i2c bus) port # for InterWave driver.");
102MODULE_PARM_SYNTAX(snd_port_tc, SNDRV_ENABLED ",allows:{{0x350,0x380,0x10}},dialog:list");
103#endif
104MODULE_PARM(snd_irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
105MODULE_PARM_DESC(snd_irq, "IRQ # for InterWave driver.");
106MODULE_PARM_SYNTAX(snd_irq, SNDRV_ENABLED ",allows:{{3},{5},{9},{11},{12},{15}},dialog:list");
107MODULE_PARM(snd_dma1, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
108MODULE_PARM_DESC(snd_dma1, "DMA1 # for InterWave driver.");
109MODULE_PARM_SYNTAX(snd_dma1, SNDRV_DMA_DESC);
110MODULE_PARM(snd_dma2, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
111MODULE_PARM_DESC(snd_dma2, "DMA2 # for InterWave driver.");
112MODULE_PARM_SYNTAX(snd_dma2, SNDRV_DMA_DESC);
113MODULE_PARM(snd_joystick_dac, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
114MODULE_PARM_DESC(snd_joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for InterWave driver.");
115MODULE_PARM_SYNTAX(snd_joystic_dac, SNDRV_ENABLED ",allows:{{0,31}}");
116MODULE_PARM(snd_midi, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
117MODULE_PARM_DESC(snd_midi, "MIDI UART enable for InterWave driver.");
118MODULE_PARM_SYNTAX(snd_midi, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
119MODULE_PARM(snd_pcm_channels, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
120MODULE_PARM_DESC(snd_pcm_channels, "Reserved PCM channels for InterWave driver.");
121MODULE_PARM_SYNTAX(snd_pcm_channels, SNDRV_ENABLED ",allows:{{2,16}}");
122MODULE_PARM(snd_effect, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
123MODULE_PARM_DESC(snd_effect, "Effects enable for InterWave driver.");
124MODULE_PARM_SYNTAX(snd_effect, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
125
126struct snd_interwave {
127 int irq;
128 snd_card_t *card;
129 snd_gus_card_t *gus;
130 cs4231_t *cs4231;
131#ifdef SNDRV_STB
132 struct resource *i2c_res;
133#endif
134 unsigned short gus_status_reg;
135 unsigned short pcm_status_reg;
136#ifdef __ISAPNP__
137 struct isapnp_dev *dev;
138#ifdef SNDRV_STB
139 struct isapnp_dev *devtc;
140#endif
141#endif
142};
143
144static snd_card_t *snd_interwave_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
145
146#ifdef __ISAPNP__
147
148static struct isapnp_card *snd_interwave_isapnp_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
149static const struct isapnp_card_id *snd_interwave_isapnp_id[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
150
151#ifdef TARGET_OS2
152#define ISAPNP_INTERWAVE(_va, _vb, _vc, _device, _audio) \
153 { \
154 0, ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
155 { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio)} \
156 }
157#define ISAPNP_INTERWAVE_STB(_va, _vb, _vc, _device, _audio, _tone) \
158 { \
159 0, ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
160 { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
161 ISAPNP_DEVICE_ID(_va, _vb, _vc, _tone) }\
162 }
163#else
164#define ISAPNP_INTERWAVE(_va, _vb, _vc, _device, _audio) \
165 { \
166 ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
167 devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), } \
168 }
169#define ISAPNP_INTERWAVE_STB(_va, _vb, _vc, _device, _audio, _tone) \
170 { \
171 ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
172 devs : { ISAPNP_DEVICE_ID(_va, _vb, _vc, _audio), \
173 ISAPNP_DEVICE_ID(_va, _vb, _vc, _tone), } \
174 }
175#endif
176
177static struct isapnp_card_id snd_interwave_pnpids[] __devinitdata = {
178#ifndef SNDRV_STB
179 /* Gravis UltraSound Plug & Play */
180 ISAPNP_INTERWAVE('G','R','V',0x0001,0x0000),
181 /* STB SoundRage32 */
182 ISAPNP_INTERWAVE('S','T','B',0x011a,0x0010),
183 /* MED3210 */
184 ISAPNP_INTERWAVE('D','X','P',0x3201,0x0010),
185 /* Dynasonic Pro */
186 /* This device also have CDC1117:DynaSonix Pro Audio Effects Processor */
187 ISAPNP_INTERWAVE('C','D','C',0x1111,0x1112),
188 /* Panasonic PCA761AW Audio Card */
189 ISAPNP_INTERWAVE('A','D','V',0x55ff,0x0010),
190#else
191 /* InterWave STB with TEA6330T */
192 ISAPNP_INTERWAVE_STB('A','D','V',0x550a,0x0010,0x0015),
193#endif
194 { ISAPNP_CARD_END, }
195};
196
197ISAPNP_CARD_TABLE(snd_interwave_pnpids);
198
199#endif /* __ISAPNP__ */
200
201
202#ifdef SNDRV_STB
203static void snd_interwave_i2c_setlines(snd_i2c_bus_t *bus, int ctrl, int data)
204{
205 unsigned long port = bus->private_value;
206
207#if 0
208 printk("i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data);
209#endif
210 outb((data << 1) | ctrl, port);
211 udelay(10);
212}
213
214static int snd_interwave_i2c_getdataline(snd_i2c_bus_t *bus)
215{
216 unsigned long port = bus->private_value;
217 unsigned char res;
218
219 res = (inb(port) & 2) >> 1;
220#if 0
221 printk("i2c_getdataline - 0x%lx -> %i\n", port, res);
222#endif
223 return res;
224}
225
226static int __init snd_interwave_detect_stb(struct snd_interwave *iwcard,
227 snd_gus_card_t * gus, int dev,
228 snd_i2c_bus_t **rbus)
229{
230 unsigned long port;
231 snd_i2c_bus_t *bus;
232 snd_card_t *card = iwcard->card;
233 unsigned long flags;
234 char name[32];
235 int err;
236
237 *rbus = NULL;
238 port = snd_port_tc[dev];
239 if (port == SNDRV_AUTO_PORT) {
240 port = 0x350;
241 if (gus->gf1.port == 0x250) {
242 port = 0x360;
243 }
244 while (port <= 0x380) {
245 if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)
246 break;
247 port += 0x10;
248 }
249 if (port > 0x380)
250 return -ENODEV;
251 } else {
252 if ((iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)")) != NULL)
253 return -ENODEV;
254 }
255 sprintf(name, "InterWave-%i", card->number);
256 if ((err = snd_i2c_bus_create(card, name, &bus)) < 0)
257 return err;
258 bus->private_value = port;
259 bus->i2c_setlines = snd_interwave_i2c_setlines;
260 bus->i2c_getdataline = snd_interwave_i2c_getdataline;
261 SNDRV_LOCK_I2C_BUS(bus);
262 snd_i2c_reset(bus);
263#if 0
264 {
265 int idx, ack;
266 for (idx = 0; idx < 256; idx += 2) {
267 snd_i2c_start(bus);
268 ack = snd_i2c_sendbyte(bus, idx, 0);
269 snd_i2c_stop(bus);
270 if (!ack) {
271 printk("i2c: scanning bus %s: found device at addr=0x%x\n",
272 bus->name, idx);
273 }
274 }
275 }
276#endif
277 SNDRV_UNLOCK_I2C_BUS(bus);
278 if ((err = snd_tea6330t_detect(bus, 0)) < 0)
279 return err;
280 *rbus = bus;
281 return 0;
282}
283#endif
284
285static int __init snd_interwave_detect(struct snd_interwave *iwcard,
286 snd_gus_card_t * gus,
287 int dev
288#ifdef SNDRV_STB
289 , snd_i2c_bus_t **rbus
290#endif
291 )
292{
293 unsigned long flags;
294 unsigned char rev1, rev2;
295
296 snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */
297#ifdef CONFIG_SND_DEBUG_DETECT
298 {
299 int d;
300
301 if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
302 snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
303 return -ENODEV;
304 }
305 }
306#else
307 if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
308 return -ENODEV;
309#endif
310 udelay(160);
311 snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */
312 udelay(160);
313#ifdef CONFIG_SND_DEBUG_DETECT
314 {
315 int d;
316
317 if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
318 snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
319 return -ENODEV;
320 }
321 }
322#else
323 if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
324 return -ENODEV;
325#endif
326
327 spin_lock_irqsave(&gus->reg_lock, flags);
328 rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
329 snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
330 rev2 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
331 snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, rev1);
332 spin_unlock_irqrestore(&gus->reg_lock, flags);
333 snd_printdd("[0x%lx] InterWave check - rev1=0x%x, rev2=0x%x\n", gus->gf1.port, rev1, rev2);
334 if ((rev1 & 0xf0) == (rev2 & 0xf0) &&
335 (rev1 & 0x0f) != (rev2 & 0x0f)) {
336 snd_printdd("[0x%lx] InterWave check - passed\n", gus->gf1.port);
337 gus->interwave = 1;
338 strcpy(gus->card->shortname, "AMD InterWave");
339 gus->revision = rev1 >> 4;
340#ifndef SNDRV_STB
341 return 0; /* ok.. We have an InterWave board */
342#else
343 return snd_interwave_detect_stb(iwcard, gus, dev, rbus);
344#endif
345 }
346 snd_printdd("[0x%lx] InterWave check - failed\n", gus->gf1.port);
347 return -ENODEV;
348}
349
350static void snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs *regs)
351{
352 struct snd_interwave *iwcard = (struct snd_interwave *) dev_id;
353 int loop, max = 5;
354
355 do {
356 loop = 0;
357 if (inb(iwcard->gus_status_reg)) {
358 snd_gus_interrupt(irq, iwcard->gus, regs);
359 loop++;
360 }
361 if (inb(iwcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
362 snd_cs4231_interrupt(irq, iwcard->cs4231, regs);
363 loop++;
364 }
365 } while (loop && --max > 0);
366}
367
368static void __init snd_interwave_reset(snd_gus_card_t * gus)
369{
370 snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00);
371 udelay(160);
372 snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x01);
373 udelay(160);
374}
375
376static void __init snd_interwave_bank_sizes(snd_gus_card_t * gus, int *sizes)
377{
378 unsigned int idx;
379 unsigned int local;
380 unsigned char d;
381
382 for (idx = 0; idx < 4; idx++) {
383 sizes[idx] = 0;
384 d = 0x55;
385 for (local = idx << 22;
386 local < (idx << 22) + 0x400000;
387 local += 0x40000, d++) {
388 snd_gf1_poke(gus, local, d);
389 snd_gf1_poke(gus, local + 1, d + 1);
390#if 0
391 printk("d = 0x%x, local = 0x%x, local + 1 = 0x%x, idx << 22 = 0x%x\n",
392 d,
393 snd_gf1_peek(gus, local),
394 snd_gf1_peek(gus, local + 1),
395 snd_gf1_peek(gus, idx << 22));
396#endif
397 if (snd_gf1_peek(gus, local) != d ||
398 snd_gf1_peek(gus, local + 1) != d + 1 ||
399 snd_gf1_peek(gus, idx << 22) != 0x55)
400 break;
401 sizes[idx]++;
402 }
403 }
404#if 0
405 printk("sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]);
406#endif
407}
408
409struct rom_hdr {
410 /* 000 */ unsigned char iwave[8];
411 /* 008 */ unsigned char rom_hdr_revision;
412 /* 009 */ unsigned char series_number;
413 /* 010 */ unsigned char series_name[16];
414 /* 026 */ unsigned char date[10];
415 /* 036 */ unsigned short vendor_revision_major;
416 /* 038 */ unsigned short vendor_revision_minor;
417 /* 040 */ unsigned int rom_size;
418 /* 044 */ unsigned char copyright[128];
419 /* 172 */ unsigned char vendor_name[64];
420 /* 236 */ unsigned char rom_description[128];
421 /* 364 */ unsigned char pad[147];
422 /* 511 */ unsigned char csum;
423};
424
425static void __init snd_interwave_detect_memory(snd_gus_card_t * gus)
426{
427 static unsigned int lmc[13] =
428 {
429 0x00000001, 0x00000101, 0x01010101, 0x00000401,
430 0x04040401, 0x00040101, 0x04040101, 0x00000004,
431 0x00000404, 0x04040404, 0x00000010, 0x00001010,
432 0x10101010
433 };
434
435 int bank_pos, pages;
436 unsigned int i, lmct;
437 int psizes[4];
438 unsigned char csum;
439 struct rom_hdr romh;
440
441 snd_interwave_reset(gus);
442 snd_gf1_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01); /* enhanced mode */
443 snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01); /* DRAM I/O cycles selected */
444 snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff10) | 0x004c);
445 /* ok.. simple test of memory size */
446 pages = 0;
447 snd_gf1_poke(gus, 0, 0x55);
448 snd_gf1_poke(gus, 1, 0xaa);
449#if 1
450 if (snd_gf1_peek(gus, 0) == 0x55 && snd_gf1_peek(gus, 1) == 0xaa)
451#else
452 if (0) /* ok.. for testing of 0k RAM */
453#endif
454 {
455 snd_interwave_bank_sizes(gus, psizes);
456 lmct = (psizes[3] << 24) | (psizes[2] << 16) |
457 (psizes[1] << 8) | psizes[0];
458#if 0
459 printk("lmct = 0x%08x\n", lmct);
460#endif
461 for (i = 0; i < sizeof(lmc) / sizeof(unsigned int); i++)
462 if (lmct == lmc[i]) {
463#if 0
464 printk("found !!! %i\n", i);
465#endif
466 snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i);
467 snd_interwave_bank_sizes(gus, psizes);
468 break;
469 }
470 if (i >= sizeof(lmc) / sizeof(unsigned int) && !gus->gf1.enh_mode)
471 snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | 2);
472 for (i = 0; i < 4; i++) {
473 gus->gf1.mem_alloc.banks_8[i].address =
474 gus->gf1.mem_alloc.banks_16[i].address = i << 22;
475 gus->gf1.mem_alloc.banks_8[i].size =
476 gus->gf1.mem_alloc.banks_16[i].size = psizes[i] << 18;
477 pages += psizes[i];
478 }
479 }
480 pages <<= 18;
481 gus->gf1.memory = pages;
482
483 snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x03); /* select ROM */
484 snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff1f) | (4 << 5));
485 gus->gf1.rom_banks = 0;
486 gus->gf1.rom_memory = 0;
487 for (bank_pos = 0; bank_pos < 16L * 1024L * 1024L; bank_pos += 4L * 1024L * 1024L) {
488 for (i = 0; i < sizeof(struct rom_hdr); i++)
489 *(((unsigned char *) &romh) + i) = snd_gf1_peek(gus, i + bank_pos);
490#ifdef CONFIG_SND_DEBUG_ROM
491 printk("ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
492 romh.iwave[0], romh.iwave[1], romh.iwave[2], romh.iwave[3],
493 romh.iwave[4], romh.iwave[5], romh.iwave[6], romh.iwave[7]);
494#endif
495 if (strncmp(romh.iwave, "INTRWAVE", 8))
496 continue; /* first check */
497 csum = 0;
498 for (i = 0; i < sizeof(struct rom_hdr) - 1; i++)
499 csum += *(((unsigned char *) &romh) + i);
500#ifdef CONFIG_SND_DEBUG_ROM
501 printk("ROM checksum = 0x%x == 0x%x (computed)\n", romh.csum, (unsigned char) (256 - csum));
502#endif
503 if (256 - csum != romh.csum)
504 continue; /* not valid rom */
505 gus->gf1.rom_banks++;
506 gus->gf1.rom_present |= 1 << (bank_pos >> 22);
507#ifdef SNDRV_LITTLE_ENDIAN
508 gus->gf1.rom_memory = romh.rom_size;
509#else
510 gus->gf1.rom_memory = ((romh.rom_size >> 24) & 0x000000ff) |
511 ((romh.rom_size >> 8) & 0x0000ff00) |
512 ((romh.rom_size << 8) & 0x00ff0000) |
513 ((romh.rom_size << 24) & 0xff000000);
514#endif
515 }
516#if 0
517 if (gus->gf1.rom_memory > 0) {
518 if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)
519 gus->card->type = SNDRV_CARD_TYPE_IW_DYNASONIC;
520 }
521#endif
522 snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x00); /* select RAM */
523
524 if (!gus->gf1.enh_mode)
525 snd_interwave_reset(gus);
526}
527
528static void __init snd_interwave_init(int dev, snd_gus_card_t * gus)
529{
530 unsigned long flags;
531
532 /* ok.. some InterWave specific initialization */
533 spin_lock_irqsave(&gus->reg_lock, flags);
534 snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0x00);
535 snd_gf1_write8(gus, SNDRV_GF1_GB_COMPATIBILITY, 0x1f);
536 snd_gf1_write8(gus, SNDRV_GF1_GB_DECODE_CONTROL, 0x49);
537 snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, 0x11);
538 snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A, 0x00);
539 snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B, 0x30);
540 snd_gf1_write8(gus, SNDRV_GF1_GB_EMULATION_IRQ, 0x00);
541 spin_unlock_irqrestore(&gus->reg_lock, flags);
542 gus->equal_irq = 1;
543 gus->codec_flag = 1;
544 gus->interwave = 1;
545 gus->max_flag = 1;
546 gus->joystick_dac = snd_joystick_dac[dev];
547
548}
549
550#define INTERWAVE_CONTROLS (sizeof(snd_interwave_controls)/sizeof(snd_kcontrol_new_t))
551
552static snd_kcontrol_new_t snd_interwave_controls[] = {
553CS4231_DOUBLE("Master Playback Switch", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1),
554CS4231_DOUBLE("Master Playback Volume", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1),
555CS4231_DOUBLE("Mic Playback Switch", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1),
556CS4231_DOUBLE("Mic Playback Volume", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)
557};
558
559static int __init snd_interwave_mixer(cs4231_t *chip)
560{
561 snd_card_t *card = chip->card;
562 snd_ctl_elem_id_t id1, id2;
563 int idx, err;
564
565 memset(&id1, 0, sizeof(id1));
566 memset(&id2, 0, sizeof(id2));
567 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
568#if 0
569 /* remove mono microphone controls */
570 strcpy(id1.name, "Mic Playback Switch");
571 if ((err = snd_ctl_remove_id(card, &id1)) < 0)
572 return err;
573 strcpy(id1.name, "Mic Playback Volume");
574 if ((err = snd_ctl_remove_id(card, &id1)) < 0)
575 return err;
576#endif
577 /* add new master and mic controls */
578 for (idx = 0; idx < INTERWAVE_CONTROLS; idx++)
579 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0)
580 return err;
581 snd_cs4231_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f);
582 snd_cs4231_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f);
583 snd_cs4231_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f);
584 snd_cs4231_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f);
585 /* reassign AUXA to SYNTHESIZER */
586 strcpy(id1.name, "Aux Playback Switch");
587 strcpy(id2.name, "Synth Playback Switch");
588 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
589 return err;
590 strcpy(id1.name, "Aux Playback Volume");
591 strcpy(id2.name, "Synth Playback Volume");
592 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
593 return err;
594 /* reassign AUXB to CD */
595 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
596 strcpy(id2.name, "CD Playback Switch");
597 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
598 return err;
599 strcpy(id1.name, "Aux Playback Volume");
600 strcpy(id2.name, "CD Playback Volume");
601 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
602 return err;
603 return 0;
604}
605
606#ifdef __ISAPNP__
607
608static int __init snd_interwave_isapnp(int dev, struct snd_interwave *iwcard)
609{
610 const struct isapnp_card_id *id = snd_interwave_isapnp_id[dev];
611 struct isapnp_card *card = snd_interwave_isapnp_cards[dev];
612 struct isapnp_dev *pdev;
613
614 iwcard->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL);
615 if (iwcard->dev->active) {
616 iwcard->dev = NULL;
617 return -EBUSY;
618 }
619#ifdef SNDRV_STB
620 iwcard->devtc = isapnp_find_dev(card, id->devs[1].vendor, id->devs[1].function, NULL);
621 if (iwcard->devtc->active) {
622 iwcard->dev = iwcard->devtc = NULL;
623 return -EBUSY;
624 }
625#endif
626 /* Synth & Codec initialization */
627 pdev = iwcard->dev;
628 if (pdev->prepare(pdev)<0)
629 return -EAGAIN;
630 if (snd_port[dev] != SNDRV_AUTO_PORT) {
631 isapnp_resource_change(&pdev->resource[0], snd_port[dev], 16);
632 isapnp_resource_change(&pdev->resource[1], snd_port[dev] + 0x100, 12);
633 isapnp_resource_change(&pdev->resource[2], snd_port[dev] + 0x10c, 4);
634 }
635 if (snd_dma1[dev] != SNDRV_AUTO_DMA)
636 isapnp_resource_change(&pdev->dma_resource[0], snd_dma1[dev], 1);
637 if (snd_dma2[dev] != SNDRV_AUTO_DMA)
638 isapnp_resource_change(&pdev->dma_resource[1], snd_dma2[dev], 1);
639 if (snd_dma2[dev] < 0)
640 isapnp_resource_change(&pdev->dma_resource[1], 4, 1);
641 if (snd_irq[dev] != SNDRV_AUTO_IRQ)
642 isapnp_resource_change(&pdev->irq_resource[0], snd_irq[dev], 1);
643 if (pdev->activate(pdev)<0) {
644 snd_printk("isapnp configure failure (out of resources?)\n");
645 return -EBUSY;
646 }
647 if (pdev->resource[0].start + 0x100 != pdev->resource[1].start ||
648 pdev->resource[0].start + 0x10c != pdev->resource[2].start) {
649 snd_printk("isapnp configure failure (wrong ports)\n");
650 pdev->deactivate(pdev);
651 return -ENOENT;
652 }
653 snd_port[dev] = pdev->resource[0].start;
654 snd_dma1[dev] = pdev->dma_resource[0].start;
655 if (snd_dma2[dev] >= 0)
656 snd_dma2[dev] = pdev->dma_resource[1].start;
657 snd_irq[dev] = pdev->irq_resource[0].start;
658 snd_printdd("isapnp IW: sb port=0x%lx, gf1 port=0x%lx, codec port=0x%lx\n",
659 pdev->resource[0].start,
660 pdev->resource[1].start,
661 pdev->resource[2].start);
662 snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", snd_dma1[dev], snd_dma2[dev], snd_irq[dev]);
663#ifdef SNDRV_STB
664 /* Tone Control initialization */
665 pdev = iwcard->devtc;
666 if (pdev->prepare(pdev)<0) {
667 iwcard->dev->deactivate(iwcard->dev);
668 return -EAGAIN;
669 }
670 if (snd_port_tc[dev] != SNDRV_AUTO_PORT)
671 isapnp_resource_change(&pdev->resource[0], snd_port_tc[dev], 1);
672 if (pdev->activate(pdev)<0) {
673 snd_printk("Tone Control isapnp configure failure (out of resources?)\n");
674 iwcard->dev->deactivate(iwcard->dev);
675 return -EBUSY;
676 }
677 snd_port_tc[dev] = pdev->resource[0].start;
678 snd_printdd("isapnp IW: tone control port=0x%lx\n", snd_port_tc[dev]);
679#endif
680 return 0;
681}
682
683static void snd_interwave_deactivate(struct snd_interwave *iwcard)
684{
685 if (iwcard->dev) {
686 iwcard->dev->deactivate(iwcard->dev);
687 iwcard->dev = NULL;
688 }
689#ifdef SNDRV_STB
690 if (iwcard->devtc) {
691 iwcard->devtc->deactivate(iwcard->devtc);
692 iwcard->devtc = NULL;
693 }
694#endif
695}
696
697#endif /* __ISAPNP__ */
698
699static void snd_interwave_free(snd_card_t *card)
700{
701 struct snd_interwave *iwcard = (struct snd_interwave *)card->private_data;
702
703 if (iwcard == NULL)
704 return;
705#ifdef __ISAPNP__
706 snd_interwave_deactivate(iwcard);
707#endif
708#ifdef SNDRV_STB
709 if (iwcard->i2c_res)
710 release_resource(iwcard->i2c_res);
711#endif
712 if (iwcard->irq >= 0)
713 free_irq(iwcard->irq, (void *)iwcard);
714}
715
716static int __init snd_interwave_probe(int dev)
717{
718 static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
719 static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
720 int irq, dma1, dma2;
721 snd_card_t *card;
722 struct snd_interwave *iwcard;
723 cs4231_t *cs4231;
724 snd_gus_card_t *gus;
725#ifdef SNDRV_STB
726 snd_i2c_bus_t *i2c_bus;
727#endif
728 snd_pcm_t *pcm;
729 char *str;
730 int err;
731
732 card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE,
733 sizeof(struct snd_interwave));
734 if (card == NULL)
735 return -ENOMEM;
736 iwcard = (struct snd_interwave *)card->private_data;
737 iwcard->card = card;
738 iwcard->irq = -1;
739 card->private_free = snd_interwave_free;
740#ifdef __ISAPNP__
741 if (snd_isapnp[dev] && snd_interwave_isapnp(dev, iwcard)) {
742 snd_card_free(card);
743 return -ENODEV;
744 }
745#endif
746 irq = snd_irq[dev];
747 if (irq == SNDRV_AUTO_IRQ) {
748 if ((irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
749 snd_card_free(card);
750 snd_printk("unable to find a free IRQ\n");
751 return -EBUSY;
752 }
753 }
754 dma1 = snd_dma1[dev];
755 if (dma1 == SNDRV_AUTO_DMA) {
756 if ((dma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
757 snd_card_free(card);
758 snd_printk("unable to find a free DMA1\n");
759 return -EBUSY;
760 }
761 }
762 dma2 = snd_dma2[dev];
763 if (dma2 == SNDRV_AUTO_DMA) {
764 if ((dma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
765 snd_card_free(card);
766 snd_printk("unable to find a free DMA2\n");
767 return -EBUSY;
768 }
769 }
770
771 if ((err = snd_gus_create(card,
772 snd_port[dev],
773 -irq, dma1, dma2,
774 0, 32,
775 snd_pcm_channels[dev], snd_effect[dev], &gus)) < 0) {
776 snd_card_free(card);
777 return err;
778 }
779 if ((err = snd_interwave_detect(iwcard, gus, dev
780#ifdef SNDRV_STB
781 , &i2c_bus
782#endif
783 )) < 0) {
784 snd_card_free(card);
785 return err;
786 }
787 iwcard->gus_status_reg = gus->gf1.reg_irqstat;
788 iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
789
790 snd_interwave_init(dev, gus);
791 snd_interwave_detect_memory(gus);
792 if ((err = snd_gus_initialize(gus)) < 0) {
793 snd_card_free(card);
794 return err;
795 }
796
797 if (request_irq(irq, snd_interwave_interrupt, SA_INTERRUPT, "InterWave", (void *)iwcard)) {
798 snd_card_free(card);
799 snd_printk("unable to grab IRQ %d\n", irq);
800 return -EBUSY;
801 }
802 iwcard->irq = irq;
803
804 if ((err = snd_cs4231_create(card,
805 gus->gf1.port + 0x10c, -1, irq,
806 dma2 < 0 ? dma1 : dma2, dma1,
807 CS4231_HW_INTERWAVE,
808 CS4231_HWSHARE_IRQ |
809 CS4231_HWSHARE_DMA1 |
810 CS4231_HWSHARE_DMA2,
811 &cs4231)) < 0) {
812 snd_card_free(card);
813 return err;
814 }
815 if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) {
816 snd_card_free(card);
817 return err;
818 }
819 sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
820 strcat(pcm->name, " (chip)");
821 if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) {
822 snd_card_free(card);
823 return err;
824 }
825 if ((err = snd_cs4231_mixer(cs4231)) < 0) {
826 snd_card_free(card);
827 return err;
828 }
829 if (snd_pcm_channels[dev] > 0) {
830 if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) {
831 snd_card_free(card);
832 return err;
833 }
834 }
835 if ((err = snd_interwave_mixer(cs4231)) < 0) {
836 snd_card_free(card);
837 return err;
838 }
839#ifdef SNDRV_STB
840 {
841 snd_ctl_elem_id_t id1, id2;
842 memset(&id1, 0, sizeof(id1));
843 memset(&id2, 0, sizeof(id2));
844 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
845 strcpy(id1.name, "Master Playback Switch");
846 strcpy(id2.name, id1.name);
847 id2.index = 1;
848 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
849 snd_card_free(card);
850 return err;
851 }
852 strcpy(id1.name, "Master Playback Volume");
853 strcpy(id2.name, id1.name);
854 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
855 snd_card_free(card);
856 return err;
857 }
858 if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0) {
859 snd_card_free(card);
860 return err;
861 }
862 }
863#endif
864
865 gus->uart_enable = snd_midi[dev];
866 if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
867 snd_card_free(card);
868 return err;
869 }
870
871#ifndef SNDRV_STB
872 str = "AMD InterWave";
873 if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)
874 str = "Dynasonic 3-D";
875#else
876 str = "InterWave STB";
877#endif
878 strcpy(card->driver, str);
879 strcpy(card->shortname, str);
880 sprintf(card->longname, "%s at 0x%lx, irq %i, dma %d",
881 str,
882 gus->gf1.port,
883 irq,
884 dma1);
885 if (dma2 >= 0)
886 sprintf(card->longname + strlen(card->longname), "&%d", dma2);
887
888 if ((err = snd_card_register(card)) < 0) {
889 snd_card_free(card);
890 return err;
891 }
892
893 iwcard->cs4231 = cs4231;
894 iwcard->gus = gus;
895 snd_interwave_cards[dev++] = card;
896 return 0;
897}
898
899static int __init snd_interwave_probe_legacy_port(unsigned long port)
900{
901 static int dev = 0;
902 int res;
903
904 for ( ; dev < SNDRV_CARDS; dev++) {
905 if (!snd_enable[dev] || snd_port[dev] != SNDRV_AUTO_PORT)
906 continue;
907#ifdef __ISAPNP__
908 if (snd_isapnp[dev])
909 continue;
910#endif
911 snd_port[dev] = port;
912 res = snd_interwave_probe(dev);
913 if (res < 0)
914 snd_port[dev] = SNDRV_AUTO_PORT;
915 return res;
916 }
917 return -ENODEV;
918}
919
920#ifdef __ISAPNP__
921
922static int __init snd_interwave_isapnp_detect(struct isapnp_card *card,
923 const struct isapnp_card_id *id)
924{
925 static int dev = 0;
926 int res;
927
928 for ( ; dev < SNDRV_CARDS; dev++) {
929 if (!snd_enable[dev] || !snd_isapnp[dev])
930 continue;
931 snd_interwave_isapnp_cards[dev] = card;
932 snd_interwave_isapnp_id[dev] = id;
933 res = snd_interwave_probe(dev);
934 if (res < 0)
935 return res;
936 dev++;
937 return 0;
938 }
939
940 return -ENODEV;
941}
942
943#endif /* __ISAPNP__ */
944
945static int __init alsa_card_interwave_init(void)
946{
947 int cards = 0;
948 static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260, -1};
949 int dev;
950
951 for (dev = 0; dev < SNDRV_CARDS; dev++) {
952 if (!snd_enable[dev] || snd_port[dev] == SNDRV_AUTO_PORT)
953 continue;
954#ifdef __ISAPNP__
955 if (snd_isapnp[dev])
956 continue;
957#endif
958 if (!snd_interwave_probe(dev)) {
959 cards++;
960 continue;
961 }
962#ifdef MODULE
963 snd_printk("InterWave soundcard #%i not found at 0x%lx or device busy\n", dev, snd_port[dev]);
964#endif
965 }
966 /* legacy auto configured cards */
967 cards += snd_legacy_auto_probe(possible_ports, snd_interwave_probe_legacy_port);
968#ifdef __ISAPNP__
969 /* ISA PnP cards */
970 cards += isapnp_probe_cards(snd_interwave_pnpids, snd_interwave_isapnp_detect);
971#endif
972
973 if (!cards) {
974#ifdef MODULE
975 snd_printk("InterWave soundcard not found or device busy\n");
976#endif
977 return -ENODEV;
978 }
979 return 0;
980}
981
982static void __exit alsa_card_interwave_exit(void)
983{
984 int dev;
985
986 for (dev = 0; dev < SNDRV_CARDS; dev++)
987 snd_card_free(snd_interwave_cards[dev]);
988}
989
990module_init(alsa_card_interwave_init)
991module_exit(alsa_card_interwave_exit)
992
993#ifndef MODULE
994
995/* format is: snd-card-interwave=snd_enable,snd_index,snd_id,snd_isapnp,
996 snd_port[,snd_port_tc],snd_irq,
997 snd_dma1,snd_dma2,
998 snd_joystick_dac,snd_midi,
999 snd_pcm_channels,snd_effect */
1000
1001static int __init alsa_card_interwave_setup(char *str)
1002{
1003 static unsigned __initdata nr_dev = 0;
1004 int __attribute__ ((__unused__)) pnp = INT_MAX;
1005
1006 if (nr_dev >= SNDRV_CARDS)
1007 return 0;
1008 (void)(get_option(&str,&snd_enable[nr_dev]) == 2 &&
1009 get_option(&str,&snd_index[nr_dev]) == 2 &&
1010 get_id(&str,&snd_id[nr_dev]) == 2 &&
1011 get_option(&str,&pnp) == 2 &&
1012 get_option(&str,(int *)&snd_port[nr_dev]) == 2 &&
1013#ifdef SNDRV_STB
1014 get_option(&str,(int *)&snd_port_tc[nr_dev]) == 2 &&
1015#endif
1016 get_option(&str,&snd_irq[nr_dev]) == 2 &&
1017 get_option(&str,&snd_dma1[nr_dev]) == 2 &&
1018 get_option(&str,&snd_dma2[nr_dev]) == 2 &&
1019 get_option(&str,&snd_joystick_dac[nr_dev]) == 2 &&
1020 get_option(&str,&snd_midi[nr_dev]) == 2 &&
1021 get_option(&str,&snd_pcm_channels[nr_dev]) == 2 &&
1022 get_option(&str,&snd_effect[nr_dev]) == 2);
1023#ifdef __ISAPNP__
1024 if (pnp != INT_MAX)
1025 snd_isapnp[nr_dev] = pnp;
1026#endif
1027 nr_dev++;
1028 return 1;
1029}
1030
1031#ifndef SNDRV_STB
1032__setup("snd-card-interwave=", alsa_card_interwave_setup);
1033#else
1034__setup("snd-card-interwave-stb=", alsa_card_interwave_setup);
1035#endif
1036
1037#endif /* ifndef MODULE */
Note: See TracBrowser for help on using the repository browser.