drivers/scsi/psi240i.c: fix an array overrun
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / oss / sgalaxy.c
blob3f32d4674371b4a14f6546ff24369a8baf96fbc0
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.
20 * Changes:
21 * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
22 * Added __init to sb_rst() and sb_cmd()
25 #include <linux/init.h>
26 #include <linux/module.h>
28 #include "sound_config.h"
29 #include "ad1848.h"
31 static void sleep( unsigned howlong )
33 current->state = TASK_INTERRUPTIBLE;
34 schedule_timeout(howlong);
37 #define DPORT 0x80
39 /* Sound Blaster regs */
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
47 static int __init sb_rst(int base)
49 int i;
51 outb( 1, base+SBDSP_RESET ); /* reset the DSP */
52 outb( 0, base+SBDSP_RESET );
54 for ( i=0; i<500; i++ ) /* delay */
55 inb(DPORT);
57 for ( i=0; i<100000; i++ )
59 if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
60 break;
63 if ( inb( base+SBDSP_READ )!=0xAA )
64 return 0;
66 return 1;
69 static int __init sb_cmd( int base, unsigned char val )
71 int i;
73 for ( i=100000; i; i-- )
75 if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
77 outb( val, base+SBDSP_COMMAND );
78 break;
81 return i; /* i>0 == success */
85 #define ai_sgbase driver_use_1
87 static int __init probe_sgalaxy( struct address_info *ai )
89 struct resource *ports;
90 int n;
92 if (!request_region(ai->io_base, 4, "WSS config")) {
93 printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
94 return 0;
97 ports = request_region(ai->io_base + 4, 4, "ad1848");
98 if (!ports) {
99 printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
100 release_region(ai->io_base, 4);
101 return 0;
104 if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) {
105 printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
106 release_region(ai->io_base + 4, 4);
107 release_region(ai->io_base, 4);
108 return 0;
111 if (ad1848_detect(ports, NULL, ai->osp))
112 goto out; /* The card is already active, check irq etc... */
114 /* switch to MSS/WSS mode */
116 sb_rst( ai->ai_sgbase );
118 sb_cmd( ai->ai_sgbase, 9 );
119 sb_cmd( ai->ai_sgbase, 0 );
121 sleep( HZ/10 );
123 out:
124 if (!probe_ms_sound(ai, ports)) {
125 release_region(ai->io_base + 4, 4);
126 release_region(ai->io_base, 4);
127 release_region(ai->ai_sgbase, 0x10);
128 return 0;
131 attach_ms_sound(ai, ports, THIS_MODULE);
132 n=ai->slots[0];
134 if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
135 AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE ); /* Line-in */
136 AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH ); /* FM+Wavetable*/
137 AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD ); /* CD */
139 return 1;
142 static void __exit unload_sgalaxy( struct address_info *ai )
144 unload_ms_sound( ai );
145 release_region( ai->ai_sgbase, 0x10 );
148 static struct address_info cfg;
150 static int __initdata io = -1;
151 static int __initdata irq = -1;
152 static int __initdata dma = -1;
153 static int __initdata dma2 = -1;
154 static int __initdata sgbase = -1;
156 module_param(io, int, 0);
157 module_param(irq, int, 0);
158 module_param(dma, int, 0);
159 module_param(dma2, int, 0);
160 module_param(sgbase, int, 0);
162 static int __init init_sgalaxy(void)
164 cfg.io_base = io;
165 cfg.irq = irq;
166 cfg.dma = dma;
167 cfg.dma2 = dma2;
168 cfg.ai_sgbase = sgbase;
170 if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
171 printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
172 return -EINVAL;
175 if ( probe_sgalaxy(&cfg) == 0 )
176 return -ENODEV;
178 return 0;
181 static void __exit cleanup_sgalaxy(void)
183 unload_sgalaxy(&cfg);
186 module_init(init_sgalaxy);
187 module_exit(cleanup_sgalaxy);
189 #ifndef MODULE
190 static int __init setup_sgalaxy(char *str)
192 /* io, irq, dma, dma2, sgbase */
193 int ints[6];
195 str = get_options(str, ARRAY_SIZE(ints), ints);
196 io = ints[1];
197 irq = ints[2];
198 dma = ints[3];
199 dma2 = ints[4];
200 sgbase = ints[5];
202 return 1;
205 __setup("sgalaxy=", setup_sgalaxy);
206 #endif
207 MODULE_LICENSE("GPL");