~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/sound/sgalaxy.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.