0001
0002
0003
0004
0005
0006
0007 #include <asm/dma.h>
0008 #include <linux/init.h>
0009 #include <linux/pnp.h>
0010 #include <linux/err.h>
0011 #include <linux/isa.h>
0012 #include <linux/module.h>
0013 #include <sound/core.h>
0014 #include <sound/sb.h>
0015 #include <sound/sb16_csp.h>
0016 #include <sound/mpu401.h>
0017 #include <sound/opl3.h>
0018 #include <sound/emu8000.h>
0019 #include <sound/seq_device.h>
0020 #define SNDRV_LEGACY_FIND_FREE_IRQ
0021 #define SNDRV_LEGACY_FIND_FREE_DMA
0022 #include <sound/initval.h>
0023
0024 #ifdef SNDRV_SBAWE
0025 #define PFX "sbawe: "
0026 #else
0027 #define PFX "sb16: "
0028 #endif
0029
0030 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
0031 MODULE_LICENSE("GPL");
0032 #ifndef SNDRV_SBAWE
0033 MODULE_DESCRIPTION("Sound Blaster 16");
0034 #else
0035 MODULE_DESCRIPTION("Sound Blaster AWE");
0036 #endif
0037
0038 #if 0
0039 #define SNDRV_DEBUG_IRQ
0040 #endif
0041
0042 #if defined(SNDRV_SBAWE) && IS_ENABLED(CONFIG_SND_SEQUENCER)
0043 #define SNDRV_SBAWE_EMU8000
0044 #endif
0045
0046 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0047 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0048 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
0049 #ifdef CONFIG_PNP
0050 static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
0051 #endif
0052 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0053 static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0054 static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0055 #ifdef SNDRV_SBAWE_EMU8000
0056 static long awe_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
0057 #endif
0058 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
0059 static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0060 static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
0061 static int mic_agc[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
0062 #ifdef CONFIG_SND_SB16_CSP
0063 static int csp[SNDRV_CARDS];
0064 #endif
0065 #ifdef SNDRV_SBAWE_EMU8000
0066 static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
0067 #endif
0068
0069 module_param_array(index, int, NULL, 0444);
0070 MODULE_PARM_DESC(index, "Index value for SoundBlaster 16 soundcard.");
0071 module_param_array(id, charp, NULL, 0444);
0072 MODULE_PARM_DESC(id, "ID string for SoundBlaster 16 soundcard.");
0073 module_param_array(enable, bool, NULL, 0444);
0074 MODULE_PARM_DESC(enable, "Enable SoundBlaster 16 soundcard.");
0075 #ifdef CONFIG_PNP
0076 module_param_array(isapnp, bool, NULL, 0444);
0077 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
0078 #endif
0079 module_param_hw_array(port, long, ioport, NULL, 0444);
0080 MODULE_PARM_DESC(port, "Port # for SB16 driver.");
0081 module_param_hw_array(mpu_port, long, ioport, NULL, 0444);
0082 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for SB16 driver.");
0083 module_param_hw_array(fm_port, long, ioport, NULL, 0444);
0084 MODULE_PARM_DESC(fm_port, "FM port # for SB16 PnP driver.");
0085 #ifdef SNDRV_SBAWE_EMU8000
0086 module_param_hw_array(awe_port, long, ioport, NULL, 0444);
0087 MODULE_PARM_DESC(awe_port, "AWE port # for SB16 PnP driver.");
0088 #endif
0089 module_param_hw_array(irq, int, irq, NULL, 0444);
0090 MODULE_PARM_DESC(irq, "IRQ # for SB16 driver.");
0091 module_param_hw_array(dma8, int, dma, NULL, 0444);
0092 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB16 driver.");
0093 module_param_hw_array(dma16, int, dma, NULL, 0444);
0094 MODULE_PARM_DESC(dma16, "16-bit DMA # for SB16 driver.");
0095 module_param_array(mic_agc, int, NULL, 0444);
0096 MODULE_PARM_DESC(mic_agc, "Mic Auto-Gain-Control switch.");
0097 #ifdef CONFIG_SND_SB16_CSP
0098 module_param_array(csp, int, NULL, 0444);
0099 MODULE_PARM_DESC(csp, "ASP/CSP chip support.");
0100 #endif
0101 #ifdef SNDRV_SBAWE_EMU8000
0102 module_param_array(seq_ports, int, NULL, 0444);
0103 MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
0104 #endif
0105
0106 #ifdef CONFIG_PNP
0107 static int isa_registered;
0108 static int pnp_registered;
0109 #endif
0110
0111 struct snd_card_sb16 {
0112 struct resource *fm_res;
0113 struct snd_sb *chip;
0114 #ifdef CONFIG_PNP
0115 int dev_no;
0116 struct pnp_dev *dev;
0117 #ifdef SNDRV_SBAWE_EMU8000
0118 struct pnp_dev *devwt;
0119 #endif
0120 #endif
0121 };
0122
0123 #ifdef CONFIG_PNP
0124
0125 static const struct pnp_card_device_id snd_sb16_pnpids[] = {
0126 #ifndef SNDRV_SBAWE
0127
0128 { .id = "CTL0024", .devs = { { "CTL0031" } } },
0129
0130 { .id = "CTL0025", .devs = { { "CTL0031" } } },
0131
0132 { .id = "CTL0026", .devs = { { "CTL0031" } } },
0133
0134 { .id = "CTL0027", .devs = { { "CTL0031" } } },
0135
0136 { .id = "CTL0028", .devs = { { "CTL0031" } } },
0137
0138 { .id = "CTL0029", .devs = { { "CTL0031" } } },
0139
0140 { .id = "CTL002a", .devs = { { "CTL0031" } } },
0141
0142
0143 { .id = "CTL002b", .devs = { { "CTL0031" } } },
0144
0145 { .id = "CTL002c", .devs = { { "CTL0031" } } },
0146
0147 { .id = "CTL0051", .devs = { { "CTL0001" } } },
0148
0149 { .id = "CTL0070", .devs = { { "CTL0001" } } },
0150
0151 { .id = "CTL0080", .devs = { { "CTL0041" } } },
0152
0153
0154 { .id = "CTL0086", .devs = { { "CTL0041" } } },
0155
0156 { .id = "CTL00f0", .devs = { { "CTL0043" } } },
0157
0158 { .id = "tBA03b0", .devs = { {.id="PNPb003" } } },
0159 #else
0160
0161 { .id = "CTL0035", .devs = { { "CTL0031" }, { "CTL0021" } } },
0162
0163 { .id = "CTL0039", .devs = { { "CTL0031" }, { "CTL0021" } } },
0164
0165 { .id = "CTL0042", .devs = { { "CTL0031" }, { "CTL0021" } } },
0166
0167 { .id = "CTL0043", .devs = { { "CTL0031" }, { "CTL0021" } } },
0168
0169
0170 { .id = "CTL0044", .devs = { { "CTL0031" }, { "CTL0021" } } },
0171
0172
0173 { .id = "CTL0045", .devs = { { "CTL0031" }, { "CTL0021" } } },
0174
0175 { .id = "CTL0046", .devs = { { "CTL0031" }, { "CTL0021" } } },
0176
0177 { .id = "CTL0047", .devs = { { "CTL0031" }, { "CTL0021" } } },
0178
0179 { .id = "CTL0048", .devs = { { "CTL0031" }, { "CTL0021" } } },
0180
0181 { .id = "CTL0054", .devs = { { "CTL0031" }, { "CTL0021" } } },
0182
0183 { .id = "CTL009a", .devs = { { "CTL0041" }, { "CTL0021" } } },
0184
0185 { .id = "CTL009c", .devs = { { "CTL0041" }, { "CTL0021" } } },
0186
0187 { .id = "CTL009f", .devs = { { "CTL0041" }, { "CTL0021" } } },
0188
0189 { .id = "CTL009d", .devs = { { "CTL0042" }, { "CTL0022" } } },
0190
0191 { .id = "CTL009e", .devs = { { "CTL0044" }, { "CTL0023" } } },
0192
0193 { .id = "CTL00b2", .devs = { { "CTL0044" }, { "CTL0023" } } },
0194
0195 { .id = "CTL00c1", .devs = { { "CTL0042" }, { "CTL0022" } } },
0196
0197 { .id = "CTL00c3", .devs = { { "CTL0045" }, { "CTL0022" } } },
0198
0199 { .id = "CTL00c5", .devs = { { "CTL0045" }, { "CTL0022" } } },
0200
0201 { .id = "CTL00c7", .devs = { { "CTL0045" }, { "CTL0022" } } },
0202
0203 { .id = "CTL00e4", .devs = { { "CTL0045" }, { "CTL0022" } } },
0204
0205 { .id = "CTL00e9", .devs = { { "CTL0045" }, { "CTL0022" } } },
0206
0207 { .id = "CTL00ed", .devs = { { "CTL0041" }, { "CTL0070" } } },
0208
0209 { .id = "CTLXXXX" , .devs = { { "CTL0031" }, { "CTL0021" } } },
0210 { .id = "CTLXXXX" , .devs = { { "CTL0041" }, { "CTL0021" } } },
0211 { .id = "CTLXXXX" , .devs = { { "CTL0042" }, { "CTL0022" } } },
0212 { .id = "CTLXXXX" , .devs = { { "CTL0044" }, { "CTL0023" } } },
0213 { .id = "CTLXXXX" , .devs = { { "CTL0045" }, { "CTL0022" } } },
0214 #endif
0215 { .id = "", }
0216 };
0217
0218 MODULE_DEVICE_TABLE(pnp_card, snd_sb16_pnpids);
0219
0220 #endif
0221
0222 #ifdef SNDRV_SBAWE_EMU8000
0223 #define DRIVER_NAME "snd-card-sbawe"
0224 #else
0225 #define DRIVER_NAME "snd-card-sb16"
0226 #endif
0227
0228 #ifdef CONFIG_PNP
0229
0230 static int snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard,
0231 struct pnp_card_link *card,
0232 const struct pnp_card_device_id *id)
0233 {
0234 struct pnp_dev *pdev;
0235 int err;
0236
0237 acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
0238 if (acard->dev == NULL)
0239 return -ENODEV;
0240
0241 #ifdef SNDRV_SBAWE_EMU8000
0242 acard->devwt = pnp_request_card_device(card, id->devs[1].id, acard->dev);
0243 #endif
0244
0245 pdev = acard->dev;
0246
0247 err = pnp_activate_dev(pdev);
0248 if (err < 0) {
0249 snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
0250 return err;
0251 }
0252 port[dev] = pnp_port_start(pdev, 0);
0253 mpu_port[dev] = pnp_port_start(pdev, 1);
0254 fm_port[dev] = pnp_port_start(pdev, 2);
0255 dma8[dev] = pnp_dma(pdev, 0);
0256 dma16[dev] = pnp_dma(pdev, 1);
0257 irq[dev] = pnp_irq(pdev, 0);
0258 snd_printdd("pnp SB16: port=0x%lx, mpu port=0x%lx, fm port=0x%lx\n",
0259 port[dev], mpu_port[dev], fm_port[dev]);
0260 snd_printdd("pnp SB16: dma1=%i, dma2=%i, irq=%i\n",
0261 dma8[dev], dma16[dev], irq[dev]);
0262 #ifdef SNDRV_SBAWE_EMU8000
0263
0264 pdev = acard->devwt;
0265 if (pdev != NULL) {
0266 err = pnp_activate_dev(pdev);
0267 if (err < 0) {
0268 goto __wt_error;
0269 }
0270 awe_port[dev] = pnp_port_start(pdev, 0);
0271 snd_printdd("pnp SB16: wavetable port=0x%llx\n",
0272 (unsigned long long)pnp_port_start(pdev, 0));
0273 } else {
0274 __wt_error:
0275 if (pdev) {
0276 pnp_release_card_device(pdev);
0277 snd_printk(KERN_ERR PFX "WaveTable pnp configure failure\n");
0278 }
0279 acard->devwt = NULL;
0280 awe_port[dev] = -1;
0281 }
0282 #endif
0283 return 0;
0284 }
0285
0286 #endif
0287
0288 #ifdef CONFIG_PNP
0289 #define is_isapnp_selected(dev) isapnp[dev]
0290 #else
0291 #define is_isapnp_selected(dev) 0
0292 #endif
0293
0294 static int snd_sb16_card_new(struct device *devptr, int dev,
0295 struct snd_card **cardp)
0296 {
0297 struct snd_card *card;
0298 int err;
0299
0300 err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE,
0301 sizeof(struct snd_card_sb16), &card);
0302 if (err < 0)
0303 return err;
0304 *cardp = card;
0305 return 0;
0306 }
0307
0308 static int snd_sb16_probe(struct snd_card *card, int dev)
0309 {
0310 int xirq, xdma8, xdma16;
0311 struct snd_sb *chip;
0312 struct snd_card_sb16 *acard = card->private_data;
0313 struct snd_opl3 *opl3;
0314 struct snd_hwdep *synth = NULL;
0315 #ifdef CONFIG_SND_SB16_CSP
0316 struct snd_hwdep *xcsp = NULL;
0317 #endif
0318 unsigned long flags;
0319 int err;
0320
0321 xirq = irq[dev];
0322 xdma8 = dma8[dev];
0323 xdma16 = dma16[dev];
0324
0325 err = snd_sbdsp_create(card, port[dev], xirq, snd_sb16dsp_interrupt,
0326 xdma8, xdma16, SB_HW_AUTO, &chip);
0327 if (err < 0)
0328 return err;
0329
0330 acard->chip = chip;
0331 if (chip->hardware != SB_HW_16) {
0332 snd_printk(KERN_ERR PFX "SB 16 chip was not detected at 0x%lx\n", port[dev]);
0333 return -ENODEV;
0334 }
0335 chip->mpu_port = mpu_port[dev];
0336 if (!is_isapnp_selected(dev)) {
0337 err = snd_sb16dsp_configure(chip);
0338 if (err < 0)
0339 return err;
0340 }
0341
0342 err = snd_sb16dsp_pcm(chip, 0);
0343 if (err < 0)
0344 return err;
0345
0346 strcpy(card->driver,
0347 #ifdef SNDRV_SBAWE_EMU8000
0348 awe_port[dev] > 0 ? "SB AWE" :
0349 #endif
0350 "SB16");
0351 strcpy(card->shortname, chip->name);
0352 sprintf(card->longname, "%s at 0x%lx, irq %i, dma ",
0353 chip->name,
0354 chip->port,
0355 xirq);
0356 if (xdma8 >= 0)
0357 sprintf(card->longname + strlen(card->longname), "%d", xdma8);
0358 if (xdma16 >= 0)
0359 sprintf(card->longname + strlen(card->longname), "%s%d",
0360 xdma8 >= 0 ? "&" : "", xdma16);
0361
0362 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
0363 err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
0364 chip->mpu_port,
0365 MPU401_INFO_IRQ_HOOK, -1,
0366 &chip->rmidi);
0367 if (err < 0)
0368 return err;
0369 chip->rmidi_callback = snd_mpu401_uart_interrupt;
0370 }
0371
0372 #ifdef SNDRV_SBAWE_EMU8000
0373 if (awe_port[dev] == SNDRV_AUTO_PORT)
0374 awe_port[dev] = 0;
0375 #endif
0376
0377 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
0378 if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
0379 OPL3_HW_OPL3,
0380 acard->fm_res != NULL || fm_port[dev] == port[dev],
0381 &opl3) < 0) {
0382 snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
0383 fm_port[dev], fm_port[dev] + 2);
0384 } else {
0385 #ifdef SNDRV_SBAWE_EMU8000
0386 int seqdev = awe_port[dev] > 0 ? 2 : 1;
0387 #else
0388 int seqdev = 1;
0389 #endif
0390 err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth);
0391 if (err < 0)
0392 return err;
0393 }
0394 }
0395
0396 err = snd_sbmixer_new(chip);
0397 if (err < 0)
0398 return err;
0399
0400 #ifdef CONFIG_SND_SB16_CSP
0401
0402 if ((chip->hardware == SB_HW_16) && csp[dev]) {
0403 snd_sb_csp_new(chip, synth != NULL ? 1 : 0, &xcsp);
0404 if (xcsp) {
0405 chip->csp = xcsp->private_data;
0406 chip->hardware = SB_HW_16CSP;
0407 } else {
0408 snd_printk(KERN_INFO PFX "warning - CSP chip not detected on soundcard #%i\n", dev + 1);
0409 }
0410 }
0411 #endif
0412 #ifdef SNDRV_SBAWE_EMU8000
0413 if (awe_port[dev] > 0) {
0414 err = snd_emu8000_new(card, 1, awe_port[dev],
0415 seq_ports[dev], NULL);
0416 if (err < 0) {
0417 snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]);
0418
0419 return err;
0420 }
0421 }
0422 #endif
0423
0424
0425 spin_lock_irqsave(&chip->mixer_lock, flags);
0426 snd_sbmixer_write(chip, SB_DSP4_MIC_AGC,
0427 (snd_sbmixer_read(chip, SB_DSP4_MIC_AGC) & 0x01) |
0428 (mic_agc[dev] ? 0x00 : 0x01));
0429 spin_unlock_irqrestore(&chip->mixer_lock, flags);
0430
0431 err = snd_card_register(card);
0432 if (err < 0)
0433 return err;
0434
0435 return 0;
0436 }
0437
0438 #ifdef CONFIG_PM
0439 static int snd_sb16_suspend(struct snd_card *card, pm_message_t state)
0440 {
0441 struct snd_card_sb16 *acard = card->private_data;
0442 struct snd_sb *chip = acard->chip;
0443
0444 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
0445 snd_sbmixer_suspend(chip);
0446 return 0;
0447 }
0448
0449 static int snd_sb16_resume(struct snd_card *card)
0450 {
0451 struct snd_card_sb16 *acard = card->private_data;
0452 struct snd_sb *chip = acard->chip;
0453
0454 snd_sbdsp_reset(chip);
0455 snd_sbmixer_resume(chip);
0456 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
0457 return 0;
0458 }
0459 #endif
0460
0461 static int snd_sb16_isa_probe1(int dev, struct device *pdev)
0462 {
0463 struct snd_card_sb16 *acard;
0464 struct snd_card *card;
0465 int err;
0466
0467 err = snd_sb16_card_new(pdev, dev, &card);
0468 if (err < 0)
0469 return err;
0470
0471 acard = card->private_data;
0472
0473 fm_port[dev] = port[dev];
0474
0475 acard->fm_res = devm_request_region(card->dev, 0x388, 4,
0476 "SoundBlaster FM");
0477 #ifdef SNDRV_SBAWE_EMU8000
0478
0479 awe_port[dev] = port[dev] + 0x400;
0480 #endif
0481
0482 err = snd_sb16_probe(card, dev);
0483 if (err < 0)
0484 return err;
0485 dev_set_drvdata(pdev, card);
0486 return 0;
0487 }
0488
0489
0490 static int snd_sb16_isa_match(struct device *pdev, unsigned int dev)
0491 {
0492 return enable[dev] && !is_isapnp_selected(dev);
0493 }
0494
0495 static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
0496 {
0497 int err;
0498 static const int possible_irqs[] = {5, 9, 10, 7, -1};
0499 static const int possible_dmas8[] = {1, 3, 0, -1};
0500 static const int possible_dmas16[] = {5, 6, 7, -1};
0501
0502 if (irq[dev] == SNDRV_AUTO_IRQ) {
0503 irq[dev] = snd_legacy_find_free_irq(possible_irqs);
0504 if (irq[dev] < 0) {
0505 snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
0506 return -EBUSY;
0507 }
0508 }
0509 if (dma8[dev] == SNDRV_AUTO_DMA) {
0510 dma8[dev] = snd_legacy_find_free_dma(possible_dmas8);
0511 if (dma8[dev] < 0) {
0512 snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
0513 return -EBUSY;
0514 }
0515 }
0516 if (dma16[dev] == SNDRV_AUTO_DMA) {
0517 dma16[dev] = snd_legacy_find_free_dma(possible_dmas16);
0518 if (dma16[dev] < 0) {
0519 snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
0520 return -EBUSY;
0521 }
0522 }
0523
0524 if (port[dev] != SNDRV_AUTO_PORT)
0525 return snd_sb16_isa_probe1(dev, pdev);
0526 else {
0527 static const int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
0528 int i;
0529 for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
0530 port[dev] = possible_ports[i];
0531 err = snd_sb16_isa_probe1(dev, pdev);
0532 if (! err)
0533 return 0;
0534 }
0535 return err;
0536 }
0537 }
0538
0539 #ifdef CONFIG_PM
0540 static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
0541 pm_message_t state)
0542 {
0543 return snd_sb16_suspend(dev_get_drvdata(dev), state);
0544 }
0545
0546 static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
0547 {
0548 return snd_sb16_resume(dev_get_drvdata(dev));
0549 }
0550 #endif
0551
0552 #ifdef SNDRV_SBAWE
0553 #define DEV_NAME "sbawe"
0554 #else
0555 #define DEV_NAME "sb16"
0556 #endif
0557
0558 static struct isa_driver snd_sb16_isa_driver = {
0559 .match = snd_sb16_isa_match,
0560 .probe = snd_sb16_isa_probe,
0561 #ifdef CONFIG_PM
0562 .suspend = snd_sb16_isa_suspend,
0563 .resume = snd_sb16_isa_resume,
0564 #endif
0565 .driver = {
0566 .name = DEV_NAME
0567 },
0568 };
0569
0570
0571 #ifdef CONFIG_PNP
0572 static int snd_sb16_pnp_detect(struct pnp_card_link *pcard,
0573 const struct pnp_card_device_id *pid)
0574 {
0575 static int dev;
0576 struct snd_card *card;
0577 int res;
0578
0579 for ( ; dev < SNDRV_CARDS; dev++) {
0580 if (!enable[dev] || !isapnp[dev])
0581 continue;
0582 res = snd_sb16_card_new(&pcard->card->dev, dev, &card);
0583 if (res < 0)
0584 return res;
0585 res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid);
0586 if (res < 0)
0587 return res;
0588 res = snd_sb16_probe(card, dev);
0589 if (res < 0)
0590 return res;
0591 pnp_set_card_drvdata(pcard, card);
0592 dev++;
0593 return 0;
0594 }
0595
0596 return -ENODEV;
0597 }
0598
0599 #ifdef CONFIG_PM
0600 static int snd_sb16_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
0601 {
0602 return snd_sb16_suspend(pnp_get_card_drvdata(pcard), state);
0603 }
0604 static int snd_sb16_pnp_resume(struct pnp_card_link *pcard)
0605 {
0606 return snd_sb16_resume(pnp_get_card_drvdata(pcard));
0607 }
0608 #endif
0609
0610 static struct pnp_card_driver sb16_pnpc_driver = {
0611 .flags = PNP_DRIVER_RES_DISABLE,
0612 #ifdef SNDRV_SBAWE
0613 .name = "sbawe",
0614 #else
0615 .name = "sb16",
0616 #endif
0617 .id_table = snd_sb16_pnpids,
0618 .probe = snd_sb16_pnp_detect,
0619 #ifdef CONFIG_PM
0620 .suspend = snd_sb16_pnp_suspend,
0621 .resume = snd_sb16_pnp_resume,
0622 #endif
0623 };
0624
0625 #endif
0626
0627 static int __init alsa_card_sb16_init(void)
0628 {
0629 int err;
0630
0631 err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
0632 #ifdef CONFIG_PNP
0633 if (!err)
0634 isa_registered = 1;
0635
0636 err = pnp_register_card_driver(&sb16_pnpc_driver);
0637 if (!err)
0638 pnp_registered = 1;
0639
0640 if (isa_registered)
0641 err = 0;
0642 #endif
0643 return err;
0644 }
0645
0646 static void __exit alsa_card_sb16_exit(void)
0647 {
0648 #ifdef CONFIG_PNP
0649 if (pnp_registered)
0650 pnp_unregister_card_driver(&sb16_pnpc_driver);
0651 if (isa_registered)
0652 #endif
0653 isa_unregister_driver(&snd_sb16_isa_driver);
0654 }
0655
0656 module_init(alsa_card_sb16_init)
0657 module_exit(alsa_card_sb16_exit)