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