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