Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / sound / sb_card.c
blob782bb46f16b43c3c6653b3ada46398d703cfdcba
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>
48 * 12-08-2000 Added Creative SB32 PnP (CTL009F).
49 * Kasatenko Ivan Alex. <skywriter@rnc.ru>
51 * 21-09-2000 Got rid of attach_sbmpu
52 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
54 * 28-10-2000 Added pnplegacy support
55 * Daniel Church <dchurch@mbhs.edu>
58 #include <linux/config.h>
59 #include <linux/mca.h>
60 #include <linux/module.h>
61 #include <linux/init.h>
62 #include <linux/isapnp.h>
64 #include "sound_config.h"
66 #include "sb_mixer.h"
67 #include "sb.h"
69 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
70 #define SB_CARDS_MAX 5
71 #else
72 #define SB_CARDS_MAX 1
73 #endif
75 static int sbmpu[SB_CARDS_MAX] = {0};
76 static int sb_cards_num = 0;
78 extern void *smw_free;
81 * Note DMA2 of -1 has the right meaning in the SB16 driver as well
82 * as here. It will cause either an error if it is needed or a fallback
83 * to the 8bit channel.
86 static int __initdata mpu_io = 0;
87 static int __initdata io = -1;
88 static int __initdata irq = -1;
89 static int __initdata dma = -1;
90 static int __initdata dma16 = -1; /* Set this for modules that need it */
91 static int __initdata type = 0; /* Can set this to a specific card type */
92 static int __initdata esstype = 0; /* ESS chip type */
93 static int __initdata acer = 0; /* Do acer notebook init? */
94 static int __initdata sm_games = 0; /* Logitech soundman games? */
96 static void __init attach_sb_card(struct address_info *hw_config)
98 if(!sb_dsp_init(hw_config, THIS_MODULE))
99 hw_config->slots[0] = -1;
102 static int __init probe_sb(struct address_info *hw_config)
104 struct sb_module_options sbmo;
106 if (hw_config->io_base == -1 || hw_config->dma == -1 || hw_config->irq == -1)
108 printk(KERN_ERR "sb: I/O, IRQ, and DMA are mandatory\n");
109 return -EINVAL;
112 #ifdef CONFIG_MCA
113 /* MCA code added by ZP Gu (zpg@castle.net) */
114 if (MCA_bus) { /* no multiple REPLY card probing */
115 int slot;
116 u8 pos2, pos3, pos4;
118 slot = mca_find_adapter( 0x5138, 0 );
119 if( slot == MCA_NOTFOUND )
121 slot = mca_find_adapter( 0x5137, 0 );
123 if (slot != MCA_NOTFOUND)
124 mca_set_adapter_name( slot, "REPLY SB16 & SCSI Adapter" );
126 else
128 mca_set_adapter_name( slot, "REPLY SB16 Adapter" );
131 if (slot != MCA_NOTFOUND)
133 mca_mark_as_used(slot);
134 pos2 = mca_read_stored_pos( slot, 2 );
135 pos3 = mca_read_stored_pos( slot, 3 );
136 pos4 = mca_read_stored_pos( slot, 4 );
138 if (pos2 & 0x4)
140 /* enabled? */
141 static unsigned short irq[] = { 0, 5, 7, 10 };
143 static unsigned short midiaddr[] = {0, 0x330, 0, 0x300 };
146 hw_config->io_base = 0x220 + 0x20 * (pos2 >> 6);
147 hw_config->irq = irq[(pos4 >> 5) & 0x3];
148 hw_config->dma = pos3 & 0xf;
149 /* Reply ADF wrong on High DMA, pos[1] should start w/ 00 */
150 hw_config->dma2 = (pos3 >> 4) & 0x3;
151 if (hw_config->dma2 == 0)
152 hw_config->dma2 = hw_config->dma;
153 else
154 hw_config->dma2 += 4;
156 hw_config->driver_use_2 = midiaddr[(pos2 >> 3) & 0x3];
159 printk(KERN_INFO "sb: Reply MCA SB at slot=%d \
160 iobase=0x%x irq=%d lo_dma=%d hi_dma=%d\n",
161 slot+1,
162 hw_config->io_base, hw_config->irq,
163 hw_config->dma, hw_config->dma2);
165 else
167 printk (KERN_INFO "sb: Reply SB Base I/O address disabled\n");
171 #endif
173 /* Setup extra module options */
175 sbmo.acer = acer;
176 sbmo.sm_games = sm_games;
177 sbmo.esstype = esstype;
179 return sb_dsp_detect(hw_config, 0, 0, &sbmo);
182 static void __exit unload_sb(struct address_info *hw_config, int card)
184 if(hw_config->slots[0]!=-1)
185 sb_dsp_unload(hw_config, sbmpu[card]);
188 static struct address_info cfg[SB_CARDS_MAX];
189 static struct address_info cfg_mpu[SB_CARDS_MAX];
191 struct pci_dev *sb_dev[SB_CARDS_MAX] = {NULL},
192 *mpu_dev[SB_CARDS_MAX] = {NULL},
193 *opl_dev[SB_CARDS_MAX] = {NULL};
196 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
197 static int isapnp = 1;
198 static int isapnpjump = 0;
199 static int multiple = 1;
200 static int pnplegacy = 0;
201 static int reverse = 0;
202 static int uart401 = 0;
204 static int audio_activated[SB_CARDS_MAX] = {0};
205 static int mpu_activated[SB_CARDS_MAX] = {0};
206 static int opl_activated[SB_CARDS_MAX] = {0};
207 #else
208 static int isapnp = 0;
209 static int multiple = 0;
210 static int pnplegacy = 0;
211 #endif
213 MODULE_DESCRIPTION("Soundblaster driver");
215 MODULE_PARM(io, "i");
216 MODULE_PARM(irq, "i");
217 MODULE_PARM(dma, "i");
218 MODULE_PARM(dma16, "i");
219 MODULE_PARM(mpu_io, "i");
220 MODULE_PARM(type, "i");
221 MODULE_PARM(sm_games, "i");
222 MODULE_PARM(esstype, "i");
223 MODULE_PARM(acer, "i");
225 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
226 MODULE_PARM(isapnp, "i");
227 MODULE_PARM(isapnpjump, "i");
228 MODULE_PARM(multiple, "i");
229 MODULE_PARM(pnplegacy, "i");
230 MODULE_PARM(reverse, "i");
231 MODULE_PARM(uart401, "i");
232 MODULE_PARM_DESC(isapnp, "When set to 0, Plug & Play support will be disabled");
233 MODULE_PARM_DESC(isapnpjump, "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
234 MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
235 MODULE_PARM_DESC(pnplegacy, "When set to 1, will search for a legacy SB card along with any PnP cards.");
236 MODULE_PARM_DESC(reverse, "When set to 1, will reverse ISAPnP search order");
237 MODULE_PARM_DESC(uart401, "When set to 1, will attempt to detect and enable the mpu on some clones");
238 #endif
240 MODULE_PARM_DESC(io, "Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
241 MODULE_PARM_DESC(irq, "IRQ (5,7,9,10)");
242 MODULE_PARM_DESC(dma, "8-bit DMA channel (0,1,3)");
243 MODULE_PARM_DESC(dma16, "16-bit DMA channel (5,6,7)");
244 MODULE_PARM_DESC(mpu_io, "Mpu base address");
245 MODULE_PARM_DESC(type, "You can set this to specific card type");
246 MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games");
247 MODULE_PARM_DESC(esstype, "ESS chip type");
248 MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks");
250 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
252 /* Please add new entries at the end of the table */
253 static struct {
254 char *name;
255 unsigned short card_vendor, card_device,
256 audio_vendor, audio_function,
257 mpu_vendor, mpu_function,
258 opl_vendor, opl_function;
259 short dma, dma2, mpu_io, mpu_irq; /* see sb_init() */
260 } sb_isapnp_list[] __initdata = {
261 {"Sound Blaster 16",
262 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
263 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
264 0,0,0,0,
265 0,1,1,-1},
266 {"Sound Blaster 16",
267 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0025),
268 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
269 0,0,0,0,
270 0,1,1,-1},
271 {"Sound Blaster 16",
272 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026),
273 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
274 0,0,0,0,
275 0,1,1,-1},
276 {"Sound Blaster 16",
277 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027),
278 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
279 0,0,0,0,
280 0,1,1,-1},
281 {"Sound Blaster 16",
282 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028),
283 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
284 0,0,0,0,
285 0,1,1,-1},
286 {"Sound Blaster 16",
287 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029),
288 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
289 0,0,0,0,
290 0,1,1,-1},
291 {"Sound Blaster 16",
292 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
293 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
294 0,0,0,0,
295 0,1,1,-1},
296 {"Sound Blaster 16",
297 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b),
298 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
299 0,0,0,0,
300 0,1,1,-1},
301 {"Sound Blaster Vibra16S",
302 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051),
303 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
304 0,0,0,0,
305 0,1,1,-1},
306 {"Sound Blaster Vibra16C",
307 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070),
308 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
309 0,0,0,0,
310 0,1,1,-1},
311 {"Sound Blaster Vibra16CL",
312 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080),
313 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
314 0,0,0,0,
315 0,1,1,-1},
316 {"Sound Blaster Vibra16X",
317 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0),
318 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043),
319 0,0,0,0,
320 0,1,1,-1},
321 {"Sound Blaster AWE 32",
322 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039),
323 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
324 0,0,0,0,
325 0,1,1,-1},
326 {"Sound Blaster AWE 32",
327 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
328 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
329 0,0,0,0,
330 0,1,1,-1},
331 {"Sound Blaster AWE 32",
332 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
333 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
334 0,0,0,0,
335 0,1,1,-1},
336 {"Sound Blaster AWE 32",
337 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
338 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
339 0,0,0,0,
340 0,1,1,-1},
341 {"Sound Blaster AWE 32",
342 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048),
343 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
344 0,0,0,0,
345 0,1,1,-1},
346 {"Sound Blaster AWE 32",
347 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054),
348 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
349 0,0,0,0,
350 0,1,1,-1},
351 {"Sound Blaster AWE 32",
352 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C),
353 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
354 0,0,0,0,
355 0,1,1,-1},
356 {"Creative SB32 PnP",
357 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009F),
358 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
359 0,0,0,0,
360 0,1,1,-1},
361 {"Sound Blaster AWE 64",
362 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D),
363 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
364 0,0,0,0,
365 0,1,1,-1},
366 {"Sound Blaster AWE 64 Gold",
367 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E),
368 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
369 0,0,0,0,
370 0,1,1,-1},
371 {"Sound Blaster AWE 64 Gold",
372 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
373 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
374 0,0,0,0,
375 0,1,1,-1},
376 {"Sound Blaster AWE 64",
377 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1),
378 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
379 0,0,0,0,
380 0,1,1,-1},
381 {"Sound Blaster AWE 64",
382 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3),
383 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
384 0,0,0,0,
385 0,1,1,-1},
386 {"Sound Blaster AWE 64",
387 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5),
388 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
389 0,0,0,0,
390 0,1,1,-1},
391 {"Sound Blaster AWE 64",
392 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7),
393 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
394 0,0,0,0,
395 0,1,1,-1},
396 {"Sound Blaster AWE 64",
397 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
398 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
399 0,0,0,0,
400 0,1,1,-1},
401 {"ESS 1688",
402 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
403 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
404 0,0,0,0,
405 0,1,2,-1},
406 {"ESS 1868",
407 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
408 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868),
409 0,0,0,0,
410 0,1,2,-1},
411 {"ESS 1868",
412 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
413 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611),
414 0,0,0,0,
415 0,1,2,-1},
416 {"ESS 1869 PnP AudioDrive",
417 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003),
418 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
419 0,0,0,0,
420 0,1,2,-1},
421 {"ESS 1869",
422 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869),
423 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
424 0,0,0,0,
425 0,1,2,-1},
426 {"ESS 1878",
427 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878),
428 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878),
429 0,0,0,0,
430 0,1,2,-1},
431 {"ESS 1879",
432 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879),
433 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879),
434 0,0,0,0,
435 0,1,2,-1},
436 {"CMI 8330 SoundPRO",
437 ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
438 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
439 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
440 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
441 0,1,0,-1},
442 {"Diamond DT0197H",
443 ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
444 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
445 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
446 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
447 0,-1,0,0},
448 {"ALS007",
449 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
450 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
451 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
452 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
453 0,-1,0,0},
454 {"ALS100",
455 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
456 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
457 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
458 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
459 1,0,0,0},
460 {"ALS110",
461 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
462 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001),
463 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001),
464 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
465 1,0,0,0},
466 {"ALS120",
467 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
468 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
469 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
470 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
471 1,0,0,0},
472 {"ALS200",
473 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
474 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020),
475 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020),
476 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
477 1,0,0,0},
478 {"RTL3000",
479 ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
480 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
481 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
482 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
483 1,0,0,0},
487 static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
489 int err;
491 /* Device already active? Let's use it */
492 if(dev->active)
493 return(dev);
495 if((err = dev->activate(dev)) < 0) {
496 printk(KERN_ERR "sb: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
498 dev->deactivate(dev);
500 return(NULL);
502 return(dev);
505 static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_config, struct address_info *mpu_config, int slot, int card)
508 /* Configure Audio device */
509 if((sb_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].audio_vendor, sb_isapnp_list[slot].audio_function, NULL)))
511 int ret;
512 ret = sb_dev[card]->prepare(sb_dev[card]);
513 /* If device is active, assume configured with /proc/isapnp
514 * and use anyway. Some other way to check this? */
515 if(ret && ret != -EBUSY) {
516 printk(KERN_ERR "sb: ISAPnP found device that could not be autoconfigured.\n");
517 return(NULL);
519 if(ret == -EBUSY)
520 audio_activated[card] = 1;
522 if((sb_dev[card] = activate_dev(sb_isapnp_list[slot].name, "sb", sb_dev[card])))
524 hw_config->io_base = sb_dev[card]->resource[0].start;
525 hw_config->irq = sb_dev[card]->irq_resource[0].start;
526 hw_config->dma = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma].start;
527 if(sb_isapnp_list[slot].dma2 != -1)
528 hw_config->dma2 = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma2].start;
529 else
530 hw_config->dma2 = -1;
531 } else
532 return(NULL);
533 } else
534 return(NULL);
536 /* Cards with separate OPL3 device (ALS, CMI, etc.)
537 * This is just to activate the device so the OPL module can use it */
538 if(sb_isapnp_list[slot].opl_vendor || sb_isapnp_list[slot].opl_function) {
539 if((opl_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].opl_vendor, sb_isapnp_list[slot].opl_function, NULL))) {
540 int ret = opl_dev[card]->prepare(opl_dev[card]);
541 /* If device is active, assume configured with
542 * /proc/isapnp and use anyway */
543 if(ret && ret != -EBUSY) {
544 printk(KERN_ERR "sb: OPL device could not be autoconfigured.\n");
545 return(sb_dev[card]);
547 if(ret == -EBUSY)
548 opl_activated[card] = 1;
550 /* Some have irq and dma for opl. the opl3 driver wont
551 * use 'em so don't configure 'em and hope it works -PEL */
552 opl_dev[card]->irq_resource[0].flags = 0;
553 opl_dev[card]->dma_resource[0].flags = 0;
555 opl_dev[card] = activate_dev(sb_isapnp_list[slot].name, "opl3", opl_dev[card]);
556 } else
557 printk(KERN_ERR "sb: %s isapnp panic: opl3 device not found\n", sb_isapnp_list[slot].name);
560 /* Cards with MPU as part of Audio device (CTL and ESS) */
561 if(!sb_isapnp_list[slot].mpu_vendor) {
562 mpu_config->io_base = sb_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
563 return(sb_dev[card]);
566 /* Cards with separate MPU device (ALS, CMI, etc.) */
567 if(!uart401)
568 return(sb_dev[card]);
569 if((mpu_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].mpu_vendor, sb_isapnp_list[slot].mpu_function, NULL)))
571 int ret = mpu_dev[card]->prepare(mpu_dev[card]);
572 /* If device is active, assume configured with /proc/isapnp
573 * and use anyway */
574 if(ret && ret != -EBUSY) {
575 printk(KERN_ERR "sb: MPU device could not be autoconfigured.\n");
576 return(sb_dev[card]);
578 if(ret == -EBUSY)
579 mpu_activated[card] = 1;
581 /* Some cards ask for irq but don't need them - azummo */
582 if(sb_isapnp_list[slot].mpu_irq == -1)
583 mpu_dev[card]->irq_resource[0].flags = 0;
585 if((mpu_dev[card] = activate_dev(sb_isapnp_list[slot].name, "mpu", mpu_dev[card]))) {
586 mpu_config->io_base = mpu_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
587 if(sb_isapnp_list[slot].mpu_irq != -1)
588 mpu_config->irq = mpu_dev[card]->irq_resource[sb_isapnp_list[slot].mpu_irq].start;
591 else
592 printk(KERN_ERR "sb: %s isapnp panic: mpu not found\n", sb_isapnp_list[slot].name);
594 return(sb_dev[card]);
597 static int __init sb_isapnp_init(struct address_info *hw_config, struct address_info *mpu_config, struct pci_bus *bus, int slot, int card)
599 char *busname = bus->name[0] ? bus->name : sb_isapnp_list[slot].name;
601 printk(KERN_INFO "sb: %s detected\n", busname);
603 /* Initialize this baby. */
605 if(sb_init(bus, hw_config, mpu_config, slot, card)) {
606 /* We got it. */
608 printk(KERN_NOTICE "sb: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
609 busname,
610 hw_config->io_base, hw_config->irq, hw_config->dma,
611 hw_config->dma2);
612 return 1;
614 else
615 printk(KERN_INFO "sb: Failed to initialize %s\n", busname);
617 return 0;
620 static int __init sb_isapnp_probe(struct address_info *hw_config, struct address_info *mpu_config, int card)
622 static int first = 1;
623 int i;
625 /* Count entries in sb_isapnp_list */
626 for (i = 0; sb_isapnp_list[i].card_vendor != 0; i++);
627 i--;
629 /* Check and adjust isapnpjump */
630 if( isapnpjump < 0 || isapnpjump > i) {
631 isapnpjump = reverse ? i : 0;
632 printk(KERN_ERR "sb: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
635 if(!first || !reverse)
636 i = isapnpjump;
637 first = 0;
638 while(sb_isapnp_list[i].card_vendor != 0) {
639 static struct pci_bus *bus = NULL;
641 while ((bus = isapnp_find_card(
642 sb_isapnp_list[i].card_vendor,
643 sb_isapnp_list[i].card_device,
644 bus))) {
646 if(sb_isapnp_init(hw_config, mpu_config, bus, i, card)) {
647 isapnpjump = i; /* start next search from here */
648 return 0;
651 i += reverse ? -1 : 1;
654 return -ENODEV;
656 #endif
658 static int __init init_sb(void)
660 int card, max = (multiple && isapnp) ? SB_CARDS_MAX : 1;
662 printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
664 for(card = 0; card < max; card++, sb_cards_num++) {
665 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
666 /* Please remember that even with CONFIG_ISAPNP defined one
667 * should still be able to disable PNP support for this
668 * single driver! */
669 if((!pnplegacy||card>0) && isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
670 if(!sb_cards_num) {
671 /* Found no ISAPnP cards, so check for a non-pnp
672 * card and set the detection loop for 1 cycle
674 printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n");
675 isapnp = 0;
676 max = 1;
677 } else
678 /* found all the ISAPnP cards so exit the
679 * detection loop. */
680 break;
682 #endif
684 if(!isapnp || (pnplegacy&&card==0)) {
685 cfg[card].io_base = io;
686 cfg[card].irq = irq;
687 cfg[card].dma = dma;
688 cfg[card].dma2 = dma16;
691 cfg[card].card_subtype = type;
693 if (!probe_sb(&cfg[card])) {
694 /* if one or more cards already registered, don't
695 * return an error but print a warning. Note, this
696 * should never really happen unless the hardware
697 * or ISAPnP screwed up. */
698 if (sb_cards_num) {
699 printk(KERN_WARNING "sb.c: There was a " \
700 "problem probing one of your SoundBlaster " \
701 "ISAPnP soundcards. Continuing.\n");
702 card--;
703 sb_cards_num--;
704 continue;
705 } else if(pnplegacy && isapnp) {
706 printk(KERN_NOTICE "sb: No legacy SoundBlaster cards " \
707 "found. Continuing with PnP detection.\n");
708 pnplegacy=0;
709 card--;
710 continue;
711 } else
712 return -ENODEV;
714 attach_sb_card(&cfg[card]);
716 if(cfg[card].slots[0]==-1) {
717 if(card==0 && pnplegacy && isapnp) {
718 printk(KERN_NOTICE "sb: No legacy SoundBlaster cards " \
719 "found. Continuing with PnP detection.\n");
720 pnplegacy=0;
721 card--;
722 continue;
723 } else
724 return -ENODEV;
727 if (!isapnp||(pnplegacy&&card==0))
728 cfg_mpu[card].io_base = mpu_io;
729 if (probe_sbmpu(&cfg_mpu[card], THIS_MODULE))
730 sbmpu[card] = 1;
733 if(isapnp)
734 printk(KERN_NOTICE "sb: %d Soundblaster PnP card(s) found.\n", sb_cards_num);
736 return 0;
739 static void __exit cleanup_sb(void)
741 int i;
743 if (smw_free) {
744 vfree(smw_free);
745 smw_free = NULL;
748 for(i = 0; i < sb_cards_num; i++) {
749 unload_sb(&cfg[i], i);
750 if (sbmpu[i])
751 unload_sbmpu(&cfg_mpu[i]);
753 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
754 if(!audio_activated[i] && sb_dev[i])
755 sb_dev[i]->deactivate(sb_dev[i]);
756 if(!mpu_activated[i] && mpu_dev[i])
757 mpu_dev[i]->deactivate(mpu_dev[i]);
758 if(!opl_activated[i] && opl_dev[i])
759 opl_dev[i]->deactivate(opl_dev[i]);
760 #endif
764 module_init(init_sb);
765 module_exit(cleanup_sb);
767 #ifndef MODULE
768 static int __init setup_sb(char *str)
770 /* io, irq, dma, dma2 - just the basics */
771 int ints[5];
773 str = get_options(str, ARRAY_SIZE(ints), ints);
775 io = ints[1];
776 irq = ints[2];
777 dma = ints[3];
778 dma16 = ints[4];
780 return 1;
782 __setup("sb=", setup_sb);
783 #endif