Home | History | Annotate | Line # | Download | only in mace
mavb.c revision 1.2.2.2
      1  1.2.2.2  yamt /* $NetBSD: mavb.c,v 1.2.2.2 2007/04/15 16:02:55 yamt Exp $ */
      2  1.2.2.2  yamt /* $OpenBSD: mavb.c,v 1.6 2005/04/15 13:05:14 mickey Exp $ */
      3  1.2.2.2  yamt 
      4  1.2.2.2  yamt /*
      5  1.2.2.2  yamt  * Copyright (c) 2005 Mark Kettenis
      6  1.2.2.2  yamt  *
      7  1.2.2.2  yamt  * Permission to use, copy, modify, and distribute this software for any
      8  1.2.2.2  yamt  * purpose with or without fee is hereby granted, provided that the above
      9  1.2.2.2  yamt  * copyright notice and this permission notice appear in all copies.
     10  1.2.2.2  yamt  *
     11  1.2.2.2  yamt  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  1.2.2.2  yamt  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  1.2.2.2  yamt  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  1.2.2.2  yamt  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  1.2.2.2  yamt  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16  1.2.2.2  yamt  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17  1.2.2.2  yamt  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  1.2.2.2  yamt  */
     19  1.2.2.2  yamt 
     20  1.2.2.2  yamt #include <sys/param.h>
     21  1.2.2.2  yamt #include <sys/systm.h>
     22  1.2.2.2  yamt #include <sys/device.h>
     23  1.2.2.2  yamt #include <sys/kernel.h>
     24  1.2.2.2  yamt #include <sys/malloc.h>
     25  1.2.2.2  yamt #include <sys/callout.h>
     26  1.2.2.2  yamt 
     27  1.2.2.2  yamt #include <machine/bus.h>
     28  1.2.2.2  yamt #include <machine/intr.h>
     29  1.2.2.2  yamt #include <machine/autoconf.h>
     30  1.2.2.2  yamt 
     31  1.2.2.2  yamt #include <sys/audioio.h>
     32  1.2.2.2  yamt #include <dev/auconv.h>
     33  1.2.2.2  yamt #include <dev/audio_if.h>
     34  1.2.2.2  yamt 
     35  1.2.2.2  yamt #include <arch/sgimips/mace/macevar.h>
     36  1.2.2.2  yamt #include <arch/sgimips/mace/macereg.h>
     37  1.2.2.2  yamt #include <arch/sgimips/mace/mavbreg.h>
     38  1.2.2.2  yamt 
     39  1.2.2.2  yamt #include <dev/ic/ad1843reg.h>
     40  1.2.2.2  yamt 
     41  1.2.2.2  yamt #undef MAVB_DEBUG
     42  1.2.2.2  yamt 
     43  1.2.2.2  yamt #ifdef MAVB_DEBUG
     44  1.2.2.2  yamt #define DPRINTF(l,x)	do { if (mavb_debug & (l)) printf x; } while (0)
     45  1.2.2.2  yamt #define MAVB_DEBUG_INTR		0x0100
     46  1.2.2.2  yamt int mavb_debug = ~MAVB_DEBUG_INTR;
     47  1.2.2.2  yamt #else
     48  1.2.2.2  yamt #define DPRINTF(l,x)	/* nothing */
     49  1.2.2.2  yamt #endif
     50  1.2.2.2  yamt 
     51  1.2.2.2  yamt /* Repeat delays for volume buttons.  */
     52  1.2.2.2  yamt #define MAVB_VOLUME_BUTTON_REPEAT_DEL1	400	/* 400ms to start repeating */
     53  1.2.2.2  yamt #define MAVB_VOLUME_BUTTON_REPEAT_DELN  100	/* 100ms between repeats */
     54  1.2.2.2  yamt 
     55  1.2.2.2  yamt /* XXX We need access to some of the MACE ISA registers.  */
     56  1.2.2.2  yamt #define MAVB_ISA_NREGS				0x20
     57  1.2.2.2  yamt 
     58  1.2.2.2  yamt /*
     59  1.2.2.2  yamt  * AD1843 Mixer.
     60  1.2.2.2  yamt  */
     61  1.2.2.2  yamt 
     62  1.2.2.2  yamt enum {
     63  1.2.2.2  yamt 	AD1843_RECORD_CLASS,
     64  1.2.2.2  yamt 	AD1843_ADC_SOURCE,	/* ADC Source Select */
     65  1.2.2.2  yamt 	AD1843_ADC_GAIN,	/* ADC Input Gain */
     66  1.2.2.2  yamt 
     67  1.2.2.2  yamt 	AD1843_INPUT_CLASS,
     68  1.2.2.2  yamt 	AD1843_DAC1_GAIN,	/* DAC1 Analog/Digital Gain/Attenuation */
     69  1.2.2.2  yamt 	AD1843_DAC1_MUTE,	/* DAC1 Analog Mute */
     70  1.2.2.2  yamt 	AD1843_DAC2_GAIN,	/* DAC2 Mix Gain */
     71  1.2.2.2  yamt 	AD1843_AUX1_GAIN,	/* Auxilliary 1 Mix Gain */
     72  1.2.2.2  yamt 	AD1843_AUX2_GAIN,	/* Auxilliary 2 Mix Gain */
     73  1.2.2.2  yamt 	AD1843_AUX3_GAIN,	/* Auxilliary 3 Mix Gain */
     74  1.2.2.2  yamt 	AD1843_MIC_GAIN,	/* Microphone Mix Gain */
     75  1.2.2.2  yamt 	AD1843_MONO_GAIN,	/* Mono Mix Gain */
     76  1.2.2.2  yamt 	AD1843_DAC2_MUTE,	/* DAC2 Mix Mute */
     77  1.2.2.2  yamt 	AD1843_AUX1_MUTE,	/* Auxilliary 1 Mix Mute */
     78  1.2.2.2  yamt 	AD1843_AUX2_MUTE,	/* Auxilliary 2 Mix Mute */
     79  1.2.2.2  yamt 	AD1843_AUX3_MUTE,	/* Auxilliary 3 Mix Mute */
     80  1.2.2.2  yamt 	AD1843_MIC_MUTE,	/* Microphone Mix Mute */
     81  1.2.2.2  yamt 	AD1843_MONO_MUTE,	/* Mono Mix Mute */
     82  1.2.2.2  yamt 	AD1843_SUM_MUTE,	/* Sum Mute */
     83  1.2.2.2  yamt 
     84  1.2.2.2  yamt 	AD1843_OUTPUT_CLASS,
     85  1.2.2.2  yamt 	AD1843_MNO_MUTE,	/* Mono Output Mute */
     86  1.2.2.2  yamt 	AD1843_HPO_MUTE		/* Headphone Output Mute */
     87  1.2.2.2  yamt };
     88  1.2.2.2  yamt 
     89  1.2.2.2  yamt /* ADC Source Select.  The order matches the hardware bits.  */
     90  1.2.2.2  yamt const char *ad1843_source[] = {
     91  1.2.2.2  yamt 	AudioNline,
     92  1.2.2.2  yamt 	AudioNmicrophone,
     93  1.2.2.2  yamt 	AudioNaux "1",
     94  1.2.2.2  yamt 	AudioNaux "2",
     95  1.2.2.2  yamt 	AudioNaux "3",
     96  1.2.2.2  yamt 	AudioNmono,
     97  1.2.2.2  yamt 	AudioNdac "1",
     98  1.2.2.2  yamt 	AudioNdac "2"
     99  1.2.2.2  yamt };
    100  1.2.2.2  yamt 
    101  1.2.2.2  yamt /* Mix Control.  The order matches the hardware register numbering.  */
    102  1.2.2.2  yamt const char *ad1843_input[] = {
    103  1.2.2.2  yamt 	AudioNdac "2",		/* AD1843_DAC2__TO_MIXER */
    104  1.2.2.2  yamt 	AudioNaux "1",
    105  1.2.2.2  yamt 	AudioNaux "2",
    106  1.2.2.2  yamt 	AudioNaux "3",
    107  1.2.2.2  yamt 	AudioNmicrophone,
    108  1.2.2.2  yamt 	AudioNmono		/* AD1843_MISC_SETTINGS */
    109  1.2.2.2  yamt };
    110  1.2.2.2  yamt 
    111  1.2.2.2  yamt struct mavb_softc {
    112  1.2.2.2  yamt 	struct device sc_dev;
    113  1.2.2.2  yamt 	bus_space_tag_t sc_st;
    114  1.2.2.2  yamt 	bus_space_handle_t sc_sh;
    115  1.2.2.2  yamt 	bus_dma_tag_t sc_dmat;
    116  1.2.2.2  yamt 	bus_dmamap_t sc_dmamap;
    117  1.2.2.2  yamt 
    118  1.2.2.2  yamt 	/* XXX We need access to some of the MACE ISA registers.  */
    119  1.2.2.2  yamt 	bus_space_handle_t sc_isash;
    120  1.2.2.2  yamt 
    121  1.2.2.2  yamt #define MAVB_ISA_RING_SIZE		0x1000
    122  1.2.2.2  yamt 	uint8_t *sc_ring;
    123  1.2.2.2  yamt 
    124  1.2.2.2  yamt 	uint8_t *sc_start, *sc_end;
    125  1.2.2.2  yamt 	int sc_blksize;
    126  1.2.2.2  yamt 	void (*sc_intr)(void *);
    127  1.2.2.2  yamt 	void *sc_intrarg;
    128  1.2.2.2  yamt 
    129  1.2.2.2  yamt 	void *sc_get;
    130  1.2.2.2  yamt 	int sc_count;
    131  1.2.2.2  yamt 
    132  1.2.2.2  yamt 	u_long sc_play_rate;
    133  1.2.2.2  yamt 	u_int sc_play_format;
    134  1.2.2.2  yamt 
    135  1.2.2.2  yamt 	struct callout sc_volume_button_ch;
    136  1.2.2.2  yamt };
    137  1.2.2.2  yamt 
    138  1.2.2.2  yamt /* XXX mavb supports way more than this, but for now I'm going to be
    139  1.2.2.2  yamt  *     lazy and let auconv work its magic
    140  1.2.2.2  yamt  */
    141  1.2.2.2  yamt #define MAVB_NENCODINGS 8
    142  1.2.2.2  yamt static audio_encoding_t mavb_encoding[MAVB_NENCODINGS] = {
    143  1.2.2.2  yamt 	{ 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8,
    144  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    145  1.2.2.2  yamt 	{ 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
    146  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    147  1.2.2.2  yamt 	{ 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8,
    148  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    149  1.2.2.2  yamt 	{ 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8,
    150  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    151  1.2.2.2  yamt 	{ 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR, 16,
    152  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    153  1.2.2.2  yamt 	{ 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR, 16,
    154  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    155  1.2.2.2  yamt 	{ 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR, 16,
    156  1.2.2.2  yamt 	  0 },
    157  1.2.2.2  yamt 	{ 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR, 16,
    158  1.2.2.2  yamt 	  AUDIO_ENCODINGFLAG_EMULATED },
    159  1.2.2.2  yamt };
    160  1.2.2.2  yamt 
    161  1.2.2.2  yamt #define MAVB_NFORMATS 3
    162  1.2.2.2  yamt static const struct audio_format mavb_formats[MAVB_NFORMATS] = {
    163  1.2.2.2  yamt 	{ NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
    164  1.2.2.2  yamt 	  2, AUFMT_STEREO, 0, { 8000, 48000 } },
    165  1.2.2.2  yamt 	{ NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
    166  1.2.2.2  yamt 	  1, AUFMT_MONAURAL, 0, { 8000, 48000 } },
    167  1.2.2.2  yamt };
    168  1.2.2.2  yamt 
    169  1.2.2.2  yamt struct mavb_codecvar {
    170  1.2.2.2  yamt 	stream_filter_t base;
    171  1.2.2.2  yamt };
    172  1.2.2.2  yamt 
    173  1.2.2.2  yamt static stream_filter_t *mavb_factory
    174  1.2.2.2  yamt     (int (*)(stream_fetcher_t *, audio_stream_t *, int));
    175  1.2.2.2  yamt static void mavb_dtor(stream_filter_t *);
    176  1.2.2.2  yamt 
    177  1.2.2.2  yamt /* XXX I'm going to complain every time I have to copy this macro */
    178  1.2.2.2  yamt #define DEFINE_FILTER(name)	\
    179  1.2.2.2  yamt static int \
    180  1.2.2.2  yamt name##_fetch_to(stream_fetcher_t *, audio_stream_t *, int); \
    181  1.2.2.2  yamt stream_filter_t *name(struct audio_softc *, \
    182  1.2.2.2  yamt     const audio_params_t *, const audio_params_t *); \
    183  1.2.2.2  yamt stream_filter_t * \
    184  1.2.2.2  yamt name(struct audio_softc *sc, const audio_params_t *from, \
    185  1.2.2.2  yamt     const audio_params_t *to) \
    186  1.2.2.2  yamt { \
    187  1.2.2.2  yamt 	return mavb_factory(name##_fetch_to); \
    188  1.2.2.2  yamt } \
    189  1.2.2.2  yamt static int \
    190  1.2.2.2  yamt name##_fetch_to(stream_fetcher_t *self, audio_stream_t *dst, int max_used)
    191  1.2.2.2  yamt 
    192  1.2.2.2  yamt DEFINE_FILTER(mavb_16to24)
    193  1.2.2.2  yamt {
    194  1.2.2.2  yamt 	stream_filter_t *this;
    195  1.2.2.2  yamt 	int m, err;
    196  1.2.2.2  yamt 
    197  1.2.2.2  yamt 	this = (stream_filter_t *)self;
    198  1.2.2.2  yamt 	max_used = (max_used + 1) & ~1;
    199  1.2.2.2  yamt 	if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
    200  1.2.2.2  yamt 		return err;
    201  1.2.2.2  yamt 	m = (dst->end - dst->start) & ~1;
    202  1.2.2.2  yamt 	m = min(m, max_used);
    203  1.2.2.2  yamt 	FILTER_LOOP_PROLOGUE(this->src, 2, dst, 4, m) {
    204  1.2.2.2  yamt 		d[3] = 0;
    205  1.2.2.2  yamt 		d[2] = s[1];
    206  1.2.2.2  yamt 		d[1] = s[0];
    207  1.2.2.2  yamt 		d[0] = (s[0] & 0x80) ? 0xff : 0;
    208  1.2.2.2  yamt 	} FILTER_LOOP_EPILOGUE(this->src, dst);
    209  1.2.2.2  yamt 
    210  1.2.2.2  yamt 	return 0;
    211  1.2.2.2  yamt }
    212  1.2.2.2  yamt 
    213  1.2.2.2  yamt DEFINE_FILTER(mavb_mts)
    214  1.2.2.2  yamt {
    215  1.2.2.2  yamt 	stream_filter_t *this;
    216  1.2.2.2  yamt 	int m, err;
    217  1.2.2.2  yamt 
    218  1.2.2.2  yamt 	this = (stream_filter_t *)self;
    219  1.2.2.2  yamt 	max_used = (max_used + 1) & ~1;
    220  1.2.2.2  yamt 	if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
    221  1.2.2.2  yamt 		return err;
    222  1.2.2.2  yamt 	m = (dst->end - dst->start) & ~1;
    223  1.2.2.2  yamt 	m = min(m, max_used);
    224  1.2.2.2  yamt 	FILTER_LOOP_PROLOGUE(this->src, 4, dst, 8, m) {
    225  1.2.2.2  yamt 		d[3] = d[7] = s[3];
    226  1.2.2.2  yamt 		d[2] = d[6] = s[2];
    227  1.2.2.2  yamt 		d[1] = d[5] = s[1];
    228  1.2.2.2  yamt 		d[0] = d[4] = s[0];
    229  1.2.2.2  yamt 	} FILTER_LOOP_EPILOGUE(this->src, dst);
    230  1.2.2.2  yamt 
    231  1.2.2.2  yamt 	return 0;
    232  1.2.2.2  yamt }
    233  1.2.2.2  yamt 
    234  1.2.2.2  yamt static stream_filter_t *
    235  1.2.2.2  yamt mavb_factory(int (*fetch_to)(stream_fetcher_t *, audio_stream_t *, int))
    236  1.2.2.2  yamt {
    237  1.2.2.2  yamt 	struct mavb_codecvar *this;
    238  1.2.2.2  yamt 
    239  1.2.2.2  yamt 	this = malloc(sizeof(*this), M_DEVBUF, M_WAITOK | M_ZERO);
    240  1.2.2.2  yamt 	this->base.base.fetch_to = fetch_to;
    241  1.2.2.2  yamt 	this->base.dtor = mavb_dtor;
    242  1.2.2.2  yamt 	this->base.set_fetcher = stream_filter_set_fetcher;
    243  1.2.2.2  yamt 	this->base.set_inputbuffer = stream_filter_set_inputbuffer;
    244  1.2.2.2  yamt 
    245  1.2.2.2  yamt 	return &this->base;
    246  1.2.2.2  yamt }
    247  1.2.2.2  yamt 
    248  1.2.2.2  yamt static void
    249  1.2.2.2  yamt mavb_dtor(stream_filter_t *this)
    250  1.2.2.2  yamt {
    251  1.2.2.2  yamt 	if (this != NULL)
    252  1.2.2.2  yamt 		free(this, M_DEVBUF);
    253  1.2.2.2  yamt }
    254  1.2.2.2  yamt 
    255  1.2.2.2  yamt typedef u_int64_t ad1843_addr_t;
    256  1.2.2.2  yamt 
    257  1.2.2.2  yamt u_int16_t ad1843_reg_read(struct mavb_softc *, ad1843_addr_t);
    258  1.2.2.2  yamt u_int16_t ad1843_reg_write(struct mavb_softc *, ad1843_addr_t, u_int16_t);
    259  1.2.2.2  yamt void ad1843_dump_regs(struct mavb_softc *);
    260  1.2.2.2  yamt 
    261  1.2.2.2  yamt int mavb_match(struct device *, struct cfdata *, void *);
    262  1.2.2.2  yamt void mavb_attach(struct device *, struct device *, void *);
    263  1.2.2.2  yamt 
    264  1.2.2.2  yamt CFATTACH_DECL(mavb, sizeof(struct mavb_softc),
    265  1.2.2.2  yamt     mavb_match, mavb_attach, NULL, NULL);
    266  1.2.2.2  yamt 
    267  1.2.2.2  yamt int mavb_open(void *, int);
    268  1.2.2.2  yamt void mavb_close(void *);
    269  1.2.2.2  yamt int mavb_query_encoding(void *, struct audio_encoding *);
    270  1.2.2.2  yamt int mavb_set_params(void *, int, int, struct audio_params *,
    271  1.2.2.2  yamt 		    struct audio_params *, stream_filter_list_t *,
    272  1.2.2.2  yamt 		    stream_filter_list_t *);
    273  1.2.2.2  yamt int mavb_round_blocksize(void *hdl, int, int, const audio_params_t *);
    274  1.2.2.2  yamt int mavb_halt_output(void *);
    275  1.2.2.2  yamt int mavb_halt_input(void *);
    276  1.2.2.2  yamt int mavb_getdev(void *, struct audio_device *);
    277  1.2.2.2  yamt int mavb_set_port(void *, struct mixer_ctrl *);
    278  1.2.2.2  yamt int mavb_get_port(void *, struct mixer_ctrl *);
    279  1.2.2.2  yamt int mavb_query_devinfo(void *, struct mixer_devinfo *);
    280  1.2.2.2  yamt size_t mavb_round_buffersize(void *, int, size_t);
    281  1.2.2.2  yamt int mavb_get_props(void *);
    282  1.2.2.2  yamt int mavb_trigger_output(void *, void *, void *, int, void (*)(void *),
    283  1.2.2.2  yamt 			void *, const audio_params_t *);
    284  1.2.2.2  yamt int mavb_trigger_input(void *, void *, void *, int, void (*)(void *),
    285  1.2.2.2  yamt 		       void *, const audio_params_t *);
    286  1.2.2.2  yamt 
    287  1.2.2.2  yamt struct audio_hw_if mavb_sa_hw_if = {
    288  1.2.2.2  yamt 	mavb_open,
    289  1.2.2.2  yamt 	mavb_close,
    290  1.2.2.2  yamt 	0,
    291  1.2.2.2  yamt 	mavb_query_encoding,
    292  1.2.2.2  yamt 	mavb_set_params,
    293  1.2.2.2  yamt 	mavb_round_blocksize,
    294  1.2.2.2  yamt 	0,
    295  1.2.2.2  yamt 	0,
    296  1.2.2.2  yamt 	0,
    297  1.2.2.2  yamt 	0,
    298  1.2.2.2  yamt 	0,
    299  1.2.2.2  yamt 	mavb_halt_output,
    300  1.2.2.2  yamt 	mavb_halt_input,
    301  1.2.2.2  yamt 	0,
    302  1.2.2.2  yamt 	mavb_getdev,
    303  1.2.2.2  yamt 	0,
    304  1.2.2.2  yamt 	mavb_set_port,
    305  1.2.2.2  yamt 	mavb_get_port,
    306  1.2.2.2  yamt 	mavb_query_devinfo,
    307  1.2.2.2  yamt 	0,
    308  1.2.2.2  yamt 	0,
    309  1.2.2.2  yamt 	mavb_round_buffersize,
    310  1.2.2.2  yamt 	0,
    311  1.2.2.2  yamt 	mavb_get_props,
    312  1.2.2.2  yamt 	mavb_trigger_output,
    313  1.2.2.2  yamt 	mavb_trigger_input,
    314  1.2.2.2  yamt 	NULL,
    315  1.2.2.2  yamt };
    316  1.2.2.2  yamt 
    317  1.2.2.2  yamt struct audio_device mavb_device = {
    318  1.2.2.2  yamt 	"A3",
    319  1.2.2.2  yamt 	"",
    320  1.2.2.2  yamt 	"mavb"
    321  1.2.2.2  yamt };
    322  1.2.2.2  yamt 
    323  1.2.2.2  yamt int
    324  1.2.2.2  yamt mavb_open(void *hdl, int flags)
    325  1.2.2.2  yamt {
    326  1.2.2.2  yamt 	return (0);
    327  1.2.2.2  yamt }
    328  1.2.2.2  yamt 
    329  1.2.2.2  yamt void
    330  1.2.2.2  yamt mavb_close(void *hdl)
    331  1.2.2.2  yamt {
    332  1.2.2.2  yamt }
    333  1.2.2.2  yamt 
    334  1.2.2.2  yamt int
    335  1.2.2.2  yamt mavb_query_encoding(void *hdl, struct audio_encoding *ae)
    336  1.2.2.2  yamt {
    337  1.2.2.2  yamt 	if (ae->index < 0 || ae->index >= MAVB_NENCODINGS)
    338  1.2.2.2  yamt 		return (EINVAL);
    339  1.2.2.2  yamt 	*ae = mavb_encoding[ae->index];
    340  1.2.2.2  yamt 
    341  1.2.2.2  yamt 	return (0);
    342  1.2.2.2  yamt }
    343  1.2.2.2  yamt 
    344  1.2.2.2  yamt static int
    345  1.2.2.2  yamt mavb_set_play_rate(struct mavb_softc *sc, u_long sample_rate)
    346  1.2.2.2  yamt {
    347  1.2.2.2  yamt 	if (sample_rate < 4000 || sample_rate > 48000)
    348  1.2.2.2  yamt 		return (EINVAL);
    349  1.2.2.2  yamt 
    350  1.2.2.2  yamt 	if (sc->sc_play_rate != sample_rate) {
    351  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_CLOCK2_SAMPLE_RATE, sample_rate);
    352  1.2.2.2  yamt 		sc->sc_play_rate = sample_rate;
    353  1.2.2.2  yamt 	}
    354  1.2.2.2  yamt 	return (0);
    355  1.2.2.2  yamt }
    356  1.2.2.2  yamt 
    357  1.2.2.2  yamt static int
    358  1.2.2.2  yamt mavb_set_play_format(struct mavb_softc *sc, u_int encoding)
    359  1.2.2.2  yamt {
    360  1.2.2.2  yamt 	u_int16_t value;
    361  1.2.2.2  yamt 	u_int format;
    362  1.2.2.2  yamt 
    363  1.2.2.2  yamt 	switch(encoding) {
    364  1.2.2.2  yamt 	case AUDIO_ENCODING_ULINEAR_BE:
    365  1.2.2.2  yamt 		format = AD1843_PCM8;
    366  1.2.2.2  yamt 		break;
    367  1.2.2.2  yamt 	case AUDIO_ENCODING_SLINEAR_BE:
    368  1.2.2.2  yamt 		format = AD1843_PCM16;
    369  1.2.2.2  yamt 		break;
    370  1.2.2.2  yamt 	case AUDIO_ENCODING_ULAW:
    371  1.2.2.2  yamt 		format = AD1843_ULAW;
    372  1.2.2.2  yamt 		break;
    373  1.2.2.2  yamt 	case AUDIO_ENCODING_ALAW:
    374  1.2.2.2  yamt 		format = AD1843_ALAW;
    375  1.2.2.2  yamt 		break;
    376  1.2.2.2  yamt 	default:
    377  1.2.2.2  yamt 		return (EINVAL);
    378  1.2.2.2  yamt 	}
    379  1.2.2.2  yamt 
    380  1.2.2.2  yamt 	if (sc->sc_play_format != format) {
    381  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
    382  1.2.2.2  yamt 		value &= ~AD1843_DA1F_MASK;
    383  1.2.2.2  yamt 		value |= (format << AD1843_DA1F_SHIFT);
    384  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value);
    385  1.2.2.2  yamt 		sc->sc_play_format = format;
    386  1.2.2.2  yamt 	}
    387  1.2.2.2  yamt 	return (0);
    388  1.2.2.2  yamt }
    389  1.2.2.2  yamt 
    390  1.2.2.2  yamt int
    391  1.2.2.2  yamt mavb_set_params(void *hdl, int setmode, int usemode,
    392  1.2.2.2  yamt     struct audio_params *play, struct audio_params *rec,
    393  1.2.2.2  yamt     stream_filter_list_t *pfil, stream_filter_list_t *rfil)
    394  1.2.2.2  yamt {
    395  1.2.2.2  yamt 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    396  1.2.2.2  yamt 	struct audio_params *p;
    397  1.2.2.2  yamt 	stream_filter_list_t *fil;
    398  1.2.2.2  yamt 	int error;
    399  1.2.2.2  yamt 
    400  1.2.2.2  yamt 	DPRINTF(1, ("%s: mavb_set_params: sample=%u precision=%d "
    401  1.2.2.2  yamt 	    "channels=%d\n", sc->sc_dev.dv_xname, play->sample_rate,
    402  1.2.2.2  yamt 	    play->precision, play->channels));
    403  1.2.2.2  yamt 
    404  1.2.2.2  yamt 	if (setmode & AUMODE_PLAY) {
    405  1.2.2.2  yamt 		if (play->sample_rate < 4000 || play->sample_rate > 48000)
    406  1.2.2.2  yamt 			return (EINVAL);
    407  1.2.2.2  yamt 
    408  1.2.2.2  yamt 		p = play;
    409  1.2.2.2  yamt 		fil = pfil;
    410  1.2.2.2  yamt 		if (auconv_set_converter(mavb_formats, MAVB_NFORMATS,
    411  1.2.2.2  yamt 		    AUMODE_PLAY, p, FALSE, fil) < 0)
    412  1.2.2.2  yamt 			return (EINVAL);
    413  1.2.2.2  yamt 
    414  1.2.2.2  yamt 		fil->append(fil, mavb_16to24, p);
    415  1.2.2.2  yamt 		if (p->channels == 1)
    416  1.2.2.2  yamt 			fil->append(fil, mavb_mts, p);
    417  1.2.2.2  yamt 		if (fil->req_size > 0)
    418  1.2.2.2  yamt 			p = &fil->filters[0].param;
    419  1.2.2.2  yamt 
    420  1.2.2.2  yamt 		error = mavb_set_play_rate(sc, p->sample_rate);
    421  1.2.2.2  yamt 		if (error)
    422  1.2.2.2  yamt 			return (error);
    423  1.2.2.2  yamt 
    424  1.2.2.2  yamt 		error = mavb_set_play_format(sc, p->encoding);
    425  1.2.2.2  yamt 		if (error)
    426  1.2.2.2  yamt 			return (error);
    427  1.2.2.2  yamt 	}
    428  1.2.2.2  yamt 
    429  1.2.2.2  yamt #if 0
    430  1.2.2.2  yamt 	if (setmode & AUMODE_RECORD) {
    431  1.2.2.2  yamt 		if (rec->sample_rate < 4000 || rec->sample_rate > 48000)
    432  1.2.2.2  yamt 			return (EINVAL);
    433  1.2.2.2  yamt 	}
    434  1.2.2.2  yamt #endif
    435  1.2.2.2  yamt 
    436  1.2.2.2  yamt 	return (0);
    437  1.2.2.2  yamt }
    438  1.2.2.2  yamt 
    439  1.2.2.2  yamt int
    440  1.2.2.2  yamt mavb_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *p)
    441  1.2.2.2  yamt {
    442  1.2.2.2  yamt 	/* Block size should be a multiple of 32.  */
    443  1.2.2.2  yamt 	return (bs + 0x1f) & ~0x1f;
    444  1.2.2.2  yamt }
    445  1.2.2.2  yamt 
    446  1.2.2.2  yamt int
    447  1.2.2.2  yamt mavb_halt_output(void *hdl)
    448  1.2.2.2  yamt {
    449  1.2.2.2  yamt 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    450  1.2.2.2  yamt 
    451  1.2.2.2  yamt 	DPRINTF(1, ("%s: mavb_halt_output called\n", sc->sc_dev.dv_xname));
    452  1.2.2.2  yamt 
    453  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
    454  1.2.2.2  yamt 	return (0);
    455  1.2.2.2  yamt }
    456  1.2.2.2  yamt 
    457  1.2.2.2  yamt int
    458  1.2.2.2  yamt mavb_halt_input(void *hdl)
    459  1.2.2.2  yamt {
    460  1.2.2.2  yamt 	return (0);
    461  1.2.2.2  yamt }
    462  1.2.2.2  yamt 
    463  1.2.2.2  yamt int
    464  1.2.2.2  yamt mavb_getdev(void *hdl, struct audio_device *ret)
    465  1.2.2.2  yamt {
    466  1.2.2.2  yamt 	*ret = mavb_device;
    467  1.2.2.2  yamt 	return (0);
    468  1.2.2.2  yamt }
    469  1.2.2.2  yamt 
    470  1.2.2.2  yamt int
    471  1.2.2.2  yamt mavb_set_port(void *hdl, struct mixer_ctrl *mc)
    472  1.2.2.2  yamt {
    473  1.2.2.2  yamt 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    474  1.2.2.2  yamt 	u_char left, right;
    475  1.2.2.2  yamt 	ad1843_addr_t reg;
    476  1.2.2.2  yamt 	u_int16_t value;
    477  1.2.2.2  yamt 
    478  1.2.2.2  yamt 	DPRINTF(1, ("%s: mavb_set_port: dev=%d\n", sc->sc_dev.dv_xname,
    479  1.2.2.2  yamt 	    mc->dev));
    480  1.2.2.2  yamt 
    481  1.2.2.2  yamt 	switch (mc->dev) {
    482  1.2.2.2  yamt 	case AD1843_ADC_SOURCE:
    483  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    484  1.2.2.2  yamt 		value &= ~(AD1843_LSS_MASK | AD1843_RSS_MASK);
    485  1.2.2.2  yamt 		value |= ((mc->un.ord << AD1843_LSS_SHIFT) & AD1843_LSS_MASK);
    486  1.2.2.2  yamt 		value |= ((mc->un.ord << AD1843_RSS_SHIFT) & AD1843_RSS_MASK);
    487  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
    488  1.2.2.2  yamt 		break;
    489  1.2.2.2  yamt 	case AD1843_ADC_GAIN:
    490  1.2.2.2  yamt 		left = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    491  1.2.2.2  yamt 		right = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    492  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    493  1.2.2.2  yamt 		value &= ~(AD1843_LIG_MASK | AD1843_RIG_MASK);
    494  1.2.2.2  yamt 		value |= ((left >> 4) << AD1843_LIG_SHIFT);
    495  1.2.2.2  yamt 		value |= ((right >> 4) << AD1843_RIG_SHIFT);
    496  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
    497  1.2.2.2  yamt 		break;
    498  1.2.2.2  yamt 
    499  1.2.2.2  yamt 	case AD1843_DAC1_GAIN:
    500  1.2.2.2  yamt 		left = AUDIO_MAX_GAIN -
    501  1.2.2.2  yamt 		    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    502  1.2.2.2  yamt 		right = AUDIO_MAX_GAIN -
    503  1.2.2.2  yamt                     mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    504  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    505  1.2.2.2  yamt 		value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
    506  1.2.2.2  yamt 		value |= ((left >> 2) << AD1843_LDA1G_SHIFT);
    507  1.2.2.2  yamt 		value |= ((right >> 2) << AD1843_RDA1G_SHIFT);
    508  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    509  1.2.2.2  yamt 		break;
    510  1.2.2.2  yamt 	case AD1843_DAC1_MUTE:
    511  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    512  1.2.2.2  yamt 		if (mc->un.ord == 0)
    513  1.2.2.2  yamt 			value &= ~(AD1843_LDA1GM | AD1843_RDA1GM);
    514  1.2.2.2  yamt 		else
    515  1.2.2.2  yamt 			value |= (AD1843_LDA1GM | AD1843_RDA1GM);
    516  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    517  1.2.2.2  yamt 		break;
    518  1.2.2.2  yamt 
    519  1.2.2.2  yamt 	case AD1843_DAC2_GAIN:
    520  1.2.2.2  yamt 	case AD1843_AUX1_GAIN:
    521  1.2.2.2  yamt 	case AD1843_AUX2_GAIN:
    522  1.2.2.2  yamt 	case AD1843_AUX3_GAIN:
    523  1.2.2.2  yamt 	case AD1843_MIC_GAIN:
    524  1.2.2.2  yamt 		left = AUDIO_MAX_GAIN -
    525  1.2.2.2  yamt 		    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    526  1.2.2.2  yamt 		right = AUDIO_MAX_GAIN -
    527  1.2.2.2  yamt                     mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    528  1.2.2.2  yamt 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
    529  1.2.2.2  yamt 		value = ad1843_reg_read(sc, reg);
    530  1.2.2.2  yamt 		value &= ~(AD1843_LD2M_MASK | AD1843_RD2M_MASK);
    531  1.2.2.2  yamt 		value |= ((left >> 3) << AD1843_LD2M_SHIFT);
    532  1.2.2.2  yamt 		value |= ((right >> 3) << AD1843_RD2M_SHIFT);
    533  1.2.2.2  yamt 		ad1843_reg_write(sc, reg, value);
    534  1.2.2.2  yamt 		break;
    535  1.2.2.2  yamt 	case AD1843_MONO_GAIN:
    536  1.2.2.2  yamt 		left = AUDIO_MAX_GAIN -
    537  1.2.2.2  yamt 		    mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    538  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    539  1.2.2.2  yamt 		value &= ~AD1843_MNM_MASK;
    540  1.2.2.2  yamt 		value |= ((left >> 3) << AD1843_MNM_SHIFT);
    541  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    542  1.2.2.2  yamt 		break;
    543  1.2.2.2  yamt 	case AD1843_DAC2_MUTE:
    544  1.2.2.2  yamt 	case AD1843_AUX1_MUTE:
    545  1.2.2.2  yamt 	case AD1843_AUX2_MUTE:
    546  1.2.2.2  yamt 	case AD1843_AUX3_MUTE:
    547  1.2.2.2  yamt 	case AD1843_MIC_MUTE:
    548  1.2.2.2  yamt 	case AD1843_MONO_MUTE:	/* matches left channel */
    549  1.2.2.2  yamt 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
    550  1.2.2.2  yamt 		value = ad1843_reg_read(sc, reg);
    551  1.2.2.2  yamt 		if (mc->un.ord == 0)
    552  1.2.2.2  yamt 			value &= ~(AD1843_LD2MM | AD1843_RD2MM);
    553  1.2.2.2  yamt 		else
    554  1.2.2.2  yamt 			value |= (AD1843_LD2MM | AD1843_RD2MM);
    555  1.2.2.2  yamt 		ad1843_reg_write(sc, reg, value);
    556  1.2.2.2  yamt 		break;
    557  1.2.2.2  yamt 
    558  1.2.2.2  yamt 	case AD1843_SUM_MUTE:
    559  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    560  1.2.2.2  yamt 		if (mc->un.ord == 0)
    561  1.2.2.2  yamt 			value &= ~AD1843_SUMM;
    562  1.2.2.2  yamt 		else
    563  1.2.2.2  yamt 			value |= AD1843_SUMM;
    564  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    565  1.2.2.2  yamt 		break;
    566  1.2.2.2  yamt 
    567  1.2.2.2  yamt 	case AD1843_MNO_MUTE:
    568  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    569  1.2.2.2  yamt 		if (mc->un.ord == 0)
    570  1.2.2.2  yamt 			value &= ~AD1843_MNOM;
    571  1.2.2.2  yamt 		else
    572  1.2.2.2  yamt 			value |= AD1843_MNOM;
    573  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    574  1.2.2.2  yamt 		break;
    575  1.2.2.2  yamt 
    576  1.2.2.2  yamt 	case AD1843_HPO_MUTE:
    577  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    578  1.2.2.2  yamt 		if (mc->un.ord == 0)
    579  1.2.2.2  yamt 			value &= ~AD1843_HPOM;
    580  1.2.2.2  yamt 		else
    581  1.2.2.2  yamt 			value |= AD1843_HPOM;
    582  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    583  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    584  1.2.2.2  yamt 		break;
    585  1.2.2.2  yamt 
    586  1.2.2.2  yamt 	default:
    587  1.2.2.2  yamt 		return (EINVAL);
    588  1.2.2.2  yamt 	}
    589  1.2.2.2  yamt 
    590  1.2.2.2  yamt 	return (0);
    591  1.2.2.2  yamt }
    592  1.2.2.2  yamt 
    593  1.2.2.2  yamt int
    594  1.2.2.2  yamt mavb_get_port(void *hdl, struct mixer_ctrl *mc)
    595  1.2.2.2  yamt {
    596  1.2.2.2  yamt 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    597  1.2.2.2  yamt 	u_char left, right;
    598  1.2.2.2  yamt 	ad1843_addr_t reg;
    599  1.2.2.2  yamt 	u_int16_t value;
    600  1.2.2.2  yamt 
    601  1.2.2.2  yamt 	DPRINTF(1, ("%s: mavb_get_port: dev=%d\n", sc->sc_dev.dv_xname,
    602  1.2.2.2  yamt 	    mc->dev));
    603  1.2.2.2  yamt 
    604  1.2.2.2  yamt 	switch (mc->dev) {
    605  1.2.2.2  yamt 	case AD1843_ADC_SOURCE:
    606  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    607  1.2.2.2  yamt 		mc->un.ord = (value & AD1843_LSS_MASK) >> AD1843_LSS_SHIFT;
    608  1.2.2.2  yamt 		break;
    609  1.2.2.2  yamt 	case AD1843_ADC_GAIN:
    610  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    611  1.2.2.2  yamt 		left = (value & AD1843_LIG_MASK) >> AD1843_LIG_SHIFT;
    612  1.2.2.2  yamt 		right = (value & AD1843_RIG_MASK) >> AD1843_RIG_SHIFT;
    613  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    614  1.2.2.2  yamt 		    (left << 4) | left;
    615  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    616  1.2.2.2  yamt 		    (right << 2) | right;
    617  1.2.2.2  yamt 		break;
    618  1.2.2.2  yamt 
    619  1.2.2.2  yamt 	case AD1843_DAC1_GAIN:
    620  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    621  1.2.2.2  yamt 		left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
    622  1.2.2.2  yamt 		right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
    623  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    624  1.2.2.2  yamt 		    AUDIO_MAX_GAIN - (left << 2);
    625  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    626  1.2.2.2  yamt 		    AUDIO_MAX_GAIN - (right << 2);
    627  1.2.2.2  yamt 		break;
    628  1.2.2.2  yamt 	case AD1843_DAC1_MUTE:
    629  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    630  1.2.2.2  yamt 		mc->un.ord = (value & AD1843_LDA1GM) ? 1 : 0;
    631  1.2.2.2  yamt 		break;
    632  1.2.2.2  yamt 
    633  1.2.2.2  yamt 	case AD1843_DAC2_GAIN:
    634  1.2.2.2  yamt 	case AD1843_AUX1_GAIN:
    635  1.2.2.2  yamt 	case AD1843_AUX2_GAIN:
    636  1.2.2.2  yamt 	case AD1843_AUX3_GAIN:
    637  1.2.2.2  yamt 	case AD1843_MIC_GAIN:
    638  1.2.2.2  yamt 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
    639  1.2.2.2  yamt 		value = ad1843_reg_read(sc, reg);
    640  1.2.2.2  yamt 		left = (value & AD1843_LD2M_MASK) >> AD1843_LD2M_SHIFT;
    641  1.2.2.2  yamt 		right = (value & AD1843_RD2M_MASK) >> AD1843_RD2M_SHIFT;
    642  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    643  1.2.2.2  yamt 		    AUDIO_MAX_GAIN - (left << 3);
    644  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    645  1.2.2.2  yamt 		    AUDIO_MAX_GAIN - (right << 3);
    646  1.2.2.2  yamt 		break;
    647  1.2.2.2  yamt 	case AD1843_MONO_GAIN:
    648  1.2.2.2  yamt 		if (mc->un.value.num_channels != 1)
    649  1.2.2.2  yamt 			return (EINVAL);
    650  1.2.2.2  yamt 
    651  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    652  1.2.2.2  yamt 		left = (value & AD1843_MNM_MASK) >> AD1843_MNM_SHIFT;
    653  1.2.2.2  yamt 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    654  1.2.2.2  yamt 		    AUDIO_MAX_GAIN - (left << 3);
    655  1.2.2.2  yamt 		break;
    656  1.2.2.2  yamt 	case AD1843_DAC2_MUTE:
    657  1.2.2.2  yamt 	case AD1843_AUX1_MUTE:
    658  1.2.2.2  yamt 	case AD1843_AUX2_MUTE:
    659  1.2.2.2  yamt 	case AD1843_AUX3_MUTE:
    660  1.2.2.2  yamt 	case AD1843_MIC_MUTE:
    661  1.2.2.2  yamt 	case AD1843_MONO_MUTE:	/* matches left channel */
    662  1.2.2.2  yamt 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
    663  1.2.2.2  yamt 		value = ad1843_reg_read(sc, reg);
    664  1.2.2.2  yamt 		mc->un.ord = (value & AD1843_LD2MM) ? 1 : 0;
    665  1.2.2.2  yamt 		break;
    666  1.2.2.2  yamt 
    667  1.2.2.2  yamt 	case AD1843_SUM_MUTE:
    668  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    669  1.2.2.2  yamt 		mc->un.ord = (value & AD1843_SUMM) ? 1 : 0;
    670  1.2.2.2  yamt 		break;
    671  1.2.2.2  yamt 
    672  1.2.2.2  yamt 	case AD1843_MNO_MUTE:
    673  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    674  1.2.2.2  yamt 		mc->un.ord = (value & AD1843_MNOM) ? 1 : 0;
    675  1.2.2.2  yamt 		break;
    676  1.2.2.2  yamt 
    677  1.2.2.2  yamt 	case AD1843_HPO_MUTE:
    678  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    679  1.2.2.2  yamt 		mc->un.ord = (value & AD1843_HPOM) ? 1 : 0;
    680  1.2.2.2  yamt 		break;
    681  1.2.2.2  yamt 
    682  1.2.2.2  yamt 	default:
    683  1.2.2.2  yamt 		return (EINVAL);
    684  1.2.2.2  yamt 	}
    685  1.2.2.2  yamt 
    686  1.2.2.2  yamt 	return (0);
    687  1.2.2.2  yamt }
    688  1.2.2.2  yamt 
    689  1.2.2.2  yamt int
    690  1.2.2.2  yamt mavb_query_devinfo(void *hdl, struct mixer_devinfo *di)
    691  1.2.2.2  yamt {
    692  1.2.2.2  yamt 	int i;
    693  1.2.2.2  yamt 
    694  1.2.2.2  yamt 	di->prev = di->next = AUDIO_MIXER_LAST;
    695  1.2.2.2  yamt 
    696  1.2.2.2  yamt 	switch (di->index) {
    697  1.2.2.2  yamt 	case AD1843_RECORD_CLASS:
    698  1.2.2.2  yamt 		di->type = AUDIO_MIXER_CLASS;
    699  1.2.2.2  yamt 		di->mixer_class = AD1843_RECORD_CLASS;
    700  1.2.2.2  yamt 		strlcpy(di->label.name, AudioCrecord, sizeof di->label.name);
    701  1.2.2.2  yamt 		break;
    702  1.2.2.2  yamt 
    703  1.2.2.2  yamt 	case AD1843_ADC_SOURCE:
    704  1.2.2.2  yamt 		di->type = AUDIO_MIXER_ENUM;
    705  1.2.2.2  yamt 		di->mixer_class = AD1843_RECORD_CLASS;
    706  1.2.2.2  yamt 		di->next = AD1843_ADC_GAIN;
    707  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNsource, sizeof di->label.name);
    708  1.2.2.2  yamt 		di->un.e.num_mem =
    709  1.2.2.2  yamt 			sizeof ad1843_source / sizeof ad1843_source[1];
    710  1.2.2.2  yamt 		for (i = 0; i < di->un.e.num_mem; i++) {
    711  1.2.2.2  yamt 			strlcpy(di->un.e.member[i].label.name,
    712  1.2.2.2  yamt                             ad1843_source[i],
    713  1.2.2.2  yamt 			    sizeof di->un.e.member[0].label.name);
    714  1.2.2.2  yamt 			di->un.e.member[i].ord = i;
    715  1.2.2.2  yamt 		}
    716  1.2.2.2  yamt 		break;
    717  1.2.2.2  yamt 	case AD1843_ADC_GAIN:
    718  1.2.2.2  yamt 		di->type = AUDIO_MIXER_VALUE;
    719  1.2.2.2  yamt 		di->mixer_class = AD1843_RECORD_CLASS;
    720  1.2.2.2  yamt 		di->prev = AD1843_ADC_SOURCE;
    721  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNvolume, sizeof di->label.name);
    722  1.2.2.2  yamt 		di->un.v.num_channels = 2;
    723  1.2.2.2  yamt 		strlcpy(di->un.v.units.name, AudioNvolume,
    724  1.2.2.2  yamt 		    sizeof di->un.v.units.name);
    725  1.2.2.2  yamt 		break;
    726  1.2.2.2  yamt 
    727  1.2.2.2  yamt 	case AD1843_INPUT_CLASS:
    728  1.2.2.2  yamt 		di->type = AUDIO_MIXER_CLASS;
    729  1.2.2.2  yamt 		di->mixer_class = AD1843_INPUT_CLASS;
    730  1.2.2.2  yamt 		strlcpy(di->label.name, AudioCinputs, sizeof di->label.name);
    731  1.2.2.2  yamt 		break;
    732  1.2.2.2  yamt 
    733  1.2.2.2  yamt 	case AD1843_DAC1_GAIN:
    734  1.2.2.2  yamt 		di->type = AUDIO_MIXER_VALUE;
    735  1.2.2.2  yamt 		di->mixer_class = AD1843_INPUT_CLASS;
    736  1.2.2.2  yamt 		di->next = AD1843_DAC1_MUTE;
    737  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNdac "1", sizeof di->label.name);
    738  1.2.2.2  yamt 		di->un.v.num_channels = 2;
    739  1.2.2.2  yamt 		strlcpy(di->un.v.units.name, AudioNvolume,
    740  1.2.2.2  yamt 		    sizeof di->un.v.units.name);
    741  1.2.2.2  yamt 		break;
    742  1.2.2.2  yamt 	case AD1843_DAC1_MUTE:
    743  1.2.2.2  yamt 		di->type = AUDIO_MIXER_ENUM;
    744  1.2.2.2  yamt 		di->mixer_class = AD1843_INPUT_CLASS;
    745  1.2.2.2  yamt 		di->prev = AD1843_DAC1_GAIN;
    746  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
    747  1.2.2.2  yamt 		di->un.e.num_mem = 2;
    748  1.2.2.2  yamt 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    749  1.2.2.2  yamt 		    sizeof di->un.e.member[0].label.name);
    750  1.2.2.2  yamt 		di->un.e.member[0].ord = 0;
    751  1.2.2.2  yamt 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    752  1.2.2.2  yamt 		    sizeof di->un.e.member[1].label.name);
    753  1.2.2.2  yamt 		di->un.e.member[1].ord = 1;
    754  1.2.2.2  yamt 		break;
    755  1.2.2.2  yamt 
    756  1.2.2.2  yamt 	case AD1843_DAC2_GAIN:
    757  1.2.2.2  yamt 	case AD1843_AUX1_GAIN:
    758  1.2.2.2  yamt 	case AD1843_AUX2_GAIN:
    759  1.2.2.2  yamt 	case AD1843_AUX3_GAIN:
    760  1.2.2.2  yamt 	case AD1843_MIC_GAIN:
    761  1.2.2.2  yamt 	case AD1843_MONO_GAIN:
    762  1.2.2.2  yamt 		di->type = AUDIO_MIXER_VALUE;
    763  1.2.2.2  yamt 		di->mixer_class = AD1843_INPUT_CLASS;
    764  1.2.2.2  yamt 		di->next = di->index + AD1843_DAC2_MUTE - AD1843_DAC2_GAIN;
    765  1.2.2.2  yamt 		strlcpy(di->label.name,
    766  1.2.2.2  yamt                     ad1843_input[di->index - AD1843_DAC2_GAIN],
    767  1.2.2.2  yamt 		    sizeof di->label.name);
    768  1.2.2.2  yamt 		if (di->index == AD1843_MONO_GAIN)
    769  1.2.2.2  yamt 			di->un.v.num_channels = 1;
    770  1.2.2.2  yamt 		else
    771  1.2.2.2  yamt 			di->un.v.num_channels = 2;
    772  1.2.2.2  yamt 		strlcpy(di->un.v.units.name, AudioNvolume,
    773  1.2.2.2  yamt 		    sizeof di->un.v.units.name);
    774  1.2.2.2  yamt 		break;
    775  1.2.2.2  yamt 	case AD1843_DAC2_MUTE:
    776  1.2.2.2  yamt 	case AD1843_AUX1_MUTE:
    777  1.2.2.2  yamt 	case AD1843_AUX2_MUTE:
    778  1.2.2.2  yamt 	case AD1843_AUX3_MUTE:
    779  1.2.2.2  yamt 	case AD1843_MIC_MUTE:
    780  1.2.2.2  yamt 	case AD1843_MONO_MUTE:
    781  1.2.2.2  yamt 		di->type = AUDIO_MIXER_ENUM;
    782  1.2.2.2  yamt 		di->mixer_class = AD1843_INPUT_CLASS;
    783  1.2.2.2  yamt 		di->prev = di->index + AD1843_DAC2_GAIN - AD1843_DAC2_MUTE;
    784  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
    785  1.2.2.2  yamt 		di->un.e.num_mem = 2;
    786  1.2.2.2  yamt 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    787  1.2.2.2  yamt 		    sizeof di->un.e.member[0].label.name);
    788  1.2.2.2  yamt 		di->un.e.member[0].ord = 0;
    789  1.2.2.2  yamt 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    790  1.2.2.2  yamt 		    sizeof di->un.e.member[1].label.name);
    791  1.2.2.2  yamt 		di->un.e.member[1].ord = 1;
    792  1.2.2.2  yamt 		break;
    793  1.2.2.2  yamt 
    794  1.2.2.2  yamt 	case AD1843_SUM_MUTE:
    795  1.2.2.2  yamt 		di->type = AUDIO_MIXER_ENUM;
    796  1.2.2.2  yamt 		di->mixer_class = AD1843_INPUT_CLASS;
    797  1.2.2.2  yamt 		strlcpy(di->label.name, "sum." AudioNmute,
    798  1.2.2.2  yamt 		    sizeof di->label.name);
    799  1.2.2.2  yamt 		di->un.e.num_mem = 2;
    800  1.2.2.2  yamt 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    801  1.2.2.2  yamt 		    sizeof di->un.e.member[0].label.name);
    802  1.2.2.2  yamt 		di->un.e.member[0].ord = 0;
    803  1.2.2.2  yamt 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    804  1.2.2.2  yamt 		    sizeof di->un.e.member[1].label.name);
    805  1.2.2.2  yamt 		di->un.e.member[1].ord = 1;
    806  1.2.2.2  yamt 		break;
    807  1.2.2.2  yamt 
    808  1.2.2.2  yamt 	case AD1843_OUTPUT_CLASS:
    809  1.2.2.2  yamt 		di->type = AUDIO_MIXER_CLASS;
    810  1.2.2.2  yamt 		di->mixer_class = AD1843_OUTPUT_CLASS;
    811  1.2.2.2  yamt 		strlcpy(di->label.name, AudioCoutputs, sizeof di->label.name);
    812  1.2.2.2  yamt 		break;
    813  1.2.2.2  yamt 
    814  1.2.2.2  yamt 	case AD1843_MNO_MUTE:
    815  1.2.2.2  yamt 		di->type = AUDIO_MIXER_ENUM;
    816  1.2.2.2  yamt 		di->mixer_class = AD1843_OUTPUT_CLASS;
    817  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNmono "." AudioNmute,
    818  1.2.2.2  yamt 		    sizeof di->label.name);
    819  1.2.2.2  yamt 		di->un.e.num_mem = 2;
    820  1.2.2.2  yamt 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    821  1.2.2.2  yamt 		    sizeof di->un.e.member[0].label.name);
    822  1.2.2.2  yamt 		di->un.e.member[0].ord = 0;
    823  1.2.2.2  yamt 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    824  1.2.2.2  yamt 		    sizeof di->un.e.member[1].label.name);
    825  1.2.2.2  yamt 		di->un.e.member[1].ord = 1;
    826  1.2.2.2  yamt 		break;
    827  1.2.2.2  yamt 
    828  1.2.2.2  yamt 	case AD1843_HPO_MUTE:
    829  1.2.2.2  yamt 		di->type = AUDIO_MIXER_ENUM;
    830  1.2.2.2  yamt 		di->mixer_class = AD1843_OUTPUT_CLASS;
    831  1.2.2.2  yamt 		strlcpy(di->label.name, AudioNheadphone "." AudioNmute,
    832  1.2.2.2  yamt 		    sizeof di->label.name);
    833  1.2.2.2  yamt 		di->un.e.num_mem = 2;
    834  1.2.2.2  yamt 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    835  1.2.2.2  yamt 		    sizeof di->un.e.member[0].label.name);
    836  1.2.2.2  yamt 		di->un.e.member[0].ord = 0;
    837  1.2.2.2  yamt 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    838  1.2.2.2  yamt 		    sizeof di->un.e.member[1].label.name);
    839  1.2.2.2  yamt 		di->un.e.member[1].ord = 1;
    840  1.2.2.2  yamt 		break;
    841  1.2.2.2  yamt 
    842  1.2.2.2  yamt 	default:
    843  1.2.2.2  yamt 		return (EINVAL);
    844  1.2.2.2  yamt 	}
    845  1.2.2.2  yamt 
    846  1.2.2.2  yamt 	return (0);
    847  1.2.2.2  yamt }
    848  1.2.2.2  yamt 
    849  1.2.2.2  yamt size_t
    850  1.2.2.2  yamt mavb_round_buffersize(void *hdl, int dir, size_t bufsize)
    851  1.2.2.2  yamt {
    852  1.2.2.2  yamt 
    853  1.2.2.2  yamt 	return bufsize;
    854  1.2.2.2  yamt }
    855  1.2.2.2  yamt 
    856  1.2.2.2  yamt int
    857  1.2.2.2  yamt mavb_get_props(void *hdl)
    858  1.2.2.2  yamt {
    859  1.2.2.2  yamt 	return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
    860  1.2.2.2  yamt }
    861  1.2.2.2  yamt 
    862  1.2.2.2  yamt static void
    863  1.2.2.2  yamt mavb_dma_output(struct mavb_softc *sc)
    864  1.2.2.2  yamt {
    865  1.2.2.2  yamt 	bus_space_tag_t st = sc->sc_st;
    866  1.2.2.2  yamt 	bus_space_handle_t sh = sc->sc_sh;
    867  1.2.2.2  yamt 	u_int64_t write_ptr;
    868  1.2.2.2  yamt 	u_int64_t depth;
    869  1.2.2.2  yamt 	uint8_t *src, *dst;
    870  1.2.2.2  yamt 	int count;
    871  1.2.2.2  yamt 
    872  1.2.2.2  yamt 	write_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL2_WRITE_PTR);
    873  1.2.2.2  yamt 	depth = bus_space_read_8(st, sh, MAVB_CHANNEL2_DEPTH);
    874  1.2.2.2  yamt 
    875  1.2.2.2  yamt 	dst = sc->sc_ring + write_ptr;
    876  1.2.2.2  yamt 	src = sc->sc_get;
    877  1.2.2.2  yamt 
    878  1.2.2.2  yamt 	count = (MAVB_ISA_RING_SIZE - depth - 32);
    879  1.2.2.2  yamt 	while (--count >= 0) {
    880  1.2.2.2  yamt 		*dst++ = *src++;
    881  1.2.2.2  yamt 		if (dst >= sc->sc_ring + MAVB_ISA_RING_SIZE)
    882  1.2.2.2  yamt 			dst = sc->sc_ring;
    883  1.2.2.2  yamt 		if (src >= sc->sc_end)
    884  1.2.2.2  yamt 			src = sc->sc_start;
    885  1.2.2.2  yamt 		if (++sc->sc_count >= sc->sc_blksize) {
    886  1.2.2.2  yamt 			if (sc->sc_intr)
    887  1.2.2.2  yamt 				sc->sc_intr(sc->sc_intrarg);
    888  1.2.2.2  yamt 			sc->sc_count = 0;
    889  1.2.2.2  yamt 		}
    890  1.2.2.2  yamt 	}
    891  1.2.2.2  yamt 
    892  1.2.2.2  yamt 	write_ptr = dst - sc->sc_ring;
    893  1.2.2.2  yamt 	bus_space_write_8(st, sh, MAVB_CHANNEL2_WRITE_PTR, write_ptr);
    894  1.2.2.2  yamt 	sc->sc_get = src;
    895  1.2.2.2  yamt }
    896  1.2.2.2  yamt 
    897  1.2.2.2  yamt int
    898  1.2.2.2  yamt mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
    899  1.2.2.2  yamt 		    void (*intr)(void *), void *intrarg,
    900  1.2.2.2  yamt 		    const audio_params_t *param)
    901  1.2.2.2  yamt {
    902  1.2.2.2  yamt 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    903  1.2.2.2  yamt 
    904  1.2.2.2  yamt 	DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
    905  1.2.2.2  yamt 	    "blksize=%d intr=%p(%p)\n", sc->sc_dev.dv_xname,
    906  1.2.2.2  yamt 	    start, end, blksize, intr, intrarg));
    907  1.2.2.2  yamt 
    908  1.2.2.2  yamt 	sc->sc_blksize = blksize;
    909  1.2.2.2  yamt 	sc->sc_intr = intr;
    910  1.2.2.2  yamt 	sc->sc_intrarg = intrarg;
    911  1.2.2.2  yamt 
    912  1.2.2.2  yamt 	sc->sc_start = sc->sc_get = start;
    913  1.2.2.2  yamt 	sc->sc_end = end;
    914  1.2.2.2  yamt 
    915  1.2.2.2  yamt 	sc->sc_count = 0;
    916  1.2.2.2  yamt 
    917  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
    918  1.2.2.2  yamt 	    MAVB_CHANNEL_RESET);
    919  1.2.2.2  yamt 	delay(1000);
    920  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
    921  1.2.2.2  yamt 
    922  1.2.2.2  yamt 	mavb_dma_output(sc);
    923  1.2.2.2  yamt 
    924  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
    925  1.2.2.2  yamt 	    MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
    926  1.2.2.2  yamt 	return (0);
    927  1.2.2.2  yamt }
    928  1.2.2.2  yamt 
    929  1.2.2.2  yamt int
    930  1.2.2.2  yamt mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
    931  1.2.2.2  yamt 		   void (*intr)(void *), void *intrarg,
    932  1.2.2.2  yamt 		   const audio_params_t *param)
    933  1.2.2.2  yamt {
    934  1.2.2.2  yamt 	return (0);
    935  1.2.2.2  yamt }
    936  1.2.2.2  yamt 
    937  1.2.2.2  yamt static void
    938  1.2.2.2  yamt mavb_button_repeat(void *hdl)
    939  1.2.2.2  yamt {
    940  1.2.2.2  yamt 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    941  1.2.2.2  yamt 	u_int64_t intmask, control;
    942  1.2.2.2  yamt 	u_int16_t value, left, right;
    943  1.2.2.2  yamt 
    944  1.2.2.2  yamt 	DPRINTF(1, ("%s: mavb_repeat called\n", sc->sc_dev.dv_xname));
    945  1.2.2.2  yamt 
    946  1.2.2.2  yamt #define  MAVB_CONTROL_VOLUME_BUTTONS \
    947  1.2.2.2  yamt     (MAVB_CONTROL_VOLUME_BUTTON_UP | MAVB_CONTROL_VOLUME_BUTTON_DOWN)
    948  1.2.2.2  yamt 
    949  1.2.2.2  yamt 	control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
    950  1.2.2.2  yamt 	if (control & MAVB_CONTROL_VOLUME_BUTTONS) {
    951  1.2.2.2  yamt 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    952  1.2.2.2  yamt 		left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
    953  1.2.2.2  yamt 		right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
    954  1.2.2.2  yamt 		if (control & MAVB_CONTROL_VOLUME_BUTTON_UP) {
    955  1.2.2.2  yamt 			control &= ~MAVB_CONTROL_VOLUME_BUTTON_UP;
    956  1.2.2.2  yamt 			if (left > 0)
    957  1.2.2.2  yamt 				left--;		/* attenuation! */
    958  1.2.2.2  yamt 			if (right > 0)
    959  1.2.2.2  yamt 				right--;
    960  1.2.2.2  yamt 		}
    961  1.2.2.2  yamt 		if (control & MAVB_CONTROL_VOLUME_BUTTON_DOWN) {
    962  1.2.2.2  yamt 			control &= ~MAVB_CONTROL_VOLUME_BUTTON_DOWN;
    963  1.2.2.2  yamt 			if (left < 63)
    964  1.2.2.2  yamt 				left++;
    965  1.2.2.2  yamt 			if (right < 63)
    966  1.2.2.2  yamt 				right++;
    967  1.2.2.2  yamt 		}
    968  1.2.2.2  yamt 		bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, control);
    969  1.2.2.2  yamt 
    970  1.2.2.2  yamt 		value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
    971  1.2.2.2  yamt 		value |= (left << AD1843_LDA1G_SHIFT);
    972  1.2.2.2  yamt 		value |= (right << AD1843_RDA1G_SHIFT);
    973  1.2.2.2  yamt 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    974  1.2.2.2  yamt 
    975  1.2.2.2  yamt 		callout_reset(&sc->sc_volume_button_ch,
    976  1.2.2.2  yamt 		    (hz * MAVB_VOLUME_BUTTON_REPEAT_DELN) / 1000,
    977  1.2.2.2  yamt 		    mavb_button_repeat, sc);
    978  1.2.2.2  yamt 	} else {
    979  1.2.2.2  yamt 		/* Enable volume button interrupts again.  */
    980  1.2.2.2  yamt 		intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
    981  1.2.2.2  yamt 		     MACE_ISA_INT_MASK);
    982  1.2.2.2  yamt 		bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
    983  1.2.2.2  yamt 		     intmask | MACE_ISA_INT_AUDIO_SC);
    984  1.2.2.2  yamt 	}
    985  1.2.2.2  yamt }
    986  1.2.2.2  yamt 
    987  1.2.2.2  yamt static int
    988  1.2.2.2  yamt mavb_intr(void *arg)
    989  1.2.2.2  yamt {
    990  1.2.2.2  yamt 	struct mavb_softc *sc = arg;
    991  1.2.2.2  yamt 	u_int64_t stat, intmask;
    992  1.2.2.2  yamt 
    993  1.2.2.2  yamt 	stat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STATUS);
    994  1.2.2.2  yamt 	DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: stat = 0x%llx\n",
    995  1.2.2.2  yamt             sc->sc_dev.dv_xname, stat));
    996  1.2.2.2  yamt 
    997  1.2.2.2  yamt 	if (stat & MACE_ISA_INT_AUDIO_SC) {
    998  1.2.2.2  yamt 		/* Disable volume button interrupts.  */
    999  1.2.2.2  yamt 		intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
   1000  1.2.2.2  yamt 		     MACE_ISA_INT_MASK);
   1001  1.2.2.2  yamt 		bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
   1002  1.2.2.2  yamt 		     intmask & ~MACE_ISA_INT_AUDIO_SC);
   1003  1.2.2.2  yamt 
   1004  1.2.2.2  yamt 		callout_reset(&sc->sc_volume_button_ch,
   1005  1.2.2.2  yamt 		    (hz * MAVB_VOLUME_BUTTON_REPEAT_DEL1) / 1000,
   1006  1.2.2.2  yamt 		    mavb_button_repeat, sc);
   1007  1.2.2.2  yamt 	}
   1008  1.2.2.2  yamt 
   1009  1.2.2.2  yamt 	if (stat & MACE_ISA_INT_AUDIO_DMA2)
   1010  1.2.2.2  yamt 		mavb_dma_output(sc);
   1011  1.2.2.2  yamt 
   1012  1.2.2.2  yamt 	return 1;
   1013  1.2.2.2  yamt }
   1014  1.2.2.2  yamt 
   1015  1.2.2.2  yamt int
   1016  1.2.2.2  yamt mavb_match(struct device *parent, struct cfdata *match, void *aux)
   1017  1.2.2.2  yamt {
   1018  1.2.2.2  yamt 	return (1);
   1019  1.2.2.2  yamt }
   1020  1.2.2.2  yamt 
   1021  1.2.2.2  yamt void
   1022  1.2.2.2  yamt mavb_attach(struct device *parent, struct device *self, void *aux)
   1023  1.2.2.2  yamt {
   1024  1.2.2.2  yamt 	struct mavb_softc *sc = (void *)self;
   1025  1.2.2.2  yamt 	struct mace_attach_args *maa = aux;
   1026  1.2.2.2  yamt 	bus_dma_segment_t seg;
   1027  1.2.2.2  yamt 	u_int64_t control;
   1028  1.2.2.2  yamt 	u_int16_t value;
   1029  1.2.2.2  yamt 	int rseg;
   1030  1.2.2.2  yamt 
   1031  1.2.2.2  yamt 	sc->sc_st = maa->maa_st;
   1032  1.2.2.2  yamt 	if (bus_space_subregion(sc->sc_st, maa->maa_sh, maa->maa_offset,
   1033  1.2.2.2  yamt 	    0, &sc->sc_sh) != 0) {
   1034  1.2.2.2  yamt 		printf(": can't map i/o space\n");
   1035  1.2.2.2  yamt 		return;
   1036  1.2.2.2  yamt 	}
   1037  1.2.2.2  yamt 
   1038  1.2.2.2  yamt 	/* XXX We need access to some of the MACE ISA registers.  */
   1039  1.2.2.2  yamt 	if (bus_space_subregion(sc->sc_st, maa->maa_sh, 0, 0,
   1040  1.2.2.2  yamt 	    &sc->sc_isash) != 0) {
   1041  1.2.2.2  yamt 		printf(": can't map isa i/o space\n");
   1042  1.2.2.2  yamt 		return;
   1043  1.2.2.2  yamt 	}
   1044  1.2.2.2  yamt 
   1045  1.2.2.2  yamt 	/* Set up DMA structures.  */
   1046  1.2.2.2  yamt 	sc->sc_dmat = maa->maa_dmat;
   1047  1.2.2.2  yamt 	if (bus_dmamap_create(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE, 1,
   1048  1.2.2.2  yamt 	    4 * MAVB_ISA_RING_SIZE, 0, 0, &sc->sc_dmamap)) {
   1049  1.2.2.2  yamt 		printf(": can't create MACE ISA DMA map\n");
   1050  1.2.2.2  yamt 		return;
   1051  1.2.2.2  yamt 	}
   1052  1.2.2.2  yamt 
   1053  1.2.2.2  yamt 	if (bus_dmamem_alloc(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE,
   1054  1.2.2.2  yamt 	    MACE_ISA_RING_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
   1055  1.2.2.2  yamt 		printf(": can't allocate ring buffer\n");
   1056  1.2.2.2  yamt 		return;
   1057  1.2.2.2  yamt 	}
   1058  1.2.2.2  yamt 
   1059  1.2.2.2  yamt 	if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, 4 * MAVB_ISA_RING_SIZE,
   1060  1.2.2.2  yamt 	    (void *)&sc->sc_ring, BUS_DMA_COHERENT)) {
   1061  1.2.2.2  yamt 		printf(": can't map ring buffer\n");
   1062  1.2.2.2  yamt 		return;
   1063  1.2.2.2  yamt 	}
   1064  1.2.2.2  yamt 
   1065  1.2.2.2  yamt 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ring,
   1066  1.2.2.2  yamt 	    4 * MAVB_ISA_RING_SIZE, NULL, BUS_DMA_NOWAIT)) {
   1067  1.2.2.2  yamt 		printf(": can't load MACE ISA DMA map\n");
   1068  1.2.2.2  yamt 		return;
   1069  1.2.2.2  yamt 	}
   1070  1.2.2.2  yamt 
   1071  1.2.2.2  yamt 	sc->sc_ring += MAVB_ISA_RING_SIZE; /* XXX */
   1072  1.2.2.2  yamt 
   1073  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_RINGBASE,
   1074  1.2.2.2  yamt 	    sc->sc_dmamap->dm_segs[0].ds_addr);
   1075  1.2.2.2  yamt 
   1076  1.2.2.2  yamt 	/* Establish interrupt.  */
   1077  1.2.2.2  yamt 	cpu_intr_establish(maa->maa_intr, maa->maa_intrmask,
   1078  1.2.2.2  yamt 	    mavb_intr, sc);
   1079  1.2.2.2  yamt 
   1080  1.2.2.2  yamt 	control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
   1081  1.2.2.2  yamt 	if (!(control & MAVB_CONTROL_CODEC_PRESENT)) {
   1082  1.2.2.2  yamt 		printf(": no codec present\n");
   1083  1.2.2.2  yamt 		return;
   1084  1.2.2.2  yamt 	}
   1085  1.2.2.2  yamt 
   1086  1.2.2.2  yamt 	/* 2. Assert the RESET signal.  */
   1087  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL,
   1088  1.2.2.2  yamt 	    MAVB_CONTROL_RESET);
   1089  1.2.2.2  yamt 	delay(1);		/* at least 100 ns */
   1090  1.2.2.2  yamt 
   1091  1.2.2.2  yamt 	/* 3. Deassert the RESET signal and enter a wait period to
   1092  1.2.2.2  yamt               allow the AD1843 internal clocks and the external
   1093  1.2.2.2  yamt               crystal oscillator to stabilize.  */
   1094  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, 0);
   1095  1.2.2.2  yamt 	delay(800);		/* typically 400 us to 800 us */
   1096  1.2.2.2  yamt 	if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_INIT) {
   1097  1.2.2.2  yamt 		printf(": codec not ready\n");
   1098  1.2.2.2  yamt 		return;
   1099  1.2.2.2  yamt 	}
   1100  1.2.2.2  yamt 
   1101  1.2.2.2  yamt 	/* 4. Put the conversion sources into standby.  */
   1102  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
   1103  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
   1104  1.2.2.2  yamt 	    value & ~AD1843_PDNI);
   1105  1.2.2.2  yamt 	delay (500000);		/* approximately 474 ms */
   1106  1.2.2.2  yamt 	if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_PDNO) {
   1107  1.2.2.2  yamt 		printf(": can't power up conversion resources\n");
   1108  1.2.2.2  yamt 		return;
   1109  1.2.2.2  yamt 	}
   1110  1.2.2.2  yamt 
   1111  1.2.2.2  yamt 	/* 5. Power up the clock generators and enable clock output pins.  */
   1112  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
   1113  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS, value | AD1843_C2EN);
   1114  1.2.2.2  yamt 
   1115  1.2.2.2  yamt 	/* 6. Configure conversion resources while they are in standby.  */
   1116  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_CHANNEL_SAMPLE_RATE);
   1117  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_CHANNEL_SAMPLE_RATE,
   1118  1.2.2.2  yamt 	     value | (2 << AD1843_DA1C_SHIFT));
   1119  1.2.2.2  yamt 
   1120  1.2.2.2  yamt 	/* 7. Enable conversion resources.  */
   1121  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_CHANNEL_POWER_DOWN);
   1122  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_CHANNEL_POWER_DOWN,
   1123  1.2.2.2  yamt 	     value | (AD1843_DA1EN | AD1843_AAMEN));
   1124  1.2.2.2  yamt 
   1125  1.2.2.2  yamt 	/* 8. Configure conversion resources while they are enabled.  */
   1126  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
   1127  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN,
   1128  1.2.2.2  yamt             value & ~(AD1843_LDA1GM | AD1843_RDA1GM));
   1129  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_DAC1_DIGITAL_GAIN);
   1130  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_DAC1_DIGITAL_GAIN,
   1131  1.2.2.2  yamt             value & ~(AD1843_LDA1AM | AD1843_RDA1AM));
   1132  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
   1133  1.2.2.2  yamt 	ad1843_reg_write(sc, AD1843_MISC_SETTINGS,
   1134  1.2.2.2  yamt             value & ~(AD1843_HPOM | AD1843_MNOM));
   1135  1.2.2.2  yamt 
   1136  1.2.2.2  yamt 	value = ad1843_reg_read(sc, AD1843_CODEC_STATUS);
   1137  1.2.2.2  yamt 	printf(": AD1843 rev %d\n", (u_int)value & AD1843_REVISION_MASK);
   1138  1.2.2.2  yamt 
   1139  1.2.2.2  yamt 	sc->sc_play_rate = 48000;
   1140  1.2.2.2  yamt 	sc->sc_play_format = AD1843_PCM8;
   1141  1.2.2.2  yamt 
   1142  1.2.2.2  yamt 	callout_init(&sc->sc_volume_button_ch);
   1143  1.2.2.2  yamt 
   1144  1.2.2.2  yamt 	audio_attach_mi(&mavb_sa_hw_if, sc, &sc->sc_dev);
   1145  1.2.2.2  yamt 
   1146  1.2.2.2  yamt 	return;
   1147  1.2.2.2  yamt }
   1148  1.2.2.2  yamt 
   1149  1.2.2.2  yamt u_int16_t
   1150  1.2.2.2  yamt ad1843_reg_read(struct mavb_softc *sc, ad1843_addr_t addr)
   1151  1.2.2.2  yamt {
   1152  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
   1153  1.2.2.2  yamt             (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
   1154  1.2.2.2  yamt 	    MAVB_CODEC_READ);
   1155  1.2.2.2  yamt 	delay(200);
   1156  1.2.2.2  yamt 	return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
   1157  1.2.2.2  yamt }
   1158  1.2.2.2  yamt 
   1159  1.2.2.2  yamt u_int16_t
   1160  1.2.2.2  yamt ad1843_reg_write(struct mavb_softc *sc, ad1843_addr_t addr, u_int16_t value)
   1161  1.2.2.2  yamt {
   1162  1.2.2.2  yamt 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
   1163  1.2.2.2  yamt 	    (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
   1164  1.2.2.2  yamt 	    (value & MAVB_CODEC_WORD_MASK) << MAVB_CODEC_WORD_SHIFT);
   1165  1.2.2.2  yamt 	delay(200);
   1166  1.2.2.2  yamt 	return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
   1167  1.2.2.2  yamt }
   1168  1.2.2.2  yamt 
   1169  1.2.2.2  yamt void
   1170  1.2.2.2  yamt ad1843_dump_regs(struct mavb_softc *sc)
   1171  1.2.2.2  yamt {
   1172  1.2.2.2  yamt 	u_int16_t addr;
   1173  1.2.2.2  yamt 
   1174  1.2.2.2  yamt 	for (addr = 0; addr < AD1843_NREGS; addr++)
   1175  1.2.2.2  yamt 		printf("%d: 0x%04x\n", addr, ad1843_reg_read(sc, addr));
   1176  1.2.2.2  yamt }
   1177