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