xref: /linux/sound/isa/sc6000.c (revision a8e7ef3cec99ba2487110e01d77a8a278593b3e9)
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