No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / isa / ess.c
blob1adcf6d96fb4c1bf679593af465297034d0ec82e
1 /* $NetBSD: ess.c,v 1.75 2007/10/19 12:00:16 ad Exp $ */
3 /*
4 * Copyright 1997
5 * Digital Equipment Corporation. All rights reserved.
7 * This software is furnished under license and may be used and
8 * copied only in accordance with the following terms and conditions.
9 * Subject to these conditions, you may download, copy, install,
10 * use, modify and distribute this software in source and/or binary
11 * form. No title or ownership is transferred hereby.
13 * 1) Any source code used, modified or distributed must reproduce
14 * and retain this copyright notice and list of conditions as
15 * they appear in the source file.
17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Digital Equipment Corporation. Neither the "Digital Equipment
19 * Corporation" name nor any trademark or logo of Digital Equipment
20 * Corporation may be used to endorse or promote products derived
21 * from this software without the prior written permission of
22 * Digital Equipment Corporation.
24 * 3) This software is provided "AS-IS" and any express or implied
25 * warranties, including but not limited to, any implied warranties
26 * of merchantability, fitness for a particular purpose, or
27 * non-infringement are disclaimed. In no event shall DIGITAL be
28 * liable for any damages whatsoever, and in particular, DIGITAL
29 * shall not be liable for special, indirect, consequential, or
30 * incidental damages or damages for lost profits, loss of
31 * revenue or loss of use, whether such damages arise in contract,
32 * negligence, tort, under statute, in equity, at law or otherwise,
33 * even if advised of the possibility of such damage.
37 **++
39 ** ess.c
41 ** FACILITY:
43 ** DIGITAL Network Appliance Reference Design (DNARD)
45 ** MODULE DESCRIPTION:
47 ** This module contains the device driver for the ESS
48 ** Technologies 1888/1887/888 sound chip. The code in sbdsp.c was
49 ** used as a reference point when implementing this driver.
51 ** AUTHORS:
53 ** Blair Fidler Software Engineering Australia
54 ** Gold Coast, Australia.
56 ** CREATION DATE:
58 ** March 10, 1997.
60 ** MODIFICATION HISTORY:
62 ** Heavily modified by Lennart Augustsson and Charles M. Hannum for
63 ** bus_dma, changes to audio interface, and many bug fixes.
64 ** ESS1788 support by Nathan J. Williams and Charles M. Hannum.
65 **--
68 #include <sys/cdefs.h>
69 __KERNEL_RCSID(0, "$NetBSD: ess.c,v 1.75 2007/10/19 12:00:16 ad Exp $");
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/errno.h>
74 #include <sys/ioctl.h>
75 #include <sys/syslog.h>
76 #include <sys/device.h>
77 #include <sys/proc.h>
78 #include <sys/kernel.h>
80 #include <sys/cpu.h>
81 #include <sys/intr.h>
82 #include <sys/bus.h>
84 #include <sys/audioio.h>
85 #include <dev/audio_if.h>
86 #include <dev/auconv.h>
87 #include <dev/mulaw.h>
89 #include <dev/isa/isavar.h>
90 #include <dev/isa/isadmavar.h>
92 #include <dev/isa/essvar.h>
93 #include <dev/isa/essreg.h>
95 #include "joy_ess.h"
97 #ifdef AUDIO_DEBUG
98 #define DPRINTF(x) if (essdebug) printf x
99 #define DPRINTFN(n,x) if (essdebug>(n)) printf x
100 int essdebug = 0;
101 #else
102 #define DPRINTF(x)
103 #define DPRINTFN(n,x)
104 #endif
106 #if 0
107 unsigned uuu;
108 #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu)
109 #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d))
110 #else
111 #define EREAD1(t, h, a) bus_space_read_1(t, h, a)
112 #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d)
113 #endif
116 int ess_setup_sc(struct ess_softc *, int);
118 int ess_open(void *, int);
119 void ess_close(void *);
120 int ess_getdev(void *, struct audio_device *);
121 int ess_drain(void *);
123 int ess_query_encoding(void *, struct audio_encoding *);
125 int ess_set_params(void *, int, int, audio_params_t *,
126 audio_params_t *, stream_filter_list_t *, stream_filter_list_t *);
128 int ess_round_blocksize(void *, int, int, const audio_params_t *);
130 int ess_audio1_trigger_output(void *, void *, void *, int,
131 void (*)(void *), void *, const audio_params_t *);
132 int ess_audio2_trigger_output(void *, void *, void *, int,
133 void (*)(void *), void *, const audio_params_t *);
134 int ess_audio1_trigger_input(void *, void *, void *, int,
135 void (*)(void *), void *, const audio_params_t *);
136 int ess_audio1_halt(void *);
137 int ess_audio2_halt(void *);
138 int ess_audio1_intr(void *);
139 int ess_audio2_intr(void *);
140 void ess_audio1_poll(void *);
141 void ess_audio2_poll(void *);
143 int ess_speaker_ctl(void *, int);
145 int ess_getdev(void *, struct audio_device *);
147 int ess_set_port(void *, mixer_ctrl_t *);
148 int ess_get_port(void *, mixer_ctrl_t *);
150 void *ess_malloc(void *, int, size_t, struct malloc_type *, int);
151 void ess_free(void *, void *, struct malloc_type *);
152 size_t ess_round_buffersize(void *, int, size_t);
153 paddr_t ess_mappage(void *, void *, off_t, int);
156 int ess_query_devinfo(void *, mixer_devinfo_t *);
157 int ess_1788_get_props(void *);
158 int ess_1888_get_props(void *);
160 void ess_speaker_on(struct ess_softc *);
161 void ess_speaker_off(struct ess_softc *);
163 void ess_config_irq(struct ess_softc *);
164 void ess_config_drq(struct ess_softc *);
165 void ess_setup(struct ess_softc *);
166 int ess_identify(struct ess_softc *);
168 int ess_reset(struct ess_softc *);
169 void ess_set_gain(struct ess_softc *, int, int);
170 int ess_set_in_port(struct ess_softc *, int);
171 int ess_set_in_ports(struct ess_softc *, int);
172 u_int ess_srtotc(u_int);
173 u_int ess_srtofc(u_int);
174 u_char ess_get_dsp_status(struct ess_softc *);
175 u_char ess_dsp_read_ready(struct ess_softc *);
176 u_char ess_dsp_write_ready(struct ess_softc *);
177 int ess_rdsp(struct ess_softc *);
178 int ess_wdsp(struct ess_softc *, u_char);
179 u_char ess_read_x_reg(struct ess_softc *, u_char);
180 int ess_write_x_reg(struct ess_softc *, u_char, u_char);
181 void ess_clear_xreg_bits(struct ess_softc *, u_char, u_char);
182 void ess_set_xreg_bits(struct ess_softc *, u_char, u_char);
183 u_char ess_read_mix_reg(struct ess_softc *, u_char);
184 void ess_write_mix_reg(struct ess_softc *, u_char, u_char);
185 void ess_clear_mreg_bits(struct ess_softc *, u_char, u_char);
186 void ess_set_mreg_bits(struct ess_softc *, u_char, u_char);
187 void ess_read_multi_mix_reg(struct ess_softc *, u_char, u_int8_t *, bus_size_t);
189 static const char *essmodel[] = {
190 "unsupported",
192 "688",
193 "1688",
194 "1788",
195 "1868",
196 "1869",
197 "1878",
198 "1879",
200 "888",
201 "1887",
202 "1888",
205 struct audio_device ess_device = {
206 "ESS Technology",
207 "x",
208 "ess"
212 * Define our interface to the higher level audio driver.
215 const struct audio_hw_if ess_1788_hw_if = {
216 ess_open,
217 ess_close,
218 ess_drain,
219 ess_query_encoding,
220 ess_set_params,
221 ess_round_blocksize,
222 NULL,
223 NULL,
224 NULL,
225 NULL,
226 NULL,
227 ess_audio1_halt,
228 ess_audio1_halt,
229 ess_speaker_ctl,
230 ess_getdev,
231 NULL,
232 ess_set_port,
233 ess_get_port,
234 ess_query_devinfo,
235 ess_malloc,
236 ess_free,
237 ess_round_buffersize,
238 ess_mappage,
239 ess_1788_get_props,
240 ess_audio1_trigger_output,
241 ess_audio1_trigger_input,
242 NULL,
243 NULL,
246 const struct audio_hw_if ess_1888_hw_if = {
247 ess_open,
248 ess_close,
249 ess_drain,
250 ess_query_encoding,
251 ess_set_params,
252 ess_round_blocksize,
253 NULL,
254 NULL,
255 NULL,
256 NULL,
257 NULL,
258 ess_audio2_halt,
259 ess_audio1_halt,
260 ess_speaker_ctl,
261 ess_getdev,
262 NULL,
263 ess_set_port,
264 ess_get_port,
265 ess_query_devinfo,
266 ess_malloc,
267 ess_free,
268 ess_round_buffersize,
269 ess_mappage,
270 ess_1888_get_props,
271 ess_audio2_trigger_output,
272 ess_audio1_trigger_input,
273 NULL,
274 NULL,
277 #define ESS_NFORMATS 8
278 static const struct audio_format ess_formats[ESS_NFORMATS] = {
279 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
280 2, AUFMT_STEREO, 0, {ESS_MINRATE, ESS_MAXRATE}},
281 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
282 1, AUFMT_MONAURAL, 0, {ESS_MINRATE, ESS_MAXRATE}},
283 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 16, 16,
284 2, AUFMT_STEREO, 0, {ESS_MINRATE, ESS_MAXRATE}},
285 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 16, 16,
286 1, AUFMT_MONAURAL, 0, {ESS_MINRATE, ESS_MAXRATE}},
287 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8,
288 2, AUFMT_STEREO, 0, {ESS_MINRATE, ESS_MAXRATE}},
289 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8,
290 1, AUFMT_MONAURAL, 0, {ESS_MINRATE, ESS_MAXRATE}},
291 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 8, 8,
292 2, AUFMT_STEREO, 0, {ESS_MINRATE, ESS_MAXRATE}},
293 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 8, 8,
294 1, AUFMT_MONAURAL, 0, {ESS_MINRATE, ESS_MAXRATE}},
297 #ifdef AUDIO_DEBUG
298 void ess_printsc(struct ess_softc *);
299 void ess_dump_mixer(struct ess_softc *);
301 void
302 ess_printsc(struct ess_softc *sc)
304 int i;
306 printf("iobase 0x%x outport %u inport %u speaker %s\n",
307 sc->sc_iobase, sc->out_port,
308 sc->in_port, sc->spkr_state ? "on" : "off");
310 printf("audio1: DMA chan %d irq %d nintr %lu intr %p arg %p\n",
311 sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
312 sc->sc_audio1.intr, sc->sc_audio1.arg);
314 if (!ESS_USE_AUDIO1(sc->sc_model)) {
315 printf("audio2: DMA chan %d irq %d nintr %lu intr %p arg %p\n",
316 sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
317 sc->sc_audio2.intr, sc->sc_audio2.arg);
320 printf("gain:");
321 for (i = 0; i < sc->ndevs; i++)
322 printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
323 printf("\n");
326 void
327 ess_dump_mixer(struct ess_softc *sc)
330 printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
331 0x7C, ess_read_mix_reg(sc, 0x7C));
332 printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
333 0x1A, ess_read_mix_reg(sc, 0x1A));
334 printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
335 0x3E, ess_read_mix_reg(sc, 0x3E));
336 printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
337 0x36, ess_read_mix_reg(sc, 0x36));
338 printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
339 0x38, ess_read_mix_reg(sc, 0x38));
340 printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
341 0x3A, ess_read_mix_reg(sc, 0x3A));
342 printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
343 0x32, ess_read_mix_reg(sc, 0x32));
344 printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
345 0x3C, ess_read_mix_reg(sc, 0x3C));
346 printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
347 0x69, ess_read_mix_reg(sc, 0x69));
348 printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
349 0x68, ess_read_mix_reg(sc, 0x68));
350 printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
351 0x6E, ess_read_mix_reg(sc, 0x6E));
352 printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
353 0x6B, ess_read_mix_reg(sc, 0x6B));
354 printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
355 0x6A, ess_read_mix_reg(sc, 0x6A));
356 printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
357 0x6C, ess_read_mix_reg(sc, 0x6C));
358 printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
359 0xB4, ess_read_x_reg(sc, 0xB4));
360 printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
361 0x14, ess_read_mix_reg(sc, 0x14));
363 printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
364 ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
365 printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
366 ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
367 printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
368 ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
369 ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
372 #endif
375 * Configure the ESS chip for the desired audio base address.
378 ess_config_addr(struct ess_softc *sc)
380 int iobase;
381 bus_space_tag_t iot;
383 * Configure using the System Control Register method. This
384 * method is used when the AMODE line is tied high, which is
385 * the case for the Shark, but not for the evaluation board.
387 bus_space_handle_t scr_access_ioh;
388 bus_space_handle_t scr_ioh;
389 u_short scr_value;
391 iobase = sc->sc_iobase;
392 iot = sc->sc_iot;
394 * Set the SCR bit to enable audio.
396 scr_value = ESS_SCR_AUDIO_ENABLE;
399 * Set the SCR bits necessary to select the specified audio
400 * base address.
402 switch(iobase) {
403 case 0x220:
404 scr_value |= ESS_SCR_AUDIO_220;
405 break;
406 case 0x230:
407 scr_value |= ESS_SCR_AUDIO_230;
408 break;
409 case 0x240:
410 scr_value |= ESS_SCR_AUDIO_240;
411 break;
412 case 0x250:
413 scr_value |= ESS_SCR_AUDIO_250;
414 break;
415 default:
416 printf("ess: configured iobase 0x%x invalid\n", iobase);
417 return 1;
418 break;
422 * Get a mapping for the System Control Register (SCR) access
423 * registers and the SCR data registers.
425 if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
426 0, &scr_access_ioh)) {
427 printf("ess: can't map SCR access registers\n");
428 return 1;
430 if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
431 0, &scr_ioh)) {
432 printf("ess: can't map SCR registers\n");
433 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
434 return 1;
437 /* Unlock the SCR. */
438 EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
440 /* Write the base address information into SCR[0]. */
441 EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
442 EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
444 /* Lock the SCR. */
445 EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
447 /* Unmap the SCR access ports and the SCR data ports. */
448 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
449 bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
451 return 0;
456 * Configure the ESS chip for the desired IRQ and DMA channels.
457 * ESS ISA
458 * --------
459 * IRQA irq9
460 * IRQB irq5
461 * IRQC irq7
462 * IRQD irq10
463 * IRQE irq15
465 * DRQA drq0
466 * DRQB drq1
467 * DRQC drq3
468 * DRQD drq5
470 void
471 ess_config_irq(struct ess_softc *sc)
473 int v;
475 DPRINTFN(2,("ess_config_irq\n"));
477 if (sc->sc_model == ESS_1887 &&
478 sc->sc_audio1.irq == sc->sc_audio2.irq &&
479 sc->sc_audio1.irq != -1) {
480 /* Use new method, both interrupts are the same. */
481 v = ESS_IS_SELECT_IRQ; /* enable intrs */
482 switch (sc->sc_audio1.irq) {
483 case 5:
484 v |= ESS_IS_INTRB;
485 break;
486 case 7:
487 v |= ESS_IS_INTRC;
488 break;
489 case 9:
490 v |= ESS_IS_INTRA;
491 break;
492 case 10:
493 v |= ESS_IS_INTRD;
494 break;
495 case 15:
496 v |= ESS_IS_INTRE;
497 break;
498 #ifdef DIAGNOSTIC
499 default:
500 printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
501 sc->sc_audio1.irq);
502 return;
503 #endif
505 /* Set the IRQ */
506 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
507 return;
510 if (sc->sc_model == ESS_1887) {
511 /* Tell the 1887 to use the old interrupt method. */
512 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
515 if (sc->sc_audio1.polled) {
516 /* Turn off Audio1 interrupts. */
517 v = 0;
518 } else {
519 /* Configure Audio 1 for the appropriate IRQ line. */
520 v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */
521 switch (sc->sc_audio1.irq) {
522 case 5:
523 v |= ESS_IRQ_CTRL_INTRB;
524 break;
525 case 7:
526 v |= ESS_IRQ_CTRL_INTRC;
527 break;
528 case 9:
529 v |= ESS_IRQ_CTRL_INTRA;
530 break;
531 case 10:
532 v |= ESS_IRQ_CTRL_INTRD;
533 break;
534 #ifdef DIAGNOSTIC
535 default:
536 printf("ess: configured irq %d not supported for Audio 1\n",
537 sc->sc_audio1.irq);
538 return;
539 #endif
542 ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
544 if (ESS_USE_AUDIO1(sc->sc_model))
545 return;
547 if (sc->sc_audio2.polled) {
548 /* Turn off Audio2 interrupts. */
549 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
550 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
551 } else {
552 /* Audio2 is hardwired to INTRE in this mode. */
553 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
554 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
559 void
560 ess_config_drq(struct ess_softc *sc)
562 int v;
564 DPRINTFN(2,("ess_config_drq\n"));
566 /* Configure Audio 1 (record) for DMA on the appropriate channel. */
567 v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
568 switch (sc->sc_audio1.drq) {
569 case 0:
570 v |= ESS_DRQ_CTRL_DRQA;
571 break;
572 case 1:
573 v |= ESS_DRQ_CTRL_DRQB;
574 break;
575 case 3:
576 v |= ESS_DRQ_CTRL_DRQC;
577 break;
578 #ifdef DIAGNOSTIC
579 default:
580 printf("ess_config_drq: configured DMA chan %d not supported for Audio 1\n",
581 sc->sc_audio1.drq);
582 return;
583 #endif
585 /* Set DRQ1 */
586 ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
588 if (ESS_USE_AUDIO1(sc->sc_model))
589 return;
591 /* Configure DRQ2 */
592 v = ESS_AUDIO2_CTRL3_DRQ_PD;
593 switch (sc->sc_audio2.drq) {
594 case 0:
595 v |= ESS_AUDIO2_CTRL3_DRQA;
596 break;
597 case 1:
598 v |= ESS_AUDIO2_CTRL3_DRQB;
599 break;
600 case 3:
601 v |= ESS_AUDIO2_CTRL3_DRQC;
602 break;
603 case 5:
604 v |= ESS_AUDIO2_CTRL3_DRQD;
605 break;
606 #ifdef DIAGNOSTIC
607 default:
608 printf("ess_config_drq: configured DMA chan %d not supported for Audio 2\n",
609 sc->sc_audio2.drq);
610 return;
611 #endif
613 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
614 /* Enable DMA 2 */
615 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
616 ESS_AUDIO2_CTRL2_DMA_ENABLE);
620 * Set up registers after a reset.
622 void
623 ess_setup(struct ess_softc *sc)
626 ess_config_irq(sc);
627 ess_config_drq(sc);
629 DPRINTFN(2,("ess_setup: done\n"));
633 * Determine the model of ESS chip we are talking to. Currently we
634 * only support ES1888, ES1887 and ES888. The method of determining
635 * the chip is based on the information on page 27 of the ES1887 data
636 * sheet.
638 * This routine sets the values of sc->sc_model and sc->sc_version.
641 ess_identify(struct ess_softc *sc)
643 u_char reg1;
644 u_char reg2;
645 u_char reg3;
646 u_int8_t ident[4];
648 sc->sc_model = ESS_UNSUPPORTED;
649 sc->sc_version = 0;
651 memset(ident, 0, sizeof(ident));
654 * 1. Check legacy ID bytes. These should be 0x68 0x8n, where
655 * n >= 8 for an ES1887 or an ES888. Other values indicate
656 * earlier (unsupported) chips.
658 ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
660 if ((reg1 = ess_rdsp(sc)) != 0x68) {
661 printf("ess: First ID byte wrong (0x%02x)\n", reg1);
662 return 1;
665 reg2 = ess_rdsp(sc);
666 if (((reg2 & 0xf0) != 0x80) ||
667 ((reg2 & 0x0f) < 8)) {
668 sc->sc_model = ESS_688;
669 return 0;
673 * Store the ID bytes as the version.
675 sc->sc_version = (reg1 << 8) + reg2;
679 * 2. Verify we can change bit 2 in mixer register 0x64. This
680 * should be possible on all supported chips.
682 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
683 reg2 = reg1 ^ 0x04; /* toggle bit 2 */
685 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
687 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
688 switch (sc->sc_version) {
689 case 0x688b:
690 sc->sc_model = ESS_1688;
691 break;
692 default:
693 printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
694 return 1;
696 return 0;
700 * Restore the original value of mixer register 0x64.
702 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
706 * 3. Verify we can change the value of mixer register
707 * ESS_MREG_SAMPLE_RATE.
708 * This is possible on the 1888/1887/888, but not on the 1788.
709 * It is not necessary to restore the value of this mixer register.
711 reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
712 reg2 = reg1 ^ 0xff; /* toggle all bits */
714 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
716 if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
717 /* If we got this far before failing, it's a 1788. */
718 sc->sc_model = ESS_1788;
721 * Identify ESS model for ES18[67]8.
723 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
724 if(ident[0] == 0x18) {
725 switch(ident[1]) {
726 case 0x68:
727 sc->sc_model = ESS_1868;
728 break;
729 case 0x78:
730 sc->sc_model = ESS_1878;
731 break;
735 return 0;
739 * 4. Determine if we can change bit 5 in mixer register 0x64.
740 * This determines whether we have an ES1887:
742 * - can change indicates ES1887
743 * - can't change indicates ES1888 or ES888
745 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
746 reg2 = reg1 ^ 0x20; /* toggle bit 5 */
748 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
750 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
751 sc->sc_model = ESS_1887;
754 * Restore the original value of mixer register 0x64.
756 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
759 * Identify ESS model for ES18[67]9.
761 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
762 if(ident[0] == 0x18) {
763 switch(ident[1]) {
764 case 0x69:
765 sc->sc_model = ESS_1869;
766 break;
767 case 0x79:
768 sc->sc_model = ESS_1879;
769 break;
773 return 0;
777 * 5. Determine if we can change the value of mixer
778 * register 0x69 independently of mixer register
779 * 0x68. This determines which chip we have:
781 * - can modify idependently indicates ES888
782 * - register 0x69 is an alias of 0x68 indicates ES1888
784 reg1 = ess_read_mix_reg(sc, 0x68);
785 reg2 = ess_read_mix_reg(sc, 0x69);
786 reg3 = reg2 ^ 0xff; /* toggle all bits */
789 * Write different values to each register.
791 ess_write_mix_reg(sc, 0x68, reg2);
792 ess_write_mix_reg(sc, 0x69, reg3);
794 if (ess_read_mix_reg(sc, 0x68) == reg2 &&
795 ess_read_mix_reg(sc, 0x69) == reg3)
796 sc->sc_model = ESS_888;
797 else
798 sc->sc_model = ESS_1888;
801 * Restore the original value of the registers.
803 ess_write_mix_reg(sc, 0x68, reg1);
804 ess_write_mix_reg(sc, 0x69, reg2);
806 return 0;
811 ess_setup_sc(struct ess_softc *sc, int doinit)
814 callout_init(&sc->sc_poll1_ch, 0);
815 callout_init(&sc->sc_poll2_ch, 0);
817 /* Reset the chip. */
818 if (ess_reset(sc) != 0) {
819 DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
820 return 1;
823 /* Identify the ESS chip, and check that it is supported. */
824 if (ess_identify(sc)) {
825 DPRINTF(("ess_setup_sc: couldn't identify\n"));
826 return 1;
829 return 0;
833 * Probe for the ESS hardware.
836 essmatch(struct ess_softc *sc)
838 if (!ESS_BASE_VALID(sc->sc_iobase)) {
839 printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
840 return 0;
843 if (ess_setup_sc(sc, 1))
844 return 0;
846 if (sc->sc_model == ESS_UNSUPPORTED) {
847 DPRINTF(("ess: Unsupported model\n"));
848 return 0;
851 /* Check that requested DMA channels are valid and different. */
852 if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
853 printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
854 return 0;
856 if (!isa_drq_isfree(sc->sc_ic, sc->sc_audio1.drq))
857 return 0;
858 if (!ESS_USE_AUDIO1(sc->sc_model)) {
859 if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
860 printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
861 return 0;
863 if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
864 printf("ess: play and record drq both %d\n",
865 sc->sc_audio1.drq);
866 return 0;
868 if (!isa_drq_isfree(sc->sc_ic, sc->sc_audio2.drq))
869 return 0;
873 * The 1887 has an additional IRQ mode where both channels are mapped
874 * to the same IRQ.
876 if (sc->sc_model == ESS_1887 &&
877 sc->sc_audio1.irq == sc->sc_audio2.irq &&
878 sc->sc_audio1.irq != -1 &&
879 ESS_IRQ12_VALID(sc->sc_audio1.irq))
880 goto irq_not1888;
882 /* Check that requested IRQ lines are valid and different. */
883 if (sc->sc_audio1.irq != -1 &&
884 !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
885 printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
886 return 0;
888 if (!ESS_USE_AUDIO1(sc->sc_model)) {
889 if (sc->sc_audio2.irq != -1 &&
890 !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
891 printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
892 return 0;
894 if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
895 sc->sc_audio1.irq != -1) {
896 printf("ess: play and record irq both %d\n",
897 sc->sc_audio1.irq);
898 return 0;
902 irq_not1888:
903 /* XXX should we check IRQs as well? */
905 return 2; /* beat "sb" */
910 * Attach hardware to driver, attach hardware driver to audio
911 * pseudo-device driver.
913 void
914 essattach(struct ess_softc *sc, int enablejoy)
916 struct audio_attach_args arg;
917 int i;
918 u_int v;
920 if (ess_setup_sc(sc, 0)) {
921 printf(": setup failed\n");
922 return;
925 printf(": ESS Technology ES%s [version 0x%04x]\n",
926 essmodel[sc->sc_model], sc->sc_version);
928 sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
929 if (!sc->sc_audio1.polled) {
930 sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
931 sc->sc_audio1.irq, sc->sc_audio1.ist, IPL_AUDIO,
932 ess_audio1_intr, sc);
933 printf("%s: audio1 interrupting at irq %d\n",
934 device_xname(&sc->sc_dev), sc->sc_audio1.irq);
935 } else
936 printf("%s: audio1 polled\n", device_xname(&sc->sc_dev));
937 sc->sc_audio1.maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_audio1.drq);
939 if (isa_drq_alloc(sc->sc_ic, sc->sc_audio1.drq) != 0) {
940 aprint_error_dev(&sc->sc_dev, "can't reserve drq %d\n",
941 sc->sc_audio1.drq);
942 return;
945 if (isa_dmamap_create(sc->sc_ic, sc->sc_audio1.drq,
946 sc->sc_audio1.maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
947 aprint_error_dev(&sc->sc_dev, "can't create map for drq %d\n",
948 sc->sc_audio1.drq);
949 return;
952 if (!ESS_USE_AUDIO1(sc->sc_model)) {
953 sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
954 if (!sc->sc_audio2.polled) {
955 sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
956 sc->sc_audio2.irq, sc->sc_audio2.ist, IPL_AUDIO,
957 ess_audio2_intr, sc);
958 printf("%s: audio2 interrupting at irq %d\n",
959 device_xname(&sc->sc_dev), sc->sc_audio2.irq);
960 } else
961 printf("%s: audio2 polled\n", device_xname(&sc->sc_dev));
962 sc->sc_audio2.maxsize = isa_dmamaxsize(sc->sc_ic,
963 sc->sc_audio2.drq);
965 if (isa_drq_alloc(sc->sc_ic, sc->sc_audio2.drq) != 0) {
966 aprint_error_dev(&sc->sc_dev, "can't reserve drq %d\n",
967 sc->sc_audio2.drq);
968 return;
971 if (isa_dmamap_create(sc->sc_ic, sc->sc_audio2.drq,
972 sc->sc_audio2.maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
973 aprint_error_dev(&sc->sc_dev, "can't create map for drq %d\n",
974 sc->sc_audio2.drq);
975 return;
979 /* Do a hardware reset on the mixer. */
980 ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
983 * Set volume of Audio 1 to zero and disable Audio 1 DAC input
984 * to playback mixer, since playback is always through Audio 2.
986 if (!ESS_USE_AUDIO1(sc->sc_model))
987 ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
988 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
990 if (ESS_USE_AUDIO1(sc->sc_model)) {
991 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
992 sc->in_port = ESS_SOURCE_MIC;
993 sc->ndevs = ESS_1788_NDEVS;
994 } else {
996 * Set hardware record source to use output of the record
997 * mixer. We do the selection of record source in software by
998 * setting the gain of the unused sources to zero. (See
999 * ess_set_in_ports.)
1001 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
1002 sc->in_mask = 1 << ESS_MIC_REC_VOL;
1003 sc->ndevs = ESS_1888_NDEVS;
1004 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
1005 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
1009 * Set gain on each mixer device to a sensible value.
1010 * Devices not normally used are turned off, and other devices
1011 * are set to 50% volume.
1013 for (i = 0; i < sc->ndevs; i++) {
1014 switch (i) {
1015 case ESS_MIC_PLAY_VOL:
1016 case ESS_LINE_PLAY_VOL:
1017 case ESS_CD_PLAY_VOL:
1018 case ESS_AUXB_PLAY_VOL:
1019 case ESS_DAC_REC_VOL:
1020 case ESS_LINE_REC_VOL:
1021 case ESS_SYNTH_REC_VOL:
1022 case ESS_CD_REC_VOL:
1023 case ESS_AUXB_REC_VOL:
1024 v = 0;
1025 break;
1026 default:
1027 v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
1028 break;
1030 sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
1031 ess_set_gain(sc, i, 1);
1034 ess_setup(sc);
1036 /* Disable the speaker until the device is opened. */
1037 ess_speaker_off(sc);
1038 sc->spkr_state = SPKR_OFF;
1040 snprintf(ess_device.name, sizeof(ess_device.name), "ES%s",
1041 essmodel[sc->sc_model]);
1042 snprintf(ess_device.version, sizeof(ess_device.version), "0x%04x",
1043 sc->sc_version);
1045 if (ESS_USE_AUDIO1(sc->sc_model))
1046 audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
1047 else
1048 audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
1050 arg.type = AUDIODEV_TYPE_OPL;
1051 arg.hwif = 0;
1052 arg.hdl = 0;
1053 (void)config_found(&sc->sc_dev, &arg, audioprint);
1055 #if NJOY_ESS > 0
1056 if (sc->sc_model == ESS_1888 && enablejoy) {
1057 unsigned char m40;
1059 m40 = ess_read_mix_reg(sc, 0x40);
1060 m40 |= 2;
1061 ess_write_mix_reg(sc, 0x40, m40);
1063 arg.type = AUDIODEV_TYPE_AUX;
1064 (void)config_found(&sc->sc_dev, &arg, audioprint);
1066 #endif
1068 #ifdef AUDIO_DEBUG
1069 if (essdebug > 0)
1070 ess_printsc(sc);
1071 #endif
1075 * Various routines to interface to higher level audio driver
1079 ess_open(void *addr, int flags)
1081 return 0;
1084 void
1085 ess_close(void *addr)
1087 struct ess_softc *sc;
1089 sc = addr;
1090 DPRINTF(("ess_close: sc=%p\n", sc));
1092 ess_speaker_off(sc);
1093 sc->spkr_state = SPKR_OFF;
1095 DPRINTF(("ess_close: closed\n"));
1099 * Wait for FIFO to drain, and analog section to settle.
1100 * XXX should check FIFO empty bit.
1103 ess_drain(void *addr)
1106 tsleep(addr, PWAIT | PCATCH, "essdr", hz/20); /* XXX */
1107 return 0;
1110 /* XXX should use reference count */
1112 ess_speaker_ctl(void *addr, int newstate)
1114 struct ess_softc *sc;
1116 sc = addr;
1117 if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
1118 ess_speaker_on(sc);
1119 sc->spkr_state = SPKR_ON;
1121 if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
1122 ess_speaker_off(sc);
1123 sc->spkr_state = SPKR_OFF;
1125 return 0;
1129 ess_getdev(void *addr, struct audio_device *retp)
1132 *retp = ess_device;
1133 return 0;
1137 ess_query_encoding(void *addr, struct audio_encoding *fp)
1139 /*struct ess_softc *sc = addr;*/
1141 switch (fp->index) {
1142 case 0:
1143 strcpy(fp->name, AudioEulinear);
1144 fp->encoding = AUDIO_ENCODING_ULINEAR;
1145 fp->precision = 8;
1146 fp->flags = 0;
1147 return 0;
1148 case 1:
1149 strcpy(fp->name, AudioEmulaw);
1150 fp->encoding = AUDIO_ENCODING_ULAW;
1151 fp->precision = 8;
1152 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1153 return 0;
1154 case 2:
1155 strcpy(fp->name, AudioEalaw);
1156 fp->encoding = AUDIO_ENCODING_ALAW;
1157 fp->precision = 8;
1158 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1159 return 0;
1160 case 3:
1161 strcpy(fp->name, AudioEslinear);
1162 fp->encoding = AUDIO_ENCODING_SLINEAR;
1163 fp->precision = 8;
1164 fp->flags = 0;
1165 return 0;
1166 case 4:
1167 strcpy(fp->name, AudioEslinear_le);
1168 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
1169 fp->precision = 16;
1170 fp->flags = 0;
1171 return 0;
1172 case 5:
1173 strcpy(fp->name, AudioEulinear_le);
1174 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
1175 fp->precision = 16;
1176 fp->flags = 0;
1177 return 0;
1178 case 6:
1179 strcpy(fp->name, AudioEslinear_be);
1180 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
1181 fp->precision = 16;
1182 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1183 return 0;
1184 case 7:
1185 strcpy(fp->name, AudioEulinear_be);
1186 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
1187 fp->precision = 16;
1188 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1189 return 0;
1190 default:
1191 return EINVAL;
1193 return 0;
1197 ess_set_params(
1198 void *addr,
1199 int setmode, int usemode,
1200 audio_params_t *play, audio_params_t *rec,
1201 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
1203 struct ess_softc *sc;
1204 int rate;
1206 DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
1207 sc = addr;
1209 * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in
1210 * full-duplex operation the sample rates must be the same for both
1211 * channels. This appears to be false; the only bit in common is the
1212 * clock source selection. However, we'll be conservative here.
1213 * - mycroft
1215 if (play->sample_rate != rec->sample_rate &&
1216 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
1217 if (setmode == AUMODE_PLAY) {
1218 rec->sample_rate = play->sample_rate;
1219 setmode |= AUMODE_RECORD;
1220 } else if (setmode == AUMODE_RECORD) {
1221 play->sample_rate = rec->sample_rate;
1222 setmode |= AUMODE_PLAY;
1223 } else
1224 return EINVAL;
1227 if (setmode & AUMODE_RECORD) {
1228 if (auconv_set_converter(ess_formats, ESS_NFORMATS,
1229 AUMODE_RECORD, rec, FALSE, rfil) < 0)
1230 return EINVAL;
1232 if (setmode & AUMODE_PLAY) {
1233 if (auconv_set_converter(ess_formats, ESS_NFORMATS,
1234 AUMODE_PLAY, play, FALSE, pfil) < 0)
1235 return EINVAL;
1238 if (usemode == AUMODE_RECORD)
1239 rate = rec->sample_rate;
1240 else
1241 rate = play->sample_rate;
1243 ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
1244 ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
1246 if (!ESS_USE_AUDIO1(sc->sc_model)) {
1247 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
1248 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
1251 return 0;
1255 ess_audio1_trigger_output(
1256 void *addr,
1257 void *start, void *end,
1258 int blksize,
1259 void (*intr)(void *),
1260 void *arg,
1261 const audio_params_t *param)
1263 struct ess_softc *sc;
1264 u_int8_t reg;
1266 sc = addr;
1267 DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p "
1268 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1270 if (sc->sc_audio1.active)
1271 panic("ess_audio1_trigger_output: already running");
1273 sc->sc_audio1.active = 1;
1274 sc->sc_audio1.intr = intr;
1275 sc->sc_audio1.arg = arg;
1276 if (sc->sc_audio1.polled) {
1277 sc->sc_audio1.dmapos = 0;
1278 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1279 sc->sc_audio1.dmacount = 0;
1280 sc->sc_audio1.blksize = blksize;
1281 callout_reset(&sc->sc_poll1_ch, hz / 30,
1282 ess_audio1_poll, sc);
1285 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1286 if (param->channels == 2) {
1287 reg &= ~ESS_AUDIO_CTRL_MONO;
1288 reg |= ESS_AUDIO_CTRL_STEREO;
1289 } else {
1290 reg |= ESS_AUDIO_CTRL_MONO;
1291 reg &= ~ESS_AUDIO_CTRL_STEREO;
1293 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1295 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1296 if (param->precision == 16)
1297 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1298 else
1299 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1300 if (param->channels == 2)
1301 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1302 else
1303 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1304 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1305 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1306 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1307 else
1308 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1309 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1310 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1312 isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1313 (char *)end - (char *)start, NULL,
1314 DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1316 /* Program transfer count registers with 2's complement of count. */
1317 blksize = -blksize;
1318 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1319 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1321 /* Use 4 bytes per output DMA. */
1322 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1324 /* Start auto-init DMA */
1325 ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
1326 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1327 reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
1328 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1329 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1331 return 0;
1335 ess_audio2_trigger_output(
1336 void *addr,
1337 void *start, void *end,
1338 int blksize,
1339 void (*intr)(void *),
1340 void *arg,
1341 const audio_params_t *param)
1343 struct ess_softc *sc;
1344 u_int8_t reg;
1346 sc = addr;
1347 DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p "
1348 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1350 if (sc->sc_audio2.active)
1351 panic("ess_audio2_trigger_output: already running");
1353 sc->sc_audio2.active = 1;
1354 sc->sc_audio2.intr = intr;
1355 sc->sc_audio2.arg = arg;
1356 if (sc->sc_audio2.polled) {
1357 sc->sc_audio2.dmapos = 0;
1358 sc->sc_audio2.buffersize = (char *)end - (char *)start;
1359 sc->sc_audio2.dmacount = 0;
1360 sc->sc_audio2.blksize = blksize;
1361 callout_reset(&sc->sc_poll2_ch, hz / 30,
1362 ess_audio2_poll, sc);
1365 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1366 if (param->precision == 16)
1367 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
1368 else
1369 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
1370 if (param->channels == 2)
1371 reg |= ESS_AUDIO2_CTRL2_CHANNELS;
1372 else
1373 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
1374 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1375 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1376 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1377 else
1378 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1379 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1381 isa_dmastart(sc->sc_ic, sc->sc_audio2.drq, start,
1382 (char *)end - (char *)start, NULL,
1383 DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1385 if (IS16BITDRQ(sc->sc_audio2.drq))
1386 blksize >>= 1; /* use word count for 16 bit DMA */
1387 /* Program transfer count registers with 2's complement of count. */
1388 blksize = -blksize;
1389 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
1390 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
1392 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
1393 if (IS16BITDRQ(sc->sc_audio2.drq))
1394 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
1395 else
1396 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
1397 reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
1398 reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
1399 ESS_AUDIO2_CTRL1_AUTO_INIT;
1400 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
1402 return (0);
1406 ess_audio1_trigger_input(
1407 void *addr,
1408 void *start, void *end,
1409 int blksize,
1410 void (*intr)(void *),
1411 void *arg,
1412 const audio_params_t *param)
1414 struct ess_softc *sc;
1415 u_int8_t reg;
1417 sc = addr;
1418 DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p "
1419 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1421 if (sc->sc_audio1.active)
1422 panic("ess_audio1_trigger_input: already running");
1424 sc->sc_audio1.active = 1;
1425 sc->sc_audio1.intr = intr;
1426 sc->sc_audio1.arg = arg;
1427 if (sc->sc_audio1.polled) {
1428 sc->sc_audio1.dmapos = 0;
1429 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1430 sc->sc_audio1.dmacount = 0;
1431 sc->sc_audio1.blksize = blksize;
1432 callout_reset(&sc->sc_poll1_ch, hz / 30,
1433 ess_audio1_poll, sc);
1436 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1437 if (param->channels == 2) {
1438 reg &= ~ESS_AUDIO_CTRL_MONO;
1439 reg |= ESS_AUDIO_CTRL_STEREO;
1440 } else {
1441 reg |= ESS_AUDIO_CTRL_MONO;
1442 reg &= ~ESS_AUDIO_CTRL_STEREO;
1444 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1446 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1447 if (param->precision == 16)
1448 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1449 else
1450 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1451 if (param->channels == 2)
1452 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1453 else
1454 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1455 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1456 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1457 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1458 else
1459 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1460 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1461 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1463 isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1464 (char *)end - (char *)start, NULL,
1465 DMAMODE_READ | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1467 /* Program transfer count registers with 2's complement of count. */
1468 blksize = -blksize;
1469 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1470 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1472 /* Use 4 bytes per input DMA. */
1473 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1475 /* Start auto-init DMA */
1476 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
1477 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1478 reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
1479 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1480 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1482 return 0;
1486 ess_audio1_halt(void *addr)
1488 struct ess_softc *sc;
1490 sc = addr;
1491 DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
1493 if (sc->sc_audio1.active) {
1494 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
1495 ESS_AUDIO1_CTRL2_FIFO_ENABLE);
1496 isa_dmaabort(sc->sc_ic, sc->sc_audio1.drq);
1497 if (sc->sc_audio1.polled)
1498 callout_stop(&sc->sc_poll1_ch);
1499 sc->sc_audio1.active = 0;
1502 return 0;
1506 ess_audio2_halt(void *addr)
1508 struct ess_softc *sc;
1510 sc = addr;
1511 DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
1513 if (sc->sc_audio2.active) {
1514 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
1515 ESS_AUDIO2_CTRL1_DAC_ENABLE |
1516 ESS_AUDIO2_CTRL1_FIFO_ENABLE);
1517 isa_dmaabort(sc->sc_ic, sc->sc_audio2.drq);
1518 if (sc->sc_audio2.polled)
1519 callout_stop(&sc->sc_poll2_ch);
1520 sc->sc_audio2.active = 0;
1523 return 0;
1527 ess_audio1_intr(void *arg)
1529 struct ess_softc *sc;
1530 uint8_t reg;
1532 sc = arg;
1533 DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
1535 /* Check and clear interrupt on Audio1. */
1536 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
1537 if ((reg & ESS_DSP_READ_OFLOW) == 0)
1538 return 0;
1539 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
1541 sc->sc_audio1.nintr++;
1543 if (sc->sc_audio1.active) {
1544 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1545 return 1;
1546 } else
1547 return 0;
1551 ess_audio2_intr(void *arg)
1553 struct ess_softc *sc;
1554 uint8_t reg;
1556 sc = arg;
1557 DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
1559 /* Check and clear interrupt on Audio2. */
1560 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1561 if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0)
1562 return 0;
1563 reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
1564 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1566 sc->sc_audio2.nintr++;
1568 if (sc->sc_audio2.active) {
1569 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1570 return 1;
1571 } else
1572 return 0;
1575 void
1576 ess_audio1_poll(void *addr)
1578 struct ess_softc *sc;
1579 int dmapos, dmacount;
1581 sc = addr;
1582 if (!sc->sc_audio1.active)
1583 return;
1585 sc->sc_audio1.nintr++;
1587 dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio1.drq);
1588 dmacount = sc->sc_audio1.dmapos - dmapos;
1589 if (dmacount < 0)
1590 dmacount += sc->sc_audio1.buffersize;
1591 sc->sc_audio1.dmapos = dmapos;
1592 #if 1
1593 dmacount += sc->sc_audio1.dmacount;
1594 while (dmacount > sc->sc_audio1.blksize) {
1595 dmacount -= sc->sc_audio1.blksize;
1596 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1598 sc->sc_audio1.dmacount = dmacount;
1599 #else
1600 (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
1601 #endif
1603 callout_reset(&sc->sc_poll1_ch, hz / 30, ess_audio1_poll, sc);
1606 void
1607 ess_audio2_poll(void *addr)
1609 struct ess_softc *sc;
1610 int dmapos, dmacount;
1612 sc = addr;
1613 if (!sc->sc_audio2.active)
1614 return;
1616 sc->sc_audio2.nintr++;
1618 dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio2.drq);
1619 dmacount = sc->sc_audio2.dmapos - dmapos;
1620 if (dmacount < 0)
1621 dmacount += sc->sc_audio2.buffersize;
1622 sc->sc_audio2.dmapos = dmapos;
1623 #if 1
1624 dmacount += sc->sc_audio2.dmacount;
1625 while (dmacount > sc->sc_audio2.blksize) {
1626 dmacount -= sc->sc_audio2.blksize;
1627 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1629 sc->sc_audio2.dmacount = dmacount;
1630 #else
1631 (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
1632 #endif
1634 callout_reset(&sc->sc_poll2_ch, hz / 30, ess_audio2_poll, sc);
1638 ess_round_blocksize(void *addr, int blk, int mode,
1639 const audio_params_t *param)
1642 return blk & -8; /* round for max DMA size */
1646 ess_set_port(void *addr, mixer_ctrl_t *cp)
1648 struct ess_softc *sc;
1649 int lgain, rgain;
1651 sc = addr;
1652 DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
1653 cp->dev, cp->un.value.num_channels));
1655 switch (cp->dev) {
1657 * The following mixer ports are all stereo. If we get a
1658 * single-channel gain value passed in, then we duplicate it
1659 * to both left and right channels.
1661 case ESS_MASTER_VOL:
1662 case ESS_DAC_PLAY_VOL:
1663 case ESS_MIC_PLAY_VOL:
1664 case ESS_LINE_PLAY_VOL:
1665 case ESS_SYNTH_PLAY_VOL:
1666 case ESS_CD_PLAY_VOL:
1667 case ESS_AUXB_PLAY_VOL:
1668 case ESS_RECORD_VOL:
1669 if (cp->type != AUDIO_MIXER_VALUE)
1670 return EINVAL;
1672 switch (cp->un.value.num_channels) {
1673 case 1:
1674 lgain = rgain = ESS_4BIT_GAIN(
1675 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1676 break;
1677 case 2:
1678 lgain = ESS_4BIT_GAIN(
1679 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1680 rgain = ESS_4BIT_GAIN(
1681 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1682 break;
1683 default:
1684 return EINVAL;
1687 sc->gain[cp->dev][ESS_LEFT] = lgain;
1688 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1689 ess_set_gain(sc, cp->dev, 1);
1690 return 0;
1693 * The PC speaker port is mono. If we get a stereo gain value
1694 * passed in, then we return EINVAL.
1696 case ESS_PCSPEAKER_VOL:
1697 if (cp->un.value.num_channels != 1)
1698 return EINVAL;
1700 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
1701 ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1702 ess_set_gain(sc, cp->dev, 1);
1703 return 0;
1705 case ESS_RECORD_SOURCE:
1706 if (ESS_USE_AUDIO1(sc->sc_model)) {
1707 if (cp->type == AUDIO_MIXER_ENUM)
1708 return ess_set_in_port(sc, cp->un.ord);
1709 else
1710 return EINVAL;
1711 } else {
1712 if (cp->type == AUDIO_MIXER_SET)
1713 return ess_set_in_ports(sc, cp->un.mask);
1714 else
1715 return EINVAL;
1717 return 0;
1719 case ESS_RECORD_MONITOR:
1720 if (cp->type != AUDIO_MIXER_ENUM)
1721 return EINVAL;
1723 if (cp->un.ord)
1724 /* Enable monitor */
1725 ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1726 ESS_AUDIO_CTRL_MONITOR);
1727 else
1728 /* Disable monitor */
1729 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1730 ESS_AUDIO_CTRL_MONITOR);
1731 return 0;
1734 if (ESS_USE_AUDIO1(sc->sc_model))
1735 return EINVAL;
1737 switch (cp->dev) {
1738 case ESS_DAC_REC_VOL:
1739 case ESS_MIC_REC_VOL:
1740 case ESS_LINE_REC_VOL:
1741 case ESS_SYNTH_REC_VOL:
1742 case ESS_CD_REC_VOL:
1743 case ESS_AUXB_REC_VOL:
1744 if (cp->type != AUDIO_MIXER_VALUE)
1745 return EINVAL;
1747 switch (cp->un.value.num_channels) {
1748 case 1:
1749 lgain = rgain = ESS_4BIT_GAIN(
1750 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1751 break;
1752 case 2:
1753 lgain = ESS_4BIT_GAIN(
1754 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1755 rgain = ESS_4BIT_GAIN(
1756 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1757 break;
1758 default:
1759 return EINVAL;
1762 sc->gain[cp->dev][ESS_LEFT] = lgain;
1763 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1764 ess_set_gain(sc, cp->dev, 1);
1765 return 0;
1767 case ESS_MIC_PREAMP:
1768 if (cp->type != AUDIO_MIXER_ENUM)
1769 return EINVAL;
1771 if (cp->un.ord)
1772 /* Enable microphone preamp */
1773 ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1774 ESS_PREAMP_CTRL_ENABLE);
1775 else
1776 /* Disable microphone preamp */
1777 ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1778 ESS_PREAMP_CTRL_ENABLE);
1779 return 0;
1782 return EINVAL;
1786 ess_get_port(void *addr, mixer_ctrl_t *cp)
1788 struct ess_softc *sc;
1790 sc = addr;
1791 DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
1793 switch (cp->dev) {
1794 case ESS_MASTER_VOL:
1795 case ESS_DAC_PLAY_VOL:
1796 case ESS_MIC_PLAY_VOL:
1797 case ESS_LINE_PLAY_VOL:
1798 case ESS_SYNTH_PLAY_VOL:
1799 case ESS_CD_PLAY_VOL:
1800 case ESS_AUXB_PLAY_VOL:
1801 case ESS_RECORD_VOL:
1802 switch (cp->un.value.num_channels) {
1803 case 1:
1804 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1805 sc->gain[cp->dev][ESS_LEFT];
1806 break;
1807 case 2:
1808 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1809 sc->gain[cp->dev][ESS_LEFT];
1810 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1811 sc->gain[cp->dev][ESS_RIGHT];
1812 break;
1813 default:
1814 return EINVAL;
1816 return 0;
1818 case ESS_PCSPEAKER_VOL:
1819 if (cp->un.value.num_channels != 1)
1820 return EINVAL;
1822 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1823 sc->gain[cp->dev][ESS_LEFT];
1824 return 0;
1826 case ESS_RECORD_SOURCE:
1827 if (ESS_USE_AUDIO1(sc->sc_model))
1828 cp->un.ord = sc->in_port;
1829 else
1830 cp->un.mask = sc->in_mask;
1831 return 0;
1833 case ESS_RECORD_MONITOR:
1834 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
1835 ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
1836 return 0;
1839 if (ESS_USE_AUDIO1(sc->sc_model))
1840 return EINVAL;
1842 switch (cp->dev) {
1843 case ESS_DAC_REC_VOL:
1844 case ESS_MIC_REC_VOL:
1845 case ESS_LINE_REC_VOL:
1846 case ESS_SYNTH_REC_VOL:
1847 case ESS_CD_REC_VOL:
1848 case ESS_AUXB_REC_VOL:
1849 switch (cp->un.value.num_channels) {
1850 case 1:
1851 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1852 sc->gain[cp->dev][ESS_LEFT];
1853 break;
1854 case 2:
1855 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1856 sc->gain[cp->dev][ESS_LEFT];
1857 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1858 sc->gain[cp->dev][ESS_RIGHT];
1859 break;
1860 default:
1861 return EINVAL;
1863 return 0;
1865 case ESS_MIC_PREAMP:
1866 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
1867 ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
1868 return 0;
1871 return EINVAL;
1875 ess_query_devinfo(void *addr, mixer_devinfo_t *dip)
1877 struct ess_softc *sc;
1879 sc = addr;
1880 DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
1881 sc->sc_model, dip->index));
1884 * REVISIT: There are some slight differences between the
1885 * mixers on the different ESS chips, which can
1886 * be sorted out using the chip model rather than a
1887 * separate mixer model.
1888 * This is currently coded assuming an ES1887; we
1889 * need to work out which bits are not applicable to
1890 * the other models (1888 and 888).
1892 switch (dip->index) {
1893 case ESS_DAC_PLAY_VOL:
1894 dip->mixer_class = ESS_INPUT_CLASS;
1895 dip->next = dip->prev = AUDIO_MIXER_LAST;
1896 strcpy(dip->label.name, AudioNdac);
1897 dip->type = AUDIO_MIXER_VALUE;
1898 dip->un.v.num_channels = 2;
1899 strcpy(dip->un.v.units.name, AudioNvolume);
1900 return 0;
1902 case ESS_MIC_PLAY_VOL:
1903 dip->mixer_class = ESS_INPUT_CLASS;
1904 dip->prev = AUDIO_MIXER_LAST;
1905 if (ESS_USE_AUDIO1(sc->sc_model))
1906 dip->next = AUDIO_MIXER_LAST;
1907 else
1908 dip->next = ESS_MIC_PREAMP;
1909 strcpy(dip->label.name, AudioNmicrophone);
1910 dip->type = AUDIO_MIXER_VALUE;
1911 dip->un.v.num_channels = 2;
1912 strcpy(dip->un.v.units.name, AudioNvolume);
1913 return 0;
1915 case ESS_LINE_PLAY_VOL:
1916 dip->mixer_class = ESS_INPUT_CLASS;
1917 dip->next = dip->prev = AUDIO_MIXER_LAST;
1918 strcpy(dip->label.name, AudioNline);
1919 dip->type = AUDIO_MIXER_VALUE;
1920 dip->un.v.num_channels = 2;
1921 strcpy(dip->un.v.units.name, AudioNvolume);
1922 return 0;
1924 case ESS_SYNTH_PLAY_VOL:
1925 dip->mixer_class = ESS_INPUT_CLASS;
1926 dip->next = dip->prev = AUDIO_MIXER_LAST;
1927 strcpy(dip->label.name, AudioNfmsynth);
1928 dip->type = AUDIO_MIXER_VALUE;
1929 dip->un.v.num_channels = 2;
1930 strcpy(dip->un.v.units.name, AudioNvolume);
1931 return 0;
1933 case ESS_CD_PLAY_VOL:
1934 dip->mixer_class = ESS_INPUT_CLASS;
1935 dip->next = dip->prev = AUDIO_MIXER_LAST;
1936 strcpy(dip->label.name, AudioNcd);
1937 dip->type = AUDIO_MIXER_VALUE;
1938 dip->un.v.num_channels = 2;
1939 strcpy(dip->un.v.units.name, AudioNvolume);
1940 return 0;
1942 case ESS_AUXB_PLAY_VOL:
1943 dip->mixer_class = ESS_INPUT_CLASS;
1944 dip->next = dip->prev = AUDIO_MIXER_LAST;
1945 strcpy(dip->label.name, "auxb");
1946 dip->type = AUDIO_MIXER_VALUE;
1947 dip->un.v.num_channels = 2;
1948 strcpy(dip->un.v.units.name, AudioNvolume);
1949 return 0;
1951 case ESS_INPUT_CLASS:
1952 dip->mixer_class = ESS_INPUT_CLASS;
1953 dip->next = dip->prev = AUDIO_MIXER_LAST;
1954 strcpy(dip->label.name, AudioCinputs);
1955 dip->type = AUDIO_MIXER_CLASS;
1956 return 0;
1958 case ESS_MASTER_VOL:
1959 dip->mixer_class = ESS_OUTPUT_CLASS;
1960 dip->next = dip->prev = AUDIO_MIXER_LAST;
1961 strcpy(dip->label.name, AudioNmaster);
1962 dip->type = AUDIO_MIXER_VALUE;
1963 dip->un.v.num_channels = 2;
1964 strcpy(dip->un.v.units.name, AudioNvolume);
1965 return 0;
1967 case ESS_PCSPEAKER_VOL:
1968 dip->mixer_class = ESS_OUTPUT_CLASS;
1969 dip->next = dip->prev = AUDIO_MIXER_LAST;
1970 strcpy(dip->label.name, "pc_speaker");
1971 dip->type = AUDIO_MIXER_VALUE;
1972 dip->un.v.num_channels = 1;
1973 strcpy(dip->un.v.units.name, AudioNvolume);
1974 return 0;
1976 case ESS_OUTPUT_CLASS:
1977 dip->mixer_class = ESS_OUTPUT_CLASS;
1978 dip->next = dip->prev = AUDIO_MIXER_LAST;
1979 strcpy(dip->label.name, AudioCoutputs);
1980 dip->type = AUDIO_MIXER_CLASS;
1981 return 0;
1983 case ESS_RECORD_VOL:
1984 dip->mixer_class = ESS_RECORD_CLASS;
1985 dip->next = dip->prev = AUDIO_MIXER_LAST;
1986 strcpy(dip->label.name, AudioNrecord);
1987 dip->type = AUDIO_MIXER_VALUE;
1988 dip->un.v.num_channels = 2;
1989 strcpy(dip->un.v.units.name, AudioNvolume);
1990 return 0;
1992 case ESS_RECORD_SOURCE:
1993 dip->mixer_class = ESS_RECORD_CLASS;
1994 dip->next = dip->prev = AUDIO_MIXER_LAST;
1995 strcpy(dip->label.name, AudioNsource);
1996 if (ESS_USE_AUDIO1(sc->sc_model)) {
1998 * The 1788 doesn't use the input mixer control that
1999 * the 1888 uses, because it's a pain when you only
2000 * have one mixer.
2001 * Perhaps it could be emulated by keeping both sets of
2002 * gain values, and doing a `context switch' of the
2003 * mixer registers when shifting from playing to
2004 * recording.
2006 dip->type = AUDIO_MIXER_ENUM;
2007 dip->un.e.num_mem = 4;
2008 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
2009 dip->un.e.member[0].ord = ESS_SOURCE_MIC;
2010 strcpy(dip->un.e.member[1].label.name, AudioNline);
2011 dip->un.e.member[1].ord = ESS_SOURCE_LINE;
2012 strcpy(dip->un.e.member[2].label.name, AudioNcd);
2013 dip->un.e.member[2].ord = ESS_SOURCE_CD;
2014 strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
2015 dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
2016 } else {
2017 dip->type = AUDIO_MIXER_SET;
2018 dip->un.s.num_mem = 6;
2019 strcpy(dip->un.s.member[0].label.name, AudioNdac);
2020 dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
2021 strcpy(dip->un.s.member[1].label.name, AudioNmicrophone);
2022 dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
2023 strcpy(dip->un.s.member[2].label.name, AudioNline);
2024 dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
2025 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
2026 dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
2027 strcpy(dip->un.s.member[4].label.name, AudioNcd);
2028 dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
2029 strcpy(dip->un.s.member[5].label.name, "auxb");
2030 dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
2032 return 0;
2034 case ESS_RECORD_CLASS:
2035 dip->mixer_class = ESS_RECORD_CLASS;
2036 dip->next = dip->prev = AUDIO_MIXER_LAST;
2037 strcpy(dip->label.name, AudioCrecord);
2038 dip->type = AUDIO_MIXER_CLASS;
2039 return 0;
2041 case ESS_RECORD_MONITOR:
2042 dip->prev = dip->next = AUDIO_MIXER_LAST;
2043 strcpy(dip->label.name, AudioNmute);
2044 dip->type = AUDIO_MIXER_ENUM;
2045 dip->mixer_class = ESS_MONITOR_CLASS;
2046 dip->un.e.num_mem = 2;
2047 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2048 dip->un.e.member[0].ord = 0;
2049 strcpy(dip->un.e.member[1].label.name, AudioNon);
2050 dip->un.e.member[1].ord = 1;
2051 return 0;
2053 case ESS_MONITOR_CLASS:
2054 dip->mixer_class = ESS_MONITOR_CLASS;
2055 dip->next = dip->prev = AUDIO_MIXER_LAST;
2056 strcpy(dip->label.name, AudioCmonitor);
2057 dip->type = AUDIO_MIXER_CLASS;
2058 return 0;
2061 if (ESS_USE_AUDIO1(sc->sc_model))
2062 return ENXIO;
2064 switch (dip->index) {
2065 case ESS_DAC_REC_VOL:
2066 dip->mixer_class = ESS_RECORD_CLASS;
2067 dip->next = dip->prev = AUDIO_MIXER_LAST;
2068 strcpy(dip->label.name, AudioNdac);
2069 dip->type = AUDIO_MIXER_VALUE;
2070 dip->un.v.num_channels = 2;
2071 strcpy(dip->un.v.units.name, AudioNvolume);
2072 return 0;
2074 case ESS_MIC_REC_VOL:
2075 dip->mixer_class = ESS_RECORD_CLASS;
2076 dip->next = dip->prev = AUDIO_MIXER_LAST;
2077 strcpy(dip->label.name, AudioNmicrophone);
2078 dip->type = AUDIO_MIXER_VALUE;
2079 dip->un.v.num_channels = 2;
2080 strcpy(dip->un.v.units.name, AudioNvolume);
2081 return 0;
2083 case ESS_LINE_REC_VOL:
2084 dip->mixer_class = ESS_RECORD_CLASS;
2085 dip->next = dip->prev = AUDIO_MIXER_LAST;
2086 strcpy(dip->label.name, AudioNline);
2087 dip->type = AUDIO_MIXER_VALUE;
2088 dip->un.v.num_channels = 2;
2089 strcpy(dip->un.v.units.name, AudioNvolume);
2090 return 0;
2092 case ESS_SYNTH_REC_VOL:
2093 dip->mixer_class = ESS_RECORD_CLASS;
2094 dip->next = dip->prev = AUDIO_MIXER_LAST;
2095 strcpy(dip->label.name, AudioNfmsynth);
2096 dip->type = AUDIO_MIXER_VALUE;
2097 dip->un.v.num_channels = 2;
2098 strcpy(dip->un.v.units.name, AudioNvolume);
2099 return 0;
2101 case ESS_CD_REC_VOL:
2102 dip->mixer_class = ESS_RECORD_CLASS;
2103 dip->next = dip->prev = AUDIO_MIXER_LAST;
2104 strcpy(dip->label.name, AudioNcd);
2105 dip->type = AUDIO_MIXER_VALUE;
2106 dip->un.v.num_channels = 2;
2107 strcpy(dip->un.v.units.name, AudioNvolume);
2108 return 0;
2110 case ESS_AUXB_REC_VOL:
2111 dip->mixer_class = ESS_RECORD_CLASS;
2112 dip->next = dip->prev = AUDIO_MIXER_LAST;
2113 strcpy(dip->label.name, "auxb");
2114 dip->type = AUDIO_MIXER_VALUE;
2115 dip->un.v.num_channels = 2;
2116 strcpy(dip->un.v.units.name, AudioNvolume);
2117 return 0;
2119 case ESS_MIC_PREAMP:
2120 dip->mixer_class = ESS_INPUT_CLASS;
2121 dip->prev = ESS_MIC_PLAY_VOL;
2122 dip->next = AUDIO_MIXER_LAST;
2123 strcpy(dip->label.name, AudioNpreamp);
2124 dip->type = AUDIO_MIXER_ENUM;
2125 dip->un.e.num_mem = 2;
2126 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2127 dip->un.e.member[0].ord = 0;
2128 strcpy(dip->un.e.member[1].label.name, AudioNon);
2129 dip->un.e.member[1].ord = 1;
2130 return 0;
2133 return ENXIO;
2136 void *
2137 ess_malloc(void *addr, int direction, size_t size,
2138 struct malloc_type *pool, int flags)
2140 struct ess_softc *sc;
2141 int drq;
2143 sc = addr;
2144 if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
2145 drq = sc->sc_audio2.drq;
2146 else
2147 drq = sc->sc_audio1.drq;
2148 return (isa_malloc(sc->sc_ic, drq, size, pool, flags));
2151 void
2152 ess_free(void *addr, void *ptr, struct malloc_type *pool)
2155 isa_free(ptr, pool);
2158 size_t
2159 ess_round_buffersize(void *addr, int direction, size_t size)
2161 struct ess_softc *sc;
2162 bus_size_t maxsize;
2164 sc = addr;
2165 if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
2166 maxsize = sc->sc_audio2.maxsize;
2167 else
2168 maxsize = sc->sc_audio1.maxsize;
2170 if (size > maxsize)
2171 size = maxsize;
2172 return size;
2175 paddr_t
2176 ess_mappage(void *addr, void *mem, off_t off, int prot)
2179 return isa_mappage(mem, off, prot);
2183 ess_1788_get_props(void *addr)
2186 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT;
2190 ess_1888_get_props(void *addr)
2193 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
2196 /* ============================================
2197 * Generic functions for ess, not used by audio h/w i/f
2198 * =============================================
2202 * Reset the chip.
2203 * Return non-zero if the chip isn't detected.
2206 ess_reset(struct ess_softc *sc)
2208 bus_space_tag_t iot;
2209 bus_space_handle_t ioh;
2211 iot = sc->sc_iot;
2212 ioh = sc->sc_ioh;
2213 sc->sc_audio1.active = 0;
2214 sc->sc_audio2.active = 0;
2216 EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
2217 delay(10000); /* XXX shouldn't delay so long */
2218 EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
2219 if (ess_rdsp(sc) != ESS_MAGIC)
2220 return 1;
2222 /* Enable access to the ESS extension commands. */
2223 ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
2225 return 0;
2228 void
2229 ess_set_gain(struct ess_softc *sc, int port, int on)
2231 int gain, left, right;
2232 int mix;
2233 int src;
2234 int stereo;
2237 * Most gain controls are found in the mixer registers and
2238 * are stereo. Any that are not, must set mix and stereo as
2239 * required.
2241 mix = 1;
2242 stereo = 1;
2244 switch (port) {
2245 case ESS_MASTER_VOL:
2246 src = ESS_MREG_VOLUME_MASTER;
2247 break;
2248 case ESS_DAC_PLAY_VOL:
2249 if (ESS_USE_AUDIO1(sc->sc_model))
2250 src = ESS_MREG_VOLUME_VOICE;
2251 else
2252 src = 0x7C;
2253 break;
2254 case ESS_MIC_PLAY_VOL:
2255 src = ESS_MREG_VOLUME_MIC;
2256 break;
2257 case ESS_LINE_PLAY_VOL:
2258 src = ESS_MREG_VOLUME_LINE;
2259 break;
2260 case ESS_SYNTH_PLAY_VOL:
2261 src = ESS_MREG_VOLUME_SYNTH;
2262 break;
2263 case ESS_CD_PLAY_VOL:
2264 src = ESS_MREG_VOLUME_CD;
2265 break;
2266 case ESS_AUXB_PLAY_VOL:
2267 src = ESS_MREG_VOLUME_AUXB;
2268 break;
2269 case ESS_PCSPEAKER_VOL:
2270 src = ESS_MREG_VOLUME_PCSPKR;
2271 stereo = 0;
2272 break;
2273 case ESS_DAC_REC_VOL:
2274 src = 0x69;
2275 break;
2276 case ESS_MIC_REC_VOL:
2277 src = 0x68;
2278 break;
2279 case ESS_LINE_REC_VOL:
2280 src = 0x6E;
2281 break;
2282 case ESS_SYNTH_REC_VOL:
2283 src = 0x6B;
2284 break;
2285 case ESS_CD_REC_VOL:
2286 src = 0x6A;
2287 break;
2288 case ESS_AUXB_REC_VOL:
2289 src = 0x6C;
2290 break;
2291 case ESS_RECORD_VOL:
2292 src = ESS_XCMD_VOLIN_CTRL;
2293 mix = 0;
2294 break;
2295 default:
2296 return;
2299 /* 1788 doesn't have a separate recording mixer */
2300 if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
2301 return;
2303 if (on) {
2304 left = sc->gain[port][ESS_LEFT];
2305 right = sc->gain[port][ESS_RIGHT];
2306 } else {
2307 left = right = 0;
2310 if (stereo)
2311 gain = ESS_STEREO_GAIN(left, right);
2312 else
2313 gain = ESS_MONO_GAIN(left);
2315 if (mix)
2316 ess_write_mix_reg(sc, src, gain);
2317 else
2318 ess_write_x_reg(sc, src, gain);
2321 /* Set the input device on devices without an input mixer. */
2323 ess_set_in_port(struct ess_softc *sc, int ord)
2325 mixer_devinfo_t di;
2326 int i;
2328 DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
2331 * Get the device info for the record source control,
2332 * including the list of available sources.
2334 di.index = ESS_RECORD_SOURCE;
2335 if (ess_query_devinfo(sc, &di))
2336 return EINVAL;
2338 /* See if the given ord value was anywhere in the list. */
2339 for (i = 0; i < di.un.e.num_mem; i++) {
2340 if (ord == di.un.e.member[i].ord)
2341 break;
2343 if (i == di.un.e.num_mem)
2344 return EINVAL;
2346 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
2348 sc->in_port = ord;
2349 return 0;
2352 /* Set the input device levels on input-mixer-enabled devices. */
2354 ess_set_in_ports(struct ess_softc *sc, int mask)
2356 mixer_devinfo_t di;
2357 int i, port;
2359 DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
2362 * Get the device info for the record source control,
2363 * including the list of available sources.
2365 di.index = ESS_RECORD_SOURCE;
2366 if (ess_query_devinfo(sc, &di))
2367 return EINVAL;
2370 * Set or disable the record volume control for each of the
2371 * possible sources.
2373 for (i = 0; i < di.un.s.num_mem; i++) {
2375 * Calculate the source port number from its mask.
2377 port = ffs(di.un.s.member[i].mask);
2380 * Set the source gain:
2381 * to the current value if source is enabled
2382 * to zero if source is disabled
2384 ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
2387 sc->in_mask = mask;
2388 return 0;
2391 void
2392 ess_speaker_on(struct ess_softc *sc)
2395 /* Unmute the DAC. */
2396 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
2399 void
2400 ess_speaker_off(struct ess_softc *sc)
2403 /* Mute the DAC. */
2404 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
2408 * Calculate the time constant for the requested sampling rate.
2410 u_int
2411 ess_srtotc(u_int rate)
2413 u_int tc;
2415 /* The following formulae are from the ESS data sheet. */
2416 if (rate <= 22050)
2417 tc = 128 - 397700L / rate;
2418 else
2419 tc = 256 - 795500L / rate;
2421 return tc;
2426 * Calculate the filter constant for the reuqested sampling rate.
2428 u_int
2429 ess_srtofc(u_int rate)
2432 * The following formula is derived from the information in
2433 * the ES1887 data sheet, based on a roll-off frequency of
2434 * 87%.
2436 return 256 - 200279L / rate;
2441 * Return the status of the DSP.
2443 u_char
2444 ess_get_dsp_status(struct ess_softc *sc)
2446 return EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
2451 * Return the read status of the DSP: 1 -> DSP ready for reading
2452 * 0 -> DSP not ready for reading
2454 u_char
2455 ess_dsp_read_ready(struct ess_softc *sc)
2458 return (ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0;
2463 * Return the write status of the DSP: 1 -> DSP ready for writing
2464 * 0 -> DSP not ready for writing
2466 u_char
2467 ess_dsp_write_ready(struct ess_softc *sc)
2469 return (ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1;
2474 * Read a byte from the DSP.
2477 ess_rdsp(struct ess_softc *sc)
2479 bus_space_tag_t iot;
2480 bus_space_handle_t ioh;
2481 int i;
2483 iot = sc->sc_iot;
2484 ioh = sc->sc_ioh;
2485 for (i = ESS_READ_TIMEOUT; i > 0; --i) {
2486 if (ess_dsp_read_ready(sc)) {
2487 i = EREAD1(iot, ioh, ESS_DSP_READ);
2488 DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
2489 return i;
2490 } else
2491 delay(10);
2494 DPRINTF(("ess_rdsp: timed out\n"));
2495 return -1;
2499 * Write a byte to the DSP.
2502 ess_wdsp(struct ess_softc *sc, u_char v)
2504 bus_space_tag_t iot;
2505 bus_space_handle_t ioh;
2506 int i;
2508 DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
2510 iot = sc->sc_iot;
2511 ioh = sc->sc_ioh;
2512 for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
2513 if (ess_dsp_write_ready(sc)) {
2514 EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
2515 return 0;
2516 } else
2517 delay(10);
2520 DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
2521 return -1;
2525 * Write a value to one of the ESS extended registers.
2528 ess_write_x_reg(struct ess_softc *sc, u_char reg, u_char val)
2530 int error;
2532 DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
2533 if ((error = ess_wdsp(sc, reg)) == 0)
2534 error = ess_wdsp(sc, val);
2536 return error;
2540 * Read the value of one of the ESS extended registers.
2542 u_char
2543 ess_read_x_reg(struct ess_softc *sc, u_char reg)
2545 int error;
2546 int val;
2548 if ((error = ess_wdsp(sc, 0xC0)) == 0)
2549 error = ess_wdsp(sc, reg);
2550 if (error) {
2551 DPRINTF(("Error reading extended register 0x%02x\n", reg));
2553 /* REVISIT: what if an error is returned above? */
2554 val = ess_rdsp(sc);
2555 DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
2556 return val;
2559 void
2560 ess_clear_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2562 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1) {
2563 DPRINTF(("Error clearing bits in extended register 0x%02x\n",
2564 reg));
2568 void
2569 ess_set_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2571 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1) {
2572 DPRINTF(("Error setting bits in extended register 0x%02x\n",
2573 reg));
2579 * Write a value to one of the ESS mixer registers.
2581 void
2582 ess_write_mix_reg(struct ess_softc *sc, u_char reg, u_char val)
2584 bus_space_tag_t iot;
2585 bus_space_handle_t ioh;
2586 int s;
2588 DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
2590 iot = sc->sc_iot;
2591 ioh = sc->sc_ioh;
2592 s = splaudio();
2593 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2594 EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
2595 splx(s);
2599 * Read the value of one of the ESS mixer registers.
2601 u_char
2602 ess_read_mix_reg(struct ess_softc *sc, u_char reg)
2604 bus_space_tag_t iot;
2605 bus_space_handle_t ioh;
2606 int s;
2607 u_char val;
2609 iot = sc->sc_iot;
2610 ioh = sc->sc_ioh;
2611 s = splaudio();
2612 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2613 val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
2614 splx(s);
2616 DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
2617 return val;
2620 void
2621 ess_clear_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2624 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
2627 void
2628 ess_set_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2631 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
2634 void
2635 ess_read_multi_mix_reg(struct ess_softc *sc, u_char reg,
2636 uint8_t *datap, bus_size_t count)
2638 bus_space_tag_t iot;
2639 bus_space_handle_t ioh;
2640 int s;
2642 iot = sc->sc_iot;
2643 ioh = sc->sc_ioh;
2644 s = splaudio();
2645 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2646 bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
2647 splx(s);