ess.c revision 1.50 1 /* $NetBSD: ess.c,v 1.50 2000/02/07 22:07:31 thorpej 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/param.h>
69 #include <sys/systm.h>
70 #include <sys/errno.h>
71 #include <sys/ioctl.h>
72 #include <sys/syslog.h>
73 #include <sys/device.h>
74 #include <sys/proc.h>
75 #include <sys/kernel.h>
76
77 #include <machine/cpu.h>
78 #include <machine/intr.h>
79 #include <machine/bus.h>
80
81 #include <sys/audioio.h>
82 #include <dev/audio_if.h>
83 #include <dev/auconv.h>
84 #include <dev/mulaw.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
111 int ess_setup_sc __P((struct ess_softc *, int));
112
113 int ess_open __P((void *, int));
114 void ess_1788_close __P((void *));
115 void ess_1888_close __P((void *));
116 int ess_getdev __P((void *, struct audio_device *));
117 int ess_drain __P((void *));
118
119 int ess_query_encoding __P((void *, struct audio_encoding *));
120
121 int ess_set_params __P((void *, int, int, struct audio_params *,
122 struct audio_params *));
123
124 int ess_round_blocksize __P((void *, int));
125
126 int ess_audio1_trigger_output __P((void *, void *, void *, int,
127 void (*)(void *), void *, struct audio_params *));
128 int ess_audio2_trigger_output __P((void *, void *, void *, int,
129 void (*)(void *), void *, struct audio_params *));
130 int ess_audio1_trigger_input __P((void *, void *, void *, int,
131 void (*)(void *), void *, struct audio_params *));
132 int ess_audio1_halt __P((void *));
133 int ess_audio2_halt __P((void *));
134 int ess_audio1_intr __P((void *));
135 int ess_audio2_intr __P((void *));
136 void ess_audio1_poll __P((void *));
137 void ess_audio2_poll __P((void *));
138
139 int ess_speaker_ctl __P((void *, int));
140
141 int ess_getdev __P((void *, struct audio_device *));
142
143 int ess_set_port __P((void *, mixer_ctrl_t *));
144 int ess_get_port __P((void *, mixer_ctrl_t *));
145
146 void *ess_malloc __P((void *, int, size_t, int, int));
147 void ess_free __P((void *, void *, int));
148 size_t ess_round_buffersize __P((void *, int, size_t));
149 int ess_mappage __P((void *, void *, int, int));
150
151
152 int ess_query_devinfo __P((void *, mixer_devinfo_t *));
153 int ess_1788_get_props __P((void *));
154 int ess_1888_get_props __P((void *));
155
156 void ess_speaker_on __P((struct ess_softc *));
157 void ess_speaker_off __P((struct ess_softc *));
158
159 int ess_config_addr __P((struct ess_softc *));
160 void ess_config_irq __P((struct ess_softc *));
161 void ess_config_drq __P((struct ess_softc *));
162 void ess_setup __P((struct ess_softc *));
163 int ess_identify __P((struct ess_softc *));
164
165 int ess_reset __P((struct ess_softc *));
166 void ess_set_gain __P((struct ess_softc *, int, int));
167 int ess_set_in_port __P((struct ess_softc *, int));
168 int ess_set_in_ports __P((struct ess_softc *, int));
169 u_int ess_srtotc __P((u_int));
170 u_int ess_srtofc __P((u_int));
171 u_char ess_get_dsp_status __P((struct ess_softc *));
172 u_char ess_dsp_read_ready __P((struct ess_softc *));
173 u_char ess_dsp_write_ready __P((struct ess_softc *));
174 int ess_rdsp __P((struct ess_softc *));
175 int ess_wdsp __P((struct ess_softc *, u_char));
176 u_char ess_read_x_reg __P((struct ess_softc *, u_char));
177 int ess_write_x_reg __P((struct ess_softc *, u_char, u_char));
178 void ess_clear_xreg_bits __P((struct ess_softc *, u_char, u_char));
179 void ess_set_xreg_bits __P((struct ess_softc *, u_char, u_char));
180 u_char ess_read_mix_reg __P((struct ess_softc *, u_char));
181 void ess_write_mix_reg __P((struct ess_softc *, u_char, u_char));
182 void ess_clear_mreg_bits __P((struct ess_softc *, u_char, u_char));
183 void ess_set_mreg_bits __P((struct ess_softc *, u_char, u_char));
184 void ess_read_multi_mix_reg __P((struct ess_softc *, u_char, u_int8_t *, bus_size_t));
185
186 static char *essmodel[] = {
187 "unsupported",
188 "1888",
189 "1887",
190 "888",
191 "1788",
192 "1869",
193 "1879",
194 "1868",
195 "1878",
196 };
197
198 struct audio_device ess_device = {
199 "ESS Technology",
200 "x",
201 "ess"
202 };
203
204 /*
205 * Define our interface to the higher level audio driver.
206 */
207
208 struct audio_hw_if ess_1788_hw_if = {
209 ess_open,
210 ess_1788_close,
211 ess_drain,
212 ess_query_encoding,
213 ess_set_params,
214 ess_round_blocksize,
215 NULL,
216 NULL,
217 NULL,
218 NULL,
219 NULL,
220 ess_audio1_halt,
221 ess_audio1_halt,
222 ess_speaker_ctl,
223 ess_getdev,
224 NULL,
225 ess_set_port,
226 ess_get_port,
227 ess_query_devinfo,
228 ess_malloc,
229 ess_free,
230 ess_round_buffersize,
231 ess_mappage,
232 ess_1788_get_props,
233 ess_audio1_trigger_output,
234 ess_audio1_trigger_input,
235 };
236
237 struct audio_hw_if ess_1888_hw_if = {
238 ess_open,
239 ess_1888_close,
240 ess_drain,
241 ess_query_encoding,
242 ess_set_params,
243 ess_round_blocksize,
244 NULL,
245 NULL,
246 NULL,
247 NULL,
248 NULL,
249 ess_audio2_halt,
250 ess_audio1_halt,
251 ess_speaker_ctl,
252 ess_getdev,
253 NULL,
254 ess_set_port,
255 ess_get_port,
256 ess_query_devinfo,
257 ess_malloc,
258 ess_free,
259 ess_round_buffersize,
260 ess_mappage,
261 ess_1888_get_props,
262 ess_audio2_trigger_output,
263 ess_audio1_trigger_input,
264 };
265
266 #ifdef AUDIO_DEBUG
267 void ess_printsc __P((struct ess_softc *));
268 void ess_dump_mixer __P((struct ess_softc *));
269
270 void
271 ess_printsc(sc)
272 struct ess_softc *sc;
273 {
274 int i;
275
276 printf("open %d iobase 0x%x outport %u inport %u speaker %s\n",
277 (int)sc->sc_open, sc->sc_iobase, sc->out_port,
278 sc->in_port, sc->spkr_state ? "on" : "off");
279
280 printf("audio1: dmachan %d irq %d nintr %lu intr %p arg %p\n",
281 sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
282 sc->sc_audio1.intr, sc->sc_audio1.arg);
283
284 if (!ESS_USE_AUDIO1(sc->sc_model)) {
285 printf("audio2: dmachan %d irq %d nintr %lu intr %p arg %p\n",
286 sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
287 sc->sc_audio2.intr, sc->sc_audio2.arg);
288 }
289
290 printf("gain:");
291 for (i = 0; i < sc->ndevs; i++)
292 printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
293 printf("\n");
294 }
295
296 void
297 ess_dump_mixer(sc)
298 struct ess_softc *sc;
299 {
300 printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
301 0x7C, ess_read_mix_reg(sc, 0x7C));
302 printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
303 0x1A, ess_read_mix_reg(sc, 0x1A));
304 printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
305 0x3E, ess_read_mix_reg(sc, 0x3E));
306 printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
307 0x36, ess_read_mix_reg(sc, 0x36));
308 printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
309 0x38, ess_read_mix_reg(sc, 0x38));
310 printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
311 0x3A, ess_read_mix_reg(sc, 0x3A));
312 printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
313 0x32, ess_read_mix_reg(sc, 0x32));
314 printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
315 0x3C, ess_read_mix_reg(sc, 0x3C));
316 printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
317 0x69, ess_read_mix_reg(sc, 0x69));
318 printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
319 0x68, ess_read_mix_reg(sc, 0x68));
320 printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
321 0x6E, ess_read_mix_reg(sc, 0x6E));
322 printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
323 0x6B, ess_read_mix_reg(sc, 0x6B));
324 printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
325 0x6A, ess_read_mix_reg(sc, 0x6A));
326 printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
327 0x6C, ess_read_mix_reg(sc, 0x6C));
328 printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
329 0xB4, ess_read_x_reg(sc, 0xB4));
330 printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
331 0x14, ess_read_mix_reg(sc, 0x14));
332
333 printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
334 ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
335 printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
336 ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
337 printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
338 ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
339 ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
340 }
341
342 #endif
343
344 /*
345 * Configure the ESS chip for the desired audio base address.
346 */
347 int
348 ess_config_addr(sc)
349 struct ess_softc *sc;
350 {
351 int iobase = sc->sc_iobase;
352 bus_space_tag_t iot = sc->sc_iot;
353
354 /*
355 * Configure using the System Control Register method. This
356 * method is used when the AMODE line is tied high, which is
357 * the case for the Shark, but not for the evaluation board.
358 */
359
360 bus_space_handle_t scr_access_ioh;
361 bus_space_handle_t scr_ioh;
362 u_short scr_value;
363
364 /*
365 * Set the SCR bit to enable audio.
366 */
367 scr_value = ESS_SCR_AUDIO_ENABLE;
368
369 /*
370 * Set the SCR bits necessary to select the specified audio
371 * base address.
372 */
373 switch(iobase) {
374 case 0x220:
375 scr_value |= ESS_SCR_AUDIO_220;
376 break;
377 case 0x230:
378 scr_value |= ESS_SCR_AUDIO_230;
379 break;
380 case 0x240:
381 scr_value |= ESS_SCR_AUDIO_240;
382 break;
383 case 0x250:
384 scr_value |= ESS_SCR_AUDIO_250;
385 break;
386 default:
387 printf("ess: configured iobase 0x%x invalid\n", iobase);
388 return (1);
389 break;
390 }
391
392 /*
393 * Get a mapping for the System Control Register (SCR) access
394 * registers and the SCR data registers.
395 */
396 if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
397 0, &scr_access_ioh)) {
398 printf("ess: can't map SCR access registers\n");
399 return (1);
400 }
401 if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
402 0, &scr_ioh)) {
403 printf("ess: can't map SCR registers\n");
404 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
405 return (1);
406 }
407
408 /* Unlock the SCR. */
409 EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
410
411 /* Write the base address information into SCR[0]. */
412 EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
413 EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
414
415 /* Lock the SCR. */
416 EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
417
418 /* Unmap the SCR access ports and the SCR data ports. */
419 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
420 bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
421
422 return 0;
423 }
424
425
426 /*
427 * Configure the ESS chip for the desired IRQ and DMA channels.
428 * ESS ISA
429 * --------
430 * IRQA irq9
431 * IRQB irq5
432 * IRQC irq7
433 * IRQD irq10
434 * IRQE irq15
435 *
436 * DRQA drq0
437 * DRQB drq1
438 * DRQC drq3
439 * DRQD drq5
440 */
441 void
442 ess_config_irq(sc)
443 struct ess_softc *sc;
444 {
445 int v;
446
447 DPRINTFN(2,("ess_config_irq\n"));
448
449 if (sc->sc_model == ESS_1887 &&
450 sc->sc_audio1.irq == sc->sc_audio2.irq &&
451 sc->sc_audio1.irq != -1) {
452 /* Use new method, both interrupts are the same. */
453 v = ESS_IS_SELECT_IRQ; /* enable intrs */
454 switch (sc->sc_audio1.irq) {
455 case 5:
456 v |= ESS_IS_INTRB;
457 break;
458 case 7:
459 v |= ESS_IS_INTRC;
460 break;
461 case 9:
462 v |= ESS_IS_INTRA;
463 break;
464 case 10:
465 v |= ESS_IS_INTRD;
466 break;
467 case 15:
468 v |= ESS_IS_INTRE;
469 break;
470 #ifdef DIAGNOSTIC
471 default:
472 printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
473 sc->sc_audio1.irq);
474 return;
475 #endif
476 }
477 /* Set the IRQ */
478 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
479 return;
480 }
481
482 if (sc->sc_model == ESS_1887) {
483 /* Tell the 1887 to use the old interrupt method. */
484 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
485 }
486
487 if (sc->sc_audio1.polled) {
488 /* Turn off Audio1 interrupts. */
489 v = 0;
490 } else {
491 /* Configure Audio 1 for the appropriate IRQ line. */
492 v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */
493 switch (sc->sc_audio1.irq) {
494 case 5:
495 v |= ESS_IRQ_CTRL_INTRB;
496 break;
497 case 7:
498 v |= ESS_IRQ_CTRL_INTRC;
499 break;
500 case 9:
501 v |= ESS_IRQ_CTRL_INTRA;
502 break;
503 case 10:
504 v |= ESS_IRQ_CTRL_INTRD;
505 break;
506 #ifdef DIAGNOSTIC
507 default:
508 printf("ess: configured irq %d not supported for Audio 1\n",
509 sc->sc_audio1.irq);
510 return;
511 #endif
512 }
513 }
514 ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
515
516 if (ESS_USE_AUDIO1(sc->sc_model))
517 return;
518
519 if (sc->sc_audio2.polled) {
520 /* Turn off Audio2 interrupts. */
521 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
522 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
523 } else {
524 /* Audio2 is hardwired to INTRE in this mode. */
525 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
526 ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
527 }
528 }
529
530
531 void
532 ess_config_drq(sc)
533 struct ess_softc *sc;
534 {
535 int v;
536
537 DPRINTFN(2,("ess_config_drq\n"));
538
539 /* Configure Audio 1 (record) for DMA on the appropriate channel. */
540 v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
541 switch (sc->sc_audio1.drq) {
542 case 0:
543 v |= ESS_DRQ_CTRL_DRQA;
544 break;
545 case 1:
546 v |= ESS_DRQ_CTRL_DRQB;
547 break;
548 case 3:
549 v |= ESS_DRQ_CTRL_DRQC;
550 break;
551 #ifdef DIAGNOSTIC
552 default:
553 printf("ess_config_drq: configured dma chan %d not supported for Audio 1\n",
554 sc->sc_audio1.drq);
555 return;
556 #endif
557 }
558 /* Set DRQ1 */
559 ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
560
561 if (ESS_USE_AUDIO1(sc->sc_model))
562 return;
563
564 /* Configure DRQ2 */
565 v = ESS_AUDIO2_CTRL3_DRQ_PD;
566 switch (sc->sc_audio2.drq) {
567 case 0:
568 v |= ESS_AUDIO2_CTRL3_DRQA;
569 break;
570 case 1:
571 v |= ESS_AUDIO2_CTRL3_DRQB;
572 break;
573 case 3:
574 v |= ESS_AUDIO2_CTRL3_DRQC;
575 break;
576 case 5:
577 v |= ESS_AUDIO2_CTRL3_DRQD;
578 break;
579 #ifdef DIAGNOSTIC
580 default:
581 printf("ess_config_drq: configured dma chan %d not supported for Audio 2\n",
582 sc->sc_audio2.drq);
583 return;
584 #endif
585 }
586 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
587 /* Enable DMA 2 */
588 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
589 ESS_AUDIO2_CTRL2_DMA_ENABLE);
590 }
591
592 /*
593 * Set up registers after a reset.
594 */
595 void
596 ess_setup(sc)
597 struct ess_softc *sc;
598 {
599
600 ess_config_irq(sc);
601 ess_config_drq(sc);
602
603 DPRINTFN(2,("ess_setup: done\n"));
604 }
605
606 /*
607 * Determine the model of ESS chip we are talking to. Currently we
608 * only support ES1888, ES1887 and ES888. The method of determining
609 * the chip is based on the information on page 27 of the ES1887 data
610 * sheet.
611 *
612 * This routine sets the values of sc->sc_model and sc->sc_version.
613 */
614 int
615 ess_identify(sc)
616 struct ess_softc *sc;
617 {
618 u_char reg1;
619 u_char reg2;
620 u_char reg3;
621 u_int8_t ident[4];
622
623 sc->sc_model = ESS_UNSUPPORTED;
624 sc->sc_version = 0;
625
626 memset(ident, 0, sizeof(ident));
627
628 /*
629 * 1. Check legacy ID bytes. These should be 0x68 0x8n, where
630 * n >= 8 for an ES1887 or an ES888. Other values indicate
631 * earlier (unsupported) chips.
632 */
633 ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
634
635 if ((reg1 = ess_rdsp(sc)) != 0x68) {
636 printf("ess: First ID byte wrong (0x%02x)\n", reg1);
637 return 1;
638 }
639
640 reg2 = ess_rdsp(sc);
641 if (((reg2 & 0xf0) != 0x80) ||
642 ((reg2 & 0x0f) < 8)) {
643 printf("ess: Second ID byte wrong (0x%02x)\n", reg2);
644 return 1;
645 }
646
647 /*
648 * Store the ID bytes as the version.
649 */
650 sc->sc_version = (reg1 << 8) + reg2;
651
652
653 /*
654 * 2. Verify we can change bit 2 in mixer register 0x64. This
655 * should be possible on all supported chips.
656 */
657 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
658 reg2 = reg1 ^ 0x04; /* toggle bit 2 */
659
660 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
661
662 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
663 printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
664 return 1;
665 }
666
667 /*
668 * Restore the original value of mixer register 0x64.
669 */
670 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
671
672
673 /*
674 * 3. Verify we can change the value of mixer register
675 * ESS_MREG_SAMPLE_RATE.
676 * This is possible on the 1888/1887/888, but not on the 1788.
677 * It is not necessary to restore the value of this mixer register.
678 */
679 reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
680 reg2 = reg1 ^ 0xff; /* toggle all bits */
681
682 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
683
684 if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
685 /* If we got this far before failing, it's a 1788. */
686 sc->sc_model = ESS_1788;
687
688 /*
689 * Identify ESS model for ES18[67]8.
690 */
691 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
692 if(ident[0] == 0x18) {
693 switch(ident[1]) {
694 case 0x68:
695 sc->sc_model = ESS_1868;
696 break;
697 case 0x78:
698 sc->sc_model = ESS_1878;
699 break;
700 }
701 }
702 } else {
703 /*
704 * 4. Determine if we can change bit 5 in mixer register 0x64.
705 * This determines whether we have an ES1887:
706 *
707 * - can change indicates ES1887
708 * - can't change indicates ES1888 or ES888
709 */
710 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
711 reg2 = reg1 ^ 0x20; /* toggle bit 5 */
712
713 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
714
715 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
716 sc->sc_model = ESS_1887;
717
718 /*
719 * Restore the original value of mixer register 0x64.
720 */
721 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
722
723 /*
724 * Identify ESS model for ES18[67]9.
725 */
726 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
727 if(ident[0] == 0x18) {
728 switch(ident[1]) {
729 case 0x69:
730 sc->sc_model = ESS_1869;
731 break;
732 case 0x79:
733 sc->sc_model = ESS_1879;
734 break;
735 }
736 }
737 } else {
738 /*
739 * 5. Determine if we can change the value of mixer
740 * register 0x69 independently of mixer register
741 * 0x68. This determines which chip we have:
742 *
743 * - can modify idependently indicates ES888
744 * - register 0x69 is an alias of 0x68 indicates ES1888
745 */
746 reg1 = ess_read_mix_reg(sc, 0x68);
747 reg2 = ess_read_mix_reg(sc, 0x69);
748 reg3 = reg2 ^ 0xff; /* toggle all bits */
749
750 /*
751 * Write different values to each register.
752 */
753 ess_write_mix_reg(sc, 0x68, reg2);
754 ess_write_mix_reg(sc, 0x69, reg3);
755
756 if (ess_read_mix_reg(sc, 0x68) == reg2 &&
757 ess_read_mix_reg(sc, 0x69) == reg3)
758 sc->sc_model = ESS_888;
759 else
760 sc->sc_model = ESS_1888;
761
762 /*
763 * Restore the original value of the registers.
764 */
765 ess_write_mix_reg(sc, 0x68, reg1);
766 ess_write_mix_reg(sc, 0x69, reg2);
767 }
768 }
769
770 return 0;
771 }
772
773
774 int
775 ess_setup_sc(sc, doinit)
776 struct ess_softc *sc;
777 int doinit;
778 {
779 /* Reset the chip. */
780 if (ess_reset(sc) != 0) {
781 DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
782 return (1);
783 }
784
785 /* Identify the ESS chip, and check that it is supported. */
786 if (ess_identify(sc)) {
787 DPRINTF(("ess_setup_sc: couldn't identify\n"));
788 return (1);
789 }
790
791 return (0);
792 }
793
794 /*
795 * Probe for the ESS hardware.
796 */
797 int
798 essmatch(sc)
799 struct ess_softc *sc;
800 {
801 if (!ESS_BASE_VALID(sc->sc_iobase)) {
802 printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
803 return (0);
804 }
805
806 /* Configure the ESS chip for the desired audio base address. */
807 if (ess_config_addr(sc))
808 return (0);
809
810 if (ess_setup_sc(sc, 1))
811 return (0);
812
813 if (sc->sc_model == ESS_UNSUPPORTED) {
814 DPRINTF(("ess: Unsupported model\n"));
815 return (0);
816 }
817
818 /* Check that requested DMA channels are valid and different. */
819 if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
820 printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
821 return (0);
822 }
823 if (!isa_drq_isfree(sc->sc_ic, sc->sc_audio1.drq))
824 return (0);
825 if (!ESS_USE_AUDIO1(sc->sc_model)) {
826 if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
827 printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
828 return (0);
829 }
830 if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
831 printf("ess: play and record drq both %d\n",
832 sc->sc_audio1.drq);
833 return (0);
834 }
835 if (!isa_drq_isfree(sc->sc_ic, sc->sc_audio2.drq))
836 return (0);
837 }
838
839 /*
840 * The 1887 has an additional IRQ mode where both channels are mapped
841 * to the same IRQ.
842 */
843 if (sc->sc_model == ESS_1887 &&
844 sc->sc_audio1.irq == sc->sc_audio2.irq &&
845 sc->sc_audio1.irq != -1 &&
846 ESS_IRQ12_VALID(sc->sc_audio1.irq))
847 goto irq_not1888;
848
849 /* Check that requested IRQ lines are valid and different. */
850 if (sc->sc_audio1.irq != -1 &&
851 !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
852 printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
853 return (0);
854 }
855 if (!ESS_USE_AUDIO1(sc->sc_model)) {
856 if (sc->sc_audio2.irq != -1 &&
857 !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
858 printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
859 return (0);
860 }
861 if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
862 sc->sc_audio1.irq != -1) {
863 printf("ess: play and record irq both %d\n",
864 sc->sc_audio1.irq);
865 return (0);
866 }
867 }
868
869 irq_not1888:
870 /* XXX should we check IRQs as well? */
871
872 return (1);
873 }
874
875
876 /*
877 * Attach hardware to driver, attach hardware driver to audio
878 * pseudo-device driver.
879 */
880 void
881 essattach(sc)
882 struct ess_softc *sc;
883 {
884 struct audio_attach_args arg;
885 struct audio_params pparams, rparams;
886 int i;
887 u_int v;
888
889 if (ess_setup_sc(sc, 0)) {
890 printf(": setup failed\n");
891 return;
892 }
893
894 printf(": ESS Technology ES%s [version 0x%04x]\n",
895 essmodel[sc->sc_model], sc->sc_version);
896
897 sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
898 if (!sc->sc_audio1.polled) {
899 sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
900 sc->sc_audio1.irq, sc->sc_audio1.ist, IPL_AUDIO,
901 ess_audio1_intr, sc);
902 printf("%s: audio1 interrupting at irq %d\n",
903 sc->sc_dev.dv_xname, sc->sc_audio1.irq);
904 } else
905 printf("%s: audio1 polled\n", sc->sc_dev.dv_xname);
906 sc->sc_audio1.maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_audio1.drq);
907 if (isa_dmamap_create(sc->sc_ic, sc->sc_audio1.drq,
908 sc->sc_audio1.maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
909 printf("%s: can't create map for drq %d\n",
910 sc->sc_dev.dv_xname, sc->sc_audio1.drq);
911 return;
912 }
913
914 if (!ESS_USE_AUDIO1(sc->sc_model)) {
915 sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
916 if (!sc->sc_audio2.polled) {
917 sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
918 sc->sc_audio2.irq, sc->sc_audio2.ist, IPL_AUDIO,
919 ess_audio2_intr, sc);
920 printf("%s: audio2 interrupting at irq %d\n",
921 sc->sc_dev.dv_xname, sc->sc_audio2.irq);
922 } else
923 printf("%s: audio2 polled\n", sc->sc_dev.dv_xname);
924 sc->sc_audio2.maxsize = isa_dmamaxsize(sc->sc_ic,
925 sc->sc_audio2.drq);
926 if (isa_dmamap_create(sc->sc_ic, sc->sc_audio2.drq,
927 sc->sc_audio2.maxsize, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
928 printf("%s: can't create map for drq %d\n",
929 sc->sc_dev.dv_xname, sc->sc_audio2.drq);
930 return;
931 }
932 }
933
934 /*
935 * Set record and play parameters to default values defined in
936 * generic audio driver.
937 */
938 pparams = audio_default;
939 rparams = audio_default;
940 ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
941
942 /* Do a hardware reset on the mixer. */
943 ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
944
945 /*
946 * Set volume of Audio 1 to zero and disable Audio 1 DAC input
947 * to playback mixer, since playback is always through Audio 2.
948 */
949 if (!ESS_USE_AUDIO1(sc->sc_model))
950 ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
951 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
952
953 if (ESS_USE_AUDIO1(sc->sc_model)) {
954 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
955 sc->in_port = ESS_SOURCE_MIC;
956 sc->ndevs = ESS_1788_NDEVS;
957 } else {
958 /*
959 * Set hardware record source to use output of the record
960 * mixer. We do the selection of record source in software by
961 * setting the gain of the unused sources to zero. (See
962 * ess_set_in_ports.)
963 */
964 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
965 sc->in_mask = 1 << ESS_MIC_REC_VOL;
966 sc->ndevs = ESS_1888_NDEVS;
967 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
968 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
969 }
970
971 /*
972 * Set gain on each mixer device to a sensible value.
973 * Devices not normally used are turned off, and other devices
974 * are set to 50% volume.
975 */
976 for (i = 0; i < sc->ndevs; i++) {
977 switch (i) {
978 case ESS_MIC_PLAY_VOL:
979 case ESS_LINE_PLAY_VOL:
980 case ESS_CD_PLAY_VOL:
981 case ESS_AUXB_PLAY_VOL:
982 case ESS_DAC_REC_VOL:
983 case ESS_LINE_REC_VOL:
984 case ESS_SYNTH_REC_VOL:
985 case ESS_CD_REC_VOL:
986 case ESS_AUXB_REC_VOL:
987 v = 0;
988 break;
989 default:
990 v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
991 break;
992 }
993 sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
994 ess_set_gain(sc, i, 1);
995 }
996
997 ess_setup(sc);
998
999 /* Disable the speaker until the device is opened. */
1000 ess_speaker_off(sc);
1001 sc->spkr_state = SPKR_OFF;
1002
1003 sprintf(ess_device.name, "ES%s", essmodel[sc->sc_model]);
1004 sprintf(ess_device.version, "0x%04x", sc->sc_version);
1005
1006 if (ESS_USE_AUDIO1(sc->sc_model))
1007 audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
1008 else
1009 audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
1010
1011 arg.type = AUDIODEV_TYPE_OPL;
1012 arg.hwif = 0;
1013 arg.hdl = 0;
1014 (void)config_found(&sc->sc_dev, &arg, audioprint);
1015
1016 #ifdef AUDIO_DEBUG
1017 if (essdebug > 0)
1018 ess_printsc(sc);
1019 #endif
1020 }
1021
1022 /*
1023 * Various routines to interface to higher level audio driver
1024 */
1025
1026 int
1027 ess_open(addr, flags)
1028 void *addr;
1029 int flags;
1030 {
1031 struct ess_softc *sc = addr;
1032 int i;
1033
1034 DPRINTF(("ess_open: sc=%p\n", sc));
1035
1036 if (sc->sc_open != 0 || ess_reset(sc) != 0)
1037 return ENXIO;
1038
1039 ess_setup(sc); /* because we did a reset */
1040
1041 /* Set all mixer controls again since some change at reset. */
1042 for (i = 0; i < ESS_MAX_NDEVS; i++)
1043 ess_set_gain(sc, i, 1);
1044
1045 sc->sc_open = 1;
1046
1047 DPRINTF(("ess_open: opened\n"));
1048
1049 return (0);
1050 }
1051
1052 void
1053 ess_1788_close(addr)
1054 void *addr;
1055 {
1056 struct ess_softc *sc = addr;
1057
1058 DPRINTF(("ess_1788_close: sc=%p\n", sc));
1059
1060 ess_speaker_off(sc);
1061 sc->spkr_state = SPKR_OFF;
1062
1063 ess_audio1_halt(sc);
1064
1065 sc->sc_open = 0;
1066 DPRINTF(("ess_1788_close: closed\n"));
1067 }
1068
1069 void
1070 ess_1888_close(addr)
1071 void *addr;
1072 {
1073 struct ess_softc *sc = addr;
1074
1075 DPRINTF(("ess_1888_close: sc=%p\n", sc));
1076
1077 ess_speaker_off(sc);
1078 sc->spkr_state = SPKR_OFF;
1079
1080 ess_audio1_halt(sc);
1081 ess_audio2_halt(sc);
1082
1083 sc->sc_open = 0;
1084 DPRINTF(("ess_1888_close: closed\n"));
1085 }
1086
1087 /*
1088 * Wait for FIFO to drain, and analog section to settle.
1089 * XXX should check FIFO empty bit.
1090 */
1091 int
1092 ess_drain(addr)
1093 void *addr;
1094 {
1095 tsleep(addr, PWAIT | PCATCH, "essdr", hz/20); /* XXX */
1096 return (0);
1097 }
1098
1099 /* XXX should use reference count */
1100 int
1101 ess_speaker_ctl(addr, newstate)
1102 void *addr;
1103 int newstate;
1104 {
1105 struct ess_softc *sc = addr;
1106
1107 if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
1108 ess_speaker_on(sc);
1109 sc->spkr_state = SPKR_ON;
1110 }
1111 if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
1112 ess_speaker_off(sc);
1113 sc->spkr_state = SPKR_OFF;
1114 }
1115 return (0);
1116 }
1117
1118 int
1119 ess_getdev(addr, retp)
1120 void *addr;
1121 struct audio_device *retp;
1122 {
1123 *retp = ess_device;
1124 return (0);
1125 }
1126
1127 int
1128 ess_query_encoding(addr, fp)
1129 void *addr;
1130 struct audio_encoding *fp;
1131 {
1132 /*struct ess_softc *sc = addr;*/
1133
1134 switch (fp->index) {
1135 case 0:
1136 strcpy(fp->name, AudioEulinear);
1137 fp->encoding = AUDIO_ENCODING_ULINEAR;
1138 fp->precision = 8;
1139 fp->flags = 0;
1140 return (0);
1141 case 1:
1142 strcpy(fp->name, AudioEmulaw);
1143 fp->encoding = AUDIO_ENCODING_ULAW;
1144 fp->precision = 8;
1145 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1146 return (0);
1147 case 2:
1148 strcpy(fp->name, AudioEalaw);
1149 fp->encoding = AUDIO_ENCODING_ALAW;
1150 fp->precision = 8;
1151 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1152 return (0);
1153 case 3:
1154 strcpy(fp->name, AudioEslinear);
1155 fp->encoding = AUDIO_ENCODING_SLINEAR;
1156 fp->precision = 8;
1157 fp->flags = 0;
1158 return (0);
1159 case 4:
1160 strcpy(fp->name, AudioEslinear_le);
1161 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
1162 fp->precision = 16;
1163 fp->flags = 0;
1164 return (0);
1165 case 5:
1166 strcpy(fp->name, AudioEulinear_le);
1167 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
1168 fp->precision = 16;
1169 fp->flags = 0;
1170 return (0);
1171 case 6:
1172 strcpy(fp->name, AudioEslinear_be);
1173 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
1174 fp->precision = 16;
1175 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1176 return (0);
1177 case 7:
1178 strcpy(fp->name, AudioEulinear_be);
1179 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
1180 fp->precision = 16;
1181 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1182 return (0);
1183 default:
1184 return EINVAL;
1185 }
1186 return (0);
1187 }
1188
1189 int
1190 ess_set_params(addr, setmode, usemode, play, rec)
1191 void *addr;
1192 int setmode, usemode;
1193 struct audio_params *play, *rec;
1194 {
1195 struct ess_softc *sc = addr;
1196 struct audio_params *p;
1197 int mode;
1198 int rate;
1199
1200 DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
1201
1202 /*
1203 * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in
1204 * full-duplex operation the sample rates must be the same for both
1205 * channels. This appears to be false; the only bit in common is the
1206 * clock source selection. However, we'll be conservative here.
1207 * - mycroft
1208 */
1209 if (play->sample_rate != rec->sample_rate &&
1210 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
1211 if (setmode == AUMODE_PLAY) {
1212 rec->sample_rate = play->sample_rate;
1213 setmode |= AUMODE_RECORD;
1214 } else if (setmode == AUMODE_RECORD) {
1215 play->sample_rate = rec->sample_rate;
1216 setmode |= AUMODE_PLAY;
1217 } else
1218 return (EINVAL);
1219 }
1220
1221 for (mode = AUMODE_RECORD; mode != -1;
1222 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
1223 if ((setmode & mode) == 0)
1224 continue;
1225
1226 p = mode == AUMODE_PLAY ? play : rec;
1227
1228 if (p->sample_rate < ESS_MINRATE ||
1229 p->sample_rate > ESS_MAXRATE ||
1230 (p->precision != 8 && p->precision != 16) ||
1231 (p->channels != 1 && p->channels != 2))
1232 return (EINVAL);
1233
1234 p->factor = 1;
1235 p->sw_code = 0;
1236 switch (p->encoding) {
1237 case AUDIO_ENCODING_SLINEAR_BE:
1238 case AUDIO_ENCODING_ULINEAR_BE:
1239 if (p->precision == 16)
1240 p->sw_code = swap_bytes;
1241 break;
1242 case AUDIO_ENCODING_SLINEAR_LE:
1243 case AUDIO_ENCODING_ULINEAR_LE:
1244 break;
1245 case AUDIO_ENCODING_ULAW:
1246 if (mode == AUMODE_PLAY) {
1247 p->factor = 2;
1248 p->sw_code = mulaw_to_ulinear16_le;
1249 } else
1250 p->sw_code = ulinear8_to_mulaw;
1251 break;
1252 case AUDIO_ENCODING_ALAW:
1253 if (mode == AUMODE_PLAY) {
1254 p->factor = 2;
1255 p->sw_code = alaw_to_ulinear16_le;
1256 } else
1257 p->sw_code = ulinear8_to_alaw;
1258 break;
1259 default:
1260 return (EINVAL);
1261 }
1262 }
1263
1264 if (usemode == AUMODE_RECORD)
1265 rate = rec->sample_rate;
1266 else
1267 rate = play->sample_rate;
1268
1269 ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
1270 ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
1271
1272 if (!ESS_USE_AUDIO1(sc->sc_model)) {
1273 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
1274 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
1275 }
1276
1277 return (0);
1278 }
1279
1280 int
1281 ess_audio1_trigger_output(addr, start, end, blksize, intr, arg, param)
1282 void *addr;
1283 void *start, *end;
1284 int blksize;
1285 void (*intr) __P((void *));
1286 void *arg;
1287 struct audio_params *param;
1288 {
1289 struct ess_softc *sc = addr;
1290 u_int8_t reg;
1291
1292 DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1293 addr, start, end, blksize, intr, arg));
1294
1295 if (sc->sc_audio1.active)
1296 panic("ess_audio1_trigger_output: already running");
1297
1298 sc->sc_audio1.active = 1;
1299 sc->sc_audio1.intr = intr;
1300 sc->sc_audio1.arg = arg;
1301 if (sc->sc_audio1.polled) {
1302 sc->sc_audio1.dmapos = 0;
1303 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1304 sc->sc_audio1.dmacount = 0;
1305 sc->sc_audio1.blksize = blksize;
1306 timeout(ess_audio1_poll, sc, hz/30);
1307 }
1308
1309 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1310 if (param->channels == 2) {
1311 reg &= ~ESS_AUDIO_CTRL_MONO;
1312 reg |= ESS_AUDIO_CTRL_STEREO;
1313 } else {
1314 reg |= ESS_AUDIO_CTRL_MONO;
1315 reg &= ~ESS_AUDIO_CTRL_STEREO;
1316 }
1317 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1318
1319 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1320 if (param->precision * param->factor == 16)
1321 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1322 else
1323 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1324 if (param->channels == 2)
1325 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1326 else
1327 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1328 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1329 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1330 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1331 else
1332 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1333 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1334 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1335
1336 isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1337 (char *)end - (char *)start, NULL,
1338 DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1339
1340 /* Program transfer count registers with 2's complement of count. */
1341 blksize = -blksize;
1342 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1343 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1344
1345 /* Use 4 bytes per output DMA. */
1346 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1347
1348 /* Start auto-init DMA */
1349 ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
1350 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1351 reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
1352 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1353 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1354
1355 return (0);
1356 }
1357
1358 int
1359 ess_audio2_trigger_output(addr, start, end, blksize, intr, arg, param)
1360 void *addr;
1361 void *start, *end;
1362 int blksize;
1363 void (*intr) __P((void *));
1364 void *arg;
1365 struct audio_params *param;
1366 {
1367 struct ess_softc *sc = addr;
1368 u_int8_t reg;
1369
1370 DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1371 addr, start, end, blksize, intr, arg));
1372
1373 if (sc->sc_audio2.active)
1374 panic("ess_audio2_trigger_output: already running");
1375
1376 sc->sc_audio2.active = 1;
1377 sc->sc_audio2.intr = intr;
1378 sc->sc_audio2.arg = arg;
1379 if (sc->sc_audio2.polled) {
1380 sc->sc_audio2.dmapos = 0;
1381 sc->sc_audio2.buffersize = (char *)end - (char *)start;
1382 sc->sc_audio2.dmacount = 0;
1383 sc->sc_audio2.blksize = blksize;
1384 timeout(ess_audio2_poll, sc, hz/30);
1385 }
1386
1387 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1388 if (param->precision * param->factor == 16)
1389 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
1390 else
1391 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
1392 if (param->channels == 2)
1393 reg |= ESS_AUDIO2_CTRL2_CHANNELS;
1394 else
1395 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
1396 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1397 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1398 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1399 else
1400 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1401 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1402
1403 isa_dmastart(sc->sc_ic, sc->sc_audio2.drq, start,
1404 (char *)end - (char *)start, NULL,
1405 DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1406
1407 if (IS16BITDRQ(sc->sc_audio2.drq))
1408 blksize >>= 1; /* use word count for 16 bit DMA */
1409 /* Program transfer count registers with 2's complement of count. */
1410 blksize = -blksize;
1411 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
1412 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
1413
1414 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
1415 if (IS16BITDRQ(sc->sc_audio2.drq))
1416 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
1417 else
1418 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
1419 reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
1420 reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
1421 ESS_AUDIO2_CTRL1_AUTO_INIT;
1422 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
1423
1424 return (0);
1425 }
1426
1427 int
1428 ess_audio1_trigger_input(addr, start, end, blksize, intr, arg, param)
1429 void *addr;
1430 void *start, *end;
1431 int blksize;
1432 void (*intr) __P((void *));
1433 void *arg;
1434 struct audio_params *param;
1435 {
1436 struct ess_softc *sc = addr;
1437 u_int8_t reg;
1438
1439 DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1440 addr, start, end, blksize, intr, arg));
1441
1442 if (sc->sc_audio1.active)
1443 panic("ess_audio1_trigger_input: already running");
1444
1445 sc->sc_audio1.active = 1;
1446 sc->sc_audio1.intr = intr;
1447 sc->sc_audio1.arg = arg;
1448 if (sc->sc_audio1.polled) {
1449 sc->sc_audio1.dmapos = 0;
1450 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1451 sc->sc_audio1.dmacount = 0;
1452 sc->sc_audio1.blksize = blksize;
1453 timeout(ess_audio1_poll, sc, hz/30);
1454 }
1455
1456 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1457 if (param->channels == 2) {
1458 reg &= ~ESS_AUDIO_CTRL_MONO;
1459 reg |= ESS_AUDIO_CTRL_STEREO;
1460 } else {
1461 reg |= ESS_AUDIO_CTRL_MONO;
1462 reg &= ~ESS_AUDIO_CTRL_STEREO;
1463 }
1464 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1465
1466 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1467 if (param->precision * param->factor == 16)
1468 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1469 else
1470 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1471 if (param->channels == 2)
1472 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1473 else
1474 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1475 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1476 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1477 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1478 else
1479 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1480 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1481 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1482
1483 isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1484 (char *)end - (char *)start, NULL,
1485 DMAMODE_READ | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1486
1487 /* Program transfer count registers with 2's complement of count. */
1488 blksize = -blksize;
1489 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1490 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1491
1492 /* Use 4 bytes per input DMA. */
1493 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1494
1495 /* Start auto-init DMA */
1496 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
1497 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1498 reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
1499 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1500 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1501
1502 return (0);
1503 }
1504
1505 int
1506 ess_audio1_halt(addr)
1507 void *addr;
1508 {
1509 struct ess_softc *sc = addr;
1510
1511 DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
1512
1513 if (sc->sc_audio1.active) {
1514 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
1515 ESS_AUDIO1_CTRL2_FIFO_ENABLE);
1516 isa_dmaabort(sc->sc_ic, sc->sc_audio1.drq);
1517 if (sc->sc_audio1.polled)
1518 untimeout(ess_audio1_poll, sc);
1519 sc->sc_audio1.active = 0;
1520 }
1521
1522 return (0);
1523 }
1524
1525 int
1526 ess_audio2_halt(addr)
1527 void *addr;
1528 {
1529 struct ess_softc *sc = addr;
1530
1531 DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
1532
1533 if (sc->sc_audio2.active) {
1534 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
1535 ESS_AUDIO2_CTRL1_DAC_ENABLE |
1536 ESS_AUDIO2_CTRL1_FIFO_ENABLE);
1537 isa_dmaabort(sc->sc_ic, sc->sc_audio2.drq);
1538 if (sc->sc_audio2.polled)
1539 untimeout(ess_audio2_poll, sc);
1540 sc->sc_audio2.active = 0;
1541 }
1542
1543 return (0);
1544 }
1545
1546 int
1547 ess_audio1_intr(arg)
1548 void *arg;
1549 {
1550 struct ess_softc *sc = arg;
1551 u_int8_t reg;
1552
1553 DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
1554
1555 /* Check and clear interrupt on Audio1. */
1556 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
1557 if ((reg & ESS_DSP_READ_OFLOW) == 0)
1558 return (0);
1559 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
1560
1561 sc->sc_audio1.nintr++;
1562
1563 if (sc->sc_audio1.active) {
1564 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1565 return (1);
1566 } else
1567 return (0);
1568 }
1569
1570 int
1571 ess_audio2_intr(arg)
1572 void *arg;
1573 {
1574 struct ess_softc *sc = arg;
1575 u_int8_t reg;
1576
1577 DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
1578
1579 /* Check and clear interrupt on Audio2. */
1580 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1581 if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0)
1582 return (0);
1583 reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
1584 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1585
1586 sc->sc_audio2.nintr++;
1587
1588 if (sc->sc_audio2.active) {
1589 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1590 return (1);
1591 } else
1592 return (0);
1593 }
1594
1595 void
1596 ess_audio1_poll(addr)
1597 void *addr;
1598 {
1599 struct ess_softc *sc = addr;
1600 int dmapos, dmacount;
1601
1602 if (!sc->sc_audio1.active)
1603 return;
1604
1605 sc->sc_audio1.nintr++;
1606
1607 dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio1.drq);
1608 dmacount = sc->sc_audio1.dmapos - dmapos;
1609 if (dmacount < 0)
1610 dmacount += sc->sc_audio1.buffersize;
1611 sc->sc_audio1.dmapos = dmapos;
1612 #if 1
1613 dmacount += sc->sc_audio1.dmacount;
1614 while (dmacount > sc->sc_audio1.blksize) {
1615 dmacount -= sc->sc_audio1.blksize;
1616 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1617 }
1618 sc->sc_audio1.dmacount = dmacount;
1619 #else
1620 (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
1621 #endif
1622
1623 timeout(ess_audio1_poll, sc, hz/30);
1624 }
1625
1626 void
1627 ess_audio2_poll(addr)
1628 void *addr;
1629 {
1630 struct ess_softc *sc = addr;
1631 int dmapos, dmacount;
1632
1633 if (!sc->sc_audio2.active)
1634 return;
1635
1636 sc->sc_audio2.nintr++;
1637
1638 dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio2.drq);
1639 dmacount = sc->sc_audio2.dmapos - dmapos;
1640 if (dmacount < 0)
1641 dmacount += sc->sc_audio2.buffersize;
1642 sc->sc_audio2.dmapos = dmapos;
1643 #if 1
1644 dmacount += sc->sc_audio2.dmacount;
1645 while (dmacount > sc->sc_audio2.blksize) {
1646 dmacount -= sc->sc_audio2.blksize;
1647 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1648 }
1649 sc->sc_audio2.dmacount = dmacount;
1650 #else
1651 (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
1652 #endif
1653
1654 timeout(ess_audio2_poll, sc, hz/30);
1655 }
1656
1657 int
1658 ess_round_blocksize(addr, blk)
1659 void *addr;
1660 int blk;
1661 {
1662 return (blk & -8); /* round for max DMA size */
1663 }
1664
1665 int
1666 ess_set_port(addr, cp)
1667 void *addr;
1668 mixer_ctrl_t *cp;
1669 {
1670 struct ess_softc *sc = addr;
1671 int lgain, rgain;
1672
1673 DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
1674 cp->dev, cp->un.value.num_channels));
1675
1676 switch (cp->dev) {
1677 /*
1678 * The following mixer ports are all stereo. If we get a
1679 * single-channel gain value passed in, then we duplicate it
1680 * to both left and right channels.
1681 */
1682 case ESS_MASTER_VOL:
1683 case ESS_DAC_PLAY_VOL:
1684 case ESS_MIC_PLAY_VOL:
1685 case ESS_LINE_PLAY_VOL:
1686 case ESS_SYNTH_PLAY_VOL:
1687 case ESS_CD_PLAY_VOL:
1688 case ESS_AUXB_PLAY_VOL:
1689 case ESS_RECORD_VOL:
1690 if (cp->type != AUDIO_MIXER_VALUE)
1691 return EINVAL;
1692
1693 switch (cp->un.value.num_channels) {
1694 case 1:
1695 lgain = rgain = ESS_4BIT_GAIN(
1696 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1697 break;
1698 case 2:
1699 lgain = ESS_4BIT_GAIN(
1700 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1701 rgain = ESS_4BIT_GAIN(
1702 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1703 break;
1704 default:
1705 return EINVAL;
1706 }
1707
1708 sc->gain[cp->dev][ESS_LEFT] = lgain;
1709 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1710 ess_set_gain(sc, cp->dev, 1);
1711 return (0);
1712
1713 /*
1714 * The PC speaker port is mono. If we get a stereo gain value
1715 * passed in, then we return EINVAL.
1716 */
1717 case ESS_PCSPEAKER_VOL:
1718 if (cp->un.value.num_channels != 1)
1719 return EINVAL;
1720
1721 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
1722 ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1723 ess_set_gain(sc, cp->dev, 1);
1724 return (0);
1725
1726 case ESS_RECORD_SOURCE:
1727 if (ESS_USE_AUDIO1(sc->sc_model)) {
1728 if (cp->type == AUDIO_MIXER_ENUM)
1729 return (ess_set_in_port(sc, cp->un.ord));
1730 else
1731 return (EINVAL);
1732 } else {
1733 if (cp->type == AUDIO_MIXER_SET)
1734 return (ess_set_in_ports(sc, cp->un.mask));
1735 else
1736 return (EINVAL);
1737 }
1738 return (0);
1739
1740 case ESS_RECORD_MONITOR:
1741 if (cp->type != AUDIO_MIXER_ENUM)
1742 return EINVAL;
1743
1744 if (cp->un.ord)
1745 /* Enable monitor */
1746 ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1747 ESS_AUDIO_CTRL_MONITOR);
1748 else
1749 /* Disable monitor */
1750 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1751 ESS_AUDIO_CTRL_MONITOR);
1752 return (0);
1753 }
1754
1755 if (ESS_USE_AUDIO1(sc->sc_model))
1756 return (EINVAL);
1757
1758 switch (cp->dev) {
1759 case ESS_DAC_REC_VOL:
1760 case ESS_MIC_REC_VOL:
1761 case ESS_LINE_REC_VOL:
1762 case ESS_SYNTH_REC_VOL:
1763 case ESS_CD_REC_VOL:
1764 case ESS_AUXB_REC_VOL:
1765 if (cp->type != AUDIO_MIXER_VALUE)
1766 return EINVAL;
1767
1768 switch (cp->un.value.num_channels) {
1769 case 1:
1770 lgain = rgain = ESS_4BIT_GAIN(
1771 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1772 break;
1773 case 2:
1774 lgain = ESS_4BIT_GAIN(
1775 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1776 rgain = ESS_4BIT_GAIN(
1777 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1778 break;
1779 default:
1780 return EINVAL;
1781 }
1782
1783 sc->gain[cp->dev][ESS_LEFT] = lgain;
1784 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1785 ess_set_gain(sc, cp->dev, 1);
1786 return (0);
1787
1788 case ESS_MIC_PREAMP:
1789 if (cp->type != AUDIO_MIXER_ENUM)
1790 return EINVAL;
1791
1792 if (cp->un.ord)
1793 /* Enable microphone preamp */
1794 ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1795 ESS_PREAMP_CTRL_ENABLE);
1796 else
1797 /* Disable microphone preamp */
1798 ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1799 ESS_PREAMP_CTRL_ENABLE);
1800 return (0);
1801 }
1802
1803 return (EINVAL);
1804 }
1805
1806 int
1807 ess_get_port(addr, cp)
1808 void *addr;
1809 mixer_ctrl_t *cp;
1810 {
1811 struct ess_softc *sc = addr;
1812
1813 DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
1814
1815 switch (cp->dev) {
1816 case ESS_MASTER_VOL:
1817 case ESS_DAC_PLAY_VOL:
1818 case ESS_MIC_PLAY_VOL:
1819 case ESS_LINE_PLAY_VOL:
1820 case ESS_SYNTH_PLAY_VOL:
1821 case ESS_CD_PLAY_VOL:
1822 case ESS_AUXB_PLAY_VOL:
1823 case ESS_RECORD_VOL:
1824 switch (cp->un.value.num_channels) {
1825 case 1:
1826 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1827 sc->gain[cp->dev][ESS_LEFT];
1828 break;
1829 case 2:
1830 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1831 sc->gain[cp->dev][ESS_LEFT];
1832 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1833 sc->gain[cp->dev][ESS_RIGHT];
1834 break;
1835 default:
1836 return EINVAL;
1837 }
1838 return (0);
1839
1840 case ESS_PCSPEAKER_VOL:
1841 if (cp->un.value.num_channels != 1)
1842 return EINVAL;
1843
1844 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1845 sc->gain[cp->dev][ESS_LEFT];
1846 return (0);
1847
1848 case ESS_RECORD_SOURCE:
1849 if (ESS_USE_AUDIO1(sc->sc_model))
1850 cp->un.ord = sc->in_port;
1851 else
1852 cp->un.mask = sc->in_mask;
1853 return (0);
1854
1855 case ESS_RECORD_MONITOR:
1856 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
1857 ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
1858 return (0);
1859 }
1860
1861 if (ESS_USE_AUDIO1(sc->sc_model))
1862 return (EINVAL);
1863
1864 switch (cp->dev) {
1865 case ESS_DAC_REC_VOL:
1866 case ESS_MIC_REC_VOL:
1867 case ESS_LINE_REC_VOL:
1868 case ESS_SYNTH_REC_VOL:
1869 case ESS_CD_REC_VOL:
1870 case ESS_AUXB_REC_VOL:
1871 switch (cp->un.value.num_channels) {
1872 case 1:
1873 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1874 sc->gain[cp->dev][ESS_LEFT];
1875 break;
1876 case 2:
1877 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1878 sc->gain[cp->dev][ESS_LEFT];
1879 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1880 sc->gain[cp->dev][ESS_RIGHT];
1881 break;
1882 default:
1883 return EINVAL;
1884 }
1885 return (0);
1886
1887 case ESS_MIC_PREAMP:
1888 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
1889 ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
1890 return (0);
1891 }
1892
1893 return (EINVAL);
1894 }
1895
1896 int
1897 ess_query_devinfo(addr, dip)
1898 void *addr;
1899 mixer_devinfo_t *dip;
1900 {
1901 struct ess_softc *sc = addr;
1902
1903 DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
1904 sc->sc_model, dip->index));
1905
1906 /*
1907 * REVISIT: There are some slight differences between the
1908 * mixers on the different ESS chips, which can
1909 * be sorted out using the chip model rather than a
1910 * separate mixer model.
1911 * This is currently coded assuming an ES1887; we
1912 * need to work out which bits are not applicable to
1913 * the other models (1888 and 888).
1914 */
1915 switch (dip->index) {
1916 case ESS_DAC_PLAY_VOL:
1917 dip->mixer_class = ESS_INPUT_CLASS;
1918 dip->next = dip->prev = AUDIO_MIXER_LAST;
1919 strcpy(dip->label.name, AudioNdac);
1920 dip->type = AUDIO_MIXER_VALUE;
1921 dip->un.v.num_channels = 2;
1922 strcpy(dip->un.v.units.name, AudioNvolume);
1923 return (0);
1924
1925 case ESS_MIC_PLAY_VOL:
1926 dip->mixer_class = ESS_INPUT_CLASS;
1927 dip->prev = AUDIO_MIXER_LAST;
1928 if (ESS_USE_AUDIO1(sc->sc_model))
1929 dip->next = AUDIO_MIXER_LAST;
1930 else
1931 dip->next = ESS_MIC_PREAMP;
1932 strcpy(dip->label.name, AudioNmicrophone);
1933 dip->type = AUDIO_MIXER_VALUE;
1934 dip->un.v.num_channels = 2;
1935 strcpy(dip->un.v.units.name, AudioNvolume);
1936 return (0);
1937
1938 case ESS_LINE_PLAY_VOL:
1939 dip->mixer_class = ESS_INPUT_CLASS;
1940 dip->next = dip->prev = AUDIO_MIXER_LAST;
1941 strcpy(dip->label.name, AudioNline);
1942 dip->type = AUDIO_MIXER_VALUE;
1943 dip->un.v.num_channels = 2;
1944 strcpy(dip->un.v.units.name, AudioNvolume);
1945 return (0);
1946
1947 case ESS_SYNTH_PLAY_VOL:
1948 dip->mixer_class = ESS_INPUT_CLASS;
1949 dip->next = dip->prev = AUDIO_MIXER_LAST;
1950 strcpy(dip->label.name, AudioNfmsynth);
1951 dip->type = AUDIO_MIXER_VALUE;
1952 dip->un.v.num_channels = 2;
1953 strcpy(dip->un.v.units.name, AudioNvolume);
1954 return (0);
1955
1956 case ESS_CD_PLAY_VOL:
1957 dip->mixer_class = ESS_INPUT_CLASS;
1958 dip->next = dip->prev = AUDIO_MIXER_LAST;
1959 strcpy(dip->label.name, AudioNcd);
1960 dip->type = AUDIO_MIXER_VALUE;
1961 dip->un.v.num_channels = 2;
1962 strcpy(dip->un.v.units.name, AudioNvolume);
1963 return (0);
1964
1965 case ESS_AUXB_PLAY_VOL:
1966 dip->mixer_class = ESS_INPUT_CLASS;
1967 dip->next = dip->prev = AUDIO_MIXER_LAST;
1968 strcpy(dip->label.name, "auxb");
1969 dip->type = AUDIO_MIXER_VALUE;
1970 dip->un.v.num_channels = 2;
1971 strcpy(dip->un.v.units.name, AudioNvolume);
1972 return (0);
1973
1974 case ESS_INPUT_CLASS:
1975 dip->mixer_class = ESS_INPUT_CLASS;
1976 dip->next = dip->prev = AUDIO_MIXER_LAST;
1977 strcpy(dip->label.name, AudioCinputs);
1978 dip->type = AUDIO_MIXER_CLASS;
1979 return (0);
1980
1981 case ESS_MASTER_VOL:
1982 dip->mixer_class = ESS_OUTPUT_CLASS;
1983 dip->next = dip->prev = AUDIO_MIXER_LAST;
1984 strcpy(dip->label.name, AudioNmaster);
1985 dip->type = AUDIO_MIXER_VALUE;
1986 dip->un.v.num_channels = 2;
1987 strcpy(dip->un.v.units.name, AudioNvolume);
1988 return (0);
1989
1990 case ESS_PCSPEAKER_VOL:
1991 dip->mixer_class = ESS_OUTPUT_CLASS;
1992 dip->next = dip->prev = AUDIO_MIXER_LAST;
1993 strcpy(dip->label.name, "pc_speaker");
1994 dip->type = AUDIO_MIXER_VALUE;
1995 dip->un.v.num_channels = 1;
1996 strcpy(dip->un.v.units.name, AudioNvolume);
1997 return (0);
1998
1999 case ESS_OUTPUT_CLASS:
2000 dip->mixer_class = ESS_OUTPUT_CLASS;
2001 dip->next = dip->prev = AUDIO_MIXER_LAST;
2002 strcpy(dip->label.name, AudioCoutputs);
2003 dip->type = AUDIO_MIXER_CLASS;
2004 return (0);
2005
2006 case ESS_RECORD_VOL:
2007 dip->mixer_class = ESS_RECORD_CLASS;
2008 dip->next = dip->prev = AUDIO_MIXER_LAST;
2009 strcpy(dip->label.name, AudioNrecord);
2010 dip->type = AUDIO_MIXER_VALUE;
2011 dip->un.v.num_channels = 2;
2012 strcpy(dip->un.v.units.name, AudioNvolume);
2013 return (0);
2014
2015 case ESS_RECORD_SOURCE:
2016 dip->mixer_class = ESS_RECORD_CLASS;
2017 dip->next = dip->prev = AUDIO_MIXER_LAST;
2018 strcpy(dip->label.name, AudioNsource);
2019 if (ESS_USE_AUDIO1(sc->sc_model)) {
2020 /*
2021 * The 1788 doesn't use the input mixer control that
2022 * the 1888 uses, because it's a pain when you only
2023 * have one mixer.
2024 * Perhaps it could be emulated by keeping both sets of
2025 * gain values, and doing a `context switch' of the
2026 * mixer registers when shifting from playing to
2027 * recording.
2028 */
2029 dip->type = AUDIO_MIXER_ENUM;
2030 dip->un.e.num_mem = 4;
2031 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
2032 dip->un.e.member[0].ord = ESS_SOURCE_MIC;
2033 strcpy(dip->un.e.member[1].label.name, AudioNline);
2034 dip->un.e.member[1].ord = ESS_SOURCE_LINE;
2035 strcpy(dip->un.e.member[2].label.name, AudioNcd);
2036 dip->un.e.member[2].ord = ESS_SOURCE_CD;
2037 strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
2038 dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
2039 } else {
2040 dip->type = AUDIO_MIXER_SET;
2041 dip->un.s.num_mem = 6;
2042 strcpy(dip->un.s.member[0].label.name, AudioNdac);
2043 dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
2044 strcpy(dip->un.s.member[1].label.name, AudioNmicrophone);
2045 dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
2046 strcpy(dip->un.s.member[2].label.name, AudioNline);
2047 dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
2048 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
2049 dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
2050 strcpy(dip->un.s.member[4].label.name, AudioNcd);
2051 dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
2052 strcpy(dip->un.s.member[5].label.name, "auxb");
2053 dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
2054 }
2055 return (0);
2056
2057 case ESS_RECORD_CLASS:
2058 dip->mixer_class = ESS_RECORD_CLASS;
2059 dip->next = dip->prev = AUDIO_MIXER_LAST;
2060 strcpy(dip->label.name, AudioCrecord);
2061 dip->type = AUDIO_MIXER_CLASS;
2062 return (0);
2063
2064 case ESS_RECORD_MONITOR:
2065 dip->prev = dip->next = AUDIO_MIXER_LAST;
2066 strcpy(dip->label.name, AudioNmute);
2067 dip->type = AUDIO_MIXER_ENUM;
2068 dip->mixer_class = ESS_MONITOR_CLASS;
2069 dip->un.e.num_mem = 2;
2070 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2071 dip->un.e.member[0].ord = 0;
2072 strcpy(dip->un.e.member[1].label.name, AudioNon);
2073 dip->un.e.member[1].ord = 1;
2074 return (0);
2075
2076 case ESS_MONITOR_CLASS:
2077 dip->mixer_class = ESS_MONITOR_CLASS;
2078 dip->next = dip->prev = AUDIO_MIXER_LAST;
2079 strcpy(dip->label.name, AudioCmonitor);
2080 dip->type = AUDIO_MIXER_CLASS;
2081 return (0);
2082 }
2083
2084 if (ESS_USE_AUDIO1(sc->sc_model))
2085 return (ENXIO);
2086
2087 switch (dip->index) {
2088 case ESS_DAC_REC_VOL:
2089 dip->mixer_class = ESS_RECORD_CLASS;
2090 dip->next = dip->prev = AUDIO_MIXER_LAST;
2091 strcpy(dip->label.name, AudioNdac);
2092 dip->type = AUDIO_MIXER_VALUE;
2093 dip->un.v.num_channels = 2;
2094 strcpy(dip->un.v.units.name, AudioNvolume);
2095 return (0);
2096
2097 case ESS_MIC_REC_VOL:
2098 dip->mixer_class = ESS_RECORD_CLASS;
2099 dip->next = dip->prev = AUDIO_MIXER_LAST;
2100 strcpy(dip->label.name, AudioNmicrophone);
2101 dip->type = AUDIO_MIXER_VALUE;
2102 dip->un.v.num_channels = 2;
2103 strcpy(dip->un.v.units.name, AudioNvolume);
2104 return (0);
2105
2106 case ESS_LINE_REC_VOL:
2107 dip->mixer_class = ESS_RECORD_CLASS;
2108 dip->next = dip->prev = AUDIO_MIXER_LAST;
2109 strcpy(dip->label.name, AudioNline);
2110 dip->type = AUDIO_MIXER_VALUE;
2111 dip->un.v.num_channels = 2;
2112 strcpy(dip->un.v.units.name, AudioNvolume);
2113 return (0);
2114
2115 case ESS_SYNTH_REC_VOL:
2116 dip->mixer_class = ESS_RECORD_CLASS;
2117 dip->next = dip->prev = AUDIO_MIXER_LAST;
2118 strcpy(dip->label.name, AudioNfmsynth);
2119 dip->type = AUDIO_MIXER_VALUE;
2120 dip->un.v.num_channels = 2;
2121 strcpy(dip->un.v.units.name, AudioNvolume);
2122 return (0);
2123
2124 case ESS_CD_REC_VOL:
2125 dip->mixer_class = ESS_RECORD_CLASS;
2126 dip->next = dip->prev = AUDIO_MIXER_LAST;
2127 strcpy(dip->label.name, AudioNcd);
2128 dip->type = AUDIO_MIXER_VALUE;
2129 dip->un.v.num_channels = 2;
2130 strcpy(dip->un.v.units.name, AudioNvolume);
2131 return (0);
2132
2133 case ESS_AUXB_REC_VOL:
2134 dip->mixer_class = ESS_RECORD_CLASS;
2135 dip->next = dip->prev = AUDIO_MIXER_LAST;
2136 strcpy(dip->label.name, "auxb");
2137 dip->type = AUDIO_MIXER_VALUE;
2138 dip->un.v.num_channels = 2;
2139 strcpy(dip->un.v.units.name, AudioNvolume);
2140 return (0);
2141
2142 case ESS_MIC_PREAMP:
2143 dip->mixer_class = ESS_INPUT_CLASS;
2144 dip->prev = ESS_MIC_PLAY_VOL;
2145 dip->next = AUDIO_MIXER_LAST;
2146 strcpy(dip->label.name, AudioNpreamp);
2147 dip->type = AUDIO_MIXER_ENUM;
2148 dip->un.e.num_mem = 2;
2149 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2150 dip->un.e.member[0].ord = 0;
2151 strcpy(dip->un.e.member[1].label.name, AudioNon);
2152 dip->un.e.member[1].ord = 1;
2153 return (0);
2154 }
2155
2156 return (ENXIO);
2157 }
2158
2159 void *
2160 ess_malloc(addr, direction, size, pool, flags)
2161 void *addr;
2162 int direction;
2163 size_t size;
2164 int pool, 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 int 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 int
2205 ess_mappage(addr, mem, off, prot)
2206 void *addr;
2207 void *mem;
2208 int 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