Home | History | Annotate | Line # | Download | only in dev
aucc.c revision 1.27.2.3
      1  1.27.2.3  jdolecek /*	$NetBSD: aucc.c,v 1.27.2.3 2002/10/10 18:31:21 jdolecek Exp $ */
      2      1.20  augustss 
      3       1.1        is /*
      4      1.24        is  * Copyright (c) 1999 Bernardo Innocenti
      5      1.24        is  * All rights reserved.
      6      1.24        is  *
      7       1.1        is  * Copyright (c) 1997 Stephan Thesing
      8       1.1        is  * All rights reserved.
      9       1.1        is  *
     10       1.1        is  * Redistribution and use in source and binary forms, with or without
     11       1.1        is  * modification, are permitted provided that the following conditions
     12       1.1        is  * are met:
     13       1.1        is  * 1. Redistributions of source code must retain the above copyright
     14       1.1        is  *    notice, this list of conditions and the following disclaimer.
     15       1.1        is  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1        is  *    notice, this list of conditions and the following disclaimer in the
     17       1.1        is  *    documentation and/or other materials provided with the distribution.
     18       1.1        is  * 3. All advertising materials mentioning features or use of this software
     19       1.1        is  *    must display the following acknowledgement:
     20       1.1        is  *      This product includes software developed by Stephan Thesing.
     21       1.1        is  * 4. The name of the author may not be used to endorse or promote products
     22       1.1        is  *    derived from this software without specific prior written permission
     23       1.1        is  *
     24       1.1        is  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     25       1.1        is  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     26       1.1        is  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27       1.1        is  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     28       1.1        is  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     29       1.1        is  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     30       1.1        is  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     31       1.1        is  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     32       1.1        is  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     33       1.1        is  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34       1.1        is  */
     35       1.1        is 
     36      1.24        is /* TODO:
     37      1.24        is  *
     38      1.24        is  * - ulaw -> 14bit conversion
     39      1.24        is  * - channel allocation is wrong for 14bit mono
     40      1.24        is  * - convert the... err... conversion routines to 68k asm for best performance
     41  1.27.2.2  jdolecek  * 	XXX: NO. aucc audio is limited by chipmem speed, anyway. You dont
     42      1.24        is  *	want to make life difficult for amigappc work.
     43      1.24        is  *		-is
     44      1.24        is  *
     45      1.24        is  * - rely on auconv.c routines for ulaw/alaw conversions
     46      1.24        is  * - perhaps use a calibration table for better 14bit output
     47      1.24        is  * - set 31KHz AGA video mode to allow 44.1KHz even if grfcc is missing
     48      1.24        is  *	in the kernel
     49      1.24        is  * - 14bit output requires maximum volume
     50      1.24        is  */
     51      1.24        is 
     52       1.1        is #include "aucc.h"
     53       1.1        is #if NAUCC > 0
     54       1.5        is 
     55  1.27.2.2  jdolecek #include <sys/cdefs.h>
     56  1.27.2.3  jdolecek __KERNEL_RCSID(0, "$NetBSD: aucc.c,v 1.27.2.3 2002/10/10 18:31:21 jdolecek Exp $");
     57  1.27.2.2  jdolecek 
     58       1.1        is #include <sys/param.h>
     59       1.1        is #include <sys/systm.h>
     60       1.1        is #include <sys/errno.h>
     61       1.1        is #include <sys/ioctl.h>
     62       1.1        is #include <sys/device.h>
     63       1.1        is #include <sys/proc.h>
     64       1.1        is #include <machine/cpu.h>
     65       1.1        is 
     66       1.1        is #include <sys/audioio.h>
     67       1.1        is #include <dev/audio_if.h>
     68       1.1        is #include <amiga/amiga/cc.h>
     69       1.1        is #include <amiga/amiga/custom.h>
     70       1.1        is #include <amiga/amiga/device.h>
     71       1.1        is #include <amiga/dev/auccvar.h>
     72      1.27        is 
     73      1.27        is #include "opt_lev6_defer.h"
     74       1.1        is 
     75       1.7        is 
     76       1.7        is #ifdef LEV6_DEFER
     77       1.7        is #define AUCC_MAXINT 3
     78       1.7        is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
     79       1.7        is #else
     80       1.7        is #define AUCC_MAXINT 4
     81       1.7        is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
     82       1.7        is #endif
     83       1.7        is /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
     84       1.7        is #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
     85       1.7        is 
     86       1.1        is #ifdef AUDIO_DEBUG
     87  1.27.2.2  jdolecek /*extern printf(const char *,...);*/
     88       1.1        is int     auccdebug = 1;
     89       1.1        is #define DPRINTF(x)      if (auccdebug) printf x
     90       1.1        is #else
     91       1.1        is #define DPRINTF(x)
     92       1.1        is #endif
     93       1.1        is 
     94       1.1        is #ifdef splaudio
     95       1.1        is #undef splaudio
     96       1.1        is #endif
     97       1.1        is 
     98       1.1        is #define splaudio() spl4();
     99       1.1        is 
    100       1.1        is /* clock frequency.. */
    101  1.27.2.2  jdolecek extern int eclockfreq;
    102       1.1        is 
    103       1.1        is 
    104       1.1        is /* hw audio ch */
    105       1.1        is extern struct audio_channel channel[4];
    106       1.1        is 
    107       1.1        is 
    108       1.1        is /*
    109       1.1        is  * Software state.
    110       1.1        is  */
    111       1.1        is struct aucc_softc {
    112       1.1        is 	struct	device sc_dev;		/* base device */
    113       1.1        is 
    114       1.1        is 	int	sc_open;		/* single use device */
    115       1.1        is 	aucc_data_t sc_channel[4];	/* per channel freq, ... */
    116       1.1        is 	u_int	sc_encoding;		/* encoding AUDIO_ENCODING_.*/
    117       1.1        is 	int	sc_channels;		/* # of channels used */
    118      1.24        is 	int	sc_precision;		/* 8 or 16 bits */
    119      1.24        is 	int	sc_14bit;		/* 14bit output enabled */
    120       1.1        is 
    121       1.1        is 	int	sc_intrcnt;		/* interrupt count */
    122       1.1        is 	int	sc_channelmask;  	/* which channels are used ? */
    123  1.27.2.2  jdolecek 	void (*sc_decodefunc)(u_char **, u_char *, int);
    124      1.24        is 				/* pointer to format conversion routine */
    125       1.1        is };
    126       1.1        is 
    127       1.1        is /* interrupt interfaces */
    128  1.27.2.2  jdolecek void aucc_inthdl(int);
    129       1.1        is 
    130       1.1        is /* forward declarations */
    131  1.27.2.2  jdolecek static int init_aucc(struct aucc_softc *);
    132  1.27.2.2  jdolecek static u_int freqtoper(u_int);
    133  1.27.2.2  jdolecek static u_int pertofreq(u_int);
    134       1.1        is 
    135       1.1        is /* autoconfiguration driver */
    136  1.27.2.2  jdolecek void	auccattach(struct device *, struct device *, void *);
    137  1.27.2.2  jdolecek int	auccmatch(struct device *, struct cfdata *, void *);
    138       1.1        is 
    139  1.27.2.3  jdolecek CFATTACH_DECL(aucc, sizeof(struct aucc_softc),
    140  1.27.2.3  jdolecek     auccmatch, auccattach, NULL, NULL);
    141       1.1        is 
    142       1.1        is struct audio_device aucc_device = {
    143       1.1        is 	"Amiga-audio",
    144      1.24        is 	"2.0",
    145       1.1        is 	"aucc"
    146       1.1        is };
    147       1.1        is 
    148       1.1        is 
    149       1.1        is struct aucc_softc *aucc=NULL;
    150       1.1        is 
    151       1.1        is 
    152       1.1        is unsigned char ulaw_to_lin[] = {
    153       1.2        is 	0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
    154       1.2        is 	0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
    155       1.2        is 	0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf,
    156       1.2        is 	0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf,
    157       1.2        is 	0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
    158       1.2        is 	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
    159       1.2        is 	0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4,
    160       1.2        is 	0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
    161       1.2        is 	0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
    162       1.2        is 	0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
    163       1.2        is 	0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
    164       1.2        is 	0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
    165       1.2        is 	0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
    166       1.2        is 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    167       1.2        is 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    168       1.2        is 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    169       1.2        is 	0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61,
    170       1.2        is 	0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41,
    171       1.2        is 	0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30,
    172       1.2        is 	0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
    173       1.2        is 	0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17,
    174       1.2        is 	0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
    175       1.2        is 	0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
    176       1.2        is 	0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
    177       1.2        is 	0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05,
    178       1.2        is 	0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
    179       1.2        is 	0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
    180       1.2        is 	0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
    181       1.2        is 	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    182       1.2        is 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    183       1.2        is 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    184       1.2        is 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    185       1.1        is };
    186       1.1        is 
    187       1.1        is /*
    188       1.1        is  * Define our interface to the higher level audio driver.
    189       1.1        is  */
    190  1.27.2.2  jdolecek int	aucc_open(void *, int);
    191  1.27.2.2  jdolecek void	aucc_close(void *);
    192  1.27.2.2  jdolecek int	aucc_set_out_sr(void *, u_long);
    193  1.27.2.2  jdolecek int	aucc_query_encoding(void *, struct audio_encoding *);
    194  1.27.2.2  jdolecek int	aucc_round_blocksize(void *, int);
    195  1.27.2.2  jdolecek int	aucc_commit_settings(void *);
    196  1.27.2.2  jdolecek int	aucc_start_output(void *, void *, int, void (*)(void *), void *);
    197  1.27.2.2  jdolecek int	aucc_start_input(void *, void *, int, void (*)(void *), void *);
    198  1.27.2.2  jdolecek int	aucc_halt_output(void *);
    199  1.27.2.2  jdolecek int	aucc_halt_input(void *);
    200  1.27.2.2  jdolecek int	aucc_getdev(void *, struct audio_device *);
    201  1.27.2.2  jdolecek int	aucc_set_port(void *, mixer_ctrl_t *);
    202  1.27.2.2  jdolecek int	aucc_get_port(void *, mixer_ctrl_t *);
    203  1.27.2.2  jdolecek int	aucc_query_devinfo(void *, mixer_devinfo_t *);
    204  1.27.2.2  jdolecek void	aucc_encode(int, int, int, int, u_char *, u_short **);
    205  1.27.2.2  jdolecek int	aucc_set_params(void *, int, int, struct audio_params *,
    206  1.27.2.2  jdolecek 			struct audio_params *);
    207  1.27.2.2  jdolecek int	aucc_get_props(void *);
    208  1.27.2.2  jdolecek 
    209  1.27.2.2  jdolecek 
    210  1.27.2.2  jdolecek static void aucc_decode_slinear8_1ch(u_char **, u_char *, int);
    211  1.27.2.2  jdolecek static void aucc_decode_slinear8_2ch(u_char **, u_char *, int);
    212  1.27.2.2  jdolecek static void aucc_decode_slinear8_3ch(u_char **, u_char *, int);
    213  1.27.2.2  jdolecek static void aucc_decode_slinear8_4ch(u_char **, u_char *, int);
    214  1.27.2.2  jdolecek 
    215  1.27.2.2  jdolecek static void aucc_decode_ulinear8_1ch(u_char **, u_char *, int);
    216  1.27.2.2  jdolecek static void aucc_decode_ulinear8_2ch(u_char **, u_char *, int);
    217  1.27.2.2  jdolecek static void aucc_decode_ulinear8_3ch(u_char **, u_char *, int);
    218  1.27.2.2  jdolecek static void aucc_decode_ulinear8_4ch(u_char **, u_char *, int);
    219  1.27.2.2  jdolecek 
    220  1.27.2.2  jdolecek static void aucc_decode_ulaw_1ch(u_char **, u_char *, int);
    221  1.27.2.2  jdolecek static void aucc_decode_ulaw_2ch(u_char **, u_char *, int);
    222  1.27.2.2  jdolecek static void aucc_decode_ulaw_3ch(u_char **, u_char *, int);
    223  1.27.2.2  jdolecek static void aucc_decode_ulaw_4ch(u_char **, u_char *, int);
    224  1.27.2.2  jdolecek 
    225  1.27.2.2  jdolecek static void aucc_decode_slinear16_1ch(u_char **, u_char *, int);
    226  1.27.2.2  jdolecek static void aucc_decode_slinear16_2ch(u_char **, u_char *, int);
    227  1.27.2.2  jdolecek static void aucc_decode_slinear16_3ch(u_char **, u_char *, int);
    228  1.27.2.2  jdolecek static void aucc_decode_slinear16_4ch(u_char **, u_char *, int);
    229  1.27.2.2  jdolecek 
    230  1.27.2.2  jdolecek static void aucc_decode_slinear16sw_1ch(u_char **, u_char *, int);
    231  1.27.2.2  jdolecek static void aucc_decode_slinear16sw_2ch(u_char **, u_char *, int);
    232  1.27.2.2  jdolecek static void aucc_decode_slinear16sw_3ch(u_char **, u_char *, int);
    233  1.27.2.2  jdolecek static void aucc_decode_slinear16sw_4ch(u_char **, u_char *, int);
    234      1.24        is 
    235      1.24        is 
    236      1.24        is 
    237       1.1        is struct audio_hw_if sa_hw_if = {
    238       1.1        is 	aucc_open,
    239       1.1        is 	aucc_close,
    240       1.1        is 	NULL,
    241       1.1        is 	aucc_query_encoding,
    242       1.1        is 	aucc_set_params,
    243       1.1        is 	aucc_round_blocksize,
    244       1.1        is 	aucc_commit_settings,
    245      1.14  augustss 	NULL,
    246      1.14  augustss 	NULL,
    247       1.1        is 	aucc_start_output,
    248       1.1        is 	aucc_start_input,
    249       1.1        is 	aucc_halt_output,
    250       1.1        is 	aucc_halt_input,
    251       1.1        is 	NULL,
    252       1.1        is 	aucc_getdev,
    253      1.13  augustss 	NULL,
    254       1.1        is 	aucc_set_port,
    255       1.1        is 	aucc_get_port,
    256       1.1        is 	aucc_query_devinfo,
    257      1.14  augustss 	NULL,
    258      1.14  augustss 	NULL,
    259      1.14  augustss 	NULL,
    260      1.15  augustss 	NULL,
    261      1.16  augustss 	aucc_get_props,
    262  1.27.2.1   thorpej 	NULL,
    263  1.27.2.1   thorpej 	NULL,
    264  1.27.2.1   thorpej 	NULL,
    265       1.1        is };
    266       1.1        is 
    267       1.1        is /* autoconfig routines */
    268       1.1        is 
    269       1.1        is int
    270  1.27.2.2  jdolecek auccmatch(struct device *pdp, struct cfdata *cfp, void *aux)
    271       1.1        is {
    272      1.25    kleink 	static int aucc_matched = 0;
    273      1.25    kleink 
    274      1.25    kleink 	if (!matchname((char *)aux, "aucc") ||
    275       1.1        is #ifdef DRACO
    276      1.25    kleink 	    is_draco() ||
    277       1.1        is #endif
    278      1.25    kleink 	    aucc_matched)
    279      1.25    kleink 		return 0;
    280       1.1        is 
    281      1.25    kleink 	aucc_matched = 1;
    282      1.25    kleink 	return 1;
    283       1.1        is }
    284       1.1        is 
    285       1.1        is /*
    286       1.1        is  * Audio chip found.
    287       1.1        is  */
    288       1.1        is void
    289  1.27.2.2  jdolecek auccattach(struct device *parent, struct device *self, void *args)
    290       1.1        is {
    291       1.1        is 	register struct aucc_softc *sc = (struct aucc_softc *)self;
    292       1.1        is 	register int i;
    293       1.1        is 
    294       1.1        is 	printf("\n");
    295       1.1        is 
    296       1.1        is 	if((i=init_aucc(sc))) {
    297       1.1        is 		printf("audio: no chipmem\n");
    298       1.1        is 		return;
    299       1.1        is 	}
    300       1.1        is 
    301      1.23  augustss 	audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev);
    302       1.1        is }
    303       1.1        is 
    304       1.1        is 
    305       1.1        is static int
    306  1.27.2.2  jdolecek init_aucc(struct aucc_softc *sc)
    307       1.1        is {
    308       1.1        is 	register int i, err=0;
    309       1.1        is 
    310       1.1        is 	/* init values per channel */
    311       1.1        is  	for (i=0;i<4;i++) {
    312       1.1        is 		sc->sc_channel[i].nd_freq=8000;
    313       1.1        is 		sc->sc_channel[i].nd_per=freqtoper(8000);
    314       1.1        is 		sc->sc_channel[i].nd_busy=0;
    315       1.1        is 		sc->sc_channel[i].nd_dma=alloc_chipmem(AUDIO_BUF_SIZE*2);
    316       1.1        is 		if (sc->sc_channel[i].nd_dma==NULL)
    317       1.1        is 			err=1;
    318       1.1        is 	 	sc->sc_channel[i].nd_dmalength=0;
    319  1.27.2.2  jdolecek 		sc->sc_channel[i].nd_volume=64;
    320       1.1        is 		sc->sc_channel[i].nd_intr=NULL;
    321       1.1        is 		sc->sc_channel[i].nd_intrdata=NULL;
    322       1.8        is 		sc->sc_channel[i].nd_doublebuf=0;
    323       1.1        is 		DPRINTF(("dma buffer for channel %d is %p\n", i,
    324       1.1        is 		    sc->sc_channel[i].nd_dma));
    325       1.1        is 	}
    326       1.1        is 
    327       1.1        is 	if (err) {
    328       1.1        is 		for(i=0;i<4;i++)
    329       1.1        is 			if (sc->sc_channel[i].nd_dma)
    330       1.1        is 				free_chipmem(sc->sc_channel[i].nd_dma);
    331       1.1        is 	}
    332       1.1        is 
    333       1.8        is 	sc->sc_channels=1;
    334       1.1        is 	sc->sc_channelmask=0xf;
    335      1.24        is 	sc->sc_precision=8;
    336      1.24        is 	sc->sc_14bit = 0;
    337      1.24        is 	sc->sc_encoding=AUDIO_ENCODING_ULAW;
    338      1.24        is 	sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    339       1.1        is 
    340       1.2        is 	/* clear interrupts and dma: */
    341       1.7        is 	custom.intena = AUCC_ALLINTF;
    342      1.24        is 	custom.dmacon = AUCC_ALLDMAF;
    343       1.1        is 
    344       1.1        is 	return err;
    345       1.1        is }
    346       1.1        is 
    347       1.1        is int
    348  1.27.2.2  jdolecek aucc_open(void *addr, int flags)
    349       1.1        is {
    350      1.16  augustss 	struct aucc_softc *sc = addr;
    351      1.16  augustss 	int i;
    352       1.1        is 
    353      1.16  augustss 	DPRINTF(("sa_open: unit %p\n",sc));
    354       1.1        is 
    355       1.1        is 	if (sc->sc_open)
    356       1.1        is 		return (EBUSY);
    357       1.1        is 	sc->sc_open = 1;
    358       1.7        is 	for (i=0;i<AUCC_MAXINT;i++) {
    359       1.1        is 		sc->sc_channel[i].nd_intr=NULL;
    360       1.1        is 		sc->sc_channel[i].nd_intrdata=NULL;
    361       1.1        is 	}
    362       1.1        is 	aucc=sc;
    363       1.1        is 	sc->sc_channelmask=0xf;
    364       1.1        is 
    365       1.1        is 	DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
    366       1.1        is 
    367       1.1        is 	return (0);
    368       1.1        is }
    369       1.1        is 
    370       1.1        is void
    371  1.27.2.2  jdolecek aucc_close(void *addr)
    372       1.1        is {
    373       1.1        is 	register struct aucc_softc *sc = addr;
    374       1.1        is 
    375       1.1        is 	DPRINTF(("sa_close: sc=0x%p\n", sc));
    376       1.1        is 	/*
    377       1.1        is 	 * halt i/o, clear open flag, and done.
    378       1.1        is 	 */
    379       1.1        is 	aucc_halt_output(sc);
    380       1.1        is 	sc->sc_open = 0;
    381       1.1        is 
    382       1.1        is 	DPRINTF(("sa_close: closed.\n"));
    383       1.1        is }
    384       1.1        is 
    385       1.1        is int
    386  1.27.2.2  jdolecek aucc_set_out_sr(void *addr, u_long sr)
    387       1.1        is {
    388       1.1        is 	struct aucc_softc *sc=addr;
    389       1.1        is 	u_long per;
    390       1.1        is 	register int i;
    391       1.1        is 
    392       1.1        is 	per=freqtoper(sr);
    393       1.1        is 	if (per>0xffff)
    394       1.1        is 		return EINVAL;
    395       1.1        is 	sr=pertofreq(per);
    396       1.1        is 
    397       1.1        is 	for (i=0;i<4;i++) {
    398       1.1        is 		sc->sc_channel[i].nd_freq=sr;
    399       1.1        is 		sc->sc_channel[i].nd_per=per;
    400       1.1        is 	}
    401       1.1        is 
    402  1.27.2.2  jdolecek 	return(0);
    403       1.1        is }
    404       1.1        is 
    405       1.1        is int
    406  1.27.2.2  jdolecek aucc_query_encoding(void *addr, struct audio_encoding *fp)
    407       1.1        is {
    408      1.24        is 	switch (fp->index) {
    409      1.24        is 		case 0:
    410      1.24        is 			strcpy(fp->name, AudioEslinear);
    411      1.24        is 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    412      1.24        is 			fp->precision = 8;
    413      1.24        is 			fp->flags = 0;
    414      1.24        is 			break;
    415      1.24        is 		case 1:
    416      1.24        is 			strcpy(fp->name, AudioEmulaw);
    417      1.24        is 			fp->encoding = AUDIO_ENCODING_ULAW;
    418      1.24        is 			fp->precision = 8;
    419      1.24        is 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    420      1.24        is 			break;
    421  1.27.2.2  jdolecek 
    422      1.24        is 		case 2:
    423      1.24        is 			strcpy(fp->name, AudioEulinear);
    424      1.24        is 			fp->encoding = AUDIO_ENCODING_ULINEAR;
    425      1.24        is 			fp->precision = 8;
    426      1.24        is 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    427      1.24        is 			break;
    428      1.24        is 
    429      1.24        is 		case 3:
    430      1.24        is 			strcpy(fp->name, AudioEslinear);
    431      1.24        is 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    432      1.24        is 			fp->precision = 16;
    433      1.24        is 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    434      1.24        is 			break;
    435      1.24        is 
    436      1.24        is 		case 4:
    437      1.24        is 			strcpy(fp->name, AudioEslinear_be);
    438      1.24        is 			fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
    439      1.24        is 			fp->precision = 16;
    440      1.24        is 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    441      1.24        is 			break;
    442      1.24        is 
    443      1.24        is 		case 5:
    444      1.24        is 			strcpy(fp->name, AudioEslinear_le);
    445      1.24        is 			fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
    446      1.24        is 			fp->precision = 16;
    447      1.24        is 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    448      1.24        is 			break;
    449       1.3        is 
    450      1.24        is 		default:
    451      1.24        is 			return(EINVAL);
    452      1.24        is 			/*NOTREACHED*/
    453       1.1        is 	}
    454       1.1        is 	return(0);
    455       1.1        is }
    456       1.1        is 
    457       1.1        is int
    458  1.27.2.2  jdolecek aucc_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
    459  1.27.2.2  jdolecek                 struct audio_params *r)
    460       1.1        is {
    461      1.18  augustss 	struct aucc_softc *sc = addr;
    462       1.8        is 
    463      1.18  augustss 	/* if (setmode & AUMODE_RECORD)
    464       1.8        is 		return 0 ENXIO*/;
    465       1.8        is 
    466       1.9        is #ifdef AUCCDEBUG
    467      1.24        is 	printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
    468      1.24        is 		"enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode,
    469      1.24        is 		p->encoding, p->precision, p->channels, p->sample_rate);
    470      1.24        is #endif
    471      1.24        is 
    472      1.24        is 	switch (p->precision) {
    473      1.24        is 	case 8:
    474      1.24        is 		switch (p->encoding) {
    475      1.24        is 		case AUDIO_ENCODING_ULAW:
    476      1.24        is 			switch (p->channels) {
    477      1.24        is 			case 1:
    478      1.24        is 				sc->sc_decodefunc = aucc_decode_ulaw_1ch;
    479      1.24        is 				break;
    480      1.24        is 			case 2:
    481      1.24        is 				sc->sc_decodefunc = aucc_decode_ulaw_2ch;
    482      1.24        is 				break;
    483      1.24        is 			case 3:
    484      1.24        is 				sc->sc_decodefunc = aucc_decode_ulaw_3ch;
    485      1.24        is 				break;
    486      1.24        is 			case 4:
    487      1.24        is 				sc->sc_decodefunc = aucc_decode_ulaw_4ch;
    488      1.24        is 				break;
    489      1.24        is 			default:
    490      1.24        is 				return EINVAL;
    491      1.24        is 			}
    492      1.24        is 			break;
    493      1.24        is 
    494      1.24        is 		case AUDIO_ENCODING_SLINEAR:
    495      1.24        is 		case AUDIO_ENCODING_SLINEAR_BE:
    496      1.24        is 		case AUDIO_ENCODING_SLINEAR_LE:
    497      1.24        is 			switch (p->channels) {
    498      1.24        is 			case 1:
    499      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear8_1ch;
    500      1.24        is 				break;
    501      1.24        is 			case 2:
    502      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear8_2ch;
    503      1.24        is 				break;
    504      1.24        is 			case 3:
    505      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear8_3ch;
    506      1.24        is 				break;
    507      1.24        is 			case 4:
    508      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear8_4ch;
    509      1.24        is 				break;
    510      1.24        is 			default:
    511      1.24        is 				return EINVAL;
    512      1.24        is 			}
    513      1.24        is 			break;
    514      1.24        is 
    515      1.24        is 		case AUDIO_ENCODING_ULINEAR:
    516      1.24        is 		case AUDIO_ENCODING_ULINEAR_BE:
    517      1.24        is 		case AUDIO_ENCODING_ULINEAR_LE:
    518      1.24        is 			switch (p->channels) {
    519      1.24        is 			case 1:
    520      1.24        is 				sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
    521      1.24        is 				break;
    522      1.24        is 			case 2:
    523      1.24        is 				sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
    524      1.24        is 				break;
    525      1.24        is 			case 3:
    526      1.24        is 				sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
    527      1.24        is 				break;
    528      1.24        is 			case 4:
    529      1.24        is 				sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
    530      1.24        is 				break;
    531      1.24        is 			default:
    532      1.24        is 				return EINVAL;
    533      1.24        is 			}
    534      1.24        is 			break;
    535      1.24        is 
    536      1.24        is 		default:
    537      1.24        is 			return EINVAL;
    538      1.24        is 		}
    539      1.24        is 		break;
    540      1.24        is 
    541      1.24        is 	case 16:
    542      1.24        is 		switch (p->encoding) {
    543      1.24        is #if BYTE_ORDER == BIG_ENDIAN
    544      1.24        is 		case AUDIO_ENCODING_SLINEAR:
    545      1.24        is #endif
    546      1.24        is 		case AUDIO_ENCODING_SLINEAR_BE:
    547      1.24        is 			switch (p->channels) {
    548      1.24        is 			case 1:
    549      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16_1ch;
    550      1.24        is 				break;
    551      1.24        is 
    552      1.24        is 			case 2:
    553      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    554      1.24        is 				break;
    555      1.24        is 			case 3:
    556      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16_3ch;
    557      1.24        is 				break;
    558      1.24        is 			case 4:
    559      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16_4ch;
    560      1.24        is 				break;
    561      1.24        is 			default:
    562      1.24        is 				return EINVAL;
    563      1.24        is 			}
    564      1.24        is 			break;
    565      1.24        is 
    566      1.24        is #if BYTE_ORDER == LITTLE_ENDIAN
    567      1.24        is 		case AUDIO_ENCODING_SLINEAR:
    568       1.9        is #endif
    569      1.24        is 		case AUDIO_ENCODING_SLINEAR_LE:
    570      1.24        is 			switch (p->channels) {
    571      1.24        is 			case 1:
    572      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
    573      1.24        is 				break;
    574      1.24        is 			case 2:
    575      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
    576      1.24        is 				break;
    577      1.24        is 			case 3:
    578      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
    579      1.24        is 				break;
    580      1.24        is 			case 4:
    581      1.24        is 				sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
    582      1.24        is 				break;
    583      1.24        is 			default:
    584      1.24        is 				return EINVAL;
    585      1.24        is 			}
    586      1.24        is 			break;
    587       1.4        is 
    588      1.24        is 		default:
    589      1.24        is 			return EINVAL;
    590      1.24        is 		}
    591      1.24        is 		break;
    592       1.8        is 
    593       1.1        is 	default:
    594       1.1        is 		return EINVAL;
    595       1.1        is 	}
    596       1.1        is 
    597       1.8        is 	sc->sc_encoding = p->encoding;
    598      1.24        is 	sc->sc_precision = p->precision;
    599      1.24        is 	sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
    600      1.24        is 	sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
    601       1.8        is 
    602       1.8        is 	return aucc_set_out_sr(addr, p->sample_rate);
    603       1.1        is }
    604       1.1        is 
    605       1.1        is int
    606  1.27.2.2  jdolecek aucc_round_blocksize(void *addr, int blk)
    607       1.1        is {
    608      1.24        is 	/* round up to even size */
    609      1.24        is 	return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
    610       1.1        is }
    611       1.1        is 
    612       1.1        is int
    613  1.27.2.2  jdolecek aucc_commit_settings(void *addr)
    614       1.1        is {
    615       1.1        is 	register struct aucc_softc *sc = addr;
    616       1.1        is 	register int i;
    617       1.1        is 
    618       1.1        is 	DPRINTF(("sa_commit.\n"));
    619       1.1        is 
    620       1.1        is 	for (i=0;i<4;i++) {
    621       1.1        is 		custom.aud[i].vol=sc->sc_channel[i].nd_volume;
    622       1.1        is 		custom.aud[i].per=sc->sc_channel[i].nd_per;
    623       1.1        is 	}
    624       1.1        is 
    625       1.1        is 	DPRINTF(("commit done\n"));
    626       1.1        is 
    627       1.1        is 	return(0);
    628       1.1        is }
    629       1.1        is 
    630       1.1        is static int masks[4] = {1,3,7,15}; /* masks for n first channels */
    631       1.1        is static int masks2[4] = {1,2,4,8};
    632       1.1        is 
    633       1.1        is int
    634  1.27.2.2  jdolecek aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    635       1.1        is {
    636       1.8        is 	struct aucc_softc *sc;
    637       1.8        is 	int mask;
    638      1.24        is 	int i, j, k, len;
    639      1.24        is 	u_char *dmap[4];
    640       1.8        is 
    641       1.1        is 
    642       1.8        is 	sc = addr;
    643       1.8        is 	mask = sc->sc_channelmask;
    644       1.1        is 
    645       1.8        is 	dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
    646       1.1        is 
    647       1.1        is 	DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
    648       1.1        is 
    649      1.10        is 	if (sc->sc_channels > 1)
    650      1.24        is 		mask &= masks[sc->sc_channels - 1];
    651      1.10        is 		/* we use first sc_channels channels */
    652      1.24        is 	if (mask == 0) /* active and used channels are disjoint */
    653       1.1        is 		return EINVAL;
    654       1.1        is 
    655      1.24        is 	for (i=0;i<4;i++) {
    656      1.24        is 		/* channels available ? */
    657      1.24        is 		if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
    658       1.1        is 			return EBUSY; /* channel is busy */
    659      1.24        is 		if (channel[i].isaudio == -1)
    660       1.1        is 			return EBUSY; /* system uses them */
    661       1.1        is 	}
    662       1.1        is 
    663       1.1        is 	/* enable interrupt on 1st channel */
    664      1.24        is 	for (i = j = 0; i < AUCC_MAXINT; i++) {
    665      1.24        is 		if (masks2[i] & mask) {
    666       1.1        is 			DPRINTF(("first channel is %d\n",i));
    667       1.1        is 			j=i;
    668       1.1        is 			sc->sc_channel[i].nd_intr=intr;
    669       1.1        is 			sc->sc_channel[i].nd_intrdata=arg;
    670       1.1        is 			break;
    671       1.1        is 		}
    672       1.1        is 	}
    673       1.1        is 
    674       1.8        is 	DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
    675       1.8        is 		dmap[2], dmap[3], mask));
    676       1.8        is 
    677       1.8        is 	/* disable ints, dma for channels, until all parameters set */
    678       1.8        is 	/* XXX dont disable DMA! custom.dmacon=mask;*/
    679      1.24        is 	custom.intreq = mask << INTB_AUD0;
    680      1.24        is 	custom.intena = mask << INTB_AUD0;
    681       1.1        is 
    682       1.1        is 	/* copy data to dma buffer */
    683  1.27.2.2  jdolecek 
    684       1.8        is 	if (sc->sc_channels == 1) {
    685       1.8        is 		dmap[0] =
    686       1.8        is 		dmap[1] =
    687       1.8        is 		dmap[2] =
    688      1.24        is 		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
    689      1.24        is 	}
    690      1.24        is 	else {
    691       1.8        is 		for (k=0; k<4; k++) {
    692      1.24        is 			if (masks2[k+j] & mask)
    693      1.24        is 				dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
    694       1.8        is 		}
    695       1.8        is 	}
    696       1.8        is 
    697       1.8        is 	sc->sc_channel[j].nd_doublebuf ^= 1;
    698       1.8        is 	if (sc->sc_channel[j].nd_doublebuf) {
    699      1.24        is 		dmap[0] += AUDIO_BUF_SIZE;
    700      1.24        is 		dmap[1] += AUDIO_BUF_SIZE;
    701      1.24        is 		dmap[2] += AUDIO_BUF_SIZE;
    702      1.24        is 		dmap[3] += AUDIO_BUF_SIZE;
    703       1.8        is 	}
    704       1.1        is 
    705      1.24        is 	/* compute output length in bytes per channel.
    706      1.24        is 	 * divide by two only for 16bit->8bit conversion.
    707      1.24        is 	 */
    708      1.24        is 	len = cc / sc->sc_channels;
    709      1.24        is 	if (!sc->sc_14bit && (sc->sc_precision == 16))
    710      1.24        is 		len /= 2;
    711      1.24        is 
    712      1.24        is 	/* call audio decoding routine */
    713      1.24        is 	sc->sc_decodefunc (dmap, (u_char *)p, len);
    714       1.1        is 
    715      1.24        is 	/* dma buffers: we use same buffer 4 all channels
    716      1.24        is 	 * write dma location and length
    717      1.24        is 	 */
    718      1.24        is 	for (i = k = 0; i < 4; i++) {
    719       1.8        is 		if (masks2[i] & mask) {
    720       1.1        is 			DPRINTF(("turning channel %d on\n",i));
    721      1.24        is 			/* sc->sc_channel[i].nd_busy=1; */
    722      1.24        is 			channel[i].isaudio = 1;
    723      1.24        is 			channel[i].play_count = 1;
    724      1.24        is 			channel[i].handler = NULL;
    725      1.24        is 			custom.aud[i].per = sc->sc_channel[i].nd_per;
    726      1.24        is 			if (sc->sc_14bit && (i > 1))
    727      1.24        is 				custom.aud[i].vol = 1;
    728      1.24        is 			else
    729      1.24        is 				custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    730       1.8        is 			custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
    731      1.24        is 			custom.aud[i].len = len / 2;
    732      1.24        is 			sc->sc_channel[i].nd_mask = mask;
    733       1.1        is 			DPRINTF(("per is %d, vol is %d, len is %d\n",\
    734       1.8        is 			    sc->sc_channel[i].nd_per,
    735      1.24        is 			    sc->sc_channel[i].nd_volume, len));
    736       1.1        is 		}
    737       1.1        is 	}
    738       1.1        is 
    739       1.1        is 	channel[j].handler=aucc_inthdl;
    740       1.1        is 
    741       1.1        is 	/* enable ints */
    742      1.24        is 	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
    743       1.1        is 
    744      1.24        is 	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
    745       1.1        is 
    746       1.1        is 	/* enable dma */
    747      1.24        is 	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
    748       1.1        is 
    749       1.1        is 	DPRINTF(("enabled dma, mask=0x%x\n",mask));
    750       1.1        is 
    751       1.1        is 	return(0);
    752       1.1        is }
    753       1.1        is 
    754       1.1        is /* ARGSUSED */
    755       1.1        is int
    756  1.27.2.2  jdolecek aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    757       1.1        is {
    758       1.1        is 
    759       1.1        is 	return ENXIO; /* no input */
    760       1.1        is }
    761       1.1        is 
    762       1.1        is int
    763  1.27.2.2  jdolecek aucc_halt_output(void *addr)
    764       1.1        is {
    765       1.1        is 	register struct aucc_softc *sc = addr;
    766       1.1        is 	register int i;
    767       1.1        is 
    768       1.1        is 	/* XXX only halt, if input is also halted ?? */
    769       1.1        is 	/* stop dma, etc */
    770       1.7        is 	custom.intena = AUCC_ALLINTF;
    771       1.7        is 	custom.dmacon = AUCC_ALLDMAF;
    772       1.1        is 	/* mark every busy unit idle */
    773       1.1        is 	for (i=0;i<4;i++) {
    774       1.1        is 		sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0;
    775       1.1        is 		channel[i].isaudio=0;
    776       1.1        is 		channel[i].play_count=0;
    777       1.1        is 	}
    778       1.1        is 
    779       1.1        is 	return(0);
    780       1.1        is }
    781       1.1        is 
    782       1.1        is int
    783  1.27.2.2  jdolecek aucc_halt_input(void *addr)
    784       1.1        is {
    785       1.1        is 	/* no input */
    786       1.1        is 
    787       1.1        is 	return ENXIO;
    788       1.1        is }
    789       1.1        is 
    790       1.1        is int
    791  1.27.2.2  jdolecek aucc_getdev(void *addr, struct audio_device *retp)
    792       1.1        is {
    793       1.1        is         *retp = aucc_device;
    794       1.1        is         return 0;
    795       1.1        is }
    796       1.1        is 
    797       1.1        is int
    798  1.27.2.2  jdolecek aucc_set_port(void *addr, mixer_ctrl_t *cp)
    799       1.1        is {
    800       1.1        is 	register struct aucc_softc *sc = addr;
    801       1.1        is 	register int i,j;
    802       1.1        is 
    803       1.1        is 	DPRINTF(("aucc_set_port: port=%d", cp->dev));
    804       1.1        is 
    805       1.1        is 	switch (cp->type) {
    806       1.1        is 	case AUDIO_MIXER_SET:
    807       1.1        is 		if (cp->dev!=AUCC_CHANNELS)
    808       1.1        is 			return EINVAL;
    809       1.1        is 		i=cp->un.mask;
    810      1.24        is 		if ((i<1) || (i>15))
    811       1.1        is 			return EINVAL;
    812      1.24        is 
    813       1.1        is 		sc->sc_channelmask=i;
    814       1.1        is 		break;
    815       1.1        is 
    816       1.1        is 	case AUDIO_MIXER_VALUE:
    817       1.1        is 		i=cp->un.value.num_channels;
    818      1.24        is 		if ((i<1) || (i>4))
    819       1.1        is 			return EINVAL;
    820       1.1        is 
    821      1.10        is #ifdef __XXXwhatsthat
    822       1.1        is 		if (cp->dev!=AUCC_VOLUME)
    823       1.1        is 			return EINVAL;
    824      1.10        is #endif
    825       1.1        is 
    826       1.1        is 		/* set volume for channel 0..i-1 */
    827      1.21        is 
    828      1.21        is 		/* evil workaround for xanim bug, IMO */
    829      1.21        is 		if ((sc->sc_channels == 1) && (i == 2)) {
    830  1.27.2.2  jdolecek 			sc->sc_channel[0].nd_volume =
    831  1.27.2.2  jdolecek 			    sc->sc_channel[3].nd_volume =
    832      1.21        is 			    cp->un.value.level[0]>>2;
    833  1.27.2.2  jdolecek 			sc->sc_channel[1].nd_volume =
    834  1.27.2.2  jdolecek 			    sc->sc_channel[2].nd_volume =
    835      1.21        is 			    cp->un.value.level[1]>>2;
    836      1.21        is 		} else if (i>1) {
    837      1.10        is 			for (j=0;j<i;j++)
    838      1.10        is 	 			sc->sc_channel[j].nd_volume =
    839      1.10        is 				    cp->un.value.level[j]>>2;
    840      1.21        is 		} else if (sc->sc_channels > 1)
    841      1.10        is 			for (j=0; j<sc->sc_channels; j++)
    842      1.10        is 	 			sc->sc_channel[j].nd_volume =
    843      1.10        is 				    cp->un.value.level[0]>>2;
    844      1.10        is 		else
    845      1.10        is 			for (j=0; j<4; j++)
    846      1.10        is 	 			sc->sc_channel[j].nd_volume =
    847      1.10        is 				    cp->un.value.level[0]>>2;
    848      1.10        is 		break;
    849       1.1        is 
    850       1.1        is 	default:
    851       1.1        is 		return EINVAL;
    852       1.1        is 		break;
    853       1.1        is 	}
    854       1.1        is 	return 0;
    855       1.1        is }
    856       1.1        is 
    857       1.1        is 
    858       1.1        is int
    859  1.27.2.2  jdolecek aucc_get_port(void *addr, mixer_ctrl_t *cp)
    860       1.1        is {
    861       1.1        is 	register struct aucc_softc *sc = addr;
    862       1.1        is 	register int i,j;
    863       1.1        is 
    864       1.1        is 	DPRINTF(("aucc_get_port: port=%d", cp->dev));
    865       1.1        is 
    866       1.1        is 	switch (cp->type) {
    867       1.1        is 	case AUDIO_MIXER_SET:
    868       1.1        is 		if (cp->dev!=AUCC_CHANNELS)
    869       1.1        is 			return EINVAL;
    870       1.1        is 		cp->un.mask=sc->sc_channelmask;
    871       1.1        is 		break;
    872       1.1        is 
    873       1.1        is 	case AUDIO_MIXER_VALUE:
    874       1.1        is 		i = cp->un.value.num_channels;
    875       1.1        is 		if ((i<1)||(i>4))
    876       1.1        is 			return EINVAL;
    877       1.1        is 
    878       1.1        is 		for (j=0;j<i;j++)
    879      1.10        is 			cp->un.value.level[j] =
    880      1.10        is 			    (sc->sc_channel[j].nd_volume<<2) +
    881      1.10        is 			    (sc->sc_channel[j].nd_volume>>4);
    882       1.1        is 		break;
    883       1.1        is 
    884       1.1        is 	default:
    885       1.1        is 		return EINVAL;
    886       1.1        is 	}
    887       1.1        is 	return 0;
    888       1.1        is }
    889       1.1        is 
    890      1.16  augustss 
    891      1.16  augustss int
    892  1.27.2.2  jdolecek aucc_get_props(void *addr)
    893      1.16  augustss {
    894      1.16  augustss 	return 0;
    895      1.16  augustss }
    896       1.1        is 
    897       1.1        is int
    898  1.27.2.2  jdolecek aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip)
    899       1.1        is {
    900       1.1        is 	register int i;
    901       1.1        is 
    902       1.1        is 	switch(dip->index) {
    903       1.1        is 	case AUCC_CHANNELS:
    904       1.1        is 		dip->type = AUDIO_MIXER_SET;
    905       1.1        is 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    906       1.1        is 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    907       1.1        is                 strcpy(dip->label.name, AudioNspeaker);
    908       1.1        is 		for (i=0;i<16;i++) {
    909       1.1        is 			sprintf(dip->un.s.member[i].label.name,
    910       1.1        is 			    "channelmask%d", i);
    911       1.1        is 			dip->un.s.member[i].mask = i;
    912       1.1        is 		}
    913       1.1        is 		dip->un.s.num_mem = 16;
    914       1.1        is 		break;
    915       1.1        is 
    916       1.1        is 	case AUCC_VOLUME:
    917       1.1        is 		dip->type = AUDIO_MIXER_VALUE;
    918       1.1        is 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    919       1.1        is 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    920      1.20  augustss 		strcpy(dip->label.name, AudioNmaster);
    921       1.1        is 		dip->un.v.num_channels = 4;
    922       1.1        is 		strcpy(dip->un.v.units.name, AudioNvolume);
    923       1.1        is 		break;
    924       1.1        is 
    925       1.1        is 	case AUCC_OUTPUT_CLASS:
    926       1.1        is 		dip->type = AUDIO_MIXER_CLASS;
    927       1.1        is 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    928       1.1        is 		dip->next = dip->prev = AUDIO_MIXER_LAST;
    929      1.19   mycroft 		strcpy(dip->label.name, AudioCoutputs);
    930       1.1        is 		break;
    931      1.20  augustss 
    932       1.1        is 	default:
    933       1.1        is 		return ENXIO;
    934       1.1        is 	}
    935       1.1        is 
    936       1.1        is 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    937       1.1        is 
    938       1.1        is 	return(0);
    939       1.1        is }
    940       1.1        is 
    941       1.1        is 
    942       1.1        is /* audio int handler */
    943       1.1        is void
    944       1.1        is aucc_inthdl(int ch)
    945       1.1        is {
    946       1.1        is 	register int i;
    947       1.1        is 	register int mask=aucc->sc_channel[ch].nd_mask;
    948       1.1        is 
    949       1.1        is 	/* for all channels in this maskgroup:
    950  1.27.2.2  jdolecek 	   disable dma, int
    951       1.1        is 	   mark idle */
    952       1.1        is 	DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask));
    953       1.1        is 
    954       1.7        is 	custom.intreq=mask<<INTB_AUD0; /* clear request */
    955      1.24        is 	/*
    956      1.24        is 	 * XXX: maybe we can leave ints and/or DMA on,
    957      1.24        is 	 * if another sample has to be played?
    958      1.24        is 	 */
    959       1.7        is 	custom.intena=mask<<INTB_AUD0;
    960       1.1        is 	/*
    961  1.27.2.2  jdolecek 	 * XXX custom.dmacon=mask; NO!!!
    962  1.27.2.2  jdolecek 	 */
    963      1.24        is 	for (i=0; i<4; i++) {
    964       1.1        is 		if (masks2[i]&&mask) {
    965       1.1        is 			DPRINTF(("marking channel %d idle\n",i));
    966       1.1        is 			aucc->sc_channel[i].nd_busy=0;
    967       1.1        is 			aucc->sc_channel[i].nd_mask=0;
    968       1.1        is 			channel[i].isaudio=channel[i].play_count=0;
    969       1.1        is 		}
    970       1.1        is 	}
    971       1.1        is 
    972       1.1        is 	/* call handler */
    973       1.1        is 	if (aucc->sc_channel[ch].nd_intr) {
    974       1.1        is 		DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
    975      1.24        is 		(*(aucc->sc_channel[ch].nd_intr))
    976      1.24        is 		    (aucc->sc_channel[ch].nd_intrdata);
    977       1.1        is 	}
    978      1.24        is 	else
    979      1.24        is 		DPRINTF(("zero int handler\n"));
    980       1.1        is 	DPRINTF(("ints done\n"));
    981       1.1        is }
    982       1.1        is 
    983       1.1        is 
    984       1.1        is 
    985       1.1        is 
    986       1.1        is /* transform frequency to period, adjust bounds */
    987       1.1        is static u_int
    988  1.27.2.2  jdolecek freqtoper(u_int freq)
    989  1.27.2.2  jdolecek {
    990       1.1        is 	u_int per=eclockfreq*5/freq;
    991  1.27.2.2  jdolecek 
    992       1.1        is 	if (per<124)
    993       1.1        is 		per=124; /* must have at least 124 ticks between samples */
    994       1.1        is 
    995       1.1        is 	return per;
    996       1.1        is }
    997       1.1        is 
    998       1.1        is /* transform period to frequency */
    999       1.1        is static u_int
   1000  1.27.2.2  jdolecek pertofreq(u_int per)
   1001  1.27.2.2  jdolecek {
   1002      1.24        is 	u_int freq=eclockfreq*5/per;
   1003      1.24        is 
   1004      1.24        is 	return freq;
   1005      1.24        is }
   1006      1.24        is 
   1007  1.27.2.2  jdolecek static void
   1008  1.27.2.2  jdolecek aucc_decode_slinear8_1ch(u_char **dmap, u_char *p, int i)
   1009  1.27.2.2  jdolecek {
   1010      1.24        is 	memcpy (dmap[0], p, i);
   1011      1.24        is }
   1012      1.24        is 
   1013  1.27.2.2  jdolecek static void
   1014  1.27.2.2  jdolecek aucc_decode_slinear8_2ch(u_char **dmap, u_char *p, int i)
   1015  1.27.2.2  jdolecek {
   1016      1.24        is 	u_char *ch0 = dmap[0];
   1017      1.24        is 	u_char *ch1 = dmap[1];
   1018      1.24        is 
   1019      1.24        is 	while (i--) {
   1020      1.24        is 		*ch0++ = *p++;
   1021      1.24        is 		*ch1++ = *p++;
   1022      1.24        is 	}
   1023      1.24        is }
   1024      1.24        is 
   1025  1.27.2.2  jdolecek static void
   1026  1.27.2.2  jdolecek aucc_decode_slinear8_3ch(u_char **dmap, u_char *p, int i)
   1027  1.27.2.2  jdolecek {
   1028      1.24        is 	u_char *ch0 = dmap[0];
   1029      1.24        is 	u_char *ch1 = dmap[1];
   1030      1.24        is 	u_char *ch2 = dmap[2];
   1031      1.24        is 
   1032      1.24        is 	while (i--) {
   1033      1.24        is 		*ch0++ = *p++;
   1034      1.24        is 		*ch1++ = *p++;
   1035      1.24        is 		*ch2++ = *p++;
   1036      1.24        is 	}
   1037      1.24        is }
   1038      1.24        is 
   1039  1.27.2.2  jdolecek static void
   1040  1.27.2.2  jdolecek aucc_decode_slinear8_4ch(u_char **dmap, u_char *p, int i)
   1041  1.27.2.2  jdolecek {
   1042      1.24        is 	u_char *ch0 = dmap[0];
   1043      1.24        is 	u_char *ch1 = dmap[1];
   1044      1.24        is 	u_char *ch2 = dmap[2];
   1045      1.24        is 	u_char *ch3 = dmap[3];
   1046      1.24        is 
   1047      1.24        is 	while (i--) {
   1048      1.24        is 		*ch0++ = *p++;
   1049      1.24        is 		*ch1++ = *p++;
   1050      1.24        is 		*ch2++ = *p++;
   1051      1.24        is 		*ch3++ = *p++;
   1052      1.24        is 	}
   1053      1.24        is }
   1054      1.24        is 
   1055      1.24        is static void
   1056  1.27.2.2  jdolecek aucc_decode_ulinear8_1ch(u_char **dmap, u_char *p, int i)
   1057      1.24        is {
   1058      1.24        is 	u_char *ch0 = dmap[0];
   1059      1.24        is 
   1060      1.24        is 	while (i--)
   1061      1.24        is 		*ch0++ = *p++ - 128;
   1062      1.24        is }
   1063      1.24        is 
   1064      1.24        is static void
   1065  1.27.2.2  jdolecek aucc_decode_ulinear8_2ch(u_char **dmap, u_char *p, int i)
   1066       1.1        is {
   1067      1.24        is 	u_char *ch0 = dmap[0];
   1068      1.24        is 	u_char *ch1 = dmap[1];
   1069      1.24        is 
   1070      1.24        is 	while (i--) {
   1071      1.24        is 		*ch0++ = *p++ - 128;
   1072      1.24        is 		*ch1++ = *p++ - 128;
   1073      1.24        is 	}
   1074      1.24        is }
   1075      1.24        is 
   1076      1.24        is static void
   1077  1.27.2.2  jdolecek aucc_decode_ulinear8_3ch(u_char **dmap, u_char *p, int i)
   1078      1.24        is {
   1079      1.24        is 	u_char *ch0 = dmap[0];
   1080      1.24        is 	u_char *ch1 = dmap[1];
   1081      1.24        is 	u_char *ch2 = dmap[2];
   1082      1.24        is 
   1083      1.24        is 	while (i--) {
   1084      1.24        is 		*ch0++ = *p++ - 128;
   1085      1.24        is 		*ch1++ = *p++ - 128;
   1086      1.24        is 		*ch2++ = *p++ - 128;
   1087      1.24        is 	}
   1088      1.24        is }
   1089      1.24        is 
   1090      1.24        is static void
   1091  1.27.2.2  jdolecek aucc_decode_ulinear8_4ch(u_char **dmap, u_char *p, int i)
   1092      1.24        is {
   1093      1.24        is 	u_char *ch0 = dmap[0];
   1094      1.24        is 	u_char *ch1 = dmap[1];
   1095      1.24        is 	u_char *ch2 = dmap[2];
   1096      1.24        is 	u_char *ch3 = dmap[3];
   1097      1.24        is 
   1098      1.24        is 	while (i--) {
   1099      1.24        is 		*ch0++ = *p++ - 128;
   1100      1.24        is 		*ch1++ = *p++ - 128;
   1101      1.24        is 		*ch2++ = *p++ - 128;
   1102      1.24        is 		*ch3++ = *p++ - 128;
   1103      1.24        is 	}
   1104      1.24        is }
   1105      1.24        is 
   1106      1.24        is 
   1107      1.24        is static void
   1108  1.27.2.2  jdolecek aucc_decode_ulaw_1ch(u_char **dmap, u_char *p, int i)
   1109      1.24        is {
   1110      1.24        is 	u_char *ch0 = dmap[0];
   1111      1.24        is 
   1112      1.24        is 	while (i--)
   1113      1.24        is 		*ch0++ = ulaw_to_lin[*p++];
   1114      1.24        is }
   1115      1.24        is 
   1116      1.24        is static void
   1117  1.27.2.2  jdolecek aucc_decode_ulaw_2ch(u_char **dmap, u_char *p, int i)
   1118      1.24        is {
   1119      1.24        is 	u_char *ch0 = dmap[0];
   1120      1.24        is 	u_char *ch1 = dmap[1];
   1121      1.24        is 
   1122      1.24        is 	while (i--) {
   1123      1.24        is 		*ch0++ = ulaw_to_lin[*p++];
   1124      1.24        is 		*ch1++ = ulaw_to_lin[*p++];
   1125      1.24        is 	}
   1126      1.24        is }
   1127       1.1        is 
   1128      1.24        is static void
   1129  1.27.2.2  jdolecek aucc_decode_ulaw_3ch(u_char **dmap, u_char *p, int i)
   1130      1.24        is {
   1131      1.24        is 	u_char *ch0 = dmap[0];
   1132      1.24        is 	u_char *ch1 = dmap[1];
   1133      1.24        is 	u_char *ch2 = dmap[2];
   1134      1.24        is 
   1135      1.24        is 	while (i--) {
   1136      1.24        is 		*ch0++ = ulaw_to_lin[*p++];
   1137      1.24        is 		*ch1++ = ulaw_to_lin[*p++];
   1138      1.24        is 		*ch2++ = ulaw_to_lin[*p++];
   1139      1.24        is 	}
   1140      1.24        is }
   1141       1.1        is 
   1142      1.24        is static void
   1143  1.27.2.2  jdolecek aucc_decode_ulaw_4ch(u_char **dmap, u_char *p, int i)
   1144      1.24        is {
   1145      1.24        is 	u_char *ch0 = dmap[0];
   1146      1.24        is 	u_char *ch1 = dmap[1];
   1147      1.24        is 	u_char *ch2 = dmap[2];
   1148      1.24        is 	u_char *ch3 = dmap[3];
   1149      1.24        is 
   1150      1.24        is 	while (i--) {
   1151      1.24        is 		*ch0++ = ulaw_to_lin[*p++];
   1152      1.24        is 		*ch1++ = ulaw_to_lin[*p++];
   1153      1.24        is 		*ch2++ = ulaw_to_lin[*p++];
   1154      1.24        is 		*ch3++ = ulaw_to_lin[*p++];
   1155      1.24        is 	}
   1156       1.1        is }
   1157       1.1        is 
   1158       1.1        is 
   1159      1.24        is /* 14bit output */
   1160      1.24        is static void
   1161  1.27.2.2  jdolecek aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i)
   1162      1.24        is {
   1163      1.24        is 	u_char *ch0 = dmap[0];
   1164      1.24        is 	u_char *ch3 = dmap[1]; /* XXX should be 3 */
   1165      1.24        is 
   1166      1.24        is 	while (i--) {
   1167      1.24        is 		*ch0++ = *p++;
   1168      1.24        is 		*ch3++ = *p++ >> 2;
   1169      1.24        is 	}
   1170      1.24        is }
   1171       1.1        is 
   1172      1.24        is /* 14bit stereo output */
   1173      1.24        is static void
   1174  1.27.2.2  jdolecek aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i)
   1175      1.24        is {
   1176      1.24        is 	u_char *ch0 = dmap[0];
   1177      1.24        is 	u_char *ch1 = dmap[1];
   1178      1.24        is 	u_char *ch2 = dmap[2];
   1179      1.24        is 	u_char *ch3 = dmap[3];
   1180      1.24        is 
   1181      1.24        is 	while (i--) {
   1182      1.24        is 		*ch0++ = *p++;
   1183      1.24        is 		*ch3++ = *p++ >> 2;
   1184      1.24        is 		*ch1++ = *p++;
   1185      1.24        is 		*ch2++ = *p++ >> 2;
   1186      1.24        is 	}
   1187      1.24        is }
   1188      1.24        is 
   1189      1.24        is static void
   1190  1.27.2.2  jdolecek aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i)
   1191      1.24        is {
   1192      1.24        is 	u_char *ch0 = dmap[0];
   1193      1.24        is 	u_char *ch1 = dmap[1];
   1194      1.24        is 	u_char *ch2 = dmap[2];
   1195      1.24        is 
   1196      1.24        is 	while (i--) {
   1197      1.24        is 		*ch0++ = *p++; p++;
   1198      1.24        is 		*ch1++ = *p++; p++;
   1199      1.24        is 		*ch2++ = *p++; p++;
   1200      1.24        is 	}
   1201      1.24        is }
   1202      1.24        is 
   1203      1.24        is static void
   1204  1.27.2.2  jdolecek aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i)
   1205       1.1        is {
   1206      1.24        is 	u_char *ch0 = dmap[0];
   1207      1.24        is 	u_char *ch1 = dmap[1];
   1208      1.24        is 	u_char *ch2 = dmap[2];
   1209      1.24        is 	u_char *ch3 = dmap[3];
   1210      1.24        is 
   1211      1.24        is 	while (i--) {
   1212      1.24        is 		*ch0++ = *p++; p++;
   1213      1.24        is 		*ch1++ = *p++; p++;
   1214      1.24        is 		*ch2++ = *p++; p++;
   1215      1.24        is 		*ch3++ = *p++; p++;
   1216      1.24        is 	}
   1217      1.24        is }
   1218       1.8        is 
   1219      1.24        is /* 14bit output, swap bytes */
   1220      1.24        is static void
   1221  1.27.2.2  jdolecek aucc_decode_slinear16sw_1ch(u_char **dmap, u_char *p, int i)
   1222      1.24        is {
   1223      1.24        is 	u_char *ch0 = dmap[0];
   1224      1.26    mhitch 	u_char *ch3 = dmap[1];	/* XXX should be 3 */
   1225       1.1        is 
   1226      1.24        is 	while (i--) {
   1227      1.24        is 		*ch3++ = *p++ >> 2;
   1228      1.24        is 		*ch0++ = *p++;
   1229      1.24        is 	}
   1230      1.24        is }
   1231       1.1        is 
   1232      1.24        is static void
   1233  1.27.2.2  jdolecek aucc_decode_slinear16sw_2ch(u_char **dmap, u_char *p, int i)
   1234      1.24        is {
   1235      1.24        is 	u_char *ch0 = dmap[0];
   1236      1.24        is 	u_char *ch1 = dmap[1];
   1237      1.24        is 	u_char *ch2 = dmap[2];
   1238      1.24        is 	u_char *ch3 = dmap[3];
   1239      1.24        is 
   1240      1.24        is 	while (i--) {
   1241      1.24        is 		*ch3++ = *p++ >> 2;
   1242      1.24        is 		*ch0++ = *p++;
   1243      1.24        is 		*ch2++ = *p++ >> 2;
   1244      1.24        is 		*ch1++ = *p++;
   1245      1.24        is 	}
   1246      1.24        is }
   1247       1.1        is 
   1248      1.24        is static void
   1249  1.27.2.2  jdolecek aucc_decode_slinear16sw_3ch(u_char **dmap, u_char *p, int i)
   1250      1.24        is {
   1251      1.24        is 	u_char *ch0 = dmap[0];
   1252      1.24        is 	u_char *ch1 = dmap[1];
   1253      1.24        is 	u_char *ch2 = dmap[2];
   1254      1.24        is 
   1255      1.24        is 	while (i--) {
   1256      1.24        is 		p++; *ch0++ = *p++;
   1257      1.24        is 		p++; *ch1++ = *p++;
   1258      1.24        is 		p++; *ch2++ = *p++;
   1259       1.1        is 	}
   1260      1.24        is }
   1261       1.1        is 
   1262      1.24        is static void
   1263  1.27.2.2  jdolecek aucc_decode_slinear16sw_4ch(u_char **dmap, u_char *p, int i)
   1264      1.24        is {
   1265      1.24        is 	u_char *ch0 = dmap[0];
   1266      1.24        is 	u_char *ch1 = dmap[1];
   1267      1.24        is 	u_char *ch2 = dmap[2];
   1268      1.24        is 	u_char *ch3 = dmap[3];
   1269      1.24        is 
   1270      1.24        is 	while (i--) {
   1271      1.24        is 		p++; *ch0++ = *p++;
   1272      1.24        is 		p++; *ch1++ = *p++;
   1273      1.24        is 		p++; *ch2++ = *p++;
   1274      1.24        is 		p++; *ch3++ = *p++;
   1275      1.24        is 	}
   1276       1.1        is }
   1277      1.24        is 
   1278       1.1        is 
   1279       1.1        is #endif /* NAUCC > 0 */
   1280