aucc.c revision 1.41 1 1.41 jmcneill /* $NetBSD: aucc.c,v 1.41 2011/11/23 23:07:28 jmcneill Exp $ */
2 1.20 augustss
3 1.1 is /*
4 1.24 is * Copyright (c) 1999 Bernardo Innocenti
5 1.24 is * All rights reserved.
6 1.24 is *
7 1.1 is * Copyright (c) 1997 Stephan Thesing
8 1.1 is * All rights reserved.
9 1.1 is *
10 1.1 is * Redistribution and use in source and binary forms, with or without
11 1.1 is * modification, are permitted provided that the following conditions
12 1.1 is * are met:
13 1.1 is * 1. Redistributions of source code must retain the above copyright
14 1.1 is * notice, this list of conditions and the following disclaimer.
15 1.1 is * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 is * notice, this list of conditions and the following disclaimer in the
17 1.1 is * documentation and/or other materials provided with the distribution.
18 1.1 is * 3. All advertising materials mentioning features or use of this software
19 1.1 is * must display the following acknowledgement:
20 1.1 is * This product includes software developed by Stephan Thesing.
21 1.1 is * 4. The name of the author may not be used to endorse or promote products
22 1.1 is * derived from this software without specific prior written permission
23 1.1 is *
24 1.1 is * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 1.1 is * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 1.1 is * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 1.1 is * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 1.1 is * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 1.1 is * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 1.1 is * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 1.1 is * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 1.1 is * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 1.1 is * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 1.1 is */
35 1.1 is
36 1.24 is /* TODO:
37 1.24 is *
38 1.33 wiz * - mu-law -> 14bit conversion
39 1.24 is * - channel allocation is wrong for 14bit mono
40 1.24 is * - convert the... err... conversion routines to 68k asm for best performance
41 1.29 aymeric * XXX: NO. aucc audio is limited by chipmem speed, anyway. You dont
42 1.24 is * want to make life difficult for amigappc work.
43 1.24 is * -is
44 1.24 is *
45 1.33 wiz * - rely on auconv.c routines for mu-law/A-law conversions
46 1.24 is * - perhaps use a calibration table for better 14bit output
47 1.40 lukem * - set 31 kHz AGA video mode to allow 44.1 kHz even if grfcc is missing
48 1.24 is * in the kernel
49 1.24 is * - 14bit output requires maximum volume
50 1.24 is */
51 1.24 is
52 1.1 is #include "aucc.h"
53 1.1 is #if NAUCC > 0
54 1.30 aymeric
55 1.30 aymeric #include <sys/cdefs.h>
56 1.41 jmcneill __KERNEL_RCSID(0, "$NetBSD: aucc.c,v 1.41 2011/11/23 23:07:28 jmcneill Exp $");
57 1.5 is
58 1.1 is #include <sys/param.h>
59 1.1 is #include <sys/systm.h>
60 1.1 is #include <sys/errno.h>
61 1.1 is #include <sys/ioctl.h>
62 1.1 is #include <sys/device.h>
63 1.1 is #include <sys/proc.h>
64 1.1 is #include <machine/cpu.h>
65 1.1 is
66 1.1 is #include <sys/audioio.h>
67 1.1 is #include <dev/audio_if.h>
68 1.1 is #include <amiga/amiga/cc.h>
69 1.1 is #include <amiga/amiga/custom.h>
70 1.1 is #include <amiga/amiga/device.h>
71 1.1 is #include <amiga/dev/auccvar.h>
72 1.27 is
73 1.27 is #include "opt_lev6_defer.h"
74 1.1 is
75 1.7 is
76 1.7 is #ifdef LEV6_DEFER
77 1.7 is #define AUCC_MAXINT 3
78 1.7 is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
79 1.7 is #else
80 1.7 is #define AUCC_MAXINT 4
81 1.7 is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
82 1.7 is #endif
83 1.7 is /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
84 1.7 is #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
85 1.7 is
86 1.1 is #ifdef AUDIO_DEBUG
87 1.29 aymeric /*extern printf(const char *,...);*/
88 1.1 is int auccdebug = 1;
89 1.1 is #define DPRINTF(x) if (auccdebug) printf x
90 1.1 is #else
91 1.1 is #define DPRINTF(x)
92 1.1 is #endif
93 1.1 is
94 1.1 is /* clock frequency.. */
95 1.29 aymeric extern int eclockfreq;
96 1.1 is
97 1.1 is
98 1.1 is /* hw audio ch */
99 1.1 is extern struct audio_channel channel[4];
100 1.1 is
101 1.1 is
102 1.1 is /*
103 1.1 is * Software state.
104 1.1 is */
105 1.1 is struct aucc_softc {
106 1.1 is struct device sc_dev; /* base device */
107 1.1 is
108 1.1 is int sc_open; /* single use device */
109 1.1 is aucc_data_t sc_channel[4]; /* per channel freq, ... */
110 1.1 is u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/
111 1.1 is int sc_channels; /* # of channels used */
112 1.24 is int sc_precision; /* 8 or 16 bits */
113 1.24 is int sc_14bit; /* 14bit output enabled */
114 1.1 is
115 1.1 is int sc_intrcnt; /* interrupt count */
116 1.37 kent int sc_channelmask; /* which channels are used ? */
117 1.29 aymeric void (*sc_decodefunc)(u_char **, u_char *, int);
118 1.24 is /* pointer to format conversion routine */
119 1.41 jmcneill
120 1.41 jmcneill kmutex_t sc_lock;
121 1.41 jmcneill kmutex_t sc_intr_lock;
122 1.1 is };
123 1.1 is
124 1.1 is /* interrupt interfaces */
125 1.29 aymeric void aucc_inthdl(int);
126 1.1 is
127 1.1 is /* forward declarations */
128 1.29 aymeric static int init_aucc(struct aucc_softc *);
129 1.29 aymeric static u_int freqtoper(u_int);
130 1.29 aymeric static u_int pertofreq(u_int);
131 1.1 is
132 1.1 is /* autoconfiguration driver */
133 1.29 aymeric void auccattach(struct device *, struct device *, void *);
134 1.29 aymeric int auccmatch(struct device *, struct cfdata *, void *);
135 1.1 is
136 1.32 thorpej CFATTACH_DECL(aucc, sizeof(struct aucc_softc),
137 1.32 thorpej auccmatch, auccattach, NULL, NULL);
138 1.1 is
139 1.1 is struct audio_device aucc_device = {
140 1.1 is "Amiga-audio",
141 1.24 is "2.0",
142 1.1 is "aucc"
143 1.1 is };
144 1.1 is
145 1.1 is
146 1.37 kent struct aucc_softc *aucc = NULL;
147 1.1 is
148 1.1 is
149 1.33 wiz unsigned char mulaw_to_lin[] = {
150 1.2 is 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
151 1.2 is 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
152 1.2 is 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf,
153 1.2 is 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf,
154 1.2 is 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
155 1.2 is 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
156 1.2 is 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4,
157 1.2 is 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
158 1.2 is 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
159 1.2 is 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
160 1.2 is 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
161 1.2 is 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
162 1.2 is 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
163 1.2 is 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
164 1.2 is 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
165 1.2 is 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
166 1.2 is 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61,
167 1.2 is 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41,
168 1.2 is 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30,
169 1.2 is 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
170 1.2 is 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17,
171 1.2 is 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
172 1.2 is 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
173 1.2 is 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
174 1.2 is 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05,
175 1.2 is 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
176 1.2 is 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
177 1.2 is 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
178 1.2 is 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
179 1.2 is 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 1.2 is 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 1.2 is 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 1.1 is };
183 1.1 is
184 1.1 is /*
185 1.1 is * Define our interface to the higher level audio driver.
186 1.1 is */
187 1.29 aymeric int aucc_open(void *, int);
188 1.29 aymeric void aucc_close(void *);
189 1.36 kent int aucc_set_out_sr(void *, u_int);
190 1.29 aymeric int aucc_query_encoding(void *, struct audio_encoding *);
191 1.36 kent int aucc_round_blocksize(void *, int, int, const audio_params_t *);
192 1.29 aymeric int aucc_commit_settings(void *);
193 1.29 aymeric int aucc_start_output(void *, void *, int, void (*)(void *), void *);
194 1.29 aymeric int aucc_start_input(void *, void *, int, void (*)(void *), void *);
195 1.29 aymeric int aucc_halt_output(void *);
196 1.29 aymeric int aucc_halt_input(void *);
197 1.29 aymeric int aucc_getdev(void *, struct audio_device *);
198 1.29 aymeric int aucc_set_port(void *, mixer_ctrl_t *);
199 1.29 aymeric int aucc_get_port(void *, mixer_ctrl_t *);
200 1.29 aymeric int aucc_query_devinfo(void *, mixer_devinfo_t *);
201 1.29 aymeric void aucc_encode(int, int, int, int, u_char *, u_short **);
202 1.36 kent int aucc_set_params(void *, int, int, audio_params_t *, audio_params_t *,
203 1.36 kent stream_filter_list_t *, stream_filter_list_t *);
204 1.29 aymeric int aucc_get_props(void *);
205 1.41 jmcneill void aucc_get_locks(void *, kmutex_t **, kmutex_t **);
206 1.29 aymeric
207 1.29 aymeric
208 1.29 aymeric static void aucc_decode_slinear8_1ch(u_char **, u_char *, int);
209 1.29 aymeric static void aucc_decode_slinear8_2ch(u_char **, u_char *, int);
210 1.29 aymeric static void aucc_decode_slinear8_3ch(u_char **, u_char *, int);
211 1.29 aymeric static void aucc_decode_slinear8_4ch(u_char **, u_char *, int);
212 1.29 aymeric
213 1.29 aymeric static void aucc_decode_ulinear8_1ch(u_char **, u_char *, int);
214 1.29 aymeric static void aucc_decode_ulinear8_2ch(u_char **, u_char *, int);
215 1.29 aymeric static void aucc_decode_ulinear8_3ch(u_char **, u_char *, int);
216 1.29 aymeric static void aucc_decode_ulinear8_4ch(u_char **, u_char *, int);
217 1.29 aymeric
218 1.33 wiz static void aucc_decode_mulaw_1ch(u_char **, u_char *, int);
219 1.33 wiz static void aucc_decode_mulaw_2ch(u_char **, u_char *, int);
220 1.33 wiz static void aucc_decode_mulaw_3ch(u_char **, u_char *, int);
221 1.33 wiz static void aucc_decode_mulaw_4ch(u_char **, u_char *, int);
222 1.29 aymeric
223 1.29 aymeric static void aucc_decode_slinear16_1ch(u_char **, u_char *, int);
224 1.29 aymeric static void aucc_decode_slinear16_2ch(u_char **, u_char *, int);
225 1.29 aymeric static void aucc_decode_slinear16_3ch(u_char **, u_char *, int);
226 1.29 aymeric static void aucc_decode_slinear16_4ch(u_char **, u_char *, int);
227 1.29 aymeric
228 1.29 aymeric static void aucc_decode_slinear16sw_1ch(u_char **, u_char *, int);
229 1.29 aymeric static void aucc_decode_slinear16sw_2ch(u_char **, u_char *, int);
230 1.29 aymeric static void aucc_decode_slinear16sw_3ch(u_char **, u_char *, int);
231 1.29 aymeric static void aucc_decode_slinear16sw_4ch(u_char **, u_char *, int);
232 1.24 is
233 1.24 is
234 1.24 is
235 1.35 yamt const struct audio_hw_if sa_hw_if = {
236 1.1 is aucc_open,
237 1.1 is aucc_close,
238 1.1 is NULL,
239 1.1 is aucc_query_encoding,
240 1.1 is aucc_set_params,
241 1.1 is aucc_round_blocksize,
242 1.1 is aucc_commit_settings,
243 1.14 augustss NULL,
244 1.14 augustss NULL,
245 1.1 is aucc_start_output,
246 1.1 is aucc_start_input,
247 1.1 is aucc_halt_output,
248 1.1 is aucc_halt_input,
249 1.1 is NULL,
250 1.1 is aucc_getdev,
251 1.13 augustss NULL,
252 1.1 is aucc_set_port,
253 1.1 is aucc_get_port,
254 1.1 is aucc_query_devinfo,
255 1.14 augustss NULL,
256 1.14 augustss NULL,
257 1.14 augustss NULL,
258 1.15 augustss NULL,
259 1.16 augustss aucc_get_props,
260 1.28 augustss NULL,
261 1.28 augustss NULL,
262 1.28 augustss NULL,
263 1.41 jmcneill aucc_get_locks,
264 1.1 is };
265 1.1 is
266 1.1 is /* autoconfig routines */
267 1.1 is
268 1.1 is int
269 1.29 aymeric auccmatch(struct device *pdp, struct cfdata *cfp, void *aux)
270 1.1 is {
271 1.25 kleink static int aucc_matched = 0;
272 1.25 kleink
273 1.25 kleink if (!matchname((char *)aux, "aucc") ||
274 1.1 is #ifdef DRACO
275 1.25 kleink is_draco() ||
276 1.1 is #endif
277 1.25 kleink aucc_matched)
278 1.25 kleink return 0;
279 1.1 is
280 1.25 kleink aucc_matched = 1;
281 1.25 kleink return 1;
282 1.1 is }
283 1.1 is
284 1.1 is /*
285 1.1 is * Audio chip found.
286 1.1 is */
287 1.1 is void
288 1.29 aymeric auccattach(struct device *parent, struct device *self, void *args)
289 1.1 is {
290 1.37 kent struct aucc_softc *sc;
291 1.37 kent int i;
292 1.1 is
293 1.37 kent sc = (struct aucc_softc *)self;
294 1.1 is printf("\n");
295 1.1 is
296 1.37 kent if ((i=init_aucc(sc))) {
297 1.1 is printf("audio: no chipmem\n");
298 1.1 is return;
299 1.1 is }
300 1.1 is
301 1.23 augustss audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev);
302 1.1 is }
303 1.1 is
304 1.1 is
305 1.1 is static int
306 1.29 aymeric init_aucc(struct aucc_softc *sc)
307 1.1 is {
308 1.37 kent int i, err;
309 1.1 is
310 1.37 kent err = 0;
311 1.1 is /* init values per channel */
312 1.37 kent for (i = 0; i < 4; i++) {
313 1.37 kent sc->sc_channel[i].nd_freq = 8000;
314 1.37 kent sc->sc_channel[i].nd_per = freqtoper(8000);
315 1.37 kent sc->sc_channel[i].nd_busy = 0;
316 1.37 kent sc->sc_channel[i].nd_dma = alloc_chipmem(AUDIO_BUF_SIZE*2);
317 1.37 kent if (sc->sc_channel[i].nd_dma == NULL)
318 1.37 kent err = 1;
319 1.37 kent sc->sc_channel[i].nd_dmalength = 0;
320 1.37 kent sc->sc_channel[i].nd_volume = 64;
321 1.37 kent sc->sc_channel[i].nd_intr = NULL;
322 1.37 kent sc->sc_channel[i].nd_intrdata = NULL;
323 1.37 kent sc->sc_channel[i].nd_doublebuf = 0;
324 1.34 wiz DPRINTF(("DMA buffer for channel %d is %p\n", i,
325 1.1 is sc->sc_channel[i].nd_dma));
326 1.1 is }
327 1.1 is
328 1.1 is if (err) {
329 1.37 kent for (i = 0; i < 4; i++)
330 1.1 is if (sc->sc_channel[i].nd_dma)
331 1.1 is free_chipmem(sc->sc_channel[i].nd_dma);
332 1.1 is }
333 1.1 is
334 1.37 kent sc->sc_channels = 1;
335 1.37 kent sc->sc_channelmask = 0xf;
336 1.37 kent sc->sc_precision = 8;
337 1.24 is sc->sc_14bit = 0;
338 1.37 kent sc->sc_encoding = AUDIO_ENCODING_ULAW;
339 1.33 wiz sc->sc_decodefunc = aucc_decode_mulaw_1ch;
340 1.1 is
341 1.34 wiz /* clear interrupts and DMA: */
342 1.7 is custom.intena = AUCC_ALLINTF;
343 1.24 is custom.dmacon = AUCC_ALLDMAF;
344 1.1 is
345 1.41 jmcneill mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
346 1.41 jmcneill mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
347 1.41 jmcneill
348 1.1 is return err;
349 1.1 is }
350 1.1 is
351 1.1 is int
352 1.29 aymeric aucc_open(void *addr, int flags)
353 1.1 is {
354 1.37 kent struct aucc_softc *sc;
355 1.16 augustss int i;
356 1.1 is
357 1.37 kent sc = addr;
358 1.16 augustss DPRINTF(("sa_open: unit %p\n",sc));
359 1.1 is
360 1.1 is if (sc->sc_open)
361 1.37 kent return EBUSY;
362 1.1 is sc->sc_open = 1;
363 1.37 kent for (i = 0; i < AUCC_MAXINT; i++) {
364 1.37 kent sc->sc_channel[i].nd_intr = NULL;
365 1.37 kent sc->sc_channel[i].nd_intrdata = NULL;
366 1.1 is }
367 1.37 kent aucc = sc;
368 1.37 kent sc->sc_channelmask = 0xf;
369 1.1 is
370 1.38 christos DPRINTF(("saopen: ok -> sc=%p\n",sc));
371 1.1 is
372 1.37 kent return 0;
373 1.1 is }
374 1.1 is
375 1.1 is void
376 1.29 aymeric aucc_close(void *addr)
377 1.1 is {
378 1.37 kent struct aucc_softc *sc;
379 1.1 is
380 1.37 kent sc = addr;
381 1.38 christos DPRINTF(("sa_close: sc=%p\n", sc));
382 1.1 is /*
383 1.1 is * halt i/o, clear open flag, and done.
384 1.1 is */
385 1.1 is aucc_halt_output(sc);
386 1.1 is sc->sc_open = 0;
387 1.1 is
388 1.1 is DPRINTF(("sa_close: closed.\n"));
389 1.1 is }
390 1.1 is
391 1.1 is int
392 1.36 kent aucc_set_out_sr(void *addr, u_int sr)
393 1.1 is {
394 1.37 kent struct aucc_softc *sc;
395 1.1 is u_long per;
396 1.37 kent int i;
397 1.1 is
398 1.37 kent sc = addr;
399 1.37 kent per = freqtoper(sr);
400 1.37 kent if (per > 0xffff)
401 1.1 is return EINVAL;
402 1.37 kent sr = pertofreq(per);
403 1.1 is
404 1.37 kent for (i = 0; i < 4; i++) {
405 1.37 kent sc->sc_channel[i].nd_freq = sr;
406 1.37 kent sc->sc_channel[i].nd_per = per;
407 1.1 is }
408 1.1 is
409 1.37 kent return 0;
410 1.1 is }
411 1.1 is
412 1.1 is int
413 1.29 aymeric aucc_query_encoding(void *addr, struct audio_encoding *fp)
414 1.1 is {
415 1.37 kent
416 1.24 is switch (fp->index) {
417 1.37 kent case 0:
418 1.37 kent strcpy(fp->name, AudioEslinear);
419 1.37 kent fp->encoding = AUDIO_ENCODING_SLINEAR;
420 1.37 kent fp->precision = 8;
421 1.37 kent fp->flags = 0;
422 1.37 kent break;
423 1.37 kent case 1:
424 1.37 kent strcpy(fp->name, AudioEmulaw);
425 1.37 kent fp->encoding = AUDIO_ENCODING_ULAW;
426 1.37 kent fp->precision = 8;
427 1.37 kent fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
428 1.37 kent break;
429 1.29 aymeric
430 1.37 kent case 2:
431 1.37 kent strcpy(fp->name, AudioEulinear);
432 1.37 kent fp->encoding = AUDIO_ENCODING_ULINEAR;
433 1.37 kent fp->precision = 8;
434 1.37 kent fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
435 1.37 kent break;
436 1.24 is
437 1.37 kent case 3:
438 1.37 kent strcpy(fp->name, AudioEslinear);
439 1.37 kent fp->encoding = AUDIO_ENCODING_SLINEAR;
440 1.37 kent fp->precision = 16;
441 1.37 kent fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
442 1.37 kent break;
443 1.24 is
444 1.37 kent case 4:
445 1.37 kent strcpy(fp->name, AudioEslinear_be);
446 1.37 kent fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
447 1.37 kent fp->precision = 16;
448 1.37 kent fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
449 1.37 kent break;
450 1.24 is
451 1.37 kent case 5:
452 1.37 kent strcpy(fp->name, AudioEslinear_le);
453 1.37 kent fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
454 1.37 kent fp->precision = 16;
455 1.37 kent fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
456 1.37 kent break;
457 1.3 is
458 1.37 kent default:
459 1.37 kent return EINVAL;
460 1.37 kent /*NOTREACHED*/
461 1.1 is }
462 1.37 kent return 0;
463 1.1 is }
464 1.1 is
465 1.1 is int
466 1.36 kent aucc_set_params(void *addr, int setmode, int usemode,
467 1.36 kent audio_params_t *p, audio_params_t *r,
468 1.36 kent stream_filter_list_t *pfil, stream_filter_list_t *rfil)
469 1.1 is {
470 1.37 kent struct aucc_softc *sc;
471 1.8 is
472 1.37 kent sc = addr;
473 1.18 augustss /* if (setmode & AUMODE_RECORD)
474 1.8 is return 0 ENXIO*/;
475 1.8 is
476 1.9 is #ifdef AUCCDEBUG
477 1.24 is printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
478 1.37 kent "enc %u, bits %u, chn %u, sr %u)\n", setmode, usemode,
479 1.37 kent p->encoding, p->precision, p->channels, p->sample_rate);
480 1.24 is #endif
481 1.24 is
482 1.24 is switch (p->precision) {
483 1.24 is case 8:
484 1.24 is switch (p->encoding) {
485 1.24 is case AUDIO_ENCODING_ULAW:
486 1.24 is switch (p->channels) {
487 1.24 is case 1:
488 1.33 wiz sc->sc_decodefunc = aucc_decode_mulaw_1ch;
489 1.24 is break;
490 1.24 is case 2:
491 1.33 wiz sc->sc_decodefunc = aucc_decode_mulaw_2ch;
492 1.24 is break;
493 1.24 is case 3:
494 1.33 wiz sc->sc_decodefunc = aucc_decode_mulaw_3ch;
495 1.24 is break;
496 1.24 is case 4:
497 1.33 wiz sc->sc_decodefunc = aucc_decode_mulaw_4ch;
498 1.24 is break;
499 1.24 is default:
500 1.24 is return EINVAL;
501 1.24 is }
502 1.24 is break;
503 1.24 is
504 1.24 is case AUDIO_ENCODING_SLINEAR:
505 1.24 is case AUDIO_ENCODING_SLINEAR_BE:
506 1.24 is case AUDIO_ENCODING_SLINEAR_LE:
507 1.24 is switch (p->channels) {
508 1.24 is case 1:
509 1.24 is sc->sc_decodefunc = aucc_decode_slinear8_1ch;
510 1.24 is break;
511 1.24 is case 2:
512 1.24 is sc->sc_decodefunc = aucc_decode_slinear8_2ch;
513 1.24 is break;
514 1.24 is case 3:
515 1.24 is sc->sc_decodefunc = aucc_decode_slinear8_3ch;
516 1.24 is break;
517 1.24 is case 4:
518 1.24 is sc->sc_decodefunc = aucc_decode_slinear8_4ch;
519 1.24 is break;
520 1.24 is default:
521 1.24 is return EINVAL;
522 1.24 is }
523 1.24 is break;
524 1.24 is
525 1.24 is case AUDIO_ENCODING_ULINEAR:
526 1.24 is case AUDIO_ENCODING_ULINEAR_BE:
527 1.24 is case AUDIO_ENCODING_ULINEAR_LE:
528 1.24 is switch (p->channels) {
529 1.24 is case 1:
530 1.24 is sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
531 1.24 is break;
532 1.24 is case 2:
533 1.24 is sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
534 1.24 is break;
535 1.24 is case 3:
536 1.24 is sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
537 1.24 is break;
538 1.24 is case 4:
539 1.24 is sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
540 1.24 is break;
541 1.24 is default:
542 1.24 is return EINVAL;
543 1.24 is }
544 1.24 is break;
545 1.24 is
546 1.24 is default:
547 1.24 is return EINVAL;
548 1.24 is }
549 1.24 is break;
550 1.24 is
551 1.24 is case 16:
552 1.24 is switch (p->encoding) {
553 1.24 is #if BYTE_ORDER == BIG_ENDIAN
554 1.24 is case AUDIO_ENCODING_SLINEAR:
555 1.24 is #endif
556 1.24 is case AUDIO_ENCODING_SLINEAR_BE:
557 1.24 is switch (p->channels) {
558 1.24 is case 1:
559 1.24 is sc->sc_decodefunc = aucc_decode_slinear16_1ch;
560 1.24 is break;
561 1.24 is
562 1.24 is case 2:
563 1.24 is sc->sc_decodefunc = aucc_decode_slinear16_2ch;
564 1.24 is break;
565 1.24 is case 3:
566 1.24 is sc->sc_decodefunc = aucc_decode_slinear16_3ch;
567 1.24 is break;
568 1.24 is case 4:
569 1.24 is sc->sc_decodefunc = aucc_decode_slinear16_4ch;
570 1.24 is break;
571 1.24 is default:
572 1.24 is return EINVAL;
573 1.24 is }
574 1.24 is break;
575 1.24 is
576 1.24 is #if BYTE_ORDER == LITTLE_ENDIAN
577 1.24 is case AUDIO_ENCODING_SLINEAR:
578 1.9 is #endif
579 1.24 is case AUDIO_ENCODING_SLINEAR_LE:
580 1.24 is switch (p->channels) {
581 1.24 is case 1:
582 1.24 is sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
583 1.24 is break;
584 1.24 is case 2:
585 1.24 is sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
586 1.24 is break;
587 1.24 is case 3:
588 1.24 is sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
589 1.24 is break;
590 1.24 is case 4:
591 1.24 is sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
592 1.24 is break;
593 1.24 is default:
594 1.24 is return EINVAL;
595 1.24 is }
596 1.24 is break;
597 1.4 is
598 1.24 is default:
599 1.24 is return EINVAL;
600 1.24 is }
601 1.24 is break;
602 1.8 is
603 1.1 is default:
604 1.1 is return EINVAL;
605 1.1 is }
606 1.1 is
607 1.8 is sc->sc_encoding = p->encoding;
608 1.24 is sc->sc_precision = p->precision;
609 1.24 is sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
610 1.24 is sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
611 1.8 is
612 1.8 is return aucc_set_out_sr(addr, p->sample_rate);
613 1.1 is }
614 1.1 is
615 1.1 is int
616 1.36 kent aucc_round_blocksize(void *addr, int blk,
617 1.36 kent int mode, const audio_params_t *param)
618 1.1 is {
619 1.37 kent
620 1.24 is /* round up to even size */
621 1.24 is return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
622 1.1 is }
623 1.1 is
624 1.1 is int
625 1.29 aymeric aucc_commit_settings(void *addr)
626 1.1 is {
627 1.37 kent struct aucc_softc *sc;
628 1.37 kent int i;
629 1.1 is
630 1.1 is DPRINTF(("sa_commit.\n"));
631 1.1 is
632 1.37 kent sc = addr;
633 1.37 kent for (i = 0; i < 4; i++) {
634 1.37 kent custom.aud[i].vol = sc->sc_channel[i].nd_volume;
635 1.37 kent custom.aud[i].per = sc->sc_channel[i].nd_per;
636 1.1 is }
637 1.1 is
638 1.1 is DPRINTF(("commit done\n"));
639 1.1 is
640 1.37 kent return 0;
641 1.1 is }
642 1.1 is
643 1.1 is static int masks[4] = {1,3,7,15}; /* masks for n first channels */
644 1.1 is static int masks2[4] = {1,2,4,8};
645 1.1 is
646 1.1 is int
647 1.29 aymeric aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
648 1.1 is {
649 1.8 is struct aucc_softc *sc;
650 1.8 is int mask;
651 1.24 is int i, j, k, len;
652 1.24 is u_char *dmap[4];
653 1.8 is
654 1.1 is
655 1.8 is sc = addr;
656 1.8 is mask = sc->sc_channelmask;
657 1.1 is
658 1.8 is dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
659 1.1 is
660 1.1 is DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
661 1.1 is
662 1.10 is if (sc->sc_channels > 1)
663 1.24 is mask &= masks[sc->sc_channels - 1];
664 1.10 is /* we use first sc_channels channels */
665 1.24 is if (mask == 0) /* active and used channels are disjoint */
666 1.1 is return EINVAL;
667 1.1 is
668 1.37 kent for (i = 0; i < 4; i++) {
669 1.24 is /* channels available ? */
670 1.24 is if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
671 1.1 is return EBUSY; /* channel is busy */
672 1.24 is if (channel[i].isaudio == -1)
673 1.1 is return EBUSY; /* system uses them */
674 1.1 is }
675 1.1 is
676 1.1 is /* enable interrupt on 1st channel */
677 1.24 is for (i = j = 0; i < AUCC_MAXINT; i++) {
678 1.24 is if (masks2[i] & mask) {
679 1.1 is DPRINTF(("first channel is %d\n",i));
680 1.37 kent j = i;
681 1.37 kent sc->sc_channel[i].nd_intr = intr;
682 1.37 kent sc->sc_channel[i].nd_intrdata = arg;
683 1.1 is break;
684 1.1 is }
685 1.1 is }
686 1.1 is
687 1.8 is DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
688 1.37 kent dmap[2], dmap[3], mask));
689 1.8 is
690 1.34 wiz /* disable ints, DMA for channels, until all parameters set */
691 1.8 is /* XXX dont disable DMA! custom.dmacon=mask;*/
692 1.24 is custom.intreq = mask << INTB_AUD0;
693 1.24 is custom.intena = mask << INTB_AUD0;
694 1.1 is
695 1.34 wiz /* copy data to DMA buffer */
696 1.29 aymeric
697 1.8 is if (sc->sc_channels == 1) {
698 1.8 is dmap[0] =
699 1.8 is dmap[1] =
700 1.8 is dmap[2] =
701 1.24 is dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
702 1.37 kent } else {
703 1.37 kent for (k = 0; k < 4; k++) {
704 1.24 is if (masks2[k+j] & mask)
705 1.24 is dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
706 1.8 is }
707 1.8 is }
708 1.8 is
709 1.8 is sc->sc_channel[j].nd_doublebuf ^= 1;
710 1.8 is if (sc->sc_channel[j].nd_doublebuf) {
711 1.24 is dmap[0] += AUDIO_BUF_SIZE;
712 1.24 is dmap[1] += AUDIO_BUF_SIZE;
713 1.24 is dmap[2] += AUDIO_BUF_SIZE;
714 1.24 is dmap[3] += AUDIO_BUF_SIZE;
715 1.8 is }
716 1.1 is
717 1.37 kent /*
718 1.37 kent * compute output length in bytes per channel.
719 1.24 is * divide by two only for 16bit->8bit conversion.
720 1.24 is */
721 1.24 is len = cc / sc->sc_channels;
722 1.24 is if (!sc->sc_14bit && (sc->sc_precision == 16))
723 1.24 is len /= 2;
724 1.24 is
725 1.24 is /* call audio decoding routine */
726 1.24 is sc->sc_decodefunc (dmap, (u_char *)p, len);
727 1.1 is
728 1.34 wiz /* DMA buffers: we use same buffer 4 all channels
729 1.34 wiz * write DMA location and length
730 1.24 is */
731 1.24 is for (i = k = 0; i < 4; i++) {
732 1.8 is if (masks2[i] & mask) {
733 1.1 is DPRINTF(("turning channel %d on\n",i));
734 1.24 is /* sc->sc_channel[i].nd_busy=1; */
735 1.24 is channel[i].isaudio = 1;
736 1.24 is channel[i].play_count = 1;
737 1.24 is channel[i].handler = NULL;
738 1.24 is custom.aud[i].per = sc->sc_channel[i].nd_per;
739 1.24 is if (sc->sc_14bit && (i > 1))
740 1.24 is custom.aud[i].vol = 1;
741 1.24 is else
742 1.24 is custom.aud[i].vol = sc->sc_channel[i].nd_volume;
743 1.8 is custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
744 1.24 is custom.aud[i].len = len / 2;
745 1.24 is sc->sc_channel[i].nd_mask = mask;
746 1.1 is DPRINTF(("per is %d, vol is %d, len is %d\n",\
747 1.8 is sc->sc_channel[i].nd_per,
748 1.24 is sc->sc_channel[i].nd_volume, len));
749 1.1 is }
750 1.1 is }
751 1.1 is
752 1.37 kent channel[j].handler = aucc_inthdl;
753 1.1 is
754 1.1 is /* enable ints */
755 1.24 is custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
756 1.1 is
757 1.24 is DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
758 1.1 is
759 1.34 wiz /* enable DMA */
760 1.24 is custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
761 1.1 is
762 1.34 wiz DPRINTF(("enabled DMA, mask=0x%x\n",mask));
763 1.1 is
764 1.37 kent return 0;
765 1.1 is }
766 1.1 is
767 1.1 is /* ARGSUSED */
768 1.1 is int
769 1.29 aymeric aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
770 1.1 is {
771 1.1 is
772 1.1 is return ENXIO; /* no input */
773 1.1 is }
774 1.1 is
775 1.1 is int
776 1.29 aymeric aucc_halt_output(void *addr)
777 1.1 is {
778 1.37 kent struct aucc_softc *sc;
779 1.37 kent int i;
780 1.1 is
781 1.1 is /* XXX only halt, if input is also halted ?? */
782 1.37 kent sc = addr;
783 1.34 wiz /* stop DMA, etc */
784 1.7 is custom.intena = AUCC_ALLINTF;
785 1.7 is custom.dmacon = AUCC_ALLDMAF;
786 1.1 is /* mark every busy unit idle */
787 1.37 kent for (i = 0; i < 4; i++) {
788 1.37 kent sc->sc_channel[i].nd_busy = sc->sc_channel[i].nd_mask = 0;
789 1.37 kent channel[i].isaudio = 0;
790 1.37 kent channel[i].play_count = 0;
791 1.1 is }
792 1.1 is
793 1.37 kent return 0;
794 1.1 is }
795 1.1 is
796 1.1 is int
797 1.29 aymeric aucc_halt_input(void *addr)
798 1.1 is {
799 1.37 kent
800 1.1 is /* no input */
801 1.1 is return ENXIO;
802 1.1 is }
803 1.1 is
804 1.1 is int
805 1.29 aymeric aucc_getdev(void *addr, struct audio_device *retp)
806 1.1 is {
807 1.37 kent
808 1.37 kent *retp = aucc_device;
809 1.37 kent return 0;
810 1.1 is }
811 1.1 is
812 1.1 is int
813 1.29 aymeric aucc_set_port(void *addr, mixer_ctrl_t *cp)
814 1.1 is {
815 1.37 kent struct aucc_softc *sc;
816 1.37 kent int i,j;
817 1.1 is
818 1.1 is DPRINTF(("aucc_set_port: port=%d", cp->dev));
819 1.37 kent sc = addr;
820 1.1 is switch (cp->type) {
821 1.1 is case AUDIO_MIXER_SET:
822 1.37 kent if (cp->dev != AUCC_CHANNELS)
823 1.1 is return EINVAL;
824 1.37 kent i = cp->un.mask;
825 1.37 kent if ((i < 1) || (i > 15))
826 1.1 is return EINVAL;
827 1.24 is
828 1.37 kent sc->sc_channelmask = i;
829 1.1 is break;
830 1.1 is
831 1.1 is case AUDIO_MIXER_VALUE:
832 1.37 kent i = cp->un.value.num_channels;
833 1.37 kent if ((i < 1) || (i > 4))
834 1.1 is return EINVAL;
835 1.1 is
836 1.10 is #ifdef __XXXwhatsthat
837 1.37 kent if (cp->dev != AUCC_VOLUME)
838 1.1 is return EINVAL;
839 1.10 is #endif
840 1.1 is
841 1.1 is /* set volume for channel 0..i-1 */
842 1.21 is
843 1.21 is /* evil workaround for xanim bug, IMO */
844 1.21 is if ((sc->sc_channels == 1) && (i == 2)) {
845 1.29 aymeric sc->sc_channel[0].nd_volume =
846 1.29 aymeric sc->sc_channel[3].nd_volume =
847 1.37 kent cp->un.value.level[0] >> 2;
848 1.29 aymeric sc->sc_channel[1].nd_volume =
849 1.29 aymeric sc->sc_channel[2].nd_volume =
850 1.37 kent cp->un.value.level[1] >> 2;
851 1.37 kent } else if (i > 1) {
852 1.37 kent for (j = 0; j < i; j++)
853 1.37 kent sc->sc_channel[j].nd_volume =
854 1.37 kent cp->un.value.level[j] >> 2;
855 1.21 is } else if (sc->sc_channels > 1)
856 1.37 kent for (j = 0; j < sc->sc_channels; j++)
857 1.37 kent sc->sc_channel[j].nd_volume =
858 1.37 kent cp->un.value.level[0] >> 2;
859 1.10 is else
860 1.37 kent for (j = 0; j < 4; j++)
861 1.37 kent sc->sc_channel[j].nd_volume =
862 1.37 kent cp->un.value.level[0] >> 2;
863 1.10 is break;
864 1.1 is
865 1.1 is default:
866 1.1 is return EINVAL;
867 1.1 is break;
868 1.1 is }
869 1.1 is return 0;
870 1.1 is }
871 1.1 is
872 1.1 is
873 1.1 is int
874 1.29 aymeric aucc_get_port(void *addr, mixer_ctrl_t *cp)
875 1.1 is {
876 1.37 kent struct aucc_softc *sc;
877 1.37 kent int i,j;
878 1.1 is
879 1.1 is DPRINTF(("aucc_get_port: port=%d", cp->dev));
880 1.37 kent sc = addr;
881 1.1 is switch (cp->type) {
882 1.1 is case AUDIO_MIXER_SET:
883 1.37 kent if (cp->dev != AUCC_CHANNELS)
884 1.1 is return EINVAL;
885 1.37 kent cp->un.mask = sc->sc_channelmask;
886 1.1 is break;
887 1.1 is
888 1.1 is case AUDIO_MIXER_VALUE:
889 1.1 is i = cp->un.value.num_channels;
890 1.37 kent if ((i < 1) || (i > 4))
891 1.1 is return EINVAL;
892 1.1 is
893 1.37 kent for (j = 0; j < i; j++)
894 1.10 is cp->un.value.level[j] =
895 1.37 kent (sc->sc_channel[j].nd_volume << 2) +
896 1.37 kent (sc->sc_channel[j].nd_volume >> 4);
897 1.1 is break;
898 1.1 is
899 1.1 is default:
900 1.1 is return EINVAL;
901 1.1 is }
902 1.1 is return 0;
903 1.1 is }
904 1.1 is
905 1.16 augustss
906 1.16 augustss int
907 1.29 aymeric aucc_get_props(void *addr)
908 1.16 augustss {
909 1.16 augustss return 0;
910 1.16 augustss }
911 1.1 is
912 1.41 jmcneill
913 1.41 jmcneill void
914 1.41 jmcneill aucc_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
915 1.41 jmcneill {
916 1.41 jmcneill struct aucc_softc *sc = opaque;
917 1.41 jmcneill
918 1.41 jmcneill *intr = &sc->sc_intr_lock;
919 1.41 jmcneill *thread = &sc->sc_lock;
920 1.41 jmcneill }
921 1.41 jmcneill
922 1.1 is int
923 1.29 aymeric aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip)
924 1.1 is {
925 1.37 kent int i;
926 1.1 is
927 1.1 is switch(dip->index) {
928 1.1 is case AUCC_CHANNELS:
929 1.1 is dip->type = AUDIO_MIXER_SET;
930 1.1 is dip->mixer_class = AUCC_OUTPUT_CLASS;
931 1.1 is dip->prev = dip->next = AUDIO_MIXER_LAST;
932 1.37 kent strcpy(dip->label.name, AudioNspeaker);
933 1.37 kent for (i = 0; i < 16; i++) {
934 1.1 is sprintf(dip->un.s.member[i].label.name,
935 1.1 is "channelmask%d", i);
936 1.1 is dip->un.s.member[i].mask = i;
937 1.1 is }
938 1.1 is dip->un.s.num_mem = 16;
939 1.1 is break;
940 1.1 is
941 1.1 is case AUCC_VOLUME:
942 1.1 is dip->type = AUDIO_MIXER_VALUE;
943 1.1 is dip->mixer_class = AUCC_OUTPUT_CLASS;
944 1.1 is dip->prev = dip->next = AUDIO_MIXER_LAST;
945 1.20 augustss strcpy(dip->label.name, AudioNmaster);
946 1.1 is dip->un.v.num_channels = 4;
947 1.1 is strcpy(dip->un.v.units.name, AudioNvolume);
948 1.1 is break;
949 1.1 is
950 1.1 is case AUCC_OUTPUT_CLASS:
951 1.1 is dip->type = AUDIO_MIXER_CLASS;
952 1.1 is dip->mixer_class = AUCC_OUTPUT_CLASS;
953 1.1 is dip->next = dip->prev = AUDIO_MIXER_LAST;
954 1.19 mycroft strcpy(dip->label.name, AudioCoutputs);
955 1.1 is break;
956 1.20 augustss
957 1.1 is default:
958 1.1 is return ENXIO;
959 1.1 is }
960 1.1 is
961 1.1 is DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
962 1.1 is
963 1.37 kent return 0;
964 1.1 is }
965 1.1 is
966 1.1 is /* audio int handler */
967 1.1 is void
968 1.1 is aucc_inthdl(int ch)
969 1.1 is {
970 1.37 kent int i;
971 1.37 kent int mask;
972 1.1 is
973 1.41 jmcneill mutex_spin_enter(&aucc->sc_intr_lock);
974 1.37 kent mask = aucc->sc_channel[ch].nd_mask;
975 1.37 kent /*
976 1.37 kent * for all channels in this maskgroup:
977 1.37 kent * disable DMA, int
978 1.37 kent * mark idle
979 1.37 kent */
980 1.37 kent DPRINTF(("inthandler called, channel %d, mask 0x%x\n", ch, mask));
981 1.1 is
982 1.37 kent custom.intreq = mask << INTB_AUD0; /* clear request */
983 1.24 is /*
984 1.24 is * XXX: maybe we can leave ints and/or DMA on,
985 1.24 is * if another sample has to be played?
986 1.24 is */
987 1.37 kent custom.intena = mask << INTB_AUD0;
988 1.1 is /*
989 1.29 aymeric * XXX custom.dmacon=mask; NO!!!
990 1.29 aymeric */
991 1.37 kent for (i = 0; i < 4; i++) {
992 1.37 kent if (masks2[i] && mask) {
993 1.1 is DPRINTF(("marking channel %d idle\n",i));
994 1.37 kent aucc->sc_channel[i].nd_busy = 0;
995 1.37 kent aucc->sc_channel[i].nd_mask = 0;
996 1.37 kent channel[i].isaudio = channel[i].play_count = 0;
997 1.1 is }
998 1.1 is }
999 1.1 is
1000 1.1 is /* call handler */
1001 1.1 is if (aucc->sc_channel[ch].nd_intr) {
1002 1.1 is DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
1003 1.24 is (*(aucc->sc_channel[ch].nd_intr))
1004 1.24 is (aucc->sc_channel[ch].nd_intrdata);
1005 1.37 kent } else
1006 1.24 is DPRINTF(("zero int handler\n"));
1007 1.41 jmcneill mutex_spin_exit(&aucc->sc_intr_lock);
1008 1.1 is DPRINTF(("ints done\n"));
1009 1.1 is }
1010 1.1 is
1011 1.1 is /* transform frequency to period, adjust bounds */
1012 1.1 is static u_int
1013 1.29 aymeric freqtoper(u_int freq)
1014 1.29 aymeric {
1015 1.37 kent u_int per;
1016 1.29 aymeric
1017 1.37 kent per = eclockfreq * 5 / freq;
1018 1.37 kent if (per < 124)
1019 1.37 kent per = 124; /* must have at least 124 ticks between samples */
1020 1.1 is
1021 1.1 is return per;
1022 1.1 is }
1023 1.1 is
1024 1.1 is /* transform period to frequency */
1025 1.1 is static u_int
1026 1.29 aymeric pertofreq(u_int per)
1027 1.29 aymeric {
1028 1.24 is
1029 1.37 kent return eclockfreq * 5 / per;
1030 1.24 is }
1031 1.24 is
1032 1.29 aymeric static void
1033 1.29 aymeric aucc_decode_slinear8_1ch(u_char **dmap, u_char *p, int i)
1034 1.29 aymeric {
1035 1.37 kent memcpy(dmap[0], p, i);
1036 1.24 is }
1037 1.24 is
1038 1.29 aymeric static void
1039 1.29 aymeric aucc_decode_slinear8_2ch(u_char **dmap, u_char *p, int i)
1040 1.29 aymeric {
1041 1.37 kent u_char *ch0;
1042 1.37 kent u_char *ch1;
1043 1.24 is
1044 1.37 kent ch0 = dmap[0];
1045 1.37 kent ch1 = dmap[1];
1046 1.24 is while (i--) {
1047 1.24 is *ch0++ = *p++;
1048 1.24 is *ch1++ = *p++;
1049 1.24 is }
1050 1.24 is }
1051 1.24 is
1052 1.29 aymeric static void
1053 1.29 aymeric aucc_decode_slinear8_3ch(u_char **dmap, u_char *p, int i)
1054 1.29 aymeric {
1055 1.37 kent u_char *ch0;
1056 1.37 kent u_char *ch1;
1057 1.37 kent u_char *ch2;
1058 1.37 kent
1059 1.37 kent ch0 = dmap[0];
1060 1.37 kent ch1 = dmap[1];
1061 1.37 kent ch2 = dmap[2];
1062 1.24 is while (i--) {
1063 1.24 is *ch0++ = *p++;
1064 1.24 is *ch1++ = *p++;
1065 1.24 is *ch2++ = *p++;
1066 1.24 is }
1067 1.24 is }
1068 1.24 is
1069 1.29 aymeric static void
1070 1.29 aymeric aucc_decode_slinear8_4ch(u_char **dmap, u_char *p, int i)
1071 1.29 aymeric {
1072 1.37 kent u_char *ch0;
1073 1.37 kent u_char *ch1;
1074 1.37 kent u_char *ch2;
1075 1.37 kent u_char *ch3;
1076 1.37 kent
1077 1.37 kent ch0 = dmap[0];
1078 1.37 kent ch1 = dmap[1];
1079 1.37 kent ch2 = dmap[2];
1080 1.37 kent ch3 = dmap[3];
1081 1.24 is while (i--) {
1082 1.24 is *ch0++ = *p++;
1083 1.24 is *ch1++ = *p++;
1084 1.24 is *ch2++ = *p++;
1085 1.24 is *ch3++ = *p++;
1086 1.24 is }
1087 1.24 is }
1088 1.24 is
1089 1.24 is static void
1090 1.29 aymeric aucc_decode_ulinear8_1ch(u_char **dmap, u_char *p, int i)
1091 1.24 is {
1092 1.37 kent u_char *ch0;
1093 1.24 is
1094 1.37 kent ch0 = dmap[0];
1095 1.24 is while (i--)
1096 1.24 is *ch0++ = *p++ - 128;
1097 1.24 is }
1098 1.24 is
1099 1.24 is static void
1100 1.29 aymeric aucc_decode_ulinear8_2ch(u_char **dmap, u_char *p, int i)
1101 1.1 is {
1102 1.37 kent u_char *ch0;
1103 1.37 kent u_char *ch1;
1104 1.24 is
1105 1.37 kent ch0 = dmap[0];
1106 1.37 kent ch1 = dmap[1];
1107 1.24 is while (i--) {
1108 1.24 is *ch0++ = *p++ - 128;
1109 1.24 is *ch1++ = *p++ - 128;
1110 1.24 is }
1111 1.24 is }
1112 1.24 is
1113 1.24 is static void
1114 1.29 aymeric aucc_decode_ulinear8_3ch(u_char **dmap, u_char *p, int i)
1115 1.24 is {
1116 1.37 kent u_char *ch0;
1117 1.37 kent u_char *ch1;
1118 1.37 kent u_char *ch2;
1119 1.37 kent
1120 1.37 kent ch0 = dmap[0];
1121 1.37 kent ch1 = dmap[1];
1122 1.37 kent ch2 = dmap[2];
1123 1.24 is while (i--) {
1124 1.24 is *ch0++ = *p++ - 128;
1125 1.24 is *ch1++ = *p++ - 128;
1126 1.24 is *ch2++ = *p++ - 128;
1127 1.24 is }
1128 1.24 is }
1129 1.24 is
1130 1.24 is static void
1131 1.29 aymeric aucc_decode_ulinear8_4ch(u_char **dmap, u_char *p, int i)
1132 1.24 is {
1133 1.37 kent u_char *ch0;
1134 1.37 kent u_char *ch1;
1135 1.37 kent u_char *ch2;
1136 1.37 kent u_char *ch3;
1137 1.37 kent
1138 1.37 kent ch0 = dmap[0];
1139 1.37 kent ch1 = dmap[1];
1140 1.37 kent ch2 = dmap[2];
1141 1.37 kent ch3 = dmap[3];
1142 1.24 is while (i--) {
1143 1.24 is *ch0++ = *p++ - 128;
1144 1.24 is *ch1++ = *p++ - 128;
1145 1.24 is *ch2++ = *p++ - 128;
1146 1.24 is *ch3++ = *p++ - 128;
1147 1.24 is }
1148 1.24 is }
1149 1.24 is
1150 1.24 is
1151 1.24 is static void
1152 1.33 wiz aucc_decode_mulaw_1ch(u_char **dmap, u_char *p, int i)
1153 1.24 is {
1154 1.37 kent u_char *ch0;
1155 1.24 is
1156 1.37 kent ch0 = dmap[0];
1157 1.24 is while (i--)
1158 1.33 wiz *ch0++ = mulaw_to_lin[*p++];
1159 1.24 is }
1160 1.24 is
1161 1.24 is static void
1162 1.33 wiz aucc_decode_mulaw_2ch(u_char **dmap, u_char *p, int i)
1163 1.24 is {
1164 1.37 kent u_char *ch0;
1165 1.37 kent u_char *ch1;
1166 1.24 is
1167 1.37 kent ch0 = dmap[0];
1168 1.37 kent ch1 = dmap[1];
1169 1.24 is while (i--) {
1170 1.33 wiz *ch0++ = mulaw_to_lin[*p++];
1171 1.33 wiz *ch1++ = mulaw_to_lin[*p++];
1172 1.24 is }
1173 1.24 is }
1174 1.1 is
1175 1.24 is static void
1176 1.33 wiz aucc_decode_mulaw_3ch(u_char **dmap, u_char *p, int i)
1177 1.24 is {
1178 1.37 kent u_char *ch0;
1179 1.37 kent u_char *ch1;
1180 1.37 kent u_char *ch2;
1181 1.37 kent
1182 1.37 kent ch0 = dmap[0];
1183 1.37 kent ch1 = dmap[1];
1184 1.37 kent ch2 = dmap[2];
1185 1.24 is while (i--) {
1186 1.33 wiz *ch0++ = mulaw_to_lin[*p++];
1187 1.33 wiz *ch1++ = mulaw_to_lin[*p++];
1188 1.33 wiz *ch2++ = mulaw_to_lin[*p++];
1189 1.24 is }
1190 1.24 is }
1191 1.1 is
1192 1.24 is static void
1193 1.33 wiz aucc_decode_mulaw_4ch(u_char **dmap, u_char *p, int i)
1194 1.24 is {
1195 1.37 kent u_char *ch0;
1196 1.37 kent u_char *ch1;
1197 1.37 kent u_char *ch2;
1198 1.37 kent u_char *ch3;
1199 1.37 kent
1200 1.37 kent ch0 = dmap[0];
1201 1.37 kent ch1 = dmap[1];
1202 1.37 kent ch2 = dmap[2];
1203 1.37 kent ch3 = dmap[3];
1204 1.24 is while (i--) {
1205 1.33 wiz *ch0++ = mulaw_to_lin[*p++];
1206 1.33 wiz *ch1++ = mulaw_to_lin[*p++];
1207 1.33 wiz *ch2++ = mulaw_to_lin[*p++];
1208 1.33 wiz *ch3++ = mulaw_to_lin[*p++];
1209 1.24 is }
1210 1.1 is }
1211 1.1 is
1212 1.1 is
1213 1.24 is /* 14bit output */
1214 1.24 is static void
1215 1.29 aymeric aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i)
1216 1.24 is {
1217 1.37 kent u_char *ch0;
1218 1.37 kent u_char *ch3;
1219 1.24 is
1220 1.37 kent ch0 = dmap[0];
1221 1.37 kent ch3 = dmap[1]; /* XXX should be 3 */
1222 1.24 is while (i--) {
1223 1.24 is *ch0++ = *p++;
1224 1.24 is *ch3++ = *p++ >> 2;
1225 1.24 is }
1226 1.24 is }
1227 1.1 is
1228 1.24 is /* 14bit stereo output */
1229 1.24 is static void
1230 1.29 aymeric aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i)
1231 1.24 is {
1232 1.37 kent u_char *ch0;
1233 1.37 kent u_char *ch1;
1234 1.37 kent u_char *ch2;
1235 1.37 kent u_char *ch3;
1236 1.37 kent
1237 1.37 kent ch0 = dmap[0];
1238 1.37 kent ch1 = dmap[1];
1239 1.37 kent ch2 = dmap[2];
1240 1.37 kent ch3 = dmap[3];
1241 1.24 is while (i--) {
1242 1.24 is *ch0++ = *p++;
1243 1.24 is *ch3++ = *p++ >> 2;
1244 1.24 is *ch1++ = *p++;
1245 1.24 is *ch2++ = *p++ >> 2;
1246 1.24 is }
1247 1.24 is }
1248 1.24 is
1249 1.24 is static void
1250 1.29 aymeric aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i)
1251 1.24 is {
1252 1.37 kent u_char *ch0;
1253 1.37 kent u_char *ch1;
1254 1.37 kent u_char *ch2;
1255 1.37 kent
1256 1.37 kent ch0 = dmap[0];
1257 1.37 kent ch1 = dmap[1];
1258 1.37 kent ch2 = dmap[2];
1259 1.24 is while (i--) {
1260 1.24 is *ch0++ = *p++; p++;
1261 1.24 is *ch1++ = *p++; p++;
1262 1.24 is *ch2++ = *p++; p++;
1263 1.24 is }
1264 1.24 is }
1265 1.24 is
1266 1.24 is static void
1267 1.29 aymeric aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i)
1268 1.1 is {
1269 1.37 kent u_char *ch0;
1270 1.37 kent u_char *ch1;
1271 1.37 kent u_char *ch2;
1272 1.37 kent u_char *ch3;
1273 1.37 kent
1274 1.37 kent ch0 = dmap[0];
1275 1.37 kent ch1 = dmap[1];
1276 1.37 kent ch2 = dmap[2];
1277 1.37 kent ch3 = dmap[3];
1278 1.24 is while (i--) {
1279 1.24 is *ch0++ = *p++; p++;
1280 1.24 is *ch1++ = *p++; p++;
1281 1.24 is *ch2++ = *p++; p++;
1282 1.24 is *ch3++ = *p++; p++;
1283 1.24 is }
1284 1.24 is }
1285 1.8 is
1286 1.24 is /* 14bit output, swap bytes */
1287 1.24 is static void
1288 1.29 aymeric aucc_decode_slinear16sw_1ch(u_char **dmap, u_char *p, int i)
1289 1.24 is {
1290 1.37 kent u_char *ch0;
1291 1.37 kent u_char *ch3;
1292 1.1 is
1293 1.37 kent ch0 = dmap[0];
1294 1.37 kent ch3 = dmap[1]; /* XXX should be 3 */
1295 1.24 is while (i--) {
1296 1.24 is *ch3++ = *p++ >> 2;
1297 1.24 is *ch0++ = *p++;
1298 1.24 is }
1299 1.24 is }
1300 1.1 is
1301 1.24 is static void
1302 1.29 aymeric aucc_decode_slinear16sw_2ch(u_char **dmap, u_char *p, int i)
1303 1.24 is {
1304 1.37 kent u_char *ch0;
1305 1.37 kent u_char *ch1;
1306 1.37 kent u_char *ch2;
1307 1.37 kent u_char *ch3;
1308 1.37 kent
1309 1.37 kent ch0 = dmap[0];
1310 1.37 kent ch1 = dmap[1];
1311 1.37 kent ch2 = dmap[2];
1312 1.37 kent ch3 = dmap[3];
1313 1.24 is while (i--) {
1314 1.24 is *ch3++ = *p++ >> 2;
1315 1.24 is *ch0++ = *p++;
1316 1.24 is *ch2++ = *p++ >> 2;
1317 1.24 is *ch1++ = *p++;
1318 1.24 is }
1319 1.24 is }
1320 1.1 is
1321 1.24 is static void
1322 1.29 aymeric aucc_decode_slinear16sw_3ch(u_char **dmap, u_char *p, int i)
1323 1.24 is {
1324 1.37 kent u_char *ch0;
1325 1.37 kent u_char *ch1;
1326 1.37 kent u_char *ch2;
1327 1.37 kent
1328 1.37 kent ch0 = dmap[0];
1329 1.37 kent ch1 = dmap[1];
1330 1.37 kent ch2 = dmap[2];
1331 1.24 is while (i--) {
1332 1.24 is p++; *ch0++ = *p++;
1333 1.24 is p++; *ch1++ = *p++;
1334 1.24 is p++; *ch2++ = *p++;
1335 1.1 is }
1336 1.24 is }
1337 1.1 is
1338 1.24 is static void
1339 1.29 aymeric aucc_decode_slinear16sw_4ch(u_char **dmap, u_char *p, int i)
1340 1.24 is {
1341 1.37 kent u_char *ch0;
1342 1.37 kent u_char *ch1;
1343 1.37 kent u_char *ch2;
1344 1.37 kent u_char *ch3;
1345 1.37 kent
1346 1.37 kent ch0 = dmap[0];
1347 1.37 kent ch1 = dmap[1];
1348 1.37 kent ch2 = dmap[2];
1349 1.37 kent ch3 = dmap[3];
1350 1.24 is while (i--) {
1351 1.24 is p++; *ch0++ = *p++;
1352 1.24 is p++; *ch1++ = *p++;
1353 1.24 is p++; *ch2++ = *p++;
1354 1.24 is p++; *ch3++ = *p++;
1355 1.24 is }
1356 1.1 is }
1357 1.24 is
1358 1.1 is
1359 1.1 is #endif /* NAUCC > 0 */
1360