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