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