vraiu.c revision 1.7 1 1.7 jmcneill /* $NetBSD: vraiu.c,v 1.7 2004/02/04 06:43:47 jmcneill Exp $ */
2 1.1 hamajima
3 1.1 hamajima /*
4 1.1 hamajima * Copyright (c) 2001 HAMAJIMA Katsuomi. All rights reserved.
5 1.1 hamajima *
6 1.1 hamajima * Redistribution and use in source and binary forms, with or without
7 1.1 hamajima * modification, are permitted provided that the following conditions
8 1.1 hamajima * are met:
9 1.1 hamajima * 1. Redistributions of source code must retain the above copyright
10 1.1 hamajima * notice, this list of conditions and the following disclaimer.
11 1.1 hamajima * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 hamajima * notice, this list of conditions and the following disclaimer in the
13 1.1 hamajima * documentation and/or other materials provided with the distribution.
14 1.1 hamajima *
15 1.1 hamajima * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 1.1 hamajima * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 1.1 hamajima * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 1.1 hamajima * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.1 hamajima * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.1 hamajima * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 1.1 hamajima * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.1 hamajima * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.1 hamajima * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.1 hamajima * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.1 hamajima * SUCH DAMAGE.
26 1.1 hamajima */
27 1.6 lukem
28 1.6 lukem #include <sys/cdefs.h>
29 1.7 jmcneill __KERNEL_RCSID(0, "$NetBSD: vraiu.c,v 1.7 2004/02/04 06:43:47 jmcneill Exp $");
30 1.1 hamajima
31 1.1 hamajima #include <sys/param.h>
32 1.1 hamajima #include <sys/systm.h>
33 1.1 hamajima #include <sys/device.h>
34 1.1 hamajima #include <sys/malloc.h>
35 1.1 hamajima #include <sys/bswap.h>
36 1.1 hamajima
37 1.1 hamajima #include <machine/cpu.h>
38 1.1 hamajima #include <machine/intr.h>
39 1.1 hamajima #include <machine/bus.h>
40 1.1 hamajima #include <machine/platid.h>
41 1.1 hamajima #include <machine/platid_mask.h>
42 1.1 hamajima #include <machine/config_hook.h>
43 1.1 hamajima
44 1.1 hamajima #include <sys/audioio.h>
45 1.1 hamajima #include <dev/audio_if.h>
46 1.1 hamajima
47 1.1 hamajima #include <hpcmips/vr/vr.h>
48 1.1 hamajima #include <hpcmips/vr/vripif.h>
49 1.1 hamajima #include <hpcmips/vr/icureg.h>
50 1.1 hamajima #include <hpcmips/vr/cmureg.h>
51 1.1 hamajima #include <hpcmips/vr/vraiureg.h>
52 1.1 hamajima
53 1.1 hamajima #ifdef VRAIU_DEBUG
54 1.1 hamajima int vraiu_debug = VRAIU_DEBUG;
55 1.1 hamajima #define DPRINTFN(n,x) if (vraiu_debug>(n)) printf x;
56 1.1 hamajima #else
57 1.1 hamajima #define DPRINTFN(n,x)
58 1.1 hamajima #endif
59 1.1 hamajima
60 1.1 hamajima #define AUDIO_BUF_SIZE 2048
61 1.1 hamajima
62 1.1 hamajima struct vraiu_softc {
63 1.1 hamajima struct device sc_dev;
64 1.1 hamajima bus_space_tag_t sc_iot;
65 1.1 hamajima bus_space_handle_t sc_ioh;
66 1.1 hamajima bus_dma_tag_t sc_dmat;
67 1.1 hamajima bus_dmamap_t sc_dmap;
68 1.1 hamajima vrip_chipset_tag_t sc_vrip;
69 1.1 hamajima vrdcu_chipset_tag_t sc_dc;
70 1.1 hamajima vrdmaau_chipset_tag_t sc_ac;
71 1.1 hamajima vrcmu_chipset_tag_t sc_cc;
72 1.1 hamajima void *sc_handler;
73 1.5 wiz u_short *sc_buf; /* DMA buffer pointer */
74 1.1 hamajima int sc_status; /* status */
75 1.1 hamajima u_int sc_rate; /* sampling rate */
76 1.1 hamajima u_int sc_channels; /* # of channels used */
77 1.1 hamajima u_int sc_encoding; /* encoding type */
78 1.1 hamajima int sc_precision; /* 8 or 16 bits */
79 1.1 hamajima /* pointer to format conversion routine */
80 1.7 jmcneill u_char sc_volume; /* volume */
81 1.1 hamajima void (*sc_decodefunc)(struct vraiu_softc *, u_short *, void *, int);
82 1.1 hamajima void (*sc_intr)(void *); /* interrupt routine */
83 1.1 hamajima void *sc_intrdata; /* interrupt data */
84 1.1 hamajima };
85 1.1 hamajima
86 1.1 hamajima int vraiu_match(struct device *, struct cfdata *, void *);
87 1.1 hamajima void vraiu_attach(struct device *, struct device *, void *);
88 1.1 hamajima int vraiu_intr(void *);
89 1.1 hamajima
90 1.3 thorpej CFATTACH_DECL(vraiu, sizeof(struct vraiu_softc),
91 1.3 thorpej vraiu_match, vraiu_attach, NULL, NULL);
92 1.1 hamajima
93 1.1 hamajima struct audio_device aiu_device = {
94 1.1 hamajima "VR4121 AIU",
95 1.1 hamajima "0.1",
96 1.1 hamajima "aiu"
97 1.1 hamajima };
98 1.1 hamajima
99 1.1 hamajima /*
100 1.1 hamajima * Define our interface to the higher level audio driver.
101 1.1 hamajima */
102 1.1 hamajima int vraiu_open(void *, int);
103 1.1 hamajima void vraiu_close(void *);
104 1.1 hamajima int vraiu_query_encoding(void *, struct audio_encoding *);
105 1.1 hamajima int vraiu_round_blocksize(void *, int);
106 1.1 hamajima int vraiu_commit_settings(void *);
107 1.1 hamajima int vraiu_init_output(void *, void*, int);
108 1.1 hamajima int vraiu_start_output(void *, void *, int, void (*)(void *), void *);
109 1.1 hamajima int vraiu_start_input(void *, void *, int, void (*)(void *), void *);
110 1.1 hamajima int vraiu_halt_output(void *);
111 1.1 hamajima int vraiu_halt_input(void *);
112 1.1 hamajima int vraiu_getdev(void *, struct audio_device *);
113 1.1 hamajima int vraiu_set_port(void *, mixer_ctrl_t *);
114 1.1 hamajima int vraiu_get_port(void *, mixer_ctrl_t *);
115 1.1 hamajima int vraiu_query_devinfo(void *, mixer_devinfo_t *);
116 1.1 hamajima int vraiu_set_params(void *, int, int, struct audio_params *,
117 1.1 hamajima struct audio_params *);
118 1.1 hamajima int vraiu_get_props(void *);
119 1.1 hamajima
120 1.1 hamajima struct audio_hw_if vraiu_hw_if = {
121 1.1 hamajima vraiu_open,
122 1.1 hamajima vraiu_close,
123 1.1 hamajima NULL,
124 1.1 hamajima vraiu_query_encoding,
125 1.1 hamajima vraiu_set_params,
126 1.1 hamajima vraiu_round_blocksize,
127 1.1 hamajima vraiu_commit_settings,
128 1.1 hamajima vraiu_init_output,
129 1.1 hamajima NULL,
130 1.1 hamajima vraiu_start_output,
131 1.1 hamajima vraiu_start_input,
132 1.1 hamajima vraiu_halt_output,
133 1.1 hamajima vraiu_halt_input,
134 1.1 hamajima NULL,
135 1.1 hamajima vraiu_getdev,
136 1.1 hamajima NULL,
137 1.1 hamajima vraiu_set_port,
138 1.1 hamajima vraiu_get_port,
139 1.1 hamajima vraiu_query_devinfo,
140 1.1 hamajima NULL,
141 1.1 hamajima NULL,
142 1.1 hamajima NULL,
143 1.1 hamajima NULL,
144 1.1 hamajima vraiu_get_props,
145 1.1 hamajima };
146 1.1 hamajima
147 1.1 hamajima /*
148 1.1 hamajima * convert to 1ch 10bit unsigned PCM data.
149 1.1 hamajima */
150 1.1 hamajima static void vraiu_slinear8_1(struct vraiu_softc *, u_short *, void *, int);
151 1.1 hamajima static void vraiu_slinear8_2(struct vraiu_softc *, u_short *, void *, int);
152 1.1 hamajima static void vraiu_ulinear8_1(struct vraiu_softc *, u_short *, void *, int);
153 1.1 hamajima static void vraiu_ulinear8_2(struct vraiu_softc *, u_short *, void *, int);
154 1.4 wiz static void vraiu_mulaw_1(struct vraiu_softc *, u_short *, void *, int);
155 1.4 wiz static void vraiu_mulaw_2(struct vraiu_softc *, u_short *, void *, int);
156 1.1 hamajima static void vraiu_slinear16_1(struct vraiu_softc *, u_short *, void *, int);
157 1.1 hamajima static void vraiu_slinear16_2(struct vraiu_softc *, u_short *, void *, int);
158 1.1 hamajima static void vraiu_slinear16sw_1(struct vraiu_softc *, u_short *, void *, int);
159 1.1 hamajima static void vraiu_slinear16sw_2(struct vraiu_softc *, u_short *, void *, int);
160 1.7 jmcneill /*
161 1.7 jmcneill * software volume control
162 1.7 jmcneill */
163 1.7 jmcneill static void vraiu_volume(struct vraiu_softc *, u_short *, void *, int);
164 1.1 hamajima
165 1.1 hamajima int
166 1.1 hamajima vraiu_match(struct device *parent, struct cfdata *cf, void *aux)
167 1.1 hamajima {
168 1.1 hamajima return 1;
169 1.1 hamajima }
170 1.1 hamajima
171 1.1 hamajima void
172 1.1 hamajima vraiu_attach(struct device *parent, struct device *self, void *aux)
173 1.1 hamajima {
174 1.1 hamajima struct vrip_attach_args *va = aux;
175 1.1 hamajima struct vraiu_softc *sc = (void*)self;
176 1.1 hamajima bus_dma_segment_t segs;
177 1.1 hamajima int rsegs;
178 1.1 hamajima
179 1.1 hamajima sc->sc_status = ENXIO;
180 1.1 hamajima sc->sc_intr = NULL;
181 1.1 hamajima sc->sc_iot = va->va_iot;
182 1.1 hamajima sc->sc_vrip = va->va_vc;
183 1.1 hamajima sc->sc_cc = va->va_cc;
184 1.1 hamajima sc->sc_dc = va->va_dc;
185 1.1 hamajima sc->sc_ac = va->va_ac;
186 1.1 hamajima sc->sc_dmat = &vrdcu_bus_dma_tag;
187 1.7 jmcneill sc->sc_volume = 127;
188 1.1 hamajima
189 1.1 hamajima if (!sc->sc_cc) {
190 1.1 hamajima printf(" not configured: cmu not found\n");
191 1.1 hamajima return;
192 1.1 hamajima }
193 1.1 hamajima if (!sc->sc_dc) {
194 1.1 hamajima printf(" not configured: dcu not found\n");
195 1.1 hamajima return;
196 1.1 hamajima }
197 1.1 hamajima if (!sc->sc_ac) {
198 1.1 hamajima printf(" not configured: dmaau not found\n");
199 1.1 hamajima return;
200 1.1 hamajima }
201 1.1 hamajima if (bus_space_map(sc->sc_iot, va->va_addr, va->va_size,
202 1.1 hamajima 0 /* no flags */, &sc->sc_ioh)) {
203 1.1 hamajima printf(": can't map i/o space\n");
204 1.1 hamajima return;
205 1.1 hamajima }
206 1.1 hamajima
207 1.1 hamajima /* install interrupt handler and enable interrupt */
208 1.1 hamajima if (!(sc->sc_handler = vrip_intr_establish(va->va_vc, va->va_unit,
209 1.1 hamajima 0, IPL_AUDIO,
210 1.1 hamajima vraiu_intr, sc))) {
211 1.1 hamajima printf(": can't map interrupt line.\n");
212 1.1 hamajima return;
213 1.1 hamajima }
214 1.1 hamajima vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, (AIUINT_INTMEND | \
215 1.1 hamajima AIUINT_INTM | \
216 1.1 hamajima AIUINT_INTMIDLE | \
217 1.1 hamajima AIUINT_INTMST | \
218 1.1 hamajima AIUINT_INTSEND | \
219 1.1 hamajima AIUINT_INTS | \
220 1.1 hamajima AIUINT_INTSIDLE), 0);
221 1.1 hamajima
222 1.1 hamajima if (bus_dmamem_alloc(sc->sc_dmat, AUDIO_BUF_SIZE, 0, 0, &segs, 1,
223 1.1 hamajima &rsegs, BUS_DMA_NOWAIT)) {
224 1.1 hamajima printf(": can't allocate memory.\n");
225 1.1 hamajima return;
226 1.1 hamajima }
227 1.1 hamajima if (bus_dmamem_map(sc->sc_dmat, &segs, rsegs, AUDIO_BUF_SIZE,
228 1.1 hamajima (caddr_t *)&sc->sc_buf,
229 1.1 hamajima BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) {
230 1.1 hamajima printf(": can't map memory.\n");
231 1.1 hamajima bus_dmamem_free(sc->sc_dmat, &segs, rsegs);
232 1.1 hamajima return;
233 1.1 hamajima }
234 1.1 hamajima if (bus_dmamap_create(sc->sc_dmat, AUDIO_BUF_SIZE, 1, AUDIO_BUF_SIZE,
235 1.1 hamajima 0, BUS_DMA_NOWAIT, &sc->sc_dmap)) {
236 1.1 hamajima printf(": can't create DMA map.\n");
237 1.1 hamajima bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_buf,
238 1.1 hamajima AUDIO_BUF_SIZE);
239 1.1 hamajima bus_dmamem_free(sc->sc_dmat, &segs, rsegs);
240 1.1 hamajima return;
241 1.1 hamajima }
242 1.1 hamajima if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmap, sc->sc_buf,
243 1.1 hamajima AUDIO_BUF_SIZE, NULL, BUS_DMA_NOWAIT)) {
244 1.1 hamajima printf(": can't load DMA map.\n");
245 1.1 hamajima bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmap);
246 1.1 hamajima bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_buf,
247 1.1 hamajima AUDIO_BUF_SIZE);
248 1.1 hamajima bus_dmamem_free(sc->sc_dmat, &segs, rsegs);
249 1.1 hamajima return;
250 1.1 hamajima }
251 1.1 hamajima if (sc->sc_ac->ac_set_aiuout(sc->sc_ac, sc->sc_buf)) {
252 1.1 hamajima printf(": can't set DMA address.\n");
253 1.1 hamajima bus_dmamap_unload(sc->sc_dmat, sc->sc_dmap);
254 1.1 hamajima bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmap);
255 1.1 hamajima bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_buf,
256 1.1 hamajima AUDIO_BUF_SIZE);
257 1.1 hamajima bus_dmamem_free(sc->sc_dmat, &segs, rsegs);
258 1.1 hamajima return;
259 1.1 hamajima }
260 1.1 hamajima printf("\n");
261 1.1 hamajima
262 1.1 hamajima sc->sc_status = 0;
263 1.1 hamajima sc->sc_rate = SPS8000;
264 1.1 hamajima sc->sc_channels = 1;
265 1.1 hamajima sc->sc_precision = 8;
266 1.1 hamajima sc->sc_encoding = AUDIO_ENCODING_ULAW;
267 1.4 wiz sc->sc_decodefunc = vraiu_mulaw_1;
268 1.1 hamajima DPRINTFN(1, ("vraiu_attach: reset AIU\n"))
269 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEQ_REG_W, AIURST);
270 1.1 hamajima /* attach audio subsystem */
271 1.1 hamajima audio_attach_mi(&vraiu_hw_if, sc, &sc->sc_dev);
272 1.1 hamajima }
273 1.1 hamajima
274 1.1 hamajima int
275 1.1 hamajima vraiu_open(void *self, int flags)
276 1.1 hamajima {
277 1.1 hamajima struct vraiu_softc *sc = (void*)self;
278 1.1 hamajima
279 1.1 hamajima DPRINTFN(1, ("vraiu_open\n"));
280 1.1 hamajima
281 1.1 hamajima if (sc->sc_status) {
282 1.1 hamajima DPRINTFN(0, ("vraiu_open: device error\n"));
283 1.1 hamajima return sc->sc_status;
284 1.1 hamajima }
285 1.1 hamajima sc->sc_status = EBUSY;
286 1.1 hamajima return 0;
287 1.1 hamajima }
288 1.1 hamajima
289 1.1 hamajima void
290 1.1 hamajima vraiu_close(void *self)
291 1.1 hamajima {
292 1.1 hamajima struct vraiu_softc *sc = (void*)self;
293 1.1 hamajima
294 1.1 hamajima DPRINTFN(1, ("vraiu_close\n"));
295 1.1 hamajima
296 1.1 hamajima vraiu_halt_output(self);
297 1.1 hamajima sc->sc_status = 0;
298 1.1 hamajima }
299 1.1 hamajima
300 1.1 hamajima int
301 1.1 hamajima vraiu_query_encoding(void *self, struct audio_encoding *ae)
302 1.1 hamajima {
303 1.1 hamajima DPRINTFN(3, ("vraiu_query_encoding\n"));
304 1.1 hamajima
305 1.1 hamajima switch (ae->index) {
306 1.1 hamajima case 0:
307 1.1 hamajima strcpy(ae->name, AudioEslinear);
308 1.1 hamajima ae->encoding = AUDIO_ENCODING_SLINEAR;
309 1.1 hamajima ae->precision = 8;
310 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
311 1.1 hamajima break;
312 1.1 hamajima case 1:
313 1.1 hamajima strcpy(ae->name, AudioEmulaw);
314 1.1 hamajima ae->encoding = AUDIO_ENCODING_ULAW;
315 1.1 hamajima ae->precision = 8;
316 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
317 1.1 hamajima break;
318 1.1 hamajima case 2:
319 1.1 hamajima strcpy(ae->name, AudioEulinear);
320 1.1 hamajima ae->encoding = AUDIO_ENCODING_ULINEAR;
321 1.1 hamajima ae->precision = 8;
322 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
323 1.1 hamajima break;
324 1.1 hamajima case 3:
325 1.1 hamajima strcpy(ae->name, AudioEslinear);
326 1.1 hamajima ae->encoding = AUDIO_ENCODING_SLINEAR;
327 1.1 hamajima ae->precision = 16;
328 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
329 1.1 hamajima break;
330 1.1 hamajima case 4:
331 1.1 hamajima strcpy(ae->name, AudioEslinear_be);
332 1.1 hamajima ae->encoding = AUDIO_ENCODING_SLINEAR_BE;
333 1.1 hamajima ae->precision = 16;
334 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
335 1.1 hamajima break;
336 1.1 hamajima case 5:
337 1.1 hamajima strcpy(ae->name, AudioEslinear_le);
338 1.1 hamajima ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
339 1.1 hamajima ae->precision = 16;
340 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
341 1.1 hamajima break;
342 1.1 hamajima case 6:
343 1.1 hamajima strcpy(ae->name, AudioEslinear);
344 1.1 hamajima ae->encoding = AUDIO_ENCODING_ULINEAR;
345 1.1 hamajima ae->precision = 16;
346 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
347 1.1 hamajima break;
348 1.1 hamajima case 7:
349 1.1 hamajima strcpy(ae->name, AudioEslinear_be);
350 1.1 hamajima ae->encoding = AUDIO_ENCODING_ULINEAR_BE;
351 1.1 hamajima ae->precision = 16;
352 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
353 1.1 hamajima break;
354 1.1 hamajima case 8:
355 1.1 hamajima strcpy(ae->name, AudioEslinear_le);
356 1.1 hamajima ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
357 1.1 hamajima ae->precision = 16;
358 1.1 hamajima ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
359 1.1 hamajima break;
360 1.1 hamajima default:
361 1.1 hamajima DPRINTFN(0, ("vraiu_query_encoding: param error"
362 1.1 hamajima " (%d)\n", ae->index));
363 1.1 hamajima return EINVAL;
364 1.1 hamajima }
365 1.1 hamajima return 0;
366 1.1 hamajima }
367 1.1 hamajima
368 1.1 hamajima int
369 1.1 hamajima vraiu_set_params(void *self, int setmode, int usemode,
370 1.1 hamajima struct audio_params *play, struct audio_params *rec)
371 1.1 hamajima {
372 1.1 hamajima struct vraiu_softc *sc = (void*)self;
373 1.1 hamajima
374 1.1 hamajima DPRINTFN(1, ("vraiu_set_params: %dbit, %dch, %ldHz, encoding %d\n",
375 1.1 hamajima play->precision, play->channels, play->sample_rate,
376 1.1 hamajima play->encoding));
377 1.1 hamajima
378 1.1 hamajima switch (play->sample_rate) {
379 1.1 hamajima case 8000:
380 1.1 hamajima sc->sc_rate = SPS8000;
381 1.1 hamajima break;
382 1.1 hamajima case 11025:
383 1.1 hamajima sc->sc_rate = SPS11025;
384 1.1 hamajima break;
385 1.1 hamajima case 22050:
386 1.1 hamajima sc->sc_rate = SPS22050;
387 1.1 hamajima break;
388 1.1 hamajima case 44100:
389 1.1 hamajima sc->sc_rate = SPS44100;
390 1.1 hamajima break;
391 1.1 hamajima default:
392 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: rate error (%ld)\n",
393 1.1 hamajima play->sample_rate));
394 1.1 hamajima return EINVAL;
395 1.1 hamajima }
396 1.1 hamajima
397 1.1 hamajima switch (play->precision) {
398 1.1 hamajima case 8:
399 1.1 hamajima switch (play->encoding) {
400 1.1 hamajima case AUDIO_ENCODING_ULAW:
401 1.1 hamajima switch (play->channels) {
402 1.1 hamajima case 1:
403 1.4 wiz sc->sc_decodefunc = vraiu_mulaw_1;
404 1.1 hamajima break;
405 1.1 hamajima case 2:
406 1.4 wiz sc->sc_decodefunc = vraiu_mulaw_2;
407 1.1 hamajima break;
408 1.1 hamajima default:
409 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: channel error"
410 1.1 hamajima " (%d)\n", play->channels));
411 1.1 hamajima return EINVAL;
412 1.1 hamajima }
413 1.1 hamajima break;
414 1.1 hamajima case AUDIO_ENCODING_SLINEAR:
415 1.1 hamajima case AUDIO_ENCODING_SLINEAR_BE:
416 1.1 hamajima case AUDIO_ENCODING_SLINEAR_LE:
417 1.1 hamajima switch (play->channels) {
418 1.1 hamajima case 1:
419 1.1 hamajima sc->sc_decodefunc = vraiu_slinear8_1;
420 1.1 hamajima break;
421 1.1 hamajima case 2:
422 1.1 hamajima sc->sc_decodefunc = vraiu_slinear8_2;
423 1.1 hamajima break;
424 1.1 hamajima default:
425 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: channel error"
426 1.1 hamajima " (%d)\n", play->channels));
427 1.1 hamajima return EINVAL;
428 1.1 hamajima }
429 1.1 hamajima break;
430 1.1 hamajima case AUDIO_ENCODING_ULINEAR:
431 1.1 hamajima case AUDIO_ENCODING_ULINEAR_BE:
432 1.1 hamajima case AUDIO_ENCODING_ULINEAR_LE:
433 1.1 hamajima switch (play->channels) {
434 1.1 hamajima case 1:
435 1.1 hamajima sc->sc_decodefunc = vraiu_ulinear8_1;
436 1.1 hamajima break;
437 1.1 hamajima case 2:
438 1.1 hamajima sc->sc_decodefunc = vraiu_ulinear8_2;
439 1.1 hamajima break;
440 1.1 hamajima default:
441 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: channel error"
442 1.1 hamajima " (%d)\n", play->channels));
443 1.1 hamajima return EINVAL;
444 1.1 hamajima }
445 1.1 hamajima break;
446 1.1 hamajima default:
447 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: encoding error"
448 1.1 hamajima " (%d)\n", play->encoding));
449 1.1 hamajima return EINVAL;
450 1.1 hamajima }
451 1.1 hamajima break;
452 1.1 hamajima case 16:
453 1.1 hamajima switch (play->encoding) {
454 1.1 hamajima #if BYTE_ORDER == BIG_ENDIAN
455 1.1 hamajima case AUDIO_ENCODING_SLINEAR:
456 1.1 hamajima #endif
457 1.1 hamajima case AUDIO_ENCODING_SLINEAR_BE:
458 1.1 hamajima switch (play->channels) {
459 1.1 hamajima case 1:
460 1.1 hamajima #if BYTE_ORDER == BIG_ENDIAN
461 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16_1;
462 1.1 hamajima #else
463 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16sw_1;
464 1.1 hamajima #endif
465 1.1 hamajima break;
466 1.1 hamajima case 2:
467 1.1 hamajima #if BYTE_ORDER == BIG_ENDIAN
468 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16_2;
469 1.1 hamajima #else
470 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16sw_2;
471 1.1 hamajima #endif
472 1.1 hamajima break;
473 1.1 hamajima default:
474 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: channel error"
475 1.1 hamajima " (%d)\n", play->channels));
476 1.1 hamajima return EINVAL;
477 1.1 hamajima }
478 1.1 hamajima break;
479 1.1 hamajima #if BYTE_ORDER == LITTLE_ENDIAN
480 1.1 hamajima case AUDIO_ENCODING_SLINEAR:
481 1.1 hamajima #endif
482 1.1 hamajima case AUDIO_ENCODING_SLINEAR_LE:
483 1.1 hamajima switch (play->channels) {
484 1.1 hamajima case 1:
485 1.1 hamajima #if BYTE_ORDER == LITTLE_ENDIAN
486 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16_1;
487 1.1 hamajima #else
488 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16sw_1;
489 1.1 hamajima #endif
490 1.1 hamajima break;
491 1.1 hamajima case 2:
492 1.1 hamajima #if BYTE_ORDER == LITTLE_ENDIAN
493 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16_2;
494 1.1 hamajima #else
495 1.1 hamajima sc->sc_decodefunc = vraiu_slinear16sw_2;
496 1.1 hamajima #endif
497 1.1 hamajima break;
498 1.1 hamajima default:
499 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: channel error"
500 1.1 hamajima " (%d)\n", play->channels));
501 1.1 hamajima return EINVAL;
502 1.1 hamajima }
503 1.1 hamajima break;
504 1.1 hamajima default:
505 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: encoding error"
506 1.1 hamajima " (%d)\n", play->encoding));
507 1.1 hamajima return EINVAL;
508 1.1 hamajima }
509 1.1 hamajima break;
510 1.1 hamajima default:
511 1.1 hamajima DPRINTFN(0, ("vraiu_set_params: precision error (%d)\n",
512 1.1 hamajima play->precision));
513 1.1 hamajima return EINVAL;
514 1.1 hamajima }
515 1.1 hamajima
516 1.1 hamajima sc->sc_encoding = play->encoding;
517 1.1 hamajima sc->sc_precision = play->precision;
518 1.1 hamajima sc->sc_channels = play->channels;
519 1.1 hamajima return 0;
520 1.1 hamajima }
521 1.1 hamajima
522 1.1 hamajima int
523 1.1 hamajima vraiu_round_blocksize(void *self, int bs)
524 1.1 hamajima {
525 1.1 hamajima struct vraiu_softc *sc = (void*)self;
526 1.1 hamajima int n = AUDIO_BUF_SIZE;
527 1.1 hamajima
528 1.1 hamajima if (sc->sc_precision == 8)
529 1.1 hamajima n /= 2;
530 1.1 hamajima n *= sc->sc_channels;
531 1.1 hamajima
532 1.1 hamajima DPRINTFN(1, ("vraiu_round_blocksize: upper %d, lower %d\n",
533 1.1 hamajima bs, n));
534 1.1 hamajima
535 1.1 hamajima return n;
536 1.1 hamajima }
537 1.1 hamajima
538 1.1 hamajima int
539 1.1 hamajima vraiu_commit_settings(void *self)
540 1.1 hamajima {
541 1.1 hamajima struct vraiu_softc *sc = (void*)self;
542 1.1 hamajima int err;
543 1.1 hamajima
544 1.1 hamajima DPRINTFN(1, ("vraiu_commit_settings\n"));
545 1.1 hamajima
546 1.1 hamajima if (sc->sc_status != EBUSY)
547 1.1 hamajima return sc->sc_status;
548 1.1 hamajima
549 1.1 hamajima DPRINTFN(1, ("vraiu_commit_settings: set conversion rate %d\n",
550 1.1 hamajima sc->sc_rate))
551 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCNVR_REG_W, sc->sc_rate);
552 1.1 hamajima DPRINTFN(1, ("vraiu_commit_settings: clock supply start\n"))
553 1.1 hamajima if ((err = sc->sc_cc->cc_clock(sc->sc_cc, VR4102_CMUMSKAIU, 1))) {
554 1.1 hamajima DPRINTFN(0, ("vraiu_commit_settings: clock supply error\n"));
555 1.1 hamajima return err;
556 1.1 hamajima }
557 1.1 hamajima DPRINTFN(1, ("vraiu_commit_settings: enable DMA\n"))
558 1.1 hamajima if ((err = sc->sc_dc->dc_enable_aiuout(sc->sc_dc))) {
559 1.1 hamajima sc->sc_cc->cc_clock(sc->sc_cc, VR4102_CMUMSKAIU, 0);
560 1.5 wiz DPRINTFN(0, ("vraiu_commit_settings: enable DMA error\n"));
561 1.1 hamajima return err;
562 1.1 hamajima }
563 1.1 hamajima DPRINTFN(1, ("vraiu_commit_settings: Vref on\n"))
564 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCNT_REG_W, DAENAIU);
565 1.1 hamajima return 0;
566 1.1 hamajima }
567 1.1 hamajima
568 1.1 hamajima int
569 1.1 hamajima vraiu_init_output(void *self, void *buffer, int size)
570 1.1 hamajima {
571 1.1 hamajima struct vraiu_softc *sc = (void*)self;
572 1.1 hamajima
573 1.1 hamajima DPRINTFN(1, ("vraiu_init_output: buffer %p, size %d\n", buffer, size));
574 1.1 hamajima
575 1.1 hamajima sc->sc_intr = NULL;
576 1.1 hamajima DPRINTFN(1, ("vraiu_init_output: speaker power on\n"))
577 1.1 hamajima config_hook_call(CONFIG_HOOK_POWERCONTROL,
578 1.1 hamajima CONFIG_HOOK_POWERCONTROL_SPEAKER, (void*)1);
579 1.1 hamajima DPRINTFN(1, ("vraiu_init_output: start output\n"))
580 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEQ_REG_W, AIUSEN);
581 1.1 hamajima return 0;
582 1.1 hamajima }
583 1.1 hamajima
584 1.1 hamajima int
585 1.1 hamajima vraiu_start_output(void *self, void *block, int bsize,
586 1.1 hamajima void (*intr)(void *), void *intrarg)
587 1.1 hamajima {
588 1.1 hamajima struct vraiu_softc *sc = (void*)self;
589 1.1 hamajima
590 1.1 hamajima DPRINTFN(2, ("vraiu_start_output: block %p, bsize %d\n",
591 1.1 hamajima block, bsize));
592 1.1 hamajima sc->sc_decodefunc(sc, sc->sc_buf, block, bsize);
593 1.7 jmcneill vraiu_volume(sc, sc->sc_buf, block, bsize);
594 1.1 hamajima bus_dmamap_sync(sc->sc_dmat, sc->sc_dmap, 0, AUDIO_BUF_SIZE,
595 1.1 hamajima BUS_DMASYNC_PREWRITE);
596 1.1 hamajima sc->sc_intr = intr;
597 1.1 hamajima sc->sc_intrdata = intrarg;
598 1.1 hamajima /* clear interrupt status */
599 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, INT_REG_W,
600 1.1 hamajima SENDINTR | SINTR | SIDLEINTR);
601 1.1 hamajima /* enable interrupt */
602 1.1 hamajima vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AIUINT_INTSEND, 1);
603 1.1 hamajima return 0;
604 1.1 hamajima }
605 1.1 hamajima
606 1.1 hamajima int
607 1.1 hamajima vraiu_start_input(void *self, void *block, int bsize,
608 1.1 hamajima void (*intr)(void *), void *intrarg)
609 1.1 hamajima {
610 1.1 hamajima DPRINTFN(3, ("vraiu_start_input\n"));
611 1.1 hamajima
612 1.1 hamajima /* no input */
613 1.1 hamajima return ENXIO;
614 1.1 hamajima }
615 1.1 hamajima
616 1.1 hamajima int
617 1.1 hamajima vraiu_intr(void* self)
618 1.1 hamajima {
619 1.1 hamajima struct vraiu_softc *sc = (void*)self;
620 1.1 hamajima u_int32_t reg;
621 1.1 hamajima
622 1.1 hamajima DPRINTFN(2, ("vraiu_intr"));
623 1.1 hamajima
624 1.1 hamajima vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AIUINT_INTSEND, 0);
625 1.1 hamajima vrip_intr_getstatus2(sc->sc_vrip, sc->sc_handler, ®);
626 1.1 hamajima if (reg & AIUINT_INTSEND) {
627 1.1 hamajima DPRINTFN(2, (": AIUINT_INTSEND"));
628 1.1 hamajima if (sc->sc_intr) {
629 1.1 hamajima void (*intr)(void *) = sc->sc_intr;
630 1.1 hamajima sc->sc_intr = NULL;
631 1.1 hamajima (*(intr))(sc->sc_intrdata);
632 1.1 hamajima }
633 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, INT_REG_W, SENDINTR);
634 1.1 hamajima }
635 1.1 hamajima DPRINTFN(2, ("\n"));
636 1.1 hamajima return 0;
637 1.1 hamajima }
638 1.1 hamajima
639 1.1 hamajima int
640 1.1 hamajima vraiu_halt_output(void *self)
641 1.1 hamajima {
642 1.1 hamajima struct vraiu_softc *sc = (void*)self;
643 1.1 hamajima
644 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output\n"));
645 1.1 hamajima
646 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output: disable interrupt\n"))
647 1.1 hamajima vrip_intr_setmask2(sc->sc_vrip, sc->sc_handler, AIUINT_INTSEND, 0);
648 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output: stop output\n"))
649 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, SEQ_REG_W, 0);
650 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output: speaker power off\n"))
651 1.1 hamajima config_hook_call(CONFIG_HOOK_POWERCONTROL,
652 1.1 hamajima CONFIG_HOOK_POWERCONTROL_SPEAKER, (void*)0);
653 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output: Vref off\n"))
654 1.1 hamajima bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCNT_REG_W, 0);
655 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output: disable DMA\n"))
656 1.1 hamajima sc->sc_dc->dc_disable(sc->sc_dc);
657 1.1 hamajima DPRINTFN(1, ("vraiu_halt_output: clock supply stop\n"))
658 1.1 hamajima sc->sc_cc->cc_clock(sc->sc_cc, VR4102_CMUMSKAIU, 0);
659 1.1 hamajima sc->sc_intr = NULL;
660 1.1 hamajima return 0;
661 1.1 hamajima }
662 1.1 hamajima
663 1.1 hamajima int
664 1.1 hamajima vraiu_halt_input(void *self)
665 1.1 hamajima {
666 1.1 hamajima DPRINTFN(3, ("vraiu_halt_input\n"));
667 1.1 hamajima
668 1.1 hamajima /* no input */
669 1.1 hamajima return ENXIO;
670 1.1 hamajima }
671 1.1 hamajima
672 1.1 hamajima
673 1.1 hamajima int
674 1.1 hamajima vraiu_getdev(void *self, struct audio_device *ret)
675 1.1 hamajima {
676 1.1 hamajima DPRINTFN(3, ("vraiu_getdev\n"));
677 1.1 hamajima
678 1.1 hamajima *ret = aiu_device;
679 1.1 hamajima return 0;
680 1.1 hamajima }
681 1.1 hamajima
682 1.1 hamajima int
683 1.1 hamajima vraiu_set_port(void *self, mixer_ctrl_t *mc)
684 1.1 hamajima {
685 1.7 jmcneill struct vraiu_softc *sc = (struct vraiu_softc *)self;
686 1.1 hamajima DPRINTFN(3, ("vraiu_set_port\n"));
687 1.1 hamajima
688 1.7 jmcneill /* software mixer, 1ch */
689 1.7 jmcneill if (mc->dev == 0) {
690 1.7 jmcneill if (mc->type != AUDIO_MIXER_VALUE)
691 1.7 jmcneill return EINVAL;
692 1.7 jmcneill if (mc->un.value.num_channels != 1)
693 1.7 jmcneill return EINVAL;
694 1.7 jmcneill sc->sc_volume = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
695 1.7 jmcneill return 0;
696 1.7 jmcneill }
697 1.7 jmcneill
698 1.1 hamajima return EINVAL;
699 1.1 hamajima }
700 1.1 hamajima
701 1.1 hamajima int
702 1.1 hamajima vraiu_get_port(void *self, mixer_ctrl_t *mc)
703 1.1 hamajima {
704 1.7 jmcneill struct vraiu_softc *sc = (struct vraiu_softc *)self;
705 1.1 hamajima DPRINTFN(3, ("vraiu_get_port\n"));
706 1.1 hamajima
707 1.7 jmcneill /* software mixer, 1ch */
708 1.7 jmcneill if (mc->dev == 0) {
709 1.7 jmcneill if (mc->un.value.num_channels != 1)
710 1.7 jmcneill return EINVAL;
711 1.7 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_volume;
712 1.7 jmcneill return 0;
713 1.7 jmcneill }
714 1.7 jmcneill
715 1.1 hamajima return EINVAL;
716 1.1 hamajima }
717 1.1 hamajima
718 1.1 hamajima int
719 1.1 hamajima vraiu_query_devinfo(void *self, mixer_devinfo_t *di)
720 1.1 hamajima {
721 1.1 hamajima DPRINTFN(3, ("vraiu_query_devinfo\n"));
722 1.1 hamajima
723 1.7 jmcneill /* software mixer, 1ch */
724 1.7 jmcneill switch (di->index) {
725 1.7 jmcneill case 0: /* inputs.dac mixer value */
726 1.7 jmcneill di->mixer_class = 1;
727 1.7 jmcneill di->next = di->prev = AUDIO_MIXER_LAST;
728 1.7 jmcneill strcpy(di->label.name, AudioNdac);
729 1.7 jmcneill di->type = AUDIO_MIXER_VALUE;
730 1.7 jmcneill di->un.v.num_channels = 1;
731 1.7 jmcneill strcpy(di->un.v.units.name, AudioNvolume);
732 1.7 jmcneill return 0;
733 1.7 jmcneill case 1: /* outputs class */
734 1.7 jmcneill di->mixer_class = 1;
735 1.7 jmcneill di->next = di->prev = AUDIO_MIXER_LAST;
736 1.7 jmcneill strcpy(di->label.name, AudioCinputs);
737 1.7 jmcneill di->type = AUDIO_MIXER_CLASS;
738 1.7 jmcneill return 0;
739 1.7 jmcneill }
740 1.7 jmcneill
741 1.1 hamajima return ENXIO;
742 1.1 hamajima }
743 1.1 hamajima
744 1.1 hamajima int
745 1.1 hamajima vraiu_get_props(void *self)
746 1.1 hamajima {
747 1.1 hamajima DPRINTFN(3, ("vraiu_get_props\n"));
748 1.1 hamajima
749 1.1 hamajima return 0;
750 1.1 hamajima }
751 1.1 hamajima
752 1.4 wiz unsigned char mulaw_to_lin[] = {
753 1.1 hamajima 0x02, 0x06, 0x0a, 0x0e, 0x12, 0x16, 0x1a, 0x1e,
754 1.1 hamajima 0x22, 0x26, 0x2a, 0x2e, 0x32, 0x36, 0x3a, 0x3e,
755 1.1 hamajima 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d, 0x4f,
756 1.1 hamajima 0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f,
757 1.1 hamajima 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
758 1.1 hamajima 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
759 1.1 hamajima 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74,
760 1.1 hamajima 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78,
761 1.1 hamajima 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a,
762 1.1 hamajima 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c,
763 1.1 hamajima 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d,
764 1.1 hamajima 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e,
765 1.1 hamajima 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
766 1.1 hamajima 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
767 1.1 hamajima 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
768 1.1 hamajima 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80,
769 1.1 hamajima 0xfd, 0xf9, 0xf5, 0xf1, 0xed, 0xe9, 0xe5, 0xe1,
770 1.1 hamajima 0xdd, 0xd9, 0xd5, 0xd1, 0xcd, 0xc9, 0xc5, 0xc1,
771 1.1 hamajima 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0,
772 1.1 hamajima 0xae, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0xa2, 0xa0,
773 1.1 hamajima 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97,
774 1.1 hamajima 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f,
775 1.1 hamajima 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b,
776 1.1 hamajima 0x8b, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x87,
777 1.1 hamajima 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85,
778 1.1 hamajima 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83,
779 1.1 hamajima 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
780 1.1 hamajima 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81,
781 1.1 hamajima 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
782 1.1 hamajima 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
783 1.1 hamajima 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
784 1.1 hamajima 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
785 1.1 hamajima };
786 1.1 hamajima
787 1.1 hamajima static void
788 1.1 hamajima vraiu_slinear8_1(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
789 1.1 hamajima {
790 1.1 hamajima char *q = (char*)p;
791 1.1 hamajima
792 1.1 hamajima DPRINTFN(3, ("vraiu_slinear8_1\n"));
793 1.1 hamajima
794 1.1 hamajima #ifdef DIAGNOSTIC
795 1.1 hamajima if (n > AUDIO_BUF_SIZE/2) {
796 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
797 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE/2);
798 1.1 hamajima n = AUDIO_BUF_SIZE/2;
799 1.1 hamajima }
800 1.1 hamajima #endif
801 1.1 hamajima while (n--) {
802 1.1 hamajima short i = *q++;
803 1.1 hamajima *dmap++ = (i << 2) + 0x200;
804 1.1 hamajima }
805 1.1 hamajima }
806 1.1 hamajima
807 1.1 hamajima static void
808 1.1 hamajima vraiu_slinear8_2(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
809 1.1 hamajima {
810 1.1 hamajima char *q = (char*)p;
811 1.1 hamajima
812 1.1 hamajima DPRINTFN(3, ("vraiu_slinear8_2\n"));
813 1.1 hamajima
814 1.1 hamajima #ifdef DIAGNOSTIC
815 1.1 hamajima if (n > AUDIO_BUF_SIZE) {
816 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
817 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE);
818 1.1 hamajima n = AUDIO_BUF_SIZE;
819 1.1 hamajima }
820 1.1 hamajima #endif
821 1.1 hamajima n /= 2;
822 1.1 hamajima while (n--) {
823 1.1 hamajima short i = *q++;
824 1.1 hamajima short j = *q++;
825 1.1 hamajima *dmap++ = ((i + j) << 1) + 0x200;
826 1.1 hamajima }
827 1.1 hamajima }
828 1.1 hamajima
829 1.1 hamajima static void
830 1.1 hamajima vraiu_ulinear8_1(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
831 1.1 hamajima {
832 1.1 hamajima u_char *q = (u_char*)p;
833 1.1 hamajima
834 1.1 hamajima DPRINTFN(3, ("vraiu_ulinear8_1\n"));
835 1.1 hamajima
836 1.1 hamajima #ifdef DIAGNOSTIC
837 1.1 hamajima if (n > AUDIO_BUF_SIZE/2) {
838 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
839 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE/2);
840 1.1 hamajima n = AUDIO_BUF_SIZE/2;
841 1.1 hamajima }
842 1.1 hamajima #endif
843 1.1 hamajima while (n--) {
844 1.1 hamajima short i = *q++;
845 1.1 hamajima *dmap++ = i << 2;
846 1.1 hamajima }
847 1.1 hamajima }
848 1.1 hamajima
849 1.1 hamajima static void
850 1.1 hamajima vraiu_ulinear8_2(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
851 1.1 hamajima {
852 1.1 hamajima u_char *q = (u_char*)p;
853 1.1 hamajima
854 1.1 hamajima DPRINTFN(3, ("vraiu_ulinear8_2\n"));
855 1.1 hamajima
856 1.1 hamajima #ifdef DIAGNOSTIC
857 1.1 hamajima if (n > AUDIO_BUF_SIZE) {
858 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
859 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE);
860 1.1 hamajima n = AUDIO_BUF_SIZE;
861 1.1 hamajima }
862 1.1 hamajima #endif
863 1.1 hamajima n /= 2;
864 1.1 hamajima while (n--) {
865 1.1 hamajima short i = *q++;
866 1.1 hamajima short j = *q++;
867 1.1 hamajima *dmap++ = (i + j) << 1;
868 1.1 hamajima }
869 1.1 hamajima }
870 1.1 hamajima
871 1.1 hamajima static void
872 1.4 wiz vraiu_mulaw_1(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
873 1.1 hamajima {
874 1.1 hamajima u_char *q = (u_char*)p;
875 1.1 hamajima
876 1.4 wiz DPRINTFN(3, ("vraiu_mulaw_1\n"));
877 1.1 hamajima
878 1.1 hamajima #ifdef DIAGNOSTIC
879 1.1 hamajima if (n > AUDIO_BUF_SIZE/2) {
880 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
881 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE/2);
882 1.1 hamajima n = AUDIO_BUF_SIZE/2;
883 1.1 hamajima }
884 1.1 hamajima #endif
885 1.1 hamajima while (n--) {
886 1.4 wiz short i = mulaw_to_lin[*q++];
887 1.1 hamajima *dmap++ = i << 2;
888 1.1 hamajima }
889 1.1 hamajima }
890 1.1 hamajima
891 1.1 hamajima static void
892 1.4 wiz vraiu_mulaw_2(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
893 1.1 hamajima {
894 1.1 hamajima u_char *q = (u_char*)p;
895 1.1 hamajima
896 1.4 wiz DPRINTFN(3, ("vraiu_mulaw_2\n"));
897 1.1 hamajima
898 1.1 hamajima #ifdef DIAGNOSTIC
899 1.1 hamajima if (n > AUDIO_BUF_SIZE) {
900 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
901 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE);
902 1.1 hamajima n = AUDIO_BUF_SIZE;
903 1.1 hamajima }
904 1.1 hamajima #endif
905 1.1 hamajima n /= 2;
906 1.1 hamajima while (n--) {
907 1.4 wiz short i = mulaw_to_lin[*q++];
908 1.4 wiz short j = mulaw_to_lin[*q++];
909 1.1 hamajima *dmap++ = (i + j) << 1;
910 1.1 hamajima }
911 1.1 hamajima }
912 1.1 hamajima
913 1.1 hamajima static void
914 1.1 hamajima vraiu_slinear16_1(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
915 1.1 hamajima {
916 1.1 hamajima short *q = (short*)p;
917 1.1 hamajima
918 1.1 hamajima DPRINTFN(3, ("vraiu_slinear16_1\n"));
919 1.1 hamajima
920 1.1 hamajima #ifdef DIAGNOSTIC
921 1.1 hamajima if (n > AUDIO_BUF_SIZE) {
922 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
923 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE);
924 1.1 hamajima n = AUDIO_BUF_SIZE;
925 1.1 hamajima }
926 1.1 hamajima #endif
927 1.1 hamajima n /= 2;
928 1.1 hamajima while (n--) {
929 1.1 hamajima short i = *q++;
930 1.1 hamajima *dmap++ = (i >> 6) + 0x200;
931 1.1 hamajima }
932 1.1 hamajima }
933 1.1 hamajima
934 1.1 hamajima static void
935 1.1 hamajima vraiu_slinear16_2(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
936 1.1 hamajima {
937 1.1 hamajima short *q = (short*)p;
938 1.1 hamajima
939 1.1 hamajima DPRINTFN(3, ("vraiu_slinear16_2\n"));
940 1.1 hamajima
941 1.1 hamajima #ifdef DIAGNOSTIC
942 1.1 hamajima if (n > AUDIO_BUF_SIZE*2) {
943 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
944 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE*2);
945 1.1 hamajima n = AUDIO_BUF_SIZE*2;
946 1.1 hamajima }
947 1.1 hamajima #endif
948 1.1 hamajima n /= 4;
949 1.1 hamajima while (n--) {
950 1.1 hamajima short i = *q++;
951 1.1 hamajima short j = *q++;
952 1.1 hamajima *dmap++ = (i >> 7) + (j >> 7) + 0x200;
953 1.1 hamajima }
954 1.1 hamajima }
955 1.1 hamajima
956 1.1 hamajima static void
957 1.1 hamajima vraiu_slinear16sw_1(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
958 1.1 hamajima {
959 1.1 hamajima short *q = (short*)p;
960 1.1 hamajima
961 1.1 hamajima DPRINTFN(3, ("vraiu_slinear16sw_1\n"));
962 1.1 hamajima
963 1.1 hamajima #ifdef DIAGNOSTIC
964 1.1 hamajima if (n > AUDIO_BUF_SIZE) {
965 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
966 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE);
967 1.1 hamajima n = AUDIO_BUF_SIZE;
968 1.1 hamajima }
969 1.1 hamajima #endif
970 1.1 hamajima n /= 2;
971 1.1 hamajima while (n--) {
972 1.1 hamajima short i = bswap16(*q++);
973 1.1 hamajima *dmap++ = (i >> 6) + 0x200;
974 1.1 hamajima }
975 1.1 hamajima }
976 1.1 hamajima
977 1.1 hamajima static void
978 1.1 hamajima vraiu_slinear16sw_2(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
979 1.1 hamajima {
980 1.1 hamajima short *q = (short*)p;
981 1.1 hamajima
982 1.1 hamajima DPRINTFN(3, ("vraiu_slinear16sw_2\n"));
983 1.1 hamajima
984 1.1 hamajima #ifdef DIAGNOSTIC
985 1.1 hamajima if (n > AUDIO_BUF_SIZE*2) {
986 1.1 hamajima printf("%s: output data too large (%d > %d)\n",
987 1.1 hamajima sc->sc_dev.dv_xname, n, AUDIO_BUF_SIZE*2);
988 1.1 hamajima n = AUDIO_BUF_SIZE*2;
989 1.1 hamajima }
990 1.1 hamajima #endif
991 1.1 hamajima n /= 4;
992 1.1 hamajima while (n--) {
993 1.1 hamajima short i = bswap16(*q++);
994 1.1 hamajima short j = bswap16(*q++);
995 1.1 hamajima *dmap++ = (i >> 7) + (j >> 7) + 0x200;
996 1.1 hamajima }
997 1.1 hamajima }
998 1.7 jmcneill
999 1.7 jmcneill static void
1000 1.7 jmcneill vraiu_volume(struct vraiu_softc *sc, u_short *dmap, void *p, int n)
1001 1.7 jmcneill {
1002 1.7 jmcneill int16_t *x = (int16_t *)dmap;
1003 1.7 jmcneill int i;
1004 1.7 jmcneill short j;
1005 1.7 jmcneill int vol = sc->sc_volume;
1006 1.7 jmcneill
1007 1.7 jmcneill for (i = 0; i < n / 2; i++) {
1008 1.7 jmcneill j = x[i] - 512;
1009 1.7 jmcneill x[i] = ((j * vol) / 255) + 512;
1010 1.7 jmcneill }
1011 1.7 jmcneill
1012 1.7 jmcneill return;
1013 1.7 jmcneill }
1014