1 /*
2 * sound/sgalaxy.c
3 *
4 * Low level driver for Aztech Sound Galaxy cards.
5 * Copyright 1998 Artur Skawina <skawina@geocities.com>
6 *
7 * Supported cards:
8 * Aztech Sound Galaxy Waverider Pro 32 - 3D
9 * Aztech Sound Galaxy Washington 16
10 *
11 * Based on cs4232.c by Hannu Savolainen and Alan Cox.
12 *
13 *
14 * Copyright (C) by Hannu Savolainen 1993-1997
15 *
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.
19 *
20 * Changes:
21 * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
22 * Added __init to sb_rst() and sb_cmd()
23 */
24
25 #include <linux/init.h>
26 #include <linux/module.h>
27
28 #include "sound_config.h"
29 #include "ad1848.h"
30
31 static void sleep( unsigned howlong )
32 {
33 current->state = TASK_INTERRUPTIBLE;
34 schedule_timeout(howlong);
35 }
36
37 #define DPORT 0x80
38
39 /* Sound Blaster regs */
40
41 #define SBDSP_RESET 0x6
42 #define SBDSP_READ 0xA
43 #define SBDSP_COMMAND 0xC
44 #define SBDSP_STATUS SBDSP_COMMAND
45 #define SBDSP_DATA_AVAIL 0xE
46
47 static int __init sb_rst(int base)
48 {
49 int i;
50
51 outb( 1, base+SBDSP_RESET ); /* reset the DSP */
52 outb( 0, base+SBDSP_RESET );
53
54 for ( i=0; i<500; i++ ) /* delay */
55 inb(DPORT);
56
57 for ( i=0; i<100000; i++ )
58 {
59 if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
60 break;
61 }
62
63 if ( inb( base+SBDSP_READ )!=0xAA )
64 return 0;
65
66 return 1;
67 }
68
69 static int __init sb_cmd( int base, unsigned char val )
70 {
71 int i;
72
73 for ( i=100000; i; i-- )
74 {
75 if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
76 {
77 outb( val, base+SBDSP_COMMAND );
78 break;
79 }
80 }
81 return i; /* i>0 == success */
82 }
83
84
85 #define ai_sgbase driver_use_1
86
87 static int __init probe_sgalaxy( struct address_info *ai )
88 {
89 if ( check_region( ai->io_base, 8 ) ) {
90 printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
91 return 0;
92 }
93
94 if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
95 return probe_ms_sound(ai); /* The card is already active, check irq etc... */
96
97 if ( check_region( ai->ai_sgbase, 0x10 ) ) {
98 printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
99 return 0;
100 }
101
102 /* switch to MSS/WSS mode */
103
104 sb_rst( ai->ai_sgbase );
105
106 sb_cmd( ai->ai_sgbase, 9 );
107 sb_cmd( ai->ai_sgbase, 0 );
108
109 sleep( HZ/10 );
110
111 return probe_ms_sound(ai);
112 }
113
114 static void __init attach_sgalaxy( struct address_info *ai )
115 {
116 int n;
117
118 request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB" );
119
120 attach_ms_sound(ai, THIS_MODULE);
121 n=ai->slots[0];
122
123 if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
124 AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE ); /* Line-in */
125 AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH ); /* FM+Wavetable*/
126 AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD ); /* CD */
127 }
128 }
129
130 static void __exit unload_sgalaxy( struct address_info *ai )
131 {
132 unload_ms_sound( ai );
133 release_region( ai->ai_sgbase, 0x10 );
134 }
135
136 static struct address_info cfg;
137
138 static int __initdata io = -1;
139 static int __initdata irq = -1;
140 static int __initdata dma = -1;
141 static int __initdata dma2 = -1;
142 static int __initdata sgbase = -1;
143
144 MODULE_PARM(io,"i");
145 MODULE_PARM(irq,"i");
146 MODULE_PARM(dma,"i");
147 MODULE_PARM(dma2,"i");
148 MODULE_PARM(sgbase,"i");
149
150 static int __init init_sgalaxy(void)
151 {
152 cfg.io_base = io;
153 cfg.irq = irq;
154 cfg.dma = dma;
155 cfg.dma2 = dma2;
156 cfg.ai_sgbase = sgbase;
157
158 if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
159 printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
160 return -EINVAL;
161 }
162
163 if ( probe_sgalaxy(&cfg) == 0 )
164 return -ENODEV;
165
166 attach_sgalaxy(&cfg);
167
168 return 0;
169 }
170
171 static void __exit cleanup_sgalaxy(void)
172 {
173 unload_sgalaxy(&cfg);
174 }
175
176 module_init(init_sgalaxy);
177 module_exit(cleanup_sgalaxy);
178
179 #ifndef MODULE
180 static int __init setup_sgalaxy(char *str)
181 {
182 /* io, irq, dma, dma2, sgbase */
183 int ints[6];
184
185 str = get_options(str, ARRAY_SIZE(ints), ints);
186 io = ints[1];
187 irq = ints[2];
188 dma = ints[3];
189 dma2 = ints[4];
190 sgbase = ints[5];
191
192 return 1;
193 }
194
195 __setup("sgalaxy=", setup_sgalaxy);
196 #endif
197
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.