This source file includes following definitions.
- ess_printsc
- ess_dump_mixer
- ess_config_addr
- ess_config_irq
- ess_config_drq
- ess_setup
- ess_identify
- ess_setup_sc
- essmatch
- essattach
- ess_open
- ess_1788_close
- ess_1888_close
- ess_drain
- ess_speaker_ctl
- ess_getdev
- ess_query_encoding
- ess_set_params
- ess_audio1_trigger_output
- ess_audio2_trigger_output
- ess_audio1_trigger_input
- ess_audio1_halt
- ess_audio2_halt
- ess_audio1_intr
- ess_audio2_intr
- ess_audio1_poll
- ess_audio2_poll
- ess_round_blocksize
- ess_set_port
- ess_get_port
- ess_query_devinfo
- ess_malloc
- ess_free
- ess_round_buffersize
- ess_mappage
- ess_1788_get_props
- ess_1888_get_props
- ess_reset
- ess_set_gain
- ess_set_in_port
- ess_set_in_ports
- ess_speaker_on
- ess_speaker_off
- ess_srtotc
- ess_srtofc
- ess_get_dsp_status
- ess_dsp_read_ready
- ess_dsp_write_ready
- ess_rdsp
- ess_wdsp
- ess_write_x_reg
- ess_read_x_reg
- ess_clear_xreg_bits
- ess_set_xreg_bits
- ess_write_mix_reg
- ess_read_mix_reg
- ess_clear_mreg_bits
- ess_set_mreg_bits
- ess_read_multi_mix_reg
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/errno.h>
72 #include <sys/ioctl.h>
73 #include <sys/syslog.h>
74 #include <sys/device.h>
75 #include <sys/proc.h>
76 #include <sys/kernel.h>
77 #include <sys/timeout.h>
78
79 #include <machine/cpu.h>
80 #include <machine/intr.h>
81 #include <machine/bus.h>
82
83 #include <sys/audioio.h>
84 #include <dev/audio_if.h>
85 #include <dev/auconv.h>
86 #include <dev/mulaw.h>
87
88 #include <dev/isa/isavar.h>
89 #include <dev/isa/isadmavar.h>
90
91 #include <dev/isa/essvar.h>
92 #include <dev/isa/essreg.h>
93
94 #ifdef AUDIO_DEBUG
95 #define DPRINTF(x) if (essdebug) printf x
96 #define DPRINTFN(n,x) if (essdebug>(n)) printf x
97 int essdebug = 0;
98 #else
99 #define DPRINTF(x)
100 #define DPRINTFN(n,x)
101 #endif
102
103 #if 0
104 unsigned uuu;
105 #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu)
106 #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d))
107 #else
108 #define EREAD1(t, h, a) bus_space_read_1(t, h, a)
109 #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d)
110 #endif
111
112 struct cfdriver ess_cd = {
113 NULL, "ess", DV_DULL
114 };
115
116 int ess_setup_sc(struct ess_softc *, int);
117
118 int ess_open(void *, int);
119 void ess_1788_close(void *);
120 void ess_1888_close(void *);
121 int ess_getdev(void *, struct audio_device *);
122 int ess_drain(void *);
123
124 int ess_query_encoding(void *, struct audio_encoding *);
125
126 int ess_set_params(void *, int, int, struct audio_params *,
127 struct audio_params *);
128
129 int ess_round_blocksize(void *, int);
130
131 int ess_audio1_trigger_output(void *, void *, void *, int,
132 void (*)(void *), void *, struct audio_params *);
133 int ess_audio2_trigger_output(void *, void *, void *, int,
134 void (*)(void *), void *, struct audio_params *);
135 int ess_audio1_trigger_input(void *, void *, void *, int,
136 void (*)(void *), void *, struct audio_params *);
137 int ess_audio1_halt(void *);
138 int ess_audio2_halt(void *);
139 int ess_audio1_intr(void *);
140 int ess_audio2_intr(void *);
141 void ess_audio1_poll(void *);
142 void ess_audio2_poll(void *);
143
144 int ess_speaker_ctl(void *, int);
145
146 int ess_getdev(void *, struct audio_device *);
147
148 int ess_set_port(void *, mixer_ctrl_t *);
149 int ess_get_port(void *, mixer_ctrl_t *);
150
151 void *ess_malloc(void *, int, size_t, int, int);
152 void ess_free(void *, void *, int);
153 size_t ess_round_buffersize(void *, int, size_t);
154 paddr_t ess_mappage(void *, void *, off_t, int);
155
156
157 int ess_query_devinfo(void *, mixer_devinfo_t *);
158 int ess_1788_get_props(void *);
159 int ess_1888_get_props(void *);
160
161 void ess_speaker_on(struct ess_softc *);
162 void ess_speaker_off(struct ess_softc *);
163
164 int ess_config_addr(struct ess_softc *);
165 void ess_config_irq(struct ess_softc *);
166 void ess_config_drq(struct ess_softc *);
167 void ess_setup(struct ess_softc *);
168 int ess_identify(struct ess_softc *);
169
170 int ess_reset(struct ess_softc *);
171 void ess_set_gain(struct ess_softc *, int, int);
172 int ess_set_in_port(struct ess_softc *, int);
173 int ess_set_in_ports(struct ess_softc *, int);
174 u_int ess_srtotc(u_int);
175 u_int ess_srtofc(u_int);
176 u_char ess_get_dsp_status(struct ess_softc *);
177 u_char ess_dsp_read_ready(struct ess_softc *);
178 u_char ess_dsp_write_ready(struct ess_softc *);
179 int ess_rdsp(struct ess_softc *);
180 int ess_wdsp(struct ess_softc *, u_char);
181 u_char ess_read_x_reg(struct ess_softc *, u_char);
182 int ess_write_x_reg(struct ess_softc *, u_char, u_char);
183 void ess_clear_xreg_bits(struct ess_softc *, u_char, u_char);
184 void ess_set_xreg_bits(struct ess_softc *, u_char, u_char);
185 u_char ess_read_mix_reg(struct ess_softc *, u_char);
186 void ess_write_mix_reg(struct ess_softc *, u_char, u_char);
187 void ess_clear_mreg_bits(struct ess_softc *, u_char, u_char);
188 void ess_set_mreg_bits(struct ess_softc *, u_char, u_char);
189 void ess_read_multi_mix_reg(struct ess_softc *, u_char, u_int8_t *, bus_size_t);
190
191 static char *essmodel[] = {
192 "unsupported",
193 "1888",
194 "1887",
195 "888",
196 "1788",
197 "1869",
198 "1879",
199 "1868",
200 "1878",
201 };
202
203 struct audio_device ess_device = {
204 "ESS Technology",
205 "x",
206 "ess"
207 };
208
209
210
211
212
213 struct audio_hw_if ess_1788_hw_if = {
214 ess_open,
215 ess_1788_close,
216 ess_drain,
217 ess_query_encoding,
218 ess_set_params,
219 ess_round_blocksize,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 ess_audio1_halt,
226 ess_audio1_halt,
227 ess_speaker_ctl,
228 ess_getdev,
229 NULL,
230 ess_set_port,
231 ess_get_port,
232 ess_query_devinfo,
233 ess_malloc,
234 ess_free,
235 ess_round_buffersize,
236 ess_mappage,
237 ess_1788_get_props,
238 ess_audio1_trigger_output,
239 ess_audio1_trigger_input,
240 };
241
242 struct audio_hw_if ess_1888_hw_if = {
243 ess_open,
244 ess_1888_close,
245 ess_drain,
246 ess_query_encoding,
247 ess_set_params,
248 ess_round_blocksize,
249 NULL,
250 NULL,
251 NULL,
252 NULL,
253 NULL,
254 ess_audio2_halt,
255 ess_audio1_halt,
256 ess_speaker_ctl,
257 ess_getdev,
258 NULL,
259 ess_set_port,
260 ess_get_port,
261 ess_query_devinfo,
262 ess_malloc,
263 ess_free,
264 ess_round_buffersize,
265 ess_mappage,
266 ess_1888_get_props,
267 ess_audio2_trigger_output,
268 ess_audio1_trigger_input,
269 };
270
271 #ifdef AUDIO_DEBUG
272 void ess_printsc(struct ess_softc *);
273 void ess_dump_mixer(struct ess_softc *);
274
275 void
276 ess_printsc(sc)
277 struct ess_softc *sc;
278 {
279 int i;
280
281 printf("open %d iobase 0x%x outport %u inport %u speaker %s\n",
282 (int)sc->sc_open, sc->sc_iobase, sc->out_port,
283 sc->in_port, sc->spkr_state ? "on" : "off");
284
285 printf("audio1: dmachan %d irq %d nintr %lu intr %p arg %p\n",
286 sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
287 sc->sc_audio1.intr, sc->sc_audio1.arg);
288
289 if (!ESS_USE_AUDIO1(sc->sc_model)) {
290 printf("audio2: dmachan %d irq %d nintr %lu intr %p arg %p\n",
291 sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
292 sc->sc_audio2.intr, sc->sc_audio2.arg);
293 }
294
295 printf("gain:");
296 for (i = 0; i < sc->ndevs; i++)
297 printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
298 printf("\n");
299 }
300
301 void
302 ess_dump_mixer(sc)
303 struct ess_softc *sc;
304 {
305 printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
306 0x7C, ess_read_mix_reg(sc, 0x7C));
307 printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
308 0x1A, ess_read_mix_reg(sc, 0x1A));
309 printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
310 0x3E, ess_read_mix_reg(sc, 0x3E));
311 printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
312 0x36, ess_read_mix_reg(sc, 0x36));
313 printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
314 0x38, ess_read_mix_reg(sc, 0x38));
315 printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
316 0x3A, ess_read_mix_reg(sc, 0x3A));
317 printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
318 0x32, ess_read_mix_reg(sc, 0x32));
319 printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
320 0x3C, ess_read_mix_reg(sc, 0x3C));
321 printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
322 0x69, ess_read_mix_reg(sc, 0x69));
323 printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
324 0x68, ess_read_mix_reg(sc, 0x68));
325 printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
326 0x6E, ess_read_mix_reg(sc, 0x6E));
327 printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
328 0x6B, ess_read_mix_reg(sc, 0x6B));
329 printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
330 0x6A, ess_read_mix_reg(sc, 0x6A));
331 printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
332 0x6C, ess_read_mix_reg(sc, 0x6C));
333 printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
334 0xB4, ess_read_x_reg(sc, 0xB4));
335 printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
336 0x14, ess_read_mix_reg(sc, 0x14));
337
338 printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
339 ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
340 printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
341 ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
342 printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
343 ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
344 ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
345 }
346
347 #endif
348
349
350
351
352 int
353 ess_config_addr(sc)
354 struct ess_softc *sc;
355 {
356 int iobase = sc->sc_iobase;
357 bus_space_tag_t iot = sc->sc_iot;
358
359
360
361
362
363
364
365 bus_space_handle_t scr_access_ioh;
366 bus_space_handle_t scr_ioh;
367 u_short scr_value;
368
369
370
371
372 scr_value = ESS_SCR_AUDIO_ENABLE;
373
374
375
376
377
378 switch(iobase) {
379 case 0x220:
380 scr_value |= ESS_SCR_AUDIO_220;
381 break;
382 case 0x230:
383 scr_value |= ESS_SCR_AUDIO_230;
384 break;
385 case 0x240:
386 scr_value |= ESS_SCR_AUDIO_240;
387 break;
388 case 0x250:
389 scr_value |= ESS_SCR_AUDIO_250;
390 break;
391 default:
392 printf("ess: configured iobase 0x%x invalid\n", iobase);
393 return (1);
394 break;
395 }
396
397
398
399
400
401 if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
402 0, &scr_access_ioh)) {
403 printf("ess: can't map SCR access registers\n");
404 return (1);
405 }
406 if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
407 0, &scr_ioh)) {
408 printf("ess: can't map SCR registers\n");
409 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
410 return (1);
411 }
412
413
414 EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
415
416
417 EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
418 EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
419
420
421 EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
422
423
424 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
425 bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
426
427 return 0;
428 }
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446 void
447 ess_config_irq(sc)
448 struct ess_softc *sc;
449 {
450 int v;
451
452 DPRINTFN(2,("ess_config_irq\n"));
453
454 if (sc->sc_model == ESS_1887 &&
455 sc->sc_audio1.irq == sc->sc_audio2.irq &&
456 sc->sc_audio1.irq != -1) {
457
458 v = ESS_IS_SELECT_IRQ;
459 switch (sc->sc_audio1.irq) {
460 case 5:
461 v |= ESS_IS_INTRB;
462 break;
463 case 7:
464 v |= ESS_IS_INTRC;
465 break;
466 case 9:
467 v |= ESS_IS_INTRA;
468 break;
469 case 10:
470 v |= ESS_IS_INTRD;
471 break;
472 case 15:
473 v |= ESS_IS_INTRE;
474 break;
475 #ifdef DIAGNOSTIC
476 default:
477 printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
478 sc->sc_audio1.irq);
479 return;
480 #endif
481 }
482
483 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
484 return;
485 }
486
487 if (sc->sc_model == ESS_1887) {
488
489 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
490 }
491
492 if (sc->sc_audio1.polled) {
493
494 v = 0;
495 } else {
496
497 v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT;
498 switch (sc->sc_audio1.irq) {
499 case 5:
500 v |= ESS_IRQ_CTRL_INTRB;
501 break;
502 case 7:
503 v |= ESS_IRQ_CTRL_INTRC;
504 break;
505 case 9:
506 v |= ESS_IRQ_CTRL_INTRA;
507 break;
508 case 10:
509 v |= ESS_IRQ_CTRL_INTRD;
510 break;
511 #ifdef DIAGNOSTIC
512 default:
513 printf("ess: configured irq %d not supported for Audio 1\n",
514 sc->sc_audio1.irq);
515 return;
516 #endif
517 }
518 }
519 ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
520
521 if (ESS_USE_AUDIO1(sc->sc_model))
522 return;
523
524 if (sc->sc_audio2.polled) {
525
526 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
527 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
528 } else {
529
530 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
531 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
532 }
533 }
534
535
536 void
537 ess_config_drq(sc)
538 struct ess_softc *sc;
539 {
540 int v;
541
542 DPRINTFN(2,("ess_config_drq\n"));
543
544
545 v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
546 switch (sc->sc_audio1.drq) {
547 case 0:
548 v |= ESS_DRQ_CTRL_DRQA;
549 break;
550 case 1:
551 v |= ESS_DRQ_CTRL_DRQB;
552 break;
553 case 3:
554 v |= ESS_DRQ_CTRL_DRQC;
555 break;
556 #ifdef DIAGNOSTIC
557 default:
558 printf("ess_config_drq: configured dma chan %d not supported for Audio 1\n",
559 sc->sc_audio1.drq);
560 return;
561 #endif
562 }
563
564 ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
565
566 if (ESS_USE_AUDIO1(sc->sc_model))
567 return;
568
569
570 v = ESS_AUDIO2_CTRL3_DRQ_PD;
571 switch (sc->sc_audio2.drq) {
572 case 0:
573 v |= ESS_AUDIO2_CTRL3_DRQA;
574 break;
575 case 1:
576 v |= ESS_AUDIO2_CTRL3_DRQB;
577 break;
578 case 3:
579 v |= ESS_AUDIO2_CTRL3_DRQC;
580 break;
581 case 5:
582 v |= ESS_AUDIO2_CTRL3_DRQD;
583 break;
584 #ifdef DIAGNOSTIC
585 default:
586 printf("ess_config_drq: configured dma chan %d not supported for Audio 2\n",
587 sc->sc_audio2.drq);
588 return;
589 #endif
590 }
591 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
592
593 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
594 ESS_AUDIO2_CTRL2_DMA_ENABLE);
595 }
596
597
598
599
600 void
601 ess_setup(sc)
602 struct ess_softc *sc;
603 {
604
605 ess_config_irq(sc);
606 ess_config_drq(sc);
607
608 DPRINTFN(2,("ess_setup: done\n"));
609 }
610
611
612
613
614
615
616
617
618
619 int
620 ess_identify(sc)
621 struct ess_softc *sc;
622 {
623 u_char reg1;
624 u_char reg2;
625 u_char reg3;
626 u_int8_t ident[4];
627
628 sc->sc_model = ESS_UNSUPPORTED;
629 sc->sc_version = 0;
630
631 memset(ident, 0, sizeof(ident));
632
633
634
635
636
637
638 ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
639
640 if ((reg1 = ess_rdsp(sc)) != 0x68) {
641 printf("ess: First ID byte wrong (0x%02x)\n", reg1);
642 return 1;
643 }
644
645 reg2 = ess_rdsp(sc);
646 if (((reg2 & 0xf0) != 0x80) ||
647 ((reg2 & 0x0f) < 8)) {
648 printf("ess: Second ID byte wrong (0x%02x)\n", reg2);
649 return 1;
650 }
651
652
653
654
655 sc->sc_version = (reg1 << 8) + reg2;
656
657
658
659
660
661
662 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
663 reg2 = reg1 ^ 0x04;
664
665 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
666
667 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
668 printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
669 return 1;
670 }
671
672
673
674
675 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
676
677
678
679
680
681
682
683
684 reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
685 reg2 = reg1 ^ 0xff;
686
687 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
688
689 if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
690
691 sc->sc_model = ESS_1788;
692
693
694
695
696 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
697 if(ident[0] == 0x18) {
698 switch(ident[1]) {
699 case 0x68:
700 sc->sc_model = ESS_1868;
701 break;
702 case 0x78:
703 sc->sc_model = ESS_1878;
704 break;
705 }
706 }
707 } else {
708
709
710
711
712
713
714
715 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
716 reg2 = reg1 ^ 0x20;
717
718 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
719
720 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
721 sc->sc_model = ESS_1887;
722
723
724
725
726 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
727
728
729
730
731 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
732 if(ident[0] == 0x18) {
733 switch(ident[1]) {
734 case 0x69:
735 sc->sc_model = ESS_1869;
736 break;
737 case 0x79:
738 sc->sc_model = ESS_1879;
739 break;
740 }
741 }
742 } else {
743
744
745
746
747
748
749
750
751 reg1 = ess_read_mix_reg(sc, 0x68);
752 reg2 = ess_read_mix_reg(sc, 0x69);
753 reg3 = reg2 ^ 0xff;
754
755
756
757
758 ess_write_mix_reg(sc, 0x68, reg2);
759 ess_write_mix_reg(sc, 0x69, reg3);
760
761 if (ess_read_mix_reg(sc, 0x68) == reg2 &&
762 ess_read_mix_reg(sc, 0x69) == reg3)
763 sc->sc_model = ESS_888;
764 else
765 sc->sc_model = ESS_1888;
766
767
768
769
770 ess_write_mix_reg(sc, 0x68, reg1);
771 ess_write_mix_reg(sc, 0x69, reg2);
772 }
773 }
774
775 return 0;
776 }
777
778
779 int
780 ess_setup_sc(sc, doinit)
781 struct ess_softc *sc;
782 int doinit;
783 {
784
785 if (ess_reset(sc) != 0) {
786 DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
787 return (1);
788 }
789
790
791 if (ess_identify(sc)) {
792 DPRINTF(("ess_setup_sc: couldn't identify\n"));
793 return (1);
794 }
795
796 return (0);
797 }
798
799
800
801
802 int
803 essmatch(sc)
804 struct ess_softc *sc;
805 {
806 if (!ESS_BASE_VALID(sc->sc_iobase)) {
807 printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
808 return (0);
809 }
810
811
812 if (ess_config_addr(sc))
813 return (0);
814
815 if (ess_setup_sc(sc, 1))
816 return (0);
817
818 if (sc->sc_model == ESS_UNSUPPORTED) {
819 DPRINTF(("ess: Unsupported model\n"));
820 return (0);
821 }
822
823
824 if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
825 printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
826 return (0);
827 }
828 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio1.drq))
829 return (0);
830 if (!ESS_USE_AUDIO1(sc->sc_model)) {
831 if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
832 printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
833 return (0);
834 }
835 if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
836 printf("ess: play and record drq both %d\n",
837 sc->sc_audio1.drq);
838 return (0);
839 }
840 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio2.drq))
841 return (0);
842 }
843
844
845
846
847
848 if (sc->sc_model == ESS_1887 &&
849 sc->sc_audio1.irq == sc->sc_audio2.irq &&
850 sc->sc_audio1.irq != -1 &&
851 ESS_IRQ12_VALID(sc->sc_audio1.irq))
852 goto irq_not1888;
853
854
855 if (sc->sc_audio1.irq != -1 &&
856 !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
857 printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
858 return (0);
859 }
860 if (!ESS_USE_AUDIO1(sc->sc_model)) {
861 if (sc->sc_audio2.irq != -1 &&
862 !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
863 printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
864 return (0);
865 }
866 if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
867 sc->sc_audio1.irq != -1) {
868 printf("ess: play and record irq both %d\n",
869 sc->sc_audio1.irq);
870 return (0);
871 }
872 }
873
874 irq_not1888:
875
876
877 return (1);
878 }
879
880
881
882
883
884
885 void
886 essattach(sc)
887 struct ess_softc *sc;
888 {
889 struct audio_attach_args arg;
890 struct audio_params pparams, rparams;
891 int i;
892 u_int v;
893
894 if (ess_setup_sc(sc, 0)) {
895 printf(": setup failed\n");
896 return;
897 }
898
899 printf(": ESS Technology ES%s [version 0x%04x]\n",
900 essmodel[sc->sc_model], sc->sc_version);
901
902 sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
903 if (!sc->sc_audio1.polled) {
904 sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
905 sc->sc_audio1.irq, sc->sc_audio1.ist, IPL_AUDIO,
906 ess_audio1_intr, sc, sc->sc_dev.dv_xname);
907 printf("%s: audio1 interrupting at irq %d\n",
908 sc->sc_dev.dv_xname, sc->sc_audio1.irq);
909 } else
910 printf("%s: audio1 polled\n", sc->sc_dev.dv_xname);
911 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio1.drq,
912 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
913 printf("%s: can't create map for drq %d\n",
914 sc->sc_dev.dv_xname, sc->sc_audio1.drq);
915 return;
916 }
917
918 if (!ESS_USE_AUDIO1(sc->sc_model)) {
919 sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
920 if (!sc->sc_audio2.polled) {
921 sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
922 sc->sc_audio2.irq, sc->sc_audio2.ist, IPL_AUDIO,
923 ess_audio2_intr, sc, sc->sc_dev.dv_xname);
924 printf("%s: audio2 interrupting at irq %d\n",
925 sc->sc_dev.dv_xname, sc->sc_audio2.irq);
926 } else
927 printf("%s: audio2 polled\n", sc->sc_dev.dv_xname);
928 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio2.drq,
929 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
930 printf("%s: can't create map for drq %d\n",
931 sc->sc_dev.dv_xname, sc->sc_audio2.drq);
932 return;
933 }
934 }
935
936 timeout_set(&sc->sc_tmo1, ess_audio1_poll, sc);
937 timeout_set(&sc->sc_tmo2, ess_audio2_poll, sc);
938
939
940
941
942
943 pparams = audio_default;
944 rparams = audio_default;
945 ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
946
947
948 ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
949
950
951
952
953
954 if (!ESS_USE_AUDIO1(sc->sc_model))
955 ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
956 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
957
958 if (ESS_USE_AUDIO1(sc->sc_model)) {
959 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
960 sc->in_port = ESS_SOURCE_MIC;
961 sc->ndevs = ESS_1788_NDEVS;
962 } else {
963
964
965
966
967
968
969 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
970 sc->in_mask = 1 << ESS_MIC_REC_VOL;
971 sc->ndevs = ESS_1888_NDEVS;
972 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
973 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
974 }
975
976
977
978
979
980
981 for (i = 0; i < sc->ndevs; i++) {
982 switch (i) {
983 case ESS_MIC_PLAY_VOL:
984 case ESS_LINE_PLAY_VOL:
985 case ESS_CD_PLAY_VOL:
986 case ESS_AUXB_PLAY_VOL:
987 case ESS_DAC_REC_VOL:
988 case ESS_LINE_REC_VOL:
989 case ESS_SYNTH_REC_VOL:
990 case ESS_CD_REC_VOL:
991 case ESS_AUXB_REC_VOL:
992 v = 0;
993 break;
994 default:
995 v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
996 break;
997 }
998 sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
999 ess_set_gain(sc, i, 1);
1000 }
1001
1002 ess_setup(sc);
1003
1004
1005 ess_speaker_off(sc);
1006 sc->spkr_state = SPKR_OFF;
1007
1008 snprintf(ess_device.name, sizeof ess_device.name, "ES%s",
1009 essmodel[sc->sc_model]);
1010 snprintf(ess_device.version, sizeof ess_device.version, "0x%04x",
1011 sc->sc_version);
1012
1013 if (ESS_USE_AUDIO1(sc->sc_model))
1014 audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
1015 else
1016 audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
1017
1018 arg.type = AUDIODEV_TYPE_OPL;
1019 arg.hwif = 0;
1020 arg.hdl = 0;
1021 (void)config_found(&sc->sc_dev, &arg, audioprint);
1022
1023 #ifdef AUDIO_DEBUG
1024 if (essdebug > 0)
1025 ess_printsc(sc);
1026 #endif
1027 }
1028
1029
1030
1031
1032
1033 int
1034 ess_open(addr, flags)
1035 void *addr;
1036 int flags;
1037 {
1038 struct ess_softc *sc = addr;
1039
1040 DPRINTF(("ess_open: sc=%p\n", sc));
1041
1042 if (sc->sc_open != 0 || ess_reset(sc) != 0)
1043 return ENXIO;
1044
1045 ess_setup(sc);
1046
1047 sc->sc_open = 1;
1048
1049 DPRINTF(("ess_open: opened\n"));
1050
1051 return (0);
1052 }
1053
1054 void
1055 ess_1788_close(addr)
1056 void *addr;
1057 {
1058 struct ess_softc *sc = addr;
1059
1060 DPRINTF(("ess_1788_close: sc=%p\n", sc));
1061
1062 ess_speaker_off(sc);
1063 sc->spkr_state = SPKR_OFF;
1064
1065 ess_audio1_halt(sc);
1066
1067 sc->sc_open = 0;
1068 DPRINTF(("ess_1788_close: closed\n"));
1069 }
1070
1071 void
1072 ess_1888_close(addr)
1073 void *addr;
1074 {
1075 struct ess_softc *sc = addr;
1076
1077 DPRINTF(("ess_1888_close: sc=%p\n", sc));
1078
1079 ess_speaker_off(sc);
1080 sc->spkr_state = SPKR_OFF;
1081
1082 ess_audio1_halt(sc);
1083 ess_audio2_halt(sc);
1084
1085 sc->sc_open = 0;
1086 DPRINTF(("ess_1888_close: closed\n"));
1087 }
1088
1089
1090
1091
1092
1093 int
1094 ess_drain(addr)
1095 void *addr;
1096 {
1097 tsleep(addr, PWAIT | PCATCH, "essdr", hz/20);
1098 return (0);
1099 }
1100
1101
1102 int
1103 ess_speaker_ctl(addr, newstate)
1104 void *addr;
1105 int newstate;
1106 {
1107 struct ess_softc *sc = addr;
1108
1109 if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
1110 ess_speaker_on(sc);
1111 sc->spkr_state = SPKR_ON;
1112 }
1113 if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
1114 ess_speaker_off(sc);
1115 sc->spkr_state = SPKR_OFF;
1116 }
1117 return (0);
1118 }
1119
1120 int
1121 ess_getdev(addr, retp)
1122 void *addr;
1123 struct audio_device *retp;
1124 {
1125 *retp = ess_device;
1126 return (0);
1127 }
1128
1129 int
1130 ess_query_encoding(addr, fp)
1131 void *addr;
1132 struct audio_encoding *fp;
1133 {
1134
1135
1136 switch (fp->index) {
1137 case 0:
1138 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
1139 fp->encoding = AUDIO_ENCODING_ULINEAR;
1140 fp->precision = 8;
1141 fp->flags = 0;
1142 return (0);
1143 case 1:
1144 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
1145 fp->encoding = AUDIO_ENCODING_ULAW;
1146 fp->precision = 8;
1147 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1148 return (0);
1149 case 2:
1150 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
1151 fp->encoding = AUDIO_ENCODING_ALAW;
1152 fp->precision = 8;
1153 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1154 return (0);
1155 case 3:
1156 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
1157 fp->encoding = AUDIO_ENCODING_SLINEAR;
1158 fp->precision = 8;
1159 fp->flags = 0;
1160 return (0);
1161 case 4:
1162 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
1163 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
1164 fp->precision = 16;
1165 fp->flags = 0;
1166 return (0);
1167 case 5:
1168 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
1169 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
1170 fp->precision = 16;
1171 fp->flags = 0;
1172 return (0);
1173 case 6:
1174 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
1175 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
1176 fp->precision = 16;
1177 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1178 return (0);
1179 case 7:
1180 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
1181 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
1182 fp->precision = 16;
1183 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1184 return (0);
1185 default:
1186 return EINVAL;
1187 }
1188 return (0);
1189 }
1190
1191 int
1192 ess_set_params(addr, setmode, usemode, play, rec)
1193 void *addr;
1194 int setmode, usemode;
1195 struct audio_params *play, *rec;
1196 {
1197 struct ess_softc *sc = addr;
1198 struct audio_params *p;
1199 int mode;
1200 int rate;
1201
1202 DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
1203
1204
1205
1206
1207
1208
1209
1210
1211 if (play->sample_rate != rec->sample_rate &&
1212 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
1213 if (setmode == AUMODE_PLAY) {
1214 rec->sample_rate = play->sample_rate;
1215 setmode |= AUMODE_RECORD;
1216 } else if (setmode == AUMODE_RECORD) {
1217 play->sample_rate = rec->sample_rate;
1218 setmode |= AUMODE_PLAY;
1219 } else
1220 return (EINVAL);
1221 }
1222
1223 for (mode = AUMODE_RECORD; mode != -1;
1224 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
1225 if ((setmode & mode) == 0)
1226 continue;
1227
1228 p = mode == AUMODE_PLAY ? play : rec;
1229
1230 if (p->sample_rate < ESS_MINRATE ||
1231 p->sample_rate > ESS_MAXRATE ||
1232 (p->precision != 8 && p->precision != 16) ||
1233 (p->channels != 1 && p->channels != 2))
1234 return (EINVAL);
1235
1236 p->factor = 1;
1237 p->sw_code = 0;
1238 switch (p->encoding) {
1239 case AUDIO_ENCODING_SLINEAR_BE:
1240 case AUDIO_ENCODING_ULINEAR_BE:
1241 if (p->precision == 16)
1242 p->sw_code = swap_bytes;
1243 break;
1244 case AUDIO_ENCODING_SLINEAR_LE:
1245 case AUDIO_ENCODING_ULINEAR_LE:
1246 break;
1247 case AUDIO_ENCODING_ULAW:
1248 if (mode == AUMODE_PLAY) {
1249 p->factor = 2;
1250 p->sw_code = mulaw_to_ulinear16;
1251 } else
1252 p->sw_code = ulinear8_to_mulaw;
1253 break;
1254 case AUDIO_ENCODING_ALAW:
1255 if (mode == AUMODE_PLAY) {
1256 p->factor = 2;
1257 p->sw_code = alaw_to_ulinear16;
1258 } else
1259 p->sw_code = ulinear8_to_alaw;
1260 break;
1261 default:
1262 return (EINVAL);
1263 }
1264 }
1265
1266 if (usemode == AUMODE_RECORD)
1267 rate = rec->sample_rate;
1268 else
1269 rate = play->sample_rate;
1270
1271 ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
1272 ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
1273
1274 if (!ESS_USE_AUDIO1(sc->sc_model)) {
1275 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
1276 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
1277 }
1278
1279 return (0);
1280 }
1281
1282 int
1283 ess_audio1_trigger_output(addr, start, end, blksize, intr, arg, param)
1284 void *addr;
1285 void *start, *end;
1286 int blksize;
1287 void (*intr)(void *);
1288 void *arg;
1289 struct audio_params *param;
1290 {
1291 struct ess_softc *sc = addr;
1292 u_int8_t reg;
1293
1294 DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1295 addr, start, end, blksize, intr, arg));
1296
1297 if (sc->sc_audio1.active)
1298 panic("ess_audio1_trigger_output: already running");
1299
1300 sc->sc_audio1.active = 1;
1301 sc->sc_audio1.intr = intr;
1302 sc->sc_audio1.arg = arg;
1303 if (sc->sc_audio1.polled) {
1304 sc->sc_audio1.dmapos = 0;
1305 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1306 sc->sc_audio1.dmacount = 0;
1307 sc->sc_audio1.blksize = blksize;
1308 timeout_add(&sc->sc_tmo1, hz/30);
1309 }
1310
1311 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1312 if (param->channels == 2) {
1313 reg &= ~ESS_AUDIO_CTRL_MONO;
1314 reg |= ESS_AUDIO_CTRL_STEREO;
1315 } else {
1316 reg |= ESS_AUDIO_CTRL_MONO;
1317 reg &= ~ESS_AUDIO_CTRL_STEREO;
1318 }
1319 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1320
1321 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1322 if (param->precision * param->factor == 16)
1323 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1324 else
1325 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1326 if (param->channels == 2)
1327 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1328 else
1329 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1330 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1331 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1332 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1333 else
1334 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1335 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1336 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1337
1338 isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
1339 (char *)end - (char *)start, NULL,
1340 DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1341
1342
1343 blksize = -blksize;
1344 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1345 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1346
1347
1348 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1349
1350
1351 ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
1352 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1353 reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
1354 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1355 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1356
1357 return (0);
1358 }
1359
1360 int
1361 ess_audio2_trigger_output(addr, start, end, blksize, intr, arg, param)
1362 void *addr;
1363 void *start, *end;
1364 int blksize;
1365 void (*intr)(void *);
1366 void *arg;
1367 struct audio_params *param;
1368 {
1369 struct ess_softc *sc = addr;
1370 u_int8_t reg;
1371
1372 DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1373 addr, start, end, blksize, intr, arg));
1374
1375 if (sc->sc_audio2.active)
1376 panic("ess_audio2_trigger_output: already running");
1377
1378 sc->sc_audio2.active = 1;
1379 sc->sc_audio2.intr = intr;
1380 sc->sc_audio2.arg = arg;
1381 if (sc->sc_audio2.polled) {
1382 sc->sc_audio2.dmapos = 0;
1383 sc->sc_audio2.buffersize = (char *)end - (char *)start;
1384 sc->sc_audio2.dmacount = 0;
1385 sc->sc_audio2.blksize = blksize;
1386 timeout_add(&sc->sc_tmo2, hz/30);
1387 }
1388
1389 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1390 if (param->precision * param->factor == 16)
1391 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
1392 else
1393 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
1394 if (param->channels == 2)
1395 reg |= ESS_AUDIO2_CTRL2_CHANNELS;
1396 else
1397 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
1398 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1399 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1400 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1401 else
1402 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1403 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1404
1405 isa_dmastart(sc->sc_isa, sc->sc_audio2.drq, start,
1406 (char *)end - (char *)start, NULL,
1407 DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1408
1409 if (IS16BITDRQ(sc->sc_audio2.drq))
1410 blksize >>= 1;
1411
1412 blksize = -blksize;
1413 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
1414 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
1415
1416 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
1417 if (IS16BITDRQ(sc->sc_audio2.drq))
1418 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
1419 else
1420 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
1421 reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
1422 reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
1423 ESS_AUDIO2_CTRL1_AUTO_INIT;
1424 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
1425
1426 return (0);
1427 }
1428
1429 int
1430 ess_audio1_trigger_input(addr, start, end, blksize, intr, arg, param)
1431 void *addr;
1432 void *start, *end;
1433 int blksize;
1434 void (*intr)(void *);
1435 void *arg;
1436 struct audio_params *param;
1437 {
1438 struct ess_softc *sc = addr;
1439 u_int8_t reg;
1440
1441 DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1442 addr, start, end, blksize, intr, arg));
1443
1444 if (sc->sc_audio1.active)
1445 panic("ess_audio1_trigger_input: already running");
1446
1447 sc->sc_audio1.active = 1;
1448 sc->sc_audio1.intr = intr;
1449 sc->sc_audio1.arg = arg;
1450 if (sc->sc_audio1.polled) {
1451 sc->sc_audio1.dmapos = 0;
1452 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1453 sc->sc_audio1.dmacount = 0;
1454 sc->sc_audio1.blksize = blksize;
1455 timeout_add(&sc->sc_tmo1, hz/30);
1456 }
1457
1458 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1459 if (param->channels == 2) {
1460 reg &= ~ESS_AUDIO_CTRL_MONO;
1461 reg |= ESS_AUDIO_CTRL_STEREO;
1462 } else {
1463 reg |= ESS_AUDIO_CTRL_MONO;
1464 reg &= ~ESS_AUDIO_CTRL_STEREO;
1465 }
1466 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1467
1468 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1469 if (param->precision * param->factor == 16)
1470 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1471 else
1472 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1473 if (param->channels == 2)
1474 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1475 else
1476 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1477 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1478 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1479 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1480 else
1481 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1482 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1483 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1484
1485 isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
1486 (char *)end - (char *)start, NULL,
1487 DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1488
1489
1490 blksize = -blksize;
1491 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1492 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1493
1494
1495 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1496
1497
1498 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
1499 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1500 reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
1501 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1502 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1503
1504 return (0);
1505 }
1506
1507 int
1508 ess_audio1_halt(addr)
1509 void *addr;
1510 {
1511 struct ess_softc *sc = addr;
1512
1513 DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
1514
1515 if (sc->sc_audio1.active) {
1516 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
1517 ESS_AUDIO1_CTRL2_FIFO_ENABLE);
1518 isa_dmaabort(sc->sc_isa, sc->sc_audio1.drq);
1519 if (sc->sc_audio1.polled)
1520 timeout_del(&sc->sc_tmo1);
1521 sc->sc_audio1.active = 0;
1522 }
1523
1524 return (0);
1525 }
1526
1527 int
1528 ess_audio2_halt(addr)
1529 void *addr;
1530 {
1531 struct ess_softc *sc = addr;
1532
1533 DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
1534
1535 if (sc->sc_audio2.active) {
1536 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
1537 ESS_AUDIO2_CTRL1_DAC_ENABLE |
1538 ESS_AUDIO2_CTRL1_FIFO_ENABLE);
1539 isa_dmaabort(sc->sc_isa, sc->sc_audio2.drq);
1540 if (sc->sc_audio2.polled)
1541 timeout_del(&sc->sc_tmo2);
1542 sc->sc_audio2.active = 0;
1543 }
1544
1545 return (0);
1546 }
1547
1548 int
1549 ess_audio1_intr(arg)
1550 void *arg;
1551 {
1552 struct ess_softc *sc = arg;
1553 u_int8_t reg;
1554
1555 DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
1556
1557
1558 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
1559 if ((reg & ESS_DSP_READ_OFLOW) == 0)
1560 return (0);
1561 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
1562
1563 sc->sc_audio1.nintr++;
1564
1565 if (sc->sc_audio1.active) {
1566 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1567 return (1);
1568 } else
1569 return (0);
1570 }
1571
1572 int
1573 ess_audio2_intr(arg)
1574 void *arg;
1575 {
1576 struct ess_softc *sc = arg;
1577 u_int8_t reg;
1578
1579 DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
1580
1581
1582 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1583 if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0)
1584 return (0);
1585 reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
1586 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1587
1588 sc->sc_audio2.nintr++;
1589
1590 if (sc->sc_audio2.active) {
1591 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1592 return (1);
1593 } else
1594 return (0);
1595 }
1596
1597 void
1598 ess_audio1_poll(addr)
1599 void *addr;
1600 {
1601 struct ess_softc *sc = addr;
1602 int dmapos, dmacount;
1603
1604 if (!sc->sc_audio1.active)
1605 return;
1606
1607 sc->sc_audio1.nintr++;
1608
1609 dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio1.drq);
1610 dmacount = sc->sc_audio1.dmapos - dmapos;
1611 if (dmacount < 0)
1612 dmacount += sc->sc_audio1.buffersize;
1613 sc->sc_audio1.dmapos = dmapos;
1614 #if 1
1615 dmacount += sc->sc_audio1.dmacount;
1616 while (dmacount > sc->sc_audio1.blksize) {
1617 dmacount -= sc->sc_audio1.blksize;
1618 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1619 }
1620 sc->sc_audio1.dmacount = dmacount;
1621 #else
1622 (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
1623 #endif
1624
1625 timeout_add(&sc->sc_tmo1, hz/30);
1626 }
1627
1628 void
1629 ess_audio2_poll(addr)
1630 void *addr;
1631 {
1632 struct ess_softc *sc = addr;
1633 int dmapos, dmacount;
1634
1635 if (!sc->sc_audio2.active)
1636 return;
1637
1638 sc->sc_audio2.nintr++;
1639
1640 dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio2.drq);
1641 dmacount = sc->sc_audio2.dmapos - dmapos;
1642 if (dmacount < 0)
1643 dmacount += sc->sc_audio2.buffersize;
1644 sc->sc_audio2.dmapos = dmapos;
1645 #if 1
1646 dmacount += sc->sc_audio2.dmacount;
1647 while (dmacount > sc->sc_audio2.blksize) {
1648 dmacount -= sc->sc_audio2.blksize;
1649 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1650 }
1651 sc->sc_audio2.dmacount = dmacount;
1652 #else
1653 (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
1654 #endif
1655
1656 timeout_add(&sc->sc_tmo2, hz/30);
1657 }
1658
1659 int
1660 ess_round_blocksize(addr, blk)
1661 void *addr;
1662 int blk;
1663 {
1664 return ((blk + 7) & -8);
1665 }
1666
1667 int
1668 ess_set_port(addr, cp)
1669 void *addr;
1670 mixer_ctrl_t *cp;
1671 {
1672 struct ess_softc *sc = addr;
1673 int lgain, rgain;
1674
1675 DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
1676 cp->dev, cp->un.value.num_channels));
1677
1678 switch (cp->dev) {
1679
1680
1681
1682
1683
1684 case ESS_MASTER_VOL:
1685 case ESS_DAC_PLAY_VOL:
1686 case ESS_MIC_PLAY_VOL:
1687 case ESS_LINE_PLAY_VOL:
1688 case ESS_SYNTH_PLAY_VOL:
1689 case ESS_CD_PLAY_VOL:
1690 case ESS_AUXB_PLAY_VOL:
1691 case ESS_RECORD_VOL:
1692 if (cp->type != AUDIO_MIXER_VALUE)
1693 return EINVAL;
1694
1695 switch (cp->un.value.num_channels) {
1696 case 1:
1697 lgain = rgain = ESS_4BIT_GAIN(
1698 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1699 break;
1700 case 2:
1701 lgain = ESS_4BIT_GAIN(
1702 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1703 rgain = ESS_4BIT_GAIN(
1704 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1705 break;
1706 default:
1707 return EINVAL;
1708 }
1709
1710 sc->gain[cp->dev][ESS_LEFT] = lgain;
1711 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1712 ess_set_gain(sc, cp->dev, 1);
1713 return (0);
1714
1715
1716
1717
1718
1719 case ESS_PCSPEAKER_VOL:
1720 if (cp->un.value.num_channels != 1)
1721 return EINVAL;
1722
1723 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
1724 ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1725 ess_set_gain(sc, cp->dev, 1);
1726 return (0);
1727
1728 case ESS_RECORD_SOURCE:
1729 if (ESS_USE_AUDIO1(sc->sc_model)) {
1730 if (cp->type == AUDIO_MIXER_ENUM)
1731 return (ess_set_in_port(sc, cp->un.ord));
1732 else
1733 return (EINVAL);
1734 } else {
1735 if (cp->type == AUDIO_MIXER_SET)
1736 return (ess_set_in_ports(sc, cp->un.mask));
1737 else
1738 return (EINVAL);
1739 }
1740 return (0);
1741
1742 case ESS_RECORD_MONITOR:
1743 if (cp->type != AUDIO_MIXER_ENUM)
1744 return EINVAL;
1745
1746 if (cp->un.ord)
1747
1748 ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1749 ESS_AUDIO_CTRL_MONITOR);
1750 else
1751
1752 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1753 ESS_AUDIO_CTRL_MONITOR);
1754 return (0);
1755 }
1756
1757 if (ESS_USE_AUDIO1(sc->sc_model))
1758 return (EINVAL);
1759
1760 switch (cp->dev) {
1761 case ESS_DAC_REC_VOL:
1762 case ESS_MIC_REC_VOL:
1763 case ESS_LINE_REC_VOL:
1764 case ESS_SYNTH_REC_VOL:
1765 case ESS_CD_REC_VOL:
1766 case ESS_AUXB_REC_VOL:
1767 if (cp->type != AUDIO_MIXER_VALUE)
1768 return EINVAL;
1769
1770 switch (cp->un.value.num_channels) {
1771 case 1:
1772 lgain = rgain = ESS_4BIT_GAIN(
1773 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1774 break;
1775 case 2:
1776 lgain = ESS_4BIT_GAIN(
1777 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1778 rgain = ESS_4BIT_GAIN(
1779 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1780 break;
1781 default:
1782 return EINVAL;
1783 }
1784
1785 sc->gain[cp->dev][ESS_LEFT] = lgain;
1786 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1787 ess_set_gain(sc, cp->dev, 1);
1788 return (0);
1789
1790 case ESS_MIC_PREAMP:
1791 if (cp->type != AUDIO_MIXER_ENUM)
1792 return EINVAL;
1793
1794 if (cp->un.ord)
1795
1796 ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1797 ESS_PREAMP_CTRL_ENABLE);
1798 else
1799
1800 ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1801 ESS_PREAMP_CTRL_ENABLE);
1802 return (0);
1803 }
1804
1805 return (EINVAL);
1806 }
1807
1808 int
1809 ess_get_port(addr, cp)
1810 void *addr;
1811 mixer_ctrl_t *cp;
1812 {
1813 struct ess_softc *sc = addr;
1814
1815 DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
1816
1817 switch (cp->dev) {
1818 case ESS_MASTER_VOL:
1819 case ESS_DAC_PLAY_VOL:
1820 case ESS_MIC_PLAY_VOL:
1821 case ESS_LINE_PLAY_VOL:
1822 case ESS_SYNTH_PLAY_VOL:
1823 case ESS_CD_PLAY_VOL:
1824 case ESS_AUXB_PLAY_VOL:
1825 case ESS_RECORD_VOL:
1826 switch (cp->un.value.num_channels) {
1827 case 1:
1828 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1829 sc->gain[cp->dev][ESS_LEFT];
1830 break;
1831 case 2:
1832 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1833 sc->gain[cp->dev][ESS_LEFT];
1834 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1835 sc->gain[cp->dev][ESS_RIGHT];
1836 break;
1837 default:
1838 return EINVAL;
1839 }
1840 return (0);
1841
1842 case ESS_PCSPEAKER_VOL:
1843 if (cp->un.value.num_channels != 1)
1844 return EINVAL;
1845
1846 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1847 sc->gain[cp->dev][ESS_LEFT];
1848 return (0);
1849
1850 case ESS_RECORD_SOURCE:
1851 if (ESS_USE_AUDIO1(sc->sc_model))
1852 cp->un.ord = sc->in_port;
1853 else
1854 cp->un.mask = sc->in_mask;
1855 return (0);
1856
1857 case ESS_RECORD_MONITOR:
1858 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
1859 ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
1860 return (0);
1861 }
1862
1863 if (ESS_USE_AUDIO1(sc->sc_model))
1864 return (EINVAL);
1865
1866 switch (cp->dev) {
1867 case ESS_DAC_REC_VOL:
1868 case ESS_MIC_REC_VOL:
1869 case ESS_LINE_REC_VOL:
1870 case ESS_SYNTH_REC_VOL:
1871 case ESS_CD_REC_VOL:
1872 case ESS_AUXB_REC_VOL:
1873 switch (cp->un.value.num_channels) {
1874 case 1:
1875 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1876 sc->gain[cp->dev][ESS_LEFT];
1877 break;
1878 case 2:
1879 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1880 sc->gain[cp->dev][ESS_LEFT];
1881 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1882 sc->gain[cp->dev][ESS_RIGHT];
1883 break;
1884 default:
1885 return EINVAL;
1886 }
1887 return (0);
1888
1889 case ESS_MIC_PREAMP:
1890 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
1891 ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
1892 return (0);
1893 }
1894
1895 return (EINVAL);
1896 }
1897
1898 int
1899 ess_query_devinfo(addr, dip)
1900 void *addr;
1901 mixer_devinfo_t *dip;
1902 {
1903 struct ess_softc *sc = addr;
1904
1905 DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
1906 sc->sc_model, dip->index));
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917 switch (dip->index) {
1918 case ESS_DAC_PLAY_VOL:
1919 dip->mixer_class = ESS_INPUT_CLASS;
1920 dip->next = dip->prev = AUDIO_MIXER_LAST;
1921 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
1922 dip->type = AUDIO_MIXER_VALUE;
1923 dip->un.v.num_channels = 2;
1924 strlcpy(dip->un.v.units.name, AudioNvolume,
1925 sizeof dip->un.v.units.name);
1926 return (0);
1927
1928 case ESS_MIC_PLAY_VOL:
1929 dip->mixer_class = ESS_INPUT_CLASS;
1930 dip->prev = AUDIO_MIXER_LAST;
1931 if (ESS_USE_AUDIO1(sc->sc_model))
1932 dip->next = AUDIO_MIXER_LAST;
1933 else
1934 dip->next = ESS_MIC_PREAMP;
1935 strlcpy(dip->label.name, AudioNmicrophone,
1936 sizeof dip->label.name);
1937 dip->type = AUDIO_MIXER_VALUE;
1938 dip->un.v.num_channels = 2;
1939 strlcpy(dip->un.v.units.name, AudioNvolume,
1940 sizeof dip->un.v.units.name);
1941 return (0);
1942
1943 case ESS_LINE_PLAY_VOL:
1944 dip->mixer_class = ESS_INPUT_CLASS;
1945 dip->next = dip->prev = AUDIO_MIXER_LAST;
1946 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
1947 dip->type = AUDIO_MIXER_VALUE;
1948 dip->un.v.num_channels = 2;
1949 strlcpy(dip->un.v.units.name, AudioNvolume,
1950 sizeof dip->un.v.units.name);
1951 return (0);
1952
1953 case ESS_SYNTH_PLAY_VOL:
1954 dip->mixer_class = ESS_INPUT_CLASS;
1955 dip->next = dip->prev = AUDIO_MIXER_LAST;
1956 strlcpy(dip->label.name, AudioNfmsynth,
1957 sizeof dip->label.name);
1958 dip->type = AUDIO_MIXER_VALUE;
1959 dip->un.v.num_channels = 2;
1960 strlcpy(dip->un.v.units.name, AudioNvolume,
1961 sizeof dip->un.v.units.name);
1962 return (0);
1963
1964 case ESS_CD_PLAY_VOL:
1965 dip->mixer_class = ESS_INPUT_CLASS;
1966 dip->next = dip->prev = AUDIO_MIXER_LAST;
1967 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
1968 dip->type = AUDIO_MIXER_VALUE;
1969 dip->un.v.num_channels = 2;
1970 strlcpy(dip->un.v.units.name, AudioNvolume,
1971 sizeof dip->un.v.units.name);
1972 return (0);
1973
1974 case ESS_AUXB_PLAY_VOL:
1975 dip->mixer_class = ESS_INPUT_CLASS;
1976 dip->next = dip->prev = AUDIO_MIXER_LAST;
1977 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
1978 dip->type = AUDIO_MIXER_VALUE;
1979 dip->un.v.num_channels = 2;
1980 strlcpy(dip->un.v.units.name, AudioNvolume,
1981 sizeof dip->un.v.units.name);
1982 return (0);
1983
1984 case ESS_INPUT_CLASS:
1985 dip->mixer_class = ESS_INPUT_CLASS;
1986 dip->next = dip->prev = AUDIO_MIXER_LAST;
1987 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
1988 dip->type = AUDIO_MIXER_CLASS;
1989 return (0);
1990
1991 case ESS_MASTER_VOL:
1992 dip->mixer_class = ESS_OUTPUT_CLASS;
1993 dip->next = dip->prev = AUDIO_MIXER_LAST;
1994 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
1995 dip->type = AUDIO_MIXER_VALUE;
1996 dip->un.v.num_channels = 2;
1997 strlcpy(dip->un.v.units.name, AudioNvolume,
1998 sizeof dip->un.v.units.name);
1999 return (0);
2000
2001 case ESS_PCSPEAKER_VOL:
2002 dip->mixer_class = ESS_OUTPUT_CLASS;
2003 dip->next = dip->prev = AUDIO_MIXER_LAST;
2004 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name);
2005 dip->type = AUDIO_MIXER_VALUE;
2006 dip->un.v.num_channels = 1;
2007 strlcpy(dip->un.v.units.name, AudioNvolume,
2008 sizeof dip->un.v.units.name);
2009 return (0);
2010
2011 case ESS_OUTPUT_CLASS:
2012 dip->mixer_class = ESS_OUTPUT_CLASS;
2013 dip->next = dip->prev = AUDIO_MIXER_LAST;
2014 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
2015 dip->type = AUDIO_MIXER_CLASS;
2016 return (0);
2017
2018 case ESS_RECORD_VOL:
2019 dip->mixer_class = ESS_RECORD_CLASS;
2020 dip->next = dip->prev = AUDIO_MIXER_LAST;
2021 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
2022 dip->type = AUDIO_MIXER_VALUE;
2023 dip->un.v.num_channels = 2;
2024 strlcpy(dip->un.v.units.name, AudioNvolume,
2025 sizeof dip->un.v.units.name);
2026 return (0);
2027
2028 case ESS_RECORD_SOURCE:
2029 dip->mixer_class = ESS_RECORD_CLASS;
2030 dip->next = dip->prev = AUDIO_MIXER_LAST;
2031 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
2032 if (ESS_USE_AUDIO1(sc->sc_model)) {
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042 dip->type = AUDIO_MIXER_ENUM;
2043 dip->un.e.num_mem = 4;
2044 strlcpy(dip->un.e.member[0].label.name,
2045 AudioNmicrophone,
2046 sizeof dip->un.e.member[0].label.name);
2047 dip->un.e.member[0].ord = ESS_SOURCE_MIC;
2048 strlcpy(dip->un.e.member[1].label.name, AudioNline,
2049 sizeof dip->un.e.member[1].label.name);
2050 dip->un.e.member[1].ord = ESS_SOURCE_LINE;
2051 strlcpy(dip->un.e.member[2].label.name, AudioNcd,
2052 sizeof dip->un.e.member[2].label.name);
2053 dip->un.e.member[2].ord = ESS_SOURCE_CD;
2054 strlcpy(dip->un.e.member[3].label.name, AudioNmixerout,
2055 sizeof dip->un.e.member[3].label.name);
2056 dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
2057 } else {
2058 dip->type = AUDIO_MIXER_SET;
2059 dip->un.s.num_mem = 6;
2060 strlcpy(dip->un.s.member[0].label.name, AudioNdac,
2061 sizeof dip->un.e.member[0].label.name);
2062 dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
2063 strlcpy(dip->un.s.member[1].label.name,
2064 AudioNmicrophone,
2065 sizeof dip->un.e.member[1].label.name);
2066 dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
2067 strlcpy(dip->un.s.member[2].label.name, AudioNline,
2068 sizeof dip->un.e.member[2].label.name);
2069 dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
2070 strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth,
2071 sizeof dip->un.e.member[3].label.name);
2072 dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
2073 strlcpy(dip->un.s.member[4].label.name, AudioNcd,
2074 sizeof dip->un.e.member[4].label.name);
2075 dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
2076 strlcpy(dip->un.s.member[5].label.name, "auxb",
2077 sizeof dip->un.e.member[5].label.name);
2078 dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
2079 }
2080 return (0);
2081
2082 case ESS_RECORD_CLASS:
2083 dip->mixer_class = ESS_RECORD_CLASS;
2084 dip->next = dip->prev = AUDIO_MIXER_LAST;
2085 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
2086 dip->type = AUDIO_MIXER_CLASS;
2087 return (0);
2088
2089 case ESS_RECORD_MONITOR:
2090 dip->prev = dip->next = AUDIO_MIXER_LAST;
2091 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
2092 dip->type = AUDIO_MIXER_ENUM;
2093 dip->mixer_class = ESS_MONITOR_CLASS;
2094 dip->un.e.num_mem = 2;
2095 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2096 sizeof dip->un.e.member[0].label.name);
2097 dip->un.e.member[0].ord = 0;
2098 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2099 sizeof dip->un.e.member[1].label.name);
2100 dip->un.e.member[1].ord = 1;
2101 return (0);
2102
2103 case ESS_MONITOR_CLASS:
2104 dip->mixer_class = ESS_MONITOR_CLASS;
2105 dip->next = dip->prev = AUDIO_MIXER_LAST;
2106 strlcpy(dip->label.name, AudioCmonitor,
2107 sizeof dip->label.name);
2108 dip->type = AUDIO_MIXER_CLASS;
2109 return (0);
2110 }
2111
2112 if (ESS_USE_AUDIO1(sc->sc_model))
2113 return (ENXIO);
2114
2115 switch (dip->index) {
2116 case ESS_DAC_REC_VOL:
2117 dip->mixer_class = ESS_RECORD_CLASS;
2118 dip->next = dip->prev = AUDIO_MIXER_LAST;
2119 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
2120 dip->type = AUDIO_MIXER_VALUE;
2121 dip->un.v.num_channels = 2;
2122 strlcpy(dip->un.v.units.name, AudioNvolume,
2123 sizeof dip->un.v.units.name);
2124 return (0);
2125
2126 case ESS_MIC_REC_VOL:
2127 dip->mixer_class = ESS_RECORD_CLASS;
2128 dip->next = dip->prev = AUDIO_MIXER_LAST;
2129 strlcpy(dip->label.name, AudioNmicrophone,
2130 sizeof dip->label.name);
2131 dip->type = AUDIO_MIXER_VALUE;
2132 dip->un.v.num_channels = 2;
2133 strlcpy(dip->un.v.units.name, AudioNvolume,
2134 sizeof dip->un.v.units.name);
2135 return (0);
2136
2137 case ESS_LINE_REC_VOL:
2138 dip->mixer_class = ESS_RECORD_CLASS;
2139 dip->next = dip->prev = AUDIO_MIXER_LAST;
2140 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
2141 dip->type = AUDIO_MIXER_VALUE;
2142 dip->un.v.num_channels = 2;
2143 strlcpy(dip->un.v.units.name, AudioNvolume,
2144 sizeof dip->un.v.units.name);
2145 return (0);
2146
2147 case ESS_SYNTH_REC_VOL:
2148 dip->mixer_class = ESS_RECORD_CLASS;
2149 dip->next = dip->prev = AUDIO_MIXER_LAST;
2150 strlcpy(dip->label.name, AudioNfmsynth,
2151 sizeof dip->label.name);
2152 dip->type = AUDIO_MIXER_VALUE;
2153 dip->un.v.num_channels = 2;
2154 strlcpy(dip->un.v.units.name, AudioNvolume,
2155 sizeof dip->un.v.units.name);
2156 return (0);
2157
2158 case ESS_CD_REC_VOL:
2159 dip->mixer_class = ESS_RECORD_CLASS;
2160 dip->next = dip->prev = AUDIO_MIXER_LAST;
2161 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2162 dip->type = AUDIO_MIXER_VALUE;
2163 dip->un.v.num_channels = 2;
2164 strlcpy(dip->un.v.units.name, AudioNvolume,
2165 sizeof dip->un.v.units.name);
2166 return (0);
2167
2168 case ESS_AUXB_REC_VOL:
2169 dip->mixer_class = ESS_RECORD_CLASS;
2170 dip->next = dip->prev = AUDIO_MIXER_LAST;
2171 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
2172 dip->type = AUDIO_MIXER_VALUE;
2173 dip->un.v.num_channels = 2;
2174 strlcpy(dip->un.v.units.name, AudioNvolume,
2175 sizeof dip->un.v.units.name);
2176 return (0);
2177
2178 case ESS_MIC_PREAMP:
2179 dip->mixer_class = ESS_INPUT_CLASS;
2180 dip->prev = ESS_MIC_PLAY_VOL;
2181 dip->next = AUDIO_MIXER_LAST;
2182 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
2183 dip->type = AUDIO_MIXER_ENUM;
2184 dip->un.e.num_mem = 2;
2185 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2186 sizeof dip->un.e.member[0].label.name);
2187 dip->un.e.member[0].ord = 0;
2188 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2189 sizeof dip->un.e.member[1].label.name);
2190 dip->un.e.member[1].ord = 1;
2191 return (0);
2192 }
2193
2194 return (ENXIO);
2195 }
2196
2197 void *
2198 ess_malloc(addr, direction, size, pool, flags)
2199 void *addr;
2200 int direction;
2201 size_t size;
2202 int pool, flags;
2203 {
2204 struct ess_softc *sc = addr;
2205 int drq;
2206
2207 if (!ESS_USE_AUDIO1(sc->sc_model))
2208 drq = sc->sc_audio2.drq;
2209 else
2210 drq = sc->sc_audio1.drq;
2211 return (isa_malloc(sc->sc_isa, drq, size, pool, flags));
2212 }
2213
2214 void
2215 ess_free(addr, ptr, pool)
2216 void *addr;
2217 void *ptr;
2218 int pool;
2219 {
2220 isa_free(ptr, pool);
2221 }
2222
2223 size_t
2224 ess_round_buffersize(addr, direction, size)
2225 void *addr;
2226 int direction;
2227 size_t size;
2228 {
2229 if (size > MAX_ISADMA)
2230 size = MAX_ISADMA;
2231 return (size);
2232 }
2233
2234 paddr_t
2235 ess_mappage(addr, mem, off, prot)
2236 void *addr;
2237 void *mem;
2238 off_t off;
2239 int prot;
2240 {
2241 return (isa_mappage(mem, off, prot));
2242 }
2243
2244 int
2245 ess_1788_get_props(addr)
2246 void *addr;
2247 {
2248
2249 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT);
2250 }
2251
2252 int
2253 ess_1888_get_props(addr)
2254 void *addr;
2255 {
2256
2257 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
2258 }
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269 int
2270 ess_reset(sc)
2271 struct ess_softc *sc;
2272 {
2273 bus_space_tag_t iot = sc->sc_iot;
2274 bus_space_handle_t ioh = sc->sc_ioh;
2275
2276 sc->sc_audio1.active = 0;
2277 sc->sc_audio2.active = 0;
2278
2279 EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
2280 delay(10000);
2281 EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
2282 if (ess_rdsp(sc) != ESS_MAGIC)
2283 return (1);
2284
2285
2286 ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
2287
2288 return (0);
2289 }
2290
2291 void
2292 ess_set_gain(sc, port, on)
2293 struct ess_softc *sc;
2294 int port;
2295 int on;
2296 {
2297 int gain, left, right;
2298 int mix;
2299 int src;
2300 int stereo;
2301
2302
2303
2304
2305
2306
2307 mix = 1;
2308 stereo = 1;
2309
2310 switch (port) {
2311 case ESS_MASTER_VOL:
2312 src = ESS_MREG_VOLUME_MASTER;
2313 break;
2314 case ESS_DAC_PLAY_VOL:
2315 if (ESS_USE_AUDIO1(sc->sc_model))
2316 src = ESS_MREG_VOLUME_VOICE;
2317 else
2318 src = 0x7C;
2319 break;
2320 case ESS_MIC_PLAY_VOL:
2321 src = ESS_MREG_VOLUME_MIC;
2322 break;
2323 case ESS_LINE_PLAY_VOL:
2324 src = ESS_MREG_VOLUME_LINE;
2325 break;
2326 case ESS_SYNTH_PLAY_VOL:
2327 src = ESS_MREG_VOLUME_SYNTH;
2328 break;
2329 case ESS_CD_PLAY_VOL:
2330 src = ESS_MREG_VOLUME_CD;
2331 break;
2332 case ESS_AUXB_PLAY_VOL:
2333 src = ESS_MREG_VOLUME_AUXB;
2334 break;
2335 case ESS_PCSPEAKER_VOL:
2336 src = ESS_MREG_VOLUME_PCSPKR;
2337 stereo = 0;
2338 break;
2339 case ESS_DAC_REC_VOL:
2340 src = 0x69;
2341 break;
2342 case ESS_MIC_REC_VOL:
2343 src = 0x68;
2344 break;
2345 case ESS_LINE_REC_VOL:
2346 src = 0x6E;
2347 break;
2348 case ESS_SYNTH_REC_VOL:
2349 src = 0x6B;
2350 break;
2351 case ESS_CD_REC_VOL:
2352 src = 0x6A;
2353 break;
2354 case ESS_AUXB_REC_VOL:
2355 src = 0x6C;
2356 break;
2357 case ESS_RECORD_VOL:
2358 src = ESS_XCMD_VOLIN_CTRL;
2359 mix = 0;
2360 break;
2361 default:
2362 return;
2363 }
2364
2365
2366 if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
2367 return;
2368
2369 if (on) {
2370 left = sc->gain[port][ESS_LEFT];
2371 right = sc->gain[port][ESS_RIGHT];
2372 } else {
2373 left = right = 0;
2374 }
2375
2376 if (stereo)
2377 gain = ESS_STEREO_GAIN(left, right);
2378 else
2379 gain = ESS_MONO_GAIN(left);
2380
2381 if (mix)
2382 ess_write_mix_reg(sc, src, gain);
2383 else
2384 ess_write_x_reg(sc, src, gain);
2385 }
2386
2387
2388 int
2389 ess_set_in_port(sc, ord)
2390 struct ess_softc *sc;
2391 int ord;
2392 {
2393 mixer_devinfo_t di;
2394 int i;
2395
2396 DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
2397
2398
2399
2400
2401
2402 di.index = ESS_RECORD_SOURCE;
2403 if (ess_query_devinfo(sc, &di))
2404 return EINVAL;
2405
2406
2407 for (i = 0; i < di.un.e.num_mem; i++) {
2408 if (ord == di.un.e.member[i].ord)
2409 break;
2410 }
2411 if (i == di.un.e.num_mem)
2412 return EINVAL;
2413
2414 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
2415
2416 sc->in_port = ord;
2417 return (0);
2418 }
2419
2420
2421 int
2422 ess_set_in_ports(sc, mask)
2423 struct ess_softc *sc;
2424 int mask;
2425 {
2426 mixer_devinfo_t di;
2427 int i, port;
2428
2429 DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
2430
2431
2432
2433
2434
2435 di.index = ESS_RECORD_SOURCE;
2436 if (ess_query_devinfo(sc, &di))
2437 return EINVAL;
2438
2439
2440
2441
2442
2443 for (i = 0; i < di.un.s.num_mem; i++) {
2444
2445
2446
2447 port = ffs(di.un.s.member[i].mask);
2448
2449
2450
2451
2452
2453
2454 ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
2455 }
2456
2457 sc->in_mask = mask;
2458 return (0);
2459 }
2460
2461 void
2462 ess_speaker_on(sc)
2463 struct ess_softc *sc;
2464 {
2465
2466 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
2467 }
2468
2469 void
2470 ess_speaker_off(sc)
2471 struct ess_softc *sc;
2472 {
2473
2474 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
2475 }
2476
2477
2478
2479
2480 u_int
2481 ess_srtotc(rate)
2482 u_int rate;
2483 {
2484 u_int tc;
2485
2486
2487 if (rate <= 22050)
2488 tc = 128 - 397700L / rate;
2489 else
2490 tc = 256 - 795500L / rate;
2491
2492 return (tc);
2493 }
2494
2495
2496
2497
2498
2499 u_int
2500 ess_srtofc(rate)
2501 u_int rate;
2502 {
2503
2504
2505
2506
2507
2508 return (256 - 200279L / rate);
2509 }
2510
2511
2512
2513
2514
2515 u_char
2516 ess_get_dsp_status(sc)
2517 struct ess_softc *sc;
2518 {
2519 return (EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS));
2520 }
2521
2522
2523
2524
2525
2526
2527 u_char
2528 ess_dsp_read_ready(sc)
2529 struct ess_softc *sc;
2530 {
2531 return ((ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0);
2532 }
2533
2534
2535
2536
2537
2538
2539 u_char
2540 ess_dsp_write_ready(sc)
2541 struct ess_softc *sc;
2542 {
2543 return ((ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1);
2544 }
2545
2546
2547
2548
2549
2550 int
2551 ess_rdsp(sc)
2552 struct ess_softc *sc;
2553 {
2554 bus_space_tag_t iot = sc->sc_iot;
2555 bus_space_handle_t ioh = sc->sc_ioh;
2556 int i;
2557
2558 for (i = ESS_READ_TIMEOUT; i > 0; --i) {
2559 if (ess_dsp_read_ready(sc)) {
2560 i = EREAD1(iot, ioh, ESS_DSP_READ);
2561 DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
2562 return i;
2563 } else
2564 delay(10);
2565 }
2566
2567 DPRINTF(("ess_rdsp: timed out\n"));
2568 return (-1);
2569 }
2570
2571
2572
2573
2574 int
2575 ess_wdsp(sc, v)
2576 struct ess_softc *sc;
2577 u_char v;
2578 {
2579 bus_space_tag_t iot = sc->sc_iot;
2580 bus_space_handle_t ioh = sc->sc_ioh;
2581 int i;
2582
2583 DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
2584
2585 for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
2586 if (ess_dsp_write_ready(sc)) {
2587 EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
2588 return (0);
2589 } else
2590 delay(10);
2591 }
2592
2593 DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
2594 return (-1);
2595 }
2596
2597
2598
2599
2600 int
2601 ess_write_x_reg(sc, reg, val)
2602 struct ess_softc *sc;
2603 u_char reg;
2604 u_char val;
2605 {
2606 int error;
2607
2608 DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
2609 if ((error = ess_wdsp(sc, reg)) == 0)
2610 error = ess_wdsp(sc, val);
2611
2612 return error;
2613 }
2614
2615
2616
2617
2618 u_char
2619 ess_read_x_reg(sc, reg)
2620 struct ess_softc *sc;
2621 u_char reg;
2622 {
2623 int error;
2624 int val;
2625
2626 if ((error = ess_wdsp(sc, 0xC0)) == 0)
2627 error = ess_wdsp(sc, reg);
2628 if (error)
2629 DPRINTF(("Error reading extended register 0x%02x\n", reg));
2630
2631 val = ess_rdsp(sc);
2632 DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
2633 return val;
2634 }
2635
2636 void
2637 ess_clear_xreg_bits(sc, reg, mask)
2638 struct ess_softc *sc;
2639 u_char reg;
2640 u_char mask;
2641 {
2642 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1)
2643 DPRINTF(("Error clearing bits in extended register 0x%02x\n",
2644 reg));
2645 }
2646
2647 void
2648 ess_set_xreg_bits(sc, reg, mask)
2649 struct ess_softc *sc;
2650 u_char reg;
2651 u_char mask;
2652 {
2653 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1)
2654 DPRINTF(("Error setting bits in extended register 0x%02x\n",
2655 reg));
2656 }
2657
2658
2659
2660
2661
2662 void
2663 ess_write_mix_reg(sc, reg, val)
2664 struct ess_softc *sc;
2665 u_char reg;
2666 u_char val;
2667 {
2668 bus_space_tag_t iot = sc->sc_iot;
2669 bus_space_handle_t ioh = sc->sc_ioh;
2670 int s;
2671
2672 DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
2673
2674 s = splaudio();
2675 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2676 EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
2677 splx(s);
2678 }
2679
2680
2681
2682
2683 u_char
2684 ess_read_mix_reg(sc, reg)
2685 struct ess_softc *sc;
2686 u_char reg;
2687 {
2688 bus_space_tag_t iot = sc->sc_iot;
2689 bus_space_handle_t ioh = sc->sc_ioh;
2690 int s;
2691 u_char val;
2692
2693 s = splaudio();
2694 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2695 val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
2696 splx(s);
2697
2698 DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
2699 return val;
2700 }
2701
2702 void
2703 ess_clear_mreg_bits(sc, reg, mask)
2704 struct ess_softc *sc;
2705 u_char reg;
2706 u_char mask;
2707 {
2708 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
2709 }
2710
2711 void
2712 ess_set_mreg_bits(sc, reg, mask)
2713 struct ess_softc *sc;
2714 u_char reg;
2715 u_char mask;
2716 {
2717 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
2718 }
2719
2720 void
2721 ess_read_multi_mix_reg(sc, reg, datap, count)
2722 struct ess_softc *sc;
2723 u_char reg;
2724 u_int8_t *datap;
2725 bus_size_t count;
2726 {
2727 bus_space_tag_t iot = sc->sc_iot;
2728 bus_space_handle_t ioh = sc->sc_ioh;
2729 int s;
2730
2731 s = splaudio();
2732 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2733 bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
2734 splx(s);
2735 }