1 /* $NetBSD: ess.c,v 1.90 2022/12/24 15:23:02 andvar 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.90 2022/12/24 15:23:02 andvar 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
ess_printsc(struct ess_softc * sc)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
ess_dump_mixer(struct ess_softc * sc)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
ess_config_addr(struct ess_softc * sc)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
ess_config_irq(struct ess_softc * sc)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
ess_config_drq(struct ess_softc * sc)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
ess_setup(struct ess_softc * sc)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
ess_identify(struct ess_softc * sc)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
ess_setup_sc(struct ess_softc * sc,int doinit)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
essmatch(struct ess_softc * sc)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
essattach(struct ess_softc * sc,int enablejoy)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 CFARGS(.iattr = "ess"));
1050
1051 #if NJOY_ESS > 0
1052 if (sc->sc_model == ESS_1888 && enablejoy) {
1053 unsigned char m40;
1054
1055 m40 = ess_read_mix_reg(sc, 0x40);
1056 m40 |= 2;
1057 ess_write_mix_reg(sc, 0x40, m40);
1058
1059 arg.type = AUDIODEV_TYPE_AUX;
1060 (void)config_found(sc->sc_dev, &arg, audioprint,
1061 CFARGS(.iattr = "ess"));
1062 }
1063 #endif
1064
1065 #ifdef AUDIO_DEBUG
1066 if (essdebug > 0)
1067 ess_printsc(sc);
1068 #endif
1069
1070 return;
1071
1072 fail:
1073 callout_destroy(&sc->sc_poll1_ch);
1074 callout_destroy(&sc->sc_poll2_ch);
1075 mutex_destroy(&sc->sc_lock);
1076 mutex_destroy(&sc->sc_intr_lock);
1077 }
1078
1079 /*
1080 * Various routines to interface to higher level audio driver
1081 */
1082
1083 void
ess_close(void * addr)1084 ess_close(void *addr)
1085 {
1086 struct ess_softc *sc;
1087
1088 sc = addr;
1089 DPRINTF(("ess_close: sc=%p\n", sc));
1090
1091 ess_speaker_off(sc);
1092 sc->spkr_state = SPKR_OFF;
1093
1094 DPRINTF(("ess_close: closed\n"));
1095 }
1096
1097 /* XXX should use reference count */
1098 int
ess_speaker_ctl(void * addr,int newstate)1099 ess_speaker_ctl(void *addr, int newstate)
1100 {
1101 struct ess_softc *sc;
1102
1103 sc = addr;
1104 if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
1105 ess_speaker_on(sc);
1106 sc->spkr_state = SPKR_ON;
1107 }
1108 if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
1109 ess_speaker_off(sc);
1110 sc->spkr_state = SPKR_OFF;
1111 }
1112 return 0;
1113 }
1114
1115 int
ess_getdev(void * addr,struct audio_device * retp)1116 ess_getdev(void *addr, struct audio_device *retp)
1117 {
1118
1119 *retp = ess_device;
1120 return 0;
1121 }
1122
1123 int
ess_query_format(void * addr,audio_format_query_t * afp)1124 ess_query_format(void *addr, audio_format_query_t *afp)
1125 {
1126
1127 return audio_query_format(ess_formats, ESS_NFORMATS, afp);
1128 }
1129
1130 int
ess_set_format(void * addr,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)1131 ess_set_format(void *addr, int setmode,
1132 const audio_params_t *play, const audio_params_t *rec,
1133 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
1134 {
1135 struct ess_softc *sc;
1136 int rate;
1137
1138 DPRINTF(("%s: set=%d\n", __func__, setmode));
1139 sc = addr;
1140
1141 /* *play and *rec are the identical because !AUDIO_PROP_INDEPENDENT. */
1142
1143 rate = play->sample_rate;
1144 ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(sc, rate));
1145 ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
1146
1147 if (!ESS_USE_AUDIO1(sc->sc_model)) {
1148 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE,
1149 ess_srtotc(sc, rate));
1150 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
1151 }
1152
1153 return 0;
1154 }
1155
1156 int
ess_audio1_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)1157 ess_audio1_trigger_output(
1158 void *addr,
1159 void *start, void *end,
1160 int blksize,
1161 void (*intr)(void *),
1162 void *arg,
1163 const audio_params_t *param)
1164 {
1165 struct ess_softc *sc;
1166 u_int8_t reg;
1167
1168 sc = addr;
1169 DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p "
1170 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1171
1172 if (sc->sc_audio1.active)
1173 panic("ess_audio1_trigger_output: already running");
1174
1175 sc->sc_audio1.active = 1;
1176 sc->sc_audio1.intr = intr;
1177 sc->sc_audio1.arg = arg;
1178 if (sc->sc_audio1.polled) {
1179 sc->sc_audio1.dmapos = 0;
1180 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1181 sc->sc_audio1.dmacount = 0;
1182 sc->sc_audio1.blksize = blksize;
1183 callout_reset(&sc->sc_poll1_ch, hz / 30,
1184 ess_audio1_poll, sc);
1185 }
1186
1187 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1188 if (param->channels == 2) {
1189 reg &= ~ESS_AUDIO_CTRL_MONO;
1190 reg |= ESS_AUDIO_CTRL_STEREO;
1191 } else {
1192 reg |= ESS_AUDIO_CTRL_MONO;
1193 reg &= ~ESS_AUDIO_CTRL_STEREO;
1194 }
1195 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1196
1197 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1198 if (param->precision == 16)
1199 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1200 else
1201 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1202 if (param->channels == 2)
1203 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1204 else
1205 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1206 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1207 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1208 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1209 else
1210 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1211 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1212 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1213
1214 isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1215 (char *)end - (char *)start, NULL,
1216 DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1217
1218 /* Program transfer count registers with 2's complement of count. */
1219 blksize = -blksize;
1220 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1221 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1222
1223 /* Use 4 bytes per output DMA. */
1224 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1225
1226 /* Start auto-init DMA */
1227 ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
1228 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1229 reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
1230 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1231 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1232
1233 return 0;
1234 }
1235
1236 int
ess_audio2_trigger_output(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)1237 ess_audio2_trigger_output(
1238 void *addr,
1239 void *start, void *end,
1240 int blksize,
1241 void (*intr)(void *),
1242 void *arg,
1243 const audio_params_t *param)
1244 {
1245 struct ess_softc *sc;
1246 u_int8_t reg;
1247
1248 sc = addr;
1249 DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p "
1250 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1251
1252 if (sc->sc_audio2.active)
1253 panic("ess_audio2_trigger_output: already running");
1254
1255 sc->sc_audio2.active = 1;
1256 sc->sc_audio2.intr = intr;
1257 sc->sc_audio2.arg = arg;
1258 if (sc->sc_audio2.polled) {
1259 sc->sc_audio2.dmapos = 0;
1260 sc->sc_audio2.buffersize = (char *)end - (char *)start;
1261 sc->sc_audio2.dmacount = 0;
1262 sc->sc_audio2.blksize = blksize;
1263 callout_reset(&sc->sc_poll2_ch, hz / 30,
1264 ess_audio2_poll, sc);
1265 }
1266
1267 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1268 if (param->precision == 16)
1269 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
1270 else
1271 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
1272 if (param->channels == 2)
1273 reg |= ESS_AUDIO2_CTRL2_CHANNELS;
1274 else
1275 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
1276 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1277 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1278 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1279 else
1280 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
1281 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1282
1283 isa_dmastart(sc->sc_ic, sc->sc_audio2.drq, start,
1284 (char *)end - (char *)start, NULL,
1285 DMAMODE_WRITE | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1286
1287 if (IS16BITDRQ(sc->sc_audio2.drq))
1288 blksize >>= 1; /* use word count for 16 bit DMA */
1289 /* Program transfer count registers with 2's complement of count. */
1290 blksize = -blksize;
1291 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
1292 ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
1293
1294 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
1295 if (IS16BITDRQ(sc->sc_audio2.drq))
1296 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
1297 else
1298 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
1299 reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
1300 reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
1301 ESS_AUDIO2_CTRL1_AUTO_INIT;
1302 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
1303
1304 return (0);
1305 }
1306
1307 int
ess_audio1_trigger_input(void * addr,void * start,void * end,int blksize,void (* intr)(void *),void * arg,const audio_params_t * param)1308 ess_audio1_trigger_input(
1309 void *addr,
1310 void *start, void *end,
1311 int blksize,
1312 void (*intr)(void *),
1313 void *arg,
1314 const audio_params_t *param)
1315 {
1316 struct ess_softc *sc;
1317 u_int8_t reg;
1318
1319 sc = addr;
1320 DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p "
1321 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1322
1323 if (sc->sc_audio1.active)
1324 panic("ess_audio1_trigger_input: already running");
1325
1326 sc->sc_audio1.active = 1;
1327 sc->sc_audio1.intr = intr;
1328 sc->sc_audio1.arg = arg;
1329 if (sc->sc_audio1.polled) {
1330 sc->sc_audio1.dmapos = 0;
1331 sc->sc_audio1.buffersize = (char *)end - (char *)start;
1332 sc->sc_audio1.dmacount = 0;
1333 sc->sc_audio1.blksize = blksize;
1334 callout_reset(&sc->sc_poll1_ch, hz / 30,
1335 ess_audio1_poll, sc);
1336 }
1337
1338 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
1339 if (param->channels == 2) {
1340 reg &= ~ESS_AUDIO_CTRL_MONO;
1341 reg |= ESS_AUDIO_CTRL_STEREO;
1342 } else {
1343 reg |= ESS_AUDIO_CTRL_MONO;
1344 reg &= ~ESS_AUDIO_CTRL_STEREO;
1345 }
1346 ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
1347
1348 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
1349 if (param->precision == 16)
1350 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
1351 else
1352 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
1353 if (param->channels == 2)
1354 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
1355 else
1356 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
1357 if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
1358 param->encoding == AUDIO_ENCODING_SLINEAR_LE)
1359 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1360 else
1361 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
1362 reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
1363 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
1364
1365 isa_dmastart(sc->sc_ic, sc->sc_audio1.drq, start,
1366 (char *)end - (char *)start, NULL,
1367 DMAMODE_READ | DMAMODE_LOOPDEMAND, BUS_DMA_NOWAIT);
1368
1369 /* Program transfer count registers with 2's complement of count. */
1370 blksize = -blksize;
1371 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
1372 ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
1373
1374 /* Use 4 bytes per input DMA. */
1375 ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
1376
1377 /* Start auto-init DMA */
1378 ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
1379 reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
1380 reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
1381 reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
1382 ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
1383
1384 return 0;
1385 }
1386
1387 int
ess_audio1_halt(void * addr)1388 ess_audio1_halt(void *addr)
1389 {
1390 struct ess_softc *sc;
1391
1392 sc = addr;
1393 DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
1394
1395 if (sc->sc_audio1.active) {
1396 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
1397 ESS_AUDIO1_CTRL2_FIFO_ENABLE);
1398 isa_dmaabort(sc->sc_ic, sc->sc_audio1.drq);
1399 if (sc->sc_audio1.polled)
1400 callout_stop(&sc->sc_poll1_ch);
1401 sc->sc_audio1.active = 0;
1402 }
1403
1404 return 0;
1405 }
1406
1407 int
ess_audio2_halt(void * addr)1408 ess_audio2_halt(void *addr)
1409 {
1410 struct ess_softc *sc;
1411
1412 sc = addr;
1413 DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
1414
1415 if (sc->sc_audio2.active) {
1416 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
1417 ESS_AUDIO2_CTRL1_DAC_ENABLE |
1418 ESS_AUDIO2_CTRL1_FIFO_ENABLE);
1419 isa_dmaabort(sc->sc_ic, sc->sc_audio2.drq);
1420 if (sc->sc_audio2.polled)
1421 callout_stop(&sc->sc_poll2_ch);
1422 sc->sc_audio2.active = 0;
1423 }
1424
1425 return 0;
1426 }
1427
1428 int
ess_audio1_intr(void * arg)1429 ess_audio1_intr(void *arg)
1430 {
1431 struct ess_softc *sc;
1432 uint8_t reg;
1433 int rv;
1434
1435 sc = arg;
1436 DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
1437
1438 mutex_spin_enter(&sc->sc_intr_lock);
1439
1440 /* Check and clear interrupt on Audio1. */
1441 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
1442 if ((reg & ESS_DSP_READ_OFLOW) == 0) {
1443 mutex_spin_exit(&sc->sc_intr_lock);
1444 return 0;
1445 }
1446 reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
1447
1448 sc->sc_audio1.nintr++;
1449
1450 if (sc->sc_audio1.active) {
1451 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1452 rv = 1;
1453 } else
1454 rv = 0;
1455
1456 mutex_spin_exit(&sc->sc_intr_lock);
1457
1458 return rv;
1459 }
1460
1461 int
ess_audio2_intr(void * arg)1462 ess_audio2_intr(void *arg)
1463 {
1464 struct ess_softc *sc;
1465 uint8_t reg;
1466 int rv;
1467
1468 sc = arg;
1469 DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
1470
1471 mutex_spin_enter(&sc->sc_intr_lock);
1472
1473 /* Check and clear interrupt on Audio2. */
1474 reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
1475 if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) {
1476 mutex_spin_exit(&sc->sc_intr_lock);
1477 return 0;
1478 }
1479 reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
1480 ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
1481
1482 sc->sc_audio2.nintr++;
1483
1484 if (sc->sc_audio2.active) {
1485 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1486 rv = 1;
1487 } else
1488 rv = 0;
1489
1490 mutex_spin_exit(&sc->sc_intr_lock);
1491
1492 return rv;
1493 }
1494
1495 void
ess_audio1_poll(void * addr)1496 ess_audio1_poll(void *addr)
1497 {
1498 struct ess_softc *sc;
1499 int dmapos, dmacount;
1500
1501 sc = addr;
1502 mutex_spin_enter(&sc->sc_intr_lock);
1503
1504 if (!sc->sc_audio1.active) {
1505 mutex_spin_exit(&sc->sc_intr_lock);
1506 return;
1507 }
1508
1509 sc->sc_audio1.nintr++;
1510
1511 dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio1.drq);
1512 dmacount = sc->sc_audio1.dmapos - dmapos;
1513 if (dmacount < 0)
1514 dmacount += sc->sc_audio1.buffersize;
1515 sc->sc_audio1.dmapos = dmapos;
1516 #if 1
1517 dmacount += sc->sc_audio1.dmacount;
1518 while (dmacount > sc->sc_audio1.blksize) {
1519 dmacount -= sc->sc_audio1.blksize;
1520 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
1521 }
1522 sc->sc_audio1.dmacount = dmacount;
1523 #else
1524 (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
1525 #endif
1526
1527 mutex_spin_exit(&sc->sc_intr_lock);
1528 callout_reset(&sc->sc_poll1_ch, hz / 30, ess_audio1_poll, sc);
1529 }
1530
1531 void
ess_audio2_poll(void * addr)1532 ess_audio2_poll(void *addr)
1533 {
1534 struct ess_softc *sc;
1535 int dmapos, dmacount;
1536
1537 sc = addr;
1538 mutex_spin_enter(&sc->sc_intr_lock);
1539
1540 if (!sc->sc_audio2.active) {
1541 mutex_spin_exit(&sc->sc_intr_lock);
1542 return;
1543 }
1544
1545 sc->sc_audio2.nintr++;
1546
1547 dmapos = isa_dmacount(sc->sc_ic, sc->sc_audio2.drq);
1548 dmacount = sc->sc_audio2.dmapos - dmapos;
1549 if (dmacount < 0)
1550 dmacount += sc->sc_audio2.buffersize;
1551 sc->sc_audio2.dmapos = dmapos;
1552 #if 1
1553 dmacount += sc->sc_audio2.dmacount;
1554 while (dmacount > sc->sc_audio2.blksize) {
1555 dmacount -= sc->sc_audio2.blksize;
1556 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
1557 }
1558 sc->sc_audio2.dmacount = dmacount;
1559 #else
1560 (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
1561 #endif
1562
1563 mutex_spin_exit(&sc->sc_intr_lock);
1564 callout_reset(&sc->sc_poll2_ch, hz / 30, ess_audio2_poll, sc);
1565 }
1566
1567 int
ess_round_blocksize(void * addr,int blk,int mode,const audio_params_t * param)1568 ess_round_blocksize(void *addr, int blk, int mode,
1569 const audio_params_t *param)
1570 {
1571
1572 return blk & -8; /* round for max DMA size */
1573 }
1574
1575 int
ess_set_port(void * addr,mixer_ctrl_t * cp)1576 ess_set_port(void *addr, mixer_ctrl_t *cp)
1577 {
1578 struct ess_softc *sc;
1579 int lgain, rgain;
1580
1581 sc = addr;
1582 DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
1583 cp->dev, cp->un.value.num_channels));
1584
1585 switch (cp->dev) {
1586 /*
1587 * The following mixer ports are all stereo. If we get a
1588 * single-channel gain value passed in, then we duplicate it
1589 * to both left and right channels.
1590 */
1591 case ESS_MASTER_VOL:
1592 case ESS_DAC_PLAY_VOL:
1593 case ESS_MIC_PLAY_VOL:
1594 case ESS_LINE_PLAY_VOL:
1595 case ESS_SYNTH_PLAY_VOL:
1596 case ESS_CD_PLAY_VOL:
1597 case ESS_AUXB_PLAY_VOL:
1598 case ESS_RECORD_VOL:
1599 if (cp->type != AUDIO_MIXER_VALUE)
1600 return EINVAL;
1601
1602 switch (cp->un.value.num_channels) {
1603 case 1:
1604 lgain = rgain = ESS_4BIT_GAIN(
1605 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1606 break;
1607 case 2:
1608 lgain = ESS_4BIT_GAIN(
1609 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1610 rgain = ESS_4BIT_GAIN(
1611 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1612 break;
1613 default:
1614 return EINVAL;
1615 }
1616
1617 sc->gain[cp->dev][ESS_LEFT] = lgain;
1618 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1619 ess_set_gain(sc, cp->dev, 1);
1620 return 0;
1621
1622 /*
1623 * The PC speaker port is mono. If we get a stereo gain value
1624 * passed in, then we return EINVAL.
1625 */
1626 case ESS_PCSPEAKER_VOL:
1627 if (cp->un.value.num_channels != 1)
1628 return EINVAL;
1629
1630 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
1631 ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1632 ess_set_gain(sc, cp->dev, 1);
1633 return 0;
1634
1635 case ESS_RECORD_SOURCE:
1636 if (ESS_USE_AUDIO1(sc->sc_model)) {
1637 if (cp->type == AUDIO_MIXER_ENUM)
1638 return ess_set_in_port(sc, cp->un.ord);
1639 else
1640 return EINVAL;
1641 } else {
1642 if (cp->type == AUDIO_MIXER_SET)
1643 return ess_set_in_ports(sc, cp->un.mask);
1644 else
1645 return EINVAL;
1646 }
1647 return 0;
1648
1649 case ESS_RECORD_MONITOR:
1650 if (cp->type != AUDIO_MIXER_ENUM)
1651 return EINVAL;
1652
1653 if (cp->un.ord)
1654 /* Enable monitor */
1655 ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1656 ESS_AUDIO_CTRL_MONITOR);
1657 else
1658 /* Disable monitor */
1659 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
1660 ESS_AUDIO_CTRL_MONITOR);
1661 return 0;
1662 }
1663
1664 if (ESS_IS_ES18X9(sc->sc_model)) {
1665
1666 switch (cp->dev) {
1667 case ESS_SPATIALIZER:
1668 if (cp->type != AUDIO_MIXER_VALUE ||
1669 cp->un.value.num_channels != 1)
1670 return EINVAL;
1671
1672 sc->gain[cp->dev][ESS_LEFT] =
1673 sc->gain[cp->dev][ESS_RIGHT] = ESS_6BIT_GAIN(
1674 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1675 ess_set_gain(sc, cp->dev, 1);
1676 return 0;
1677
1678 case ESS_SPATIALIZER_ENABLE:
1679 if (cp->type != AUDIO_MIXER_ENUM)
1680 return EINVAL;
1681
1682 sc->sc_spatializer = (cp->un.ord != 0);
1683 if (sc->sc_spatializer)
1684 ess_set_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
1685 ESS_SPATIAL_CTRL_ENABLE);
1686 else
1687 ess_clear_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
1688 ESS_SPATIAL_CTRL_ENABLE);
1689 return 0;
1690 }
1691 }
1692
1693 if (ESS_USE_AUDIO1(sc->sc_model))
1694 return EINVAL;
1695
1696 switch (cp->dev) {
1697 case ESS_DAC_REC_VOL:
1698 case ESS_MIC_REC_VOL:
1699 case ESS_LINE_REC_VOL:
1700 case ESS_SYNTH_REC_VOL:
1701 case ESS_CD_REC_VOL:
1702 case ESS_AUXB_REC_VOL:
1703 if (cp->type != AUDIO_MIXER_VALUE)
1704 return EINVAL;
1705
1706 switch (cp->un.value.num_channels) {
1707 case 1:
1708 lgain = rgain = ESS_4BIT_GAIN(
1709 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
1710 break;
1711 case 2:
1712 lgain = ESS_4BIT_GAIN(
1713 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
1714 rgain = ESS_4BIT_GAIN(
1715 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
1716 break;
1717 default:
1718 return EINVAL;
1719 }
1720
1721 sc->gain[cp->dev][ESS_LEFT] = lgain;
1722 sc->gain[cp->dev][ESS_RIGHT] = rgain;
1723 ess_set_gain(sc, cp->dev, 1);
1724 return 0;
1725
1726 case ESS_MIC_PREAMP:
1727 if (cp->type != AUDIO_MIXER_ENUM)
1728 return EINVAL;
1729
1730 if (cp->un.ord)
1731 /* Enable microphone preamp */
1732 ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1733 ESS_PREAMP_CTRL_ENABLE);
1734 else
1735 /* Disable microphone preamp */
1736 ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
1737 ESS_PREAMP_CTRL_ENABLE);
1738 return 0;
1739 }
1740
1741 return EINVAL;
1742 }
1743
1744 int
ess_get_port(void * addr,mixer_ctrl_t * cp)1745 ess_get_port(void *addr, mixer_ctrl_t *cp)
1746 {
1747 struct ess_softc *sc;
1748
1749 sc = addr;
1750 DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
1751
1752 switch (cp->dev) {
1753 case ESS_MASTER_VOL:
1754 case ESS_DAC_PLAY_VOL:
1755 case ESS_MIC_PLAY_VOL:
1756 case ESS_LINE_PLAY_VOL:
1757 case ESS_SYNTH_PLAY_VOL:
1758 case ESS_CD_PLAY_VOL:
1759 case ESS_AUXB_PLAY_VOL:
1760 case ESS_RECORD_VOL:
1761 switch (cp->un.value.num_channels) {
1762 case 1:
1763 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1764 sc->gain[cp->dev][ESS_LEFT];
1765 break;
1766 case 2:
1767 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1768 sc->gain[cp->dev][ESS_LEFT];
1769 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1770 sc->gain[cp->dev][ESS_RIGHT];
1771 break;
1772 default:
1773 return EINVAL;
1774 }
1775 return 0;
1776
1777 case ESS_PCSPEAKER_VOL:
1778 if (cp->un.value.num_channels != 1)
1779 return EINVAL;
1780
1781 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1782 sc->gain[cp->dev][ESS_LEFT];
1783 return 0;
1784
1785 case ESS_RECORD_SOURCE:
1786 if (ESS_USE_AUDIO1(sc->sc_model))
1787 cp->un.ord = sc->in_port;
1788 else
1789 cp->un.mask = sc->in_mask;
1790 return 0;
1791
1792 case ESS_RECORD_MONITOR:
1793 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
1794 ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
1795 return 0;
1796 }
1797
1798 if (ESS_IS_ES18X9(sc->sc_model)) {
1799
1800 switch (cp->dev) {
1801 case ESS_SPATIALIZER:
1802 if (cp->un.value.num_channels != 1)
1803 return EINVAL;
1804
1805 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1806 sc->gain[cp->dev][ESS_LEFT];
1807 return 0;
1808
1809 case ESS_SPATIALIZER_ENABLE:
1810 cp->un.ord = sc->sc_spatializer;
1811 return 0;
1812 }
1813 }
1814
1815 if (ESS_USE_AUDIO1(sc->sc_model))
1816 return EINVAL;
1817
1818 switch (cp->dev) {
1819 case ESS_DAC_REC_VOL:
1820 case ESS_MIC_REC_VOL:
1821 case ESS_LINE_REC_VOL:
1822 case ESS_SYNTH_REC_VOL:
1823 case ESS_CD_REC_VOL:
1824 case ESS_AUXB_REC_VOL:
1825 switch (cp->un.value.num_channels) {
1826 case 1:
1827 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1828 sc->gain[cp->dev][ESS_LEFT];
1829 break;
1830 case 2:
1831 cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
1832 sc->gain[cp->dev][ESS_LEFT];
1833 cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
1834 sc->gain[cp->dev][ESS_RIGHT];
1835 break;
1836 default:
1837 return EINVAL;
1838 }
1839 return 0;
1840
1841 case ESS_MIC_PREAMP:
1842 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
1843 ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
1844 return 0;
1845 }
1846
1847 return EINVAL;
1848 }
1849
1850 int
ess_query_devinfo(void * addr,mixer_devinfo_t * dip)1851 ess_query_devinfo(void *addr, mixer_devinfo_t *dip)
1852 {
1853 struct ess_softc *sc;
1854
1855 sc = addr;
1856 DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
1857 sc->sc_model, dip->index));
1858
1859 /*
1860 * REVISIT: There are some slight differences between the
1861 * mixers on the different ESS chips, which can
1862 * be sorted out using the chip model rather than a
1863 * separate mixer model.
1864 * This is currently coded assuming an ES1887; we
1865 * need to work out which bits are not applicable to
1866 * the other models (1888 and 888).
1867 */
1868 switch (dip->index) {
1869 case ESS_DAC_PLAY_VOL:
1870 dip->mixer_class = ESS_INPUT_CLASS;
1871 dip->next = dip->prev = AUDIO_MIXER_LAST;
1872 strcpy(dip->label.name, AudioNdac);
1873 dip->type = AUDIO_MIXER_VALUE;
1874 dip->un.v.num_channels = 2;
1875 strcpy(dip->un.v.units.name, AudioNvolume);
1876 return 0;
1877
1878 case ESS_MIC_PLAY_VOL:
1879 dip->mixer_class = ESS_INPUT_CLASS;
1880 dip->prev = AUDIO_MIXER_LAST;
1881 if (ESS_USE_AUDIO1(sc->sc_model))
1882 dip->next = AUDIO_MIXER_LAST;
1883 else
1884 dip->next = ESS_MIC_PREAMP;
1885 strcpy(dip->label.name, AudioNmicrophone);
1886 dip->type = AUDIO_MIXER_VALUE;
1887 dip->un.v.num_channels = 2;
1888 strcpy(dip->un.v.units.name, AudioNvolume);
1889 return 0;
1890
1891 case ESS_LINE_PLAY_VOL:
1892 dip->mixer_class = ESS_INPUT_CLASS;
1893 dip->next = dip->prev = AUDIO_MIXER_LAST;
1894 strcpy(dip->label.name, AudioNline);
1895 dip->type = AUDIO_MIXER_VALUE;
1896 dip->un.v.num_channels = 2;
1897 strcpy(dip->un.v.units.name, AudioNvolume);
1898 return 0;
1899
1900 case ESS_SYNTH_PLAY_VOL:
1901 dip->mixer_class = ESS_INPUT_CLASS;
1902 dip->next = dip->prev = AUDIO_MIXER_LAST;
1903 strcpy(dip->label.name, AudioNfmsynth);
1904 dip->type = AUDIO_MIXER_VALUE;
1905 dip->un.v.num_channels = 2;
1906 strcpy(dip->un.v.units.name, AudioNvolume);
1907 return 0;
1908
1909 case ESS_CD_PLAY_VOL:
1910 dip->mixer_class = ESS_INPUT_CLASS;
1911 dip->next = dip->prev = AUDIO_MIXER_LAST;
1912 strcpy(dip->label.name, AudioNcd);
1913 dip->type = AUDIO_MIXER_VALUE;
1914 dip->un.v.num_channels = 2;
1915 strcpy(dip->un.v.units.name, AudioNvolume);
1916 return 0;
1917
1918 case ESS_AUXB_PLAY_VOL:
1919 dip->mixer_class = ESS_INPUT_CLASS;
1920 dip->next = dip->prev = AUDIO_MIXER_LAST;
1921 strcpy(dip->label.name, "auxb");
1922 dip->type = AUDIO_MIXER_VALUE;
1923 dip->un.v.num_channels = 2;
1924 strcpy(dip->un.v.units.name, AudioNvolume);
1925 return 0;
1926
1927 case ESS_INPUT_CLASS:
1928 dip->mixer_class = ESS_INPUT_CLASS;
1929 dip->next = dip->prev = AUDIO_MIXER_LAST;
1930 strcpy(dip->label.name, AudioCinputs);
1931 dip->type = AUDIO_MIXER_CLASS;
1932 return 0;
1933
1934 case ESS_MASTER_VOL:
1935 dip->mixer_class = ESS_OUTPUT_CLASS;
1936 dip->next = dip->prev = AUDIO_MIXER_LAST;
1937 strcpy(dip->label.name, AudioNmaster);
1938 dip->type = AUDIO_MIXER_VALUE;
1939 dip->un.v.num_channels = 2;
1940 strcpy(dip->un.v.units.name, AudioNvolume);
1941 return 0;
1942
1943 case ESS_PCSPEAKER_VOL:
1944 dip->mixer_class = ESS_OUTPUT_CLASS;
1945 dip->next = dip->prev = AUDIO_MIXER_LAST;
1946 strcpy(dip->label.name, "pc_speaker");
1947 dip->type = AUDIO_MIXER_VALUE;
1948 dip->un.v.num_channels = 1;
1949 strcpy(dip->un.v.units.name, AudioNvolume);
1950 return 0;
1951
1952 case ESS_OUTPUT_CLASS:
1953 dip->mixer_class = ESS_OUTPUT_CLASS;
1954 dip->next = dip->prev = AUDIO_MIXER_LAST;
1955 strcpy(dip->label.name, AudioCoutputs);
1956 dip->type = AUDIO_MIXER_CLASS;
1957 return 0;
1958
1959 case ESS_RECORD_VOL:
1960 dip->mixer_class = ESS_RECORD_CLASS;
1961 dip->next = dip->prev = AUDIO_MIXER_LAST;
1962 strcpy(dip->label.name, AudioNrecord);
1963 dip->type = AUDIO_MIXER_VALUE;
1964 dip->un.v.num_channels = 2;
1965 strcpy(dip->un.v.units.name, AudioNvolume);
1966 return 0;
1967
1968 case ESS_RECORD_SOURCE:
1969 dip->mixer_class = ESS_RECORD_CLASS;
1970 dip->next = dip->prev = AUDIO_MIXER_LAST;
1971 strcpy(dip->label.name, AudioNsource);
1972 if (ESS_USE_AUDIO1(sc->sc_model)) {
1973 /*
1974 * The 1788 doesn't use the input mixer control that
1975 * the 1888 uses, because it's a pain when you only
1976 * have one mixer.
1977 * Perhaps it could be emulated by keeping both sets of
1978 * gain values, and doing a `context switch' of the
1979 * mixer registers when shifting from playing to
1980 * recording.
1981 */
1982 dip->type = AUDIO_MIXER_ENUM;
1983 dip->un.e.num_mem = 4;
1984 strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
1985 dip->un.e.member[0].ord = ESS_SOURCE_MIC;
1986 strcpy(dip->un.e.member[1].label.name, AudioNline);
1987 dip->un.e.member[1].ord = ESS_SOURCE_LINE;
1988 strcpy(dip->un.e.member[2].label.name, AudioNcd);
1989 dip->un.e.member[2].ord = ESS_SOURCE_CD;
1990 strcpy(dip->un.e.member[3].label.name, AudioNmixerout);
1991 dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
1992 } else {
1993 dip->type = AUDIO_MIXER_SET;
1994 dip->un.s.num_mem = 6;
1995 strcpy(dip->un.s.member[0].label.name, AudioNdac);
1996 dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
1997 strcpy(dip->un.s.member[1].label.name, AudioNmicrophone);
1998 dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
1999 strcpy(dip->un.s.member[2].label.name, AudioNline);
2000 dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
2001 strcpy(dip->un.s.member[3].label.name, AudioNfmsynth);
2002 dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
2003 strcpy(dip->un.s.member[4].label.name, AudioNcd);
2004 dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
2005 strcpy(dip->un.s.member[5].label.name, "auxb");
2006 dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
2007 }
2008 return 0;
2009
2010 case ESS_RECORD_CLASS:
2011 dip->mixer_class = ESS_RECORD_CLASS;
2012 dip->next = dip->prev = AUDIO_MIXER_LAST;
2013 strcpy(dip->label.name, AudioCrecord);
2014 dip->type = AUDIO_MIXER_CLASS;
2015 return 0;
2016
2017 case ESS_RECORD_MONITOR:
2018 dip->prev = dip->next = AUDIO_MIXER_LAST;
2019 strcpy(dip->label.name, AudioNmute);
2020 dip->type = AUDIO_MIXER_ENUM;
2021 dip->mixer_class = ESS_MONITOR_CLASS;
2022 dip->un.e.num_mem = 2;
2023 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2024 dip->un.e.member[0].ord = 0;
2025 strcpy(dip->un.e.member[1].label.name, AudioNon);
2026 dip->un.e.member[1].ord = 1;
2027 return 0;
2028
2029 case ESS_MONITOR_CLASS:
2030 dip->mixer_class = ESS_MONITOR_CLASS;
2031 dip->next = dip->prev = AUDIO_MIXER_LAST;
2032 strcpy(dip->label.name, AudioCmonitor);
2033 dip->type = AUDIO_MIXER_CLASS;
2034 return 0;
2035 }
2036
2037 if (ESS_IS_ES18X9(sc->sc_model)) {
2038
2039 switch (dip->index) {
2040 case ESS_SPATIALIZER:
2041 dip->mixer_class = ESS_OUTPUT_CLASS;
2042 dip->prev = AUDIO_MIXER_LAST;
2043 dip->next = ESS_SPATIALIZER_ENABLE;
2044 strcpy(dip->label.name, AudioNspatial);
2045 dip->type = AUDIO_MIXER_VALUE;
2046 dip->un.v.num_channels = 1;
2047 strcpy(dip->un.v.units.name, "level");
2048 return 0;
2049
2050 case ESS_SPATIALIZER_ENABLE:
2051 dip->mixer_class = ESS_OUTPUT_CLASS;
2052 dip->prev = ESS_SPATIALIZER;
2053 dip->next = AUDIO_MIXER_LAST;
2054 strcpy(dip->label.name, "enable");
2055 dip->type = AUDIO_MIXER_ENUM;
2056 dip->un.e.num_mem = 2;
2057 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2058 dip->un.e.member[0].ord = 0;
2059 strcpy(dip->un.e.member[1].label.name, AudioNon);
2060 dip->un.e.member[1].ord = 1;
2061 return 0;
2062 }
2063 }
2064
2065 if (ESS_USE_AUDIO1(sc->sc_model))
2066 return ENXIO;
2067
2068 switch (dip->index) {
2069 case ESS_DAC_REC_VOL:
2070 dip->mixer_class = ESS_RECORD_CLASS;
2071 dip->next = dip->prev = AUDIO_MIXER_LAST;
2072 strcpy(dip->label.name, AudioNdac);
2073 dip->type = AUDIO_MIXER_VALUE;
2074 dip->un.v.num_channels = 2;
2075 strcpy(dip->un.v.units.name, AudioNvolume);
2076 return 0;
2077
2078 case ESS_MIC_REC_VOL:
2079 dip->mixer_class = ESS_RECORD_CLASS;
2080 dip->next = dip->prev = AUDIO_MIXER_LAST;
2081 strcpy(dip->label.name, AudioNmicrophone);
2082 dip->type = AUDIO_MIXER_VALUE;
2083 dip->un.v.num_channels = 2;
2084 strcpy(dip->un.v.units.name, AudioNvolume);
2085 return 0;
2086
2087 case ESS_LINE_REC_VOL:
2088 dip->mixer_class = ESS_RECORD_CLASS;
2089 dip->next = dip->prev = AUDIO_MIXER_LAST;
2090 strcpy(dip->label.name, AudioNline);
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_SYNTH_REC_VOL:
2097 dip->mixer_class = ESS_RECORD_CLASS;
2098 dip->next = dip->prev = AUDIO_MIXER_LAST;
2099 strcpy(dip->label.name, AudioNfmsynth);
2100 dip->type = AUDIO_MIXER_VALUE;
2101 dip->un.v.num_channels = 2;
2102 strcpy(dip->un.v.units.name, AudioNvolume);
2103 return 0;
2104
2105 case ESS_CD_REC_VOL:
2106 dip->mixer_class = ESS_RECORD_CLASS;
2107 dip->next = dip->prev = AUDIO_MIXER_LAST;
2108 strcpy(dip->label.name, AudioNcd);
2109 dip->type = AUDIO_MIXER_VALUE;
2110 dip->un.v.num_channels = 2;
2111 strcpy(dip->un.v.units.name, AudioNvolume);
2112 return 0;
2113
2114 case ESS_AUXB_REC_VOL:
2115 dip->mixer_class = ESS_RECORD_CLASS;
2116 dip->next = dip->prev = AUDIO_MIXER_LAST;
2117 strcpy(dip->label.name, "auxb");
2118 dip->type = AUDIO_MIXER_VALUE;
2119 dip->un.v.num_channels = 2;
2120 strcpy(dip->un.v.units.name, AudioNvolume);
2121 return 0;
2122
2123 case ESS_MIC_PREAMP:
2124 dip->mixer_class = ESS_INPUT_CLASS;
2125 dip->prev = ESS_MIC_PLAY_VOL;
2126 dip->next = AUDIO_MIXER_LAST;
2127 strcpy(dip->label.name, AudioNpreamp);
2128 dip->type = AUDIO_MIXER_ENUM;
2129 dip->un.e.num_mem = 2;
2130 strcpy(dip->un.e.member[0].label.name, AudioNoff);
2131 dip->un.e.member[0].ord = 0;
2132 strcpy(dip->un.e.member[1].label.name, AudioNon);
2133 dip->un.e.member[1].ord = 1;
2134 return 0;
2135 }
2136
2137 return ENXIO;
2138 }
2139
2140 void *
ess_malloc(void * addr,int direction,size_t size)2141 ess_malloc(void *addr, int direction, size_t size)
2142 {
2143 struct ess_softc *sc;
2144 int drq;
2145
2146 sc = addr;
2147 if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
2148 drq = sc->sc_audio2.drq;
2149 else
2150 drq = sc->sc_audio1.drq;
2151 return (isa_malloc(sc->sc_ic, drq, size, M_DEVBUF, M_WAITOK));
2152 }
2153
2154 void
ess_free(void * addr,void * ptr,size_t size)2155 ess_free(void *addr, void *ptr, size_t size)
2156 {
2157
2158 isa_free(ptr, M_DEVBUF);
2159 }
2160
2161 size_t
ess_round_buffersize(void * addr,int direction,size_t size)2162 ess_round_buffersize(void *addr, int direction, size_t size)
2163 {
2164 struct ess_softc *sc;
2165 bus_size_t maxsize;
2166
2167 sc = addr;
2168 if ((!ESS_USE_AUDIO1(sc->sc_model)) && direction == AUMODE_PLAY)
2169 maxsize = sc->sc_audio2.maxsize;
2170 else
2171 maxsize = sc->sc_audio1.maxsize;
2172
2173 if (size > maxsize)
2174 size = maxsize;
2175 return size;
2176 }
2177
2178 int
ess_1788_get_props(void * addr)2179 ess_1788_get_props(void *addr)
2180 {
2181
2182 return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE;
2183 }
2184
2185 int
ess_1888_get_props(void * addr)2186 ess_1888_get_props(void *addr)
2187 {
2188
2189 return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE |
2190 AUDIO_PROP_FULLDUPLEX;
2191 }
2192
2193 void
ess_get_locks(void * addr,kmutex_t ** intr,kmutex_t ** thread)2194 ess_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread)
2195 {
2196 struct ess_softc *sc;
2197
2198 sc = addr;
2199 *intr = &sc->sc_intr_lock;
2200 *thread = &sc->sc_lock;
2201 }
2202
2203
2204 /* ============================================
2205 * Generic functions for ess, not used by audio h/w i/f
2206 * =============================================
2207 */
2208
2209 /*
2210 * Reset the chip.
2211 * Return non-zero if the chip isn't detected.
2212 */
2213 int
ess_reset(struct ess_softc * sc)2214 ess_reset(struct ess_softc *sc)
2215 {
2216 bus_space_tag_t iot;
2217 bus_space_handle_t ioh;
2218
2219 iot = sc->sc_iot;
2220 ioh = sc->sc_ioh;
2221 sc->sc_audio1.active = 0;
2222 sc->sc_audio2.active = 0;
2223
2224 EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
2225 delay(10000); /* XXX shouldn't delay so long */
2226 EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
2227 if (ess_rdsp(sc) != ESS_MAGIC)
2228 return 1;
2229
2230 /* Enable access to the ESS extension commands. */
2231 ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
2232
2233 return 0;
2234 }
2235
2236 void
ess_set_gain(struct ess_softc * sc,int port,int on)2237 ess_set_gain(struct ess_softc *sc, int port, int on)
2238 {
2239 int gain, left, right;
2240 int mix;
2241 int src;
2242 int stereo;
2243
2244 /*
2245 * Most gain controls are found in the mixer registers and
2246 * are stereo. Any that are not, must set mix and stereo as
2247 * required.
2248 */
2249 mix = 1;
2250 stereo = 1;
2251
2252 if (ESS_IS_ES18X9(sc->sc_model)) {
2253 switch (port) {
2254 case ESS_SPATIALIZER:
2255 src = ESS_MREG_SPATIAL_LEVEL;
2256 stereo = -1;
2257 goto skip;
2258 case ESS_SPATIALIZER_ENABLE:
2259 return;
2260 }
2261 }
2262 switch (port) {
2263 case ESS_MASTER_VOL:
2264 src = ESS_MREG_VOLUME_MASTER;
2265 break;
2266 case ESS_DAC_PLAY_VOL:
2267 if (ESS_USE_AUDIO1(sc->sc_model))
2268 src = ESS_MREG_VOLUME_VOICE;
2269 else
2270 src = 0x7C;
2271 break;
2272 case ESS_MIC_PLAY_VOL:
2273 src = ESS_MREG_VOLUME_MIC;
2274 break;
2275 case ESS_LINE_PLAY_VOL:
2276 src = ESS_MREG_VOLUME_LINE;
2277 break;
2278 case ESS_SYNTH_PLAY_VOL:
2279 src = ESS_MREG_VOLUME_SYNTH;
2280 break;
2281 case ESS_CD_PLAY_VOL:
2282 src = ESS_MREG_VOLUME_CD;
2283 break;
2284 case ESS_AUXB_PLAY_VOL:
2285 src = ESS_MREG_VOLUME_AUXB;
2286 break;
2287 case ESS_PCSPEAKER_VOL:
2288 src = ESS_MREG_VOLUME_PCSPKR;
2289 stereo = 0;
2290 break;
2291 case ESS_DAC_REC_VOL:
2292 src = 0x69;
2293 break;
2294 case ESS_MIC_REC_VOL:
2295 src = 0x68;
2296 break;
2297 case ESS_LINE_REC_VOL:
2298 src = 0x6E;
2299 break;
2300 case ESS_SYNTH_REC_VOL:
2301 src = 0x6B;
2302 break;
2303 case ESS_CD_REC_VOL:
2304 src = 0x6A;
2305 break;
2306 case ESS_AUXB_REC_VOL:
2307 src = 0x6C;
2308 break;
2309 case ESS_RECORD_VOL:
2310 src = ESS_XCMD_VOLIN_CTRL;
2311 mix = 0;
2312 break;
2313 default:
2314 return;
2315 }
2316 skip:
2317
2318 /* 1788 doesn't have a separate recording mixer */
2319 if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
2320 return;
2321
2322 if (on) {
2323 left = sc->gain[port][ESS_LEFT];
2324 right = sc->gain[port][ESS_RIGHT];
2325 } else {
2326 left = right = 0;
2327 }
2328
2329 if (stereo == -1)
2330 gain = ESS_SPATIAL_GAIN(left);
2331 else if (stereo)
2332 gain = ESS_STEREO_GAIN(left, right);
2333 else
2334 gain = ESS_MONO_GAIN(left);
2335
2336 if (mix)
2337 ess_write_mix_reg(sc, src, gain);
2338 else
2339 ess_write_x_reg(sc, src, gain);
2340 }
2341
2342 /* Set the input device on devices without an input mixer. */
2343 int
ess_set_in_port(struct ess_softc * sc,int ord)2344 ess_set_in_port(struct ess_softc *sc, int ord)
2345 {
2346 mixer_devinfo_t di;
2347 int i;
2348
2349 DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
2350
2351 /*
2352 * Get the device info for the record source control,
2353 * including the list of available sources.
2354 */
2355 di.index = ESS_RECORD_SOURCE;
2356 if (ess_query_devinfo(sc, &di))
2357 return EINVAL;
2358
2359 /* See if the given ord value was anywhere in the list. */
2360 for (i = 0; i < di.un.e.num_mem; i++) {
2361 if (ord == di.un.e.member[i].ord)
2362 break;
2363 }
2364 if (i == di.un.e.num_mem)
2365 return EINVAL;
2366
2367 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
2368
2369 sc->in_port = ord;
2370 return 0;
2371 }
2372
2373 /* Set the input device levels on input-mixer-enabled devices. */
2374 int
ess_set_in_ports(struct ess_softc * sc,int mask)2375 ess_set_in_ports(struct ess_softc *sc, int mask)
2376 {
2377 mixer_devinfo_t di;
2378 int i, port;
2379
2380 DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
2381
2382 /*
2383 * Get the device info for the record source control,
2384 * including the list of available sources.
2385 */
2386 di.index = ESS_RECORD_SOURCE;
2387 if (ess_query_devinfo(sc, &di))
2388 return EINVAL;
2389
2390 /*
2391 * Set or disable the record volume control for each of the
2392 * possible sources.
2393 */
2394 for (i = 0; i < di.un.s.num_mem; i++) {
2395 /*
2396 * Calculate the source port number from its mask.
2397 */
2398 port = ffs(di.un.s.member[i].mask);
2399
2400 /*
2401 * Set the source gain:
2402 * to the current value if source is enabled
2403 * to zero if source is disabled
2404 */
2405 ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
2406 }
2407
2408 sc->in_mask = mask;
2409 return 0;
2410 }
2411
2412 void
ess_speaker_on(struct ess_softc * sc)2413 ess_speaker_on(struct ess_softc *sc)
2414 {
2415
2416 /* Unmute the DAC. */
2417 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
2418 }
2419
2420 void
ess_speaker_off(struct ess_softc * sc)2421 ess_speaker_off(struct ess_softc *sc)
2422 {
2423
2424 /* Mute the DAC. */
2425 ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
2426 }
2427
2428 /*
2429 * Calculate the time constant for the requested sampling rate.
2430 */
2431 u_int
ess_srtotc(struct ess_softc * sc,u_int rate)2432 ess_srtotc(struct ess_softc *sc, u_int rate)
2433 {
2434 u_int tc;
2435
2436 /* The following formulae are from the ESS data sheet. */
2437 if (ESS_IS_ES18X9(sc->sc_model)) {
2438 if ((rate % 8000) != 0)
2439 tc = 128 - 793800L / rate;
2440 else
2441 tc = 256 - 768000L / rate;
2442 } else {
2443 if (rate <= 22050)
2444 tc = 128 - 397700L / rate;
2445 else
2446 tc = 256 - 795500L / rate;
2447 }
2448
2449 return tc;
2450 }
2451
2452
2453 /*
2454 * Calculate the filter constant for the requested sampling rate.
2455 */
2456 u_int
ess_srtofc(u_int rate)2457 ess_srtofc(u_int rate)
2458 {
2459 /*
2460 * The following formula is derived from the information in
2461 * the ES1887 data sheet, based on a roll-off frequency of
2462 * 87%.
2463 */
2464 return 256 - 200279L / rate;
2465 }
2466
2467
2468 /*
2469 * Return the status of the DSP.
2470 */
2471 u_char
ess_get_dsp_status(struct ess_softc * sc)2472 ess_get_dsp_status(struct ess_softc *sc)
2473 {
2474 return EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
2475 }
2476
2477
2478 /*
2479 * Return the read status of the DSP: 1 -> DSP ready for reading
2480 * 0 -> DSP not ready for reading
2481 */
2482 u_char
ess_dsp_read_ready(struct ess_softc * sc)2483 ess_dsp_read_ready(struct ess_softc *sc)
2484 {
2485
2486 return (ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0;
2487 }
2488
2489
2490 /*
2491 * Return the write status of the DSP: 1 -> DSP ready for writing
2492 * 0 -> DSP not ready for writing
2493 */
2494 u_char
ess_dsp_write_ready(struct ess_softc * sc)2495 ess_dsp_write_ready(struct ess_softc *sc)
2496 {
2497 return (ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1;
2498 }
2499
2500
2501 /*
2502 * Read a byte from the DSP.
2503 */
2504 int
ess_rdsp(struct ess_softc * sc)2505 ess_rdsp(struct ess_softc *sc)
2506 {
2507 bus_space_tag_t iot;
2508 bus_space_handle_t ioh;
2509 int i;
2510
2511 iot = sc->sc_iot;
2512 ioh = sc->sc_ioh;
2513 for (i = ESS_READ_TIMEOUT; i > 0; --i) {
2514 if (ess_dsp_read_ready(sc)) {
2515 i = EREAD1(iot, ioh, ESS_DSP_READ);
2516 DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
2517 return i;
2518 } else
2519 delay(10);
2520 }
2521
2522 DPRINTF(("ess_rdsp: timed out\n"));
2523 return -1;
2524 }
2525
2526 /*
2527 * Write a byte to the DSP.
2528 */
2529 int
ess_wdsp(struct ess_softc * sc,u_char v)2530 ess_wdsp(struct ess_softc *sc, u_char v)
2531 {
2532 bus_space_tag_t iot;
2533 bus_space_handle_t ioh;
2534 int i;
2535
2536 DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
2537
2538 iot = sc->sc_iot;
2539 ioh = sc->sc_ioh;
2540 for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
2541 if (ess_dsp_write_ready(sc)) {
2542 EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
2543 return 0;
2544 } else
2545 delay(10);
2546 }
2547
2548 DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
2549 return -1;
2550 }
2551
2552 /*
2553 * Write a value to one of the ESS extended registers.
2554 */
2555 int
ess_write_x_reg(struct ess_softc * sc,u_char reg,u_char val)2556 ess_write_x_reg(struct ess_softc *sc, u_char reg, u_char val)
2557 {
2558 int error;
2559
2560 DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
2561 if ((error = ess_wdsp(sc, reg)) == 0)
2562 error = ess_wdsp(sc, val);
2563
2564 return error;
2565 }
2566
2567 /*
2568 * Read the value of one of the ESS extended registers.
2569 */
2570 u_char
ess_read_x_reg(struct ess_softc * sc,u_char reg)2571 ess_read_x_reg(struct ess_softc *sc, u_char reg)
2572 {
2573 int error;
2574 int val;
2575
2576 if ((error = ess_wdsp(sc, 0xC0)) == 0)
2577 error = ess_wdsp(sc, reg);
2578 if (error) {
2579 DPRINTF(("Error reading extended register 0x%02x\n", reg));
2580 }
2581 /* REVISIT: what if an error is returned above? */
2582 val = ess_rdsp(sc);
2583 DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
2584 return val;
2585 }
2586
2587 void
ess_clear_xreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2588 ess_clear_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2589 {
2590 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1) {
2591 DPRINTF(("Error clearing bits in extended register 0x%02x\n",
2592 reg));
2593 }
2594 }
2595
2596 void
ess_set_xreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2597 ess_set_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2598 {
2599 if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1) {
2600 DPRINTF(("Error setting bits in extended register 0x%02x\n",
2601 reg));
2602 }
2603 }
2604
2605
2606 /*
2607 * Write a value to one of the ESS mixer registers.
2608 */
2609 void
ess_write_mix_reg(struct ess_softc * sc,u_char reg,u_char val)2610 ess_write_mix_reg(struct ess_softc *sc, u_char reg, u_char val)
2611 {
2612 bus_space_tag_t iot;
2613 bus_space_handle_t ioh;
2614
2615 DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
2616
2617 iot = sc->sc_iot;
2618 ioh = sc->sc_ioh;
2619 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2620 EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
2621 }
2622
2623 /*
2624 * Read the value of one of the ESS mixer registers.
2625 */
2626 u_char
ess_read_mix_reg(struct ess_softc * sc,u_char reg)2627 ess_read_mix_reg(struct ess_softc *sc, u_char reg)
2628 {
2629 bus_space_tag_t iot;
2630 bus_space_handle_t ioh;
2631 u_char val;
2632
2633 iot = sc->sc_iot;
2634 ioh = sc->sc_ioh;
2635 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2636 val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
2637
2638 DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
2639 return val;
2640 }
2641
2642 void
ess_clear_mreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2643 ess_clear_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2644 {
2645
2646 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
2647 }
2648
2649 void
ess_set_mreg_bits(struct ess_softc * sc,u_char reg,u_char mask)2650 ess_set_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
2651 {
2652
2653 ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
2654 }
2655
2656 void
ess_read_multi_mix_reg(struct ess_softc * sc,u_char reg,uint8_t * datap,bus_size_t count)2657 ess_read_multi_mix_reg(struct ess_softc *sc, u_char reg,
2658 uint8_t *datap, bus_size_t count)
2659 {
2660 bus_space_tag_t iot;
2661 bus_space_handle_t ioh;
2662
2663 iot = sc->sc_iot;
2664 ioh = sc->sc_ioh;
2665 EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
2666 bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
2667 }
2668