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