Home | History | Annotate | Line # | Download | only in ic
am7930.c revision 1.1
      1  1.1  pk /*	$NetBSD: am7930.c,v 1.1 1995/04/25 20:05:37 pk Exp $ */
      2  1.1  pk /*
      3  1.1  pk  * Copyright (c) 1995 Rolf Grossmann
      4  1.1  pk  * All rights reserved.
      5  1.1  pk  *
      6  1.1  pk  * Redistribution and use in source and binary forms, with or without
      7  1.1  pk  * modification, are permitted provided that the following conditions
      8  1.1  pk  * are met:
      9  1.1  pk  * 1. Redistributions of source code must retain the above copyright
     10  1.1  pk  *    notice, this list of conditions and the following disclaimer.
     11  1.1  pk  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  pk  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  pk  *    documentation and/or other materials provided with the distribution.
     14  1.1  pk  * 3. All advertising materials mentioning features or use of this software
     15  1.1  pk  *    must display the following acknowledgement:
     16  1.1  pk  *      This product includes software developed by Rolf Grossmann.
     17  1.1  pk  * 4. The name of the author may not be used to endorse or promote products
     18  1.1  pk  *    derived from this software without specific prior written permission
     19  1.1  pk  *
     20  1.1  pk  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  1.1  pk  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  1.1  pk  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  1.1  pk  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  1.1  pk  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  1.1  pk  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  1.1  pk  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  1.1  pk  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  1.1  pk  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  1.1  pk  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  1.1  pk  *
     31  1.1  pk  */
     32  1.1  pk 
     33  1.1  pk #include "audio.h"
     34  1.1  pk #if NAUDIO > 0
     35  1.1  pk 
     36  1.1  pk #include <sys/param.h>
     37  1.1  pk #include <sys/systm.h>
     38  1.1  pk #include <sys/errno.h>
     39  1.1  pk #include <sys/ioctl.h>
     40  1.1  pk #include <sys/device.h>
     41  1.1  pk #include <sys/proc.h>
     42  1.1  pk 
     43  1.1  pk #include <machine/autoconf.h>
     44  1.1  pk #include <machine/cpu.h>
     45  1.1  pk 
     46  1.1  pk #include <sys/audioio.h>
     47  1.1  pk #include <dev/audio_if.h>
     48  1.1  pk 
     49  1.1  pk #include <dev/ic/amd7930.h>
     50  1.1  pk #include <sparc/dev/amd7930var.h>
     51  1.1  pk 
     52  1.1  pk #ifdef DEBUG
     53  1.1  pk extern void Dprintf __P((const char *, ...));
     54  1.1  pk 
     55  1.1  pk int     amd7930debug = 0;
     56  1.1  pk #define DPRINTF(x)      if (amd7930debug) Dprintf x
     57  1.1  pk #else
     58  1.1  pk #define DPRINTF(x)
     59  1.1  pk #endif
     60  1.1  pk 
     61  1.1  pk /*
     62  1.1  pk  * Software state, per AMD79C30 audio chip.
     63  1.1  pk  */
     64  1.1  pk struct amd7930_softc {
     65  1.1  pk 	struct	device sc_dev;		/* base device */
     66  1.1  pk 	struct	intrhand sc_hwih;	/* hardware interrupt vector */
     67  1.1  pk 	struct	intrhand sc_swih;	/* software interrupt vector */
     68  1.1  pk 	int	sc_interrupts;		/* number of interrupts taken */
     69  1.1  pk 
     70  1.1  pk 	int	sc_open;		/* single use device */
     71  1.1  pk 	int	sc_locked;		/* true when transfering data */
     72  1.1  pk 	struct	mapreg sc_map;		/* current contents of map registers */
     73  1.1  pk 
     74  1.1  pk 	u_char	sc_rlevel;		/* record level */
     75  1.1  pk 	u_char	sc_plevel;		/* play level */
     76  1.1  pk 	u_char	sc_mlevel;		/* monitor level */
     77  1.1  pk 	u_char	sc_out_port;		/* output port */
     78  1.1  pk 
     79  1.1  pk 	/* interfacing with the interrupt handlers */
     80  1.1  pk 	void	(*sc_rintr)(void*);	/* input completion intr handler */
     81  1.1  pk 	void	*sc_rarg;		/* arg for sc_rintr() */
     82  1.1  pk 	void	(*sc_pintr)(void*);	/* output completion intr handler */
     83  1.1  pk 	void	*sc_parg;		/* arg for sc_pintr() */
     84  1.1  pk 
     85  1.1  pk         /* sc_au is special in that the hardware interrupt handler uses it */
     86  1.1  pk         struct  auio sc_au;		/* recv and xmit buffers, etc */
     87  1.1  pk };
     88  1.1  pk 
     89  1.1  pk /* interrupt interfaces */
     90  1.1  pk #ifdef AUDIO_C_HANDLER
     91  1.1  pk int	amd7930hwintr __P((void *));
     92  1.1  pk #define AUDIO_SET_SWINTR ienab_bis(IE_L4)
     93  1.1  pk #else
     94  1.1  pk struct auio *auiop;
     95  1.1  pk extern void amd7930_trap();
     96  1.1  pk #endif
     97  1.1  pk int	amd7930swintr __P((void *));
     98  1.1  pk 
     99  1.1  pk /* forward declarations */
    100  1.1  pk void	audio_setmap __P((volatile struct amd7930 *, struct mapreg *));
    101  1.1  pk static void init_amd __P((volatile struct amd7930 *));
    102  1.1  pk 
    103  1.1  pk /* autoconfiguration driver */
    104  1.1  pk void	amd9730attach __P((struct device *, struct device *, void *));
    105  1.1  pk int	amd9730match __P((struct device *, void *, void *));
    106  1.1  pk 
    107  1.1  pk struct	cfdriver audiocd = {
    108  1.1  pk 	NULL, "audio", amd9730match, amd9730attach,
    109  1.1  pk 	DV_DULL, sizeof(struct amd7930_softc)
    110  1.1  pk };
    111  1.1  pk 
    112  1.1  pk struct audio_device amd7930_device = {
    113  1.1  pk 	"amd7930",
    114  1.1  pk 	"x",
    115  1.1  pk 	"audio"
    116  1.1  pk };
    117  1.1  pk 
    118  1.1  pk /* Write 16 bits of data from variable v to the data port of the audio chip */
    119  1.1  pk #define	WAMD16(amd, v) ((amd)->dr = (v), (amd)->dr = (v) >> 8)
    120  1.1  pk 
    121  1.1  pk /* The following tables stolen from former (4.4Lite's) sys/sparc/bsd_audio.c */
    122  1.1  pk 
    123  1.1  pk /*
    124  1.1  pk  * gx, gr & stg gains.  this table must contain 256 elements with
    125  1.1  pk  * the 0th being "infinity" (the magic value 9008).  The remaining
    126  1.1  pk  * elements match sun's gain curve (but with higher resolution):
    127  1.1  pk  * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps.
    128  1.1  pk  */
    129  1.1  pk static const u_short gx_coeff[256] = {
    130  1.1  pk 	0x9008, 0x8b7c, 0x8b51, 0x8b45, 0x8b42, 0x8b3b, 0x8b36, 0x8b33,
    131  1.1  pk 	0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22,
    132  1.1  pk 	0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b,
    133  1.1  pk 	0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb,
    134  1.1  pk 	0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a,
    135  1.1  pk 	0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213,
    136  1.1  pk 	0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231,
    137  1.1  pk 	0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4,
    138  1.1  pk 	0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2,
    139  1.1  pk 	0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa,
    140  1.1  pk 	0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b,
    141  1.1  pk 	0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b,
    142  1.1  pk 	0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd,
    143  1.1  pk 	0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808,
    144  1.1  pk 	0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243,
    145  1.1  pk 	0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224,
    146  1.1  pk 	0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb,
    147  1.1  pk 	0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33,
    148  1.1  pk 	0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32,
    149  1.1  pk 	0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323,
    150  1.1  pk 	0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a,
    151  1.1  pk 	0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23,
    152  1.1  pk 	0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1,
    153  1.1  pk 	0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333,
    154  1.1  pk 	0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227,
    155  1.1  pk 	0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6,
    156  1.1  pk 	0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2,
    157  1.1  pk 	0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba,
    158  1.1  pk 	0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033,
    159  1.1  pk 	0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021,
    160  1.1  pk 	0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012,
    161  1.1  pk 	0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,
    162  1.1  pk };
    163  1.1  pk 
    164  1.1  pk /*
    165  1.1  pk  * second stage play gain.
    166  1.1  pk  */
    167  1.1  pk static const u_short ger_coeff[] = {
    168  1.1  pk 	0x431f, /* 5. dB */
    169  1.1  pk 	0x331f, /* 5.5 dB */
    170  1.1  pk 	0x40dd, /* 6. dB */
    171  1.1  pk 	0x11dd, /* 6.5 dB */
    172  1.1  pk 	0x440f, /* 7. dB */
    173  1.1  pk 	0x411f, /* 7.5 dB */
    174  1.1  pk 	0x311f, /* 8. dB */
    175  1.1  pk 	0x5520, /* 8.5 dB */
    176  1.1  pk 	0x10dd, /* 9. dB */
    177  1.1  pk 	0x4211, /* 9.5 dB */
    178  1.1  pk 	0x410f, /* 10. dB */
    179  1.1  pk 	0x111f, /* 10.5 dB */
    180  1.1  pk 	0x600b, /* 11. dB */
    181  1.1  pk 	0x00dd, /* 11.5 dB */
    182  1.1  pk 	0x4210, /* 12. dB */
    183  1.1  pk 	0x110f, /* 13. dB */
    184  1.1  pk 	0x7200, /* 14. dB */
    185  1.1  pk 	0x2110, /* 15. dB */
    186  1.1  pk 	0x2200, /* 15.9 dB */
    187  1.1  pk 	0x000b, /* 16.9 dB */
    188  1.1  pk 	0x000f  /* 18. dB */
    189  1.1  pk #define NGER (sizeof(ger_coeff) / sizeof(ger_coeff[0]))
    190  1.1  pk };
    191  1.1  pk 
    192  1.1  pk /*
    193  1.1  pk  * Define our interface to the higher level audio driver.
    194  1.1  pk  */
    195  1.1  pk int	amd7930_open __P((dev_t, int));
    196  1.1  pk void	amd7930_close __P((void *));
    197  1.1  pk int	amd7930_set_in_sr __P((void *, u_long));
    198  1.1  pk u_long	amd7930_get_in_sr __P((void *));
    199  1.1  pk int	amd7930_set_out_sr __P((void *, u_long));
    200  1.1  pk u_long	amd7930_get_out_sr __P((void *));
    201  1.1  pk int	amd7930_query_encoding __P((void *, struct audio_encoding *));
    202  1.1  pk int	amd7930_set_encoding __P((void *, u_int));
    203  1.1  pk int	amd7930_get_encoding __P((void *));
    204  1.1  pk int	amd7930_set_precision __P((void *, u_int));
    205  1.1  pk int	amd7930_get_precision __P((void *));
    206  1.1  pk int	amd7930_set_channels __P((void *, int));
    207  1.1  pk int	amd7930_get_channels __P((void *));
    208  1.1  pk int	amd7930_round_blocksize __P((void *, int));
    209  1.1  pk int	amd7930_set_out_port __P((void *, int));
    210  1.1  pk int	amd7930_get_out_port __P((void *));
    211  1.1  pk int	amd7930_set_in_port __P((void *, int));
    212  1.1  pk int	amd7930_get_in_port __P((void *));
    213  1.1  pk int	amd7930_commit_settings __P((void *));
    214  1.1  pk u_int	amd7930_get_silence __P((int));
    215  1.1  pk int	amd7930_start_output __P((void *, void *, int, void (*)(), void *));
    216  1.1  pk int	amd7930_start_input __P((void *, void *, int, void (*)(), void *));
    217  1.1  pk int	amd7930_halt_output __P((void *));
    218  1.1  pk int	amd7930_halt_input __P((void *));
    219  1.1  pk int	amd7930_cont_output __P((void *));
    220  1.1  pk int	amd7930_cont_input __P((void *));
    221  1.1  pk int	amd7930_getdev __P((void *, struct audio_device *));
    222  1.1  pk int	amd7930_setfd __P((void *, int));
    223  1.1  pk int	amd7930_set_port __P((void *, mixer_ctrl_t *));
    224  1.1  pk int	amd7930_get_port __P((void *, mixer_ctrl_t *));
    225  1.1  pk int	amd7930_query_devinfo __P((void *, mixer_devinfo_t *));
    226  1.1  pk 
    227  1.1  pk 
    228  1.1  pk struct audio_hw_if sa_hw_if = {
    229  1.1  pk 	amd7930_open,
    230  1.1  pk 	amd7930_close,
    231  1.1  pk 	NULL,
    232  1.1  pk 	amd7930_set_in_sr,
    233  1.1  pk 	amd7930_get_in_sr,
    234  1.1  pk 	amd7930_set_out_sr,
    235  1.1  pk 	amd7930_get_out_sr,
    236  1.1  pk 	amd7930_query_encoding,
    237  1.1  pk 	amd7930_set_encoding,
    238  1.1  pk 	amd7930_get_encoding,
    239  1.1  pk 	amd7930_set_precision,
    240  1.1  pk 	amd7930_get_precision,
    241  1.1  pk 	amd7930_set_channels,
    242  1.1  pk 	amd7930_get_channels,
    243  1.1  pk 	amd7930_round_blocksize,
    244  1.1  pk 	amd7930_set_out_port,
    245  1.1  pk 	amd7930_get_out_port,
    246  1.1  pk 	amd7930_set_in_port,
    247  1.1  pk 	amd7930_get_in_port,
    248  1.1  pk 	amd7930_commit_settings,
    249  1.1  pk 	amd7930_get_silence,
    250  1.1  pk 	NULL,
    251  1.1  pk 	NULL,
    252  1.1  pk 	amd7930_start_output,
    253  1.1  pk 	amd7930_start_input,
    254  1.1  pk 	amd7930_halt_output,
    255  1.1  pk 	amd7930_halt_input,
    256  1.1  pk 	amd7930_cont_output,
    257  1.1  pk 	amd7930_cont_input,
    258  1.1  pk 	NULL,
    259  1.1  pk 	amd7930_getdev,
    260  1.1  pk 	amd7930_setfd,
    261  1.1  pk 	amd7930_set_port,
    262  1.1  pk 	amd7930_get_port,
    263  1.1  pk 	amd7930_query_devinfo,
    264  1.1  pk 	1,
    265  1.1  pk 	0
    266  1.1  pk };
    267  1.1  pk 
    268  1.1  pk /* autoconfig routines */
    269  1.1  pk 
    270  1.1  pk int
    271  1.1  pk amd9730match(parent, vcf, aux)
    272  1.1  pk 	struct device *parent;
    273  1.1  pk 	void *vcf, *aux;
    274  1.1  pk {
    275  1.1  pk 	struct cfdata *cf = vcf;
    276  1.1  pk 	register struct confargs *ca = aux;
    277  1.1  pk 	register struct romaux *ra = &ca->ca_ra;
    278  1.1  pk 
    279  1.1  pk 	if (cputyp==CPU_SUN4)
    280  1.1  pk 		return (0);
    281  1.1  pk 	return (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0);
    282  1.1  pk }
    283  1.1  pk 
    284  1.1  pk /*
    285  1.1  pk  * Audio chip found.
    286  1.1  pk  */
    287  1.1  pk void
    288  1.1  pk amd9730attach(parent, self, args)
    289  1.1  pk 	struct device *parent, *self;
    290  1.1  pk 	void *args;
    291  1.1  pk {
    292  1.1  pk 	register struct amd7930_softc *sc = (struct amd7930_softc *)self;
    293  1.1  pk 	register struct confargs *ca = args;
    294  1.1  pk 	register struct romaux *ra = &ca->ca_ra;
    295  1.1  pk 	register volatile struct amd7930 *amd;
    296  1.1  pk 	register int pri;
    297  1.1  pk 
    298  1.1  pk 	if (ra->ra_nintr != 1) {
    299  1.1  pk 		printf(": expected 1 interrupt, got %d\n", ra->ra_nintr);
    300  1.1  pk 		return;
    301  1.1  pk 	}
    302  1.1  pk 	pri = ra->ra_intr[0].int_pri;
    303  1.1  pk 	printf(" pri %d, softpri %d\n", pri, PIL_AUSOFT);
    304  1.1  pk 	amd = (volatile struct amd7930 *)(ra->ra_vaddr ?
    305  1.1  pk 		ra->ra_vaddr : mapiodev(ra->ra_paddr, sizeof (*amd),
    306  1.1  pk 					ca->ca_bustype));
    307  1.1  pk 
    308  1.1  pk 	sc->sc_map.mr_mmr1 = AMD_MMR1_GX | AMD_MMR1_GER |
    309  1.1  pk 			     AMD_MMR1_GR | AMD_MMR1_STG;
    310  1.1  pk 	sc->sc_au.au_amd = amd;
    311  1.1  pk 	/* set boot defaults */
    312  1.1  pk 	sc->sc_rlevel = 128;
    313  1.1  pk 	sc->sc_plevel = 128;
    314  1.1  pk 	sc->sc_mlevel = 0;
    315  1.1  pk 	sc->sc_out_port = SUNAUDIO_SPEAKER;
    316  1.1  pk 
    317  1.1  pk 	init_amd(amd);
    318  1.1  pk 
    319  1.1  pk #ifndef AUDIO_C_HANDLER
    320  1.1  pk 	auiop = &sc->sc_au;
    321  1.1  pk 	intr_fasttrap(pri, amd7930_trap);
    322  1.1  pk #else
    323  1.1  pk 	sc->sc_hwih.ih_fun = amd7930hwintr;
    324  1.1  pk 	sc->sc_hwih.ih_arg = &sc->sc_au;
    325  1.1  pk 	intr_establish(pri, &sc->sc_hwih);
    326  1.1  pk #endif
    327  1.1  pk 	sc->sc_swih.ih_fun = amd7930swintr;
    328  1.1  pk 	sc->sc_swih.ih_arg = sc;
    329  1.1  pk 	intr_establish(PIL_AUSOFT, &sc->sc_swih);
    330  1.1  pk 
    331  1.1  pk 	if (audio_hardware_attach(&sa_hw_if, sc) != 0)
    332  1.1  pk 		printf("audio: could not attach to audio pseudo-device driver\n");
    333  1.1  pk }
    334  1.1  pk 
    335  1.1  pk static void
    336  1.1  pk init_amd(amd)
    337  1.1  pk 	register volatile struct amd7930 *amd;
    338  1.1  pk {
    339  1.1  pk 	/* disable interrupts */
    340  1.1  pk 	amd->cr = AMDR_INIT;
    341  1.1  pk 	amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
    342  1.1  pk 
    343  1.1  pk 	/*
    344  1.1  pk 	 * Initialize the mux unit.  We use MCR3 to route audio (MAP)
    345  1.1  pk 	 * through channel Bb.  MCR1 and MCR2 are unused.
    346  1.1  pk 	 * Setting the INT enable bit in MCR4 will generate an interrupt
    347  1.1  pk 	 * on each converted audio sample.
    348  1.1  pk 	 */
    349  1.1  pk 	amd->cr = AMDR_MUX_1_4;
    350  1.1  pk  	amd->dr = 0;
    351  1.1  pk 	amd->dr = 0;
    352  1.1  pk 	amd->dr = (AMD_MCRCHAN_BB << 4) | AMD_MCRCHAN_BA;
    353  1.1  pk 	amd->dr = AMD_MCR4_INT_ENABLE;
    354  1.1  pk }
    355  1.1  pk 
    356  1.1  pk int
    357  1.1  pk amd7930_open(dev, flags)
    358  1.1  pk 	dev_t dev;
    359  1.1  pk 	int flags;
    360  1.1  pk {
    361  1.1  pk 	register struct amd7930_softc *sc;
    362  1.1  pk 	register volatile struct amd7930 *amd;
    363  1.1  pk 	int unit = AUDIOUNIT(dev);
    364  1.1  pk 
    365  1.1  pk 	DPRINTF(("sa_open: unit %d\n",unit));
    366  1.1  pk 
    367  1.1  pk 	if (unit >= audiocd.cd_ndevs)
    368  1.1  pk 		return (ENODEV);
    369  1.1  pk 	if ((sc = audiocd.cd_devs[unit]) == NULL)
    370  1.1  pk 		return (ENXIO);
    371  1.1  pk 	if (sc->sc_open)
    372  1.1  pk 		return (EBUSY);
    373  1.1  pk 	sc->sc_open = 1;
    374  1.1  pk 	sc->sc_locked = 0;
    375  1.1  pk 	sc->sc_rintr = 0;
    376  1.1  pk 	sc->sc_rarg = 0;
    377  1.1  pk 	sc->sc_pintr = 0;
    378  1.1  pk 	sc->sc_parg = 0;
    379  1.1  pk 
    380  1.1  pk 	sc->sc_au.au_rdata = 0;
    381  1.1  pk 	sc->sc_au.au_pdata = 0;
    382  1.1  pk 
    383  1.1  pk 	DPRINTF(("saopen: ok -> sc=0x%x\n",sc));
    384  1.1  pk 
    385  1.1  pk 	return (0);
    386  1.1  pk }
    387  1.1  pk 
    388  1.1  pk void
    389  1.1  pk amd7930_close(addr)
    390  1.1  pk 	void *addr;
    391  1.1  pk {
    392  1.1  pk 	register struct amd7930_softc *sc = addr;
    393  1.1  pk 
    394  1.1  pk 	DPRINTF(("sa_close: sc=0x%x\n", sc));
    395  1.1  pk 	/*
    396  1.1  pk 	 * halt i/o, clear open flag, and done.
    397  1.1  pk 	 */
    398  1.1  pk 	amd7930_halt_input(sc);
    399  1.1  pk 	amd7930_halt_output(sc);
    400  1.1  pk 	sc->sc_open = 0;
    401  1.1  pk 
    402  1.1  pk 	DPRINTF(("sa_close: closed.\n"));
    403  1.1  pk }
    404  1.1  pk 
    405  1.1  pk int
    406  1.1  pk amd7930_set_in_sr(addr, sr)
    407  1.1  pk 	void *addr;
    408  1.1  pk 	u_long sr;
    409  1.1  pk {
    410  1.1  pk 	if (sr != 8000)
    411  1.1  pk 		return EINVAL;
    412  1.1  pk 
    413  1.1  pk 	return(0);	/* no other sampling rates supported by amd chip */
    414  1.1  pk }
    415  1.1  pk 
    416  1.1  pk u_long
    417  1.1  pk amd7930_get_in_sr(addr)
    418  1.1  pk 	void *addr;
    419  1.1  pk {
    420  1.1  pk 	return(8000);
    421  1.1  pk }
    422  1.1  pk 
    423  1.1  pk int
    424  1.1  pk amd7930_set_out_sr(addr, sr)
    425  1.1  pk 	void *addr;
    426  1.1  pk 	u_long sr;
    427  1.1  pk {
    428  1.1  pk 	if (sr != 8000)
    429  1.1  pk 		return(EINVAL);
    430  1.1  pk 
    431  1.1  pk 	return(0);	/* no other sampling rates supported by amd chip */
    432  1.1  pk }
    433  1.1  pk 
    434  1.1  pk u_long
    435  1.1  pk amd7930_get_out_sr(addr)
    436  1.1  pk 	void *addr;
    437  1.1  pk {
    438  1.1  pk 	return(8000);
    439  1.1  pk }
    440  1.1  pk 
    441  1.1  pk int
    442  1.1  pk amd7930_query_encoding(addr, fp)
    443  1.1  pk 	void *addr;
    444  1.1  pk 	struct audio_encoding *fp;
    445  1.1  pk {
    446  1.1  pk 	switch (fp->index) {	/* ??? */
    447  1.1  pk 	    case 0:
    448  1.1  pk 		    strcpy(fp->name, "MU-Law");
    449  1.1  pk 		    fp->format_id = AUDIO_ENCODING_ULAW;
    450  1.1  pk 		    break;
    451  1.1  pk 	    default:
    452  1.1  pk 		    return(EINVAL);
    453  1.1  pk 		    /*NOTREACHED*/
    454  1.1  pk 	}
    455  1.1  pk 	return(0);
    456  1.1  pk }
    457  1.1  pk 
    458  1.1  pk int
    459  1.1  pk amd7930_set_encoding(addr, enc)
    460  1.1  pk 	void *addr;
    461  1.1  pk 	u_int enc;
    462  1.1  pk {
    463  1.1  pk 	if (enc != AUDIO_ENCODING_ULAW)
    464  1.1  pk 		return(EINVAL);
    465  1.1  pk 
    466  1.1  pk 	return(0);		/* no other encoding supported by amd chip */
    467  1.1  pk }
    468  1.1  pk 
    469  1.1  pk int
    470  1.1  pk amd7930_get_encoding(addr)
    471  1.1  pk 	void *addr;
    472  1.1  pk {
    473  1.1  pk 	return(AUDIO_ENCODING_ULAW);
    474  1.1  pk }
    475  1.1  pk 
    476  1.1  pk int
    477  1.1  pk amd7930_set_precision(addr, prec)
    478  1.1  pk 	void *addr;
    479  1.1  pk 	u_int prec;
    480  1.1  pk {
    481  1.1  pk 	if (prec != 8)
    482  1.1  pk 		return(EINVAL);
    483  1.1  pk 
    484  1.1  pk 	return(0);		/* no other precision supported by amd chip */
    485  1.1  pk }
    486  1.1  pk 
    487  1.1  pk int
    488  1.1  pk amd7930_get_precision(addr)
    489  1.1  pk 	void *addr;
    490  1.1  pk {
    491  1.1  pk 	return(8);
    492  1.1  pk }
    493  1.1  pk 
    494  1.1  pk int
    495  1.1  pk amd7930_set_channels(addr, chans)
    496  1.1  pk 	void *addr;
    497  1.1  pk 	int chans;
    498  1.1  pk {
    499  1.1  pk 	if (chans != 1)
    500  1.1  pk 		return(EINVAL);
    501  1.1  pk 
    502  1.1  pk 	return(0);		/* only 1 channel supported by amd chip */
    503  1.1  pk }
    504  1.1  pk 
    505  1.1  pk int
    506  1.1  pk amd7930_get_channels(addr)
    507  1.1  pk 	void *addr;
    508  1.1  pk {
    509  1.1  pk 	return(1);
    510  1.1  pk }
    511  1.1  pk 
    512  1.1  pk int
    513  1.1  pk amd7930_round_blocksize(addr, blk)
    514  1.1  pk 	void *addr;
    515  1.1  pk 	int blk;
    516  1.1  pk {
    517  1.1  pk 	return(blk);
    518  1.1  pk }
    519  1.1  pk 
    520  1.1  pk int
    521  1.1  pk amd7930_set_out_port(addr, port)
    522  1.1  pk 	void *addr;
    523  1.1  pk 	int port;
    524  1.1  pk {
    525  1.1  pk 	register struct amd7930_softc *sc = addr;
    526  1.1  pk 
    527  1.1  pk 	switch(port) {
    528  1.1  pk 	    case SUNAUDIO_SPEAKER:
    529  1.1  pk 	    case SUNAUDIO_HEADPHONES:
    530  1.1  pk 		sc->sc_out_port = port;	/* set on commit */
    531  1.1  pk 		break;
    532  1.1  pk 	    default:
    533  1.1  pk 		return(EINVAL);
    534  1.1  pk 	}
    535  1.1  pk 	return(0);
    536  1.1  pk }
    537  1.1  pk 
    538  1.1  pk int
    539  1.1  pk amd7930_get_out_port(addr)
    540  1.1  pk 	void *addr;
    541  1.1  pk {
    542  1.1  pk 	register struct amd7930_softc *sc = addr;
    543  1.1  pk 
    544  1.1  pk 	return(sc->sc_out_port);
    545  1.1  pk }
    546  1.1  pk 
    547  1.1  pk int
    548  1.1  pk amd7930_set_in_port(addr, port)
    549  1.1  pk 	void *addr;
    550  1.1  pk 	int port;
    551  1.1  pk {
    552  1.1  pk 	if (port != SUNAUDIO_MIC_PORT)
    553  1.1  pk 		return(EINVAL);
    554  1.1  pk 
    555  1.1  pk 	return(0);	/* only microphone input supported by amd chip */
    556  1.1  pk }
    557  1.1  pk 
    558  1.1  pk int
    559  1.1  pk amd7930_get_in_port(addr)
    560  1.1  pk 	void *addr;
    561  1.1  pk {
    562  1.1  pk 	return(SUNAUDIO_MIC_PORT);
    563  1.1  pk }
    564  1.1  pk 
    565  1.1  pk int
    566  1.1  pk amd7930_commit_settings(addr)
    567  1.1  pk 	void *addr;
    568  1.1  pk {
    569  1.1  pk 	register struct amd7930_softc *sc = addr;
    570  1.1  pk 	register struct mapreg *map;
    571  1.1  pk 	register volatile struct amd7930 *amd;
    572  1.1  pk 	register int s, level;
    573  1.1  pk 
    574  1.1  pk 	DPRINTF(("sa_commit.\n"));
    575  1.1  pk 
    576  1.1  pk 	map = &sc->sc_map;
    577  1.1  pk 	amd = sc->sc_au.au_amd;
    578  1.1  pk 
    579  1.1  pk 	map->mr_gx = gx_coeff[sc->sc_rlevel];
    580  1.1  pk 	map->mr_stgr = gx_coeff[sc->sc_mlevel];
    581  1.1  pk 
    582  1.1  pk 	level = (sc->sc_plevel * (256 + NGER)) >> 8;
    583  1.1  pk 	if (level >= 256) {
    584  1.1  pk 		map->mr_ger = ger_coeff[level - 256];
    585  1.1  pk 		map->mr_gr = gx_coeff[255];
    586  1.1  pk 	} else {
    587  1.1  pk 		map->mr_ger = ger_coeff[0];
    588  1.1  pk 		map->mr_gr = gx_coeff[level];
    589  1.1  pk 	}
    590  1.1  pk 
    591  1.1  pk 	if (sc->sc_out_port == SUNAUDIO_SPEAKER)
    592  1.1  pk 		map->mr_mmr2 |= AMD_MMR2_LS;
    593  1.1  pk 	else
    594  1.1  pk 		map->mr_mmr2 &= ~AMD_MMR2_LS;
    595  1.1  pk 
    596  1.1  pk 	s = splaudio();
    597  1.1  pk 
    598  1.1  pk 	amd->cr = AMDR_MAP_MMR1;
    599  1.1  pk 	amd->dr = map->mr_mmr1;
    600  1.1  pk 	amd->cr = AMDR_MAP_GX;
    601  1.1  pk 	WAMD16(amd, map->mr_gx);
    602  1.1  pk 	amd->cr = AMDR_MAP_STG;
    603  1.1  pk 	WAMD16(amd, map->mr_stgr);
    604  1.1  pk 	amd->cr = AMDR_MAP_GR;
    605  1.1  pk 	WAMD16(amd, map->mr_gr);
    606  1.1  pk 	amd->cr = AMDR_MAP_GER;
    607  1.1  pk 	WAMD16(amd, map->mr_ger);
    608  1.1  pk 	amd->cr = AMDR_MAP_MMR2;
    609  1.1  pk 	amd->dr = map->mr_mmr2;
    610  1.1  pk 
    611  1.1  pk 	splx(s);
    612  1.1  pk 	return(0);
    613  1.1  pk }
    614  1.1  pk 
    615  1.1  pk u_int
    616  1.1  pk amd7930_get_silence(enc)
    617  1.1  pk 	int enc;
    618  1.1  pk {
    619  1.1  pk 	return(0x7f);
    620  1.1  pk }
    621  1.1  pk 
    622  1.1  pk int
    623  1.1  pk amd7930_start_output(addr, p, cc, intr, arg)
    624  1.1  pk 	void *addr;
    625  1.1  pk 	void *p;
    626  1.1  pk 	int cc;
    627  1.1  pk 	void (*intr)();
    628  1.1  pk 	void *arg;
    629  1.1  pk {
    630  1.1  pk 	register struct amd7930_softc *sc = addr;
    631  1.1  pk 
    632  1.1  pk #ifdef DEBUG
    633  1.1  pk 	if (amd7930debug > 1)
    634  1.1  pk 		Dprintf("sa_start_output: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
    635  1.1  pk #endif
    636  1.1  pk 
    637  1.1  pk 	if (!sc->sc_locked) {
    638  1.1  pk 		register volatile struct amd7930 *amd;
    639  1.1  pk 
    640  1.1  pk 		amd = sc->sc_au.au_amd;
    641  1.1  pk 		amd->cr = AMDR_INIT;
    642  1.1  pk 		amd->dr = AMD_INIT_PMS_ACTIVE;
    643  1.1  pk 		sc->sc_locked = 1;
    644  1.1  pk 		DPRINTF(("sa_start_output: started intrs.\n"));
    645  1.1  pk 	}
    646  1.1  pk 	sc->sc_pintr = intr;
    647  1.1  pk 	sc->sc_parg = arg;
    648  1.1  pk 	sc->sc_au.au_pdata = p;
    649  1.1  pk 	sc->sc_au.au_pend = p + cc - 1;
    650  1.1  pk 	return(0);
    651  1.1  pk }
    652  1.1  pk 
    653  1.1  pk /* ARGSUSED */
    654  1.1  pk int
    655  1.1  pk amd7930_start_input(addr, p, cc, intr, arg)
    656  1.1  pk 	void *addr;
    657  1.1  pk 	void *p;
    658  1.1  pk 	int cc;
    659  1.1  pk 	void (*intr)();
    660  1.1  pk 	void *arg;
    661  1.1  pk {
    662  1.1  pk 	register struct amd7930_softc *sc = addr;
    663  1.1  pk 
    664  1.1  pk #ifdef DEBUG
    665  1.1  pk 	if (amd7930debug > 1)
    666  1.1  pk 		Dprintf("sa_start_input: cc=%d 0x%x (0x%x)\n", cc, intr, arg);
    667  1.1  pk #endif
    668  1.1  pk 
    669  1.1  pk 	if (!sc->sc_locked) {
    670  1.1  pk 		register volatile struct amd7930 *amd;
    671  1.1  pk 
    672  1.1  pk 		amd = sc->sc_au.au_amd;
    673  1.1  pk 		amd->cr = AMDR_INIT;
    674  1.1  pk 		amd->dr = AMD_INIT_PMS_ACTIVE;
    675  1.1  pk 		sc->sc_locked = 1;
    676  1.1  pk 		DPRINTF(("sa_start_input: started intrs.\n"));
    677  1.1  pk 	}
    678  1.1  pk 	sc->sc_rintr = intr;
    679  1.1  pk 	sc->sc_rarg = arg;
    680  1.1  pk 	sc->sc_au.au_rdata = p;
    681  1.1  pk 	sc->sc_au.au_rend = p + cc -1;
    682  1.1  pk 	return(0);
    683  1.1  pk }
    684  1.1  pk 
    685  1.1  pk int
    686  1.1  pk amd7930_halt_output(addr)
    687  1.1  pk 	void *addr;
    688  1.1  pk {
    689  1.1  pk 	register struct amd7930_softc *sc = addr;
    690  1.1  pk 	register volatile struct amd7930 *amd;
    691  1.1  pk 
    692  1.1  pk 	/* XXX only halt, if input is also halted ?? */
    693  1.1  pk 	amd = sc->sc_au.au_amd;
    694  1.1  pk 	amd->cr = AMDR_INIT;
    695  1.1  pk 	amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
    696  1.1  pk 	sc->sc_locked = 0;
    697  1.1  pk 
    698  1.1  pk 	return(0);
    699  1.1  pk }
    700  1.1  pk 
    701  1.1  pk int
    702  1.1  pk amd7930_halt_input(addr)
    703  1.1  pk 	void *addr;
    704  1.1  pk {
    705  1.1  pk 	register struct amd7930_softc *sc = addr;
    706  1.1  pk 	register volatile struct amd7930 *amd;
    707  1.1  pk 
    708  1.1  pk 	/* XXX only halt, if output is also halted ?? */
    709  1.1  pk 	amd = sc->sc_au.au_amd;
    710  1.1  pk 	amd->cr = AMDR_INIT;
    711  1.1  pk 	amd->dr = AMD_INIT_PMS_ACTIVE | AMD_INIT_INT_DISABLE;
    712  1.1  pk 	sc->sc_locked = 0;
    713  1.1  pk 
    714  1.1  pk 	return(0);
    715  1.1  pk }
    716  1.1  pk 
    717  1.1  pk int
    718  1.1  pk amd7930_cont_output(addr)
    719  1.1  pk 	void *addr;
    720  1.1  pk {
    721  1.1  pk 	DPRINTF(("amd7930_cont_output: never called, what should it do?!\n"));
    722  1.1  pk 	return(0);
    723  1.1  pk }
    724  1.1  pk 
    725  1.1  pk int
    726  1.1  pk amd7930_cont_input(addr)
    727  1.1  pk 	void *addr;
    728  1.1  pk {
    729  1.1  pk 	DPRINTF(("amd7930_cont_input: never called, what should it do?!\n"));
    730  1.1  pk 	return(0);
    731  1.1  pk }
    732  1.1  pk 
    733  1.1  pk int
    734  1.1  pk amd7930_getdev(addr, retp)
    735  1.1  pk         void *addr;
    736  1.1  pk         struct audio_device *retp;
    737  1.1  pk {
    738  1.1  pk         *retp = amd7930_device;
    739  1.1  pk         return 0;
    740  1.1  pk }
    741  1.1  pk 
    742  1.1  pk int
    743  1.1  pk amd7930_setfd(addr, flag)
    744  1.1  pk         void *addr;
    745  1.1  pk         int flag;
    746  1.1  pk {
    747  1.1  pk         /* Always full-duplex */
    748  1.1  pk         return(0);
    749  1.1  pk }
    750  1.1  pk 
    751  1.1  pk int
    752  1.1  pk amd7930_set_port(addr, cp)
    753  1.1  pk 	void *addr;
    754  1.1  pk 	mixer_ctrl_t *cp;
    755  1.1  pk {
    756  1.1  pk 	register struct amd7930_softc *sc = addr;
    757  1.1  pk 
    758  1.1  pk 	DPRINTF(("amd7930_set_port: port=%d", cp->dev));
    759  1.1  pk 
    760  1.1  pk 	if (cp->type != AUDIO_MIXER_VALUE || cp->un.value.num_channels != 1)
    761  1.1  pk 		return(EINVAL);
    762  1.1  pk 
    763  1.1  pk 	switch(cp->dev) {
    764  1.1  pk 	    case SUNAUDIO_MIC_PORT:
    765  1.1  pk 		    sc->sc_rlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    766  1.1  pk 		    break;
    767  1.1  pk 	    case SUNAUDIO_SPEAKER:
    768  1.1  pk 	    case SUNAUDIO_HEADPHONES:
    769  1.1  pk 		    sc->sc_plevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    770  1.1  pk 		    break;
    771  1.1  pk 	    case SUNAUDIO_MONITOR:
    772  1.1  pk 		    sc->sc_mlevel = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    773  1.1  pk 		    break;
    774  1.1  pk 	    default:
    775  1.1  pk 		    return(EINVAL);
    776  1.1  pk 		    /* NOTREACHED */
    777  1.1  pk 	}
    778  1.1  pk 	return(0);
    779  1.1  pk }
    780  1.1  pk 
    781  1.1  pk int
    782  1.1  pk amd7930_get_port(addr, cp)
    783  1.1  pk 	void *addr;
    784  1.1  pk 	mixer_ctrl_t *cp;
    785  1.1  pk {
    786  1.1  pk 	register struct amd7930_softc *sc = addr;
    787  1.1  pk 
    788  1.1  pk 	DPRINTF(("amd7930_get_port: port=%d", cp->dev));
    789  1.1  pk 
    790  1.1  pk 	if (cp->type != AUDIO_MIXER_VALUE || cp->un.value.num_channels != 1)
    791  1.1  pk 		return(EINVAL);
    792  1.1  pk 
    793  1.1  pk 	switch(cp->dev) {
    794  1.1  pk 	    case SUNAUDIO_MIC_PORT:
    795  1.1  pk 		    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_rlevel;
    796  1.1  pk 		    break;
    797  1.1  pk 	    case SUNAUDIO_SPEAKER:
    798  1.1  pk 	    case SUNAUDIO_HEADPHONES:
    799  1.1  pk 		    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_plevel;
    800  1.1  pk 		    break;
    801  1.1  pk 	    case SUNAUDIO_MONITOR:
    802  1.1  pk 		    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_mlevel;
    803  1.1  pk 		    break;
    804  1.1  pk 	    default:
    805  1.1  pk 		    return(EINVAL);
    806  1.1  pk 		    /* NOTREACHED */
    807  1.1  pk 	}
    808  1.1  pk 	return(0);
    809  1.1  pk }
    810  1.1  pk 
    811  1.1  pk int
    812  1.1  pk amd7930_query_devinfo(addr, dip)
    813  1.1  pk 	void *addr;
    814  1.1  pk 	register mixer_devinfo_t *dip;
    815  1.1  pk {
    816  1.1  pk 	register struct amd7930_softc *sc = addr;
    817  1.1  pk 
    818  1.1  pk 	switch(dip->index) {
    819  1.1  pk 	    case SUNAUDIO_MIC_PORT:
    820  1.1  pk 		    dip->type = AUDIO_MIXER_VALUE;
    821  1.1  pk 		    dip->mixer_class = SUNAUDIO_INPUT_CLASS;
    822  1.1  pk 		    dip->prev = dip->next = AUDIO_MIXER_LAST;
    823  1.1  pk 		    strcpy(dip->label.name, AudioNmicrophone);
    824  1.1  pk 		    dip->un.v.num_channels = 1;
    825  1.1  pk 		    strcpy(dip->un.v.units.name, AudioNvolume);
    826  1.1  pk 		    break;
    827  1.1  pk 	    case SUNAUDIO_SPEAKER:
    828  1.1  pk 		    dip->type = AUDIO_MIXER_VALUE;
    829  1.1  pk 		    dip->mixer_class = SUNAUDIO_OUTPUT_CLASS;
    830  1.1  pk 		    dip->prev = dip->next = AUDIO_MIXER_LAST;
    831  1.1  pk 		    strcpy(dip->label.name, AudioNspeaker);
    832  1.1  pk 		    dip->un.v.num_channels = 1;
    833  1.1  pk 		    strcpy(dip->un.v.units.name, AudioNvolume);
    834  1.1  pk 		    break;
    835  1.1  pk 	    case SUNAUDIO_HEADPHONES:
    836  1.1  pk 		    dip->type = AUDIO_MIXER_VALUE;
    837  1.1  pk 		    dip->mixer_class = SUNAUDIO_OUTPUT_CLASS;
    838  1.1  pk 		    dip->prev = dip->next = AUDIO_MIXER_LAST;
    839  1.1  pk 		    strcpy(dip->label.name, AudioNheadphone);
    840  1.1  pk 		    dip->un.v.num_channels = 1;
    841  1.1  pk 		    strcpy(dip->un.v.units.name, AudioNvolume);
    842  1.1  pk 		    break;
    843  1.1  pk 	    case SUNAUDIO_MONITOR:
    844  1.1  pk 		    dip->type = AUDIO_MIXER_VALUE;
    845  1.1  pk 		    dip->mixer_class = SUNAUDIO_OUTPUT_CLASS;
    846  1.1  pk 		    dip->next = dip->prev = AUDIO_MIXER_LAST;
    847  1.1  pk 		    strcpy(dip->label.name, AudioNmonitor);
    848  1.1  pk 		    dip->un.v.num_channels = 1;
    849  1.1  pk 		    strcpy(dip->un.v.units.name, AudioNvolume);
    850  1.1  pk 		    break;
    851  1.1  pk 	    case SUNAUDIO_INPUT_CLASS:
    852  1.1  pk 		    dip->type = AUDIO_MIXER_CLASS;
    853  1.1  pk 		    dip->mixer_class = SUNAUDIO_INPUT_CLASS;
    854  1.1  pk 		    dip->next = dip->prev = AUDIO_MIXER_LAST;
    855  1.1  pk 		    strcpy(dip->label.name, AudioCInputs);
    856  1.1  pk 		    break;
    857  1.1  pk 	    case SUNAUDIO_OUTPUT_CLASS:
    858  1.1  pk 		    dip->type = AUDIO_MIXER_CLASS;
    859  1.1  pk 		    dip->mixer_class = SUNAUDIO_OUTPUT_CLASS;
    860  1.1  pk 		    dip->next = dip->prev = AUDIO_MIXER_LAST;
    861  1.1  pk 		    strcpy(dip->label.name, AudioCOutputs);
    862  1.1  pk 		    break;
    863  1.1  pk 	    default:
    864  1.1  pk 		    return ENXIO;
    865  1.1  pk 		    /*NOTREACHED*/
    866  1.1  pk 	}
    867  1.1  pk 
    868  1.1  pk 	DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
    869  1.1  pk 
    870  1.1  pk 	return(0);
    871  1.1  pk }
    872  1.1  pk 
    873  1.1  pk #ifdef AUDIO_C_HANDLER
    874  1.1  pk int
    875  1.1  pk amd7930hwintr(au0)
    876  1.1  pk 	void *au0;
    877  1.1  pk {
    878  1.1  pk 	register struct auio *au = au0;
    879  1.1  pk 	register volatile struct amd7930 *amd = au->au_amd;
    880  1.1  pk 	register u_char *d, *e;
    881  1.1  pk 	register int k;
    882  1.1  pk 
    883  1.1  pk 	k = amd->ir;		/* clear interrupt */
    884  1.1  pk 
    885  1.1  pk 	/* receive incoming data */
    886  1.1  pk 	d = au->au_rdata;
    887  1.1  pk 	e = au->au_rend;
    888  1.1  pk 	if (d && d <= e) {
    889  1.1  pk 		*d = amd->bbrb;
    890  1.1  pk 		au->au_rdata++;
    891  1.1  pk 		if (d == e) {
    892  1.1  pk #ifdef DEBUG
    893  1.1  pk 		        if (amd7930debug > 1)
    894  1.1  pk                 		Dprintf("amd7930hwintr: swintr(r) requested");
    895  1.1  pk #endif
    896  1.1  pk 			AUDIO_SET_SWINTR;
    897  1.1  pk 		}
    898  1.1  pk 	}
    899  1.1  pk 
    900  1.1  pk 	/* send outgoing data */
    901  1.1  pk 	d = au->au_pdata;
    902  1.1  pk 	e = au->au_pend;
    903  1.1  pk 	if (d && d <= e) {
    904  1.1  pk 		amd->bbtb = *d;
    905  1.1  pk 		au->au_pdata++;
    906  1.1  pk 		if (d == e) {
    907  1.1  pk #ifdef DEBUG
    908  1.1  pk 		        if (amd7930debug > 1)
    909  1.1  pk                 		Dprintf("amd7930hwintr: swintr(p) requested");
    910  1.1  pk #endif
    911  1.1  pk 			AUDIO_SET_SWINTR;
    912  1.1  pk 		}
    913  1.1  pk 	}
    914  1.1  pk 
    915  1.1  pk 	return (1);
    916  1.1  pk }
    917  1.1  pk #endif /* AUDIO_C_HANDLER */
    918  1.1  pk 
    919  1.1  pk int
    920  1.1  pk amd7930swintr(sc0)
    921  1.1  pk 	void *sc0;
    922  1.1  pk {
    923  1.1  pk 	register struct amd7930_softc *sc = sc0;
    924  1.1  pk 	register struct auio *au;
    925  1.1  pk 	register int s, ret = 0;
    926  1.1  pk 
    927  1.1  pk #ifdef DEBUG
    928  1.1  pk 	if (amd7930debug > 1)
    929  1.1  pk 		Dprintf("audiointr: sc=0x%x\n",sc);
    930  1.1  pk #endif
    931  1.1  pk 
    932  1.1  pk 	au = &sc->sc_au;
    933  1.1  pk 	s = splaudio();
    934  1.1  pk 	if (au->au_rdata > au->au_rend && sc->sc_rintr != NULL) {
    935  1.1  pk 		splx(s);
    936  1.1  pk 		ret = 1;
    937  1.1  pk 		(*sc->sc_rintr)(sc->sc_rarg);
    938  1.1  pk 		s = splaudio();
    939  1.1  pk 	}
    940  1.1  pk 	if (au->au_pdata > au->au_pend && sc->sc_pintr != NULL) {
    941  1.1  pk 		splx(s);
    942  1.1  pk 		ret = 1;
    943  1.1  pk 		(*sc->sc_pintr)(sc->sc_parg);
    944  1.1  pk 	} else
    945  1.1  pk 		splx(s);
    946  1.1  pk 	return (ret);
    947  1.1  pk }
    948  1.1  pk #endif /* NAUDIO > 0 */
    949