Home | History | Annotate | Line # | Download | only in dev
      1  1.48     isaki /*	$NetBSD: aucc.c,v 1.48 2020/02/29 06:03:55 isaki 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  * - channel allocation is wrong for 14bit mono
     39  1.24        is  * - perhaps use a calibration table for better 14bit output
     40  1.40     lukem  * - set 31 kHz AGA video mode to allow 44.1 kHz even if grfcc is missing
     41  1.24        is  *	in the kernel
     42  1.24        is  * - 14bit output requires maximum volume
     43  1.24        is  */
     44  1.24        is 
     45   1.1        is #include "aucc.h"
     46   1.1        is #if NAUCC > 0
     47  1.30   aymeric 
     48  1.30   aymeric #include <sys/cdefs.h>
     49  1.48     isaki __KERNEL_RCSID(0, "$NetBSD: aucc.c,v 1.48 2020/02/29 06:03:55 isaki Exp $");
     50   1.5        is 
     51   1.1        is #include <sys/param.h>
     52   1.1        is #include <sys/systm.h>
     53   1.1        is #include <sys/errno.h>
     54   1.1        is #include <sys/ioctl.h>
     55   1.1        is #include <sys/device.h>
     56   1.1        is #include <sys/proc.h>
     57   1.1        is #include <machine/cpu.h>
     58   1.1        is 
     59   1.1        is #include <sys/audioio.h>
     60  1.45     isaki #include <dev/audio/audio_if.h>
     61  1.45     isaki #include <dev/audio/audiovar.h>	/* for AUDIO_MIN_FREQUENCY */
     62  1.45     isaki 
     63   1.1        is #include <amiga/amiga/cc.h>
     64   1.1        is #include <amiga/amiga/custom.h>
     65   1.1        is #include <amiga/amiga/device.h>
     66   1.1        is #include <amiga/dev/auccvar.h>
     67  1.27        is 
     68  1.27        is #include "opt_lev6_defer.h"
     69   1.1        is 
     70   1.7        is 
     71   1.7        is #ifdef LEV6_DEFER
     72   1.7        is #define AUCC_MAXINT 3
     73   1.7        is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
     74   1.7        is #else
     75   1.7        is #define AUCC_MAXINT 4
     76   1.7        is #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
     77   1.7        is #endif
     78   1.7        is /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
     79   1.7        is #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
     80   1.7        is 
     81   1.1        is #ifdef AUDIO_DEBUG
     82  1.29   aymeric /*extern printf(const char *,...);*/
     83   1.1        is int     auccdebug = 1;
     84   1.1        is #define DPRINTF(x)      if (auccdebug) printf x
     85   1.1        is #else
     86   1.1        is #define DPRINTF(x)
     87   1.1        is #endif
     88   1.1        is 
     89   1.1        is /* clock frequency.. */
     90  1.29   aymeric extern int eclockfreq;
     91   1.1        is 
     92   1.1        is 
     93   1.1        is /* hw audio ch */
     94   1.1        is extern struct audio_channel channel[4];
     95   1.1        is 
     96   1.1        is 
     97   1.1        is /*
     98   1.1        is  * Software state.
     99   1.1        is  */
    100   1.1        is struct aucc_softc {
    101   1.1        is 	aucc_data_t sc_channel[4];	/* per channel freq, ... */
    102   1.1        is 	u_int	sc_encoding;		/* encoding AUDIO_ENCODING_.*/
    103   1.1        is 	int	sc_channels;		/* # of channels used */
    104  1.24        is 	int	sc_precision;		/* 8 or 16 bits */
    105  1.24        is 	int	sc_14bit;		/* 14bit output enabled */
    106   1.1        is 
    107   1.1        is 	int	sc_intrcnt;		/* interrupt count */
    108  1.37      kent 	int	sc_channelmask;		/* which channels are used ? */
    109  1.29   aymeric 	void (*sc_decodefunc)(u_char **, u_char *, int);
    110  1.24        is 				/* pointer to format conversion routine */
    111  1.41  jmcneill 
    112  1.41  jmcneill 	kmutex_t sc_lock;
    113  1.41  jmcneill 	kmutex_t sc_intr_lock;
    114   1.1        is };
    115   1.1        is 
    116   1.1        is /* interrupt interfaces */
    117  1.29   aymeric void aucc_inthdl(int);
    118   1.1        is 
    119   1.1        is /* forward declarations */
    120  1.29   aymeric static int init_aucc(struct aucc_softc *);
    121  1.29   aymeric static u_int freqtoper(u_int);
    122  1.29   aymeric static u_int pertofreq(u_int);
    123   1.1        is 
    124   1.1        is /* autoconfiguration driver */
    125  1.42       chs void	auccattach(device_t, device_t, void *);
    126  1.42       chs int	auccmatch(device_t, cfdata_t, void *);
    127   1.1        is 
    128  1.42       chs CFATTACH_DECL_NEW(aucc, sizeof(struct aucc_softc),
    129  1.32   thorpej     auccmatch, auccattach, NULL, NULL);
    130   1.1        is 
    131   1.1        is struct audio_device aucc_device = {
    132   1.1        is 	"Amiga-audio",
    133  1.24        is 	"2.0",
    134   1.1        is 	"aucc"
    135   1.1        is };
    136   1.1        is 
    137   1.1        is 
    138  1.37      kent struct aucc_softc *aucc = NULL;
    139   1.1        is 
    140   1.1        is 
    141   1.1        is /*
    142   1.1        is  * Define our interface to the higher level audio driver.
    143   1.1        is  */
    144  1.29   aymeric int	aucc_open(void *, int);
    145  1.29   aymeric void	aucc_close(void *);
    146  1.36      kent int	aucc_set_out_sr(void *, u_int);
    147  1.45     isaki int	aucc_query_format(void *, audio_format_query_t *);
    148  1.36      kent int	aucc_round_blocksize(void *, int, int, const audio_params_t *);
    149  1.29   aymeric int	aucc_commit_settings(void *);
    150  1.29   aymeric int	aucc_start_output(void *, void *, int, void (*)(void *), void *);
    151  1.29   aymeric int	aucc_start_input(void *, void *, int, void (*)(void *), void *);
    152  1.29   aymeric int	aucc_halt_output(void *);
    153  1.29   aymeric int	aucc_halt_input(void *);
    154  1.29   aymeric int	aucc_getdev(void *, struct audio_device *);
    155  1.29   aymeric int	aucc_set_port(void *, mixer_ctrl_t *);
    156  1.29   aymeric int	aucc_get_port(void *, mixer_ctrl_t *);
    157  1.29   aymeric int	aucc_query_devinfo(void *, mixer_devinfo_t *);
    158  1.29   aymeric void	aucc_encode(int, int, int, int, u_char *, u_short **);
    159  1.45     isaki int	aucc_set_format(void *, int,
    160  1.45     isaki 			const audio_params_t *, const audio_params_t *,
    161  1.45     isaki 			audio_filter_reg_t *, audio_filter_reg_t *);
    162  1.29   aymeric int	aucc_get_props(void *);
    163  1.41  jmcneill void	aucc_get_locks(void *, kmutex_t **, kmutex_t **);
    164  1.29   aymeric 
    165  1.29   aymeric 
    166  1.29   aymeric static void aucc_decode_slinear16_1ch(u_char **, u_char *, int);
    167  1.29   aymeric static void aucc_decode_slinear16_2ch(u_char **, u_char *, int);
    168  1.29   aymeric static void aucc_decode_slinear16_3ch(u_char **, u_char *, int);
    169  1.29   aymeric static void aucc_decode_slinear16_4ch(u_char **, u_char *, int);
    170  1.29   aymeric 
    171  1.24        is 
    172  1.35      yamt const struct audio_hw_if sa_hw_if = {
    173  1.44     isaki 	.open			= aucc_open,
    174  1.44     isaki 	.close			= aucc_close,
    175  1.45     isaki 	.query_format		= aucc_query_format,
    176  1.45     isaki 	.set_format		= aucc_set_format,
    177  1.44     isaki 	.round_blocksize	= aucc_round_blocksize,
    178  1.44     isaki 	.commit_settings	= aucc_commit_settings,
    179  1.44     isaki 	.start_output		= aucc_start_output,
    180  1.44     isaki 	.start_input		= aucc_start_input,
    181  1.44     isaki 	.halt_output		= aucc_halt_output,
    182  1.44     isaki 	.halt_input		= aucc_halt_input,
    183  1.44     isaki 	.getdev			= aucc_getdev,
    184  1.44     isaki 	.set_port		= aucc_set_port,
    185  1.44     isaki 	.get_port		= aucc_get_port,
    186  1.44     isaki 	.query_devinfo		= aucc_query_devinfo,
    187  1.44     isaki 	.get_props		= aucc_get_props,
    188  1.44     isaki 	.get_locks		= aucc_get_locks,
    189   1.1        is };
    190   1.1        is 
    191  1.45     isaki /*
    192  1.45     isaki  * XXX *1 How lower limit of frequency should be?  same as audio(4)?
    193  1.45     isaki  * XXX *2 Should avoid a magic number at the upper limit of frequency.
    194  1.45     isaki  * XXX *3 In fact, there is a number in this range that have minimal errors.
    195  1.45     isaki  *        It would be better if there is a mechanism which such frequency
    196  1.45     isaki  *        is prioritized.
    197  1.45     isaki  * XXX *4 3/4ch modes use 8bits, 1/2ch modes use 14bits,
    198  1.45     isaki  *        so I imagined that 1/2ch modes are better.
    199  1.45     isaki  */
    200  1.45     isaki #define AUCC_FORMAT(prio, ch, chmask) \
    201  1.45     isaki 	{ \
    202  1.45     isaki 		.mode		= AUMODE_PLAY, \
    203  1.45     isaki 		.priority	= (prio), \
    204  1.45     isaki 		.encoding	= AUDIO_ENCODING_SLINEAR_BE, \
    205  1.45     isaki 		.validbits	= 16, \
    206  1.45     isaki 		.precision	= 16, \
    207  1.45     isaki 		.channels	= (ch), \
    208  1.45     isaki 		.channel_mask	= (chmask), \
    209  1.45     isaki 		.frequency_type	= 0, \
    210  1.45     isaki 		.frequency	= { AUDIO_MIN_FREQUENCY, 28867 }, \
    211  1.45     isaki 	}
    212  1.45     isaki static const struct audio_format aucc_formats[] = {
    213  1.45     isaki 	AUCC_FORMAT(1, 1, AUFMT_MONAURAL),
    214  1.45     isaki 	AUCC_FORMAT(1, 2, AUFMT_STEREO),
    215  1.45     isaki 	AUCC_FORMAT(0, 3, AUFMT_UNKNOWN_POSITION),
    216  1.45     isaki 	AUCC_FORMAT(0, 4, AUFMT_UNKNOWN_POSITION),
    217  1.45     isaki };
    218  1.45     isaki #define AUCC_NFORMATS __arraycount(aucc_formats)
    219  1.45     isaki 
    220   1.1        is /* autoconfig routines */
    221   1.1        is 
    222   1.1        is int
    223  1.42       chs auccmatch(device_t parent, cfdata_t cf, void *aux)
    224   1.1        is {
    225  1.25    kleink 	static int aucc_matched = 0;
    226  1.25    kleink 
    227  1.25    kleink 	if (!matchname((char *)aux, "aucc") ||
    228   1.1        is #ifdef DRACO
    229  1.25    kleink 	    is_draco() ||
    230   1.1        is #endif
    231  1.25    kleink 	    aucc_matched)
    232  1.25    kleink 		return 0;
    233   1.1        is 
    234  1.25    kleink 	aucc_matched = 1;
    235  1.25    kleink 	return 1;
    236   1.1        is }
    237   1.1        is 
    238   1.1        is /*
    239   1.1        is  * Audio chip found.
    240   1.1        is  */
    241   1.1        is void
    242  1.42       chs auccattach(device_t parent, device_t self, void *args)
    243   1.1        is {
    244  1.37      kent 	struct aucc_softc *sc;
    245  1.37      kent 	int i;
    246   1.1        is 
    247  1.42       chs 	sc = device_private(self);
    248   1.1        is 	printf("\n");
    249   1.1        is 
    250  1.37      kent 	if ((i=init_aucc(sc))) {
    251   1.1        is 		printf("audio: no chipmem\n");
    252   1.1        is 		return;
    253   1.1        is 	}
    254   1.1        is 
    255  1.42       chs 	audio_attach_mi(&sa_hw_if, sc, self);
    256   1.1        is }
    257   1.1        is 
    258   1.1        is 
    259   1.1        is static int
    260  1.29   aymeric init_aucc(struct aucc_softc *sc)
    261   1.1        is {
    262  1.37      kent 	int i, err;
    263   1.1        is 
    264  1.37      kent 	err = 0;
    265   1.1        is 	/* init values per channel */
    266  1.37      kent 	for (i = 0; i < 4; i++) {
    267  1.37      kent 		sc->sc_channel[i].nd_freq = 8000;
    268  1.37      kent 		sc->sc_channel[i].nd_per = freqtoper(8000);
    269  1.37      kent 		sc->sc_channel[i].nd_busy = 0;
    270  1.37      kent 		sc->sc_channel[i].nd_dma = alloc_chipmem(AUDIO_BUF_SIZE*2);
    271  1.37      kent 		if (sc->sc_channel[i].nd_dma == NULL)
    272  1.37      kent 			err = 1;
    273  1.37      kent 		sc->sc_channel[i].nd_dmalength = 0;
    274  1.37      kent 		sc->sc_channel[i].nd_volume = 64;
    275  1.37      kent 		sc->sc_channel[i].nd_intr = NULL;
    276  1.37      kent 		sc->sc_channel[i].nd_intrdata = NULL;
    277  1.37      kent 		sc->sc_channel[i].nd_doublebuf = 0;
    278  1.34       wiz 		DPRINTF(("DMA buffer for channel %d is %p\n", i,
    279   1.1        is 		    sc->sc_channel[i].nd_dma));
    280   1.1        is 	}
    281   1.1        is 
    282   1.1        is 	if (err) {
    283  1.37      kent 		for (i = 0; i < 4; i++)
    284   1.1        is 			if (sc->sc_channel[i].nd_dma)
    285   1.1        is 				free_chipmem(sc->sc_channel[i].nd_dma);
    286   1.1        is 	}
    287   1.1        is 
    288  1.37      kent 	sc->sc_channels = 1;
    289  1.37      kent 	sc->sc_channelmask = 0xf;
    290  1.45     isaki 	sc->sc_precision = 16;
    291  1.45     isaki 	sc->sc_14bit = 1;
    292  1.45     isaki 	sc->sc_encoding = AUDIO_ENCODING_SLINEAR_BE;
    293  1.45     isaki 	sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    294   1.1        is 
    295  1.34       wiz 	/* clear interrupts and DMA: */
    296   1.7        is 	custom.intena = AUCC_ALLINTF;
    297  1.24        is 	custom.dmacon = AUCC_ALLDMAF;
    298   1.1        is 
    299  1.41  jmcneill 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    300  1.41  jmcneill 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
    301  1.41  jmcneill 
    302   1.1        is 	return err;
    303   1.1        is }
    304   1.1        is 
    305   1.1        is int
    306  1.29   aymeric aucc_open(void *addr, int flags)
    307   1.1        is {
    308  1.37      kent 	struct aucc_softc *sc;
    309  1.16  augustss 	int i;
    310   1.1        is 
    311  1.37      kent 	sc = addr;
    312  1.16  augustss 	DPRINTF(("sa_open: unit %p\n",sc));
    313   1.1        is 
    314  1.37      kent 	for (i = 0; i < AUCC_MAXINT; i++) {
    315  1.37      kent 		sc->sc_channel[i].nd_intr = NULL;
    316  1.37      kent 		sc->sc_channel[i].nd_intrdata = NULL;
    317   1.1        is 	}
    318  1.37      kent 	aucc = sc;
    319  1.37      kent 	sc->sc_channelmask = 0xf;
    320   1.1        is 
    321  1.38  christos 	DPRINTF(("saopen: ok -> sc=%p\n",sc));
    322   1.1        is 
    323  1.37      kent 	return 0;
    324   1.1        is }
    325   1.1        is 
    326   1.1        is void
    327  1.29   aymeric aucc_close(void *addr)
    328   1.1        is {
    329   1.1        is 
    330   1.1        is 	DPRINTF(("sa_close: closed.\n"));
    331   1.1        is }
    332   1.1        is 
    333   1.1        is int
    334  1.36      kent aucc_set_out_sr(void *addr, u_int sr)
    335   1.1        is {
    336  1.37      kent 	struct aucc_softc *sc;
    337   1.1        is 	u_long per;
    338  1.37      kent 	int i;
    339   1.1        is 
    340  1.37      kent 	sc = addr;
    341  1.37      kent 	per = freqtoper(sr);
    342  1.37      kent 	if (per > 0xffff)
    343   1.1        is 		return EINVAL;
    344  1.37      kent 	sr = pertofreq(per);
    345   1.1        is 
    346  1.37      kent 	for (i = 0; i < 4; i++) {
    347  1.37      kent 		sc->sc_channel[i].nd_freq = sr;
    348  1.37      kent 		sc->sc_channel[i].nd_per = per;
    349   1.1        is 	}
    350   1.1        is 
    351  1.37      kent 	return 0;
    352   1.1        is }
    353   1.1        is 
    354   1.1        is int
    355  1.45     isaki aucc_query_format(void *addr, audio_format_query_t *afp)
    356   1.1        is {
    357  1.37      kent 
    358  1.45     isaki 	return audio_query_format(aucc_formats, AUCC_NFORMATS, afp);
    359   1.1        is }
    360   1.1        is 
    361   1.1        is int
    362  1.45     isaki aucc_set_format(void *addr, int setmode,
    363  1.45     isaki 	const audio_params_t *p, const audio_params_t *r,
    364  1.45     isaki 	audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
    365   1.1        is {
    366  1.37      kent 	struct aucc_softc *sc;
    367   1.8        is 
    368  1.37      kent 	sc = addr;
    369  1.45     isaki 	KASSERT((setmode & AUMODE_RECORD) == 0);
    370   1.8        is 
    371   1.9        is #ifdef AUCCDEBUG
    372  1.45     isaki 	printf("%s(setmode 0x%x,"
    373  1.45     isaki 	    "enc %u bits %u, chn %u, sr %u)\n", setmode,
    374  1.45     isaki 	    p->encoding, p->precision, p->channels, p->sample_rate);
    375  1.24        is #endif
    376  1.24        is 
    377  1.45     isaki 	switch (p->channels) {
    378  1.45     isaki 	case 1:
    379  1.45     isaki 		sc->sc_decodefunc = aucc_decode_slinear16_1ch;
    380  1.45     isaki 		break;
    381  1.45     isaki 	case 2:
    382  1.45     isaki 		sc->sc_decodefunc = aucc_decode_slinear16_2ch;
    383  1.45     isaki 		break;
    384  1.45     isaki 	case 3:
    385  1.45     isaki 		sc->sc_decodefunc = aucc_decode_slinear16_3ch;
    386  1.24        is 		break;
    387  1.45     isaki 	case 4:
    388  1.45     isaki 		sc->sc_decodefunc = aucc_decode_slinear16_4ch;
    389  1.24        is 		break;
    390   1.1        is 	default:
    391   1.1        is 		return EINVAL;
    392   1.1        is 	}
    393   1.1        is 
    394   1.8        is 	sc->sc_encoding = p->encoding;
    395  1.24        is 	sc->sc_precision = p->precision;
    396  1.24        is 	sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
    397  1.24        is 	sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
    398   1.8        is 
    399   1.8        is 	return aucc_set_out_sr(addr, p->sample_rate);
    400   1.1        is }
    401   1.1        is 
    402   1.1        is int
    403  1.36      kent aucc_round_blocksize(void *addr, int blk,
    404  1.36      kent 		     int mode, const audio_params_t *param)
    405   1.1        is {
    406  1.37      kent 
    407  1.48     isaki 	if (blk > AUDIO_BUF_SIZE)
    408  1.48     isaki 		blk = AUDIO_BUF_SIZE;
    409  1.48     isaki 
    410  1.48     isaki 	blk = rounddown(blk, param->channels * param->precision / NBBY);
    411  1.48     isaki 	return blk;
    412   1.1        is }
    413   1.1        is 
    414   1.1        is int
    415  1.29   aymeric aucc_commit_settings(void *addr)
    416   1.1        is {
    417  1.37      kent 	struct aucc_softc *sc;
    418  1.37      kent 	int i;
    419   1.1        is 
    420   1.1        is 	DPRINTF(("sa_commit.\n"));
    421   1.1        is 
    422  1.37      kent 	sc = addr;
    423  1.37      kent 	for (i = 0; i < 4; i++) {
    424  1.37      kent 		custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    425  1.37      kent 		custom.aud[i].per = sc->sc_channel[i].nd_per;
    426   1.1        is 	}
    427   1.1        is 
    428   1.1        is 	DPRINTF(("commit done\n"));
    429   1.1        is 
    430  1.37      kent 	return 0;
    431   1.1        is }
    432   1.1        is 
    433   1.1        is static int masks[4] = {1,3,7,15}; /* masks for n first channels */
    434   1.1        is static int masks2[4] = {1,2,4,8};
    435   1.1        is 
    436   1.1        is int
    437  1.29   aymeric aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    438   1.1        is {
    439   1.8        is 	struct aucc_softc *sc;
    440   1.8        is 	int mask;
    441  1.24        is 	int i, j, k, len;
    442  1.24        is 	u_char *dmap[4];
    443   1.8        is 
    444   1.1        is 
    445   1.8        is 	sc = addr;
    446   1.8        is 	mask = sc->sc_channelmask;
    447   1.1        is 
    448   1.8        is 	dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
    449   1.1        is 
    450   1.1        is 	DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
    451   1.1        is 
    452  1.10        is 	if (sc->sc_channels > 1)
    453  1.24        is 		mask &= masks[sc->sc_channels - 1];
    454  1.10        is 		/* we use first sc_channels channels */
    455  1.24        is 	if (mask == 0) /* active and used channels are disjoint */
    456   1.1        is 		return EINVAL;
    457   1.1        is 
    458  1.37      kent 	for (i = 0; i < 4; i++) {
    459  1.24        is 		/* channels available ? */
    460  1.24        is 		if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
    461   1.1        is 			return EBUSY; /* channel is busy */
    462  1.24        is 		if (channel[i].isaudio == -1)
    463   1.1        is 			return EBUSY; /* system uses them */
    464   1.1        is 	}
    465   1.1        is 
    466   1.1        is 	/* enable interrupt on 1st channel */
    467  1.24        is 	for (i = j = 0; i < AUCC_MAXINT; i++) {
    468  1.24        is 		if (masks2[i] & mask) {
    469   1.1        is 			DPRINTF(("first channel is %d\n",i));
    470  1.37      kent 			j = i;
    471  1.37      kent 			sc->sc_channel[i].nd_intr = intr;
    472  1.37      kent 			sc->sc_channel[i].nd_intrdata = arg;
    473   1.1        is 			break;
    474   1.1        is 		}
    475   1.1        is 	}
    476   1.1        is 
    477   1.8        is 	DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
    478  1.37      kent 		 dmap[2], dmap[3], mask));
    479   1.8        is 
    480  1.34       wiz 	/* disable ints, DMA for channels, until all parameters set */
    481   1.8        is 	/* XXX dont disable DMA! custom.dmacon=mask;*/
    482  1.24        is 	custom.intreq = mask << INTB_AUD0;
    483  1.24        is 	custom.intena = mask << INTB_AUD0;
    484   1.1        is 
    485  1.34       wiz 	/* copy data to DMA buffer */
    486  1.29   aymeric 
    487   1.8        is 	if (sc->sc_channels == 1) {
    488   1.8        is 		dmap[0] =
    489   1.8        is 		dmap[1] =
    490   1.8        is 		dmap[2] =
    491  1.24        is 		dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
    492  1.37      kent 	} else {
    493  1.37      kent 		for (k = 0; k < 4; k++) {
    494  1.24        is 			if (masks2[k+j] & mask)
    495  1.24        is 				dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
    496   1.8        is 		}
    497   1.8        is 	}
    498   1.8        is 
    499   1.8        is 	sc->sc_channel[j].nd_doublebuf ^= 1;
    500   1.8        is 	if (sc->sc_channel[j].nd_doublebuf) {
    501  1.24        is 		dmap[0] += AUDIO_BUF_SIZE;
    502  1.24        is 		dmap[1] += AUDIO_BUF_SIZE;
    503  1.24        is 		dmap[2] += AUDIO_BUF_SIZE;
    504  1.24        is 		dmap[3] += AUDIO_BUF_SIZE;
    505   1.8        is 	}
    506   1.1        is 
    507  1.37      kent 	/*
    508  1.37      kent 	 * compute output length in bytes per channel.
    509  1.24        is 	 * divide by two only for 16bit->8bit conversion.
    510  1.24        is 	 */
    511  1.24        is 	len = cc / sc->sc_channels;
    512  1.24        is 	if (!sc->sc_14bit && (sc->sc_precision == 16))
    513  1.24        is 		len /= 2;
    514  1.24        is 
    515  1.24        is 	/* call audio decoding routine */
    516  1.24        is 	sc->sc_decodefunc (dmap, (u_char *)p, len);
    517   1.1        is 
    518  1.34       wiz 	/* DMA buffers: we use same buffer 4 all channels
    519  1.34       wiz 	 * write DMA location and length
    520  1.24        is 	 */
    521  1.24        is 	for (i = k = 0; i < 4; i++) {
    522   1.8        is 		if (masks2[i] & mask) {
    523   1.1        is 			DPRINTF(("turning channel %d on\n",i));
    524  1.24        is 			/* sc->sc_channel[i].nd_busy=1; */
    525  1.24        is 			channel[i].isaudio = 1;
    526  1.24        is 			channel[i].play_count = 1;
    527  1.24        is 			channel[i].handler = NULL;
    528  1.24        is 			custom.aud[i].per = sc->sc_channel[i].nd_per;
    529  1.24        is 			if (sc->sc_14bit && (i > 1))
    530  1.24        is 				custom.aud[i].vol = 1;
    531  1.24        is 			else
    532  1.24        is 				custom.aud[i].vol = sc->sc_channel[i].nd_volume;
    533   1.8        is 			custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
    534  1.24        is 			custom.aud[i].len = len / 2;
    535  1.24        is 			sc->sc_channel[i].nd_mask = mask;
    536   1.1        is 			DPRINTF(("per is %d, vol is %d, len is %d\n",\
    537   1.8        is 			    sc->sc_channel[i].nd_per,
    538  1.24        is 			    sc->sc_channel[i].nd_volume, len));
    539   1.1        is 		}
    540   1.1        is 	}
    541   1.1        is 
    542  1.37      kent 	channel[j].handler = aucc_inthdl;
    543   1.1        is 
    544   1.1        is 	/* enable ints */
    545  1.24        is 	custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
    546   1.1        is 
    547  1.24        is 	DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
    548   1.1        is 
    549  1.34       wiz 	/* enable DMA */
    550  1.24        is 	custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
    551   1.1        is 
    552  1.34       wiz 	DPRINTF(("enabled DMA, mask=0x%x\n",mask));
    553   1.1        is 
    554  1.37      kent 	return 0;
    555   1.1        is }
    556   1.1        is 
    557   1.1        is /* ARGSUSED */
    558   1.1        is int
    559  1.29   aymeric aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
    560   1.1        is {
    561   1.1        is 
    562   1.1        is 	return ENXIO; /* no input */
    563   1.1        is }
    564   1.1        is 
    565   1.1        is int
    566  1.29   aymeric aucc_halt_output(void *addr)
    567   1.1        is {
    568  1.37      kent 	struct aucc_softc *sc;
    569  1.37      kent 	int i;
    570   1.1        is 
    571   1.1        is 	/* XXX only halt, if input is also halted ?? */
    572  1.37      kent 	sc = addr;
    573  1.34       wiz 	/* stop DMA, etc */
    574   1.7        is 	custom.intena = AUCC_ALLINTF;
    575   1.7        is 	custom.dmacon = AUCC_ALLDMAF;
    576   1.1        is 	/* mark every busy unit idle */
    577  1.37      kent 	for (i = 0; i < 4; i++) {
    578  1.37      kent 		sc->sc_channel[i].nd_busy = sc->sc_channel[i].nd_mask = 0;
    579  1.37      kent 		channel[i].isaudio = 0;
    580  1.37      kent 		channel[i].play_count = 0;
    581   1.1        is 	}
    582   1.1        is 
    583  1.37      kent 	return 0;
    584   1.1        is }
    585   1.1        is 
    586   1.1        is int
    587  1.29   aymeric aucc_halt_input(void *addr)
    588   1.1        is {
    589  1.37      kent 
    590   1.1        is 	/* no input */
    591   1.1        is 	return ENXIO;
    592   1.1        is }
    593   1.1        is 
    594   1.1        is int
    595  1.29   aymeric aucc_getdev(void *addr, struct audio_device *retp)
    596   1.1        is {
    597  1.37      kent 
    598  1.37      kent 	*retp = aucc_device;
    599  1.37      kent 	return 0;
    600   1.1        is }
    601   1.1        is 
    602   1.1        is int
    603  1.29   aymeric aucc_set_port(void *addr, mixer_ctrl_t *cp)
    604   1.1        is {
    605  1.37      kent 	struct aucc_softc *sc;
    606  1.37      kent 	int i,j;
    607   1.1        is 
    608   1.1        is 	DPRINTF(("aucc_set_port: port=%d", cp->dev));
    609  1.37      kent 	sc = addr;
    610   1.1        is 	switch (cp->type) {
    611   1.1        is 	case AUDIO_MIXER_SET:
    612  1.37      kent 		if (cp->dev != AUCC_CHANNELS)
    613   1.1        is 			return EINVAL;
    614  1.37      kent 		i = cp->un.mask;
    615  1.37      kent 		if ((i < 1) || (i > 15))
    616   1.1        is 			return EINVAL;
    617  1.24        is 
    618  1.37      kent 		sc->sc_channelmask = i;
    619   1.1        is 		break;
    620   1.1        is 
    621   1.1        is 	case AUDIO_MIXER_VALUE:
    622  1.37      kent 		i = cp->un.value.num_channels;
    623  1.37      kent 		if ((i < 1) || (i > 4))
    624   1.1        is 			return EINVAL;
    625   1.1        is 
    626  1.10        is #ifdef __XXXwhatsthat
    627  1.37      kent 		if (cp->dev != AUCC_VOLUME)
    628   1.1        is 			return EINVAL;
    629  1.10        is #endif
    630   1.1        is 
    631   1.1        is 		/* set volume for channel 0..i-1 */
    632  1.21        is 
    633  1.21        is 		/* evil workaround for xanim bug, IMO */
    634  1.21        is 		if ((sc->sc_channels == 1) && (i == 2)) {
    635  1.29   aymeric 			sc->sc_channel[0].nd_volume =
    636  1.29   aymeric 			    sc->sc_channel[3].nd_volume =
    637  1.37      kent 			    cp->un.value.level[0] >> 2;
    638  1.29   aymeric 			sc->sc_channel[1].nd_volume =
    639  1.29   aymeric 			    sc->sc_channel[2].nd_volume =
    640  1.37      kent 			    cp->un.value.level[1] >> 2;
    641  1.37      kent 		} else if (i > 1) {
    642  1.37      kent 			for (j = 0; j < i; j++)
    643  1.37      kent 				sc->sc_channel[j].nd_volume =
    644  1.37      kent 				    cp->un.value.level[j] >> 2;
    645  1.21        is 		} else if (sc->sc_channels > 1)
    646  1.37      kent 			for (j = 0; j < sc->sc_channels; j++)
    647  1.37      kent 				sc->sc_channel[j].nd_volume =
    648  1.37      kent 				    cp->un.value.level[0] >> 2;
    649  1.10        is 		else
    650  1.37      kent 			for (j = 0; j < 4; j++)
    651  1.37      kent 				sc->sc_channel[j].nd_volume =
    652  1.37      kent 				    cp->un.value.level[0] >> 2;
    653  1.10        is 		break;
    654   1.1        is 
    655   1.1        is 	default:
    656   1.1        is 		return EINVAL;
    657   1.1        is 		break;
    658   1.1        is 	}
    659   1.1        is 	return 0;
    660   1.1        is }
    661   1.1        is 
    662   1.1        is 
    663   1.1        is int
    664  1.29   aymeric aucc_get_port(void *addr, mixer_ctrl_t *cp)
    665   1.1        is {
    666  1.37      kent 	struct aucc_softc *sc;
    667  1.37      kent 	int i,j;
    668   1.1        is 
    669   1.1        is 	DPRINTF(("aucc_get_port: port=%d", cp->dev));
    670  1.37      kent 	sc = addr;
    671   1.1        is 	switch (cp->type) {
    672   1.1        is 	case AUDIO_MIXER_SET:
    673  1.37      kent 		if (cp->dev != AUCC_CHANNELS)
    674   1.1        is 			return EINVAL;
    675  1.37      kent 		cp->un.mask = sc->sc_channelmask;
    676   1.1        is 		break;
    677   1.1        is 
    678   1.1        is 	case AUDIO_MIXER_VALUE:
    679   1.1        is 		i = cp->un.value.num_channels;
    680  1.37      kent 		if ((i < 1) || (i > 4))
    681   1.1        is 			return EINVAL;
    682   1.1        is 
    683  1.37      kent 		for (j = 0; j < i; j++)
    684  1.10        is 			cp->un.value.level[j] =
    685  1.37      kent 			    (sc->sc_channel[j].nd_volume << 2) +
    686  1.37      kent 			    (sc->sc_channel[j].nd_volume >> 4);
    687   1.1        is 		break;
    688   1.1        is 
    689   1.1        is 	default:
    690   1.1        is 		return EINVAL;
    691   1.1        is 	}
    692   1.1        is 	return 0;
    693   1.1        is }
    694   1.1        is 
    695  1.16  augustss 
    696  1.16  augustss int
    697  1.29   aymeric aucc_get_props(void *addr)
    698  1.16  augustss {
    699  1.46     isaki 
    700  1.47       rin 	return AUDIO_PROP_PLAYBACK;
    701  1.16  augustss }
    702   1.1        is 
    703  1.41  jmcneill 
    704  1.41  jmcneill void
    705  1.41  jmcneill aucc_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
    706  1.41  jmcneill {
    707  1.41  jmcneill 	struct aucc_softc *sc = opaque;
    708  1.41  jmcneill 
    709  1.41  jmcneill 	*intr = &sc->sc_intr_lock;
    710  1.41  jmcneill 	*thread = &sc->sc_lock;
    711  1.41  jmcneill }
    712  1.41  jmcneill 
    713   1.1        is int
    714  1.29   aymeric aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip)
    715   1.1        is {
    716  1.37      kent 	int i;
    717   1.1        is 
    718   1.1        is 	switch(dip->index) {
    719   1.1        is 	case AUCC_CHANNELS:
    720   1.1        is 		dip->type = AUDIO_MIXER_SET;
    721   1.1        is 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    722   1.1        is 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    723  1.43  christos #define setname(a) strlcpy(dip->label.name, (a), sizeof(dip->label.name))
    724  1.43  christos 		setname(AudioNspeaker);
    725  1.37      kent 		for (i = 0; i < 16; i++) {
    726  1.43  christos 			snprintf(dip->un.s.member[i].label.name,
    727  1.43  christos 			    sizeof(dip->un.s.member[i].label.name),
    728   1.1        is 			    "channelmask%d", i);
    729   1.1        is 			dip->un.s.member[i].mask = i;
    730   1.1        is 		}
    731   1.1        is 		dip->un.s.num_mem = 16;
    732   1.1        is 		break;
    733   1.1        is 
    734   1.1        is 	case AUCC_VOLUME:
    735   1.1        is 		dip->type = AUDIO_MIXER_VALUE;
    736   1.1        is 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    737   1.1        is 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    738  1.43  christos 		setname(AudioNmaster);
    739   1.1        is 		dip->un.v.num_channels = 4;
    740   1.1        is 		strcpy(dip->un.v.units.name, AudioNvolume);
    741   1.1        is 		break;
    742   1.1        is 
    743   1.1        is 	case AUCC_OUTPUT_CLASS:
    744   1.1        is 		dip->type = AUDIO_MIXER_CLASS;
    745   1.1        is 		dip->mixer_class = AUCC_OUTPUT_CLASS;
    746   1.1        is 		dip->next = dip->prev = AUDIO_MIXER_LAST;
    747  1.43  christos 		setname(AudioCoutputs);
    748   1.1        is 		break;
    749  1.20  augustss 
    750   1.1        is 	default:
    751   1.1        is 		return ENXIO;
    752   1.1        is 	}
    753   1.1        is 
    754   1.1        is 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    755   1.1        is 
    756  1.37      kent 	return 0;
    757   1.1        is }
    758   1.1        is 
    759   1.1        is /* audio int handler */
    760   1.1        is void
    761   1.1        is aucc_inthdl(int ch)
    762   1.1        is {
    763  1.37      kent 	int i;
    764  1.37      kent 	int mask;
    765   1.1        is 
    766  1.41  jmcneill 	mutex_spin_enter(&aucc->sc_intr_lock);
    767  1.37      kent 	mask = aucc->sc_channel[ch].nd_mask;
    768  1.37      kent 	/*
    769  1.37      kent 	 * for all channels in this maskgroup:
    770  1.37      kent 	 * disable DMA, int
    771  1.37      kent 	 * mark idle
    772  1.37      kent 	 */
    773  1.37      kent 	DPRINTF(("inthandler called, channel %d, mask 0x%x\n", ch, mask));
    774   1.1        is 
    775  1.37      kent 	custom.intreq = mask << INTB_AUD0; /* clear request */
    776  1.24        is 	/*
    777  1.24        is 	 * XXX: maybe we can leave ints and/or DMA on,
    778  1.24        is 	 * if another sample has to be played?
    779  1.24        is 	 */
    780  1.37      kent 	custom.intena = mask << INTB_AUD0;
    781   1.1        is 	/*
    782  1.29   aymeric 	 * XXX custom.dmacon=mask; NO!!!
    783  1.29   aymeric 	 */
    784  1.37      kent 	for (i = 0; i < 4; i++) {
    785  1.37      kent 		if (masks2[i] && mask) {
    786   1.1        is 			DPRINTF(("marking channel %d idle\n",i));
    787  1.37      kent 			aucc->sc_channel[i].nd_busy = 0;
    788  1.37      kent 			aucc->sc_channel[i].nd_mask = 0;
    789  1.37      kent 			channel[i].isaudio = channel[i].play_count = 0;
    790   1.1        is 		}
    791   1.1        is 	}
    792   1.1        is 
    793   1.1        is 	/* call handler */
    794   1.1        is 	if (aucc->sc_channel[ch].nd_intr) {
    795   1.1        is 		DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
    796  1.24        is 		(*(aucc->sc_channel[ch].nd_intr))
    797  1.24        is 		    (aucc->sc_channel[ch].nd_intrdata);
    798  1.37      kent 	} else
    799  1.24        is 		DPRINTF(("zero int handler\n"));
    800  1.41  jmcneill 	mutex_spin_exit(&aucc->sc_intr_lock);
    801   1.1        is 	DPRINTF(("ints done\n"));
    802   1.1        is }
    803   1.1        is 
    804   1.1        is /* transform frequency to period, adjust bounds */
    805   1.1        is static u_int
    806  1.29   aymeric freqtoper(u_int freq)
    807  1.29   aymeric {
    808  1.37      kent 	u_int per;
    809  1.29   aymeric 
    810  1.37      kent 	per = eclockfreq * 5 / freq;
    811  1.37      kent 	if (per < 124)
    812  1.37      kent 		per = 124;   /* must have at least 124 ticks between samples */
    813   1.1        is 
    814   1.1        is 	return per;
    815   1.1        is }
    816   1.1        is 
    817   1.1        is /* transform period to frequency */
    818   1.1        is static u_int
    819  1.29   aymeric pertofreq(u_int per)
    820  1.29   aymeric {
    821  1.24        is 
    822  1.37      kent 	return eclockfreq * 5 / per;
    823  1.24        is }
    824  1.24        is 
    825   1.1        is 
    826  1.24        is /* 14bit output */
    827  1.24        is static void
    828  1.29   aymeric aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i)
    829  1.24        is {
    830  1.37      kent 	u_char *ch0;
    831  1.37      kent 	u_char *ch3;
    832  1.24        is 
    833  1.37      kent 	ch0 = dmap[0];
    834  1.37      kent 	ch3 = dmap[1];		/* XXX should be 3 */
    835  1.24        is 	while (i--) {
    836  1.24        is 		*ch0++ = *p++;
    837  1.24        is 		*ch3++ = *p++ >> 2;
    838  1.24        is 	}
    839  1.24        is }
    840   1.1        is 
    841  1.24        is /* 14bit stereo output */
    842  1.24        is static void
    843  1.29   aymeric aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i)
    844  1.24        is {
    845  1.37      kent 	u_char *ch0;
    846  1.37      kent 	u_char *ch1;
    847  1.37      kent 	u_char *ch2;
    848  1.37      kent 	u_char *ch3;
    849  1.37      kent 
    850  1.37      kent 	ch0 = dmap[0];
    851  1.37      kent 	ch1 = dmap[1];
    852  1.37      kent 	ch2 = dmap[2];
    853  1.37      kent 	ch3 = dmap[3];
    854  1.24        is 	while (i--) {
    855  1.24        is 		*ch0++ = *p++;
    856  1.24        is 		*ch3++ = *p++ >> 2;
    857  1.24        is 		*ch1++ = *p++;
    858  1.24        is 		*ch2++ = *p++ >> 2;
    859  1.24        is 	}
    860  1.24        is }
    861  1.24        is 
    862  1.24        is static void
    863  1.29   aymeric aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i)
    864  1.24        is {
    865  1.37      kent 	u_char *ch0;
    866  1.37      kent 	u_char *ch1;
    867  1.37      kent 	u_char *ch2;
    868  1.37      kent 
    869  1.37      kent 	ch0 = dmap[0];
    870  1.37      kent 	ch1 = dmap[1];
    871  1.37      kent 	ch2 = dmap[2];
    872  1.24        is 	while (i--) {
    873  1.24        is 		*ch0++ = *p++; p++;
    874  1.24        is 		*ch1++ = *p++; p++;
    875  1.24        is 		*ch2++ = *p++; p++;
    876  1.24        is 	}
    877  1.24        is }
    878  1.24        is 
    879  1.24        is static void
    880  1.29   aymeric aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i)
    881   1.1        is {
    882  1.37      kent 	u_char *ch0;
    883  1.37      kent 	u_char *ch1;
    884  1.37      kent 	u_char *ch2;
    885  1.37      kent 	u_char *ch3;
    886  1.37      kent 
    887  1.37      kent 	ch0 = dmap[0];
    888  1.37      kent 	ch1 = dmap[1];
    889  1.37      kent 	ch2 = dmap[2];
    890  1.37      kent 	ch3 = dmap[3];
    891  1.24        is 	while (i--) {
    892  1.24        is 		*ch0++ = *p++; p++;
    893  1.24        is 		*ch1++ = *p++; p++;
    894  1.24        is 		*ch2++ = *p++; p++;
    895  1.24        is 		*ch3++ = *p++; p++;
    896  1.24        is 	}
    897  1.24        is }
    898   1.8        is 
    899   1.1        is #endif /* NAUCC > 0 */
    900