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