1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61#include <linux/config.h>
62#include <linux/mca.h>
63#include <linux/module.h>
64#include <linux/init.h>
65#include <linux/isapnp.h>
66
67#include "sound_config.h"
68
69#include "sb_mixer.h"
70#include "sb.h"
71
72#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
73#define SB_CARDS_MAX 5
74#else
75#define SB_CARDS_MAX 1
76#endif
77
78static int sbmpu[SB_CARDS_MAX] = {0};
79static int sb_cards_num = 0;
80
81extern void *smw_free;
82
83
84
85
86
87
88
89static int __initdata mpu_io = 0;
90static int __initdata io = -1;
91static int __initdata irq = -1;
92static int __initdata dma = -1;
93static int __initdata dma16 = -1;
94static int __initdata type = 0;
95static int __initdata esstype = 0;
96static int __initdata acer = 0;
97static int __initdata sm_games = 0;
98
99static void __init attach_sb_card(struct address_info *hw_config)
100{
101 if(!sb_dsp_init(hw_config, THIS_MODULE))
102 hw_config->slots[0] = -1;
103}
104
105static int __init probe_sb(struct address_info *hw_config)
106{
107 struct sb_module_options sbmo;
108
109 if (hw_config->io_base == -1 || hw_config->dma == -1 || hw_config->irq == -1)
110 {
111 printk(KERN_ERR "sb: I/O, IRQ, and DMA are mandatory\n");
112 return -EINVAL;
113 }
114
115#ifdef CONFIG_MCA
116
117 if (MCA_bus) {
118 int slot;
119 u8 pos2, pos3, pos4;
120
121 slot = mca_find_adapter( 0x5138, 0 );
122 if( slot == MCA_NOTFOUND )
123 {
124 slot = mca_find_adapter( 0x5137, 0 );
125
126 if (slot != MCA_NOTFOUND)
127 mca_set_adapter_name( slot, "REPLY SB16 & SCSI Adapter" );
128 }
129 else
130 {
131 mca_set_adapter_name( slot, "REPLY SB16 Adapter" );
132 }
133
134 if (slot != MCA_NOTFOUND)
135 {
136 mca_mark_as_used(slot);
137 pos2 = mca_read_stored_pos( slot, 2 );
138 pos3 = mca_read_stored_pos( slot, 3 );
139 pos4 = mca_read_stored_pos( slot, 4 );
140
141 if (pos2 & 0x4)
142 {
143
144 static unsigned short irq[] = { 0, 5, 7, 10 };
145
146
147
148
149 hw_config->io_base = 0x220 + 0x20 * (pos2 >> 6);
150 hw_config->irq = irq[(pos4 >> 5) & 0x3];
151 hw_config->dma = pos3 & 0xf;
152
153 hw_config->dma2 = (pos3 >> 4) & 0x3;
154 if (hw_config->dma2 == 0)
155 hw_config->dma2 = hw_config->dma;
156 else
157 hw_config->dma2 += 4;
158
159
160
161
162 printk(KERN_INFO "sb: Reply MCA SB at slot=%d \
163iobase=0x%x irq=%d lo_dma=%d hi_dma=%d\n",
164 slot+1,
165 hw_config->io_base, hw_config->irq,
166 hw_config->dma, hw_config->dma2);
167 }
168 else
169 {
170 printk (KERN_INFO "sb: Reply SB Base I/O address disabled\n");
171 }
172 }
173 }
174#endif
175
176
177
178 sbmo.acer = acer;
179 sbmo.sm_games = sm_games;
180 sbmo.esstype = esstype;
181
182 return sb_dsp_detect(hw_config, 0, 0, &sbmo);
183}
184
185static void __exit unload_sb(struct address_info *hw_config, int card)
186{
187 if(hw_config->slots[0]!=-1)
188 sb_dsp_unload(hw_config, sbmpu[card]);
189}
190
191static struct address_info cfg[SB_CARDS_MAX];
192static struct address_info cfg_mpu[SB_CARDS_MAX];
193
194struct pci_dev *sb_dev[SB_CARDS_MAX] = {NULL},
195 *mpu_dev[SB_CARDS_MAX] = {NULL},
196 *opl_dev[SB_CARDS_MAX] = {NULL};
197
198
199#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
200static int isapnp = 1;
201static int isapnpjump = 0;
202static int multiple = 1;
203static int pnplegacy = 0;
204static int reverse = 0;
205static int uart401 = 0;
206
207static int audio_activated[SB_CARDS_MAX] = {0};
208static int mpu_activated[SB_CARDS_MAX] = {0};
209static int opl_activated[SB_CARDS_MAX] = {0};
210#else
211static int isapnp = 0;
212static int multiple = 0;
213static int pnplegacy = 0;
214#endif
215
216MODULE_DESCRIPTION("Soundblaster driver");
217MODULE_LICENSE("GPL");
218
219MODULE_PARM(io, "i");
220MODULE_PARM(irq, "i");
221MODULE_PARM(dma, "i");
222MODULE_PARM(dma16, "i");
223MODULE_PARM(mpu_io, "i");
224MODULE_PARM(type, "i");
225MODULE_PARM(sm_games, "i");
226MODULE_PARM(esstype, "i");
227MODULE_PARM(acer, "i");
228
229#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
230MODULE_PARM(isapnp, "i");
231MODULE_PARM(isapnpjump, "i");
232MODULE_PARM(multiple, "i");
233MODULE_PARM(pnplegacy, "i");
234MODULE_PARM(reverse, "i");
235MODULE_PARM(uart401, "i");
236MODULE_PARM_DESC(isapnp, "When set to 0, Plug & Play support will be disabled");
237MODULE_PARM_DESC(isapnpjump, "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
238MODULE_PARM_DESC(multiple, "When set to 0, will not search for multiple cards");
239MODULE_PARM_DESC(pnplegacy, "When set to 1, will search for a legacy SB card along with any PnP cards.");
240MODULE_PARM_DESC(reverse, "When set to 1, will reverse ISAPnP search order");
241MODULE_PARM_DESC(uart401, "When set to 1, will attempt to detect and enable the mpu on some clones");
242#endif
243
244MODULE_PARM_DESC(io, "Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
245MODULE_PARM_DESC(irq, "IRQ (5,7,9,10)");
246MODULE_PARM_DESC(dma, "8-bit DMA channel (0,1,3)");
247MODULE_PARM_DESC(dma16, "16-bit DMA channel (5,6,7)");
248MODULE_PARM_DESC(mpu_io, "Mpu base address");
249MODULE_PARM_DESC(type, "You can set this to specific card type");
250MODULE_PARM_DESC(sm_games, "Enable support for Logitech soundman games");
251MODULE_PARM_DESC(esstype, "ESS chip type");
252MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks");
253
254#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
255
256
257static struct {
258 char *name;
259 unsigned short card_vendor, card_device,
260 audio_vendor, audio_function,
261 mpu_vendor, mpu_function,
262 opl_vendor, opl_function;
263 short dma, dma2, mpu_io, mpu_irq;
264} sb_isapnp_list[] __initdata = {
265 {"Sound Blaster 16",
266 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
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(0x0025),
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(0x0026),
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(0x0027),
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(0x0028),
287 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
288 0,0,0,0,
289 0,1,1,-1},
290 {"Sound Blaster 16",
291 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029),
292 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
293 0,0,0,0,
294 0,1,1,-1},
295 {"Sound Blaster 16",
296 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
297 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
298 0,0,0,0,
299 0,1,1,-1},
300 {"Sound Blaster 16",
301 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b),
302 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
303 0,0,0,0,
304 0,1,1,-1},
305 {"Sound Blaster 16",
306 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
307 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
308 0,0,0,0,
309 0,1,1,-1},
310 {"Sound Blaster 16",
311 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
312 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
313 0,0,0,0,
314 0,1,1,-1},
315 {"Sound Blaster 16",
316 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00ed),
317 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
318 0,0,0,0,
319 0,1,1,-1},
320 {"Sound Blaster 16",
321 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
322 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
323 0,0,0,0,
324 0,1,1,-1},
325 {"Sound Blaster 16",
326 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
327 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
328 0,0,0,0,
329 0,1,1,-1},
330 {"Sound Blaster Vibra16S",
331 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051),
332 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
333 0,0,0,0,
334 0,1,1,-1},
335 {"Sound Blaster Vibra16C",
336 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070),
337 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001),
338 0,0,0,0,
339 0,1,1,-1},
340 {"Sound Blaster Vibra16CL",
341 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080),
342 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
343 0,0,0,0,
344 0,1,1,-1},
345 {"Sound Blaster Vibra16X",
346 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0),
347 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043),
348 0,0,0,0,
349 0,1,1,-1},
350 {"Sound Blaster AWE 32",
351 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039),
352 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
353 0,0,0,0,
354 0,1,1,-1},
355 {"Sound Blaster AWE 32",
356 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
357 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
358 0,0,0,0,
359 0,1,1,-1},
360 {"Sound Blaster AWE 32",
361 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
362 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
363 0,0,0,0,
364 0,1,1,-1},
365 {"Sound Blaster AWE 32",
366 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
367 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
368 0,0,0,0,
369 0,1,1,-1},
370 {"Sound Blaster AWE 32",
371 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0045),
372 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
373 0,0,0,0,
374 0,1,1,-1},
375 {"Sound Blaster AWE 32",
376 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0046),
377 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
378 0,0,0,0,
379 0,1,1,-1},
380 {"Sound Blaster AWE 32",
381 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047),
382 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
383 0,0,0,0,
384 0,1,1,-1},
385 {"Sound Blaster AWE 32",
386 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048),
387 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
388 0,0,0,0,
389 0,1,1,-1},
390 {"Sound Blaster AWE 32",
391 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054),
392 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
393 0,0,0,0,
394 0,1,1,-1},
395 {"Sound Blaster AWE 32",
396 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C),
397 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
398 0,0,0,0,
399 0,1,1,-1},
400 {"Creative SB32 PnP",
401 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009F),
402 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041),
403 0,0,0,0,
404 0,1,1,-1},
405 {"Sound Blaster AWE 64",
406 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D),
407 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
408 0,0,0,0,
409 0,1,1,-1},
410 {"Sound Blaster AWE 64 Gold",
411 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E),
412 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
413 0,0,0,0,
414 0,1,1,-1},
415 {"Sound Blaster AWE 64 Gold",
416 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
417 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044),
418 0,0,0,0,
419 0,1,1,-1},
420 {"Sound Blaster AWE 64",
421 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1),
422 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042),
423 0,0,0,0,
424 0,1,1,-1},
425 {"Sound Blaster AWE 64",
426 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3),
427 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
428 0,0,0,0,
429 0,1,1,-1},
430 {"Sound Blaster AWE 64",
431 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5),
432 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
433 0,0,0,0,
434 0,1,1,-1},
435 {"Sound Blaster AWE 64",
436 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7),
437 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
438 0,0,0,0,
439 0,1,1,-1},
440 {"Sound Blaster AWE 64",
441 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
442 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
443 0,0,0,0,
444 0,1,1,-1},
445 {"Sound Blaster AWE 64",
446 ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
447 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045),
448 0,0,0,0,
449 0,1,1,-1},
450 {"ESS 1688",
451 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
452 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968),
453 0,0,0,0,
454 0,1,2,-1},
455 {"ESS 1868",
456 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
457 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868),
458 0,0,0,0,
459 0,1,2,-1},
460 {"ESS 1868",
461 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
462 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611),
463 0,0,0,0,
464 0,1,2,-1},
465 {"ESS 1869 PnP AudioDrive",
466 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003),
467 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
468 0,0,0,0,
469 0,1,2,-1},
470 {"ESS 1869",
471 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869),
472 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869),
473 0,0,0,0,
474 0,1,2,-1},
475 {"ESS 1878",
476 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878),
477 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878),
478 0,0,0,0,
479 0,1,2,-1},
480 {"ESS 1879",
481 ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879),
482 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879),
483 0,0,0,0,
484 0,1,2,-1},
485 {"CMI 8330 SoundPRO",
486 ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
487 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
488 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
489 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
490 0,1,0,-1},
491 {"Diamond DT0197H",
492 ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
493 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
494 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
495 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
496 0,-1,0,0},
497 {"ALS007",
498 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
499 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
500 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
501 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
502 0,-1,0,0},
503 {"ALS100",
504 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
505 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
506 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001),
507 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
508 1,0,0,0},
509 {"ALS110",
510 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
511 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001),
512 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001),
513 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
514 1,0,0,0},
515 {"ALS120",
516 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
517 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
518 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
519 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
520 1,0,0,0},
521 {"ALS200",
522 ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
523 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020),
524 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020),
525 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
526 1,0,0,0},
527 {"RTL3000",
528 ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
529 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001),
530 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001),
531 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001),
532 1,0,0,0},
533 {0}
534};
535
536static struct isapnp_device_id id_table[] __devinitdata = {
537 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024),
538 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
539
540 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0025),
541 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
542
543 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026),
544 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
545
546 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027),
547 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
548
549 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0028),
550 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
551
552 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029),
553 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
554
555 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002a),
556 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
557
558 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b),
559 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
560
561 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
562 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
563
564 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002c),
565 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
566
567 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00ed),
568 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
569
570 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
571 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
572
573 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0086),
574 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
575
576 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051),
577 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
578
579 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070),
580 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), 0 },
581
582 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080),
583 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
584
585 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0),
586 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), 0 },
587
588 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039),
589 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
590
591 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042),
592 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
593
594 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043),
595 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
596
597 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044),
598 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
599
600 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0045),
601 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
602
603 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048),
604 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
605
606 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054),
607 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), 0 },
608
609 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C),
610 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
611
612 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009F),
613 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), 0 },
614
615 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D),
616 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), 0 },
617
618 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E),
619 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0 },
620
621 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00B2),
622 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), 0 },
623
624 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1),
625 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), 0 },
626
627 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3),
628 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
629
630 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5),
631 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
632
633 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7),
634 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
635
636 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4),
637 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
638
639 { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E9),
640 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), 0 },
641
642 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0968),
643 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x0968), 0 },
644
645 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
646 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), 0 },
647
648 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868),
649 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), 0 },
650
651 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003),
652 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), 0 },
653
654 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869),
655 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), 0 },
656
657 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878),
658 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), 0 },
659
660 { ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879),
661 ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), 0 },
662
663 { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
664 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
665
666 { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
667 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
668
669 { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
670 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
671
672 { ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
673 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
674
675 { ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
676 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
677
678 { ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688),
679 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
680
681 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
682 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
683
684 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
685 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
686
687 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007),
688 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
689
690 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
691 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
692
693 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
694 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), 0 },
695
696 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001),
697 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
698
699 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
700 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001), 0 },
701
702 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
703 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001), 0 },
704
705 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110),
706 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
707
708 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
709 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), 0 },
710
711 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
712 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), 0 },
713
714 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120),
715 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
716
717 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
718 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020), 0 },
719
720 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
721 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020), 0 },
722
723 { ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200),
724 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
725
726 { ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
727 ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), 0 },
728
729 { ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
730 ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), 0 },
731
732 { ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000),
733 ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0 },
734 {0}
735};
736
737MODULE_DEVICE_TABLE(isapnp, id_table);
738
739static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
740{
741 int err;
742
743
744 if(dev->active)
745 return(dev);
746
747 if((err = dev->activate(dev)) < 0) {
748 printk(KERN_ERR "sb: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
749
750 dev->deactivate(dev);
751
752 return(NULL);
753 }
754 return(dev);
755}
756
757static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_config, struct address_info *mpu_config, int slot, int card)
758{
759
760
761 if((sb_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].audio_vendor, sb_isapnp_list[slot].audio_function, NULL)))
762 {
763 int ret;
764 ret = sb_dev[card]->prepare(sb_dev[card]);
765
766
767 if(ret && ret != -EBUSY) {
768 printk(KERN_ERR "sb: ISAPnP found device that could not be autoconfigured.\n");
769 return(NULL);
770 }
771 if(ret == -EBUSY)
772 audio_activated[card] = 1;
773
774 if((sb_dev[card] = activate_dev(sb_isapnp_list[slot].name, "sb", sb_dev[card])))
775 {
776 hw_config->io_base = sb_dev[card]->resource[0].start;
777 hw_config->irq = sb_dev[card]->irq_resource[0].start;
778 hw_config->dma = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma].start;
779 if(sb_isapnp_list[slot].dma2 != -1)
780 hw_config->dma2 = sb_dev[card]->dma_resource[sb_isapnp_list[slot].dma2].start;
781 else
782 hw_config->dma2 = -1;
783 } else
784 return(NULL);
785 } else
786 return(NULL);
787
788
789
790 if(sb_isapnp_list[slot].opl_vendor || sb_isapnp_list[slot].opl_function) {
791 if((opl_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].opl_vendor, sb_isapnp_list[slot].opl_function, NULL))) {
792 int ret = opl_dev[card]->prepare(opl_dev[card]);
793
794
795 if(ret && ret != -EBUSY) {
796 printk(KERN_ERR "sb: OPL device could not be autoconfigured.\n");
797 return(sb_dev[card]);
798 }
799 if(ret == -EBUSY)
800 opl_activated[card] = 1;
801
802
803
804 opl_dev[card]->irq_resource[0].flags = 0;
805 opl_dev[card]->dma_resource[0].flags = 0;
806
807 opl_dev[card] = activate_dev(sb_isapnp_list[slot].name, "opl3", opl_dev[card]);
808 } else
809 printk(KERN_ERR "sb: %s isapnp panic: opl3 device not found\n", sb_isapnp_list[slot].name);
810 }
811
812
813 if(!sb_isapnp_list[slot].mpu_vendor) {
814 mpu_config->io_base = sb_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
815 return(sb_dev[card]);
816 }
817
818
819 if(!uart401)
820 return(sb_dev[card]);
821 if((mpu_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].mpu_vendor, sb_isapnp_list[slot].mpu_function, NULL)))
822 {
823 int ret = mpu_dev[card]->prepare(mpu_dev[card]);
824
825
826 if(ret && ret != -EBUSY) {
827 printk(KERN_ERR "sb: MPU device could not be autoconfigured.\n");
828 return(sb_dev[card]);
829 }
830 if(ret == -EBUSY)
831 mpu_activated[card] = 1;
832
833
834 if(sb_isapnp_list[slot].mpu_irq == -1)
835 mpu_dev[card]->irq_resource[0].flags = 0;
836
837 if((mpu_dev[card] = activate_dev(sb_isapnp_list[slot].name, "mpu", mpu_dev[card]))) {
838 mpu_config->io_base = mpu_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start;
839 if(sb_isapnp_list[slot].mpu_irq != -1)
840 mpu_config->irq = mpu_dev[card]->irq_resource[sb_isapnp_list[slot].mpu_irq].start;
841 }
842 }
843 else
844 printk(KERN_ERR "sb: %s isapnp panic: mpu not found\n", sb_isapnp_list[slot].name);
845
846 return(sb_dev[card]);
847}
848
849static int __init sb_isapnp_init(struct address_info *hw_config, struct address_info *mpu_config, struct pci_bus *bus, int slot, int card)
850{
851 char *busname = bus->name[0] ? bus->name : sb_isapnp_list[slot].name;
852
853 printk(KERN_INFO "sb: %s detected\n", busname);
854
855
856
857 if(sb_init(bus, hw_config, mpu_config, slot, card)) {
858
859
860 printk(KERN_NOTICE "sb: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
861 busname,
862 hw_config->io_base, hw_config->irq, hw_config->dma,
863 hw_config->dma2);
864 return 1;
865 }
866 else
867 printk(KERN_INFO "sb: Failed to initialize %s\n", busname);
868
869 return 0;
870}
871
872static int __init sb_isapnp_probe(struct address_info *hw_config, struct address_info *mpu_config, int card)
873{
874 static int first = 1;
875 int i;
876
877
878 for (i = 0; sb_isapnp_list[i].card_vendor != 0; i++);
879 i--;
880
881
882 if( isapnpjump < 0 || isapnpjump > i) {
883 isapnpjump = reverse ? i : 0;
884 printk(KERN_ERR "sb: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
885 }
886
887 if(!first || !reverse)
888 i = isapnpjump;
889 first = 0;
890 while(sb_isapnp_list[i].card_vendor != 0) {
891 static struct pci_bus *bus = NULL;
892
893 while ((bus = isapnp_find_card(
894 sb_isapnp_list[i].card_vendor,
895 sb_isapnp_list[i].card_device,
896 bus))) {
897
898 if(sb_isapnp_init(hw_config, mpu_config, bus, i, card)) {
899 isapnpjump = i;
900 return 0;
901 }
902 }
903 i += reverse ? -1 : 1;
904 }
905
906 return -ENODEV;
907}
908#endif
909
910static int __init init_sb(void)
911{
912 int card, max = (multiple && isapnp) ? SB_CARDS_MAX : 1;
913
914 printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
915
916 for(card = 0; card < max; card++, sb_cards_num++) {
917#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
918
919
920
921 if((!pnplegacy||card>0) && isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
922 if(!sb_cards_num) {
923
924
925
926 printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n");
927 isapnp = 0;
928 max = 1;
929 } else
930
931
932 break;
933 }
934#endif
935
936 if(!isapnp || (pnplegacy&&card==0)) {
937 cfg[card].io_base = io;
938 cfg[card].irq = irq;
939 cfg[card].dma = dma;
940 cfg[card].dma2 = dma16;
941 }
942
943 cfg[card].card_subtype = type;
944
945 if (!probe_sb(&cfg[card])) {
946
947
948
949
950 if (sb_cards_num) {
951 printk(KERN_WARNING "sb.c: There was a " \
952 "problem probing one of your SoundBlaster " \
953 "ISAPnP soundcards. Continuing.\n");
954 card--;
955 sb_cards_num--;
956 continue;
957 } else if(pnplegacy && isapnp) {
958 printk(KERN_NOTICE "sb: No legacy SoundBlaster cards " \
959 "found. Continuing with PnP detection.\n");
960 pnplegacy=0;
961 card--;
962 continue;
963 } else
964 return -ENODEV;
965 }
966 attach_sb_card(&cfg[card]);
967
968 if(cfg[card].slots[0]==-1) {
969 if(card==0 && pnplegacy && isapnp) {
970 printk(KERN_NOTICE "sb: No legacy SoundBlaster cards " \
971 "found. Continuing with PnP detection.\n");
972 pnplegacy=0;
973 card--;
974 continue;
975 } else
976 return -ENODEV;
977 }
978
979 if (!isapnp||(pnplegacy&&card==0))
980 cfg_mpu[card].io_base = mpu_io;
981 if (probe_sbmpu(&cfg_mpu[card], THIS_MODULE))
982 sbmpu[card] = 1;
983 }
984
985 if(isapnp)
986 printk(KERN_NOTICE "sb: %d Soundblaster PnP card(s) found.\n", sb_cards_num);
987
988 return 0;
989}
990
991static void __exit cleanup_sb(void)
992{
993 int i;
994
995 if (smw_free) {
996 vfree(smw_free);
997 smw_free = NULL;
998 }
999
1000 for(i = 0; i < sb_cards_num; i++) {
1001 unload_sb(&cfg[i], i);
1002 if (sbmpu[i])
1003 unload_sbmpu(&cfg_mpu[i]);
1004
1005#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
1006 if(!audio_activated[i] && sb_dev[i])
1007 sb_dev[i]->deactivate(sb_dev[i]);
1008 if(!mpu_activated[i] && mpu_dev[i])
1009 mpu_dev[i]->deactivate(mpu_dev[i]);
1010 if(!opl_activated[i] && opl_dev[i])
1011 opl_dev[i]->deactivate(opl_dev[i]);
1012#endif
1013 }
1014}
1015
1016module_init(init_sb);
1017module_exit(cleanup_sb);
1018
1019#ifndef MODULE
1020static int __init setup_sb(char *str)
1021{
1022
1023 int ints[5];
1024
1025 str = get_options(str, ARRAY_SIZE(ints), ints);
1026
1027 io = ints[1];
1028 irq = ints[2];
1029 dma = ints[3];
1030 dma16 = ints[4];
1031
1032 return 1;
1033}
1034__setup("sb=", setup_sb);
1035#endif
1036