Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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         struct resource *ports;
 90         int n;
 91 
 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;
 95         }
 96 
 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;
102         }
103 
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;
109         }
110         
111         if (ad1848_detect(ports, NULL, ai->osp))
112                 goto out;  /* The card is already active, check irq etc... */
113         
114         /* switch to MSS/WSS mode */
115    
116         sb_rst( ai->ai_sgbase );
117    
118         sb_cmd( ai->ai_sgbase, 9 );
119         sb_cmd( ai->ai_sgbase, 0 );
120 
121         sleep( HZ/10 );
122 
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;
129         }
130 
131         attach_ms_sound(ai, ports, THIS_MODULE);
132         n=ai->slots[0];
133         
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 */
138         }
139         return 1;
140 }
141 
142 static void __exit unload_sgalaxy( struct address_info *ai )
143 {
144         unload_ms_sound( ai );
145         release_region( ai->ai_sgbase, 0x10 );
146 }
147 
148 static struct address_info cfg;
149 
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;
155 
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);
161 
162 static int __init init_sgalaxy(void)
163 {
164         cfg.io_base   = io;
165         cfg.irq       = irq;
166         cfg.dma       = dma;
167         cfg.dma2      = dma2;
168         cfg.ai_sgbase = sgbase;
169 
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;
173         }
174 
175         if ( probe_sgalaxy(&cfg) == 0 )
176                 return -ENODEV;
177 
178         return 0;
179 }
180 
181 static void __exit cleanup_sgalaxy(void)
182 {
183         unload_sgalaxy(&cfg);
184 }
185 
186 module_init(init_sgalaxy);
187 module_exit(cleanup_sgalaxy);
188 
189 #ifndef MODULE
190 static int __init setup_sgalaxy(char *str)
191 {
192         /* io, irq, dma, dma2, sgbase */
193         int ints[6];
194         
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];
201 
202         return 1;
203 }
204 
205 __setup("sgalaxy=", setup_sgalaxy);
206 #endif
207 MODULE_LICENSE("GPL");
208 
  This page was automatically generated by the LXR engine.