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