]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/sound/gus_card.c
This is the Linux generic soundcard driver, version 1.0c. Supports
[FreeBSD/FreeBSD.git] / sys / i386 / isa / sound / gus_card.c
1
2 /*
3  * linux/kernel/chr_drv/sound/gus_card.c
4  * 
5  * Detection routine for the Gravis Ultrasound.
6  * 
7  * (C) 1993  Hannu Savolainen (hsavolai@cs.helsinki.fi) See COPYING for further
8  * details. Should be distributed with this file.
9  */
10
11 #include "sound_config.h"
12
13 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
14
15 #include "gus_hw.h"
16
17 void            gusintr (int);
18
19 int             gus_base, gus_irq, gus_dma;
20
21 static int
22 set_gus_irq (int interrupt_level)
23 {
24   int             retcode;
25
26 #ifdef linux
27   struct sigaction sa;
28
29   sa.sa_handler = gusintr;
30
31 #ifdef SND_SA_INTERRUPT
32   sa.sa_flags = SA_INTERRUPT;
33 #else
34   sa.sa_flags = 0;
35 #endif
36
37   sa.sa_mask = 0;
38   sa.sa_restorer = NULL;
39
40   retcode = irqaction (interrupt_level, &sa);
41
42   if (retcode < 0)
43     {
44       printk ("GUS: IRQ%d already in use\n", interrupt_level);
45     }
46
47 #else
48   /* #  error Unimplemented for this OS  */
49 #endif
50   return retcode;
51 }
52
53 int
54 gus_set_midi_irq (int interrupt_level)
55 {
56   int             retcode;
57
58 #ifdef linux
59   struct sigaction sa;
60
61   sa.sa_handler = gus_midi_interrupt;
62
63 #ifdef SND_SA_INTERRUPT
64   sa.sa_flags = SA_INTERRUPT;
65 #else
66   sa.sa_flags = 0;
67 #endif
68
69   sa.sa_mask = 0;
70   sa.sa_restorer = NULL;
71
72   retcode = irqaction (interrupt_level, &sa);
73
74   if (retcode < 0)
75     {
76       printk ("GUS: IRQ%d already in use\n", interrupt_level);
77     }
78
79 #else
80   /* #  error Unimplemented for this OS  */
81 #endif
82   return retcode;
83 }
84
85 long
86 attach_gus_card (long mem_start, struct address_info *hw_config)
87 {
88   int             io_addr;
89
90   set_gus_irq (hw_config->irq);
91
92   if (gus_wave_detect (hw_config->io_base))     /* Try first the default */
93     {
94       mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma);
95 #ifndef EXCLUDE_MIDI
96       mem_start = gus_midi_init (mem_start);
97 #endif
98       return mem_start;
99     }
100
101 #ifndef EXCLUDE_GUS_IODETECT
102
103   /*
104    * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
105    */
106
107   for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
108     if (io_addr != hw_config->io_base)  /* Already tested */
109       if (gus_wave_detect (io_addr))
110         {
111           printk (" WARNING! GUS found at %03x, config was %03x ", io_addr, hw_config->io_base);
112           mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma);
113 #ifndef EXCLUDE_MIDI
114           mem_start = gus_midi_init (mem_start);
115 #endif
116           return mem_start;
117         }
118
119 #endif
120
121   return mem_start;             /* Not detected */
122 }
123
124 int
125 probe_gus (struct address_info *hw_config)
126 {
127   int             io_addr;
128
129   if (gus_wave_detect (hw_config->io_base))
130     return 1;
131
132 #ifndef EXCLUDE_GUS_IODETECT
133
134   /*
135    * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
136    */
137
138   for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
139     if (io_addr != hw_config->io_base)  /* Already tested */
140       if (gus_wave_detect (io_addr))
141         return 1;
142
143 #endif
144
145   return 0;
146 }
147
148 void
149 gusintr (int unit)
150 {
151   unsigned char   src;
152
153   while (1)
154     {
155       if (!(src = INB (u_IrqStatus)))
156         return;
157
158       if (src & DMA_TC_IRQ)
159         {
160           guswave_dma_irq ();
161         }
162
163       if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
164         {
165 #ifndef EXCLUDE_MIDI
166           gus_midi_interrupt (0);
167 #endif
168         }
169
170       if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
171         {
172           printk ("T");
173           gus_write8 (0x45, 0); /* Timer control */
174         }
175
176       if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
177         {
178           gus_voice_irq ();
179         }
180     }
181 }
182
183 #endif