1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Gallant SC-6000 soundcard. This card is also known as 4 * Audio Excel DSP 16 or Zoltrix AV302. 5 * These cards use CompuMedia ASC-9308 chip + AD1848 codec. 6 * SC-6600 and SC-7000 cards are also supported. They are based on 7 * CompuMedia ASC-9408 chip and CS4231 codec. 8 * 9 * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl> 10 * 11 * I don't have documentation for this card. I used the driver 12 * for OSS/Free included in the kernel source as reference. 13 */ 14 15 #include <linux/module.h> 16 #include <linux/delay.h> 17 #include <linux/isa.h> 18 #include <linux/io.h> 19 #include <asm/dma.h> 20 #include <sound/core.h> 21 #include <sound/wss.h> 22 #include <sound/opl3.h> 23 #include <sound/mpu401.h> 24 #include <sound/control.h> 25 #define SNDRV_LEGACY_FIND_FREE_IRQ 26 #define SNDRV_LEGACY_FIND_FREE_DMA 27 #include <sound/initval.h> 28 29 MODULE_AUTHOR("Krzysztof Helt"); 30 MODULE_DESCRIPTION("Gallant SC-6000"); 31 MODULE_LICENSE("GPL"); 32 33 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 34 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 35 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ 36 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220, 0x240 */ 37 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 11 */ 38 static long mss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530, 0xe80 */ 39 static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; 40 /* 0x300, 0x310, 0x320, 0x330 */ 41 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 0 */ 42 static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0, 1, 3 */ 43 static bool joystick[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = false }; 44 45 module_param_array(index, int, NULL, 0444); 46 MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard."); 47 module_param_array(id, charp, NULL, 0444); 48 MODULE_PARM_DESC(id, "ID string for sc-6000 based soundcard."); 49 module_param_array(enable, bool, NULL, 0444); 50 MODULE_PARM_DESC(enable, "Enable sc-6000 based soundcard."); 51 module_param_hw_array(port, long, ioport, NULL, 0444); 52 MODULE_PARM_DESC(port, "Port # for sc-6000 driver."); 53 module_param_hw_array(mss_port, long, ioport, NULL, 0444); 54 MODULE_PARM_DESC(mss_port, "MSS Port # for sc-6000 driver."); 55 module_param_hw_array(mpu_port, long, ioport, NULL, 0444); 56 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for sc-6000 driver."); 57 module_param_hw_array(irq, int, irq, NULL, 0444); 58 MODULE_PARM_DESC(irq, "IRQ # for sc-6000 driver."); 59 module_param_hw_array(mpu_irq, int, irq, NULL, 0444); 60 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver."); 61 module_param_hw_array(dma, int, dma, NULL, 0444); 62 MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver."); 63 module_param_array(joystick, bool, NULL, 0444); 64 MODULE_PARM_DESC(joystick, "Enable gameport."); 65 66 /* 67 * Commands of SC6000's DSP (SBPRO+special). 68 * Some of them are COMMAND_xx, in the future they may change. 69 */ 70 #define WRITE_MDIRQ_CFG 0x50 /* Set M&I&DRQ mask (the real config) */ 71 #define COMMAND_52 0x52 /* */ 72 #define READ_HARD_CFG 0x58 /* Read Hardware Config (I/O base etc) */ 73 #define COMMAND_5C 0x5c /* */ 74 #define COMMAND_60 0x60 /* */ 75 #define COMMAND_66 0x66 /* */ 76 #define COMMAND_6C 0x6c /* */ 77 #define COMMAND_6E 0x6e /* */ 78 #define COMMAND_88 0x88 /* Unknown command */ 79 #define DSP_INIT_MSS 0x8c /* Enable Microsoft Sound System mode */ 80 #define COMMAND_C5 0xc5 /* */ 81 #define GET_DSP_VERSION 0xe1 /* Get DSP Version */ 82 #define GET_DSP_COPYRIGHT 0xe3 /* Get DSP Copyright */ 83 84 /* 85 * Offsets of SC6000 DSP I/O ports. The offset is added to base I/O port 86 * to have the actual I/O port. 87 * Register permissions are: 88 * (wo) == Write Only 89 * (ro) == Read Only 90 * (w-) == Write 91 * (r-) == Read 92 */ 93 #define DSP_RESET 0x06 /* offset of DSP RESET (wo) */ 94 #define DSP_READ 0x0a /* offset of DSP READ (ro) */ 95 #define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */ 96 #define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */ 97 #define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */ 98 #define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */ 99 100 #define PFX "sc6000: " 101 #define DRV_NAME "SC-6000" 102 103 struct snd_sc6000 { 104 char __iomem *vport; 105 char __iomem *vmss_port; 106 struct snd_wss *chip; 107 u8 mss_config; 108 u8 config; 109 u8 hw_cfg[2]; 110 bool old_dsp; 111 }; 112 113 /* hardware dependent functions */ 114 115 /* 116 * sc6000_irq_to_softcfg - Decode irq number into cfg code. 117 */ 118 static unsigned char sc6000_irq_to_softcfg(int irq) 119 { 120 unsigned char val = 0; 121 122 switch (irq) { 123 case 5: 124 val = 0x28; 125 break; 126 case 7: 127 val = 0x8; 128 break; 129 case 9: 130 val = 0x10; 131 break; 132 case 10: 133 val = 0x18; 134 break; 135 case 11: 136 val = 0x20; 137 break; 138 default: 139 break; 140 } 141 return val; 142 } 143 144 /* 145 * sc6000_dma_to_softcfg - Decode dma number into cfg code. 146 */ 147 static unsigned char sc6000_dma_to_softcfg(int dma) 148 { 149 unsigned char val = 0; 150 151 switch (dma) { 152 case 0: 153 val = 1; 154 break; 155 case 1: 156 val = 2; 157 break; 158 case 3: 159 val = 3; 160 break; 161 default: 162 break; 163 } 164 return val; 165 } 166 167 /* 168 * sc6000_mpu_irq_to_softcfg - Decode MPU-401 irq number into cfg code. 169 */ 170 static unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq) 171 { 172 unsigned char val = 0; 173 174 switch (mpu_irq) { 175 case 5: 176 val = 4; 177 break; 178 case 7: 179 val = 0x44; 180 break; 181 case 9: 182 val = 0x84; 183 break; 184 case 10: 185 val = 0xc4; 186 break; 187 default: 188 break; 189 } 190 return val; 191 } 192 193 static int sc6000_wait_data(char __iomem *vport) 194 { 195 int loop = 1000; 196 unsigned char val = 0; 197 198 do { 199 val = ioread8(vport + DSP_DATAVAIL); 200 if (val & 0x80) 201 return 0; 202 cpu_relax(); 203 } while (loop--); 204 205 return -EAGAIN; 206 } 207 208 static int sc6000_read(char __iomem *vport) 209 { 210 if (sc6000_wait_data(vport)) 211 return -EBUSY; 212 213 return ioread8(vport + DSP_READ); 214 215 } 216 217 static int sc6000_write(struct device *devptr, char __iomem *vport, int cmd) 218 { 219 unsigned char val; 220 int loop = 500000; 221 222 do { 223 val = ioread8(vport + DSP_STATUS); 224 /* 225 * DSP ready to receive data if bit 7 of val == 0 226 */ 227 if (!(val & 0x80)) { 228 iowrite8(cmd, vport + DSP_COMMAND); 229 return 0; 230 } 231 cpu_relax(); 232 } while (loop--); 233 234 dev_err(devptr, "DSP Command (0x%x) timeout.\n", cmd); 235 236 return -EIO; 237 } 238 239 static int sc6000_dsp_get_answer(struct device *devptr, 240 char __iomem *vport, int command, 241 char *data, int data_len) 242 { 243 int len = 0; 244 245 if (sc6000_write(devptr, vport, command)) { 246 dev_err(devptr, "CMD 0x%x: failed!\n", command); 247 return -EIO; 248 } 249 250 do { 251 int val = sc6000_read(vport); 252 253 if (val < 0) 254 break; 255 256 data[len++] = val; 257 258 } while (len < data_len); 259 260 /* 261 * If no more data available, return to the caller, no error if len>0. 262 * We have no other way to know when the string is finished. 263 */ 264 return len ? len : -EIO; 265 } 266 267 static int sc6000_dsp_reset(char __iomem *vport) 268 { 269 iowrite8(1, vport + DSP_RESET); 270 udelay(10); 271 iowrite8(0, vport + DSP_RESET); 272 udelay(20); 273 if (sc6000_read(vport) == 0xaa) 274 return 0; 275 return -ENODEV; 276 } 277 278 /* detection and initialization */ 279 static int sc6000_hw_cfg_write(struct device *devptr, 280 char __iomem *vport, const u8 *cfg) 281 { 282 if (sc6000_write(devptr, vport, COMMAND_6C) < 0) { 283 dev_warn(devptr, "CMD 0x%x: failed!\n", COMMAND_6C); 284 return -EIO; 285 } 286 if (sc6000_write(devptr, vport, COMMAND_5C) < 0) { 287 dev_err(devptr, "CMD 0x%x: failed!\n", COMMAND_5C); 288 return -EIO; 289 } 290 if (sc6000_write(devptr, vport, cfg[0]) < 0) { 291 dev_err(devptr, "DATA 0x%x: failed!\n", cfg[0]); 292 return -EIO; 293 } 294 if (sc6000_write(devptr, vport, cfg[1]) < 0) { 295 dev_err(devptr, "DATA 0x%x: failed!\n", cfg[1]); 296 return -EIO; 297 } 298 if (sc6000_write(devptr, vport, COMMAND_C5) < 0) { 299 dev_err(devptr, "CMD 0x%x: failed!\n", COMMAND_C5); 300 return -EIO; 301 } 302 303 return 0; 304 } 305 306 static int sc6000_cfg_write(struct device *devptr, 307 char __iomem *vport, unsigned char softcfg) 308 { 309 310 if (sc6000_write(devptr, vport, WRITE_MDIRQ_CFG)) { 311 dev_err(devptr, "CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG); 312 return -EIO; 313 } 314 if (sc6000_write(devptr, vport, softcfg)) { 315 dev_err(devptr, "%s: failed!\n", __func__); 316 return -EIO; 317 } 318 return 0; 319 } 320 321 static int sc6000_setup_board(struct device *devptr, 322 char __iomem *vport, int config) 323 { 324 int loop = 10; 325 326 do { 327 if (sc6000_write(devptr, vport, COMMAND_88)) { 328 dev_err(devptr, "CMD 0x%x: failed!\n", 329 COMMAND_88); 330 return -EIO; 331 } 332 } while ((sc6000_wait_data(vport) < 0) && loop--); 333 334 if (sc6000_read(vport) < 0) { 335 dev_err(devptr, "sc6000_read after CMD 0x%x: failed\n", 336 COMMAND_88); 337 return -EIO; 338 } 339 340 if (sc6000_cfg_write(devptr, vport, config)) 341 return -ENODEV; 342 343 return 0; 344 } 345 346 static int sc6000_init_mss(struct device *devptr, 347 char __iomem *vport, int config, 348 char __iomem *vmss_port, int mss_config) 349 { 350 if (sc6000_write(devptr, vport, DSP_INIT_MSS)) { 351 dev_err(devptr, "%s [0x%x]: failed!\n", __func__, 352 DSP_INIT_MSS); 353 return -EIO; 354 } 355 356 msleep(10); 357 358 if (sc6000_cfg_write(devptr, vport, config)) 359 return -EIO; 360 361 iowrite8(mss_config, vmss_port); 362 363 return 0; 364 } 365 366 static void sc6000_hw_cfg_encode(struct device *devptr, u8 *cfg, 367 long xport, long xmpu, 368 long xmss_port, int joystick) 369 { 370 cfg[0] = 0; 371 cfg[1] = 0; 372 if (xport == 0x240) 373 cfg[0] |= 1; 374 if (xmpu != SNDRV_AUTO_PORT) { 375 cfg[0] |= (xmpu & 0x30) >> 2; 376 cfg[1] |= 0x20; 377 } 378 if (xmss_port == 0xe80) 379 cfg[0] |= 0x10; 380 cfg[0] |= 0x40; /* always set */ 381 if (!joystick) 382 cfg[0] |= 0x02; 383 cfg[1] |= 0x80; /* enable WSS system */ 384 cfg[1] &= ~0x40; /* disable IDE */ 385 dev_dbg(devptr, "hw cfg %x, %x\n", cfg[0], cfg[1]); 386 } 387 388 static void sc6000_prepare_board(struct device *devptr, 389 struct snd_sc6000 *sc6000, 390 unsigned int dev, int xirq, int xdma) 391 { 392 sc6000->mss_config = sc6000_irq_to_softcfg(xirq) | 393 sc6000_dma_to_softcfg(xdma); 394 sc6000->config = sc6000->mss_config | 395 sc6000_mpu_irq_to_softcfg(mpu_irq[dev]); 396 sc6000_hw_cfg_encode(devptr, sc6000->hw_cfg, port[dev], mpu_port[dev], 397 mss_port[dev], joystick[dev]); 398 } 399 400 static void sc6000_detect_old_dsp(struct device *devptr, 401 struct snd_sc6000 *sc6000) 402 { 403 sc6000_write(devptr, sc6000->vport, COMMAND_5C); 404 sc6000->old_dsp = sc6000_read(sc6000->vport) < 0; 405 } 406 407 static int sc6000_program_board(struct device *devptr, 408 struct snd_sc6000 *sc6000) 409 { 410 int err; 411 412 if (!sc6000->old_dsp) { 413 if (sc6000_hw_cfg_write(devptr, sc6000->vport, 414 sc6000->hw_cfg) < 0) { 415 dev_err(devptr, "sc6000_hw_cfg_write: failed!\n"); 416 return -EIO; 417 } 418 } 419 420 err = sc6000_setup_board(devptr, sc6000->vport, sc6000->config); 421 if (err < 0) { 422 dev_err(devptr, "sc6000_setup_board: failed!\n"); 423 return -ENODEV; 424 } 425 426 sc6000_dsp_reset(sc6000->vport); 427 428 if (!sc6000->old_dsp) { 429 sc6000_write(devptr, sc6000->vport, COMMAND_60); 430 sc6000_write(devptr, sc6000->vport, 0x02); 431 sc6000_dsp_reset(sc6000->vport); 432 } 433 434 err = sc6000_setup_board(devptr, sc6000->vport, sc6000->config); 435 if (err < 0) { 436 dev_err(devptr, "sc6000_setup_board: failed!\n"); 437 return -ENODEV; 438 } 439 440 err = sc6000_init_mss(devptr, sc6000->vport, sc6000->config, 441 sc6000->vmss_port, sc6000->mss_config); 442 if (err < 0) { 443 dev_err(devptr, "Cannot initialize Microsoft Sound System mode.\n"); 444 return -ENODEV; 445 } 446 447 return 0; 448 } 449 450 static int sc6000_init_board(struct device *devptr, struct snd_sc6000 *sc6000) 451 { 452 char answer[15]; 453 char version[2]; 454 int err; 455 456 err = sc6000_dsp_reset(sc6000->vport); 457 if (err < 0) { 458 dev_err(devptr, "sc6000_dsp_reset: failed!\n"); 459 return err; 460 } 461 462 memset(answer, 0, sizeof(answer)); 463 err = sc6000_dsp_get_answer(devptr, sc6000->vport, GET_DSP_COPYRIGHT, 464 answer, 15); 465 if (err <= 0) { 466 dev_err(devptr, "sc6000_dsp_copyright: failed!\n"); 467 return -ENODEV; 468 } 469 /* 470 * My SC-6000 card return "SC-6000" in DSPCopyright, so 471 * if we have something different, we have to be warned. 472 */ 473 if (strncmp("SC-6000", answer, 7)) 474 dev_warn(devptr, "Warning: non SC-6000 audio card!\n"); 475 476 if (sc6000_dsp_get_answer(devptr, sc6000->vport, 477 GET_DSP_VERSION, version, 2) < 2) { 478 dev_err(devptr, "sc6000_dsp_version: failed!\n"); 479 return -ENODEV; 480 } 481 dev_info(devptr, "Detected model: %s, DSP version %d.%d\n", 482 answer, version[0], version[1]); 483 484 sc6000_detect_old_dsp(devptr, sc6000); 485 486 return sc6000_program_board(devptr, sc6000); 487 } 488 489 static int snd_sc6000_mixer(struct snd_wss *chip) 490 { 491 struct snd_card *card = chip->card; 492 struct snd_ctl_elem_id id1, id2; 493 int err; 494 495 memset(&id1, 0, sizeof(id1)); 496 memset(&id2, 0, sizeof(id2)); 497 id1.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 498 id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 499 /* reassign AUX0 to FM */ 500 strscpy(id1.name, "Aux Playback Switch"); 501 strscpy(id2.name, "FM Playback Switch"); 502 err = snd_ctl_rename_id(card, &id1, &id2); 503 if (err < 0) 504 return err; 505 strscpy(id1.name, "Aux Playback Volume"); 506 strscpy(id2.name, "FM Playback Volume"); 507 err = snd_ctl_rename_id(card, &id1, &id2); 508 if (err < 0) 509 return err; 510 /* reassign AUX1 to CD */ 511 strscpy(id1.name, "Aux Playback Switch"); id1.index = 1; 512 strscpy(id2.name, "CD Playback Switch"); 513 err = snd_ctl_rename_id(card, &id1, &id2); 514 if (err < 0) 515 return err; 516 strscpy(id1.name, "Aux Playback Volume"); 517 strscpy(id2.name, "CD Playback Volume"); 518 err = snd_ctl_rename_id(card, &id1, &id2); 519 if (err < 0) 520 return err; 521 return 0; 522 } 523 524 static int snd_sc6000_match(struct device *devptr, unsigned int dev) 525 { 526 if (!enable[dev]) 527 return 0; 528 if (port[dev] == SNDRV_AUTO_PORT) { 529 dev_err(devptr, "specify IO port\n"); 530 return 0; 531 } 532 if (mss_port[dev] == SNDRV_AUTO_PORT) { 533 dev_err(devptr, "specify MSS port\n"); 534 return 0; 535 } 536 if (port[dev] != 0x220 && port[dev] != 0x240) { 537 dev_err(devptr, "Port must be 0x220 or 0x240\n"); 538 return 0; 539 } 540 if (mss_port[dev] != 0x530 && mss_port[dev] != 0xe80) { 541 dev_err(devptr, "MSS port must be 0x530 or 0xe80\n"); 542 return 0; 543 } 544 if (irq[dev] != SNDRV_AUTO_IRQ && !sc6000_irq_to_softcfg(irq[dev])) { 545 dev_err(devptr, "invalid IRQ %d\n", irq[dev]); 546 return 0; 547 } 548 if (dma[dev] != SNDRV_AUTO_DMA && !sc6000_dma_to_softcfg(dma[dev])) { 549 dev_err(devptr, "invalid DMA %d\n", dma[dev]); 550 return 0; 551 } 552 if (mpu_port[dev] != SNDRV_AUTO_PORT && 553 (mpu_port[dev] & ~0x30L) != 0x300) { 554 dev_err(devptr, "invalid MPU-401 port %lx\n", 555 mpu_port[dev]); 556 return 0; 557 } 558 if (mpu_port[dev] != SNDRV_AUTO_PORT && 559 mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] != 0 && 560 !sc6000_mpu_irq_to_softcfg(mpu_irq[dev])) { 561 dev_err(devptr, "invalid MPU-401 IRQ %d\n", mpu_irq[dev]); 562 return 0; 563 } 564 return 1; 565 } 566 567 static void snd_sc6000_free(struct snd_card *card) 568 { 569 struct snd_sc6000 *sc6000 = card->private_data; 570 571 if (sc6000->vport) 572 sc6000_setup_board(card->dev, sc6000->vport, 0); 573 } 574 575 static int __snd_sc6000_probe(struct device *devptr, unsigned int dev) 576 { 577 static const int possible_irqs[] = { 5, 7, 9, 10, 11, -1 }; 578 static const int possible_dmas[] = { 1, 3, 0, -1 }; 579 int err; 580 int xirq = irq[dev]; 581 int xdma = dma[dev]; 582 struct snd_card *card; 583 struct snd_sc6000 *sc6000; 584 struct snd_wss *chip; 585 struct snd_opl3 *opl3; 586 char __iomem *vport; 587 char __iomem *vmss_port; 588 589 err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE, 590 sizeof(*sc6000), &card); 591 if (err < 0) 592 return err; 593 sc6000 = card->private_data; 594 595 if (xirq == SNDRV_AUTO_IRQ) { 596 xirq = snd_legacy_find_free_irq(possible_irqs); 597 if (xirq < 0) { 598 dev_err(devptr, "unable to find a free IRQ\n"); 599 return -EBUSY; 600 } 601 } 602 603 if (xdma == SNDRV_AUTO_DMA) { 604 xdma = snd_legacy_find_free_dma(possible_dmas); 605 if (xdma < 0) { 606 dev_err(devptr, "unable to find a free DMA\n"); 607 return -EBUSY; 608 } 609 } 610 611 if (!devm_request_region(devptr, port[dev], 0x10, DRV_NAME)) { 612 dev_err(devptr, "I/O port region is already in use.\n"); 613 return -EBUSY; 614 } 615 vport = devm_ioport_map(devptr, port[dev], 0x10); 616 if (!vport) { 617 dev_err(devptr, "I/O port cannot be iomapped.\n"); 618 return -EBUSY; 619 } 620 sc6000->vport = vport; 621 622 /* to make it marked as used */ 623 if (!devm_request_region(devptr, mss_port[dev], 4, DRV_NAME)) { 624 dev_err(devptr, 625 "SC-6000 port I/O port region is already in use.\n"); 626 return -EBUSY; 627 } 628 vmss_port = devm_ioport_map(devptr, mss_port[dev], 4); 629 if (!vmss_port) { 630 dev_err(devptr, "MSS port I/O cannot be iomapped.\n"); 631 return -EBUSY; 632 } 633 sc6000->vmss_port = vmss_port; 634 635 dev_dbg(devptr, "Initializing BASE[0x%lx] IRQ[%d] DMA[%d] MIRQ[%d]\n", 636 port[dev], xirq, xdma, 637 mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]); 638 639 sc6000_prepare_board(devptr, sc6000, dev, xirq, xdma); 640 641 err = sc6000_init_board(devptr, sc6000); 642 if (err < 0) 643 return err; 644 card->private_free = snd_sc6000_free; 645 646 err = snd_wss_create(card, mss_port[dev] + 4, -1, xirq, xdma, -1, 647 WSS_HW_DETECT, 0, &chip); 648 if (err < 0) 649 return err; 650 sc6000->chip = chip; 651 652 err = snd_wss_pcm(chip, 0); 653 if (err < 0) { 654 dev_err(devptr, "error creating new WSS PCM device\n"); 655 return err; 656 } 657 err = snd_wss_mixer(chip); 658 if (err < 0) { 659 dev_err(devptr, "error creating new WSS mixer\n"); 660 return err; 661 } 662 err = snd_sc6000_mixer(chip); 663 if (err < 0) { 664 dev_err(devptr, "the mixer rewrite failed\n"); 665 return err; 666 } 667 if (snd_opl3_create(card, 668 0x388, 0x388 + 2, 669 OPL3_HW_AUTO, 0, &opl3) < 0) { 670 dev_err(devptr, "no OPL device at 0x%x-0x%x ?\n", 671 0x388, 0x388 + 2); 672 } else { 673 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 674 if (err < 0) 675 return err; 676 } 677 678 if (mpu_port[dev] != SNDRV_AUTO_PORT) { 679 if (mpu_irq[dev] == SNDRV_AUTO_IRQ) 680 mpu_irq[dev] = -1; 681 if (snd_mpu401_uart_new(card, 0, 682 MPU401_HW_MPU401, 683 mpu_port[dev], 0, 684 mpu_irq[dev], NULL) < 0) 685 dev_err(devptr, "no MPU-401 device at 0x%lx ?\n", 686 mpu_port[dev]); 687 } 688 689 strscpy(card->driver, DRV_NAME); 690 strscpy(card->shortname, "SC-6000"); 691 sprintf(card->longname, "Gallant SC-6000 at 0x%lx, irq %d, dma %d", 692 mss_port[dev], xirq, xdma); 693 694 err = snd_card_register(card); 695 if (err < 0) 696 return err; 697 698 dev_set_drvdata(devptr, card); 699 return 0; 700 } 701 702 static int snd_sc6000_probe(struct device *devptr, unsigned int dev) 703 { 704 return snd_card_free_on_error(devptr, __snd_sc6000_probe(devptr, dev)); 705 } 706 707 #ifdef CONFIG_PM 708 static int snd_sc6000_suspend(struct device *devptr, unsigned int dev, 709 pm_message_t state) 710 { 711 struct snd_card *card = dev_get_drvdata(devptr); 712 struct snd_sc6000 *sc6000 = card->private_data; 713 714 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 715 sc6000->chip->suspend(sc6000->chip); 716 return 0; 717 } 718 719 static int snd_sc6000_resume(struct device *devptr, unsigned int dev) 720 { 721 struct snd_card *card = dev_get_drvdata(devptr); 722 struct snd_sc6000 *sc6000 = card->private_data; 723 int err; 724 725 err = sc6000_dsp_reset(sc6000->vport); 726 if (err < 0) { 727 dev_err(devptr, "sc6000_dsp_reset: failed!\n"); 728 return err; 729 } 730 731 err = sc6000_program_board(devptr, sc6000); 732 if (err < 0) 733 return err; 734 735 sc6000->chip->resume(sc6000->chip); 736 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 737 return 0; 738 } 739 #endif 740 741 static struct isa_driver snd_sc6000_driver = { 742 .match = snd_sc6000_match, 743 .probe = snd_sc6000_probe, 744 #ifdef CONFIG_PM 745 .suspend = snd_sc6000_suspend, 746 .resume = snd_sc6000_resume, 747 #endif 748 .driver = { 749 .name = DRV_NAME, 750 }, 751 }; 752 753 754 module_isa_driver(snd_sc6000_driver, SNDRV_CARDS); 755