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