1 /* $NetBSD: vraiu.c,v 1.11 2005/12/11 12:17:34 christos Exp $ */
4 * Copyright (c) 2001 HAMAJIMA Katsuomi. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: vraiu.c,v 1.11 2005/12/11 12:17:34 christos Exp $");
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/device.h>
34 #include <sys/malloc.h>
35 #include <sys/bswap.h>
37 #include <machine/cpu.h>
38 #include <machine/intr.h>
39 #include <machine/bus.h>
40 #include <machine/platid.h>
41 #include <machine/platid_mask.h>
42 #include <machine/config_hook.h>
44 #include <sys/audioio.h>
45 #include <dev/audio_if.h>
47 #include <hpcmips/vr/vr.h>
48 #include <hpcmips/vr/vripif.h>
49 #include <hpcmips/vr/icureg.h>
50 #include <hpcmips/vr/cmureg.h>
51 #include <hpcmips/vr/vraiureg.h>
54 int vraiu_debug
= VRAIU_DEBUG
;
55 #define DPRINTFN(n,x) if (vraiu_debug>(n)) printf x;
60 #define AUDIO_BUF_SIZE 2048
64 bus_space_tag_t sc_iot
;
65 bus_space_handle_t sc_ioh
;
66 bus_dma_tag_t sc_dmat
;
68 vrip_chipset_tag_t sc_vrip
;
69 vrdcu_chipset_tag_t sc_dc
;
70 vrdmaau_chipset_tag_t sc_ac
;
71 vrcmu_chipset_tag_t sc_cc
;
73 u_short
*sc_buf
; /* DMA buffer pointer */
74 int sc_status
; /* status */
75 u_int sc_rate
; /* sampling rate */
76 u_int sc_channels
; /* # of channels used */
77 u_int sc_encoding
; /* encoding type */
78 int sc_precision
; /* 8 or 16 bits */
79 /* pointer to format conversion routine */
80 u_char sc_volume
; /* volume */
81 void (*sc_decodefunc
)(struct vraiu_softc
*, u_short
*, void *, int);
82 void (*sc_intr
)(void *); /* interrupt routine */
83 void *sc_intrdata
; /* interrupt data */
86 int vraiu_match(struct device
*, struct cfdata
*, void *);
87 void vraiu_attach(struct device
*, struct device
*, void *);
88 int vraiu_intr(void *);
90 CFATTACH_DECL(vraiu
, sizeof(struct vraiu_softc
),
91 vraiu_match
, vraiu_attach
, NULL
, NULL
);
93 struct audio_device aiu_device
= {
100 * Define our interface to the higher level audio driver.
102 int vraiu_open(void *, int);
103 void vraiu_close(void *);
104 int vraiu_query_encoding(void *, struct audio_encoding
*);
105 int vraiu_round_blocksize(void *, int, int, const audio_params_t
*);
106 int vraiu_commit_settings(void *);
107 int vraiu_init_output(void *, void*, int);
108 int vraiu_start_output(void *, void *, int, void (*)(void *), void *);
109 int vraiu_start_input(void *, void *, int, void (*)(void *), void *);
110 int vraiu_halt_output(void *);
111 int vraiu_halt_input(void *);
112 int vraiu_getdev(void *, struct audio_device
*);
113 int vraiu_set_port(void *, mixer_ctrl_t
*);
114 int vraiu_get_port(void *, mixer_ctrl_t
*);
115 int vraiu_query_devinfo(void *, mixer_devinfo_t
*);
116 int vraiu_set_params(void *, int, int, audio_params_t
*, audio_params_t
*,
117 stream_filter_list_t
*, stream_filter_list_t
*);
118 int vraiu_get_props(void *);
120 const struct audio_hw_if vraiu_hw_if
= {
124 vraiu_query_encoding
,
126 vraiu_round_blocksize
,
127 vraiu_commit_settings
,
148 * convert to 1ch 10bit unsigned PCM data.
150 static void vraiu_slinear8_1(struct vraiu_softc
*, u_short
*, void *, int);
151 static void vraiu_slinear8_2(struct vraiu_softc
*, u_short
*, void *, int);
152 static void vraiu_ulinear8_1(struct vraiu_softc
*, u_short
*, void *, int);
153 static void vraiu_ulinear8_2(struct vraiu_softc
*, u_short
*, void *, int);
154 static void vraiu_mulaw_1(struct vraiu_softc
*, u_short
*, void *, int);
155 static void vraiu_mulaw_2(struct vraiu_softc
*, u_short
*, void *, int);
156 static void vraiu_slinear16_1(struct vraiu_softc
*, u_short
*, void *, int);
157 static void vraiu_slinear16_2(struct vraiu_softc
*, u_short
*, void *, int);
158 static void vraiu_slinear16sw_1(struct vraiu_softc
*, u_short
*, void *, int);
159 static void vraiu_slinear16sw_2(struct vraiu_softc
*, u_short
*, void *, int);
161 * software volume control
163 static void vraiu_volume(struct vraiu_softc
*, u_short
*, void *, int);
166 vraiu_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
172 vraiu_attach(struct device
*parent
, struct device
*self
, void *aux
)
174 struct vrip_attach_args
*va
;
175 struct vraiu_softc
*sc
;
176 bus_dma_segment_t segs
;
181 sc
->sc_status
= ENXIO
;
183 sc
->sc_iot
= va
->va_iot
;
184 sc
->sc_vrip
= va
->va_vc
;
185 sc
->sc_cc
= va
->va_cc
;
186 sc
->sc_dc
= va
->va_dc
;
187 sc
->sc_ac
= va
->va_ac
;
188 sc
->sc_dmat
= &vrdcu_bus_dma_tag
;
192 printf(" not configured: cmu not found\n");
196 printf(" not configured: dcu not found\n");
200 printf(" not configured: dmaau not found\n");
203 if (bus_space_map(sc
->sc_iot
, va
->va_addr
, va
->va_size
,
204 0 /* no flags */, &sc
->sc_ioh
)) {
205 printf(": can't map i/o space\n");
209 /* install interrupt handler and enable interrupt */
210 if (!(sc
->sc_handler
= vrip_intr_establish(va
->va_vc
, va
->va_unit
,
211 0, IPL_AUDIO
, vraiu_intr
, sc
))) {
212 printf(": can't map interrupt line.\n");
215 vrip_intr_setmask2(sc
->sc_vrip
, sc
->sc_handler
, (AIUINT_INTMEND
| \
221 AIUINT_INTSIDLE
), 0);
223 if (bus_dmamem_alloc(sc
->sc_dmat
, AUDIO_BUF_SIZE
, 0, 0, &segs
, 1,
224 &rsegs
, BUS_DMA_NOWAIT
)) {
225 printf(": can't allocate memory.\n");
228 if (bus_dmamem_map(sc
->sc_dmat
, &segs
, rsegs
, AUDIO_BUF_SIZE
,
229 (void **)&sc
->sc_buf
,
230 BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
)) {
231 printf(": can't map memory.\n");
232 bus_dmamem_free(sc
->sc_dmat
, &segs
, rsegs
);
235 if (bus_dmamap_create(sc
->sc_dmat
, AUDIO_BUF_SIZE
, 1, AUDIO_BUF_SIZE
,
236 0, BUS_DMA_NOWAIT
, &sc
->sc_dmap
)) {
237 printf(": can't create DMA map.\n");
238 bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_buf
,
240 bus_dmamem_free(sc
->sc_dmat
, &segs
, rsegs
);
243 if (bus_dmamap_load(sc
->sc_dmat
, sc
->sc_dmap
, sc
->sc_buf
,
244 AUDIO_BUF_SIZE
, NULL
, BUS_DMA_NOWAIT
)) {
245 printf(": can't load DMA map.\n");
246 bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_dmap
);
247 bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_buf
,
249 bus_dmamem_free(sc
->sc_dmat
, &segs
, rsegs
);
252 if (sc
->sc_ac
->ac_set_aiuout(sc
->sc_ac
, sc
->sc_buf
)) {
253 printf(": can't set DMA address.\n");
254 bus_dmamap_unload(sc
->sc_dmat
, sc
->sc_dmap
);
255 bus_dmamap_destroy(sc
->sc_dmat
, sc
->sc_dmap
);
256 bus_dmamem_unmap(sc
->sc_dmat
, (void *)sc
->sc_buf
,
258 bus_dmamem_free(sc
->sc_dmat
, &segs
, rsegs
);
264 sc
->sc_rate
= SPS8000
;
266 sc
->sc_precision
= 8;
267 sc
->sc_encoding
= AUDIO_ENCODING_ULAW
;
268 sc
->sc_decodefunc
= vraiu_mulaw_1
;
269 DPRINTFN(1, ("vraiu_attach: reset AIU\n"))
270 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, SEQ_REG_W
, AIURST
);
271 /* attach audio subsystem */
272 audio_attach_mi(&vraiu_hw_if
, sc
, &sc
->sc_dev
);
276 vraiu_open(void *self
, int flags
)
278 struct vraiu_softc
*sc
;
280 DPRINTFN(1, ("vraiu_open\n"));
283 DPRINTFN(0, ("vraiu_open: device error\n"));
284 return sc
->sc_status
;
286 sc
->sc_status
= EBUSY
;
291 vraiu_close(void *self
)
293 struct vraiu_softc
*sc
;
295 DPRINTFN(1, ("vraiu_close\n"));
297 vraiu_halt_output(self
);
302 vraiu_query_encoding(void *self
, struct audio_encoding
*ae
)
304 DPRINTFN(3, ("vraiu_query_encoding\n"));
308 strcpy(ae
->name
, AudioEslinear
);
309 ae
->encoding
= AUDIO_ENCODING_SLINEAR
;
311 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
314 strcpy(ae
->name
, AudioEmulaw
);
315 ae
->encoding
= AUDIO_ENCODING_ULAW
;
317 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
320 strcpy(ae
->name
, AudioEulinear
);
321 ae
->encoding
= AUDIO_ENCODING_ULINEAR
;
323 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
326 strcpy(ae
->name
, AudioEslinear
);
327 ae
->encoding
= AUDIO_ENCODING_SLINEAR
;
329 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
332 strcpy(ae
->name
, AudioEslinear_be
);
333 ae
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
335 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
338 strcpy(ae
->name
, AudioEslinear_le
);
339 ae
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
341 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
344 strcpy(ae
->name
, AudioEslinear
);
345 ae
->encoding
= AUDIO_ENCODING_ULINEAR
;
347 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
350 strcpy(ae
->name
, AudioEslinear_be
);
351 ae
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
353 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
356 strcpy(ae
->name
, AudioEslinear_le
);
357 ae
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
359 ae
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
362 DPRINTFN(0, ("vraiu_query_encoding: param error"
363 " (%d)\n", ae
->index
));
370 vraiu_set_params(void *self
, int setmode
, int usemode
,
371 audio_params_t
*play
, audio_params_t
*rec
,
372 stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
374 struct vraiu_softc
*sc
;
376 DPRINTFN(1, ("vraiu_set_params: %ubit, %uch, %uHz, encoding %u\n",
377 play
->precision
, play
->channels
, play
->sample_rate
,
380 switch (play
->sample_rate
) {
382 sc
->sc_rate
= SPS8000
;
385 sc
->sc_rate
= SPS11025
;
388 sc
->sc_rate
= SPS22050
;
391 sc
->sc_rate
= SPS44100
;
394 DPRINTFN(0, ("vraiu_set_params: rate error (%ld)\n",
399 switch (play
->precision
) {
401 switch (play
->encoding
) {
402 case AUDIO_ENCODING_ULAW
:
403 switch (play
->channels
) {
405 sc
->sc_decodefunc
= vraiu_mulaw_1
;
408 sc
->sc_decodefunc
= vraiu_mulaw_2
;
411 DPRINTFN(0, ("vraiu_set_params: channel error"
412 " (%d)\n", play
->channels
));
416 case AUDIO_ENCODING_SLINEAR
:
417 case AUDIO_ENCODING_SLINEAR_BE
:
418 case AUDIO_ENCODING_SLINEAR_LE
:
419 switch (play
->channels
) {
421 sc
->sc_decodefunc
= vraiu_slinear8_1
;
424 sc
->sc_decodefunc
= vraiu_slinear8_2
;
427 DPRINTFN(0, ("vraiu_set_params: channel error"
428 " (%d)\n", play
->channels
));
432 case AUDIO_ENCODING_ULINEAR
:
433 case AUDIO_ENCODING_ULINEAR_BE
:
434 case AUDIO_ENCODING_ULINEAR_LE
:
435 switch (play
->channels
) {
437 sc
->sc_decodefunc
= vraiu_ulinear8_1
;
440 sc
->sc_decodefunc
= vraiu_ulinear8_2
;
443 DPRINTFN(0, ("vraiu_set_params: channel error"
444 " (%d)\n", play
->channels
));
449 DPRINTFN(0, ("vraiu_set_params: encoding error"
450 " (%d)\n", play
->encoding
));
455 switch (play
->encoding
) {
456 #if BYTE_ORDER == BIG_ENDIAN
457 case AUDIO_ENCODING_SLINEAR
:
459 case AUDIO_ENCODING_SLINEAR_BE
:
460 switch (play
->channels
) {
462 #if BYTE_ORDER == BIG_ENDIAN
463 sc
->sc_decodefunc
= vraiu_slinear16_1
;
465 sc
->sc_decodefunc
= vraiu_slinear16sw_1
;
469 #if BYTE_ORDER == BIG_ENDIAN
470 sc
->sc_decodefunc
= vraiu_slinear16_2
;
472 sc
->sc_decodefunc
= vraiu_slinear16sw_2
;
476 DPRINTFN(0, ("vraiu_set_params: channel error"
477 " (%d)\n", play
->channels
));
481 #if BYTE_ORDER == LITTLE_ENDIAN
482 case AUDIO_ENCODING_SLINEAR
:
484 case AUDIO_ENCODING_SLINEAR_LE
:
485 switch (play
->channels
) {
487 #if BYTE_ORDER == LITTLE_ENDIAN
488 sc
->sc_decodefunc
= vraiu_slinear16_1
;
490 sc
->sc_decodefunc
= vraiu_slinear16sw_1
;
494 #if BYTE_ORDER == LITTLE_ENDIAN
495 sc
->sc_decodefunc
= vraiu_slinear16_2
;
497 sc
->sc_decodefunc
= vraiu_slinear16sw_2
;
501 DPRINTFN(0, ("vraiu_set_params: channel error"
502 " (%d)\n", play
->channels
));
507 DPRINTFN(0, ("vraiu_set_params: encoding error"
508 " (%d)\n", play
->encoding
));
513 DPRINTFN(0, ("vraiu_set_params: precision error (%d)\n",
518 sc
->sc_encoding
= play
->encoding
;
519 sc
->sc_precision
= play
->precision
;
520 sc
->sc_channels
= play
->channels
;
525 vraiu_round_blocksize(void *self
, int bs
, int mode
, const audio_params_t
*param
)
527 struct vraiu_softc
*sc
;
532 if (sc
->sc_precision
== 8)
534 n
*= sc
->sc_channels
;
536 DPRINTFN(1, ("vraiu_round_blocksize: upper %d, lower %d\n",
543 vraiu_commit_settings(void *self
)
545 struct vraiu_softc
*sc
;
548 DPRINTFN(1, ("vraiu_commit_settings\n"));
550 if (sc
->sc_status
!= EBUSY
)
551 return sc
->sc_status
;
553 DPRINTFN(1, ("vraiu_commit_settings: set conversion rate %d\n",
555 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, SCNVR_REG_W
, sc
->sc_rate
);
556 DPRINTFN(1, ("vraiu_commit_settings: clock supply start\n"))
557 if ((err
= sc
->sc_cc
->cc_clock(sc
->sc_cc
, VR4102_CMUMSKAIU
, 1))) {
558 DPRINTFN(0, ("vraiu_commit_settings: clock supply error\n"));
561 DPRINTFN(1, ("vraiu_commit_settings: enable DMA\n"))
562 if ((err
= sc
->sc_dc
->dc_enable_aiuout(sc
->sc_dc
))) {
563 sc
->sc_cc
->cc_clock(sc
->sc_cc
, VR4102_CMUMSKAIU
, 0);
564 DPRINTFN(0, ("vraiu_commit_settings: enable DMA error\n"));
567 DPRINTFN(1, ("vraiu_commit_settings: Vref on\n"))
568 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, SCNT_REG_W
, DAENAIU
);
573 vraiu_init_output(void *self
, void *buffer
, int size
)
575 struct vraiu_softc
*sc
;
577 DPRINTFN(1, ("vraiu_init_output: buffer %p, size %d\n", buffer
, size
));
580 DPRINTFN(1, ("vraiu_init_output: speaker power on\n"))
581 config_hook_call(CONFIG_HOOK_POWERCONTROL
,
582 CONFIG_HOOK_POWERCONTROL_SPEAKER
, (void*)1);
583 DPRINTFN(1, ("vraiu_init_output: start output\n"))
584 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, SEQ_REG_W
, AIUSEN
);
589 vraiu_start_output(void *self
, void *block
, int bsize
,
590 void (*intr
)(void *), void *intrarg
)
592 struct vraiu_softc
*sc
;
594 DPRINTFN(2, ("vraiu_start_output: block %p, bsize %d\n",
597 sc
->sc_decodefunc(sc
, sc
->sc_buf
, block
, bsize
);
598 vraiu_volume(sc
, sc
->sc_buf
, block
, bsize
);
599 bus_dmamap_sync(sc
->sc_dmat
, sc
->sc_dmap
, 0, AUDIO_BUF_SIZE
,
600 BUS_DMASYNC_PREWRITE
);
602 sc
->sc_intrdata
= intrarg
;
603 /* clear interrupt status */
604 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, INT_REG_W
,
605 SENDINTR
| SINTR
| SIDLEINTR
);
606 /* enable interrupt */
607 vrip_intr_setmask2(sc
->sc_vrip
, sc
->sc_handler
, AIUINT_INTSEND
, 1);
612 vraiu_start_input(void *self
, void *block
, int bsize
,
613 void (*intr
)(void *), void *intrarg
)
616 DPRINTFN(3, ("vraiu_start_input\n"));
622 vraiu_intr(void* self
)
624 struct vraiu_softc
*sc
;
627 DPRINTFN(2, ("vraiu_intr"));
629 vrip_intr_setmask2(sc
->sc_vrip
, sc
->sc_handler
, AIUINT_INTSEND
, 0);
630 vrip_intr_getstatus2(sc
->sc_vrip
, sc
->sc_handler
, ®
);
631 if (reg
& AIUINT_INTSEND
) {
632 DPRINTFN(2, (": AIUINT_INTSEND"));
634 void (*intr
)(void *);
637 (*(intr
))(sc
->sc_intrdata
);
639 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, INT_REG_W
, SENDINTR
);
646 vraiu_halt_output(void *self
)
648 struct vraiu_softc
*sc
;
650 DPRINTFN(1, ("vraiu_halt_output\n"));
652 DPRINTFN(1, ("vraiu_halt_output: disable interrupt\n"))
653 vrip_intr_setmask2(sc
->sc_vrip
, sc
->sc_handler
, AIUINT_INTSEND
, 0);
654 DPRINTFN(1, ("vraiu_halt_output: stop output\n"))
655 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, SEQ_REG_W
, 0);
656 DPRINTFN(1, ("vraiu_halt_output: speaker power off\n"))
657 config_hook_call(CONFIG_HOOK_POWERCONTROL
,
658 CONFIG_HOOK_POWERCONTROL_SPEAKER
, (void*)0);
659 DPRINTFN(1, ("vraiu_halt_output: Vref off\n"))
660 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, SCNT_REG_W
, 0);
661 DPRINTFN(1, ("vraiu_halt_output: disable DMA\n"))
662 sc
->sc_dc
->dc_disable(sc
->sc_dc
);
663 DPRINTFN(1, ("vraiu_halt_output: clock supply stop\n"))
664 sc
->sc_cc
->cc_clock(sc
->sc_cc
, VR4102_CMUMSKAIU
, 0);
670 vraiu_halt_input(void *self
)
673 DPRINTFN(3, ("vraiu_halt_input\n"));
680 vraiu_getdev(void *self
, struct audio_device
*ret
)
683 DPRINTFN(3, ("vraiu_getdev\n"));
689 vraiu_set_port(void *self
, mixer_ctrl_t
*mc
)
691 struct vraiu_softc
*sc
;
693 DPRINTFN(3, ("vraiu_set_port\n"));
695 /* software mixer, 1ch */
697 if (mc
->type
!= AUDIO_MIXER_VALUE
)
699 if (mc
->un
.value
.num_channels
!= 1)
701 sc
->sc_volume
= mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
709 vraiu_get_port(void *self
, mixer_ctrl_t
*mc
)
711 struct vraiu_softc
*sc
;
713 DPRINTFN(3, ("vraiu_get_port\n"));
715 /* software mixer, 1ch */
717 if (mc
->un
.value
.num_channels
!= 1)
719 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] = sc
->sc_volume
;
727 vraiu_query_devinfo(void *self
, mixer_devinfo_t
*di
)
730 DPRINTFN(3, ("vraiu_query_devinfo\n"));
731 /* software mixer, 1ch */
733 case 0: /* inputs.dac mixer value */
735 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
736 strcpy(di
->label
.name
, AudioNdac
);
737 di
->type
= AUDIO_MIXER_VALUE
;
738 di
->un
.v
.num_channels
= 1;
739 strcpy(di
->un
.v
.units
.name
, AudioNvolume
);
741 case 1: /* outputs class */
743 di
->next
= di
->prev
= AUDIO_MIXER_LAST
;
744 strcpy(di
->label
.name
, AudioCinputs
);
745 di
->type
= AUDIO_MIXER_CLASS
;
753 vraiu_get_props(void *self
)
755 DPRINTFN(3, ("vraiu_get_props\n"));
760 unsigned char mulaw_to_lin
[] = {
761 0x02, 0x06, 0x0a, 0x0e, 0x12, 0x16, 0x1a, 0x1e,
762 0x22, 0x26, 0x2a, 0x2e, 0x32, 0x36, 0x3a, 0x3e,
763 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d, 0x4f,
764 0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f,
765 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
766 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
767 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74,
768 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78,
769 0x78, 0x78, 0x79, 0x79, 0x79, 0x79, 0x7a, 0x7a,
770 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c,
771 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d,
772 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e,
773 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
774 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
775 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
776 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80,
777 0xfd, 0xf9, 0xf5, 0xf1, 0xed, 0xe9, 0xe5, 0xe1,
778 0xdd, 0xd9, 0xd5, 0xd1, 0xcd, 0xc9, 0xc5, 0xc1,
779 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0,
780 0xae, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0xa2, 0xa0,
781 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97,
782 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f,
783 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b,
784 0x8b, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x87,
785 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85,
786 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83,
787 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
788 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81,
789 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
790 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
791 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
792 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
796 vraiu_slinear8_1(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
800 DPRINTFN(3, ("vraiu_slinear8_1\n"));
803 if (n
> AUDIO_BUF_SIZE
/2) {
804 printf("%s: output data too large (%d > %d)\n",
805 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
/2);
806 n
= AUDIO_BUF_SIZE
/2;
811 *dmap
++ = (i
<< 2) + 0x200;
816 vraiu_slinear8_2(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
820 DPRINTFN(3, ("vraiu_slinear8_2\n"));
823 if (n
> AUDIO_BUF_SIZE
) {
824 printf("%s: output data too large (%d > %d)\n",
825 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
);
833 *dmap
++ = ((i
+ j
) << 1) + 0x200;
838 vraiu_ulinear8_1(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
842 DPRINTFN(3, ("vraiu_ulinear8_1\n"));
845 if (n
> AUDIO_BUF_SIZE
/2) {
846 printf("%s: output data too large (%d > %d)\n",
847 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
/2);
848 n
= AUDIO_BUF_SIZE
/2;
858 vraiu_ulinear8_2(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
862 DPRINTFN(3, ("vraiu_ulinear8_2\n"));
865 if (n
> AUDIO_BUF_SIZE
) {
866 printf("%s: output data too large (%d > %d)\n",
867 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
);
875 *dmap
++ = (i
+ j
) << 1;
880 vraiu_mulaw_1(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
884 DPRINTFN(3, ("vraiu_mulaw_1\n"));
887 if (n
> AUDIO_BUF_SIZE
/2) {
888 printf("%s: output data too large (%d > %d)\n",
889 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
/2);
890 n
= AUDIO_BUF_SIZE
/2;
894 short i
= mulaw_to_lin
[*q
++];
900 vraiu_mulaw_2(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
904 DPRINTFN(3, ("vraiu_mulaw_2\n"));
907 if (n
> AUDIO_BUF_SIZE
) {
908 printf("%s: output data too large (%d > %d)\n",
909 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
);
915 short i
= mulaw_to_lin
[*q
++];
916 short j
= mulaw_to_lin
[*q
++];
917 *dmap
++ = (i
+ j
) << 1;
922 vraiu_slinear16_1(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
926 DPRINTFN(3, ("vraiu_slinear16_1\n"));
929 if (n
> AUDIO_BUF_SIZE
) {
930 printf("%s: output data too large (%d > %d)\n",
931 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
);
938 *dmap
++ = (i
>> 6) + 0x200;
943 vraiu_slinear16_2(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
947 DPRINTFN(3, ("vraiu_slinear16_2\n"));
950 if (n
> AUDIO_BUF_SIZE
*2) {
951 printf("%s: output data too large (%d > %d)\n",
952 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
*2);
953 n
= AUDIO_BUF_SIZE
*2;
960 *dmap
++ = (i
>> 7) + (j
>> 7) + 0x200;
965 vraiu_slinear16sw_1(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
969 DPRINTFN(3, ("vraiu_slinear16sw_1\n"));
972 if (n
> AUDIO_BUF_SIZE
) {
973 printf("%s: output data too large (%d > %d)\n",
974 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
);
980 short i
= bswap16(*q
++);
981 *dmap
++ = (i
>> 6) + 0x200;
986 vraiu_slinear16sw_2(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
990 DPRINTFN(3, ("vraiu_slinear16sw_2\n"));
993 if (n
> AUDIO_BUF_SIZE
*2) {
994 printf("%s: output data too large (%d > %d)\n",
995 sc
->sc_dev
.dv_xname
, n
, AUDIO_BUF_SIZE
*2);
996 n
= AUDIO_BUF_SIZE
*2;
1001 short i
= bswap16(*q
++);
1002 short j
= bswap16(*q
++);
1003 *dmap
++ = (i
>> 7) + (j
>> 7) + 0x200;
1008 vraiu_volume(struct vraiu_softc
*sc
, u_short
*dmap
, void *p
, int n
)
1015 x
= (int16_t *)dmap
;
1016 vol
= sc
->sc_volume
;
1017 for (i
= 0; i
< n
/ 2; i
++) {
1019 x
[i
] = ((j
* vol
) / 255) + 512;