Linux 2.1.127
[davej-history.git] / drivers / sound / sgalaxy.c
blobe92aa8321b0ad019db6c5a51d8d32a1e5d0564f9
1 /*
2 * sound/sgalaxy.c
4 * Low level driver for Aztech Sound Galaxy cards.
5 * Copyright 1998 Artur Skawina
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/config.h>
22 #include <linux/module.h>
24 #include "sound_config.h"
25 #include "soundmodule.h"
27 #if defined(CONFIG_SGALAXY) || defined (MODULE)
29 static void sleep( unsigned howlong )
31 current->state = TASK_INTERRUPTIBLE;
32 schedule(howlong);
35 #define DPORT 0x80
37 /* Sound Blaster regs */
39 #define SBDSP_RESET 0x6
40 #define SBDSP_READ 0xA
41 #define SBDSP_COMMAND 0xC
42 #define SBDSP_STATUS SBDSP_COMMAND
43 #define SBDSP_DATA_AVAIL 0xE
45 static int sb_rst(int base)
47 int i;
49 outb( 1, base+SBDSP_RESET ); /* reset the DSP */
50 outb( 0, base+SBDSP_RESET );
52 for ( i=0; i<500; i++ ) /* delay */
53 inb(DPORT);
55 for ( i=0; i<100000; i++ )
57 if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
58 break;
61 if ( inb( base+SBDSP_READ )!=0xAA )
62 return 0;
64 return 1;
67 static int sb_cmd( int base, unsigned char val )
69 int i;
71 for ( i=100000; i; i-- )
73 if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
75 outb( val, base+SBDSP_COMMAND );
76 break;
79 return i; /* i>0 == success */
83 #define ai_sgbase driver_use_1
85 int probe_sgalaxy( struct address_info *ai )
87 if ( check_region( ai->io_base, 8 ) )
89 printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
90 return 0;
93 if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
94 return probe_ms_sound(ai); /* The card is already active, check irq etc... */
96 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;
102 /* switch to MSS/WSS mode */
104 sb_rst( ai->ai_sgbase );
106 sb_cmd( ai->ai_sgbase, 9 );
107 sb_cmd( ai->ai_sgbase, 0 );
109 sleep( HZ/10 );
111 if ( ad1848_detect( ai->io_base+4, NULL, ai->osp ) )
112 return 1;
113 return 0;
116 void attach_sgalaxy( struct address_info *ai )
118 int n;
120 request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB" );
122 attach_ms_sound( ai );
123 n=ai->slots[0];
125 if (n!=-1 && audio_devs[n]->mixer_dev != -1 )
127 AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE ); /* Line-in */
128 AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH ); /* FM+Wavetable*/
129 AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD ); /* CD */
133 void unload_sgalaxy( struct address_info *ai )
135 unload_ms_sound( ai );
136 release_region( ai->ai_sgbase, 0x10 );
139 #ifdef MODULE
141 int io = -1;
142 int irq = -1;
143 int dma = -1;
144 int dma2 = -1;
145 int sgbase = -1;
147 MODULE_PARM(io,"i");
148 MODULE_PARM(irq,"i");
149 MODULE_PARM(dma,"i");
150 MODULE_PARM(dma2,"i");
151 MODULE_PARM(sgbase,"i");
153 EXPORT_NO_SYMBOLS;
155 struct address_info ai;
158 int init_module(void)
160 if ( io==-1 || irq==-1 || dma==-1 || sgbase==-1 )
162 printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
163 return -EINVAL;
166 ai.io_base = io;
167 ai.irq = irq;
168 ai.dma = dma;
169 ai.dma2 = dma2;
170 ai.ai_sgbase = sgbase;
172 if ( probe_sgalaxy( &ai )==0 )
173 return -ENODEV;
175 attach_sgalaxy( &ai );
177 SOUND_LOCK;
178 return 0;
181 void cleanup_module(void)
183 unload_sgalaxy( &ai );
184 SOUND_LOCK_END;
187 #endif
188 #endif