Revert last change. Bug noticed by Linus.
[linux-2.6/linux-mips.git] / drivers / sound / sb_card.c
blobf66c0b6048279aee9545203ff61b12cdc7eec559
1 /*
2 * sound/sb_card.c
4 * Detection routine for the Sound Blaster cards.
7 * Copyright (C) by Hannu Savolainen 1993-1997
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
13 * 26-11-1999 Patched to compile without ISA PnP support in the
14 * kernel - Daniel Stone (tamriel@ductape.net)
16 * 06-01-2000 Refined and bugfixed ISA PnP support, added
17 * CMI 8330 support - Alessandro Zummo <azummo@ita.flashnet.it>
19 * 18-01-2000 Separated sb_card and sb_common
20 * Jeff Garzik <jgarzik@mandrakesoft.com>
22 * 04-02-2000 Added Soundblaster AWE 64 PnP support, isapnpjump
23 * Alessandro Zummo <azummo@ita.flashnet.it>
25 * 11-02-2000 Added Soundblaster AWE 32 PnP support, refined PnP code
26 * Alessandro Zummo <azummo@ita.flashnet.it>
28 * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup
29 * Alessandro Zummo <azummo@ita.flashnet.it>
31 * 13-03-2000 Added some more cards, thanks to Torsten Werner.
32 * Removed joystick and wavetable code, there are better places for them.
33 * Code cleanup plus some fixes.
34 * Alessandro Zummo <azummo@ita.flashnet.it>
36 * 26-03-2000 Fixed acer, esstype and sm_games module options.
37 * Alessandro Zummo <azummo@ita.flashnet.it>
39 * 12-04-2000 ISAPnP cleanup, reorg, fixes, and multiple card support.
40 * Thanks to Gaël Quéri and Alessandro Zummo for testing and fixes.
41 * Paul E. Laufer <pelaufer@csupomona.edu>
43 * 06-05-2000 added another card. Daniel M. Newman <dmnewman@pobox.com>
45 * 25-05-2000 Added Creative SB AWE64 Gold (CTL00B2).
46 * Pål-Kristian Engstad <engstad@att.net>
50 #include <linux/config.h>
51 #include <linux/mca.h>
52 #include <linux/module.h>
53 #include <linux/init.h>
54 #include <linux/isapnp.h>
56 #include "sound_config.h"
57 #include "soundmodule.h"
59 #include "sb_mixer.h"
60 #include "sb.h"
62 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
63 #define SB_CARDS_MAX 4
64 #else
65 #define SB_CARDS_MAX 1
66 #endif
68 static int sbmpu[SB_CARDS_MAX] = {0};
69 static int sb_cards_num = 0;
71 extern void *smw_free;
74 * Note DMA2 of -1 has the right meaning in the SB16 driver as well
75 * as here. It will cause either an error if it is needed or a fallback
76 * to the 8bit channel.
79 static int __initdata mpu_io = 0;
80 static int __initdata io = -1;
81 static int __initdata irq = -1;
82 static int __initdata dma = -1;
83 static int __initdata dma16 = -1; /* Set this for modules that need it */
84 static int __initdata type = 0; /* Can set this to a specific card type */
85 static int __initdata esstype = 0; /* ESS chip type */
86 static int __initdata acer = 0; /* Do acer notebook init? */
87 static int __initdata sm_games = 0; /* Logitech soundman games? */
89 static void __init attach_sb_card(struct address_info *hw_config)
91 if(!sb_dsp_init(hw_config))
92 hw_config->slots[0] = -1;
95 static int __init probe_sb(struct address_info *hw_config)
97 struct sb_module_options sbmo;
99 if (hw_config->io_base == -1 || hw_config->dma == -1 || hw_config->irq == -1)
101 printk(KERN_ERR "sb: I/O, IRQ, and DMA are mandatory\n");
102 return -EINVAL;
105 #ifdef CONFIG_MCA
106 /* MCA code added by ZP Gu (zpg@castle.net) */
107 if (MCA_bus) { /* no multiple REPLY card probing */
108 int slot;
109 u8 pos2, pos3, pos4;
111 slot = mca_find_adapter( 0x5138, 0 );
112 if( slot == MCA_NOTFOUND )
114 slot = mca_find_adapter( 0x5137, 0 );
116 if (slot != MCA_NOTFOUND)
117 mca_set_adapter_name( slot, "REPLY SB16 & SCSI Adapter" );
119 else
121 mca_set_adapter_name( slot, "REPLY SB16 Adapter" );
124 if (slot != MCA_NOTFOUND)
126 mca_mark_as_used(slot);
127 pos2 = mca_read_stored_pos( slot, 2 );
128 pos3 = mca_read_stored_pos( slot, 3 );
129 pos4 = mca_read_stored_pos( slot, 4 );
131 if (pos2 & 0x4)
133 /* enabled? */
134 static unsigned short irq[] = { 0, 5, 7, 10 };
136 static unsigned short midiaddr[] = {0, 0x330, 0, 0x300 };
139 hw_config->io_base = 0x220 + 0x20 * (pos2 >> 6);
140 hw_config->irq = irq[(pos4 >> 5) & 0x3];
141 hw_config->dma = pos3 & 0xf;
142 /* Reply ADF wrong on High DMA, pos[1] should start w/ 00 */
143 hw_config->dma2 = (pos3 >> 4) & 0x3;
144 if (hw_config->dma2 == 0)
145 hw_config->dma2 = hw_config->dma;
146 else
147 hw_config->dma2 += 4;
149 hw_config->driver_use_2 = midiaddr[(pos2 >> 3) & 0x3];
152 printk(KERN_INFO "sb: Reply MCA SB at slot=%d \
153 iobase=0x%x irq=%d lo_dma=%d hi_dma=%d\n",
154 slot+1,
155 hw_config->io_base, hw_config->irq,
156 hw_config->dma, hw_config->dma2);
158 else
160 printk (KERN_INFO "sb: Reply SB Base I/O address disabled\n");
164 #endif
166 /* Setup extra module options */
168 sbmo.acer = acer;
169 sbmo.sm_games = sm_games;
170 sbmo.esstype = esstype;
172 return sb_dsp_detect(hw_config, 0, 0, &sbmo);
175 static void __exit unload_sb(struct address_info *hw_config, int card)
177 if(hw_config->slots[0]!=-1)
178 sb_dsp_unload(hw_config, sbmpu[card]);
181 static struct address_info cfg[SB_CARDS_MAX];
182 static struct address_info cfg_mpu[SB_CARDS_MAX];
184 struct pci_dev *sb_dev[SB_CARDS_MAX] = {NULL},
185 *mpu_dev[SB_CARDS_MAX] = {NULL},
186 *opl_dev[SB_CARDS_MAX] = {NULL};
189 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
190 static int isapnp = 1;
191 static int isapnpjump = 0;
192 static int multiple = 0;
193 static int reverse = 0;
194 static int uart401 = 0;
196 static int audio_activated[SB_CARDS_MAX] = {0};
197 static int mpu_activated[SB_CARDS_MAX] = {0};
198 static int opl_activated[SB_CARDS_MAX] = {0};
199 #else
200 static int isapnp = 0;
201 static int multiple = 1;
202 #endif
204 MODULE_DESCRIPTION("Soundblaster driver");
206 MODULE_PARM(io, "i");
207 MODULE_PARM(irq, "i");
208 MODULE_PARM(dma, "i");
209 MODULE_PARM(dma16, "i");
210 MODULE_PARM(mpu_io, "i");
211 MODULE_PARM(type, "i");
212 MODULE_PARM(sm_games, "i");
213 MODULE_PARM(esstype, "i");
214 MODULE_PARM(acer, "i");
216 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
217 MODULE_PARM(isapnp, "i");
218 MODULE_PARM(isapnpjump, "i");
219 MODULE_PARM(multiple, "i");
220 MODULE_PARM(reverse, "i");
221 MODULE_PARM(uart401, "i");
222 MODULE_PARM_DESC(isapnp, "When set to 0, Plug & Play support will be disabled");
223 MODULE_PARM_DESC(isapnpjump, "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
224 MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
225 MODULE_PARM_DESC(reverse, "When set to 1, will reverse ISAPnP search order");
226 MODULE_PARM_DESC(uart401, "When set to 1, will attempt to detect and enable the mpu on some clones");
227 #endif
229 MODULE_PARM_DESC(io, "Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
230 MODULE_PARM_DESC(irq, "IRQ (5,7,9,10)");
231 MODULE_PARM_DESC(dma, "8-bit DMA channel (0,1,3)");
232 MODULE_PARM_DESC(dma16, "16-bit DMA channel (5,6,7)");
233 MODULE_PARM_DESC(mpu_io, "Mpu base address");
234 MODULE_PARM_DESC(type, "You can set this to specific card type");
235 MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games");
236 MODULE_PARM_DESC(esstype, "ESS chip type");
237 MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks");
239 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
241 /* Please add new entries at the end of the table */
242 static struct {
243 char *name;
244 unsigned short card_vendor, card_device,
245 audio_vendor, audio_function,
246 mpu_vendor, mpu_function,
247 opl_vendor, opl_function;
248 short dma, dma2, mpu_io, mpu_irq; /* see sb_init() */
249 } sb_isapnp_list[] __initdata = {
250 {"Sound Blaster 16",
251 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
252 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
253 0,0,0,0,
254 0,1,1,-1},
255 {"Sound Blaster 16",
256 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0025),
257 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
258 0,0,0,0,
259 0,1,1,-1},
260 {"Sound Blaster 16",
261 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026),
262 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
263 0,0,0,0,
264 0,1,1,-1},
265 {"Sound Blaster 16",
266 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027),
267 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
268 0,0,0,0,
269 0,1,1,-1},
270 {"Sound Blaster 16",
271 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028),
272 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
273 0,0,0,0,
274 0,1,1,-1},
275 {"Sound Blaster 16",
276 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029),
277 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
278 0,0,0,0,
279 0,1,1,-1},
280 {"Sound Blaster 16",
281 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
282 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
283 0,0,0,0,
284 0,1,1,-1},
285 {"Sound Blaster 16",
286 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b),
287 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
288 0,0,0,0,
289 0,1,1,-1},
290 {"Sound Blaster Vibra16S",
291 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051),
292 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
293 0,0,0,0,
294 0,1,1,-1},
295 {"Sound Blaster Vibra16C",
296 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070),
297 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
298 0,0,0,0,
299 0,1,1,-1},
300 {"Sound Blaster Vibra16CL",
301 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080),
302 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
303 0,0,0,0,
304 0,1,1,-1},
305 {"Sound Blaster Vibra16X",
306 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0),
307 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043),
308 0,0,0,0,
309 0,1,1,-1},
310 {"Sound Blaster AWE 32",
311 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039),
312 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
313 0,0,0,0,
314 0,1,1,-1},
315 {"Sound Blaster AWE 32",
316 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
317 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
318 0,0,0,0,
319 0,1,1,-1},
320 {"Sound Blaster AWE 32",
321 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
322 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
323 0,0,0,0,
324 0,1,1,-1},
325 {"Sound Blaster AWE 32",
326 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
327 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
328 0,0,0,0,
329 0,1,1,-1},
330 {"Sound Blaster AWE 32",
331 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048),
332 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
333 0,0,0,0,
334 0,1,1,-1},
335 {"Sound Blaster AWE 32",
336 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054),
337 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
338 0,0,0,0,
339 0,1,1,-1},
340 {"Sound Blaster AWE 32",
341 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C),
342 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
343 0,0,0,0,
344 0,1,1,-1},
345 {"Sound Blaster AWE 64",
346 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D),
347 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
348 0,0,0,0,
349 0,1,1,-1},
350 {"Sound Blaster AWE 64 Gold",
351 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E),
352 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
353 0,0,0,0,
354 0,1,1,-1},
355 {"Sound Blaster AWE 64 Gold",
356 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
357 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
358 0,0,0,0,
359 0,1,1,-1},
360 {"Sound Blaster AWE 64",
361 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1),
362 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
363 0,0,0,0,
364 0,1,1,-1},
365 {"Sound Blaster AWE 64",
366 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3),
367 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
368 0,0,0,0,
369 0,1,1,-1},
370 {"Sound Blaster AWE 64",
371 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5),
372 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
373 0,0,0,0,
374 0,1,1,-1},
375 {"Sound Blaster AWE 64",
376 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7),
377 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
378 0,0,0,0,
379 0,1,1,-1},
380 {"Sound Blaster AWE 64",
381 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
382 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
383 0,0,0,0,
384 0,1,1,-1},
385 {"ESS 1688",
386 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
387 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
388 0,0,0,0,
389 0,1,2,-1},
390 {"ESS 1868",
391 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
392 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868),
393 0,0,0,0,
394 0,1,2,-1},
395 {"ESS 1868",
396 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
397 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611),
398 0,0,0,0,
399 0,1,2,-1},
400 {"ESS 1869 PnP AudioDrive",
401 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003),
402 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
403 0,0,0,0,
404 0,1,2,-1},
405 {"ESS 1869",
406 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869),
407 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
408 0,0,0,0,
409 0,1,2,-1},
410 {"ESS 1878",
411 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878),
412 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878),
413 0,0,0,0,
414 0,1,2,-1},
415 {"ESS 1879",
416 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879),
417 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879),
418 0,0,0,0,
419 0,1,2,-1},
420 {"CMI 8330 SoundPRO",
421 ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
422 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
423 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
424 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
425 0,1,0,-1},
426 {"Diamond DT0197H",
427 ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
428 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
429 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
430 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
431 0,-1,0,0},
432 {"ALS007",
433 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
434 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
435 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
436 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
437 0,-1,0,0},
438 {"ALS100",
439 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
440 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
441 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
442 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
443 1,0,0,0},
444 {"ALS110",
445 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
446 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001),
447 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001),
448 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
449 1,0,0,0},
450 {"ALS120",
451 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
452 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
453 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
454 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
455 1,0,0,0},
456 {"ALS200",
457 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
458 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020),
459 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020),
460 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
461 1,0,0,0},
462 {"RTL3000",
463 ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
464 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
465 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
466 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
467 1,0,0,0},
471 /* That's useful. */
473 #define show_base(devname, resname, resptr) printk(KERN_INFO "sb: %s %s base located at %#lx\n", devname, resname, (resptr)->start)
475 static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
477 int err;
479 /* Device already active? Let's use it */
480 if(dev->active)
481 return(dev);
483 if((err = dev->activate(dev)) < 0) {
484 printk(KERN_ERR "sb: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
486 dev->deactivate(dev);
488 return(NULL);
490 return(dev);
493 static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_config, struct address_info *mpu_config, int slot, int card)
496 /* Configure Audio device */
497 if((sb_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].audio_vendor, sb_isapnp_list[slot].audio_function, NULL)))
499 int ret;
500 ret = sb_dev[card]->prepare(sb_dev[card]);
501 /* If device is active, assume configured with /proc/isapnp
502 * and use anyway. Some other way to check this? */
503 if(ret && ret != -EBUSY) {
504 printk(KERN_ERR "sb: ISAPnP found device that could not be autoconfigured.\n");
505 return(NULL);
507 if(ret == -EBUSY)
508 audio_activated[card] = 1;
510 if((sb_dev[card] = activate_dev(sb_isapnp_list[slot].name, "sb", sb_dev[card])))
512 hw_config->io_base = sb_dev[card]->resource[0].start;
513 hw_config->irq = sb_dev[card]->irq_resource[0].start;
514 hw_config->dma = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma].start;
515 if(sb_isapnp_list[slot].dma2 != -1)
516 hw_config->dma2 = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma2].start;
517 else
518 hw_config->dma2 = -1;
519 } else
520 return(NULL);
521 } else
522 return(NULL);
524 /* Cards with separate OPL3 device (ALS, CMI, etc.)
525 * This is just to activate the device... */
526 if(sb_isapnp_list[slot].opl_vendor || sb_isapnp_list[slot].opl_function) {
527 if((opl_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].opl_vendor, sb_isapnp_list[slot].opl_function, NULL))) {
528 int ret = opl_dev[card]->prepare(opl_dev[card]);
529 /* If device is active, assume configured with
530 * /proc/isapnp and use anyway */
531 if(ret && ret != -EBUSY) {
532 printk(KERN_ERR "sb: OPL device could not be autoconfigured.\n");
533 return(sb_dev[card]);
535 if(ret == -EBUSY)
536 opl_activated[card] = 1;
538 /* Some have irq and dma for opl. the opl3 driver wont
539 * use 'em so don't configure 'em and hope it works -PEL */
540 opl_dev[card]->irq_resource[0].flags = 0;
541 opl_dev[card]->dma_resource[0].flags = 0;
543 opl_dev[card] = activate_dev(sb_isapnp_list[slot].name, "opl3", opl_dev[card]);
544 } else
545 printk(KERN_ERR "sb: %s isapnp panic: opl3 device not found\n", sb_isapnp_list[slot].name);
548 /* Cards with MPU as part of Audio device (CTL and ESS) */
549 if(!sb_isapnp_list[slot].mpu_vendor) {
550 mpu_config->io_base = sb_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
551 return(sb_dev[card]);
554 /* Cards with separate MPU device (ALS, CMI, etc.) */
555 if(!uart401)
556 return(sb_dev[card]);
557 if((mpu_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].mpu_vendor, sb_isapnp_list[slot].mpu_function, NULL)))
559 int ret = mpu_dev[card]->prepare(mpu_dev[card]);
560 /* If device is active, assume configured with /proc/isapnp
561 * and use anyway */
562 if(ret && ret != -EBUSY) {
563 printk(KERN_ERR "sb: MPU device could not be autoconfigured.\n");
564 return(sb_dev[card]);
566 if(ret == -EBUSY)
567 mpu_activated[card] = 1;
569 /* Some cards ask for irq but don't need them - azummo */
570 if(sb_isapnp_list[slot].mpu_irq == -1)
571 mpu_dev[card]->irq_resource[0].flags = 0;
573 if((mpu_dev[card] = activate_dev(sb_isapnp_list[slot].name, "mpu", mpu_dev[card]))) {
574 mpu_config->io_base = mpu_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
575 if(sb_isapnp_list[slot].mpu_irq != -1)
576 mpu_config->irq = mpu_dev[card]->irq_resource[sb_isapnp_list[slot].mpu_irq].start;
579 else
580 printk(KERN_ERR "sb: %s isapnp panic: mpu not found\n", sb_isapnp_list[slot].name);
582 return(sb_dev[card]);
585 static int __init sb_isapnp_init(struct address_info *hw_config, struct address_info *mpu_config, struct pci_bus *bus, int slot, int card)
587 char *busname = bus->name[0] ? bus->name : sb_isapnp_list[slot].name;
589 printk(KERN_INFO "sb: %s detected\n", busname);
591 /* Initialize this baby. */
593 if(sb_init(bus, hw_config, mpu_config, slot, card)) {
594 /* We got it. */
596 printk(KERN_NOTICE "sb: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
597 busname,
598 hw_config->io_base, hw_config->irq, hw_config->dma,
599 hw_config->dma2);
600 return 1;
602 else
603 printk(KERN_INFO "sb: Failed to initialize %s\n", busname);
605 return 0;
608 int __init sb_isapnp_probe(struct address_info *hw_config, struct address_info *mpu_config, int card)
610 static int first = 1;
611 int i;
613 /* Count entries in sb_isapnp_list */
614 for (i = 0; sb_isapnp_list[i].card_vendor != 0; i++);
615 i--;
617 /* Check and adjust isapnpjump */
618 if( isapnpjump < 0 || isapnpjump > i) {
619 isapnpjump = reverse ? i : 0;
620 printk(KERN_ERR "sb: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
623 if(!first || !reverse)
624 i = isapnpjump;
625 first = 0;
626 while(sb_isapnp_list[i].card_vendor != 0) {
627 static struct pci_bus *bus = NULL;
629 while ((bus = isapnp_find_card(
630 sb_isapnp_list[i].card_vendor,
631 sb_isapnp_list[i].card_device,
632 bus))) {
634 if(sb_isapnp_init(hw_config, mpu_config, bus, i, card)) {
635 isapnpjump = i; /* start next search from here */
636 return 0;
639 i += reverse ? -1 : 1;
642 return -ENODEV;
644 #endif
646 static int __init init_sb(void)
648 int card, max = multiple ? SB_CARDS_MAX : 1;
650 printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
652 for(card = 0; card < max; card++, sb_cards_num++) {
653 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
654 /* Please remember that even with CONFIG_ISAPNP defined one
655 * should still be able to disable PNP support for this
656 * single driver! */
657 if(isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
658 if(!sb_cards_num) {
659 printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n");
660 isapnp = 0;
661 } else
662 break;
664 #endif
666 if(!isapnp) {
667 cfg[card].io_base = io;
668 cfg[card].irq = irq;
669 cfg[card].dma = dma;
670 cfg[card].dma2 = dma16;
673 cfg[card].card_subtype = type;
675 if (!probe_sb(&cfg[card]))
676 return -ENODEV;
677 attach_sb_card(&cfg[card]);
679 if(cfg[card].slots[0]==-1)
680 return -ENODEV;
682 if (!isapnp)
683 cfg_mpu[card].io_base = mpu_io;
684 if (probe_sbmpu(&cfg_mpu[card]))
685 sbmpu[card] = 1;
686 if (sbmpu[card])
687 attach_sbmpu(&cfg_mpu[card]);
690 SOUND_LOCK;
692 if(isapnp)
693 printk(KERN_NOTICE "sb: %d Soundblaster PnP card(s) found.\n", sb_cards_num);
695 return 0;
698 static void __exit cleanup_sb(void)
700 int i;
702 if (smw_free) {
703 vfree(smw_free);
704 smw_free = NULL;
707 for(i = 0; i < sb_cards_num; i++) {
708 unload_sb(&cfg[i], i);
709 if (sbmpu[i])
710 unload_sbmpu(&cfg_mpu[i]);
712 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
713 if(!audio_activated[i] && sb_dev[i])
714 sb_dev[i]->deactivate(sb_dev[i]);
715 if(!mpu_activated[i] && mpu_dev[i])
716 mpu_dev[i]->deactivate(mpu_dev[i]);
717 if(!opl_activated[i] && opl_dev[i])
718 opl_dev[i]->deactivate(opl_dev[i]);
719 #endif
721 SOUND_LOCK_END;
724 module_init(init_sb);
725 module_exit(cleanup_sb);
727 #ifndef MODULE
728 static int __init setup_sb(char *str)
730 /* io, irq, dma, dma2 - just the basics */
731 int ints[5];
733 str = get_options(str, ARRAY_SIZE(ints), ints);
735 io = ints[1];
736 irq = ints[2];
737 dma = ints[3];
738 dma16 = ints[4];
740 return 1;
742 __setup("sb=", setup_sb);
743 #endif