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