aboutsummaryrefslogtreecommitdiffstats
path: root/sound/isa/opl3sa2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/isa/opl3sa2.c')
-rw-r--r--sound/isa/opl3sa2.c556
1 files changed, 308 insertions, 248 deletions
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 47cabda792b6..ca359e0c674b 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -21,6 +21,8 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/err.h>
25#include <linux/platform_device.h>
24#include <linux/interrupt.h> 26#include <linux/interrupt.h>
25#include <linux/pm.h> 27#include <linux/pm.h>
26#include <linux/slab.h> 28#include <linux/slab.h>
@@ -88,6 +90,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
88module_param_array(opl3sa3_ymode, int, NULL, 0444); 90module_param_array(opl3sa3_ymode, int, NULL, 0444);
89MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); 91MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
90 92
93static struct platform_device *platform_devices[SNDRV_CARDS];
94static int pnp_registered;
95static int pnpc_registered;
96
91/* control ports */ 97/* control ports */
92#define OPL3SA2_PM_CTRL 0x01 98#define OPL3SA2_PM_CTRL 0x01
93#define OPL3SA2_SYS_CTRL 0x02 99#define OPL3SA2_SYS_CTRL 0x02
@@ -115,34 +121,23 @@ MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode:
115#define OPL3SA2_PM_D0 0x00 121#define OPL3SA2_PM_D0 0x00
116#define OPL3SA2_PM_D3 (OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX) 122#define OPL3SA2_PM_D3 (OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX)
117 123
118typedef struct snd_opl3sa2 opl3sa2_t;
119
120struct snd_opl3sa2 { 124struct snd_opl3sa2 {
121 snd_card_t *card; 125 struct snd_card *card;
122 int version; /* 2 or 3 */ 126 int version; /* 2 or 3 */
123 unsigned long port; /* control port */ 127 unsigned long port; /* control port */
124 struct resource *res_port; /* control port resource */ 128 struct resource *res_port; /* control port resource */
125 int irq; 129 int irq;
126 int single_dma; 130 int single_dma;
127 spinlock_t reg_lock; 131 spinlock_t reg_lock;
128 snd_hwdep_t *synth; 132 struct snd_hwdep *synth;
129 snd_rawmidi_t *rmidi; 133 struct snd_rawmidi *rmidi;
130 cs4231_t *cs4231; 134 struct snd_cs4231 *cs4231;
131#ifdef CONFIG_PNP
132 struct pnp_dev *dev;
133#endif
134 unsigned char ctlregs[0x20]; 135 unsigned char ctlregs[0x20];
135 int ymode; /* SL added */ 136 int ymode; /* SL added */
136 snd_kcontrol_t *master_switch; 137 struct snd_kcontrol *master_switch;
137 snd_kcontrol_t *master_volume; 138 struct snd_kcontrol *master_volume;
138#ifdef CONFIG_PM
139 void (*cs4231_suspend)(cs4231_t *);
140 void (*cs4231_resume)(cs4231_t *);
141#endif
142}; 139};
143 140
144static snd_card_t *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
145
146#define PFX "opl3sa2: " 141#define PFX "opl3sa2: "
147 142
148#ifdef CONFIG_PNP 143#ifdef CONFIG_PNP
@@ -176,7 +171,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opl3sa2_pnpids);
176 171
177 172
178/* read control port (w/o spinlock) */ 173/* read control port (w/o spinlock) */
179static unsigned char __snd_opl3sa2_read(opl3sa2_t *chip, unsigned char reg) 174static unsigned char __snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
180{ 175{
181 unsigned char result; 176 unsigned char result;
182#if 0 177#if 0
@@ -192,7 +187,7 @@ static unsigned char __snd_opl3sa2_read(opl3sa2_t *chip, unsigned char reg)
192} 187}
193 188
194/* read control port (with spinlock) */ 189/* read control port (with spinlock) */
195static unsigned char snd_opl3sa2_read(opl3sa2_t *chip, unsigned char reg) 190static unsigned char snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
196{ 191{
197 unsigned long flags; 192 unsigned long flags;
198 unsigned char result; 193 unsigned char result;
@@ -204,7 +199,7 @@ static unsigned char snd_opl3sa2_read(opl3sa2_t *chip, unsigned char reg)
204} 199}
205 200
206/* write control port (w/o spinlock) */ 201/* write control port (w/o spinlock) */
207static void __snd_opl3sa2_write(opl3sa2_t *chip, unsigned char reg, unsigned char value) 202static void __snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
208{ 203{
209#if 0 204#if 0
210 outb(0x1d, port); /* password */ 205 outb(0x1d, port); /* password */
@@ -215,7 +210,7 @@ static void __snd_opl3sa2_write(opl3sa2_t *chip, unsigned char reg, unsigned cha
215} 210}
216 211
217/* write control port (with spinlock) */ 212/* write control port (with spinlock) */
218static void snd_opl3sa2_write(opl3sa2_t *chip, unsigned char reg, unsigned char value) 213static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
219{ 214{
220 unsigned long flags; 215 unsigned long flags;
221 spin_lock_irqsave(&chip->reg_lock, flags); 216 spin_lock_irqsave(&chip->reg_lock, flags);
@@ -223,9 +218,9 @@ static void snd_opl3sa2_write(opl3sa2_t *chip, unsigned char reg, unsigned char
223 spin_unlock_irqrestore(&chip->reg_lock, flags); 218 spin_unlock_irqrestore(&chip->reg_lock, flags);
224} 219}
225 220
226static int __init snd_opl3sa2_detect(opl3sa2_t *chip) 221static int __init snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
227{ 222{
228 snd_card_t *card; 223 struct snd_card *card;
229 unsigned long port; 224 unsigned long port;
230 unsigned char tmp, tmp1; 225 unsigned char tmp, tmp1;
231 char str[2]; 226 char str[2];
@@ -298,7 +293,7 @@ static int __init snd_opl3sa2_detect(opl3sa2_t *chip)
298static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *regs) 293static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
299{ 294{
300 unsigned short status; 295 unsigned short status;
301 opl3sa2_t *chip = dev_id; 296 struct snd_opl3sa2 *chip = dev_id;
302 int handled = 0; 297 int handled = 0;
303 298
304 if (chip == NULL || chip->card == NULL) 299 if (chip == NULL || chip->card == NULL)
@@ -340,7 +335,7 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *
340 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \ 335 .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
341 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 336 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
342 337
343static int snd_opl3sa2_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 338static int snd_opl3sa2_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
344{ 339{
345 int mask = (kcontrol->private_value >> 16) & 0xff; 340 int mask = (kcontrol->private_value >> 16) & 0xff;
346 341
@@ -351,9 +346,9 @@ static int snd_opl3sa2_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
351 return 0; 346 return 0;
352} 347}
353 348
354static int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 349static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
355{ 350{
356 opl3sa2_t *chip = snd_kcontrol_chip(kcontrol); 351 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
357 unsigned long flags; 352 unsigned long flags;
358 int reg = kcontrol->private_value & 0xff; 353 int reg = kcontrol->private_value & 0xff;
359 int shift = (kcontrol->private_value >> 8) & 0xff; 354 int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -368,9 +363,9 @@ static int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
368 return 0; 363 return 0;
369} 364}
370 365
371static int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 366static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
372{ 367{
373 opl3sa2_t *chip = snd_kcontrol_chip(kcontrol); 368 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
374 unsigned long flags; 369 unsigned long flags;
375 int reg = kcontrol->private_value & 0xff; 370 int reg = kcontrol->private_value & 0xff;
376 int shift = (kcontrol->private_value >> 8) & 0xff; 371 int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -398,7 +393,7 @@ static int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
398 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \ 393 .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
399 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 394 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
400 395
401static int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 396static int snd_opl3sa2_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
402{ 397{
403 int mask = (kcontrol->private_value >> 24) & 0xff; 398 int mask = (kcontrol->private_value >> 24) & 0xff;
404 399
@@ -409,9 +404,9 @@ static int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t
409 return 0; 404 return 0;
410} 405}
411 406
412static int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 407static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
413{ 408{
414 opl3sa2_t *chip = snd_kcontrol_chip(kcontrol); 409 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
415 unsigned long flags; 410 unsigned long flags;
416 int left_reg = kcontrol->private_value & 0xff; 411 int left_reg = kcontrol->private_value & 0xff;
417 int right_reg = (kcontrol->private_value >> 8) & 0xff; 412 int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -431,9 +426,9 @@ static int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
431 return 0; 426 return 0;
432} 427}
433 428
434static int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 429static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
435{ 430{
436 opl3sa2_t *chip = snd_kcontrol_chip(kcontrol); 431 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
437 unsigned long flags; 432 unsigned long flags;
438 int left_reg = kcontrol->private_value & 0xff; 433 int left_reg = kcontrol->private_value & 0xff;
439 int right_reg = (kcontrol->private_value >> 8) & 0xff; 434 int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -471,31 +466,31 @@ static int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
471 return change; 466 return change;
472} 467}
473 468
474static snd_kcontrol_new_t snd_opl3sa2_controls[] = { 469static struct snd_kcontrol_new snd_opl3sa2_controls[] = {
475OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1), 470OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1),
476OPL3SA2_DOUBLE("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1), 471OPL3SA2_DOUBLE("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1),
477OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1), 472OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1),
478OPL3SA2_SINGLE("Mic Playback Volume", 0, 0x09, 0, 31, 1) 473OPL3SA2_SINGLE("Mic Playback Volume", 0, 0x09, 0, 31, 1)
479}; 474};
480 475
481static snd_kcontrol_new_t snd_opl3sa2_tone_controls[] = { 476static struct snd_kcontrol_new snd_opl3sa2_tone_controls[] = {
482OPL3SA2_DOUBLE("3D Control - Wide", 0, 0x14, 0x14, 4, 0, 7, 0), 477OPL3SA2_DOUBLE("3D Control - Wide", 0, 0x14, 0x14, 4, 0, 7, 0),
483OPL3SA2_DOUBLE("Tone Control - Bass", 0, 0x15, 0x15, 4, 0, 7, 0), 478OPL3SA2_DOUBLE("Tone Control - Bass", 0, 0x15, 0x15, 4, 0, 7, 0),
484OPL3SA2_DOUBLE("Tone Control - Treble", 0, 0x16, 0x16, 4, 0, 7, 0) 479OPL3SA2_DOUBLE("Tone Control - Treble", 0, 0x16, 0x16, 4, 0, 7, 0)
485}; 480};
486 481
487static void snd_opl3sa2_master_free(snd_kcontrol_t *kcontrol) 482static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol)
488{ 483{
489 opl3sa2_t *chip = snd_kcontrol_chip(kcontrol); 484 struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
490 chip->master_switch = NULL; 485 chip->master_switch = NULL;
491 chip->master_volume = NULL; 486 chip->master_volume = NULL;
492} 487}
493 488
494static int __init snd_opl3sa2_mixer(opl3sa2_t *chip) 489static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip)
495{ 490{
496 snd_card_t *card = chip->card; 491 struct snd_card *card = chip->card;
497 snd_ctl_elem_id_t id1, id2; 492 struct snd_ctl_elem_id id1, id2;
498 snd_kcontrol_t *kctl; 493 struct snd_kcontrol *kctl;
499 unsigned int idx; 494 unsigned int idx;
500 int err; 495 int err;
501 496
@@ -505,21 +500,29 @@ static int __init snd_opl3sa2_mixer(opl3sa2_t *chip)
505 /* reassign AUX0 to CD */ 500 /* reassign AUX0 to CD */
506 strcpy(id1.name, "Aux Playback Switch"); 501 strcpy(id1.name, "Aux Playback Switch");
507 strcpy(id2.name, "CD Playback Switch"); 502 strcpy(id2.name, "CD Playback Switch");
508 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) 503 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
504 snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
509 return err; 505 return err;
506 }
510 strcpy(id1.name, "Aux Playback Volume"); 507 strcpy(id1.name, "Aux Playback Volume");
511 strcpy(id2.name, "CD Playback Volume"); 508 strcpy(id2.name, "CD Playback Volume");
512 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) 509 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
510 snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
513 return err; 511 return err;
512 }
514 /* reassign AUX1 to FM */ 513 /* reassign AUX1 to FM */
515 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1; 514 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
516 strcpy(id2.name, "FM Playback Switch"); 515 strcpy(id2.name, "FM Playback Switch");
517 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) 516 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
517 snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
518 return err; 518 return err;
519 }
519 strcpy(id1.name, "Aux Playback Volume"); 520 strcpy(id1.name, "Aux Playback Volume");
520 strcpy(id2.name, "FM Playback Volume"); 521 strcpy(id2.name, "FM Playback Volume");
521 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) 522 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
523 snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
522 return err; 524 return err;
525 }
523 /* add OPL3SA2 controls */ 526 /* add OPL3SA2 controls */
524 for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) { 527 for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) {
525 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0) 528 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0)
@@ -539,22 +542,21 @@ static int __init snd_opl3sa2_mixer(opl3sa2_t *chip)
539 542
540/* Power Management support functions */ 543/* Power Management support functions */
541#ifdef CONFIG_PM 544#ifdef CONFIG_PM
542static int snd_opl3sa2_suspend(snd_card_t *card, pm_message_t state) 545static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
543{ 546{
544 opl3sa2_t *chip = card->pm_private_data; 547 struct snd_opl3sa2 *chip = card->private_data;
545
546 snd_pcm_suspend_all(chip->cs4231->pcm); /* stop before saving regs */
547 chip->cs4231_suspend(chip->cs4231);
548 548
549 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
550 chip->cs4231->suspend(chip->cs4231);
549 /* power down */ 551 /* power down */
550 snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); 552 snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
551 553
552 return 0; 554 return 0;
553} 555}
554 556
555static int snd_opl3sa2_resume(snd_card_t *card) 557static int snd_opl3sa2_resume(struct snd_card *card)
556{ 558{
557 opl3sa2_t *chip = card->pm_private_data; 559 struct snd_opl3sa2 *chip = card->private_data;
558 int i; 560 int i;
559 561
560 /* power up */ 562 /* power up */
@@ -570,26 +572,25 @@ static int snd_opl3sa2_resume(snd_card_t *card)
570 snd_opl3sa2_write(chip, i, chip->ctlregs[i]); 572 snd_opl3sa2_write(chip, i, chip->ctlregs[i]);
571 } 573 }
572 /* restore cs4231 */ 574 /* restore cs4231 */
573 chip->cs4231_resume(chip->cs4231); 575 chip->cs4231->resume(chip->cs4231);
574 576
577 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
575 return 0; 578 return 0;
576} 579}
577#endif /* CONFIG_PM */ 580#endif /* CONFIG_PM */
578 581
579#ifdef CONFIG_PNP 582#ifdef CONFIG_PNP
580static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip, 583static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
581 struct pnp_dev *pdev, 584 struct pnp_dev *pdev)
582 int isapnp)
583{ 585{
584 struct pnp_resource_table * cfg; 586 struct pnp_resource_table * cfg;
585 int err; 587 int err;
586 588
587 if (!isapnp && pnp_device_is_isapnp(pdev))
588 return -ENOENT; /* we have another procedure - card */
589
590 cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); 589 cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
591 if (!cfg) 590 if (!cfg) {
591 snd_printk(KERN_ERR PFX "cannot allocate pnp cfg\n");
592 return -ENOMEM; 592 return -ENOMEM;
593 }
593 /* PnP initialization */ 594 /* PnP initialization */
594 pnp_init_resource_table(cfg); 595 pnp_init_resource_table(cfg);
595 if (sb_port[dev] != SNDRV_AUTO_PORT) 596 if (sb_port[dev] != SNDRV_AUTO_PORT)
@@ -609,8 +610,8 @@ static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip,
609 if (irq[dev] != SNDRV_AUTO_IRQ) 610 if (irq[dev] != SNDRV_AUTO_IRQ)
610 pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1); 611 pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
611 err = pnp_manual_config_dev(pdev, cfg, 0); 612 err = pnp_manual_config_dev(pdev, cfg, 0);
612 if (err < 0 && isapnp) 613 if (err < 0)
613 snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n"); 614 snd_printk(KERN_WARNING "PnP manual resources are invalid, using auto config\n");
614 err = pnp_activate_dev(pdev); 615 err = pnp_activate_dev(pdev);
615 if (err < 0) { 616 if (err < 0) {
616 kfree(cfg); 617 kfree(cfg);
@@ -630,111 +631,47 @@ static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip,
630 snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n", 631 snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n",
631 pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]); 632 pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]);
632 kfree(cfg); 633 kfree(cfg);
633 chip->dev = pdev;
634 return 0; 634 return 0;
635} 635}
636
637static int __init snd_opl3sa2_cpnp(int dev, opl3sa2_t *chip,
638 struct pnp_card_link *card,
639 const struct pnp_card_device_id *id)
640{
641 struct pnp_dev *pdev;
642 struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
643
644 if (!cfg)
645 return -ENOMEM;
646 pdev = pnp_request_card_device(card, id->devs[0].id, NULL);
647 if (pdev == NULL) {
648 kfree(cfg);
649 return -EBUSY;
650 }
651 return snd_opl3sa2_pnp(dev, chip, pdev, 1);
652}
653#endif /* CONFIG_PNP */ 636#endif /* CONFIG_PNP */
654 637
655static int snd_opl3sa2_free(opl3sa2_t *chip) 638static void snd_opl3sa2_free(struct snd_card *card)
656{ 639{
640 struct snd_opl3sa2 *chip = card->private_data;
657 if (chip->irq >= 0) 641 if (chip->irq >= 0)
658 free_irq(chip->irq, (void *)chip); 642 free_irq(chip->irq, (void *)chip);
659 release_and_free_resource(chip->res_port); 643 release_and_free_resource(chip->res_port);
660 kfree(chip);
661 return 0;
662} 644}
663 645
664static int snd_opl3sa2_dev_free(snd_device_t *device) 646static struct snd_card *snd_opl3sa2_card_new(int dev)
665{
666 opl3sa2_t *chip = device->device_data;
667 return snd_opl3sa2_free(chip);
668}
669
670#ifdef CONFIG_PNP
671#define is_isapnp_selected(dev) isapnp[dev]
672#else
673#define is_isapnp_selected(dev) 0
674#endif
675
676static int __devinit snd_opl3sa2_probe(int dev,
677 struct pnp_dev *pdev,
678 struct pnp_card_link *pcard,
679 const struct pnp_card_device_id *pid)
680{ 647{
681 int xirq, xdma1, xdma2; 648 struct snd_card *card;
682 snd_card_t *card;
683 struct snd_opl3sa2 *chip; 649 struct snd_opl3sa2 *chip;
684 cs4231_t *cs4231;
685 opl3_t *opl3;
686 static snd_device_ops_t ops = {
687 .dev_free = snd_opl3sa2_dev_free,
688 };
689 int err;
690
691 if (! is_isapnp_selected(dev)) {
692 if (port[dev] == SNDRV_AUTO_PORT) {
693 snd_printk(KERN_ERR PFX "specify port\n");
694 return -EINVAL;
695 }
696 if (wss_port[dev] == SNDRV_AUTO_PORT) {
697 snd_printk(KERN_ERR PFX "specify wss_port\n");
698 return -EINVAL;
699 }
700 if (fm_port[dev] == SNDRV_AUTO_PORT) {
701 snd_printk(KERN_ERR PFX "specify fm_port\n");
702 return -EINVAL;
703 }
704 if (midi_port[dev] == SNDRV_AUTO_PORT) {
705 snd_printk(KERN_ERR PFX "specify midi_port\n");
706 return -EINVAL;
707 }
708 }
709 650
710 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); 651 card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_opl3sa2));
711 if (card == NULL) 652 if (card == NULL)
712 return -ENOMEM; 653 return NULL;
713 strcpy(card->driver, "OPL3SA2"); 654 strcpy(card->driver, "OPL3SA2");
714 strcpy(card->shortname, "Yamaha OPL3-SA2"); 655 strcpy(card->shortname, "Yamaha OPL3-SA2");
715 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 656 chip = card->private_data;
716 if (chip == NULL) {
717 err = -ENOMEM;
718 goto __error;
719 }
720 spin_lock_init(&chip->reg_lock); 657 spin_lock_init(&chip->reg_lock);
721 chip->irq = -1; 658 chip->irq = -1;
722 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
723 goto __error;
724#ifdef CONFIG_PNP
725 if (pdev) {
726 if ((err = snd_opl3sa2_pnp(dev, chip, pdev, 0)) < 0)
727 goto __error;
728 snd_card_set_dev(card, &pdev->dev);
729 }
730 if (pcard) {
731 if ((err = snd_opl3sa2_cpnp(dev, chip, pcard, pid)) < 0)
732 goto __error;
733 snd_card_set_dev(card, &pcard->card->dev);
734 }
735#endif
736 chip->ymode = opl3sa3_ymode[dev] & 0x03 ; /* initialise this card from supplied (or default) parameter*/
737 chip->card = card; 659 chip->card = card;
660 card->private_free = snd_opl3sa2_free;
661 return card;
662}
663
664static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
665{
666 int xirq, xdma1, xdma2;
667 struct snd_opl3sa2 *chip;
668 struct snd_cs4231 *cs4231;
669 struct snd_opl3 *opl3;
670 int err;
671
672 /* initialise this card from supplied (or default) parameter*/
673 chip = card->private_data;
674 chip->ymode = opl3sa3_ymode[dev] & 0x03 ;
738 chip->port = port[dev]; 675 chip->port = port[dev];
739 xirq = irq[dev]; 676 xirq = irq[dev];
740 xdma1 = dma1[dev]; 677 xdma1 = dma1[dev];
@@ -742,11 +679,10 @@ static int __devinit snd_opl3sa2_probe(int dev,
742 if (xdma2 < 0) 679 if (xdma2 < 0)
743 chip->single_dma = 1; 680 chip->single_dma = 1;
744 if ((err = snd_opl3sa2_detect(chip)) < 0) 681 if ((err = snd_opl3sa2_detect(chip)) < 0)
745 goto __error; 682 return err;
746 if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", (void *)chip)) { 683 if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", chip)) {
747 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); 684 snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
748 err = -ENODEV; 685 return -ENODEV;
749 goto __error;
750 } 686 }
751 chip->irq = xirq; 687 chip->irq = xirq;
752 if ((err = snd_cs4231_create(card, 688 if ((err = snd_cs4231_create(card,
@@ -756,179 +692,303 @@ static int __devinit snd_opl3sa2_probe(int dev,
756 CS4231_HWSHARE_IRQ, 692 CS4231_HWSHARE_IRQ,
757 &cs4231)) < 0) { 693 &cs4231)) < 0) {
758 snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4); 694 snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4);
759 goto __error; 695 return err;
760 } 696 }
761 chip->cs4231 = cs4231; 697 chip->cs4231 = cs4231;
762 if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) 698 if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0)
763 goto __error; 699 return err;
764 if ((err = snd_cs4231_mixer(cs4231)) < 0) 700 if ((err = snd_cs4231_mixer(cs4231)) < 0)
765 goto __error; 701 return err;
766 if ((err = snd_opl3sa2_mixer(chip)) < 0) 702 if ((err = snd_opl3sa2_mixer(chip)) < 0)
767 goto __error; 703 return err;
768 if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0) 704 if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0)
769 goto __error; 705 return err;
770 if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) { 706 if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
771 if ((err = snd_opl3_create(card, fm_port[dev], 707 if ((err = snd_opl3_create(card, fm_port[dev],
772 fm_port[dev] + 2, 708 fm_port[dev] + 2,
773 OPL3_HW_OPL3, 0, &opl3)) < 0) 709 OPL3_HW_OPL3, 0, &opl3)) < 0)
774 goto __error; 710 return err;
775 if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0) 711 if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0)
776 goto __error; 712 return err;
777 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0) 713 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0)
778 goto __error; 714 return err;
779 } 715 }
780 if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) { 716 if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
781 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2, 717 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
782 midi_port[dev], 0, 718 midi_port[dev], 0,
783 xirq, 0, &chip->rmidi)) < 0) 719 xirq, 0, &chip->rmidi)) < 0)
784 goto __error; 720 return err;
785 } 721 }
786#ifdef CONFIG_PM
787 chip->cs4231_suspend = chip->cs4231->suspend;
788 chip->cs4231_resume = chip->cs4231->resume;
789 /* now clear callbacks for cs4231 */
790 chip->cs4231->suspend = NULL;
791 chip->cs4231->resume = NULL;
792 snd_card_set_isa_pm_callback(card, snd_opl3sa2_suspend, snd_opl3sa2_resume, chip);
793#endif
794
795 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", 722 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
796 card->shortname, chip->port, xirq, xdma1); 723 card->shortname, chip->port, xirq, xdma1);
797 if (dma2 >= 0) 724 if (dma2 >= 0)
798 sprintf(card->longname + strlen(card->longname), "&%d", xdma2); 725 sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
799 726
800 if ((err = snd_card_set_generic_dev(card)) < 0) 727 return snd_card_register(card);
801 goto __error;
802
803 if ((err = snd_card_register(card)) < 0)
804 goto __error;
805
806 if (pdev)
807 pnp_set_drvdata(pdev, card);
808 else if (pcard)
809 pnp_set_card_drvdata(pcard, card);
810 else
811 snd_opl3sa2_legacy[dev] = card;
812 return 0;
813
814 __error:
815 snd_card_free(card);
816 return err;
817} 728}
818 729
819#ifdef CONFIG_PNP 730#ifdef CONFIG_PNP
820static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, 731static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
821 const struct pnp_device_id *id) 732 const struct pnp_device_id *id)
822{ 733{
823 static int dev; 734 static int dev;
824 int res; 735 int err;
736 struct snd_card *card;
825 737
826 for ( ; dev < SNDRV_CARDS; dev++) { 738 if (pnp_device_is_isapnp(pdev))
827 if (!enable[dev] || !isapnp[dev]) 739 return -ENOENT; /* we have another procedure - card */
828 continue; 740 for (; dev < SNDRV_CARDS; dev++) {
829 res = snd_opl3sa2_probe(dev, pdev, NULL, NULL); 741 if (enable[dev] && isapnp[dev])
830 if (res < 0) 742 break;
831 return res; 743 }
832 dev++; 744 if (dev >= SNDRV_CARDS)
833 return 0; 745 return -ENODEV;
834 } 746
835 return -ENODEV; 747 card = snd_opl3sa2_card_new(dev);
748 if (! card)
749 return -ENOMEM;
750 if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
751 snd_card_free(card);
752 return err;
753 }
754 snd_card_set_dev(card, &pdev->dev);
755 if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
756 snd_card_free(card);
757 return err;
758 }
759 pnp_set_drvdata(pdev, card);
760 dev++;
761 return 0;
836} 762}
837 763
838static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev) 764static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev)
839{ 765{
840 snd_card_t *card = (snd_card_t *) pnp_get_drvdata(pdev); 766 snd_card_free(pnp_get_drvdata(pdev));
841 767 pnp_set_drvdata(pdev, NULL);
842 snd_card_disconnect(card); 768}
843 snd_card_free_in_thread(card); 769
770#ifdef CONFIG_PM
771static int snd_opl3sa2_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
772{
773 return snd_opl3sa2_suspend(pnp_get_drvdata(pdev), state);
844} 774}
775static int snd_opl3sa2_pnp_resume(struct pnp_dev *pdev)
776{
777 return snd_opl3sa2_resume(pnp_get_drvdata(pdev));
778}
779#endif
845 780
846static struct pnp_driver opl3sa2_pnp_driver = { 781static struct pnp_driver opl3sa2_pnp_driver = {
847 .name = "opl3sa2-pnpbios", 782 .name = "opl3sa2-pnpbios",
848 .id_table = snd_opl3sa2_pnpbiosids, 783 .id_table = snd_opl3sa2_pnpbiosids,
849 .probe = snd_opl3sa2_pnp_detect, 784 .probe = snd_opl3sa2_pnp_detect,
850 .remove = __devexit_p(snd_opl3sa2_pnp_remove), 785 .remove = __devexit_p(snd_opl3sa2_pnp_remove),
786#ifdef CONFIG_PM
787 .suspend = snd_opl3sa2_pnp_suspend,
788 .resume = snd_opl3sa2_pnp_resume,
789#endif
851}; 790};
852 791
853static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *card, 792static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
854 const struct pnp_card_device_id *id) 793 const struct pnp_card_device_id *id)
855{ 794{
856 static int dev; 795 static int dev;
857 int res; 796 struct pnp_dev *pdev;
797 int err;
798 struct snd_card *card;
858 799
859 for ( ; dev < SNDRV_CARDS; dev++) { 800 pdev = pnp_request_card_device(pcard, id->devs[0].id, NULL);
860 if (!enable[dev]) 801 if (pdev == NULL) {
861 continue; 802 snd_printk(KERN_ERR PFX "can't get pnp device from id '%s'\n",
862 if (is_isapnp_selected(dev)) 803 id->devs[0].id);
863 continue; 804 return -EBUSY;
864 res = snd_opl3sa2_probe(dev, NULL, card, id); 805 }
865 if (res < 0) 806 for (; dev < SNDRV_CARDS; dev++) {
866 return res; 807 if (enable[dev] && isapnp[dev])
867 dev++; 808 break;
868 return 0; 809 }
869 } 810 if (dev >= SNDRV_CARDS)
870 return -ENODEV; 811 return -ENODEV;
812
813 card = snd_opl3sa2_card_new(dev);
814 if (! card)
815 return -ENOMEM;
816 if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
817 snd_card_free(card);
818 return err;
819 }
820 snd_card_set_dev(card, &pdev->dev);
821 if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
822 snd_card_free(card);
823 return err;
824 }
825 pnp_set_card_drvdata(pcard, card);
826 dev++;
827 return 0;
871} 828}
872 829
873static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard) 830static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard)
874{ 831{
875 snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard); 832 snd_card_free(pnp_get_card_drvdata(pcard));
876 833 pnp_set_card_drvdata(pcard, NULL);
877 snd_card_disconnect(card);
878 snd_card_free_in_thread(card);
879} 834}
880 835
836#ifdef CONFIG_PM
837static int snd_opl3sa2_pnp_csuspend(struct pnp_card_link *pcard, pm_message_t state)
838{
839 return snd_opl3sa2_suspend(pnp_get_card_drvdata(pcard), state);
840}
841static int snd_opl3sa2_pnp_cresume(struct pnp_card_link *pcard)
842{
843 return snd_opl3sa2_resume(pnp_get_card_drvdata(pcard));
844}
845#endif
846
881static struct pnp_card_driver opl3sa2_pnpc_driver = { 847static struct pnp_card_driver opl3sa2_pnpc_driver = {
882 .flags = PNP_DRIVER_RES_DISABLE, 848 .flags = PNP_DRIVER_RES_DISABLE,
883 .name = "opl3sa2", 849 .name = "opl3sa2",
884 .id_table = snd_opl3sa2_pnpids, 850 .id_table = snd_opl3sa2_pnpids,
885 .probe = snd_opl3sa2_pnp_cdetect, 851 .probe = snd_opl3sa2_pnp_cdetect,
886 .remove = __devexit_p(snd_opl3sa2_pnp_cremove), 852 .remove = __devexit_p(snd_opl3sa2_pnp_cremove),
853#ifdef CONFIG_PM
854 .suspend = snd_opl3sa2_pnp_csuspend,
855 .resume = snd_opl3sa2_pnp_cresume,
856#endif
887}; 857};
888#endif /* CONFIG_PNP */ 858#endif /* CONFIG_PNP */
889 859
860static int __init snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
861{
862 struct snd_card *card;
863 int err;
864 int dev = pdev->id;
865
866 if (port[dev] == SNDRV_AUTO_PORT) {
867 snd_printk(KERN_ERR PFX "specify port\n");
868 return -EINVAL;
869 }
870 if (wss_port[dev] == SNDRV_AUTO_PORT) {
871 snd_printk(KERN_ERR PFX "specify wss_port\n");
872 return -EINVAL;
873 }
874 if (fm_port[dev] == SNDRV_AUTO_PORT) {
875 snd_printk(KERN_ERR PFX "specify fm_port\n");
876 return -EINVAL;
877 }
878 if (midi_port[dev] == SNDRV_AUTO_PORT) {
879 snd_printk(KERN_ERR PFX "specify midi_port\n");
880 return -EINVAL;
881 }
882
883 card = snd_opl3sa2_card_new(dev);
884 if (! card)
885 return -ENOMEM;
886 snd_card_set_dev(card, &pdev->dev);
887 if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
888 snd_card_free(card);
889 return err;
890 }
891 platform_set_drvdata(pdev, card);
892 return 0;
893}
894
895static int snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
896{
897 snd_card_free(platform_get_drvdata(devptr));
898 platform_set_drvdata(devptr, NULL);
899 return 0;
900}
901
902#ifdef CONFIG_PM
903static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
904{
905 return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
906}
907
908static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
909{
910 return snd_opl3sa2_resume(platform_get_drvdata(dev));
911}
912#endif
913
914#define OPL3SA2_DRIVER "snd_opl3sa2"
915
916static struct platform_driver snd_opl3sa2_nonpnp_driver = {
917 .probe = snd_opl3sa2_nonpnp_probe,
918 .remove = snd_opl3sa2_nonpnp_remove,
919#ifdef CONFIG_PM
920 .suspend = snd_opl3sa2_nonpnp_suspend,
921 .resume = snd_opl3sa2_nonpnp_resume,
922#endif
923 .driver = {
924 .name = OPL3SA2_DRIVER
925 },
926};
927
928static void __init_or_module snd_opl3sa2_unregister_all(void)
929{
930 int i;
931
932 if (pnpc_registered)
933 pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
934 if (pnp_registered)
935 pnp_unregister_driver(&opl3sa2_pnp_driver);
936 for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
937 platform_device_unregister(platform_devices[i]);
938 platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
939}
940
890static int __init alsa_card_opl3sa2_init(void) 941static int __init alsa_card_opl3sa2_init(void)
891{ 942{
892 int dev, cards = 0; 943 int i, err, cards = 0;
893 944
894 for (dev = 0; dev < SNDRV_CARDS; dev++) { 945 if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
895 if (!enable[dev]) 946 return err;
896 continue; 947
948 for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
949 struct platform_device *device;
897#ifdef CONFIG_PNP 950#ifdef CONFIG_PNP
898 if (isapnp[dev]) 951 if (isapnp[i])
899 continue; 952 continue;
900#endif 953#endif
901 if (snd_opl3sa2_probe(dev, NULL, NULL, NULL) >= 0) 954 device = platform_device_register_simple(OPL3SA2_DRIVER,
902 cards++; 955 i, NULL, 0);
956 if (IS_ERR(device)) {
957 err = PTR_ERR(device);
958 goto errout;
959 }
960 platform_devices[i] = device;
961 cards++;
903 } 962 }
904#ifdef CONFIG_PNP 963
905 cards += pnp_register_driver(&opl3sa2_pnp_driver); 964 err = pnp_register_driver(&opl3sa2_pnp_driver);
906 cards += pnp_register_card_driver(&opl3sa2_pnpc_driver); 965 if (err >= 0) {
907#endif 966 pnp_registered = 1;
967 cards += err;
968 }
969 err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
970 if (err >= 0) {
971 pnpc_registered = 1;
972 cards += err;
973 }
974
908 if (!cards) { 975 if (!cards) {
909#ifdef MODULE 976#ifdef MODULE
910 snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); 977 snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
911#endif 978#endif
912#ifdef CONFIG_PNP 979 err = -ENODEV;
913 pnp_unregister_card_driver(&opl3sa2_pnpc_driver); 980 goto errout;
914 pnp_unregister_driver(&opl3sa2_pnp_driver);
915#endif
916 return -ENODEV;
917 } 981 }
918 return 0; 982 return 0;
983
984 errout:
985 snd_opl3sa2_unregister_all();
986 return err;
919} 987}
920 988
921static void __exit alsa_card_opl3sa2_exit(void) 989static void __exit alsa_card_opl3sa2_exit(void)
922{ 990{
923 int idx; 991 snd_opl3sa2_unregister_all();
924
925#ifdef CONFIG_PNP
926 /* PnP cards first */
927 pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
928 pnp_unregister_driver(&opl3sa2_pnp_driver);
929#endif
930 for (idx = 0; idx < SNDRV_CARDS; idx++)
931 snd_card_free(snd_opl3sa2_legacy[idx]);
932} 992}
933 993
934module_init(alsa_card_opl3sa2_init) 994module_init(alsa_card_opl3sa2_init)