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