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