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