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