OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [sb_card.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * sound/sb_card.c
3
 *
4
 * Detection routine for the Sound Blaster cards.
5
 *
6
 *
7
 * Copyright (C) by Hannu Savolainen 1993-1997
8
 *
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.
12
 *
13
 * 26-11-1999 Patched to compile without ISA PnP support in the
14
 * kernel - Daniel Stone (tamriel@ductape.net)
15
 *
16
 * 06-01-2000 Refined and bugfixed ISA PnP support, added
17
 *  CMI 8330 support - Alessandro Zummo <azummo@ita.flashnet.it>
18
 *
19
 * 18-01-2000 Separated sb_card and sb_common
20
 *  Jeff Garzik <jgarzik@pobox.com>
21
 *
22
 * 04-02-2000 Added Soundblaster AWE 64 PnP support, isapnpjump
23
 *  Alessandro Zummo <azummo@ita.flashnet.it>
24
 *
25
 * 11-02-2000 Added Soundblaster AWE 32 PnP support, refined PnP code
26
 *  Alessandro Zummo <azummo@ita.flashnet.it>
27
 *
28
 * 13-02-2000 Hopefully fixed awe/sb16 related bugs, code cleanup
29
 *  Alessandro Zummo <azummo@ita.flashnet.it>
30
 *
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>
35
 *
36
 * 26-03-2000 Fixed acer, esstype and sm_games module options.
37
 *  Alessandro Zummo <azummo@ita.flashnet.it>
38
 *
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>
42
 *
43
 * 06-05-2000 added another card. Daniel M. Newman <dmnewman@pobox.com>
44
 *
45
 * 25-05-2000 Added Creative SB AWE64 Gold (CTL00B2).
46
 *      Pål-Kristian Engstad <engstad@att.net>
47
 *
48
 * 12-08-2000 Added Creative SB32 PnP (CTL009F).
49
 *      Kasatenko Ivan Alex. <skywriter@rnc.ru>
50
 *
51
 * 21-09-2000 Got rid of attach_sbmpu
52
 *      Arnaldo Carvalho de Melo <acme@conectiva.com.br>
53
 *
54
 * 28-10-2000 Added pnplegacy support
55
 *      Daniel Church <dchurch@mbhs.edu>
56
 *
57
 * 01-10-2001 Added a new flavor of Creative SB AWE64 PnP (CTL00E9).
58
 *      Jerome Cornet <jcornet@free.fr>
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
 
78
static int sbmpu[SB_CARDS_MAX] = {0};
79
static int sb_cards_num = 0;
80
 
81
extern void *smw_free;
82
 
83
/*
84
 *    Note DMA2 of -1 has the right meaning in the SB16 driver as well
85
 *    as here. It will cause either an error if it is needed or a fallback
86
 *    to the 8bit channel.
87
 */
88
 
89
static int __initdata mpu_io    = 0;
90
static int __initdata io        = -1;
91
static int __initdata irq       = -1;
92
static int __initdata dma       = -1;
93
static int __initdata dma16     = -1;   /* Set this for modules that need it */
94
static int __initdata type      = 0;    /* Can set this to a specific card type */
95
static int __initdata esstype   = 0;     /* ESS chip type */
96
static int __initdata acer      = 0;     /* Do acer notebook init? */
97
static int __initdata sm_games  = 0;     /* Logitech soundman games? */
98
 
99
static 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
 
105
static 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
        /* MCA code added by ZP Gu (zpg@castle.net) */
117
        if (MCA_bus) {               /* no multiple REPLY card probing */
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
                                /* enabled? */
144
                                static unsigned short irq[] = { 0, 5, 7, 10 };
145
                                /*
146
                                static unsigned short midiaddr[] = {0, 0x330, 0, 0x300 };
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
                                /* Reply ADF wrong on High DMA, pos[1] should start w/ 00 */
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
                                        hw_config->driver_use_2 = midiaddr[(pos2 >> 3) & 0x3];
160
                                */
161
 
162
                                printk(KERN_INFO "sb: Reply MCA SB at slot=%d \
163
iobase=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
        /* Setup extra module options */
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
 
185
static 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
 
191
static struct address_info cfg[SB_CARDS_MAX];
192
static struct address_info cfg_mpu[SB_CARDS_MAX];
193
 
194
struct 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
200
static int isapnp       = 1;
201
static int isapnpjump   = 0;
202
static int multiple     = 1;
203
static int pnplegacy    = 0;
204
static int reverse      = 0;
205
static int uart401      = 0;
206
 
207
static int audio_activated[SB_CARDS_MAX] = {0};
208
static int mpu_activated[SB_CARDS_MAX]   = {0};
209
static int opl_activated[SB_CARDS_MAX]   = {0};
210
#else
211
static int isapnp       = 0;
212
static int multiple     = 0;
213
static int pnplegacy    = 0;
214
#endif
215
 
216
MODULE_DESCRIPTION("Soundblaster driver");
217
MODULE_LICENSE("GPL");
218
 
219
MODULE_PARM(io,         "i");
220
MODULE_PARM(irq,        "i");
221
MODULE_PARM(dma,        "i");
222
MODULE_PARM(dma16,      "i");
223
MODULE_PARM(mpu_io,     "i");
224
MODULE_PARM(type,       "i");
225
MODULE_PARM(sm_games,   "i");
226
MODULE_PARM(esstype,    "i");
227
MODULE_PARM(acer,       "i");
228
 
229
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
230
MODULE_PARM(isapnp,     "i");
231
MODULE_PARM(isapnpjump, "i");
232
MODULE_PARM(multiple,   "i");
233
MODULE_PARM(pnplegacy,  "i");
234
MODULE_PARM(reverse,    "i");
235
MODULE_PARM(uart401,    "i");
236
MODULE_PARM_DESC(isapnp,        "When set to 0, Plug & Play support will be disabled");
237
MODULE_PARM_DESC(isapnpjump,    "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
238
MODULE_PARM_DESC(multiple,      "When set to 0, will not search for multiple cards");
239
MODULE_PARM_DESC(pnplegacy,     "When set to 1, will search for a legacy SB card along with any PnP cards.");
240
MODULE_PARM_DESC(reverse,       "When set to 1, will reverse ISAPnP search order");
241
MODULE_PARM_DESC(uart401,       "When set to 1, will attempt to detect and enable the mpu on some clones");
242
#endif
243
 
244
MODULE_PARM_DESC(io,            "Soundblaster i/o base address (0x220,0x240,0x260,0x280)");
245
MODULE_PARM_DESC(irq,           "IRQ (5,7,9,10)");
246
MODULE_PARM_DESC(dma,           "8-bit DMA channel (0,1,3)");
247
MODULE_PARM_DESC(dma16,         "16-bit DMA channel (5,6,7)");
248
MODULE_PARM_DESC(mpu_io,        "Mpu base address");
249
MODULE_PARM_DESC(type,          "You can set this to specific card type");
250
MODULE_PARM_DESC(sm_games,      "Enable support for Logitech soundman games");
251
MODULE_PARM_DESC(esstype,       "ESS chip type");
252
MODULE_PARM_DESC(acer,          "Set this to detect cards in some ACER notebooks");
253
 
254
#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
255
 
256
/* Please add new entries at the end of the table */
257
static 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; /* see sb_init() */
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
 
536
static 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
 
737
MODULE_DEVICE_TABLE(isapnp, id_table);
738
 
739
static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
740
{
741
        int err;
742
 
743
        /* Device already active? Let's use it */
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
 
757
static 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
        /* Configure Audio device */
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
                /* If device is active, assume configured with /proc/isapnp
766
                 * and use anyway. Some other way to check this? */
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
        /* Cards with separate OPL3 device (ALS, CMI, etc.)
789
         * This is just to activate the device so the OPL module can use it */
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
                        /* If device is active, assume configured with
794
                         * /proc/isapnp and use anyway */
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
                        /* Some have irq and dma for opl. the opl3 driver wont
803
                         * use 'em so don't configure 'em and hope it works -PEL */
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
        /* Cards with MPU as part of Audio device (CTL and ESS) */
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
        /* Cards with separate MPU device (ALS, CMI, etc.) */
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
                /* If device is active, assume configured with /proc/isapnp
825
                 * and use anyway */
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
                /* Some cards ask for irq but don't need them - azummo */
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
 
849
static 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
        /* Initialize this baby. */
856
 
857
        if(sb_init(bus, hw_config, mpu_config, slot, card)) {
858
                /* We got it. */
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
 
872
static 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
        /* Count entries in sb_isapnp_list */
878
        for (i = 0; sb_isapnp_list[i].card_vendor != 0; i++);
879
        i--;
880
 
881
        /* Check and adjust isapnpjump */
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; /* start next search from here */
900
                                return 0;
901
                        }
902
                }
903
                i += reverse ? -1 : 1;
904
        }
905
 
906
        return -ENODEV;
907
}
908
#endif
909
 
910
static 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
                /* Please remember that even with CONFIG_ISAPNP defined one
919
                 * should still be able to disable PNP support for this
920
                 * single driver! */
921
                if((!pnplegacy||card>0) && isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
922
                        if(!sb_cards_num) {
923
                                /* Found no ISAPnP cards, so check for a non-pnp
924
                                 * card and set the detection loop for 1 cycle
925
                                 */
926
                                printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n");
927
                                isapnp = 0;
928
                                max = 1;
929
                        } else
930
                                /* found all the ISAPnP cards so exit the
931
                                 * detection loop. */
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
                        /* if one or more cards already registered, don't
947
                         * return an error but print a warning. Note, this
948
                         * should never really happen unless the hardware
949
                         * or ISAPnP screwed up. */
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
 
991
static 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
 
1016
module_init(init_sb);
1017
module_exit(cleanup_sb);
1018
 
1019
#ifndef MODULE
1020
static int __init setup_sb(char *str)
1021
{
1022
        /* io, irq, dma, dma2 - just the basics */
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.