1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61#include <sound/driver.h>
62#include <asm/io.h>
63#include <linux/init.h>
64#include <linux/pci.h>
65#include <linux/slab.h>
66#include <linux/gameport.h>
67#include <linux/moduleparam.h>
68#include <sound/core.h>
69#include <sound/pcm.h>
70#include <sound/rawmidi.h>
71#include <sound/mpu401.h>
72#include <sound/opl3.h>
73#include <sound/sb.h>
74#include <sound/initval.h>
75
76MODULE_AUTHOR("Bart Hartgers <bart@etpmod.phys.tue.nl>");
77MODULE_DESCRIPTION("Avance Logic ALS4000");
78MODULE_LICENSE("GPL");
79MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}");
80
81#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
82#define SUPPORT_JOYSTICK 1
83#endif
84
85static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
86static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
87static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
88#ifdef SUPPORT_JOYSTICK
89static int joystick_port[SNDRV_CARDS];
90#endif
91
92module_param_array(index, int, NULL, 0444);
93MODULE_PARM_DESC(index, "Index value for ALS4000 soundcard.");
94module_param_array(id, charp, NULL, 0444);
95MODULE_PARM_DESC(id, "ID string for ALS4000 soundcard.");
96module_param_array(enable, bool, NULL, 0444);
97MODULE_PARM_DESC(enable, "Enable ALS4000 soundcard.");
98#ifdef SUPPORT_JOYSTICK
99module_param_array(joystick_port, int, NULL, 0444);
100MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 = disabled)");
101#endif
102
103typedef struct {
104 struct pci_dev *pci;
105 unsigned long gcr;
106#ifdef SUPPORT_JOYSTICK
107 struct gameport gameport;
108 struct resource *res_joystick;
109#endif
110} snd_card_als4000_t;
111
112static struct pci_device_id snd_als4000_ids[] = {
113 { 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
114 { 0, }
115};
116
117MODULE_DEVICE_TABLE(pci, snd_als4000_ids);
118
119static inline void snd_als4000_gcr_write_addr(unsigned long port, u32 reg, u32 val)
120{
121 outb(reg, port+0x0c);
122 outl(val, port+0x08);
123}
124
125static inline void snd_als4000_gcr_write(sb_t *sb, u32 reg, u32 val)
126{
127 snd_als4000_gcr_write_addr(sb->alt_port, reg, val);
128}
129
130static inline u32 snd_als4000_gcr_read_addr(unsigned long port, u32 reg)
131{
132 outb(reg, port+0x0c);
133 return inl(port+0x08);
134}
135
136static inline u32 snd_als4000_gcr_read(sb_t *sb, u32 reg)
137{
138 return snd_als4000_gcr_read_addr(sb->alt_port, reg);
139}
140
141static void snd_als4000_set_rate(sb_t *chip, unsigned int rate)
142{
143 if (!(chip->mode & SB_RATE_LOCK)) {
144 snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
145 snd_sbdsp_command(chip, rate>>8);
146 snd_sbdsp_command(chip, rate);
147 }
148}
149
150static void snd_als4000_set_capture_dma(sb_t *chip, dma_addr_t addr, unsigned size)
151{
152 snd_als4000_gcr_write(chip, 0xa2, addr);
153 snd_als4000_gcr_write(chip, 0xa3, (size-1));
154}
155
156static void snd_als4000_set_playback_dma(sb_t *chip, dma_addr_t addr, unsigned size)
157{
158 snd_als4000_gcr_write(chip, 0x91, addr);
159 snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000);
160}
161
162#define ALS4000_FORMAT_SIGNED (1<<0)
163#define ALS4000_FORMAT_16BIT (1<<1)
164#define ALS4000_FORMAT_STEREO (1<<2)
165
166static int snd_als4000_get_format(snd_pcm_runtime_t *runtime)
167{
168 int result;
169
170 result = 0;
171 if (snd_pcm_format_signed(runtime->format))
172 result |= ALS4000_FORMAT_SIGNED;
173 if (snd_pcm_format_physical_width(runtime->format) == 16)
174 result |= ALS4000_FORMAT_16BIT;
175 if (runtime->channels > 1)
176 result |= ALS4000_FORMAT_STEREO;
177 return result;
178}
179
180
181static struct {
182 unsigned char dsp_cmd, dma_on, dma_off, format;
183} playback_cmd_vals[]={
184
185{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_MONO },
186
187{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_MONO },
188
189{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_MONO },
190
191{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_MONO },
192
193{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_UNS_STEREO },
194
195{ SB_DSP4_OUT8_AI, SB_DSP_DMA8_ON, SB_DSP_DMA8_OFF, SB_DSP4_MODE_SIGN_STEREO },
196
197{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_UNS_STEREO },
198
199{ SB_DSP4_OUT16_AI, SB_DSP_DMA16_ON, SB_DSP_DMA16_OFF, SB_DSP4_MODE_SIGN_STEREO },
200};
201#define playback_cmd(chip) (playback_cmd_vals[(chip)->playback_format])
202
203
204enum { CMD_WIDTH8=0x04, CMD_SIGNED=0x10, CMD_MONO=0x80, CMD_STEREO=0xA0 };
205static unsigned char capture_cmd_vals[]=
206{
207CMD_WIDTH8|CMD_MONO,
208CMD_WIDTH8|CMD_SIGNED|CMD_MONO,
209CMD_MONO,
210CMD_SIGNED|CMD_MONO,
211CMD_WIDTH8|CMD_STEREO,
212CMD_WIDTH8|CMD_SIGNED|CMD_STEREO,
213CMD_STEREO,
214CMD_SIGNED|CMD_STEREO,
215};
216#define capture_cmd(chip) (capture_cmd_vals[(chip)->capture_format])
217
218static int snd_als4000_hw_params(snd_pcm_substream_t * substream,
219 snd_pcm_hw_params_t * hw_params)
220{
221 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
222}
223
224static int snd_als4000_hw_free(snd_pcm_substream_t * substream)
225{
226 snd_pcm_lib_free_pages(substream);
227 return 0;
228}
229
230static int snd_als4000_capture_prepare(snd_pcm_substream_t * substream)
231{
232 unsigned long flags;
233 sb_t *chip = snd_pcm_substream_chip(substream);
234 snd_pcm_runtime_t *runtime = substream->runtime;
235 unsigned long size;
236 unsigned count;
237
238 chip->capture_format = snd_als4000_get_format(runtime);
239
240 size = snd_pcm_lib_buffer_bytes(substream);
241 count = snd_pcm_lib_period_bytes(substream);
242
243 if (chip->capture_format & ALS4000_FORMAT_16BIT)
244 count >>=1;
245 count--;
246
247 spin_lock_irqsave(&chip->reg_lock, flags);
248 snd_als4000_set_rate(chip, runtime->rate);
249 snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
250 spin_unlock_irqrestore(&chip->reg_lock, flags);
251 spin_lock_irqsave(&chip->mixer_lock, flags );
252 snd_sbmixer_write(chip, 0xdc, count);
253 snd_sbmixer_write(chip, 0xdd, count>>8);
254 spin_unlock_irqrestore(&chip->mixer_lock, flags );
255 return 0;
256}
257
258static int snd_als4000_playback_prepare(snd_pcm_substream_t *substream)
259{
260 unsigned long flags;
261 sb_t *chip = snd_pcm_substream_chip(substream);
262 snd_pcm_runtime_t *runtime = substream->runtime;
263 unsigned long size;
264 unsigned count;
265
266 chip->playback_format = snd_als4000_get_format(runtime);
267
268 size = snd_pcm_lib_buffer_bytes(substream);
269 count = snd_pcm_lib_period_bytes(substream);
270
271 if (chip->playback_format & ALS4000_FORMAT_16BIT)
272 count >>=1;
273 count--;
274
275
276
277
278
279
280
281 spin_lock_irqsave(&chip->reg_lock, flags);
282 snd_als4000_set_rate(chip, runtime->rate);
283 snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
284
285
286
287 snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
288 snd_sbdsp_command(chip, playback_cmd(chip).format);
289 snd_sbdsp_command(chip, count);
290 snd_sbdsp_command(chip, count>>8);
291 snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
292 spin_unlock_irqrestore(&chip->reg_lock, flags);
293
294 return 0;
295}
296
297static int snd_als4000_capture_trigger(snd_pcm_substream_t * substream, int cmd)
298{
299 sb_t *chip = snd_pcm_substream_chip(substream);
300 int result = 0;
301
302 spin_lock(&chip->mixer_lock);
303 if (cmd == SNDRV_PCM_TRIGGER_START) {
304 chip->mode |= SB_RATE_LOCK_CAPTURE;
305 snd_sbmixer_write(chip, 0xde, capture_cmd(chip));
306 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
307 chip->mode &= ~SB_RATE_LOCK_CAPTURE;
308 snd_sbmixer_write(chip, 0xde, 0);
309 } else {
310 result = -EINVAL;
311 }
312 spin_unlock(&chip->mixer_lock);
313 return result;
314}
315
316static int snd_als4000_playback_trigger(snd_pcm_substream_t * substream, int cmd)
317{
318 sb_t *chip = snd_pcm_substream_chip(substream);
319 int result = 0;
320
321 spin_lock(&chip->reg_lock);
322 if (cmd == SNDRV_PCM_TRIGGER_START) {
323 chip->mode |= SB_RATE_LOCK_PLAYBACK;
324 snd_sbdsp_command(chip, playback_cmd(chip).dma_on);
325 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
326 snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
327 chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
328 } else {
329 result = -EINVAL;
330 }
331 spin_unlock(&chip->reg_lock);
332 return result;
333}
334
335static snd_pcm_uframes_t snd_als4000_capture_pointer(snd_pcm_substream_t * substream)
336{
337 sb_t *chip = snd_pcm_substream_chip(substream);
338 unsigned int result;
339
340 spin_lock(&chip->reg_lock);
341 result = snd_als4000_gcr_read(chip, 0xa4) & 0xffff;
342 spin_unlock(&chip->reg_lock);
343 return bytes_to_frames( substream->runtime, result );
344}
345
346static snd_pcm_uframes_t snd_als4000_playback_pointer(snd_pcm_substream_t * substream)
347{
348 sb_t *chip = snd_pcm_substream_chip(substream);
349 unsigned result;
350
351 spin_lock(&chip->reg_lock);
352 result = snd_als4000_gcr_read(chip, 0xa0) & 0xffff;
353 spin_unlock(&chip->reg_lock);
354 return bytes_to_frames( substream->runtime, result );
355}
356
357static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
358{
359 sb_t *chip = dev_id;
360 unsigned gcr_status;
361 unsigned sb_status;
362
363
364 gcr_status = inb(chip->alt_port + 0xe);
365
366 if ((gcr_status & 0x80) && (chip->playback_substream))
367 snd_pcm_period_elapsed(chip->playback_substream);
368 if ((gcr_status & 0x40) && (chip->capture_substream))
369 snd_pcm_period_elapsed(chip->capture_substream);
370 if ((gcr_status & 0x10) && (chip->rmidi))
371 snd_mpu401_uart_interrupt(irq, chip->rmidi, regs);
372
373 outb(gcr_status, chip->alt_port + 0xe);
374
375 spin_lock(&chip->mixer_lock);
376 sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
377 spin_unlock(&chip->mixer_lock);
378
379 if (sb_status & SB_IRQTYPE_8BIT)
380 snd_sb_ack_8bit(chip);
381 if (sb_status & SB_IRQTYPE_16BIT)
382 snd_sb_ack_16bit(chip);
383 if (sb_status & SB_IRQTYPE_MPUIN)
384 inb(chip->mpu_port);
385 if (sb_status & 0x20)
386 inb(SBP(chip, RESET));
387 return IRQ_HANDLED;
388}
389
390
391
392static snd_pcm_hardware_t snd_als4000_playback =
393{
394 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
395 SNDRV_PCM_INFO_MMAP_VALID),
396 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
397 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
398 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
399 .rate_min = 4000,
400 .rate_max = 48000,
401 .channels_min = 1,
402 .channels_max = 2,
403 .buffer_bytes_max = 65536,
404 .period_bytes_min = 64,
405 .period_bytes_max = 65536,
406 .periods_min = 1,
407 .periods_max = 1024,
408 .fifo_size = 0
409};
410
411static snd_pcm_hardware_t snd_als4000_capture =
412{
413 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
414 SNDRV_PCM_INFO_MMAP_VALID),
415 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
416 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
417 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
418 .rate_min = 4000,
419 .rate_max = 48000,
420 .channels_min = 1,
421 .channels_max = 2,
422 .buffer_bytes_max = 65536,
423 .period_bytes_min = 64,
424 .period_bytes_max = 65536,
425 .periods_min = 1,
426 .periods_max = 1024,
427 .fifo_size = 0
428};
429
430
431
432static int snd_als4000_playback_open(snd_pcm_substream_t * substream)
433{
434 sb_t *chip = snd_pcm_substream_chip(substream);
435 snd_pcm_runtime_t *runtime = substream->runtime;
436
437 chip->playback_substream = substream;
438 runtime->hw = snd_als4000_playback;
439 return 0;
440}
441
442static int snd_als4000_playback_close(snd_pcm_substream_t * substream)
443{
444 sb_t *chip = snd_pcm_substream_chip(substream);
445
446 chip->playback_substream = NULL;
447 snd_pcm_lib_free_pages(substream);
448 return 0;
449}
450
451static int snd_als4000_capture_open(snd_pcm_substream_t * substream)
452{
453 sb_t *chip = snd_pcm_substream_chip(substream);
454 snd_pcm_runtime_t *runtime = substream->runtime;
455
456 chip->capture_substream = substream;
457 runtime->hw = snd_als4000_capture;
458 return 0;
459}
460
461static int snd_als4000_capture_close(snd_pcm_substream_t * substream)
462{
463 sb_t *chip = snd_pcm_substream_chip(substream);
464
465 chip->capture_substream = NULL;
466 snd_pcm_lib_free_pages(substream);
467 return 0;
468}
469
470
471
472static snd_pcm_ops_t snd_als4000_playback_ops = {
473 .open = snd_als4000_playback_open,
474 .close = snd_als4000_playback_close,
475 .ioctl = snd_pcm_lib_ioctl,
476 .hw_params = snd_als4000_hw_params,
477 .hw_free = snd_als4000_hw_free,
478 .prepare = snd_als4000_playback_prepare,
479 .trigger = snd_als4000_playback_trigger,
480 .pointer = snd_als4000_playback_pointer
481};
482
483static snd_pcm_ops_t snd_als4000_capture_ops = {
484 .open = snd_als4000_capture_open,
485 .close = snd_als4000_capture_close,
486 .ioctl = snd_pcm_lib_ioctl,
487 .hw_params = snd_als4000_hw_params,
488 .hw_free = snd_als4000_hw_free,
489 .prepare = snd_als4000_capture_prepare,
490 .trigger = snd_als4000_capture_trigger,
491 .pointer = snd_als4000_capture_pointer
492};
493
494static void snd_als4000_pcm_free(snd_pcm_t *pcm)
495{
496 sb_t *chip = pcm->private_data;
497 chip->pcm = NULL;
498 snd_pcm_lib_preallocate_free_for_all(pcm);
499}
500
501static int __devinit snd_als4000_pcm(sb_t *chip, int device)
502{
503 snd_pcm_t *pcm;
504 int err;
505
506 if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0)
507 return err;
508 pcm->private_free = snd_als4000_pcm_free;
509 pcm->private_data = chip;
510 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
511 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_als4000_playback_ops);
512 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_als4000_capture_ops);
513
514 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
515 64*1024, 64*1024);
516
517 chip->pcm = pcm;
518
519 return 0;
520}
521
522
523
524static void snd_als4000_set_addr(unsigned long gcr,
525 unsigned int sb,
526 unsigned int mpu,
527 unsigned int opl,
528 unsigned int game)
529{
530 u32 confA = 0;
531 u32 confB = 0;
532
533 if (mpu > 0)
534 confB |= (mpu | 1) << 16;
535 if (sb > 0)
536 confB |= (sb | 1);
537 if (game > 0)
538 confA |= (game | 1) << 16;
539 if (opl > 0)
540 confA |= (opl | 1);
541 snd_als4000_gcr_write_addr(gcr, 0xa8, confA);
542 snd_als4000_gcr_write_addr(gcr, 0xa9, confB);
543}
544
545static void __devinit snd_als4000_configure(sb_t *chip)
546{
547 unsigned tmp;
548 int i;
549
550
551 spin_lock_irq(&chip->mixer_lock);
552 tmp = snd_sbmixer_read(chip, 0xc0);
553 snd_sbmixer_write(chip, 0xc0, tmp|0x80);
554
555 snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0);
556 snd_sbmixer_write(chip, 0xc0, tmp&0x7f);
557 spin_unlock_irq(&chip->mixer_lock);
558
559 spin_lock_irq(&chip->reg_lock);
560
561 snd_als4000_gcr_write(chip, 0x8c, 0x28000);
562 for(i = 0x91; i <= 0x96; ++i)
563 snd_als4000_gcr_write(chip, i, 0);
564
565 snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99));
566 spin_unlock_irq(&chip->reg_lock);
567}
568
569static void snd_card_als4000_free( snd_card_t *card )
570{
571 snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
572
573 snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
574
575#ifdef SUPPORT_JOYSTICK
576 if (acard->res_joystick) {
577 if (acard->gameport.io)
578 gameport_unregister_port(&acard->gameport);
579 snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0);
580 release_resource(acard->res_joystick);
581 kfree_nocheck(acard->res_joystick);
582 }
583#endif
584 pci_release_regions(acard->pci);
585 pci_disable_device(acard->pci);
586}
587
588static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
589 const struct pci_device_id *pci_id)
590{
591 static int dev;
592 snd_card_t *card;
593 snd_card_als4000_t *acard;
594 unsigned long gcr;
595 sb_t *chip;
596 opl3_t *opl3;
597 unsigned short word;
598 int err;
599 int joystick = 0;
600
601 if (dev >= SNDRV_CARDS)
602 return -ENODEV;
603 if (!enable[dev]) {
604 dev++;
605 return -ENOENT;
606 }
607
608
609 if ((err = pci_enable_device(pci)) < 0) {
610 return err;
611 }
612
613 if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
614 pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
615 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
616 pci_disable_device(pci);
617 return -ENXIO;
618 }
619
620 if ((err = pci_request_regions(pci, "ALS4000")) < 0) {
621 pci_disable_device(pci);
622 return err;
623 }
624 gcr = pci_resource_start(pci, 0);
625
626 pci_read_config_word(pci, PCI_COMMAND, &word);
627 pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
628 pci_set_master(pci);
629
630 card = snd_card_new(index[dev], id[dev], THIS_MODULE,
631 sizeof( snd_card_als4000_t ) );
632 if (card == NULL) {
633 pci_release_regions(pci);
634 pci_disable_device(pci);
635 return -ENOMEM;
636 }
637
638 acard = (snd_card_als4000_t *)card->private_data;
639 acard->pci = pci;
640 acard->gcr = gcr;
641 card->private_free = snd_card_als4000_free;
642
643
644#ifdef SUPPORT_JOYSTICK
645 if (joystick_port[dev] == 1) {
646
647 long p;
648 for (p = 0x200; p <= 0x218; p += 8) {
649 if ((acard->res_joystick = request_region(p, 8, "ALS4000 gameport")) != NULL) {
650 joystick_port[dev] = p;
651 break;
652 }
653 }
654 } else if (joystick_port[dev] > 0)
655 acard->res_joystick = request_region(joystick_port[dev], 8, "ALS4000 gameport");
656 if (acard->res_joystick)
657 joystick = joystick_port[dev];
658 else
659 joystick = 0;
660#endif
661 snd_als4000_set_addr(gcr, 0, 0, 0, joystick);
662
663 if ((err = snd_sbdsp_create(card,
664 gcr + 0x10,
665 pci->irq,
666 snd_als4000_interrupt,
667 -1,
668 -1,
669 SB_HW_ALS4000,
670 &chip)) < 0) {
671 snd_card_free(card);
672 return err;
673 }
674
675 chip->pci = pci;
676 chip->alt_port = gcr;
677 snd_card_set_dev(card, &pci->dev);
678
679 snd_als4000_configure(chip);
680
681 strcpy(card->driver, "ALS4000");
682 strcpy(card->shortname, "Avance Logic ALS4000");
683 sprintf(card->longname, "%s at 0x%lx, irq %i",
684 card->shortname, chip->alt_port, chip->irq);
685
686 if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
687 gcr+0x30, 1, pci->irq, 0,
688 &chip->rmidi)) < 0) {
689 snd_card_free(card);
690 printk(KERN_ERR "als4000: no MPU-401device at 0x%lx ?\n", gcr+0x30);
691 return err;
692 }
693
694 if ((err = snd_als4000_pcm(chip, 0)) < 0) {
695 snd_card_free(card);
696 return err;
697 }
698 if ((err = snd_sbmixer_new(chip)) < 0) {
699 snd_card_free(card);
700 return err;
701 }
702
703 if (snd_opl3_create(card, gcr+0x10, gcr+0x12,
704 OPL3_HW_AUTO, 1, &opl3) < 0) {
705 printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx ?\n",
706 gcr+0x10, gcr+0x12 );
707 } else {
708 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
709 snd_card_free(card);
710 return err;
711 }
712 }
713
714#ifdef SUPPORT_JOYSTICK
715 if (acard->res_joystick) {
716 acard->gameport.io = joystick;
717 gameport_register_port(&acard->gameport);
718 }
719#endif
720
721 if ((err = snd_card_register(card)) < 0) {
722 snd_card_free(card);
723 return err;
724 }
725 pci_set_drvdata(pci, card);
726 dev++;
727 return 0;
728}
729
730static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
731{
732 snd_card_free(pci_get_drvdata(pci));
733 pci_set_drvdata(pci, NULL);
734}
735
736static struct pci_driver driver = {
737 .name = "ALS4000",
738 .id_table = snd_als4000_ids,
739 .probe = snd_card_als4000_probe,
740 .remove = __devexit_p(snd_card_als4000_remove),
741};
742
743static int __init alsa_card_als4000_init(void)
744{
745 return pci_module_init(&driver);
746}
747
748static void __exit alsa_card_als4000_exit(void)
749{
750 pci_unregister_driver(&driver);
751}
752
753module_init(alsa_card_als4000_init)
754module_exit(alsa_card_als4000_exit)
755