1 /* $OpenBSD: ess.c,v 1.33 2022/11/02 10:41:34 kn Exp $ */
2 /* $NetBSD: ess.c,v 1.44.4.1 1999/06/21 01:18:00 thorpej Exp $ */
3
4 /*
5 * Copyright 1997
6 * Digital Equipment Corporation. All rights reserved.
7 *
8 * This software is furnished under license and may be used and
9 * copied only in accordance with the following terms and conditions.
10 * Subject to these conditions, you may download, copy, install,
11 * use, modify and distribute this software in source and/or binary
12 * form. No title or ownership is transferred hereby.
13 *
14 * 1) Any source code used, modified or distributed must reproduce
15 * and retain this copyright notice and list of conditions as
16 * they appear in the source file.
17 *
18 * 2) No right is granted to use any trade name, trademark, or logo of
19 * Digital Equipment Corporation. Neither the "Digital Equipment
20 * Corporation" name nor any trademark or logo of Digital Equipment
21 * Corporation may be used to endorse or promote products derived
22 * from this software without the prior written permission of
23 * Digital Equipment Corporation.
24 *
25 * 3) This software is provided "AS-IS" and any express or implied
26 * warranties, including but not limited to, any implied warranties
27 * of merchantability, fitness for a particular purpose, or
28 * non-infringement are disclaimed. In no event shall DIGITAL be
29 * liable for any damages whatsoever, and in particular, DIGITAL
30 * shall not be liable for special, indirect, consequential, or
31 * incidental damages or damages for lost profits, loss of
32 * revenue or loss of use, whether such damages arise in contract,
33 * negligence, tort, under statute, in equity, at law or otherwise,
34 * even if advised of the possibility of such damage.
35 */
36
37 /*
38 **++
39 **
40 ** ess.c
41 **
42 ** FACILITY:
43 **
44 ** DIGITAL Network Appliance Reference Design (DNARD)
45 **
46 ** MODULE DESCRIPTION:
47 **
48 ** This module contains the device driver for the ESS
49 ** Technologies 1888/1887/888 sound chip. The code in sbdsp.c was
50 ** used as a reference point when implementing this driver.
51 **
52 ** AUTHORS:
53 **
54 ** Blair Fidler Software Engineering Australia
55 ** Gold Coast, Australia.
56 **
57 ** CREATION DATE:
58 **
59 ** March 10, 1997.
60 **
61 ** MODIFICATION HISTORY:
62 **
63 ** Heavily modified by Lennart Augustsson and Charles M. Hannum for
64 ** bus_dma, changes to audio interface, and many bug fixes.
65 ** ESS1788 support by Nathan J. Williams and Charles M. Hannum.
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/kernel.h>
76 #include <sys/timeout.h>
77 #include <sys/fcntl.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
86 #include <dev/isa/isavar.h>
87 #include <dev/isa/isadmavar.h>
88
89 #include <dev/isa/essvar.h>
90 #include <dev/isa/essreg.h>
91
92 #ifdef AUDIO_DEBUG
93 #define DPRINTF(x) if (essdebug) printf x
94 #define DPRINTFN(n,x) if (essdebug>(n)) printf x
95 int essdebug = 0;
96 #else
97 #define DPRINTF(x)
98 #define DPRINTFN(n,x)
99 #endif
100
101 #if 0
102 unsigned uuu;
103 #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu)
104 #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d))
105 #else
106 #define EREAD1(t, h, a) bus_space_read_1(t, h, a)
107 #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d)
108 #endif
109
110 struct cfdriver ess_cd = {
111 NULL, "ess", DV_DULL
112 };
113
114 struct audio_params ess_audio_default =
115 {44100, AUDIO_ENCODING_SLINEAR_LE, 16, 2, 1, 2};
116
117 int ess_setup_sc(struct ess_softc *, int);
118
119 int ess_1788_open(void *, int);
120 int ess_open(void *, int);
121 void ess_1788_close(void *);
122 void ess_1888_close(void *);
123
124 int ess_set_params(void *, int, int, struct audio_params *,
125 struct audio_params *);
126
127 int ess_round_blocksize(void *, int);
128
129 int ess_audio1_trigger_output(void *, void *, void *, int,
130 void (*)(void *), void *, struct audio_params *);
131 int ess_audio2_trigger_output(void *, void *, void *, int,
132 void (*)(void *), void *, struct audio_params *);
133 int ess_audio1_trigger_input(void *, void *, void *, int,
134 void (*)(void *), void *, struct audio_params *);
135 int ess_audio1_halt(void *);
136 int ess_audio2_halt(void *);
137 int ess_audio1_intr(void *);
138 int ess_audio2_intr(void *);
139 void ess_audio1_poll(void *);
140 void ess_audio2_poll(void *);
141
142 int ess_speaker_ctl(void *, int);
143
144 int ess_set_port(void *, mixer_ctrl_t *);
145 int ess_get_port(void *, mixer_ctrl_t *);
146
147 void *ess_malloc(void *, int, size_t, int, int);
148 void ess_free(void *, void *, int);
149 size_t ess_round_buffersize(void *, int, size_t);
150
151
152 int ess_query_devinfo(void *, mixer_devinfo_t *);
153
154 void ess_speaker_on(struct ess_softc *);
155 void ess_speaker_off(struct ess_softc *);
156
157 int ess_config_addr(struct ess_softc *);
158 void ess_config_irq(struct ess_softc *);
159 void ess_config_drq(struct ess_softc *);
160 void ess_setup(struct ess_softc *);
161 int ess_identify(struct ess_softc *);
162
163 int ess_reset(struct ess_softc *);
164 void ess_set_gain(struct ess_softc *, int, int);
165 int ess_set_in_port(struct ess_softc *, int);
166 int ess_set_in_ports(struct ess_softc *, int);
167 u_int ess_srtotc(u_int);
168 u_int ess_srtofc(u_int);
169 u_char ess_get_dsp_status(struct ess_softc *);
170 u_char ess_dsp_read_ready(struct ess_softc *);
171 u_char ess_dsp_write_ready(struct ess_softc *);
172 int ess_rdsp(struct ess_softc *);
173 int ess_wdsp(struct ess_softc *, u_char);
174 u_char ess_read_x_reg(struct ess_softc *, u_char);
175 int ess_write_x_reg(struct ess_softc *, u_char, u_char);
176 void ess_clear_xreg_bits(struct ess_softc *, u_char, u_char);
177 void ess_set_xreg_bits(struct ess_softc *, u_char, u_char);
178 u_char ess_read_mix_reg(struct ess_softc *, u_char);
179 void ess_write_mix_reg(struct ess_softc *, u_char, u_char);
180 void ess_clear_mreg_bits(struct ess_softc *, u_char, u_char);
181 void ess_set_mreg_bits(struct ess_softc *, u_char, u_char);
182 void ess_read_multi_mix_reg(struct ess_softc *, u_char, u_int8_t *, bus_size_t);
183
184 static const char *essmodel[] = {
185 "unsupported",
186 "1888",
187 "1887",
188 "888",
189 "1788",
190 "1869",
191 "1879",
192 "1868",
193 "1878",
194 };
195
196 /*
197 * Define our interface to the higher level audio driver.
198 */
199
200 const struct audio_hw_if ess_1788_hw_if = {
201 .open = ess_1788_open,
202 .close = ess_1788_close,
203 .set_params = ess_set_params,
204 .round_blocksize = ess_round_blocksize,
205 .halt_output = ess_audio1_halt,
206 .halt_input = ess_audio1_halt,
207 .set_port = ess_set_port,
208 .get_port = ess_get_port,
209 .query_devinfo = ess_query_devinfo,
210 .allocm = ess_malloc,
211 .freem = ess_free,
212 .round_buffersize = ess_round_buffersize,
213 .trigger_output = ess_audio1_trigger_output,
214 .trigger_input = ess_audio1_trigger_input,
215 };
216
217 const struct audio_hw_if ess_1888_hw_if = {
218 .open = ess_open,
219 .close = ess_1888_close,
220 .set_params = ess_set_params,
221 .round_blocksize = ess_round_blocksize,
222 .halt_output = ess_audio2_halt,
223 .halt_input = ess_audio1_halt,
224 .set_port = ess_set_port,
225 .get_port = ess_get_port,
226 .query_devinfo = ess_query_devinfo,
227 .allocm = ess_malloc,
228 .freem = ess_free,
229 .round_buffersize = ess_round_buffersize,
230 .trigger_output = ess_audio2_trigger_output,
231 .trigger_input = ess_audio1_trigger_input,
232 };
233
234 #ifdef AUDIO_DEBUG
235 void ess_printsc(struct ess_softc *);
236 void ess_dump_mixer(struct ess_softc *);
237
238 void
ess_printsc(struct ess_softc * sc)239 ess_printsc(struct ess_softc *sc)
240 {
241 int i;
242
243 printf("open %d iobase 0x%x outport %u inport %u speaker %s\n",
244 (int)sc->sc_open, sc->sc_iobase, sc->out_port,
245 sc->in_port, sc->spkr_state ? "on" : "off");
246
247 printf("audio1: dmachan %d irq %d nintr %lu intr %p arg %p\n",
248 sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
249 sc->sc_audio1.intr, sc->sc_audio1.arg);
250
251 if (!ESS_USE_AUDIO1(sc->sc_model)) {
252 printf("audio2: dmachan %d irq %d nintr %lu intr %p arg %p\n",
253 sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
254 sc->sc_audio2.intr, sc->sc_audio2.arg);
255 }
256
257 printf("gain:");
258 for (i = 0; i < sc->ndevs; i++)
259 printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
260 printf("\n");
261 }
262
263 void
ess_dump_mixer(struct ess_softc * sc)264 ess_dump_mixer(struct ess_softc *sc)
265 {
266 printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
267 0x7C, ess_read_mix_reg(sc, 0x7C));
268 printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
269 0x1A, ess_read_mix_reg(sc, 0x1A));
270 printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
271 0x3E, ess_read_mix_reg(sc, 0x3E));
272 printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
273 0x36, ess_read_mix_reg(sc, 0x36));
274 printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
275 0x38, ess_read_mix_reg(sc, 0x38));
276 printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
277 0x3A, ess_read_mix_reg(sc, 0x3A));
278 printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
279 0x32, ess_read_mix_reg(sc, 0x32));
280 printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
281 0x3C, ess_read_mix_reg(sc, 0x3C));
282 printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
283 0x69, ess_read_mix_reg(sc, 0x69));
284 printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
285 0x68, ess_read_mix_reg(sc, 0x68));
286 printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
287 0x6E, ess_read_mix_reg(sc, 0x6E));
288 printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
289 0x6B, ess_read_mix_reg(sc, 0x6B));
290 printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
291 0x6A, ess_read_mix_reg(sc, 0x6A));
292 printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
293 0x6C, ess_read_mix_reg(sc, 0x6C));
294 printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
295 0xB4, ess_read_x_reg(sc, 0xB4));
296 printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
297 0x14, ess_read_mix_reg(sc, 0x14));
298
299 printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
300 ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
301 printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
302 ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
303 printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
304 ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
305 ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
306 }
307
308 #endif
309
310 /*
311 * Configure the ESS chip for the desired audio base address.
312 */
313 int
ess_config_addr(struct ess_softc * sc)314 ess_config_addr(struct ess_softc *sc)
315 {
316 int iobase = sc->sc_iobase;
317 bus_space_tag_t iot = sc->sc_iot;
318
319 /*
320 * Configure using the System Control Register method. This
321 * method is used when the AMODE line is tied high, which is
322 * the case for the Shark, but not for the evaluation board.
323 */
324
325 bus_space_handle_t scr_access_ioh;
326 bus_space_handle_t scr_ioh;
327 u_short scr_value;
328
329 /*
330 * Set the SCR bit to enable audio.
331 */
332 scr_value = ESS_SCR_AUDIO_ENABLE;
333
334 /*
335 * Set the SCR bits necessary to select the specified audio
336 * base address.
337 */
338 switch(iobase) {
339 case 0x220:
340 scr_value |= ESS_SCR_AUDIO_220;
341 break;
342 case 0x230:
343 scr_value |= ESS_SCR_AUDIO_230;
344 break;
345 case 0x240:
346 scr_value |= ESS_SCR_AUDIO_240;
347 break;
348 case 0x250:
349 scr_value |= ESS_SCR_AUDIO_250;
350 break;
351 default:
352 printf("ess: configured iobase 0x%x invalid\n", iobase);
353 return (1);
354 break;
355 }
356
357 /*
358 * Get a mapping for the System Control Register (SCR) access
359 * registers and the SCR data registers.
360 */
361 if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
362 0, &scr_access_ioh)) {
363 printf("ess: can't map SCR access registers\n");
364 return (1);
365 }
366 if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
367 0, &scr_ioh)) {
368 printf("ess: can't map SCR registers\n");
369 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
370 return (1);
371 }
372
373 /* Unlock the SCR. */
374 EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
375
376 /* Write the base address information into SCR[0]. */
377 EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
378 EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
379
380 /* Lock the SCR. */
381 EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
382
383 /* Unmap the SCR access ports and the SCR data ports. */
384 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
385 bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
386
387 return 0;
388 }
389
390
391 /*
392 * Configure the ESS chip for the desired IRQ and DMA channels.
393 * ESS ISA
394 * --------
395 * IRQA irq9
396 * IRQB irq5
397 * IRQC irq7
398 * IRQD irq10
399 * IRQE irq15
400 *
401 * DRQA drq0
402 * DRQB drq1
403 * DRQC drq3
404 * DRQD drq5
405 */
406 void
ess_config_irq(struct ess_softc * sc)407 ess_config_irq(struct ess_softc *sc)
408 {
409 int v;
410
411 DPRINTFN(2,("ess_config_irq\n"));
412
413 if (sc->sc_model == ESS_1887 &&
414 sc->sc_audio1.irq == sc->sc_audio2.irq &&
415 sc->sc_audio1.irq != -1) {
416 /* Use new method, both interrupts are the same. */
417 v = ESS_IS_SELECT_IRQ; /* enable intrs */
418 switch (sc->sc_audio1.irq) {
419 case 5:
420 v |= ESS_IS_INTRB;
421 break;
422 case 7:
423 v |= ESS_IS_INTRC;
424 break;
425 case 9:
426 v |= ESS_IS_INTRA;
427 break;
428 case 10:
429 v |= ESS_IS_INTRD;
430 break;
431 case 15:
432 v |= ESS_IS_INTRE;
433 break;
434 #ifdef DIAGNOSTIC
435 default:
436 printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
437 sc->sc_audio1.irq);
438 return;
439 #endif
440 }
441 /* Set the IRQ */
442 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
443 return;
444 }
445
446 if (sc->sc_model == ESS_1887) {
447 /* Tell the 1887 to use the old interrupt method. */
448 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
449 }
450
451 if (sc->sc_audio1.polled) {
452 /* Turn off Audio1 interrupts. */
453 v = 0;
454 } else {
455 /* Configure Audio 1 for the appropriate IRQ line. */
456 v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */
457 switch (sc->sc_audio1.irq) {
458 case 5:
459 v |= ESS_IRQ_CTRL_INTRB;
460 break;
461 case 7:
462 v |= ESS_IRQ_CTRL_INTRC;
463 break;
464 case 9:
465 v |= ESS_IRQ_CTRL_INTRA;
466 break;
467 case 10:
468 v |= ESS_IRQ_CTRL_INTRD;
469 break;
470 #ifdef DIAGNOSTIC
471 default:
472 printf("ess: configured irq %d not supported for Audio 1\n",
473 sc->sc_audio1.irq);
474 return;
475 #endif
476 }
477 }
478 ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
479
480 if (ESS_USE_AUDIO1(sc->sc_model))
481 return;
482
483 if (sc->sc_audio2.polled) {
484 /* Turn off Audio2 interrupts. */
485 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
486 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
487 } else {
488 /* Audio2 is hardwired to INTRE in this mode. */
489 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
490 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
491 }
492 }
493
494
495 void
ess_config_drq(struct ess_softc * sc)496 ess_config_drq(struct ess_softc *sc)
497 {
498 int v;
499
500 DPRINTFN(2,("ess_config_drq\n"));
501
502 /* Configure Audio 1 (record) for DMA on the appropriate channel. */
503 v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
504 switch (sc->sc_audio1.drq) {
505 case 0:
506 v |= ESS_DRQ_CTRL_DRQA;
507 break;
508 case 1:
509 v |= ESS_DRQ_CTRL_DRQB;
510 break;
511 case 3:
512 v |= ESS_DRQ_CTRL_DRQC;
513 break;
514 #ifdef DIAGNOSTIC
515 default:
516 printf("ess_config_drq: configured dma chan %d not supported for Audio 1\n",
517 sc->sc_audio1.drq);
518 return;
519 #endif
520 }
521 /* Set DRQ1 */
522 ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
523
524 if (ESS_USE_AUDIO1(sc->sc_model))
525 return;
526
527 /* Configure DRQ2 */
528 v = ESS_AUDIO2_CTRL3_DRQ_PD;
529 switch (sc->sc_audio2.drq) {
530 case 0:
531 v |= ESS_AUDIO2_CTRL3_DRQA;
532 break;
533 case 1:
534 v |= ESS_AUDIO2_CTRL3_DRQB;
535 break;
536 case 3:
537 v |= ESS_AUDIO2_CTRL3_DRQC;
538 break;
539 case 5:
540 v |= ESS_AUDIO2_CTRL3_DRQD;
541 break;
542 #ifdef DIAGNOSTIC
543 default:
544 printf("ess_config_drq: configured dma chan %d not supported for Audio 2\n",
545 sc->sc_audio2.drq);
546 return;
547 #endif
548 }
549 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
550 /* Enable DMA 2 */
551 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
552 ESS_AUDIO2_CTRL2_DMA_ENABLE);
553 }
554
555 /*
556 * Set up registers after a reset.
557 */
558 void
ess_setup(struct ess_softc * sc)559 ess_setup(struct ess_softc *sc)
560 {
561 ess_config_irq(sc);
562 ess_config_drq(sc);
563
564 DPRINTFN(2,("ess_setup: done\n"));
565 }
566
567 /*
568 * Determine the model of ESS chip we are talking to. Currently we
569 * only support ES1888, ES1887 and ES888. The method of determining
570 * the chip is based on the information on page 27 of the ES1887 data
571 * sheet.
572 *
573 * This routine sets the values of sc->sc_model and sc->sc_version.
574 */
575 int
ess_identify(struct ess_softc * sc)576 ess_identify(struct ess_softc *sc)
577 {
578 u_char reg1;
579 u_char reg2;
580 u_char reg3;
581 u_int8_t ident[4];
582
583 sc->sc_model = ESS_UNSUPPORTED;
584 sc->sc_version = 0;
585
586 memset(ident, 0, sizeof(ident));
587
588 /*
589 * 1. Check legacy ID bytes. These should be 0x68 0x8n, where
590 * n >= 8 for an ES1887 or an ES888. Other values indicate
591 * earlier (unsupported) chips.
592 */
593 ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
594
595 if ((reg1 = ess_rdsp(sc)) != 0x68) {
596 printf("ess: First ID byte wrong (0x%02x)\n", reg1);
597 return 1;
598 }
599
600 reg2 = ess_rdsp(sc);
601 if (((reg2 & 0xf0) != 0x80) ||
602 ((reg2 & 0x0f) < 8)) {
603 printf("ess: Second ID byte wrong (0x%02x)\n", reg2);
604 return 1;
605 }
606
607 /*
608 * Store the ID bytes as the version.
609 */
610 sc->sc_version = (reg1 << 8) + reg2;
611
612
613 /*
614 * 2. Verify we can change bit 2 in mixer register 0x64. This
615 * should be possible on all supported chips.
616 */
617 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
618 reg2 = reg1 ^ 0x04; /* toggle bit 2 */
619
620 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
621
622 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
623 printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
624 return 1;
625 }
626
627 /*
628 * Restore the original value of mixer register 0x64.
629 */
630 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
631
632
633 /*
634 * 3. Verify we can change the value of mixer register
635 * ESS_MREG_SAMPLE_RATE.
636 * This is possible on the 1888/1887/888, but not on the 1788.
637 * It is not necessary to restore the value of this mixer register.
638 */
639 reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
640 reg2 = reg1 ^ 0xff; /* toggle all bits */
641
642 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
643
644 if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
645 /* If we got this far before failing, it's a 1788. */
646 sc->sc_model = ESS_1788;
647
648 /*
649 * Identify ESS model for ES18[67]8.
650 */
651 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
652 if(ident[0] == 0x18) {
653 switch(ident[1]) {
654 case 0x68:
655 sc->sc_model = ESS_1868;
656 break;
657 case 0x78:
658 sc->sc_model = ESS_1878;
659 break;
660 }
661 }
662 } else {
663 /*
664 * 4. Determine if we can change bit 5 in mixer register 0x64.
665 * This determines whether we have an ES1887:
666 *
667 * - can change indicates ES1887
668 * - can't change indicates ES1888 or ES888
669 */
670 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
671 reg2 = reg1 ^ 0x20; /* toggle bit 5 */
672
673 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
674
675 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
676 sc->sc_model = ESS_1887;
677
678 /*
679 * Restore the original value of mixer register 0x64.
680 */
681 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
682
683 /*
684 * Identify ESS model for ES18[67]9.
685 */
686 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
687 if(ident[0] == 0x18) {
688 switch(ident[1]) {
689 case 0x69:
690 sc->sc_model = ESS_1869;
691 break;
692 case 0x79:
693 sc->sc_model = ESS_1879;
694 break;
695 }
696 }
697 } else {
698 /*
699 * 5. Determine if we can change the value of mixer
700 * register 0x69 independently of mixer register
701 * 0x68. This determines which chip we have:
702 *
703 * - can modify independently indicates ES888
704 * - register 0x69 is an alias of 0x68 indicates ES1888
705 */
706 reg1 = ess_read_mix_reg(sc, 0x68);
707 reg2 = ess_read_mix_reg(sc, 0x69);
708 reg3 = reg2 ^ 0xff; /* toggle all bits */
709
710 /*
711 * Write different values to each register.
712 */
713 ess_write_mix_reg(sc, 0x68, reg2);
714 ess_write_mix_reg(sc, 0x69, reg3);
715
716 if (ess_read_mix_reg(sc, 0x68) == reg2 &&
717 ess_read_mix_reg(sc, 0x69) == reg3)
718 sc->sc_model = ESS_888;
719 else
720 sc->sc_model = ESS_1888;
721
722 /*
723 * Restore the original value of the registers.
724 */
725 ess_write_mix_reg(sc, 0x68, reg1);
726 ess_write_mix_reg(sc, 0x69, reg2);
727 }
728 }
729
730 return 0;
731 }
732
733
734 int
ess_setup_sc(struct ess_softc * sc,int doinit)735 ess_setup_sc(struct ess_softc *sc, int doinit)
736 {
737 /* Reset the chip. */
738 if (ess_reset(sc) != 0) {
739 DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
740 return (1);
741 }
742
743 /* Identify the ESS chip, and check that it is supported. */
744 if (ess_identify(sc)) {
745 DPRINTF(("ess_setup_sc: couldn't identify\n"));
746 return (1);
747 }
748
749 return (0);
750 }
751
752 /*
753 * Probe for the ESS hardware.
754 */
755 int
essmatch(struct ess_softc * sc)756 essmatch(struct ess_softc *sc)
757 {
758 if (!ESS_BASE_VALID(sc->sc_iobase)) {
759 printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
760 return (0);
761 }
762
763 /* Configure the ESS chip for the desired audio base address. */
764 if (ess_config_addr(sc))
765 return (0);
766
767 if (ess_setup_sc(sc, 1))
768 return (0);
769
770 if (sc->sc_model == ESS_UNSUPPORTED) {
771 DPRINTF(("ess: Unsupported model\n"));
772 return (0);
773 }
774
775 /* Check that requested DMA channels are valid and different. */
776 if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
777 printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
778 return (0);
779 }
780 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio1.drq))
781 return (0);
782 if (!ESS_USE_AUDIO1(sc->sc_model)) {
783 if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
784 printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
785 return (0);
786 }
787 if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
788 printf("ess: play and record drq both %d\n",
789 sc->sc_audio1.drq);
790 return (0);
791 }
792 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio2.drq))
793 return (0);
794 }
795
796 /*
797 * The 1887 has an additional IRQ mode where both channels are mapped
798 * to the same IRQ.
799 */
800 if (sc->sc_model == ESS_1887 &&
801 sc->sc_audio1.irq == sc->sc_audio2.irq &&
802 sc->sc_audio1.irq != -1 &&
803 ESS_IRQ12_VALID(sc->sc_audio1.irq))
804 goto irq_not1888;
805
806 /* Check that requested IRQ lines are valid and different. */
807 if (sc->sc_audio1.irq != -1 &&
808 !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
809 printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
810 return (0);
811 }
812 if (!ESS_USE_AUDIO1(sc->sc_model)) {
813 if (sc->sc_audio2.irq != -1 &&
814 !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
815 printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
816 return (0);
817 }
818 if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
819 sc->sc_audio1.irq != -1) {
820 printf("ess: play and record irq both %d\n",
821 sc->sc_audio1.irq);
822 return (0);
823 }
824 }
825
826 irq_not1888:
827 /* XXX should we check IRQs as well? */
828
829 return (1);
830 }
831
832
833 /*
834 * Attach hardware to driver, attach hardware driver to audio
835 * pseudo-device driver.
836 */
837 void
essattach(struct ess_softc * sc)838 essattach(struct ess_softc *sc)
839 {
840 struct audio_attach_args arg;
841 struct audio_params pparams, rparams;
842 int i;
843 u_int v;
844
845 if (ess_setup_sc(sc, 0)) {
846 printf(": setup failed\n");
847 return;
848 }
849
850 printf(": ESS Technology ES%s [version 0x%04x]\n",
851 essmodel[sc->sc_model], sc->sc_version);
852
853 sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
854 if (!sc->sc_audio1.polled) {
855 sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
856 sc->sc_audio1.irq, sc->sc_audio1.ist,
857 IPL_AUDIO | IPL_MPSAFE,
858 ess_audio1_intr, sc, sc->sc_dev.dv_xname);
859 printf("%s: audio1 interrupting at irq %d\n",
860 sc->sc_dev.dv_xname, sc->sc_audio1.irq);
861 } else
862 printf("%s: audio1 polled\n", sc->sc_dev.dv_xname);
863 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio1.drq,
864 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
865 printf("%s: can't create map for drq %d\n",
866 sc->sc_dev.dv_xname, sc->sc_audio1.drq);
867 return;
868 }
869
870 if (!ESS_USE_AUDIO1(sc->sc_model)) {
871 sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
872 if (!sc->sc_audio2.polled) {
873 sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
874 sc->sc_audio2.irq, sc->sc_audio2.ist,
875 IPL_AUDIO | IPL_MPSAFE,
876 ess_audio2_intr, sc, sc->sc_dev.dv_xname);
877 printf("%s: audio2 interrupting at irq %d\n",
878 sc->sc_dev.dv_xname, sc->sc_audio2.irq);
879 } else
880 printf("%s: audio2 polled\n", sc->sc_dev.dv_xname);
881 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio2.drq,
882 MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
883 printf("%s: can't create map for drq %d\n",
884 sc->sc_dev.dv_xname, sc->sc_audio2.drq);
885 return;
886 }
887 }
888
889 timeout_set(&sc->sc_tmo1, ess_audio1_poll, sc);
890 timeout_set(&sc->sc_tmo2, ess_audio2_poll, sc);
891
892 /*
893 * Set record and play parameters to default values defined in
894 * generic audio driver.
895 */
896 pparams = ess_audio_default;
897 rparams = ess_audio_default;
898 ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
899
900 /* Do a hardware reset on the mixer. */
901 ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
902
903 /*
904 * Set volume of Audio 1 to zero and disable Audio 1 DAC input
905 * to playback mixer, since playback is always through Audio 2.
906 */
907 if (!ESS_USE_AUDIO1(sc->sc_model))
908 ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
909 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
910
911 if (ESS_USE_AUDIO1(sc->sc_model)) {
912 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
913 sc->in_port = ESS_SOURCE_MIC;
914 sc->ndevs = ESS_1788_NDEVS;
915 } else {
916 /*
917 * Set hardware record source to use output of the record
918 * mixer. We do the selection of record source in software by
919 * setting the gain of the unused sources to zero. (See
920 * ess_set_in_ports.)
921 */
922 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
923 sc->in_mask = 1 << ESS_MIC_REC_VOL;
924 sc->ndevs = ESS_1888_NDEVS;
925 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
926 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
927 }
928
929 /*
930 * Set gain on each mixer device to a sensible value.
931 * Devices not normally used are turned off, and other devices
932 * are set to 50% volume.
933 */
934 for (i = 0; i < sc->ndevs; i++) {
935 switch (i) {
936 case ESS_MIC_PLAY_VOL:
937 case ESS_LINE_PLAY_VOL:
938 case ESS_CD_PLAY_VOL:
939 case ESS_AUXB_PLAY_VOL:
940 case ESS_DAC_REC_VOL:
941 case ESS_LINE_REC_VOL:
942 case ESS_SYNTH_REC_VOL:
943 case ESS_CD_REC_VOL:
944 case ESS_AUXB_REC_VOL:
945 v = 0;
946 break;
947 default:
948 v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
949 break;
950 }
951 sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
952 ess_set_gain(sc, i, 1);
953 }
954
955 ess_setup(sc);
956
957 /* Disable the speaker until the device is opened. */
958 ess_speaker_off(sc);
959 sc->spkr_state = SPKR_OFF;
960
961 if (ESS_USE_AUDIO1(sc->sc_model))
962 audio_attach_mi(&ess_1788_hw_if, sc, NULL, &sc->sc_dev);
963 else
964 audio_attach_mi(&ess_1888_hw_if, sc, NULL, &sc->sc_dev);
965
966 arg.type = AUDIODEV_TYPE_OPL;
967 arg.hwif = 0;
968 arg.hdl = 0;
969 (void)config_found(&sc->sc_dev, &arg, audioprint);
970
971 #ifdef AUDIO_DEBUG
972 if (essdebug > 0)
973 ess_printsc(sc);
974 #endif
975 }
976
977 /*
978 * Various routines to interface to higher level audio driver
979 */
980
981 int
ess_1788_open(void * addr,int flags)982 ess_1788_open(void *addr, int flags)
983 {
984 if ((flags & (FWRITE | FREAD)) == (FWRITE | FREAD))
985 return ENXIO;
986
987 return ess_open(addr, flags);
988 }
989
990 int
ess_open(void * addr,int flags)991 ess_open(void *addr, int flags)
992 {
993 struct ess_softc *sc = addr;
994
995 DPRINTF(("ess_open: sc=%p\n", sc));
996
997 if (sc->sc_open != 0 || ess_reset(sc) != 0)
998 return ENXIO;
999
1000 ess_setup(sc); /* because we did a reset */
1001
1002 ess_speaker_ctl(sc, (flags & FWRITE) ? SPKR_ON : SPKR_OFF);
1003
1004 sc->sc_open = 1;
1005
1006 DPRINTF(("ess_open: opened\n"));
1007
1008 return (0);
1009 }
1010
1011 void
ess_1788_close(void * addr)1012 ess_1788_close(void *addr)
1013 {
1014 struct ess_softc *sc = addr;
1015
1016 DPRINTF(("ess_1788_close: sc=%p\n", sc));
1017
1018 ess_speaker_off(sc);
1019 sc->spkr_state = SPKR_OFF;
1020
1021 ess_audio1_halt(sc);
1022
1023 sc->sc_open = 0;
1024 DPRINTF(("ess_1788_close: closed\n"));
1025 }
1026
1027 void
ess_1888_close(void * addr)1028 ess_1888_close(void *addr)
1029 {
1030 struct ess_softc *sc = addr;
1031
1032 DPRINTF(("ess_1888_close: sc=%p\n", sc));
1033
1034 ess_speaker_off(sc);
1035 sc->spkr_state = SPKR_OFF;
1036
1037 ess_audio1_halt(sc);
1038 ess_audio2_halt(sc);
1039
1040 sc->sc_open = 0;
1041 DPRINTF(("ess_1888_close: closed\n"));
1042 }
1043
1044 /* XXX should use reference count */
1045 int
ess_speaker_ctl(void * addr,int newstate)1046 ess_speaker_ctl(void *addr, int newstate)
1047 {
1048 struct ess_softc *sc = addr;
1049
1050 if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
1051 ess_speaker_on(sc);
1052 sc->spkr_state = SPKR_ON;
1053 }
1054 if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
1055 ess_speaker_off(sc);
1056 sc->spkr_state = SPKR_OFF;
1057 }
1058 return (0);
1059 }
1060
1061 int
ess_set_params(void * addr,int setmode,int usemode,struct audio_params * play,struct audio_params * rec)1062 ess_set_params(void *addr, int setmode, int usemode,
1063 struct audio_params *play, struct audio_params *rec)
1064 {
1065 struct ess_softc *sc = addr;
1066 struct audio_params *p;
1067 int mode;
1068 int rate;
1069
1070 DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
1071
1072 /*
1073 * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in
1074 * full-duplex operation the sample rates must be the same for both
1075 * channels. This appears to be false; the only bit in common is the
1076 * clock source selection. However, we'll be conservative here.
1077 * - mycroft
1078 */
1079 if (play->sample_rate != rec->sample_rate &&
1080 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
1081 if (setmode == AUMODE_PLAY) {
1082 rec->sample_rate = play->sample_rate;
1083 setmode |= AUMODE_RECORD;
1084 } else if (setmode == AUMODE_RECORD) {
1085 play->sample_rate = rec->sample_rate;
1086 setmode |= AUMODE_PLAY;
1087 } else
1088 return (EINVAL);
1089 }
1090
1091 for (mode = AUMODE_RECORD; mode != -1;
1092 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
1093 if ((setmode & mode) == 0)
1094 continue;
1095
1096 p = mode == AUMODE_PLAY ? play : rec;
1097
1098 if (p->sample_rate < ESS_MINRATE)
1099 p->sample_rate = ESS_MINRATE;
1100 if (p->sample_rate > ESS_MAXRATE)
1101 p->sample_rate = ESS_MAXRATE;
1102 if (p->precision > 16)
1103 p->precision = 16;
1104 if (p->channels > 2)
1105 p->channels = 2;
1106
1107 switch (p->encoding) {
1108 case AUDIO_ENCODING_SLINEAR_BE:
1109 case AUDIO_ENCODING_ULINEAR_BE:
1110 if (p->precision != 8)
1111 return EINVAL;
1112 break;
1113 case AUDIO_ENCODING_SLINEAR_LE:
1114 case AUDIO_ENCODING_ULINEAR_LE:
1115 break;
1116 default:
1117 return (EINVAL);
1118 }
1119 p->bps = AUDIO_BPS(p->precision);
1120 p->msb = 1;
1121 }
1122
1123 if (usemode == AUMODE_RECORD)
1124 rate = rec->sample_rate;
1125 else
1126 rate = play->sample_rate;
1127
1128 ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
1129 ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
1130
1131 if (!ESS_USE_AUDIO1(sc->sc_model)) {
1132 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
1133 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
1134 }
1135
1136 return (0);
1137 }
1138
1139 int
ess_audio1_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,struct audio_params * param)1140 ess_audio1_trigger_output(void *addr, void *start, void *end, int blksize,
1141 void (*intr)(void *), void *arg, struct audio_params *param)
1142 {
1143 struct ess_softc *sc = addr;
1144 u_int8_t reg;
1145
1146 mtx_enter(&audio_lock);
1147 DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1148 addr, start, end, blksize, intr, arg));
1149
1150 if (sc->sc_audio1.active)
1151 panic("ess_audio1_trigger_output: already running");
1152
1153 sc->sc_audio1.active = 1;
1154 sc->sc_audio1.intr = intr;
1155 sc->sc_audio1.arg = arg;
1156 if (sc->sc_audio1.polled) {
1157 sc->sc_audio1.dmapos = 0;
1158 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1159 sc->sc_audio1.dmacount = 0;
1160 sc->sc_audio1.blksize = blksize;
1161 timeout_add_msec(&sc->sc_tmo1, 1000/30);
1162 }
1163
1164 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1165 if (param->channels == 2) {
1166 reg &= ~ESS_AUDIO_CTRL_MONO;
1167 reg |= ESS_AUDIO_CTRL_STEREO;
1168 } else {
1169 reg |= ESS_AUDIO_CTRL_MONO;
1170 reg &= ~ESS_AUDIO_CTRL_STEREO;
1171 }
1172 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1173
1174 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1175 if (param->precision == 16)
1176 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1177 else
1178 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1179 if (param->channels == 2)
1180 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1181 else
1182 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1183 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1184 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1185 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1186 else
1187 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1188 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1189 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1190
1191 isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
1192 (char *)end - (char *)start, NULL,
1193 DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1194
1195 /* Program transfer count registers with 2's complement of count. */
1196 blksize = -blksize;
1197 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1198 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1199
1200 /* Use 4 bytes per output DMA. */
1201 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1202
1203 /* Start auto-init DMA */
1204 ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
1205 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1206 reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
1207 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1208 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1209 mtx_leave(&audio_lock);
1210 return (0);
1211 }
1212
1213 int
ess_audio2_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,struct audio_params * param)1214 ess_audio2_trigger_output(void *addr, void *start, void *end, int blksize,
1215 void (*intr)(void *), void *arg, struct audio_params *param)
1216 {
1217 struct ess_softc *sc = addr;
1218 u_int8_t reg;
1219
1220 mtx_enter(&audio_lock);
1221 DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1222 addr, start, end, blksize, intr, arg));
1223
1224 if (sc->sc_audio2.active)
1225 panic("ess_audio2_trigger_output: already running");
1226
1227 sc->sc_audio2.active = 1;
1228 sc->sc_audio2.intr = intr;
1229 sc->sc_audio2.arg = arg;
1230 if (sc->sc_audio2.polled) {
1231 sc->sc_audio2.dmapos = 0;
1232 sc->sc_audio2.buffersize = (char *)end - (char *)start;
1233 sc->sc_audio2.dmacount = 0;
1234 sc->sc_audio2.blksize = blksize;
1235 timeout_add_msec(&sc->sc_tmo2, 1000/30);
1236 }
1237
1238 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1239 if (param->precision == 16)
1240 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
1241 else
1242 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
1243 if (param->channels == 2)
1244 reg |= ESS_AUDIO2_CTRL2_CHANNELS;
1245 else
1246 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
1247 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1248 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1249 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1250 else
1251 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1252 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1253
1254 isa_dmastart(sc->sc_isa, sc->sc_audio2.drq, start,
1255 (char *)end - (char *)start, NULL,
1256 DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1257
1258 if (IS16BITDRQ(sc->sc_audio2.drq))
1259 blksize >>= 1; /* use word count for 16 bit DMA */
1260 /* Program transfer count registers with 2's complement of count. */
1261 blksize = -blksize;
1262 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
1263 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
1264
1265 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
1266 if (IS16BITDRQ(sc->sc_audio2.drq))
1267 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
1268 else
1269 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
1270 reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
1271 reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
1272 ESS_AUDIO2_CTRL1_AUTO_INIT;
1273 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
1274 mtx_leave(&audio_lock);
1275 return (0);
1276 }
1277
1278 int
ess_audio1_trigger_input(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,struct audio_params * param)1279 ess_audio1_trigger_input(void *addr, void *start, void *end, int blksize,
1280 void (*intr)(void *), void *arg, struct audio_params *param)
1281 {
1282 struct ess_softc *sc = addr;
1283 u_int8_t reg;
1284
1285 mtx_enter(&audio_lock);
1286 DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1287 addr, start, end, blksize, intr, arg));
1288
1289 if (sc->sc_audio1.active)
1290 panic("ess_audio1_trigger_input: already running");
1291
1292 sc->sc_audio1.active = 1;
1293 sc->sc_audio1.intr = intr;
1294 sc->sc_audio1.arg = arg;
1295 if (sc->sc_audio1.polled) {
1296 sc->sc_audio1.dmapos = 0;
1297 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1298 sc->sc_audio1.dmacount = 0;
1299 sc->sc_audio1.blksize = blksize;
1300 timeout_add_msec(&sc->sc_tmo1, 1000/30);
1301 }
1302
1303 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1304 if (param->channels == 2) {
1305 reg &= ~ESS_AUDIO_CTRL_MONO;
1306 reg |= ESS_AUDIO_CTRL_STEREO;
1307 } else {
1308 reg |= ESS_AUDIO_CTRL_MONO;
1309 reg &= ~ESS_AUDIO_CTRL_STEREO;
1310 }
1311 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1312
1313 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1314 if (param->precision == 16)
1315 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1316 else
1317 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1318 if (param->channels == 2)
1319 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1320 else
1321 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1322 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1323 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1324 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1325 else
1326 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1327 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1328 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1329
1330 isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
1331 (char *)end - (char *)start, NULL,
1332 DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
1333
1334 /* Program transfer count registers with 2's complement of count. */
1335 blksize = -blksize;
1336 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1337 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1338
1339 /* Use 4 bytes per input DMA. */
1340 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1341
1342 /* Start auto-init DMA */
1343 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
1344 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1345 reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
1346 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1347 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1348 mtx_leave(&audio_lock);
1349 return (0);
1350 }
1351
1352 int
ess_audio1_halt(void * addr)1353 ess_audio1_halt(void *addr)
1354 {
1355 struct ess_softc *sc = addr;
1356
1357 DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
1358 mtx_enter(&audio_lock);
1359 if (sc->sc_audio1.active) {
1360 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
1361 ESS_AUDIO1_CTRL2_FIFO_ENABLE);
1362 isa_dmaabort(sc->sc_isa, sc->sc_audio1.drq);
1363 if (sc->sc_audio1.polled)
1364 timeout_del(&sc->sc_tmo1);
1365 sc->sc_audio1.active = 0;
1366 }
1367 mtx_leave(&audio_lock);
1368 return (0);
1369 }
1370
1371 int
ess_audio2_halt(void * addr)1372 ess_audio2_halt(void *addr)
1373 {
1374 struct ess_softc *sc = addr;
1375
1376 DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
1377 mtx_enter(&audio_lock);
1378 if (sc->sc_audio2.active) {
1379 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
1380 ESS_AUDIO2_CTRL1_DAC_ENABLE |
1381 ESS_AUDIO2_CTRL1_FIFO_ENABLE);
1382 isa_dmaabort(sc->sc_isa, sc->sc_audio2.drq);
1383 if (sc->sc_audio2.polled)
1384 timeout_del(&sc->sc_tmo2);
1385 sc->sc_audio2.active = 0;
1386 }
1387 mtx_leave(&audio_lock);
1388 return (0);
1389 }
1390
1391 int
ess_audio1_intr(void * arg)1392 ess_audio1_intr(void *arg)
1393 {
1394 struct ess_softc *sc = arg;
1395 u_int8_t reg;
1396
1397 DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
1398
1399 mtx_enter(&audio_lock);
1400 /* Check and clear interrupt on Audio1. */
1401 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
1402 if ((reg & ESS_DSP_READ_OFLOW) == 0) {
1403 mtx_leave(&audio_lock);
1404 return (0);
1405 }
1406 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
1407
1408 sc->sc_audio1.nintr++;
1409
1410 if (sc->sc_audio1.active) {
1411 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1412 mtx_leave(&audio_lock);
1413 return (1);
1414 } else {
1415 mtx_leave(&audio_lock);
1416 return (0);
1417 }
1418 }
1419
1420 int
ess_audio2_intr(void * arg)1421 ess_audio2_intr(void *arg)
1422 {
1423 struct ess_softc *sc = arg;
1424 u_int8_t reg;
1425
1426 DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
1427
1428 mtx_enter(&audio_lock);
1429 /* Check and clear interrupt on Audio2. */
1430 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1431 if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) {
1432 mtx_leave(&audio_lock);
1433 return (0);
1434 }
1435 reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
1436 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1437
1438 sc->sc_audio2.nintr++;
1439
1440 if (sc->sc_audio2.active) {
1441 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1442 mtx_leave(&audio_lock);
1443 return (1);
1444 } else {
1445 mtx_leave(&audio_lock);
1446 return (0);
1447 }
1448 }
1449
1450 void
ess_audio1_poll(void * addr)1451 ess_audio1_poll(void *addr)
1452 {
1453 struct ess_softc *sc = addr;
1454 int dmapos, dmacount;
1455
1456 if (!sc->sc_audio1.active)
1457 return;
1458
1459 mtx_enter(&audio_lock);
1460 sc->sc_audio1.nintr++;
1461
1462 dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio1.drq);
1463 dmacount = sc->sc_audio1.dmapos - dmapos;
1464 if (dmacount < 0)
1465 dmacount += sc->sc_audio1.buffersize;
1466 sc->sc_audio1.dmapos = dmapos;
1467 #if 1
1468 dmacount += sc->sc_audio1.dmacount;
1469 while (dmacount > sc->sc_audio1.blksize) {
1470 dmacount -= sc->sc_audio1.blksize;
1471 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1472 }
1473 sc->sc_audio1.dmacount = dmacount;
1474 #else
1475 (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
1476 #endif
1477 timeout_add_msec(&sc->sc_tmo1, 1000/30);
1478 mtx_leave(&audio_lock);
1479 }
1480
1481 void
ess_audio2_poll(void * addr)1482 ess_audio2_poll(void *addr)
1483 {
1484 struct ess_softc *sc = addr;
1485 int dmapos, dmacount;
1486
1487 if (!sc->sc_audio2.active)
1488 return;
1489
1490 mtx_enter(&audio_lock);
1491 sc->sc_audio2.nintr++;
1492
1493 dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio2.drq);
1494 dmacount = sc->sc_audio2.dmapos - dmapos;
1495 if (dmacount < 0)
1496 dmacount += sc->sc_audio2.buffersize;
1497 sc->sc_audio2.dmapos = dmapos;
1498 #if 1
1499 dmacount += sc->sc_audio2.dmacount;
1500 while (dmacount > sc->sc_audio2.blksize) {
1501 dmacount -= sc->sc_audio2.blksize;
1502 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1503 }
1504 sc->sc_audio2.dmacount = dmacount;
1505 #else
1506 (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
1507 #endif
1508 timeout_add_msec(&sc->sc_tmo2, 1000/30);
1509 mtx_leave(&audio_lock);
1510 }
1511
1512 int
ess_round_blocksize(void * addr,int blk)1513 ess_round_blocksize(void *addr, int blk)
1514 {
1515 return ((blk + 7) & -8); /* round for max DMA size */
1516 }
1517
1518 int
ess_set_port(void * addr,mixer_ctrl_t * cp)1519 ess_set_port(void *addr, mixer_ctrl_t *cp)
1520 {
1521 struct ess_softc *sc = addr;
1522 int lgain, rgain;
1523
1524 DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
1525 cp->dev, cp->un.value.num_channels));
1526
1527 switch (cp->dev) {
1528 /*
1529 * The following mixer ports are all stereo. If we get a
1530 * single-channel gain value passed in, then we duplicate it
1531 * to both left and right channels.
1532 */
1533 case ESS_MASTER_VOL:
1534 case ESS_DAC_PLAY_VOL:
1535 case ESS_MIC_PLAY_VOL:
1536 case ESS_LINE_PLAY_VOL:
1537 case ESS_SYNTH_PLAY_VOL:
1538 case ESS_CD_PLAY_VOL:
1539 case ESS_AUXB_PLAY_VOL:
1540 case ESS_RECORD_VOL:
1541 if (cp->type != AUDIO_MIXER_VALUE)
1542 return EINVAL;
1543
1544 switch (cp->un.value.num_channels) {
1545 case 1:
1546 lgain = rgain = ESS_4BIT_GAIN(
1547 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1548 break;
1549 case 2:
1550 lgain = ESS_4BIT_GAIN(
1551 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1552 rgain = ESS_4BIT_GAIN(
1553 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1554 break;
1555 default:
1556 return EINVAL;
1557 }
1558
1559 sc->gain[cp->dev][ESS_LEFT] = lgain;
1560 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1561 ess_set_gain(sc, cp->dev, 1);
1562 return (0);
1563
1564 /*
1565 * The PC speaker port is mono. If we get a stereo gain value
1566 * passed in, then we return EINVAL.
1567 */
1568 case ESS_PCSPEAKER_VOL:
1569 if (cp->un.value.num_channels != 1)
1570 return EINVAL;
1571
1572 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
1573 ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1574 ess_set_gain(sc, cp->dev, 1);
1575 return (0);
1576
1577 case ESS_RECORD_SOURCE:
1578 if (ESS_USE_AUDIO1(sc->sc_model)) {
1579 if (cp->type == AUDIO_MIXER_ENUM)
1580 return (ess_set_in_port(sc, cp->un.ord));
1581 else
1582 return (EINVAL);
1583 } else {
1584 if (cp->type == AUDIO_MIXER_SET)
1585 return (ess_set_in_ports(sc, cp->un.mask));
1586 else
1587 return (EINVAL);
1588 }
1589 return (0);
1590
1591 case ESS_RECORD_MONITOR:
1592 if (cp->type != AUDIO_MIXER_ENUM)
1593 return EINVAL;
1594
1595 if (cp->un.ord)
1596 /* Enable monitor */
1597 ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1598 ESS_AUDIO_CTRL_MONITOR);
1599 else
1600 /* Disable monitor */
1601 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1602 ESS_AUDIO_CTRL_MONITOR);
1603 return (0);
1604 }
1605
1606 if (ESS_USE_AUDIO1(sc->sc_model))
1607 return (EINVAL);
1608
1609 switch (cp->dev) {
1610 case ESS_DAC_REC_VOL:
1611 case ESS_MIC_REC_VOL:
1612 case ESS_LINE_REC_VOL:
1613 case ESS_SYNTH_REC_VOL:
1614 case ESS_CD_REC_VOL:
1615 case ESS_AUXB_REC_VOL:
1616 if (cp->type != AUDIO_MIXER_VALUE)
1617 return EINVAL;
1618
1619 switch (cp->un.value.num_channels) {
1620 case 1:
1621 lgain = rgain = ESS_4BIT_GAIN(
1622 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1623 break;
1624 case 2:
1625 lgain = ESS_4BIT_GAIN(
1626 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1627 rgain = ESS_4BIT_GAIN(
1628 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1629 break;
1630 default:
1631 return EINVAL;
1632 }
1633
1634 sc->gain[cp->dev][ESS_LEFT] = lgain;
1635 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1636 ess_set_gain(sc, cp->dev, 1);
1637 return (0);
1638
1639 case ESS_MIC_PREAMP:
1640 if (cp->type != AUDIO_MIXER_ENUM)
1641 return EINVAL;
1642
1643 if (cp->un.ord)
1644 /* Enable microphone preamp */
1645 ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1646 ESS_PREAMP_CTRL_ENABLE);
1647 else
1648 /* Disable microphone preamp */
1649 ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1650 ESS_PREAMP_CTRL_ENABLE);
1651 return (0);
1652 }
1653
1654 return (EINVAL);
1655 }
1656
1657 int
ess_get_port(void * addr,mixer_ctrl_t * cp)1658 ess_get_port(void *addr, mixer_ctrl_t *cp)
1659 {
1660 struct ess_softc *sc = addr;
1661
1662 DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
1663
1664 switch (cp->dev) {
1665 case ESS_MASTER_VOL:
1666 case ESS_DAC_PLAY_VOL:
1667 case ESS_MIC_PLAY_VOL:
1668 case ESS_LINE_PLAY_VOL:
1669 case ESS_SYNTH_PLAY_VOL:
1670 case ESS_CD_PLAY_VOL:
1671 case ESS_AUXB_PLAY_VOL:
1672 case ESS_RECORD_VOL:
1673 switch (cp->un.value.num_channels) {
1674 case 1:
1675 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1676 sc->gain[cp->dev][ESS_LEFT];
1677 break;
1678 case 2:
1679 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1680 sc->gain[cp->dev][ESS_LEFT];
1681 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1682 sc->gain[cp->dev][ESS_RIGHT];
1683 break;
1684 default:
1685 return EINVAL;
1686 }
1687 return (0);
1688
1689 case ESS_PCSPEAKER_VOL:
1690 if (cp->un.value.num_channels != 1)
1691 return EINVAL;
1692
1693 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1694 sc->gain[cp->dev][ESS_LEFT];
1695 return (0);
1696
1697 case ESS_RECORD_SOURCE:
1698 if (ESS_USE_AUDIO1(sc->sc_model))
1699 cp->un.ord = sc->in_port;
1700 else
1701 cp->un.mask = sc->in_mask;
1702 return (0);
1703
1704 case ESS_RECORD_MONITOR:
1705 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
1706 ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
1707 return (0);
1708 }
1709
1710 if (ESS_USE_AUDIO1(sc->sc_model))
1711 return (EINVAL);
1712
1713 switch (cp->dev) {
1714 case ESS_DAC_REC_VOL:
1715 case ESS_MIC_REC_VOL:
1716 case ESS_LINE_REC_VOL:
1717 case ESS_SYNTH_REC_VOL:
1718 case ESS_CD_REC_VOL:
1719 case ESS_AUXB_REC_VOL:
1720 switch (cp->un.value.num_channels) {
1721 case 1:
1722 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1723 sc->gain[cp->dev][ESS_LEFT];
1724 break;
1725 case 2:
1726 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1727 sc->gain[cp->dev][ESS_LEFT];
1728 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1729 sc->gain[cp->dev][ESS_RIGHT];
1730 break;
1731 default:
1732 return EINVAL;
1733 }
1734 return (0);
1735
1736 case ESS_MIC_PREAMP:
1737 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
1738 ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
1739 return (0);
1740 }
1741
1742 return (EINVAL);
1743 }
1744
1745 int
ess_query_devinfo(void * addr,mixer_devinfo_t * dip)1746 ess_query_devinfo(void *addr, mixer_devinfo_t *dip)
1747 {
1748 struct ess_softc *sc = addr;
1749
1750 DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
1751 sc->sc_model, dip->index));
1752
1753 /*
1754 * REVISIT: There are some slight differences between the
1755 * mixers on the different ESS chips, which can
1756 * be sorted out using the chip model rather than a
1757 * separate mixer model.
1758 * This is currently coded assuming an ES1887; we
1759 * need to work out which bits are not applicable to
1760 * the other models (1888 and 888).
1761 */
1762 switch (dip->index) {
1763 case ESS_DAC_PLAY_VOL:
1764 dip->mixer_class = ESS_INPUT_CLASS;
1765 dip->next = dip->prev = AUDIO_MIXER_LAST;
1766 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
1767 dip->type = AUDIO_MIXER_VALUE;
1768 dip->un.v.num_channels = 2;
1769 strlcpy(dip->un.v.units.name, AudioNvolume,
1770 sizeof dip->un.v.units.name);
1771 return (0);
1772
1773 case ESS_MIC_PLAY_VOL:
1774 dip->mixer_class = ESS_INPUT_CLASS;
1775 dip->prev = AUDIO_MIXER_LAST;
1776 if (ESS_USE_AUDIO1(sc->sc_model))
1777 dip->next = AUDIO_MIXER_LAST;
1778 else
1779 dip->next = ESS_MIC_PREAMP;
1780 strlcpy(dip->label.name, AudioNmicrophone,
1781 sizeof dip->label.name);
1782 dip->type = AUDIO_MIXER_VALUE;
1783 dip->un.v.num_channels = 2;
1784 strlcpy(dip->un.v.units.name, AudioNvolume,
1785 sizeof dip->un.v.units.name);
1786 return (0);
1787
1788 case ESS_LINE_PLAY_VOL:
1789 dip->mixer_class = ESS_INPUT_CLASS;
1790 dip->next = dip->prev = AUDIO_MIXER_LAST;
1791 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
1792 dip->type = AUDIO_MIXER_VALUE;
1793 dip->un.v.num_channels = 2;
1794 strlcpy(dip->un.v.units.name, AudioNvolume,
1795 sizeof dip->un.v.units.name);
1796 return (0);
1797
1798 case ESS_SYNTH_PLAY_VOL:
1799 dip->mixer_class = ESS_INPUT_CLASS;
1800 dip->next = dip->prev = AUDIO_MIXER_LAST;
1801 strlcpy(dip->label.name, AudioNfmsynth,
1802 sizeof dip->label.name);
1803 dip->type = AUDIO_MIXER_VALUE;
1804 dip->un.v.num_channels = 2;
1805 strlcpy(dip->un.v.units.name, AudioNvolume,
1806 sizeof dip->un.v.units.name);
1807 return (0);
1808
1809 case ESS_CD_PLAY_VOL:
1810 dip->mixer_class = ESS_INPUT_CLASS;
1811 dip->next = dip->prev = AUDIO_MIXER_LAST;
1812 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
1813 dip->type = AUDIO_MIXER_VALUE;
1814 dip->un.v.num_channels = 2;
1815 strlcpy(dip->un.v.units.name, AudioNvolume,
1816 sizeof dip->un.v.units.name);
1817 return (0);
1818
1819 case ESS_AUXB_PLAY_VOL:
1820 dip->mixer_class = ESS_INPUT_CLASS;
1821 dip->next = dip->prev = AUDIO_MIXER_LAST;
1822 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
1823 dip->type = AUDIO_MIXER_VALUE;
1824 dip->un.v.num_channels = 2;
1825 strlcpy(dip->un.v.units.name, AudioNvolume,
1826 sizeof dip->un.v.units.name);
1827 return (0);
1828
1829 case ESS_INPUT_CLASS:
1830 dip->mixer_class = ESS_INPUT_CLASS;
1831 dip->next = dip->prev = AUDIO_MIXER_LAST;
1832 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
1833 dip->type = AUDIO_MIXER_CLASS;
1834 return (0);
1835
1836 case ESS_MASTER_VOL:
1837 dip->mixer_class = ESS_OUTPUT_CLASS;
1838 dip->next = dip->prev = AUDIO_MIXER_LAST;
1839 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
1840 dip->type = AUDIO_MIXER_VALUE;
1841 dip->un.v.num_channels = 2;
1842 strlcpy(dip->un.v.units.name, AudioNvolume,
1843 sizeof dip->un.v.units.name);
1844 return (0);
1845
1846 case ESS_PCSPEAKER_VOL:
1847 dip->mixer_class = ESS_OUTPUT_CLASS;
1848 dip->next = dip->prev = AUDIO_MIXER_LAST;
1849 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name);
1850 dip->type = AUDIO_MIXER_VALUE;
1851 dip->un.v.num_channels = 1;
1852 strlcpy(dip->un.v.units.name, AudioNvolume,
1853 sizeof dip->un.v.units.name);
1854 return (0);
1855
1856 case ESS_OUTPUT_CLASS:
1857 dip->mixer_class = ESS_OUTPUT_CLASS;
1858 dip->next = dip->prev = AUDIO_MIXER_LAST;
1859 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
1860 dip->type = AUDIO_MIXER_CLASS;
1861 return (0);
1862
1863 case ESS_RECORD_VOL:
1864 dip->mixer_class = ESS_RECORD_CLASS;
1865 dip->next = dip->prev = AUDIO_MIXER_LAST;
1866 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
1867 dip->type = AUDIO_MIXER_VALUE;
1868 dip->un.v.num_channels = 2;
1869 strlcpy(dip->un.v.units.name, AudioNvolume,
1870 sizeof dip->un.v.units.name);
1871 return (0);
1872
1873 case ESS_RECORD_SOURCE:
1874 dip->mixer_class = ESS_RECORD_CLASS;
1875 dip->next = dip->prev = AUDIO_MIXER_LAST;
1876 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
1877 if (ESS_USE_AUDIO1(sc->sc_model)) {
1878 /*
1879 * The 1788 doesn't use the input mixer control that
1880 * the 1888 uses, because it's a pain when you only
1881 * have one mixer.
1882 * Perhaps it could be emulated by keeping both sets of
1883 * gain values, and doing a `context switch' of the
1884 * mixer registers when shifting from playing to
1885 * recording.
1886 */
1887 dip->type = AUDIO_MIXER_ENUM;
1888 dip->un.e.num_mem = 4;
1889 strlcpy(dip->un.e.member[0].label.name,
1890 AudioNmicrophone,
1891 sizeof dip->un.e.member[0].label.name);
1892 dip->un.e.member[0].ord = ESS_SOURCE_MIC;
1893 strlcpy(dip->un.e.member[1].label.name, AudioNline,
1894 sizeof dip->un.e.member[1].label.name);
1895 dip->un.e.member[1].ord = ESS_SOURCE_LINE;
1896 strlcpy(dip->un.e.member[2].label.name, AudioNcd,
1897 sizeof dip->un.e.member[2].label.name);
1898 dip->un.e.member[2].ord = ESS_SOURCE_CD;
1899 strlcpy(dip->un.e.member[3].label.name, AudioNmixerout,
1900 sizeof dip->un.e.member[3].label.name);
1901 dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
1902 } else {
1903 dip->type = AUDIO_MIXER_SET;
1904 dip->un.s.num_mem = 6;
1905 strlcpy(dip->un.s.member[0].label.name, AudioNdac,
1906 sizeof dip->un.e.member[0].label.name);
1907 dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
1908 strlcpy(dip->un.s.member[1].label.name,
1909 AudioNmicrophone,
1910 sizeof dip->un.e.member[1].label.name);
1911 dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
1912 strlcpy(dip->un.s.member[2].label.name, AudioNline,
1913 sizeof dip->un.e.member[2].label.name);
1914 dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
1915 strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth,
1916 sizeof dip->un.e.member[3].label.name);
1917 dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
1918 strlcpy(dip->un.s.member[4].label.name, AudioNcd,
1919 sizeof dip->un.e.member[4].label.name);
1920 dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
1921 strlcpy(dip->un.s.member[5].label.name, "auxb",
1922 sizeof dip->un.e.member[5].label.name);
1923 dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
1924 }
1925 return (0);
1926
1927 case ESS_RECORD_CLASS:
1928 dip->mixer_class = ESS_RECORD_CLASS;
1929 dip->next = dip->prev = AUDIO_MIXER_LAST;
1930 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
1931 dip->type = AUDIO_MIXER_CLASS;
1932 return (0);
1933
1934 case ESS_RECORD_MONITOR:
1935 dip->prev = dip->next = AUDIO_MIXER_LAST;
1936 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
1937 dip->type = AUDIO_MIXER_ENUM;
1938 dip->mixer_class = ESS_MONITOR_CLASS;
1939 dip->un.e.num_mem = 2;
1940 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
1941 sizeof dip->un.e.member[0].label.name);
1942 dip->un.e.member[0].ord = 0;
1943 strlcpy(dip->un.e.member[1].label.name, AudioNon,
1944 sizeof dip->un.e.member[1].label.name);
1945 dip->un.e.member[1].ord = 1;
1946 return (0);
1947
1948 case ESS_MONITOR_CLASS:
1949 dip->mixer_class = ESS_MONITOR_CLASS;
1950 dip->next = dip->prev = AUDIO_MIXER_LAST;
1951 strlcpy(dip->label.name, AudioCmonitor,
1952 sizeof dip->label.name);
1953 dip->type = AUDIO_MIXER_CLASS;
1954 return (0);
1955 }
1956
1957 if (ESS_USE_AUDIO1(sc->sc_model))
1958 return (ENXIO);
1959
1960 switch (dip->index) {
1961 case ESS_DAC_REC_VOL:
1962 dip->mixer_class = ESS_RECORD_CLASS;
1963 dip->next = dip->prev = AUDIO_MIXER_LAST;
1964 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
1965 dip->type = AUDIO_MIXER_VALUE;
1966 dip->un.v.num_channels = 2;
1967 strlcpy(dip->un.v.units.name, AudioNvolume,
1968 sizeof dip->un.v.units.name);
1969 return (0);
1970
1971 case ESS_MIC_REC_VOL:
1972 dip->mixer_class = ESS_RECORD_CLASS;
1973 dip->next = dip->prev = AUDIO_MIXER_LAST;
1974 strlcpy(dip->label.name, AudioNmicrophone,
1975 sizeof dip->label.name);
1976 dip->type = AUDIO_MIXER_VALUE;
1977 dip->un.v.num_channels = 2;
1978 strlcpy(dip->un.v.units.name, AudioNvolume,
1979 sizeof dip->un.v.units.name);
1980 return (0);
1981
1982 case ESS_LINE_REC_VOL:
1983 dip->mixer_class = ESS_RECORD_CLASS;
1984 dip->next = dip->prev = AUDIO_MIXER_LAST;
1985 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
1986 dip->type = AUDIO_MIXER_VALUE;
1987 dip->un.v.num_channels = 2;
1988 strlcpy(dip->un.v.units.name, AudioNvolume,
1989 sizeof dip->un.v.units.name);
1990 return (0);
1991
1992 case ESS_SYNTH_REC_VOL:
1993 dip->mixer_class = ESS_RECORD_CLASS;
1994 dip->next = dip->prev = AUDIO_MIXER_LAST;
1995 strlcpy(dip->label.name, AudioNfmsynth,
1996 sizeof dip->label.name);
1997 dip->type = AUDIO_MIXER_VALUE;
1998 dip->un.v.num_channels = 2;
1999 strlcpy(dip->un.v.units.name, AudioNvolume,
2000 sizeof dip->un.v.units.name);
2001 return (0);
2002
2003 case ESS_CD_REC_VOL:
2004 dip->mixer_class = ESS_RECORD_CLASS;
2005 dip->next = dip->prev = AUDIO_MIXER_LAST;
2006 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
2007 dip->type = AUDIO_MIXER_VALUE;
2008 dip->un.v.num_channels = 2;
2009 strlcpy(dip->un.v.units.name, AudioNvolume,
2010 sizeof dip->un.v.units.name);
2011 return (0);
2012
2013 case ESS_AUXB_REC_VOL:
2014 dip->mixer_class = ESS_RECORD_CLASS;
2015 dip->next = dip->prev = AUDIO_MIXER_LAST;
2016 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
2017 dip->type = AUDIO_MIXER_VALUE;
2018 dip->un.v.num_channels = 2;
2019 strlcpy(dip->un.v.units.name, AudioNvolume,
2020 sizeof dip->un.v.units.name);
2021 return (0);
2022
2023 case ESS_MIC_PREAMP:
2024 dip->mixer_class = ESS_INPUT_CLASS;
2025 dip->prev = ESS_MIC_PLAY_VOL;
2026 dip->next = AUDIO_MIXER_LAST;
2027 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
2028 dip->type = AUDIO_MIXER_ENUM;
2029 dip->un.e.num_mem = 2;
2030 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
2031 sizeof dip->un.e.member[0].label.name);
2032 dip->un.e.member[0].ord = 0;
2033 strlcpy(dip->un.e.member[1].label.name, AudioNon,
2034 sizeof dip->un.e.member[1].label.name);
2035 dip->un.e.member[1].ord = 1;
2036 return (0);
2037 }
2038
2039 return (ENXIO);
2040 }
2041
2042 void *
ess_malloc(void * addr,int direction,size_t size,int pool,int flags)2043 ess_malloc(void *addr, int direction, size_t size, int pool, int flags)
2044 {
2045 struct ess_softc *sc = addr;
2046 int drq;
2047
2048 if (!ESS_USE_AUDIO1(sc->sc_model))
2049 drq = sc->sc_audio2.drq;
2050 else
2051 drq = sc->sc_audio1.drq;
2052 return (isa_malloc(sc->sc_isa, drq, size, pool, flags));
2053 }
2054
2055 void
ess_free(void * addr,void * ptr,int pool)2056 ess_free(void *addr, void *ptr, int pool)
2057 {
2058 isa_free(ptr, pool);
2059 }
2060
2061 size_t
ess_round_buffersize(void * addr,int direction,size_t size)2062 ess_round_buffersize(void *addr, int direction, size_t size)
2063 {
2064 if (size > MAX_ISADMA)
2065 size = MAX_ISADMA;
2066 return (size);
2067 }
2068
2069 /* ============================================
2070 * Generic functions for ess, not used by audio h/w i/f
2071 * =============================================
2072 */
2073
2074 /*
2075 * Reset the chip.
2076 * Return non-zero if the chip isn't detected.
2077 */
2078 int
ess_reset(struct ess_softc * sc)2079 ess_reset(struct ess_softc *sc)
2080 {
2081 bus_space_tag_t iot = sc->sc_iot;
2082 bus_space_handle_t ioh = sc->sc_ioh;
2083
2084 sc->sc_audio1.active = 0;
2085 sc->sc_audio2.active = 0;
2086
2087 EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
2088 delay(10000);
2089 EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
2090 if (ess_rdsp(sc) != ESS_MAGIC)
2091 return (1);
2092
2093 /* Enable access to the ESS extension commands. */
2094 ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
2095
2096 return (0);
2097 }
2098
2099 void
ess_set_gain(struct ess_softc * sc,int port,int on)2100 ess_set_gain(struct ess_softc *sc, int port, int on)
2101 {
2102 int gain, left, right;
2103 int mix;
2104 int src;
2105 int stereo;
2106
2107 /*
2108 * Most gain controls are found in the mixer registers and
2109 * are stereo. Any that are not, must set mix and stereo as
2110 * required.
2111 */
2112 mix = 1;
2113 stereo = 1;
2114
2115 switch (port) {
2116 case ESS_MASTER_VOL:
2117 src = ESS_MREG_VOLUME_MASTER;
2118 break;
2119 case ESS_DAC_PLAY_VOL:
2120 if (ESS_USE_AUDIO1(sc->sc_model))
2121 src = ESS_MREG_VOLUME_VOICE;
2122 else
2123 src = 0x7C;
2124 break;
2125 case ESS_MIC_PLAY_VOL:
2126 src = ESS_MREG_VOLUME_MIC;
2127 break;
2128 case ESS_LINE_PLAY_VOL:
2129 src = ESS_MREG_VOLUME_LINE;
2130 break;
2131 case ESS_SYNTH_PLAY_VOL:
2132 src = ESS_MREG_VOLUME_SYNTH;
2133 break;
2134 case ESS_CD_PLAY_VOL:
2135 src = ESS_MREG_VOLUME_CD;
2136 break;
2137 case ESS_AUXB_PLAY_VOL:
2138 src = ESS_MREG_VOLUME_AUXB;
2139 break;
2140 case ESS_PCSPEAKER_VOL:
2141 src = ESS_MREG_VOLUME_PCSPKR;
2142 stereo = 0;
2143 break;
2144 case ESS_DAC_REC_VOL:
2145 src = 0x69;
2146 break;
2147 case ESS_MIC_REC_VOL:
2148 src = 0x68;
2149 break;
2150 case ESS_LINE_REC_VOL:
2151 src = 0x6E;
2152 break;
2153 case ESS_SYNTH_REC_VOL:
2154 src = 0x6B;
2155 break;
2156 case ESS_CD_REC_VOL:
2157 src = 0x6A;
2158 break;
2159 case ESS_AUXB_REC_VOL:
2160 src = 0x6C;
2161 break;
2162 case ESS_RECORD_VOL:
2163 src = ESS_XCMD_VOLIN_CTRL;
2164 mix = 0;
2165 break;
2166 default:
2167 return;
2168 }
2169
2170 /* 1788 doesn't have a separate recording mixer */
2171 if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
2172 return;
2173
2174 if (on) {
2175 left = sc->gain[port][ESS_LEFT];
2176 right = sc->gain[port][ESS_RIGHT];
2177 } else {
2178 left = right = 0;
2179 }
2180
2181 if (stereo)
2182 gain = ESS_STEREO_GAIN(left, right);
2183 else
2184 gain = ESS_MONO_GAIN(left);
2185
2186 if (mix)
2187 ess_write_mix_reg(sc, src, gain);
2188 else
2189 ess_write_x_reg(sc, src, gain);
2190 }
2191
2192 /* Set the input device on devices without an input mixer. */
2193 int
ess_set_in_port(struct ess_softc * sc,int ord)2194 ess_set_in_port(struct ess_softc *sc, int ord)
2195 {
2196 mixer_devinfo_t di;
2197 int i;
2198
2199 DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
2200
2201 /*
2202 * Get the device info for the record source control,
2203 * including the list of available sources.
2204 */
2205 di.index = ESS_RECORD_SOURCE;
2206 if (ess_query_devinfo(sc, &di))
2207 return EINVAL;
2208
2209 /* See if the given ord value was anywhere in the list. */
2210 for (i = 0; i < di.un.e.num_mem; i++) {
2211 if (ord == di.un.e.member[i].ord)
2212 break;
2213 }
2214 if (i == di.un.e.num_mem)
2215 return EINVAL;
2216
2217 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
2218
2219 sc->in_port = ord;
2220 return (0);
2221 }
2222
2223 /* Set the input device levels on input-mixer-enabled devices. */
2224 int
ess_set_in_ports(struct ess_softc * sc,int mask)2225 ess_set_in_ports(struct ess_softc *sc, int mask)
2226 {
2227 mixer_devinfo_t di;
2228 int i, port;
2229
2230 DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
2231
2232 /*
2233 * Get the device info for the record source control,
2234 * including the list of available sources.
2235 */
2236 di.index = ESS_RECORD_SOURCE;
2237 if (ess_query_devinfo(sc, &di))
2238 return EINVAL;
2239
2240 /*
2241 * Set or disable the record volume control for each of the
2242 * possible sources.
2243 */
2244 for (i = 0; i < di.un.s.num_mem; i++) {
2245 /*
2246 * Calculate the source port number from its mask.
2247 */
2248 port = ffs(di.un.s.member[i].mask);
2249
2250 /*
2251 * Set the source gain:
2252 * to the current value if source is enabled
2253 * to zero if source is disabled
2254 */
2255 ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
2256 }
2257
2258 sc->in_mask = mask;
2259 return (0);
2260 }
2261
2262 void
ess_speaker_on(struct ess_softc * sc)2263 ess_speaker_on(struct ess_softc *sc)
2264 {
2265 /* Unmute the DAC. */
2266 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
2267 }
2268
2269 void
ess_speaker_off(struct ess_softc * sc)2270 ess_speaker_off(struct ess_softc *sc)
2271 {
2272 /* Mute the DAC. */
2273 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
2274 }
2275
2276 /*
2277 * Calculate the time constant for the requested sampling rate.
2278 */
2279 u_int
ess_srtotc(u_int rate)2280 ess_srtotc(u_int rate)
2281 {
2282 u_int tc;
2283
2284 /* The following formulae are from the ESS data sheet. */
2285 if (rate <= 22050)
2286 tc = 128 - 397700L / rate;
2287 else
2288 tc = 256 - 795500L / rate;
2289
2290 return (tc);
2291 }
2292
2293
2294 /*
2295 * Calculate the filter constant for the requested sampling rate.
2296 */
2297 u_int
ess_srtofc(u_int rate)2298 ess_srtofc(u_int rate)
2299 {
2300 /*
2301 * The following formula is derived from the information in
2302 * the ES1887 data sheet, based on a roll-off frequency of
2303 * 87%.
2304 */
2305 return (256 - 200279L / rate);
2306 }
2307
2308
2309 /*
2310 * Return the status of the DSP.
2311 */
2312 u_char
ess_get_dsp_status(struct ess_softc * sc)2313 ess_get_dsp_status(struct ess_softc *sc)
2314 {
2315 return (EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS));
2316 }
2317
2318
2319 /*
2320 * Return the read status of the DSP: 1 -> DSP ready for reading
2321 * 0 -> DSP not ready for reading
2322 */
2323 u_char
ess_dsp_read_ready(struct ess_softc * sc)2324 ess_dsp_read_ready(struct ess_softc *sc)
2325 {
2326 return ((ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0);
2327 }
2328
2329
2330 /*
2331 * Return the write status of the DSP: 1 -> DSP ready for writing
2332 * 0 -> DSP not ready for writing
2333 */
2334 u_char
ess_dsp_write_ready(struct ess_softc * sc)2335 ess_dsp_write_ready(struct ess_softc *sc)
2336 {
2337 return ((ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1);
2338 }
2339
2340
2341 /*
2342 * Read a byte from the DSP.
2343 */
2344 int
ess_rdsp(struct ess_softc * sc)2345 ess_rdsp(struct ess_softc *sc)
2346 {
2347 bus_space_tag_t iot = sc->sc_iot;
2348 bus_space_handle_t ioh = sc->sc_ioh;
2349 int i;
2350
2351 for (i = ESS_READ_TIMEOUT; i > 0; --i) {
2352 if (ess_dsp_read_ready(sc)) {
2353 i = EREAD1(iot, ioh, ESS_DSP_READ);
2354 DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
2355 return i;
2356 } else
2357 delay(10);
2358 }
2359
2360 DPRINTF(("ess_rdsp: timed out\n"));
2361 return (-1);
2362 }
2363
2364 /*
2365 * Write a byte to the DSP.
2366 */
2367 int
ess_wdsp(struct ess_softc * sc,u_char v)2368 ess_wdsp(struct ess_softc *sc, u_char v)
2369 {
2370 bus_space_tag_t iot = sc->sc_iot;
2371 bus_space_handle_t ioh = sc->sc_ioh;
2372 int i;
2373
2374 DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
2375
2376 for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
2377 if (ess_dsp_write_ready(sc)) {
2378 EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
2379 return (0);
2380 } else
2381 delay(10);
2382 }
2383
2384 DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
2385 return (-1);
2386 }
2387
2388 /*
2389 * Write a value to one of the ESS extended registers.
2390 */
2391 int
ess_write_x_reg(struct ess_softc * sc,u_char reg,u_char val)2392 ess_write_x_reg(struct ess_softc *sc, u_char reg, u_char val)
2393 {
2394 int error;
2395
2396 DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
2397 if ((error = ess_wdsp(sc, reg)) == 0)
2398 error = ess_wdsp(sc, val);
2399
2400 return error;
2401 }
2402
2403 /*
2404 * Read the value of one of the ESS extended registers.
2405 */
2406 u_char
ess_read_x_reg(struct ess_softc * sc,u_char reg)2407 ess_read_x_reg(struct ess_softc *sc, u_char reg)
2408 {
2409 int error;
2410 int val;
2411
2412 if ((error = ess_wdsp(sc, 0xC0)) == 0)
2413 error = ess_wdsp(sc, reg);
2414 if (error)
2415 DPRINTF(("Error reading extended register 0x%02x\n", reg));
2416 /* REVISIT: what if an error is returned above? */
2417 val = ess_rdsp(sc);
2418 DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
2419 return val;
2420 }
2421
2422 void
ess_clear_xreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2423 ess_clear_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2424 {
2425 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1)
2426 DPRINTF(("Error clearing bits in extended register 0x%02x\n",
2427 reg));
2428 }
2429
2430 void
ess_set_xreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2431 ess_set_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2432 {
2433 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1)
2434 DPRINTF(("Error setting bits in extended register 0x%02x\n",
2435 reg));
2436 }
2437
2438
2439 /*
2440 * Write a value to one of the ESS mixer registers.
2441 */
2442 void
ess_write_mix_reg(struct ess_softc * sc,u_char reg,u_char val)2443 ess_write_mix_reg(struct ess_softc *sc, u_char reg, u_char val)
2444 {
2445 bus_space_tag_t iot = sc->sc_iot;
2446 bus_space_handle_t ioh = sc->sc_ioh;
2447
2448 DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
2449
2450 mtx_enter(&audio_lock);
2451 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2452 EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
2453 mtx_leave(&audio_lock);
2454 }
2455
2456 /*
2457 * Read the value of one of the ESS mixer registers.
2458 */
2459 u_char
ess_read_mix_reg(struct ess_softc * sc,u_char reg)2460 ess_read_mix_reg(struct ess_softc *sc, u_char reg)
2461 {
2462 bus_space_tag_t iot = sc->sc_iot;
2463 bus_space_handle_t ioh = sc->sc_ioh;
2464 u_char val;
2465
2466 mtx_enter(&audio_lock);
2467 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2468 val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
2469 mtx_leave(&audio_lock);
2470
2471 DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
2472 return val;
2473 }
2474
2475 void
ess_clear_mreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2476 ess_clear_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2477 {
2478 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
2479 }
2480
2481 void
ess_set_mreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2482 ess_set_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2483 {
2484 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
2485 }
2486
2487 void
ess_read_multi_mix_reg(struct ess_softc * sc,u_char reg,u_int8_t * datap,bus_size_t count)2488 ess_read_multi_mix_reg(struct ess_softc *sc, u_char reg, u_int8_t *datap,
2489 bus_size_t count)
2490 {
2491 bus_space_tag_t iot = sc->sc_iot;
2492 bus_space_handle_t ioh = sc->sc_ioh;
2493
2494 mtx_enter(&audio_lock);
2495 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2496 bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
2497 mtx_leave(&audio_lock);
2498 }
2499