- pre4:
[davej-history.git] / drivers / sound / sgalaxy.c
blobef0e4199c2f5d60968364708c0ffb6759e11cb25
1 /*
2 * sound/sgalaxy.c
4 * Low level driver for Aztech Sound Galaxy cards.
5 * Copyright 1998 Artur Skawina <skawina@geocities.com>
7 * Supported cards:
8 * Aztech Sound Galaxy Waverider Pro 32 - 3D
9 * Aztech Sound Galaxy Washington 16
11 * Based on cs4232.c by Hannu Savolainen and Alan Cox.
14 * Copyright (C) by Hannu Savolainen 1993-1997
16 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
17 * Version 2 (June 1991). See the "COPYING" file distributed with this software
18 * for more info.
21 #include <linux/init.h>
22 #include <linux/module.h>
24 #include "sound_config.h"
25 #include "ad1848.h"
27 static void sleep( unsigned howlong )
29 current->state = TASK_INTERRUPTIBLE;
30 schedule_timeout(howlong);
33 #define DPORT 0x80
35 /* Sound Blaster regs */
37 #define SBDSP_RESET 0x6
38 #define SBDSP_READ 0xA
39 #define SBDSP_COMMAND 0xC
40 #define SBDSP_STATUS SBDSP_COMMAND
41 #define SBDSP_DATA_AVAIL 0xE
43 static int sb_rst(int base)
45 int i;
47 outb( 1, base+SBDSP_RESET ); /* reset the DSP */
48 outb( 0, base+SBDSP_RESET );
50 for ( i=0; i<500; i++ ) /* delay */
51 inb(DPORT);
53 for ( i=0; i<100000; i++ )
55 if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
56 break;
59 if ( inb( base+SBDSP_READ )!=0xAA )
60 return 0;
62 return 1;
65 static int sb_cmd( int base, unsigned char val )
67 int i;
69 for ( i=100000; i; i-- )
71 if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
73 outb( val, base+SBDSP_COMMAND );
74 break;
77 return i; /* i>0 == success */
81 #define ai_sgbase driver_use_1
83 static int __init probe_sgalaxy( struct address_info *ai )
85 if ( check_region( ai->io_base, 8 ) ) {
86 printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
87 return 0;
90 if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
91 return probe_ms_sound(ai); /* The card is already active, check irq etc... */
93 if ( check_region( ai->ai_sgbase, 0x10 ) ) {
94 printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
95 return 0;
98 /* switch to MSS/WSS mode */
100 sb_rst( ai->ai_sgbase );
102 sb_cmd( ai->ai_sgbase, 9 );
103 sb_cmd( ai->ai_sgbase, 0 );
105 sleep( HZ/10 );
107 return probe_ms_sound(ai);
110 static void __init attach_sgalaxy( struct address_info *ai )
112 int n;
114 request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB" );
116 attach_ms_sound(ai, THIS_MODULE);
117 n=ai->slots[0];
119 if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
120 AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE ); /* Line-in */
121 AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH ); /* FM+Wavetable*/
122 AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD ); /* CD */
126 static void __exit unload_sgalaxy( struct address_info *ai )
128 unload_ms_sound( ai );
129 release_region( ai->ai_sgbase, 0x10 );
132 static struct address_info cfg;
134 static int __initdata io = -1;
135 static int __initdata irq = -1;
136 static int __initdata dma = -1;
137 static int __initdata dma2 = -1;
138 static int __initdata sgbase = -1;
140 MODULE_PARM(io,"i");
141 MODULE_PARM(irq,"i");
142 MODULE_PARM(dma,"i");
143 MODULE_PARM(dma2,"i");
144 MODULE_PARM(sgbase,"i");
146 static int __init init_sgalaxy(void)
148 cfg.io_base = io;
149 cfg.irq = irq;
150 cfg.dma = dma;
151 cfg.dma2 = dma2;
152 cfg.ai_sgbase = sgbase;
154 if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
155 printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
156 return -EINVAL;
159 if ( probe_sgalaxy(&cfg) == 0 )
160 return -ENODEV;
162 attach_sgalaxy(&cfg);
164 return 0;
167 static void __exit cleanup_sgalaxy(void)
169 unload_sgalaxy(&cfg);
172 module_init(init_sgalaxy);
173 module_exit(cleanup_sgalaxy);
175 #ifndef MODULE
176 static int __init setup_sgalaxy(char *str)
178 /* io, irq, dma, dma2, sgbase */
179 int ints[6];
181 str = get_options(str, ARRAY_SIZE(ints), ints);
182 io = ints[1];
183 irq = ints[2];
184 dma = ints[3];
185 dma2 = ints[4];
186 sgbase = ints[5];
188 return 1;
191 __setup("sgalaxy=", setup_sgalaxy);
192 #endif