This source file includes following definitions.
- sb_printsc
- sbdsp_probe
- sbdsp_jazz16_probe
- sbdsp_attach
- sbdsp_mix_write
- sbdsp_mix_read
- sbdsp_query_encoding
- sbdsp_set_params
- sbdsp_set_ifilter
- sbdsp_get_ifilter
- sbdsp_set_in_ports
- sbdsp_speaker_ctl
- sbdsp_round_blocksize
- sbdsp_open
- sbdsp_close
- sbdsp_reset
- sbdsp_wdsp
- sbdsp_rdsp
- sbdsp_to
- sbdsp_pause
- sbdsp_spkron
- sbdsp_spkroff
- sbversion
- sbdsp_haltdma
- sbdsp_set_timeconst
- sbdsp16_set_rate
- sbdsp_trigger_input
- sbdsp_block_input
- sbdsp_trigger_output
- sbdsp_block_output
- sbdsp_intr
- sbdsp_adjust
- sbdsp_set_mixer_gain
- sbdsp_mixer_set_port
- sbdsp_mixer_get_port
- sbdsp_mixer_query_devinfo
- sb_malloc
- sb_free
- sb_round
- sb_mappage
- sbdsp_get_props
- sbdsp_midi_open
- sbdsp_midi_close
- sbdsp_midi_output
- sbdsp_midi_getinfo
- sbdsp_midi_intr
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
39
40
41
42
43
44
45
46
47 #include "midi.h"
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/errno.h>
52 #include <sys/ioctl.h>
53 #include <sys/syslog.h>
54 #include <sys/device.h>
55 #include <sys/proc.h>
56 #include <sys/buf.h>
57
58 #include <machine/cpu.h>
59 #include <machine/intr.h>
60 #include <machine/bus.h>
61
62 #include <sys/audioio.h>
63 #include <dev/audio_if.h>
64 #include <dev/midi_if.h>
65 #include <dev/mulaw.h>
66 #include <dev/auconv.h>
67
68 #include <dev/isa/isavar.h>
69 #include <dev/isa/isadmavar.h>
70
71 #include <dev/isa/sbreg.h>
72 #include <dev/isa/sbdspvar.h>
73
74
75 #ifdef AUDIO_DEBUG
76 #define DPRINTF(x) if (sbdspdebug) printf x
77 #define DPRINTFN(n,x) if (sbdspdebug >= (n)) printf x
78 int sbdspdebug = 0;
79 #else
80 #define DPRINTF(x)
81 #define DPRINTFN(n,x)
82 #endif
83
84 #ifndef SBDSP_NPOLL
85 #define SBDSP_NPOLL 3000
86 #endif
87
88 struct {
89 int wdsp;
90 int rdsp;
91 int wmidi;
92 } sberr;
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 #define SB_RATE_TO_TC(x) (256 - 1000000 / (x))
123 #define SB_TC_TO_RATE(tc) (1000000 / (256 - (tc)))
124
125 struct sbmode {
126 short model;
127 u_char channels;
128 u_char precision;
129 u_short lowrate, highrate;
130 u_char cmd;
131 u_char cmdchan;
132 };
133 static struct sbmode sbpmodes[] = {
134 { SB_1, 1, 8, 4000, 22727, SB_DSP_WDMA },
135 { SB_20, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP },
136 { SB_2x, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP },
137 { SB_2x, 1, 8, 22727, 45454, SB_DSP_HS_OUTPUT },
138 { SB_PRO, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP },
139 { SB_PRO, 1, 8, 22727, 45454, SB_DSP_HS_OUTPUT },
140 { SB_PRO, 2, 8, 11025, 22727, SB_DSP_HS_OUTPUT },
141
142 { SB_JAZZ, 1, 8, 4000, 22727, SB_DSP_WDMA_LOOP, SB_DSP_RECORD_MONO },
143 { SB_JAZZ, 1, 8, 22727, 45454, SB_DSP_HS_OUTPUT, SB_DSP_RECORD_MONO },
144 { SB_JAZZ, 2, 8, 11025, 22727, SB_DSP_HS_OUTPUT, SB_DSP_RECORD_STEREO },
145 { SB_JAZZ, 1, 16, 4000, 22727, SB_DSP_WDMA_LOOP, JAZZ16_RECORD_MONO },
146 { SB_JAZZ, 1, 16, 22727, 45454, SB_DSP_HS_OUTPUT, JAZZ16_RECORD_MONO },
147 { SB_JAZZ, 2, 16, 11025, 22727, SB_DSP_HS_OUTPUT, JAZZ16_RECORD_STEREO },
148 { SB_16, 1, 8, 5000, 45000, SB_DSP16_WDMA_8 },
149 { SB_16, 2, 8, 5000, 45000, SB_DSP16_WDMA_8 },
150 #define PLAY16 15
151 { SB_16, 1, 16, 5000, 45000, SB_DSP16_WDMA_16 },
152 { SB_16, 2, 16, 5000, 45000, SB_DSP16_WDMA_16 },
153 { -1 }
154 };
155 static struct sbmode sbrmodes[] = {
156 { SB_1, 1, 8, 4000, 12987, SB_DSP_RDMA },
157 { SB_20, 1, 8, 4000, 12987, SB_DSP_RDMA_LOOP },
158 { SB_2x, 1, 8, 4000, 12987, SB_DSP_RDMA_LOOP },
159 { SB_2x, 1, 8, 12987, 14925, SB_DSP_HS_INPUT },
160 { SB_PRO, 1, 8, 4000, 22727, SB_DSP_RDMA_LOOP, SB_DSP_RECORD_MONO },
161 { SB_PRO, 1, 8, 22727, 45454, SB_DSP_HS_INPUT, SB_DSP_RECORD_MONO },
162 { SB_PRO, 2, 8, 11025, 22727, SB_DSP_HS_INPUT, SB_DSP_RECORD_STEREO },
163 { SB_JAZZ, 1, 8, 4000, 22727, SB_DSP_RDMA_LOOP, SB_DSP_RECORD_MONO },
164 { SB_JAZZ, 1, 8, 22727, 45454, SB_DSP_HS_INPUT, SB_DSP_RECORD_MONO },
165 { SB_JAZZ, 2, 8, 11025, 22727, SB_DSP_HS_INPUT, SB_DSP_RECORD_STEREO },
166 { SB_JAZZ, 1, 16, 4000, 22727, SB_DSP_RDMA_LOOP, JAZZ16_RECORD_MONO },
167 { SB_JAZZ, 1, 16, 22727, 45454, SB_DSP_HS_INPUT, JAZZ16_RECORD_MONO },
168 { SB_JAZZ, 2, 16, 11025, 22727, SB_DSP_HS_INPUT, JAZZ16_RECORD_STEREO },
169 { SB_16, 1, 8, 5000, 45000, SB_DSP16_RDMA_8 },
170 { SB_16, 2, 8, 5000, 45000, SB_DSP16_RDMA_8 },
171 { SB_16, 1, 16, 5000, 45000, SB_DSP16_RDMA_16 },
172 { SB_16, 2, 16, 5000, 45000, SB_DSP16_RDMA_16 },
173 { -1 }
174 };
175
176 void sbversion(struct sbdsp_softc *);
177 void sbdsp_jazz16_probe(struct sbdsp_softc *);
178 void sbdsp_set_mixer_gain(struct sbdsp_softc *sc, int port);
179 void sbdsp_to(void *);
180 void sbdsp_pause(struct sbdsp_softc *);
181 int sbdsp_set_timeconst(struct sbdsp_softc *, int);
182 int sbdsp16_set_rate(struct sbdsp_softc *, int, int);
183 int sbdsp_set_in_ports(struct sbdsp_softc *, int);
184 void sbdsp_set_ifilter(void *, int);
185 int sbdsp_get_ifilter(void *);
186
187 int sbdsp_block_output(void *);
188 int sbdsp_block_input(void *);
189 static int sbdsp_adjust(int, int);
190
191 int sbdsp_midi_intr(void *);
192
193 #ifdef AUDIO_DEBUG
194 void sb_printsc(struct sbdsp_softc *);
195
196 void
197 sb_printsc(sc)
198 struct sbdsp_softc *sc;
199 {
200 int i;
201
202 printf("open %d dmachan %d/%d %d/%d iobase 0x%x irq %d\n",
203 (int)sc->sc_open, sc->sc_i.run, sc->sc_o.run,
204 sc->sc_drq8, sc->sc_drq16,
205 sc->sc_iobase, sc->sc_irq);
206 printf("irate %d itc %x orate %d otc %x\n",
207 sc->sc_i.rate, sc->sc_i.tc,
208 sc->sc_o.rate, sc->sc_o.tc);
209 printf("spkron %u nintr %lu\n",
210 sc->spkr_state, sc->sc_interrupts);
211 printf("intr8 %p arg8 %p\n",
212 sc->sc_intr8, sc->sc_arg16);
213 printf("intr16 %p arg16 %p\n",
214 sc->sc_intr8, sc->sc_arg16);
215 printf("gain:");
216 for (i = 0; i < SB_NDEVS; i++)
217 printf(" %u,%u", sc->gain[i][SB_LEFT], sc->gain[i][SB_RIGHT]);
218 printf("\n");
219 }
220 #endif
221
222
223
224
225
226
227
228
229 int
230 sbdsp_probe(sc)
231 struct sbdsp_softc *sc;
232 {
233
234 if (sbdsp_reset(sc) < 0) {
235 DPRINTF(("sbdsp: couldn't reset card\n"));
236 return 0;
237 }
238
239 if (sc->sc_dev.dv_cfdata->cf_flags & 1)
240 sbdsp_jazz16_probe(sc);
241 else
242 sbversion(sc);
243 if (sc->sc_model == SB_UNK) {
244
245 DPRINTF(("sbdsp: unknown SB model found\n"));
246 return 0;
247 }
248 return 1;
249 }
250
251
252
253
254 void
255 sbdsp_jazz16_probe(sc)
256 struct sbdsp_softc *sc;
257 {
258 static u_char jazz16_irq_conf[16] = {
259 -1, -1, 0x02, 0x03,
260 -1, 0x01, -1, 0x04,
261 -1, 0x02, 0x05, -1,
262 -1, -1, -1, 0x06};
263 static u_char jazz16_drq_conf[8] = {
264 -1, 0x01, -1, 0x02,
265 -1, 0x03, -1, 0x04};
266
267 bus_space_tag_t iot = sc->sc_iot;
268 bus_space_handle_t ioh;
269
270 sbversion(sc);
271
272 DPRINTF(("jazz16 probe\n"));
273
274 if (bus_space_map(iot, JAZZ16_CONFIG_PORT, 1, 0, &ioh)) {
275 DPRINTF(("bus map failed\n"));
276 return;
277 }
278
279 if (jazz16_drq_conf[sc->sc_drq8] == (u_char)-1 ||
280 jazz16_irq_conf[sc->sc_irq] == (u_char)-1) {
281 DPRINTF(("drq/irq check failed\n"));
282 goto done;
283 }
284
285 bus_space_write_1(iot, ioh, 0, JAZZ16_WAKEUP);
286 delay(10000);
287 bus_space_write_1(iot, ioh, 0, JAZZ16_SETBASE);
288 bus_space_write_1(iot, ioh, 0, sc->sc_iobase & 0x70);
289
290 if (sbdsp_reset(sc) < 0) {
291 DPRINTF(("sbdsp_reset check failed\n"));
292 goto done;
293 }
294
295 if (sbdsp_wdsp(sc, JAZZ16_READ_VER)) {
296 DPRINTF(("read16 setup failed\n"));
297 goto done;
298 }
299
300 if (sbdsp_rdsp(sc) != JAZZ16_VER_JAZZ) {
301 DPRINTF(("read16 failed\n"));
302 goto done;
303 }
304
305
306 sc->sc_drq16 = sc->sc_drq8;
307 if (sbdsp_wdsp(sc, JAZZ16_SET_DMAINTR) ||
308 sbdsp_wdsp(sc, (jazz16_drq_conf[sc->sc_drq16] << 4) |
309 jazz16_drq_conf[sc->sc_drq8]) ||
310 sbdsp_wdsp(sc, jazz16_irq_conf[sc->sc_irq])) {
311 DPRINTF(("sbdsp: can't write jazz16 probe stuff\n"));
312 } else {
313 DPRINTF(("jazz16 detected!\n"));
314 sc->sc_model = SB_JAZZ;
315 sc->sc_mixer_model = SBM_CT1345;
316 }
317
318 done:
319 bus_space_unmap(iot, ioh, 1);
320 }
321
322
323
324
325
326 void
327 sbdsp_attach(sc)
328 struct sbdsp_softc *sc;
329 {
330 struct audio_params pparams, rparams;
331 int i;
332 u_int v;
333
334
335
336
337 if (sc->sc_drq8 != -1) {
338 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq8,
339 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
340 printf("%s: can't create map for drq %d\n",
341 sc->sc_dev.dv_xname, sc->sc_drq8);
342 return;
343 }
344 }
345 if (sc->sc_drq16 != -1 && sc->sc_drq16 != sc->sc_drq8) {
346 if (isa_dmamap_create(sc->sc_isa, sc->sc_drq16,
347 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
348 printf("%s: can't create map for drq %d\n",
349 sc->sc_dev.dv_xname, sc->sc_drq16);
350 return;
351 }
352 }
353
354 pparams = audio_default;
355 rparams = audio_default;
356 sbdsp_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
357
358 sbdsp_set_in_ports(sc, 1 << SB_MIC_VOL);
359
360 if (sc->sc_mixer_model != SBM_NONE) {
361
362 sbdsp_mix_write(sc, SBP_MIX_RESET, SBP_MIX_RESET);
363
364 for (i = 0; i < SB_NDEVS; i++) {
365 switch(i) {
366 case SB_MIC_VOL:
367 case SB_LINE_IN_VOL:
368 v = 0;
369 break;
370 case SB_BASS:
371 case SB_TREBLE:
372 v = SB_ADJUST_GAIN(sc, AUDIO_MAX_GAIN/2);
373 break;
374 case SB_CD_IN_MUTE:
375 case SB_MIC_IN_MUTE:
376 case SB_LINE_IN_MUTE:
377 case SB_MIDI_IN_MUTE:
378 case SB_CD_SWAP:
379 case SB_MIC_SWAP:
380 case SB_LINE_SWAP:
381 case SB_MIDI_SWAP:
382 case SB_CD_OUT_MUTE:
383 case SB_MIC_OUT_MUTE:
384 case SB_LINE_OUT_MUTE:
385 v = 0;
386 break;
387 default:
388 v = SB_ADJUST_GAIN(sc, AUDIO_MAX_GAIN / 2);
389 break;
390 }
391 sc->gain[i][SB_LEFT] = sc->gain[i][SB_RIGHT] = v;
392 sbdsp_set_mixer_gain(sc, i);
393 }
394 sc->in_filter = 0;
395 }
396
397 printf(": dsp v%d.%02d%s\n",
398 SBVER_MAJOR(sc->sc_version), SBVER_MINOR(sc->sc_version),
399 sc->sc_model == SB_JAZZ ? ": <Jazz16>" : "");
400
401 timeout_set(&sc->sc_tmo, sbdsp_to, sbdsp_to);
402 sc->sc_fullduplex = ISSB16CLASS(sc) &&
403 sc->sc_drq8 != -1 && sc->sc_drq16 != -1 &&
404 sc->sc_drq8 != sc->sc_drq16;
405 }
406
407 void
408 sbdsp_mix_write(sc, mixerport, val)
409 struct sbdsp_softc *sc;
410 int mixerport;
411 int val;
412 {
413 bus_space_tag_t iot = sc->sc_iot;
414 bus_space_handle_t ioh = sc->sc_ioh;
415 int s;
416
417 s = splaudio();
418 bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport);
419 delay(20);
420 bus_space_write_1(iot, ioh, SBP_MIXER_DATA, val);
421 delay(30);
422 splx(s);
423 }
424
425 int
426 sbdsp_mix_read(sc, mixerport)
427 struct sbdsp_softc *sc;
428 int mixerport;
429 {
430 bus_space_tag_t iot = sc->sc_iot;
431 bus_space_handle_t ioh = sc->sc_ioh;
432 int val;
433 int s;
434
435 s = splaudio();
436 bus_space_write_1(iot, ioh, SBP_MIXER_ADDR, mixerport);
437 delay(20);
438 val = bus_space_read_1(iot, ioh, SBP_MIXER_DATA);
439 delay(30);
440 splx(s);
441 return val;
442 }
443
444
445
446
447
448 int
449 sbdsp_query_encoding(addr, fp)
450 void *addr;
451 struct audio_encoding *fp;
452 {
453 struct sbdsp_softc *sc = addr;
454 int emul;
455
456 emul = ISSB16CLASS(sc) ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
457
458 switch (fp->index) {
459 case 0:
460 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
461 fp->encoding = AUDIO_ENCODING_ULINEAR;
462 fp->precision = 8;
463 fp->flags = 0;
464 return 0;
465 case 1:
466 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
467 fp->encoding = AUDIO_ENCODING_ULAW;
468 fp->precision = 8;
469 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
470 return 0;
471 case 2:
472 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
473 fp->encoding = AUDIO_ENCODING_ALAW;
474 fp->precision = 8;
475 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
476 return 0;
477 case 3:
478 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
479 fp->encoding = AUDIO_ENCODING_SLINEAR;
480 fp->precision = 8;
481 fp->flags = emul;
482 return 0;
483 }
484 if (!ISSB16CLASS(sc) && sc->sc_model != SB_JAZZ)
485 return EINVAL;
486
487 switch(fp->index) {
488 case 4:
489 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
490 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
491 fp->precision = 16;
492 fp->flags = 0;
493 return 0;
494 case 5:
495 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
496 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
497 fp->precision = 16;
498 fp->flags = emul;
499 return 0;
500 case 6:
501 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
502 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
503 fp->precision = 16;
504 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
505 return 0;
506 case 7:
507 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
508 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
509 fp->precision = 16;
510 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
511 return 0;
512 default:
513 return EINVAL;
514 }
515 return 0;
516 }
517
518 int
519 sbdsp_set_params(addr, setmode, usemode, play, rec)
520 void *addr;
521 int setmode, usemode;
522 struct audio_params *play, *rec;
523 {
524 struct sbdsp_softc *sc = addr;
525 struct sbmode *m;
526 u_int rate, tc, bmode;
527 void (*swcode)(void *, u_char *buf, int cnt);
528 int factor;
529 int model;
530 int chan;
531 struct audio_params *p;
532 int mode;
533
534 if (sc->sc_open == SB_OPEN_MIDI)
535 return EBUSY;
536
537 model = sc->sc_model;
538 if (model > SB_16)
539 model = SB_16;
540
541
542
543
544
545 if (!ISSB16CLASS(sc) &&
546 play->sample_rate != rec->sample_rate &&
547 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
548 if (setmode == AUMODE_PLAY) {
549 rec->sample_rate = play->sample_rate;
550 setmode |= AUMODE_RECORD;
551 } else if (setmode == AUMODE_RECORD) {
552 play->sample_rate = rec->sample_rate;
553 setmode |= AUMODE_PLAY;
554 } else
555 return (EINVAL);
556 }
557
558
559 for (mode = AUMODE_RECORD; mode != -1;
560 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
561 if ((setmode & mode) == 0)
562 continue;
563
564 p = mode == AUMODE_PLAY ? play : rec;
565
566 for(m = mode == AUMODE_PLAY ? sbpmodes : sbrmodes;
567 m->model != -1; m++) {
568 if (model == m->model &&
569 p->channels == m->channels &&
570 p->precision == m->precision &&
571 p->sample_rate >= m->lowrate &&
572 p->sample_rate <= m->highrate)
573 break;
574 }
575 if (m->model == -1)
576 return EINVAL;
577 rate = p->sample_rate;
578 swcode = 0;
579 factor = 1;
580 tc = 1;
581 bmode = -1;
582 if (model == SB_16) {
583 switch (p->encoding) {
584 case AUDIO_ENCODING_SLINEAR_BE:
585 if (p->precision == 16)
586 swcode = swap_bytes;
587
588 case AUDIO_ENCODING_SLINEAR_LE:
589 bmode = SB_BMODE_SIGNED;
590 break;
591 case AUDIO_ENCODING_ULINEAR_BE:
592 if (p->precision == 16)
593 swcode = swap_bytes;
594
595 case AUDIO_ENCODING_ULINEAR_LE:
596 bmode = SB_BMODE_UNSIGNED;
597 break;
598 case AUDIO_ENCODING_ULAW:
599 if (mode == AUMODE_PLAY) {
600 swcode = mulaw_to_ulinear16;
601 factor = 2;
602 m = &sbpmodes[PLAY16];
603 } else
604 swcode = ulinear8_to_mulaw;
605 bmode = SB_BMODE_UNSIGNED;
606 break;
607 case AUDIO_ENCODING_ALAW:
608 if (mode == AUMODE_PLAY) {
609 swcode = alaw_to_ulinear16;
610 factor = 2;
611 m = &sbpmodes[PLAY16];
612 } else
613 swcode = ulinear8_to_alaw;
614 bmode = SB_BMODE_UNSIGNED;
615 break;
616 default:
617 return EINVAL;
618 }
619 if (p->channels == 2)
620 bmode |= SB_BMODE_STEREO;
621 } else if (m->model == SB_JAZZ && m->precision == 16) {
622 switch (p->encoding) {
623 case AUDIO_ENCODING_SLINEAR_LE:
624 break;
625 case AUDIO_ENCODING_ULINEAR_LE:
626 swcode = change_sign16;
627 break;
628 case AUDIO_ENCODING_SLINEAR_BE:
629 swcode = swap_bytes;
630 break;
631 case AUDIO_ENCODING_ULINEAR_BE:
632 swcode = mode == AUMODE_PLAY ?
633 swap_bytes_change_sign16 : change_sign16_swap_bytes;
634 break;
635 case AUDIO_ENCODING_ULAW:
636 swcode = mode == AUMODE_PLAY ?
637 mulaw_to_ulinear8 : ulinear8_to_mulaw;
638 break;
639 case AUDIO_ENCODING_ALAW:
640 swcode = mode == AUMODE_PLAY ?
641 alaw_to_ulinear8 : ulinear8_to_alaw;
642 break;
643 default:
644 return EINVAL;
645 }
646 tc = SB_RATE_TO_TC(p->sample_rate * p->channels);
647 p->sample_rate = SB_TC_TO_RATE(tc) / p->channels;
648 } else {
649 switch (p->encoding) {
650 case AUDIO_ENCODING_SLINEAR_BE:
651 case AUDIO_ENCODING_SLINEAR_LE:
652 swcode = change_sign8;
653 break;
654 case AUDIO_ENCODING_ULINEAR_BE:
655 case AUDIO_ENCODING_ULINEAR_LE:
656 break;
657 case AUDIO_ENCODING_ULAW:
658 swcode = mode == AUMODE_PLAY ?
659 mulaw_to_ulinear8 : ulinear8_to_mulaw;
660 break;
661 case AUDIO_ENCODING_ALAW:
662 swcode = mode == AUMODE_PLAY ?
663 alaw_to_ulinear8 : ulinear8_to_alaw;
664 break;
665 default:
666 return EINVAL;
667 }
668 tc = SB_RATE_TO_TC(p->sample_rate * p->channels);
669 p->sample_rate = SB_TC_TO_RATE(tc) / p->channels;
670 }
671
672 chan = m->precision == 16 ? sc->sc_drq16 : sc->sc_drq8;
673 if (mode == AUMODE_PLAY) {
674 sc->sc_o.rate = rate;
675 sc->sc_o.tc = tc;
676 sc->sc_o.modep = m;
677 sc->sc_o.bmode = bmode;
678 sc->sc_o.dmachan = chan;
679 } else {
680 sc->sc_i.rate = rate;
681 sc->sc_i.tc = tc;
682 sc->sc_i.modep = m;
683 sc->sc_i.bmode = bmode;
684 sc->sc_i.dmachan = chan;
685 }
686
687 p->sw_code = swcode;
688 p->factor = factor;
689 DPRINTF(("sbdsp_set_params: model=%d, mode=%d, rate=%ld, prec=%d, chan=%d, enc=%d -> tc=%02x, cmd=%02x, bmode=%02x, cmdchan=%02x, swcode=%p, factor=%d\n",
690 sc->sc_model, mode, p->sample_rate, p->precision, p->channels,
691 p->encoding, tc, m->cmd, bmode, m->cmdchan, swcode, factor));
692
693 }
694
695
696
697
698
699 sc->sc_i.run = SB_NOTRUNNING;
700 sc->sc_o.run = SB_NOTRUNNING;
701
702 if (sc->sc_fullduplex &&
703 usemode == (AUMODE_PLAY | AUMODE_RECORD) &&
704 sc->sc_i.dmachan == sc->sc_o.dmachan) {
705 DPRINTF(("sbdsp_set_params: fd=%d, usemode=%d, idma=%d, odma=%d\n", sc->sc_fullduplex, usemode, sc->sc_i.dmachan, sc->sc_o.dmachan));
706 if (sc->sc_o.dmachan == sc->sc_drq8) {
707
708 play->sw_code = linear8_to_linear16;
709 play->factor = 2;
710 sc->sc_o.modep = &sbpmodes[PLAY16];
711 sc->sc_o.dmachan = sc->sc_drq16;
712 } else {
713 return EINVAL;
714 }
715 }
716 DPRINTF(("sbdsp_set_params ichan=%d, ochan=%d\n",
717 sc->sc_i.dmachan, sc->sc_o.dmachan));
718
719 return 0;
720 }
721
722 void
723 sbdsp_set_ifilter(addr, which)
724 void *addr;
725 int which;
726 {
727 struct sbdsp_softc *sc = addr;
728 int mixval;
729
730 mixval = sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_IFILTER_MASK;
731 switch (which) {
732 case 0:
733 mixval |= SBP_FILTER_OFF;
734 break;
735 case SB_TREBLE:
736 mixval |= SBP_FILTER_ON | SBP_IFILTER_HIGH;
737 break;
738 case SB_BASS:
739 mixval |= SBP_FILTER_ON | SBP_IFILTER_LOW;
740 break;
741 default:
742 return;
743 }
744 sc->in_filter = mixval & SBP_IFILTER_MASK;
745 sbdsp_mix_write(sc, SBP_INFILTER, mixval);
746 }
747
748 int
749 sbdsp_get_ifilter(addr)
750 void *addr;
751 {
752 struct sbdsp_softc *sc = addr;
753
754 sc->in_filter =
755 sbdsp_mix_read(sc, SBP_INFILTER) & SBP_IFILTER_MASK;
756 switch (sc->in_filter) {
757 case SBP_FILTER_ON|SBP_IFILTER_HIGH:
758 return SB_TREBLE;
759 case SBP_FILTER_ON|SBP_IFILTER_LOW:
760 return SB_BASS;
761 default:
762 return 0;
763 }
764 }
765
766 int
767 sbdsp_set_in_ports(sc, mask)
768 struct sbdsp_softc *sc;
769 int mask;
770 {
771 int bitsl, bitsr;
772 int sbport;
773
774 if (sc->sc_open == SB_OPEN_MIDI)
775 return EBUSY;
776
777 DPRINTF(("sbdsp_set_in_ports: model=%d, mask=%x\n",
778 sc->sc_mixer_model, mask));
779
780 switch(sc->sc_mixer_model) {
781 case SBM_NONE:
782 return EINVAL;
783 case SBM_CT1335:
784 if (mask != (1 << SB_MIC_VOL))
785 return EINVAL;
786 break;
787 case SBM_CT1345:
788 switch (mask) {
789 case 1 << SB_MIC_VOL:
790 sbport = SBP_FROM_MIC;
791 break;
792 case 1 << SB_LINE_IN_VOL:
793 sbport = SBP_FROM_LINE;
794 break;
795 case 1 << SB_CD_VOL:
796 sbport = SBP_FROM_CD;
797 break;
798 default:
799 return (EINVAL);
800 }
801 sbdsp_mix_write(sc, SBP_RECORD_SOURCE, sbport | sc->in_filter);
802 break;
803 case SBM_CT1XX5:
804 case SBM_CT1745:
805 if (mask & ~((1<<SB_MIDI_VOL) | (1<<SB_LINE_IN_VOL) |
806 (1<<SB_CD_VOL) | (1<<SB_MIC_VOL)))
807 return EINVAL;
808 bitsr = 0;
809 if (mask & (1<<SB_MIDI_VOL)) bitsr |= SBP_MIDI_SRC_R;
810 if (mask & (1<<SB_LINE_IN_VOL)) bitsr |= SBP_LINE_SRC_R;
811 if (mask & (1<<SB_CD_VOL)) bitsr |= SBP_CD_SRC_R;
812 bitsl = SB_SRC_R_TO_L(bitsr);
813 if (mask & (1<<SB_MIC_VOL)) {
814 bitsl |= SBP_MIC_SRC;
815 bitsr |= SBP_MIC_SRC;
816 }
817 sbdsp_mix_write(sc, SBP_RECORD_SOURCE_L, bitsl);
818 sbdsp_mix_write(sc, SBP_RECORD_SOURCE_R, bitsr);
819 break;
820 }
821 sc->in_mask = mask;
822
823 return 0;
824 }
825
826 int
827 sbdsp_speaker_ctl(addr, newstate)
828 void *addr;
829 int newstate;
830 {
831 struct sbdsp_softc *sc = addr;
832
833 if (sc->sc_open == SB_OPEN_MIDI)
834 return EBUSY;
835
836 if ((newstate == SPKR_ON) &&
837 (sc->spkr_state == SPKR_OFF)) {
838 sbdsp_spkron(sc);
839 sc->spkr_state = SPKR_ON;
840 }
841 if ((newstate == SPKR_OFF) &&
842 (sc->spkr_state == SPKR_ON)) {
843 sbdsp_spkroff(sc);
844 sc->spkr_state = SPKR_OFF;
845 }
846 return 0;
847 }
848
849 int
850 sbdsp_round_blocksize(addr, blk)
851 void *addr;
852 int blk;
853 {
854 return (blk + 3) & -4;
855 }
856
857 int
858 sbdsp_open(addr, flags)
859 void *addr;
860 int flags;
861 {
862 struct sbdsp_softc *sc = addr;
863
864 DPRINTF(("sbdsp_open: sc=%p\n", sc));
865
866 if (sc->sc_open != SB_CLOSED)
867 return EBUSY;
868 if (sbdsp_reset(sc) != 0)
869 return EIO;
870
871 sc->sc_open = SB_OPEN_AUDIO;
872 sc->sc_openflags = flags;
873 sc->sc_intrm = 0;
874 if (ISSBPRO(sc) &&
875 sbdsp_wdsp(sc, SB_DSP_RECORD_MONO) < 0) {
876 DPRINTF(("sbdsp_open: can't set mono mode\n"));
877
878 }
879
880
881
882
883
884
885
886 DPRINTF(("sbdsp_open: opened\n"));
887
888 return 0;
889 }
890
891 void
892 sbdsp_close(addr)
893 void *addr;
894 {
895 struct sbdsp_softc *sc = addr;
896
897 DPRINTF(("sbdsp_close: sc=%p\n", sc));
898
899 sc->sc_open = SB_CLOSED;
900 sbdsp_spkroff(sc);
901 sc->spkr_state = SPKR_OFF;
902 sc->sc_intr8 = 0;
903 sc->sc_intr16 = 0;
904 sc->sc_intrm = 0;
905 sbdsp_haltdma(sc);
906
907 DPRINTF(("sbdsp_close: closed\n"));
908 }
909
910
911
912
913
914
915
916
917
918 int
919 sbdsp_reset(sc)
920 struct sbdsp_softc *sc;
921 {
922 bus_space_tag_t iot = sc->sc_iot;
923 bus_space_handle_t ioh = sc->sc_ioh;
924
925 sc->sc_intr8 = 0;
926 sc->sc_intr16 = 0;
927 if (sc->sc_i.run != SB_NOTRUNNING) {
928 isa_dmaabort(sc->sc_isa, sc->sc_i.dmachan);
929 sc->sc_i.run = SB_NOTRUNNING;
930 }
931 if (sc->sc_o.run != SB_NOTRUNNING) {
932 isa_dmaabort(sc->sc_isa, sc->sc_o.dmachan);
933 sc->sc_o.run = SB_NOTRUNNING;
934 }
935
936
937
938
939
940
941 bus_space_write_1(iot, ioh, SBP_DSP_RESET, 1);
942 delay(10);
943 bus_space_write_1(iot, ioh, SBP_DSP_RESET, 0);
944 delay(30);
945 if (sbdsp_rdsp(sc) != SB_MAGIC)
946 return -1;
947
948 return 0;
949 }
950
951
952
953
954
955
956 int
957 sbdsp_wdsp(sc, v)
958 struct sbdsp_softc *sc;
959 int v;
960 {
961 bus_space_tag_t iot = sc->sc_iot;
962 bus_space_handle_t ioh = sc->sc_ioh;
963 int i;
964 u_char x;
965
966 for (i = SBDSP_NPOLL; --i >= 0; ) {
967 x = bus_space_read_1(iot, ioh, SBP_DSP_WSTAT);
968 delay(10);
969 if ((x & SB_DSP_BUSY) == 0) {
970 bus_space_write_1(iot, ioh, SBP_DSP_WRITE, v);
971 delay(10);
972 return 0;
973 }
974 }
975 ++sberr.wdsp;
976 return -1;
977 }
978
979
980
981
982 int
983 sbdsp_rdsp(sc)
984 struct sbdsp_softc *sc;
985 {
986 bus_space_tag_t iot = sc->sc_iot;
987 bus_space_handle_t ioh = sc->sc_ioh;
988 int i;
989 u_char x;
990
991 for (i = SBDSP_NPOLL; --i >= 0; ) {
992 x = bus_space_read_1(iot, ioh, SBP_DSP_RSTAT);
993 delay(10);
994 if (x & SB_DSP_READY) {
995 x = bus_space_read_1(iot, ioh, SBP_DSP_READ);
996 delay(10);
997 return x;
998 }
999 }
1000 ++sberr.rdsp;
1001 return -1;
1002 }
1003
1004
1005
1006
1007
1008 void
1009 sbdsp_to(arg)
1010 void *arg;
1011 {
1012 wakeup(arg);
1013 }
1014
1015 void
1016 sbdsp_pause(sc)
1017 struct sbdsp_softc *sc;
1018 {
1019 extern int hz;
1020
1021 timeout_add(&sc->sc_tmo, hz/8);
1022 (void)tsleep(sbdsp_to, PWAIT, "sbpause", 0);
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 void
1036 sbdsp_spkron(sc)
1037 struct sbdsp_softc *sc;
1038 {
1039 (void)sbdsp_wdsp(sc, SB_DSP_SPKR_ON);
1040 sbdsp_pause(sc);
1041 }
1042
1043
1044
1045
1046 void
1047 sbdsp_spkroff(sc)
1048 struct sbdsp_softc *sc;
1049 {
1050 (void)sbdsp_wdsp(sc, SB_DSP_SPKR_OFF);
1051 sbdsp_pause(sc);
1052 }
1053
1054
1055
1056
1057
1058 void
1059 sbversion(sc)
1060 struct sbdsp_softc *sc;
1061 {
1062 int v;
1063
1064 sc->sc_model = SB_UNK;
1065 sc->sc_version = 0;
1066 if (sbdsp_wdsp(sc, SB_DSP_VERSION) < 0)
1067 return;
1068 v = sbdsp_rdsp(sc) << 8;
1069 v |= sbdsp_rdsp(sc);
1070 if (v < 0)
1071 return;
1072 sc->sc_version = v;
1073 switch(SBVER_MAJOR(v)) {
1074 case 1:
1075 sc->sc_mixer_model = SBM_NONE;
1076 sc->sc_model = SB_1;
1077 break;
1078 case 2:
1079
1080 sbdsp_mix_write(sc, SBP_1335_MASTER_VOL, 0x04);
1081 sbdsp_mix_write(sc, SBP_1335_MIDI_VOL, 0x06);
1082
1083 if ((sbdsp_mix_read(sc, SBP_1335_MASTER_VOL) & 0x0e) == 0x04 &&
1084 (sbdsp_mix_read(sc, SBP_1335_MIDI_VOL) & 0x0e) == 0x06)
1085 sc->sc_mixer_model = SBM_CT1335;
1086 else
1087 sc->sc_mixer_model = SBM_NONE;
1088 if (SBVER_MINOR(v) == 0)
1089 sc->sc_model = SB_20;
1090 else
1091 sc->sc_model = SB_2x;
1092 break;
1093 case 3:
1094 sc->sc_mixer_model = SBM_CT1345;
1095 sc->sc_model = SB_PRO;
1096 break;
1097 case 4:
1098 #if 0
1099
1100
1101 sbdsp_mix_write(sc, SB16P_TREBLE_L, 0x80);
1102
1103 if ((sbdsp_mix_read(sc, SB16P_TREBLE_L) & 0xf0) == 0x80)
1104 sc->sc_mixer_model = SBM_CT1745;
1105 else
1106 sc->sc_mixer_model = SBM_CT1XX5;
1107 #else
1108 sc->sc_mixer_model = SBM_CT1745;
1109 #endif
1110 #if 0
1111
1112
1113 if (SBVER_MINOR(v) == 16)
1114 sc->sc_model = SB_64;
1115 else
1116 #endif
1117 sc->sc_model = SB_16;
1118 break;
1119 }
1120 }
1121
1122
1123
1124
1125 int
1126 sbdsp_haltdma(addr)
1127 void *addr;
1128 {
1129 struct sbdsp_softc *sc = addr;
1130
1131 DPRINTF(("sbdsp_haltdma: sc=%p\n", sc));
1132
1133 sbdsp_reset(sc);
1134 return 0;
1135 }
1136
1137 int
1138 sbdsp_set_timeconst(sc, tc)
1139 struct sbdsp_softc *sc;
1140 int tc;
1141 {
1142 DPRINTF(("sbdsp_set_timeconst: sc=%p tc=%d\n", sc, tc));
1143
1144 if (sbdsp_wdsp(sc, SB_DSP_TIMECONST) < 0 ||
1145 sbdsp_wdsp(sc, tc) < 0)
1146 return EIO;
1147
1148 return 0;
1149 }
1150
1151 int
1152 sbdsp16_set_rate(sc, cmd, rate)
1153 struct sbdsp_softc *sc;
1154 int cmd, rate;
1155 {
1156 DPRINTF(("sbdsp16_set_rate: sc=%p cmd=0x%02x rate=%d\n", sc, cmd, rate));
1157
1158 if (sbdsp_wdsp(sc, cmd) < 0 ||
1159 sbdsp_wdsp(sc, rate >> 8) < 0 ||
1160 sbdsp_wdsp(sc, rate) < 0)
1161 return EIO;
1162 return 0;
1163 }
1164
1165 int
1166 sbdsp_trigger_input(addr, start, end, blksize, intr, arg, param)
1167 void *addr;
1168 void *start, *end;
1169 int blksize;
1170 void (*intr)(void *);
1171 void *arg;
1172 struct audio_params *param;
1173 {
1174 struct sbdsp_softc *sc = addr;
1175 int stereo = param->channels == 2;
1176 int width = param->precision * param->factor;
1177 int filter;
1178
1179 #ifdef DIAGNOSTIC
1180 if (stereo && (blksize & 1)) {
1181 DPRINTF(("stereo record odd bytes (%d)\n", blksize));
1182 return (EIO);
1183 }
1184 #endif
1185
1186 sc->sc_intrr = intr;
1187 sc->sc_argr = arg;
1188
1189 if (width == 8) {
1190 #ifdef DIAGNOSTIC
1191 if (sc->sc_i.dmachan != sc->sc_drq8) {
1192 printf("sbdsp_trigger_input: width=%d bad chan %d\n",
1193 width, sc->sc_i.dmachan);
1194 return (EIO);
1195 }
1196 #endif
1197 sc->sc_intr8 = sbdsp_block_input;
1198 sc->sc_arg8 = addr;
1199 } else {
1200 #ifdef DIAGNOSTIC
1201 if (sc->sc_i.dmachan != sc->sc_drq16) {
1202 printf("sbdsp_trigger_input: width=%d bad chan %d\n",
1203 width, sc->sc_i.dmachan);
1204 return (EIO);
1205 }
1206 #endif
1207 sc->sc_intr16 = sbdsp_block_input;
1208 sc->sc_arg16 = addr;
1209 }
1210
1211 if ((sc->sc_model == SB_JAZZ) ? (sc->sc_i.dmachan > 3) : (width == 16))
1212 blksize >>= 1;
1213 --blksize;
1214 sc->sc_i.blksize = blksize;
1215
1216 if (ISSBPRO(sc)) {
1217 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmdchan) < 0)
1218 return (EIO);
1219 filter = stereo ? SBP_FILTER_OFF : sc->in_filter;
1220 sbdsp_mix_write(sc, SBP_INFILTER,
1221 (sbdsp_mix_read(sc, SBP_INFILTER) & ~SBP_IFILTER_MASK) |
1222 filter);
1223 }
1224
1225 if (ISSB16CLASS(sc)) {
1226 if (sbdsp16_set_rate(sc, SB_DSP16_INPUTRATE, sc->sc_i.rate)) {
1227 DPRINTF(("sbdsp_trigger_input: rate=%d set failed\n",
1228 sc->sc_i.rate));
1229 return (EIO);
1230 }
1231 } else {
1232 if (sbdsp_set_timeconst(sc, sc->sc_i.tc)) {
1233 DPRINTF(("sbdsp_trigger_input: tc=%d set failed\n",
1234 sc->sc_i.rate));
1235 return (EIO);
1236 }
1237 }
1238
1239 DPRINTF(("sbdsp: dma start loop input start=%p end=%p chan=%d\n",
1240 start, end, sc->sc_i.dmachan));
1241 isa_dmastart(sc->sc_isa, sc->sc_i.dmachan, start, (char *)end -
1242 (char *)start, NULL, DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1243
1244 return sbdsp_block_input(addr);
1245 }
1246
1247 int
1248 sbdsp_block_input(addr)
1249 void *addr;
1250 {
1251 struct sbdsp_softc *sc = addr;
1252 int cc = sc->sc_i.blksize;
1253
1254 DPRINTFN(2, ("sbdsp_block_input: sc=%p cc=%d\n", addr, cc));
1255
1256 if (sc->sc_i.run != SB_NOTRUNNING)
1257 sc->sc_intrr(sc->sc_argr);
1258
1259 if (sc->sc_model == SB_1) {
1260
1261 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmd) < 0 ||
1262 sbdsp_wdsp(sc, cc) < 0 ||
1263 sbdsp_wdsp(sc, cc >> 8) < 0) {
1264 DPRINTF(("sbdsp_block_input: SB1 DMA start failed\n"));
1265 return (EIO);
1266 }
1267 sc->sc_i.run = SB_RUNNING;
1268 } else if (sc->sc_i.run == SB_NOTRUNNING) {
1269
1270 if (ISSB16CLASS(sc)) {
1271 DPRINTFN(3, ("sbdsp16 input command cmd=0x%02x bmode=0x%02x cc=%d\n",
1272 sc->sc_i.modep->cmd, sc->sc_i.bmode, cc));
1273 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmd) < 0 ||
1274 sbdsp_wdsp(sc, sc->sc_i.bmode) < 0 ||
1275 sbdsp_wdsp(sc, cc) < 0 ||
1276 sbdsp_wdsp(sc, cc >> 8) < 0) {
1277 DPRINTF(("sbdsp_block_input: SB16 DMA start failed\n"));
1278 return (EIO);
1279 }
1280 } else {
1281 DPRINTF(("sbdsp_block_input: set blocksize=%d\n", cc));
1282 if (sbdsp_wdsp(sc, SB_DSP_BLOCKSIZE) < 0 ||
1283 sbdsp_wdsp(sc, cc) < 0 ||
1284 sbdsp_wdsp(sc, cc >> 8) < 0) {
1285 DPRINTF(("sbdsp_block_input: SB2 DMA blocksize failed\n"));
1286 return (EIO);
1287 }
1288 if (sbdsp_wdsp(sc, sc->sc_i.modep->cmd) < 0) {
1289 DPRINTF(("sbdsp_block_input: SB2 DMA start failed\n"));
1290 return (EIO);
1291 }
1292 }
1293 sc->sc_i.run = SB_LOOPING;
1294 }
1295
1296 return (0);
1297 }
1298
1299 int
1300 sbdsp_trigger_output(addr, start, end, blksize, intr, arg, param)
1301 void *addr;
1302 void *start, *end;
1303 int blksize;
1304 void (*intr)(void *);
1305 void *arg;
1306 struct audio_params *param;
1307 {
1308 struct sbdsp_softc *sc = addr;
1309 int stereo = param->channels == 2;
1310 int width = param->precision * param->factor;
1311 int cmd;
1312
1313 #ifdef DIAGNOSTIC
1314 if (stereo && (blksize & 1)) {
1315 DPRINTF(("stereo playback odd bytes (%d)\n", blksize));
1316 return (EIO);
1317 }
1318 #endif
1319
1320 sc->sc_intrp = intr;
1321 sc->sc_argp = arg;
1322
1323 if (width == 8) {
1324 #ifdef DIAGNOSTIC
1325 if (sc->sc_o.dmachan != sc->sc_drq8) {
1326 printf("sbdsp_trigger_output: width=%d bad chan %d\n",
1327 width, sc->sc_o.dmachan);
1328 return (EIO);
1329 }
1330 #endif
1331 sc->sc_intr8 = sbdsp_block_output;
1332 sc->sc_arg8 = addr;
1333 } else {
1334 #ifdef DIAGNOSTIC
1335 if (sc->sc_o.dmachan != sc->sc_drq16) {
1336 printf("sbdsp_trigger_output: width=%d bad chan %d\n",
1337 width, sc->sc_o.dmachan);
1338 return (EIO);
1339 }
1340 #endif
1341 sc->sc_intr16 = sbdsp_block_output;
1342 sc->sc_arg16 = addr;
1343 }
1344
1345 if ((sc->sc_model == SB_JAZZ) ? (sc->sc_o.dmachan > 3) : (width == 16))
1346 blksize >>= 1;
1347 --blksize;
1348 sc->sc_o.blksize = blksize;
1349
1350 if (ISSBPRO(sc)) {
1351
1352 sbdsp_mix_write(sc, SBP_STEREO,
1353 (sbdsp_mix_read(sc, SBP_STEREO) & ~SBP_PLAYMODE_MASK) |
1354 (stereo ? SBP_PLAYMODE_STEREO : SBP_PLAYMODE_MONO));
1355 cmd = sc->sc_o.modep->cmdchan;
1356 if (cmd && sbdsp_wdsp(sc, cmd) < 0)
1357 return (EIO);
1358 }
1359
1360 if (ISSB16CLASS(sc)) {
1361 if (sbdsp16_set_rate(sc, SB_DSP16_OUTPUTRATE, sc->sc_o.rate)) {
1362 DPRINTF(("sbdsp_trigger_output: rate=%d set failed\n",
1363 sc->sc_o.rate));
1364 return (EIO);
1365 }
1366 } else {
1367 if (sbdsp_set_timeconst(sc, sc->sc_o.tc)) {
1368 DPRINTF(("sbdsp_trigger_output: tc=%d set failed\n",
1369 sc->sc_o.rate));
1370 return (EIO);
1371 }
1372 }
1373
1374 DPRINTF(("sbdsp: dma start loop output start=%p end=%p chan=%d\n",
1375 start, end, sc->sc_o.dmachan));
1376 isa_dmastart(sc->sc_isa, sc->sc_o.dmachan, start, (char *)end -
1377 (char *)start, NULL, DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1378
1379 return sbdsp_block_output(addr);
1380 }
1381
1382 int
1383 sbdsp_block_output(addr)
1384 void *addr;
1385 {
1386 struct sbdsp_softc *sc = addr;
1387 int cc = sc->sc_o.blksize;
1388
1389 DPRINTFN(2, ("sbdsp_block_output: sc=%p cc=%d\n", addr, cc));
1390
1391 if (sc->sc_o.run != SB_NOTRUNNING)
1392 sc->sc_intrp(sc->sc_argp);
1393
1394 if (sc->sc_model == SB_1) {
1395
1396 if (sbdsp_wdsp(sc, sc->sc_o.modep->cmd) < 0 ||
1397 sbdsp_wdsp(sc, cc) < 0 ||
1398 sbdsp_wdsp(sc, cc >> 8) < 0) {
1399 DPRINTF(("sbdsp_block_output: SB1 DMA start failed\n"));
1400 return (EIO);
1401 }
1402 sc->sc_o.run = SB_RUNNING;
1403 } else if (sc->sc_o.run == SB_NOTRUNNING) {
1404
1405 if (ISSB16CLASS(sc)) {
1406 DPRINTF(("sbdsp_block_output: SB16 cmd=0x%02x bmode=0x%02x cc=%d\n",
1407 sc->sc_o.modep->cmd,sc->sc_o.bmode, cc));
1408 if (sbdsp_wdsp(sc, sc->sc_o.modep->cmd) < 0 ||
1409 sbdsp_wdsp(sc, sc->sc_o.bmode) < 0 ||
1410 sbdsp_wdsp(sc, cc) < 0 ||
1411 sbdsp_wdsp(sc, cc >> 8) < 0) {
1412 DPRINTF(("sbdsp_block_output: SB16 DMA start failed\n"));
1413 return (EIO);
1414 }
1415 } else {
1416 DPRINTF(("sbdsp_block_output: set blocksize=%d\n", cc));
1417 if (sbdsp_wdsp(sc, SB_DSP_BLOCKSIZE) < 0 ||
1418 sbdsp_wdsp(sc, cc) < 0 ||
1419 sbdsp_wdsp(sc, cc >> 8) < 0) {
1420 DPRINTF(("sbdsp_block_output: SB2 DMA blocksize failed\n"));
1421 return (EIO);
1422 }
1423 if (sbdsp_wdsp(sc, sc->sc_o.modep->cmd) < 0) {
1424 DPRINTF(("sbdsp_block_output: SB2 DMA start failed\n"));
1425 return (EIO);
1426 }
1427 }
1428 sc->sc_o.run = SB_LOOPING;
1429 }
1430
1431 return (0);
1432 }
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444 int
1445 sbdsp_intr(arg)
1446 void *arg;
1447 {
1448 struct sbdsp_softc *sc = arg;
1449 u_char irq;
1450
1451 DPRINTFN(2, ("sbdsp_intr: intr8=%p, intr16=%p\n",
1452 sc->sc_intr8, sc->sc_intr16));
1453 if (ISSB16CLASS(sc)) {
1454 irq = sbdsp_mix_read(sc, SBP_IRQ_STATUS);
1455 if ((irq & (SBP_IRQ_DMA8 | SBP_IRQ_DMA16 | SBP_IRQ_MPU401)) == 0) {
1456 DPRINTF(("sbdsp_intr: Spurious interrupt 0x%x\n", irq));
1457 return 0;
1458 }
1459 } else {
1460
1461 irq = SBP_IRQ_DMA8;
1462 }
1463
1464 sc->sc_interrupts++;
1465 delay(10);
1466
1467
1468 if (irq & SBP_IRQ_DMA8) {
1469 bus_space_read_1(sc->sc_iot, sc->sc_ioh, SBP_DSP_IRQACK8);
1470 if (sc->sc_intr8)
1471 sc->sc_intr8(sc->sc_arg8);
1472 }
1473 if (irq & SBP_IRQ_DMA16) {
1474 bus_space_read_1(sc->sc_iot, sc->sc_ioh, SBP_DSP_IRQACK16);
1475 if (sc->sc_intr16)
1476 sc->sc_intr16(sc->sc_arg16);
1477 }
1478 #if NMIDI > 0
1479 if ((irq & SBP_IRQ_MPU401) && sc->sc_hasmpu) {
1480 mpu_intr(&sc->sc_mpu_sc);
1481 }
1482 #endif
1483 return 1;
1484 }
1485
1486
1487 #define MAXVAL 256
1488 static int
1489 sbdsp_adjust(val, mask)
1490 int val, mask;
1491 {
1492 val += (MAXVAL - mask) >> 1;
1493 if (val >= MAXVAL)
1494 val = MAXVAL-1;
1495 return val & mask;
1496 }
1497
1498 void
1499 sbdsp_set_mixer_gain(sc, port)
1500 struct sbdsp_softc *sc;
1501 int port;
1502 {
1503 int src, gain;
1504
1505 switch(sc->sc_mixer_model) {
1506 case SBM_NONE:
1507 return;
1508 case SBM_CT1335:
1509 gain = SB_1335_GAIN(sc->gain[port][SB_LEFT]);
1510 switch(port) {
1511 case SB_MASTER_VOL:
1512 src = SBP_1335_MASTER_VOL;
1513 break;
1514 case SB_MIDI_VOL:
1515 src = SBP_1335_MIDI_VOL;
1516 break;
1517 case SB_CD_VOL:
1518 src = SBP_1335_CD_VOL;
1519 break;
1520 case SB_VOICE_VOL:
1521 src = SBP_1335_VOICE_VOL;
1522 gain = SB_1335_MASTER_GAIN(sc->gain[port][SB_LEFT]);
1523 break;
1524 default:
1525 return;
1526 }
1527 sbdsp_mix_write(sc, src, gain);
1528 break;
1529 case SBM_CT1345:
1530 gain = SB_STEREO_GAIN(sc->gain[port][SB_LEFT],
1531 sc->gain[port][SB_RIGHT]);
1532 switch (port) {
1533 case SB_MIC_VOL:
1534 src = SBP_MIC_VOL;
1535 gain = SB_MIC_GAIN(sc->gain[port][SB_LEFT]);
1536 break;
1537 case SB_MASTER_VOL:
1538 src = SBP_MASTER_VOL;
1539 break;
1540 case SB_LINE_IN_VOL:
1541 src = SBP_LINE_VOL;
1542 break;
1543 case SB_VOICE_VOL:
1544 src = SBP_VOICE_VOL;
1545 break;
1546 case SB_MIDI_VOL:
1547 src = SBP_MIDI_VOL;
1548 break;
1549 case SB_CD_VOL:
1550 src = SBP_CD_VOL;
1551 break;
1552 default:
1553 return;
1554 }
1555 sbdsp_mix_write(sc, src, gain);
1556 break;
1557 case SBM_CT1XX5:
1558 case SBM_CT1745:
1559 switch (port) {
1560 case SB_MIC_VOL:
1561 src = SB16P_MIC_L;
1562 break;
1563 case SB_MASTER_VOL:
1564 src = SB16P_MASTER_L;
1565 break;
1566 case SB_LINE_IN_VOL:
1567 src = SB16P_LINE_L;
1568 break;
1569 case SB_VOICE_VOL:
1570 src = SB16P_VOICE_L;
1571 break;
1572 case SB_MIDI_VOL:
1573 src = SB16P_MIDI_L;
1574 break;
1575 case SB_CD_VOL:
1576 src = SB16P_CD_L;
1577 break;
1578 case SB_INPUT_GAIN:
1579 src = SB16P_INPUT_GAIN_L;
1580 break;
1581 case SB_OUTPUT_GAIN:
1582 src = SB16P_OUTPUT_GAIN_L;
1583 break;
1584 case SB_TREBLE:
1585 src = SB16P_TREBLE_L;
1586 break;
1587 case SB_BASS:
1588 src = SB16P_BASS_L;
1589 break;
1590 case SB_PCSPEAKER:
1591 sbdsp_mix_write(sc, SB16P_PCSPEAKER, sc->gain[port][SB_LEFT]);
1592 return;
1593 default:
1594 return;
1595 }
1596 sbdsp_mix_write(sc, src, sc->gain[port][SB_LEFT]);
1597 sbdsp_mix_write(sc, SB16P_L_TO_R(src), sc->gain[port][SB_RIGHT]);
1598 break;
1599 }
1600 }
1601
1602 int
1603 sbdsp_mixer_set_port(addr, cp)
1604 void *addr;
1605 mixer_ctrl_t *cp;
1606 {
1607 struct sbdsp_softc *sc = addr;
1608 int lgain, rgain;
1609 int mask, bits;
1610 int lmask, rmask, lbits, rbits;
1611 int mute, swap;
1612
1613 if (sc->sc_open == SB_OPEN_MIDI)
1614 return EBUSY;
1615
1616 DPRINTF(("sbdsp_mixer_set_port: port=%d num_channels=%d\n", cp->dev,
1617 cp->un.value.num_channels));
1618
1619 if (sc->sc_mixer_model == SBM_NONE)
1620 return EINVAL;
1621
1622 switch (cp->dev) {
1623 case SB_TREBLE:
1624 case SB_BASS:
1625 if (sc->sc_mixer_model == SBM_CT1345 ||
1626 sc->sc_mixer_model == SBM_CT1XX5) {
1627 if (cp->type != AUDIO_MIXER_ENUM)
1628 return EINVAL;
1629 switch (cp->dev) {
1630 case SB_TREBLE:
1631 sbdsp_set_ifilter(addr, cp->un.ord ? SB_TREBLE : 0);
1632 return 0;
1633 case SB_BASS:
1634 sbdsp_set_ifilter(addr, cp->un.ord ? SB_BASS : 0);
1635 return 0;
1636 }
1637 }
1638 case SB_PCSPEAKER:
1639 case SB_INPUT_GAIN:
1640 case SB_OUTPUT_GAIN:
1641 if (!ISSBM1745(sc))
1642 return EINVAL;
1643 case SB_MIC_VOL:
1644 case SB_LINE_IN_VOL:
1645 if (sc->sc_mixer_model == SBM_CT1335)
1646 return EINVAL;
1647 case SB_VOICE_VOL:
1648 case SB_MIDI_VOL:
1649 case SB_CD_VOL:
1650 case SB_MASTER_VOL:
1651 if (cp->type != AUDIO_MIXER_VALUE)
1652 return EINVAL;
1653
1654
1655
1656
1657
1658
1659
1660 switch (cp->dev) {
1661 case SB_MIC_VOL:
1662 if (cp->un.value.num_channels != 1)
1663 return EINVAL;
1664
1665 lgain = rgain = SB_ADJUST_MIC_GAIN(sc,
1666 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1667 break;
1668 case SB_PCSPEAKER:
1669 if (cp->un.value.num_channels != 1)
1670 return EINVAL;
1671
1672 case SB_INPUT_GAIN:
1673 case SB_OUTPUT_GAIN:
1674 lgain = rgain = SB_ADJUST_2_GAIN(sc,
1675 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1676 break;
1677 default:
1678 switch (cp->un.value.num_channels) {
1679 case 1:
1680 lgain = rgain = SB_ADJUST_GAIN(sc,
1681 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1682 break;
1683 case 2:
1684 if (sc->sc_mixer_model == SBM_CT1335)
1685 return EINVAL;
1686 lgain = SB_ADJUST_GAIN(sc,
1687 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1688 rgain = SB_ADJUST_GAIN(sc,
1689 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1690 break;
1691 default:
1692 return EINVAL;
1693 }
1694 break;
1695 }
1696 sc->gain[cp->dev][SB_LEFT] = lgain;
1697 sc->gain[cp->dev][SB_RIGHT] = rgain;
1698
1699 sbdsp_set_mixer_gain(sc, cp->dev);
1700 break;
1701
1702 case SB_RECORD_SOURCE:
1703 if (ISSBM1745(sc)) {
1704 if (cp->type != AUDIO_MIXER_SET)
1705 return EINVAL;
1706 return sbdsp_set_in_ports(sc, cp->un.mask);
1707 } else {
1708 if (cp->type != AUDIO_MIXER_ENUM)
1709 return EINVAL;
1710 sc->in_port = cp->un.ord;
1711 return sbdsp_set_in_ports(sc, 1 << cp->un.ord);
1712 }
1713 break;
1714
1715 case SB_AGC:
1716 if (!ISSBM1745(sc) || cp->type != AUDIO_MIXER_ENUM)
1717 return EINVAL;
1718 sbdsp_mix_write(sc, SB16P_AGC, cp->un.ord & 1);
1719 break;
1720
1721 case SB_CD_OUT_MUTE:
1722 mask = SB16P_SW_CD;
1723 goto omute;
1724 case SB_MIC_OUT_MUTE:
1725 mask = SB16P_SW_MIC;
1726 goto omute;
1727 case SB_LINE_OUT_MUTE:
1728 mask = SB16P_SW_LINE;
1729 omute:
1730 if (cp->type != AUDIO_MIXER_ENUM)
1731 return EINVAL;
1732 bits = sbdsp_mix_read(sc, SB16P_OSWITCH);
1733 sc->gain[cp->dev][SB_LR] = cp->un.ord != 0;
1734 if (cp->un.ord)
1735 bits = bits & ~mask;
1736 else
1737 bits = bits | mask;
1738 sbdsp_mix_write(sc, SB16P_OSWITCH, bits);
1739 break;
1740
1741 case SB_MIC_IN_MUTE:
1742 case SB_MIC_SWAP:
1743 lmask = rmask = SB16P_SW_MIC;
1744 goto imute;
1745 case SB_CD_IN_MUTE:
1746 case SB_CD_SWAP:
1747 lmask = SB16P_SW_CD_L;
1748 rmask = SB16P_SW_CD_R;
1749 goto imute;
1750 case SB_LINE_IN_MUTE:
1751 case SB_LINE_SWAP:
1752 lmask = SB16P_SW_LINE_L;
1753 rmask = SB16P_SW_LINE_R;
1754 goto imute;
1755 case SB_MIDI_IN_MUTE:
1756 case SB_MIDI_SWAP:
1757 lmask = SB16P_SW_MIDI_L;
1758 rmask = SB16P_SW_MIDI_R;
1759 imute:
1760 if (cp->type != AUDIO_MIXER_ENUM)
1761 return EINVAL;
1762 mask = lmask | rmask;
1763 lbits = sbdsp_mix_read(sc, SB16P_ISWITCH_L) & ~mask;
1764 rbits = sbdsp_mix_read(sc, SB16P_ISWITCH_R) & ~mask;
1765 sc->gain[cp->dev][SB_LR] = cp->un.ord != 0;
1766 if (SB_IS_IN_MUTE(cp->dev)) {
1767 mute = cp->dev;
1768 swap = mute - SB_CD_IN_MUTE + SB_CD_SWAP;
1769 } else {
1770 swap = cp->dev;
1771 mute = swap + SB_CD_IN_MUTE - SB_CD_SWAP;
1772 }
1773 if (sc->gain[swap][SB_LR]) {
1774 mask = lmask;
1775 lmask = rmask;
1776 rmask = mask;
1777 }
1778 if (!sc->gain[mute][SB_LR]) {
1779 lbits = lbits | lmask;
1780 rbits = rbits | rmask;
1781 }
1782 sbdsp_mix_write(sc, SB16P_ISWITCH_L, lbits);
1783 sbdsp_mix_write(sc, SB16P_ISWITCH_L, rbits);
1784 break;
1785
1786 default:
1787 return EINVAL;
1788 }
1789
1790 return 0;
1791 }
1792
1793 int
1794 sbdsp_mixer_get_port(addr, cp)
1795 void *addr;
1796 mixer_ctrl_t *cp;
1797 {
1798 struct sbdsp_softc *sc = addr;
1799
1800 if (sc->sc_open == SB_OPEN_MIDI)
1801 return EBUSY;
1802
1803 DPRINTF(("sbdsp_mixer_get_port: port=%d\n", cp->dev));
1804
1805 if (sc->sc_mixer_model == SBM_NONE)
1806 return EINVAL;
1807
1808 switch (cp->dev) {
1809 case SB_TREBLE:
1810 case SB_BASS:
1811 if (sc->sc_mixer_model == SBM_CT1345 ||
1812 sc->sc_mixer_model == SBM_CT1XX5) {
1813 switch (cp->dev) {
1814 case SB_TREBLE:
1815 cp->un.ord = sbdsp_get_ifilter(addr) == SB_TREBLE;
1816 return 0;
1817 case SB_BASS:
1818 cp->un.ord = sbdsp_get_ifilter(addr) == SB_BASS;
1819 return 0;
1820 }
1821 }
1822 case SB_PCSPEAKER:
1823 case SB_INPUT_GAIN:
1824 case SB_OUTPUT_GAIN:
1825 if (!ISSBM1745(sc))
1826 return EINVAL;
1827 case SB_MIC_VOL:
1828 case SB_LINE_IN_VOL:
1829 if (sc->sc_mixer_model == SBM_CT1335)
1830 return EINVAL;
1831 case SB_VOICE_VOL:
1832 case SB_MIDI_VOL:
1833 case SB_CD_VOL:
1834 case SB_MASTER_VOL:
1835 switch (cp->dev) {
1836 case SB_MIC_VOL:
1837 case SB_PCSPEAKER:
1838 if (cp->un.value.num_channels != 1)
1839 return EINVAL;
1840
1841 default:
1842 switch (cp->un.value.num_channels) {
1843 case 1:
1844 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1845 sc->gain[cp->dev][SB_LEFT];
1846 break;
1847 case 2:
1848 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1849 sc->gain[cp->dev][SB_LEFT];
1850 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1851 sc->gain[cp->dev][SB_RIGHT];
1852 break;
1853 default:
1854 return EINVAL;
1855 }
1856 break;
1857 }
1858 break;
1859
1860 case SB_RECORD_SOURCE:
1861 if (ISSBM1745(sc))
1862 cp->un.mask = sc->in_mask;
1863 else
1864 cp->un.ord = sc->in_port;
1865 break;
1866
1867 case SB_AGC:
1868 if (!ISSBM1745(sc))
1869 return EINVAL;
1870 cp->un.ord = sbdsp_mix_read(sc, SB16P_AGC);
1871 break;
1872
1873 case SB_CD_IN_MUTE:
1874 case SB_MIC_IN_MUTE:
1875 case SB_LINE_IN_MUTE:
1876 case SB_MIDI_IN_MUTE:
1877 case SB_CD_SWAP:
1878 case SB_MIC_SWAP:
1879 case SB_LINE_SWAP:
1880 case SB_MIDI_SWAP:
1881 case SB_CD_OUT_MUTE:
1882 case SB_MIC_OUT_MUTE:
1883 case SB_LINE_OUT_MUTE:
1884 cp->un.ord = sc->gain[cp->dev][SB_LR];
1885 break;
1886
1887 default:
1888 return EINVAL;
1889 }
1890
1891 return 0;
1892 }
1893
1894 int
1895 sbdsp_mixer_query_devinfo(addr, dip)
1896 void *addr;
1897 mixer_devinfo_t *dip;
1898 {
1899 struct sbdsp_softc *sc = addr;
1900 int chan, class, is1745;
1901
1902 DPRINTF(("sbdsp_mixer_query_devinfo: model=%d index=%d\n",
1903 sc->sc_mixer_model, dip->index));
1904
1905 if (sc->sc_mixer_model == SBM_NONE)
1906 return ENXIO;
1907
1908 chan = sc->sc_mixer_model == SBM_CT1335 ? 1 : 2;
1909 is1745 = ISSBM1745(sc);
1910 class = is1745 ? SB_INPUT_CLASS : SB_OUTPUT_CLASS;
1911
1912 switch (dip->index) {
1913 case SB_MASTER_VOL:
1914 dip->type = AUDIO_MIXER_VALUE;
1915 dip->mixer_class = SB_OUTPUT_CLASS;
1916 dip->prev = dip->next = AUDIO_MIXER_LAST;
1917 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
1918 dip->un.v.num_channels = chan;
1919 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
1920 return 0;
1921 case SB_MIDI_VOL:
1922 dip->type = AUDIO_MIXER_VALUE;
1923 dip->mixer_class = class;
1924 dip->prev = AUDIO_MIXER_LAST;
1925 dip->next = is1745 ? SB_MIDI_IN_MUTE : AUDIO_MIXER_LAST;
1926 strlcpy(dip->label.name, AudioNfmsynth, sizeof dip->label.name);
1927 dip->un.v.num_channels = chan;
1928 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
1929 return 0;
1930 case SB_CD_VOL:
1931 dip->type = AUDIO_MIXER_VALUE;
1932 dip->mixer_class = class;
1933 dip->prev = AUDIO_MIXER_LAST;
1934 dip->next = is1745 ? SB_CD_IN_MUTE : AUDIO_MIXER_LAST;
1935 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
1936 dip->un.v.num_channels = chan;
1937 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
1938 return 0;
1939 case SB_VOICE_VOL:
1940 dip->type = AUDIO_MIXER_VALUE;
1941 dip->mixer_class = class;
1942 dip->prev = AUDIO_MIXER_LAST;
1943 dip->next = AUDIO_MIXER_LAST;
1944 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
1945 dip->un.v.num_channels = chan;
1946 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
1947 return 0;
1948 case SB_OUTPUT_CLASS:
1949 dip->type = AUDIO_MIXER_CLASS;
1950 dip->mixer_class = SB_OUTPUT_CLASS;
1951 dip->next = dip->prev = AUDIO_MIXER_LAST;
1952 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
1953 return 0;
1954 }
1955
1956 if (sc->sc_mixer_model == SBM_CT1335)
1957 return ENXIO;
1958
1959 switch (dip->index) {
1960 case SB_MIC_VOL:
1961 dip->type = AUDIO_MIXER_VALUE;
1962 dip->mixer_class = class;
1963 dip->prev = AUDIO_MIXER_LAST;
1964 dip->next = is1745 ? SB_MIC_IN_MUTE : AUDIO_MIXER_LAST;
1965 strlcpy(dip->label.name, AudioNmicrophone,
1966 sizeof dip->label.name);
1967 dip->un.v.num_channels = 1;
1968 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
1969 return 0;
1970
1971 case SB_LINE_IN_VOL:
1972 dip->type = AUDIO_MIXER_VALUE;
1973 dip->mixer_class = class;
1974 dip->prev = AUDIO_MIXER_LAST;
1975 dip->next = is1745 ? SB_LINE_IN_MUTE : AUDIO_MIXER_LAST;
1976 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
1977 dip->un.v.num_channels = 2;
1978 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
1979 return 0;
1980
1981 case SB_RECORD_SOURCE:
1982 dip->mixer_class = SB_RECORD_CLASS;
1983 dip->prev = dip->next = AUDIO_MIXER_LAST;
1984 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
1985 if (ISSBM1745(sc)) {
1986 dip->type = AUDIO_MIXER_SET;
1987 dip->un.s.num_mem = 4;
1988 strlcpy(dip->un.s.member[0].label.name,
1989 AudioNmicrophone,
1990 sizeof dip->un.s.member[0].label.name);
1991 dip->un.s.member[0].mask = 1 << SB_MIC_VOL;
1992 strlcpy(dip->un.s.member[1].label.name,
1993 AudioNcd, sizeof dip->un.s.member[1].label.name);
1994 dip->un.s.member[1].mask = 1 << SB_CD_VOL;
1995 strlcpy(dip->un.s.member[2].label.name,
1996 AudioNline, sizeof dip->un.s.member[2].label.name);
1997 dip->un.s.member[2].mask = 1 << SB_LINE_IN_VOL;
1998 strlcpy(dip->un.s.member[3].label.name,
1999 AudioNfmsynth,
2000 sizeof dip->un.s.member[3].label.name);
2001 dip->un.s.member[3].mask = 1 << SB_MIDI_VOL;
2002 } else {
2003 dip->type = AUDIO_MIXER_ENUM;
2004 dip->un.e.num_mem = 3;
2005 strlcpy(dip->un.e.member[0].label.name,
2006 AudioNmicrophone,
2007 sizeof dip->un.e.member[0].label.name);
2008 dip->un.e.member[0].ord = SB_MIC_VOL;
2009 strlcpy(dip->un.e.member[1].label.name, AudioNcd,
2010 sizeof dip->un.e.member[1].label.name);
2011 dip->un.e.member[1].ord = SB_CD_VOL;
2012 strlcpy(dip->un.e.member[2].label.name, AudioNline,
2013 sizeof dip->un.e.member[2].label.name);
2014 dip->un.e.member[2].ord = SB_LINE_IN_VOL;
2015 }
2016 return 0;
2017
2018 case SB_BASS:
2019 dip->prev = dip->next = AUDIO_MIXER_LAST;
2020 strlcpy(dip->label.name, AudioNbass, sizeof dip->label.name);
2021 if (sc->sc_mixer_model == SBM_CT1745) {
2022 dip->type = AUDIO_MIXER_VALUE;
2023 dip->mixer_class = SB_EQUALIZATION_CLASS;
2024 dip->un.v.num_channels = 2;
2025 strlcpy(dip->un.v.units.name, AudioNbass, sizeof dip->un.v.units.name);
2026 } else {
2027 dip->type = AUDIO_MIXER_ENUM;
2028 dip->mixer_class = SB_INPUT_CLASS;
2029 dip->un.e.num_mem = 2;
2030 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2031 sizeof dip->un.e.member[0].label.name);
2032 dip->un.e.member[0].ord = 0;
2033 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2034 sizeof dip->un.e.member[1].label.name);
2035 dip->un.e.member[1].ord = 1;
2036 }
2037 return 0;
2038
2039 case SB_TREBLE:
2040 dip->prev = dip->next = AUDIO_MIXER_LAST;
2041 strlcpy(dip->label.name, AudioNtreble, sizeof dip->label.name);
2042 if (sc->sc_mixer_model == SBM_CT1745) {
2043 dip->type = AUDIO_MIXER_VALUE;
2044 dip->mixer_class = SB_EQUALIZATION_CLASS;
2045 dip->un.v.num_channels = 2;
2046 strlcpy(dip->un.v.units.name, AudioNtreble, sizeof dip->un.v.units.name);
2047 } else {
2048 dip->type = AUDIO_MIXER_ENUM;
2049 dip->mixer_class = SB_INPUT_CLASS;
2050 dip->un.e.num_mem = 2;
2051 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2052 sizeof dip->un.e.member[0].label.name);
2053 dip->un.e.member[0].ord = 0;
2054 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2055 sizeof dip->un.e.member[1].label.name);
2056 dip->un.e.member[1].ord = 1;
2057 }
2058 return 0;
2059
2060 case SB_RECORD_CLASS:
2061 dip->type = AUDIO_MIXER_CLASS;
2062 dip->mixer_class = SB_RECORD_CLASS;
2063 dip->next = dip->prev = AUDIO_MIXER_LAST;
2064 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
2065 return 0;
2066
2067 case SB_INPUT_CLASS:
2068 dip->type = AUDIO_MIXER_CLASS;
2069 dip->mixer_class = SB_INPUT_CLASS;
2070 dip->next = dip->prev = AUDIO_MIXER_LAST;
2071 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
2072 return 0;
2073
2074 }
2075
2076 if (sc->sc_mixer_model == SBM_CT1345)
2077 return ENXIO;
2078
2079 switch(dip->index) {
2080 case SB_PCSPEAKER:
2081 dip->type = AUDIO_MIXER_VALUE;
2082 dip->mixer_class = SB_INPUT_CLASS;
2083 dip->prev = dip->next = AUDIO_MIXER_LAST;
2084 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name);
2085 dip->un.v.num_channels = 1;
2086 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
2087 return 0;
2088
2089 case SB_INPUT_GAIN:
2090 dip->type = AUDIO_MIXER_VALUE;
2091 dip->mixer_class = SB_INPUT_CLASS;
2092 dip->prev = dip->next = AUDIO_MIXER_LAST;
2093 strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name);
2094 dip->un.v.num_channels = 2;
2095 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
2096 return 0;
2097
2098 case SB_OUTPUT_GAIN:
2099 dip->type = AUDIO_MIXER_VALUE;
2100 dip->mixer_class = SB_OUTPUT_CLASS;
2101 dip->prev = dip->next = AUDIO_MIXER_LAST;
2102 strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
2103 dip->un.v.num_channels = 2;
2104 strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
2105 return 0;
2106
2107 case SB_AGC:
2108 dip->type = AUDIO_MIXER_ENUM;
2109 dip->mixer_class = SB_INPUT_CLASS;
2110 dip->prev = dip->next = AUDIO_MIXER_LAST;
2111 strlcpy(dip->label.name, "agc", sizeof dip->label.name);
2112 dip->un.e.num_mem = 2;
2113 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2114 sizeof dip->un.e.member[0].label.name);
2115 dip->un.e.member[0].ord = 0;
2116 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2117 sizeof dip->un.e.member[1].label.name);
2118 dip->un.e.member[1].ord = 1;
2119 return 0;
2120
2121 case SB_EQUALIZATION_CLASS:
2122 dip->type = AUDIO_MIXER_CLASS;
2123 dip->mixer_class = SB_EQUALIZATION_CLASS;
2124 dip->next = dip->prev = AUDIO_MIXER_LAST;
2125 strlcpy(dip->label.name, AudioCequalization, sizeof dip->label.name);
2126 return 0;
2127
2128 case SB_CD_IN_MUTE:
2129 dip->prev = SB_CD_VOL;
2130 dip->next = SB_CD_SWAP;
2131 dip->mixer_class = SB_INPUT_CLASS;
2132 goto mute;
2133
2134 case SB_MIC_IN_MUTE:
2135 dip->prev = SB_MIC_VOL;
2136 dip->next = SB_MIC_SWAP;
2137 dip->mixer_class = SB_INPUT_CLASS;
2138 goto mute;
2139
2140 case SB_LINE_IN_MUTE:
2141 dip->prev = SB_LINE_IN_VOL;
2142 dip->next = SB_LINE_SWAP;
2143 dip->mixer_class = SB_INPUT_CLASS;
2144 goto mute;
2145
2146 case SB_MIDI_IN_MUTE:
2147 dip->prev = SB_MIDI_VOL;
2148 dip->next = SB_MIDI_SWAP;
2149 dip->mixer_class = SB_INPUT_CLASS;
2150 goto mute;
2151
2152 case SB_CD_SWAP:
2153 dip->prev = SB_CD_IN_MUTE;
2154 dip->next = SB_CD_OUT_MUTE;
2155 goto swap;
2156
2157 case SB_MIC_SWAP:
2158 dip->prev = SB_MIC_IN_MUTE;
2159 dip->next = SB_MIC_OUT_MUTE;
2160 goto swap;
2161
2162 case SB_LINE_SWAP:
2163 dip->prev = SB_LINE_IN_MUTE;
2164 dip->next = SB_LINE_OUT_MUTE;
2165 goto swap;
2166
2167 case SB_MIDI_SWAP:
2168 dip->prev = SB_MIDI_IN_MUTE;
2169 dip->next = AUDIO_MIXER_LAST;
2170 swap:
2171 dip->mixer_class = SB_INPUT_CLASS;
2172 strlcpy(dip->label.name, AudioNswap, sizeof dip->label.name);
2173 goto mute1;
2174
2175 case SB_CD_OUT_MUTE:
2176 dip->prev = SB_CD_SWAP;
2177 dip->next = AUDIO_MIXER_LAST;
2178 dip->mixer_class = SB_OUTPUT_CLASS;
2179 goto mute;
2180
2181 case SB_MIC_OUT_MUTE:
2182 dip->prev = SB_MIC_SWAP;
2183 dip->next = AUDIO_MIXER_LAST;
2184 dip->mixer_class = SB_OUTPUT_CLASS;
2185 goto mute;
2186
2187 case SB_LINE_OUT_MUTE:
2188 dip->prev = SB_LINE_SWAP;
2189 dip->next = AUDIO_MIXER_LAST;
2190 dip->mixer_class = SB_OUTPUT_CLASS;
2191 mute:
2192 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
2193 mute1:
2194 dip->type = AUDIO_MIXER_ENUM;
2195 dip->un.e.num_mem = 2;
2196 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2197 sizeof dip->un.e.member[0].label.name);
2198 dip->un.e.member[0].ord = 0;
2199 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2200 sizeof dip->un.e.member[1].label.name);
2201 dip->un.e.member[1].ord = 1;
2202 return 0;
2203
2204 }
2205
2206 return ENXIO;
2207 }
2208
2209 void *
2210 sb_malloc(addr, direction, size, pool, flags)
2211 void *addr;
2212 int direction;
2213 size_t size;
2214 int pool;
2215 int flags;
2216 {
2217 struct sbdsp_softc *sc = addr;
2218 int drq;
2219
2220
2221 if (sc->sc_drq8 != -1)
2222 drq = sc->sc_drq8;
2223 else
2224 drq = sc->sc_drq16;
2225
2226 return isa_malloc(sc->sc_isa, drq, size, pool, flags);
2227 }
2228
2229 void
2230 sb_free(addr, ptr, pool)
2231 void *addr;
2232 void *ptr;
2233 int pool;
2234 {
2235 isa_free(ptr, pool);
2236 }
2237
2238 size_t
2239 sb_round(addr, direction, size)
2240 void *addr;
2241 int direction;
2242 size_t size;
2243 {
2244 if (size > MAX_ISADMA)
2245 size = MAX_ISADMA;
2246 return size;
2247 }
2248
2249 paddr_t
2250 sb_mappage(addr, mem, off, prot)
2251 void *addr;
2252 void *mem;
2253 off_t off;
2254 int prot;
2255 {
2256 return isa_mappage(mem, off, prot);
2257 }
2258
2259 int
2260 sbdsp_get_props(addr)
2261 void *addr;
2262 {
2263 struct sbdsp_softc *sc = addr;
2264 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
2265 (sc->sc_fullduplex ? AUDIO_PROP_FULLDUPLEX : 0);
2266 }
2267
2268 #if NMIDI > 0
2269
2270
2271
2272
2273 int
2274 sbdsp_midi_open(addr, flags, iintr, ointr, arg)
2275 void *addr;
2276 int flags;
2277 void (*iintr)(void *, int);
2278 void (*ointr)(void *);
2279 void *arg;
2280 {
2281 struct sbdsp_softc *sc = addr;
2282
2283 DPRINTF(("sbdsp_midi_open: sc=%p\n", sc));
2284
2285 if (sc->sc_open != SB_CLOSED)
2286 return EBUSY;
2287 if (sbdsp_reset(sc) != 0)
2288 return EIO;
2289
2290 if (sc->sc_model >= SB_20)
2291 if (sbdsp_wdsp(sc, SB_MIDI_UART_INTR))
2292 return EIO;
2293 sc->sc_open = SB_OPEN_MIDI;
2294 sc->sc_openflags = flags;
2295 sc->sc_intr8 = sbdsp_midi_intr;
2296 sc->sc_arg8 = addr;
2297 sc->sc_intrm = iintr;
2298 sc->sc_argm = arg;
2299 return 0;
2300 }
2301
2302 void
2303 sbdsp_midi_close(addr)
2304 void *addr;
2305 {
2306 struct sbdsp_softc *sc = addr;
2307
2308 DPRINTF(("sbdsp_midi_close: sc=%p\n", sc));
2309
2310 if (sc->sc_model >= SB_20)
2311 sbdsp_reset(sc);
2312 sc->sc_open = SB_CLOSED;
2313 sc->sc_intrm = 0;
2314 }
2315
2316 int
2317 sbdsp_midi_output(addr, d)
2318 void *addr;
2319 int d;
2320 {
2321 struct sbdsp_softc *sc = addr;
2322
2323 if (sc->sc_model < SB_20 && sbdsp_wdsp(sc, SB_MIDI_WRITE))
2324 return EIO;
2325 if (sbdsp_wdsp(sc, d))
2326 return EIO;
2327 return 0;
2328 }
2329
2330 void
2331 sbdsp_midi_getinfo(addr, mi)
2332 void *addr;
2333 struct midi_info *mi;
2334 {
2335 struct sbdsp_softc *sc = addr;
2336
2337 mi->name = sc->sc_model < SB_20 ? "SB MIDI cmd" : "SB MIDI UART";
2338 mi->props = MIDI_PROP_CAN_INPUT;
2339 }
2340
2341 int
2342 sbdsp_midi_intr(addr)
2343 void *addr;
2344 {
2345 struct sbdsp_softc *sc = addr;
2346
2347 sc->sc_intrm(sc->sc_argm, sbdsp_rdsp(sc));
2348 return (0);
2349 }
2350
2351 #endif