This source file includes following definitions.
- sbmatch
- sbattach
- sb_getdev
- sb_mpu401_open
- sb_mpu401_output
- sb_mpu401_close
- sb_mpu401_getinfo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include "midi.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/errno.h>
43 #include <sys/ioctl.h>
44 #include <sys/syslog.h>
45 #include <sys/device.h>
46 #include <sys/proc.h>
47
48 #include <machine/cpu.h>
49 #include <machine/intr.h>
50 #include <machine/bus.h>
51
52 #include <sys/audioio.h>
53 #include <dev/audio_if.h>
54 #include <dev/midi_if.h>
55
56 #include <dev/isa/isavar.h>
57 #include <dev/isa/isadmavar.h>
58
59 #include <dev/isa/sbreg.h>
60 #include <dev/isa/sbvar.h>
61 #include <dev/isa/sbdspvar.h>
62
63 struct cfdriver sb_cd = {
64 NULL, "sb", DV_DULL
65 };
66
67 #if NMIDI > 0
68 int sb_mpu401_open(void *, int, void (*iintr)(void *, int),
69 void (*ointr)(void *), void *arg);
70 void sb_mpu401_close(void *);
71 int sb_mpu401_output(void *, int);
72 void sb_mpu401_getinfo(void *, struct midi_info *);
73
74 struct midi_hw_if sb_midi_hw_if = {
75 sbdsp_midi_open,
76 sbdsp_midi_close,
77 sbdsp_midi_output,
78 0,
79 sbdsp_midi_getinfo,
80 0,
81 };
82
83 struct midi_hw_if sb_mpu401_hw_if = {
84 sb_mpu401_open,
85 sb_mpu401_close,
86 sb_mpu401_output,
87 0,
88 sb_mpu401_getinfo,
89 0,
90 };
91 #endif
92
93 struct audio_device sb_device = {
94 "SoundBlaster",
95 "x",
96 "sb"
97 };
98
99 int sb_getdev(void *, struct audio_device *);
100
101
102
103
104
105 struct audio_hw_if sb_hw_if = {
106 sbdsp_open,
107 sbdsp_close,
108 0,
109 sbdsp_query_encoding,
110 sbdsp_set_params,
111 sbdsp_round_blocksize,
112 0,
113 0,
114 0,
115 0,
116 0,
117 sbdsp_haltdma,
118 sbdsp_haltdma,
119 sbdsp_speaker_ctl,
120 sb_getdev,
121 0,
122 sbdsp_mixer_set_port,
123 sbdsp_mixer_get_port,
124 sbdsp_mixer_query_devinfo,
125 sb_malloc,
126 sb_free,
127 sb_round,
128 sb_mappage,
129 sbdsp_get_props,
130 sbdsp_trigger_output,
131 sbdsp_trigger_input
132 };
133
134 #ifdef AUDIO_DEBUG
135 #define DPRINTF(x) if (sbdebug) printf x
136 int sbdebug = 0;
137 #else
138 #define DPRINTF(x)
139 #endif
140
141
142
143
144
145
146 int
147 sbmatch(sc)
148 struct sbdsp_softc *sc;
149 {
150 static u_char drq_conf[8] = {
151 0x01, 0x02, -1, 0x08, -1, 0x20, 0x40, 0x80
152 };
153
154 static u_char irq_conf[11] = {
155 -1, -1, 0x01, -1, -1, 0x02, -1, 0x04, -1, 0x01, 0x08
156 };
157
158 if (sbdsp_probe(sc) == 0)
159 return 0;
160
161
162
163
164 if (ISSBPROCLASS(sc)) {
165 if (!SBP_DRQ_VALID(sc->sc_drq8)) {
166 DPRINTF(("%s: configured dma chan %d invalid\n",
167 sc->sc_dev.dv_xname, sc->sc_drq8));
168 return 0;
169 }
170 } else {
171 if (!SB_DRQ_VALID(sc->sc_drq8)) {
172 DPRINTF(("%s: configured dma chan %d invalid\n",
173 sc->sc_dev.dv_xname, sc->sc_drq8));
174 return 0;
175 }
176 }
177
178 if (0 <= sc->sc_drq16 && sc->sc_drq16 <= 3)
179
180
181
182
183
184 sc->sc_drq16 = -1;
185
186 if (ISSB16CLASS(sc)) {
187 if (sc->sc_drq16 == -1)
188 sc->sc_drq16 = sc->sc_drq8;
189 if (!SB16_DRQ_VALID(sc->sc_drq16)) {
190 DPRINTF(("%s: configured dma chan %d invalid\n",
191 sc->sc_dev.dv_xname, sc->sc_drq16));
192 return 0;
193 }
194 } else
195 sc->sc_drq16 = sc->sc_drq8;
196
197 if (ISSBPROCLASS(sc)) {
198 if (!SBP_IRQ_VALID(sc->sc_irq)) {
199 DPRINTF(("%s: configured irq %d invalid\n",
200 sc->sc_dev.dv_xname, sc->sc_irq));
201 return 0;
202 }
203 } else {
204 if (!SB_IRQ_VALID(sc->sc_irq)) {
205 DPRINTF(("%s: configured irq %d invalid\n",
206 sc->sc_dev.dv_xname, sc->sc_irq));
207 return 0;
208 }
209 }
210
211 if (ISSB16CLASS(sc)) {
212 int w, r;
213 #if 0
214 DPRINTF(("%s: old drq conf %02x\n", sc->sc_dev.dv_xname,
215 sbdsp_mix_read(sc, SBP_SET_DRQ)));
216 DPRINTF(("%s: try drq conf %02x\n", sc->sc_dev.dv_xname,
217 drq_conf[sc->sc_drq16] | drq_conf[sc->sc_drq8]));
218 #endif
219 w = drq_conf[sc->sc_drq16] | drq_conf[sc->sc_drq8];
220 sbdsp_mix_write(sc, SBP_SET_DRQ, w);
221 r = sbdsp_mix_read(sc, SBP_SET_DRQ) & 0xeb;
222 if (r != w) {
223 DPRINTF(("%s: setting drq mask %02x failed, got %02x\n", sc->sc_dev.dv_xname, w, r));
224 return 0;
225 }
226 #if 0
227 DPRINTF(("%s: new drq conf %02x\n", sc->sc_dev.dv_xname,
228 sbdsp_mix_read(sc, SBP_SET_DRQ)));
229 #endif
230
231 #if 0
232 DPRINTF(("%s: old irq conf %02x\n", sc->sc_dev.dv_xname,
233 sbdsp_mix_read(sc, SBP_SET_IRQ)));
234 DPRINTF(("%s: try irq conf %02x\n", sc->sc_dev.dv_xname,
235 irq_conf[sc->sc_irq]));
236 #endif
237 w = irq_conf[sc->sc_irq];
238 sbdsp_mix_write(sc, SBP_SET_IRQ, w);
239 r = sbdsp_mix_read(sc, SBP_SET_IRQ) & 0x0f;
240 if (r != w) {
241 DPRINTF(("%s: setting irq mask %02x failed, got %02x\n",
242 sc->sc_dev.dv_xname, w, r));
243 return 0;
244 }
245 #if 0
246 DPRINTF(("%s: new irq conf %02x\n", sc->sc_dev.dv_xname,
247 sbdsp_mix_read(sc, SBP_SET_IRQ)));
248 #endif
249 }
250
251 return 1;
252 }
253
254
255 void
256 sbattach(sc)
257 struct sbdsp_softc *sc;
258 {
259 struct audio_attach_args arg;
260 #if NMIDI > 0
261 struct midi_hw_if *mhw = &sb_midi_hw_if;
262 #endif
263
264 sc->sc_ih = isa_intr_establish(sc->sc_ic, sc->sc_irq, IST_EDGE,
265 IPL_AUDIO, sbdsp_intr, sc, sc->sc_dev.dv_xname);
266
267 sbdsp_attach(sc);
268
269 #if NMIDI > 0
270 sc->sc_hasmpu = 0;
271 if (ISSB16CLASS(sc) && sc->sc_mpu_sc.iobase != 0) {
272 sc->sc_mpu_sc.iot = sc->sc_iot;
273 if (mpu_find(&sc->sc_mpu_sc)) {
274 sc->sc_hasmpu = 1;
275 mhw = &sb_mpu401_hw_if;
276 }
277 }
278 midi_attach_mi(mhw, sc, &sc->sc_dev);
279 #endif
280
281 audio_attach_mi(&sb_hw_if, sc, &sc->sc_dev);
282
283 arg.type = AUDIODEV_TYPE_OPL;
284 arg.hwif = 0;
285 arg.hdl = 0;
286 (void)config_found(&sc->sc_dev, &arg, audioprint);
287 }
288
289
290
291
292
293 int
294 sb_getdev(addr, retp)
295 void *addr;
296 struct audio_device *retp;
297 {
298 struct sbdsp_softc *sc = addr;
299 static char *names[] = SB_NAMES;
300 char *config;
301
302 if (sc->sc_model == SB_JAZZ)
303 strlcpy(retp->name, "MV Jazz16", sizeof retp->name);
304 else
305 strlcpy(retp->name, "SoundBlaster", sizeof retp->name);
306 snprintf(retp->version, sizeof retp->version, "%d.%02d",
307 SBVER_MAJOR(sc->sc_version),
308 SBVER_MINOR(sc->sc_version));
309 if (0 <= sc->sc_model && sc->sc_model < sizeof names / sizeof names[0])
310 config = names[sc->sc_model];
311 else
312 config = "??";
313 strlcpy(retp->config, config, sizeof retp->config);
314
315 return 0;
316 }
317
318 #if NMIDI > 0
319
320 #define SBMPU(a) (&((struct sbdsp_softc *)addr)->sc_mpu_sc)
321
322 int
323 sb_mpu401_open(addr, flags, iintr, ointr, arg)
324 void *addr;
325 int flags;
326 void (*iintr)(void *, int);
327 void (*ointr)(void *);
328 void *arg;
329 {
330 return mpu_open(SBMPU(addr), flags, iintr, ointr, arg);
331 }
332
333 int
334 sb_mpu401_output(addr, d)
335 void *addr;
336 int d;
337 {
338 return mpu_output(SBMPU(addr), d);
339 }
340
341 void
342 sb_mpu401_close(addr)
343 void *addr;
344 {
345 mpu_close(SBMPU(addr));
346 }
347
348 void
349 sb_mpu401_getinfo(addr, mi)
350 void *addr;
351 struct midi_info *mi;
352 {
353 mi->name = "SB MPU-401 UART";
354 mi->props = 0;
355 }
356 #endif