kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / dev / sound / isa / i386 / dev_table.c
1 /*
2  * sound/dev_table.c
3  * 
4  * Device call tables.
5  * 
6  * Copyright by Hannu Savolainen 1993
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met: 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer. 2.
12  * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  * 
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  * 
28  * $FreeBSD: src/sys/i386/isa/sound/dev_table.c,v 1.18 1999/12/20 18:04:59 eivind Exp $
29  * $DragonFly: src/sys/dev/sound/isa/i386/Attic/dev_table.c,v 1.3 2003/08/07 21:17:12 dillon Exp $
30  */
31
32 #define _DEV_TABLE_C_
33 #include "sound_config.h"
34
35 #if NSND > 0
36
37 int             sound_started = 0;
38
39 int             sndtable_get_cardcount(void);
40 int             snd_find_driver(int type);
41 static void     sndtable_init(void);
42 int             sndtable_probe(int unit, struct address_info * hw_config);
43 int             sndtable_init_card(int unit, struct address_info * hw_config);
44 static void     start_services(void);
45 static void     start_cards(void);
46 struct address_info *sound_getconf(int card_type);
47
48 int
49 snd_find_driver(int type)
50 {
51     int   i, n = num_sound_drivers;
52
53     for (i = 0; i < n; i++)
54         if (sound_drivers[i].card_type == type)
55             return i;
56
57     return -1;
58 }
59
60 static void
61 start_services()
62 {
63     int   soundcards_installed;
64
65     if (!(soundcards_installed = sndtable_get_cardcount()))
66         return ;        /* No cards detected */
67
68 #ifdef CONFIG_AUDIO
69     if (num_audiodevs)  /* Audio devices present */
70         DMAbuf_init();
71 #endif
72
73 #ifdef CONFIG_MIDI
74     if (num_midis)
75         /* MIDIbuf_init(0) */;
76 #endif
77
78 #ifdef CONFIG_SEQUENCER
79     if (num_midis + num_synths)
80         sequencer_init();
81 #endif
82 }
83
84 static void
85 start_cards()
86 {
87     int  drv, i, n = num_sound_cards;
88     struct card_info *ci = snd_installed_cards ;
89
90     sound_started = 1;
91     if (trace_init)
92         printf("Sound initialization started\n");
93
94     /*
95      * Check the number of cards actually defined in the table
96      */
97
98     for (i = 0; i < n && snd_installed_cards[i].card_type; i++)
99         num_sound_cards = i + 1;
100
101     for (i = 0; i < n && ci->card_type; ci++, i++)
102         if (ci->enabled) {
103             if ((drv = snd_find_driver(ci->card_type)) == -1) {
104                 ci->enabled = 0;        /* Mark as not detected */
105                 continue;
106             }
107             ci->config.card_subtype = sound_drivers[drv].card_subtype;
108
109             if (sound_drivers[drv].probe(&(ci->config)))
110                 sound_drivers[drv].attach(&(ci->config));
111             else
112                 ci->enabled = 0;        /* Mark as not detected */
113         }
114     if (trace_init)
115         printf("Sound initialization complete\n");
116 }
117
118 static void
119 sndtable_init()
120 {
121     start_cards();
122 }
123
124 /*
125  * sndtable_probe probes a specific device. unit is the voxware unit number.
126  */
127
128 int
129 sndtable_probe(int unit, struct address_info * hw_config)
130 {
131     int  i, sel = -1, n = num_sound_cards;
132     struct card_info *ci = snd_installed_cards ;
133
134     DDB(printf("-- sndtable_probe(%d)\n", unit));
135
136
137     /*
138      * for some reason unit 0 always succeeds ?
139      */
140     if (!unit)
141         return TRUE;
142
143     sound_started = 1;
144
145     for (i=0; i<n && sel== -1 && ci->card_type; ci++, i++)
146         if ( (ci->enabled) && (ci->card_type == unit) ) {
147             /* DDB(printf("-- found card %d\n", i) ); */
148             sel = i; /* and break */
149         }
150
151     /*
152      * not found. Creates a new entry in the table for this unit.
153      */
154     if (sel == -1 && num_sound_cards < max_sound_cards) {
155         int   i;
156
157         i = sel = (num_sound_cards++);
158         DDB(printf("-- installing card %d\n", i) );
159
160         ci = &snd_installed_cards[sel] ;
161         ci->card_type = unit;
162         ci->enabled = 1;
163     }
164     /* DDB(printf("-- installed card %d\n", sel) ); */
165     if (sel != -1) {
166         int   drv;
167
168         ci->config.io_base = hw_config->io_base;
169         ci->config.irq = hw_config->irq;
170         ci->config.dma = hw_config->dma;
171         ci->config.dma2 = hw_config->dma2;
172         ci->config.name = hw_config->name;
173         ci->config.always_detect = hw_config->always_detect;
174         ci->config.card_subtype = hw_config->card_subtype;
175         ci->config.osp = hw_config->osp;
176
177         if ((drv = snd_find_driver(ci->card_type)) == -1) {
178             ci->enabled = 0;
179             DDB(printf("Failed to find driver\n"));
180             return FALSE;
181         }
182         DDB(printf("-- Driver name '%s' probe 0x%08x\n",
183                 sound_drivers[drv].name, sound_drivers[drv].probe));
184
185         hw_config->card_subtype =
186         ci->config.card_subtype = sound_drivers[drv].card_subtype;
187
188         if (sound_drivers[drv].probe(hw_config)) {
189             DDB(printf("-- Hardware probed OK\n"));
190             return TRUE;
191         }
192         DDB(printf("-- Failed to find hardware\n"));
193         ci->enabled = 0;        /* mark as not detected */
194         return FALSE;
195     }
196     return FALSE;
197 }
198
199 int
200 sndtable_init_card(int unit, struct address_info * hw_config)
201 {
202     int     i, n = num_sound_cards;
203     struct card_info *ci = snd_installed_cards ;
204
205     DDB(printf("sndtable_init_card(%d) entered\n", unit));
206
207     if (!unit) {
208         sndtable_init() ;
209         return TRUE;
210     }
211     for (i = 0; i < n && ci->card_type; ci++, i++)
212         if (ci->card_type == unit) {
213             int             drv;
214
215             ci->config.io_base = hw_config->io_base;
216             ci->config.irq = hw_config->irq;
217             ci->config.dma = hw_config->dma;
218             ci->config.dma2 = hw_config->dma2;
219             ci->config.name = hw_config->name;
220             ci->config.always_detect = hw_config->always_detect;
221             ci->config.card_subtype = hw_config->card_subtype;
222             ci->config.osp = hw_config->osp;
223
224             if ((drv = snd_find_driver(ci->card_type)) == -1)
225                 ci->enabled = 0; /* Mark not fnd */
226             else {
227                 DDB(printf("Located card - calling attach routine\n"));
228                 sound_drivers[drv].attach(hw_config) ;
229                 DDB(printf("attach routine finished\n"));
230             }
231             start_services();
232             return TRUE;
233         }
234         DDB(printf("sndtable_init_card: No card defined with type=%d, num cards: %d\n",
235                unit, num_sound_cards));
236     return FALSE;
237 }
238
239 int
240 sndtable_get_cardcount(void)
241 {
242     return num_audiodevs + num_mixers + num_synths + num_midis;
243 }
244
245 struct address_info *
246 sound_getconf(int card_type)
247 {
248     int    j, ptr = -1, n = num_sound_cards;
249
250     for (j = 0; j < n && ptr == -1 && snd_installed_cards[j].card_type; j++)
251         if (snd_installed_cards[j].card_type == card_type)
252             ptr = j;
253
254     if (ptr == -1)
255         return (struct address_info *) NULL;
256
257     return &snd_installed_cards[ptr].config;
258 }
259
260 #endif