Home | History | Annotate | Line # | Download | only in mace
mavb.c revision 1.10
      1 /* $NetBSD: mavb.c,v 1.10 2015/02/17 11:25:43 macallan 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 	device_t 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(device_t, cfdata_t, void *);
    248 void mavb_attach(device_t, device_t, void *);
    249 
    250 CFATTACH_DECL_NEW(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 	mavb_get_locks,
    303 };
    304 
    305 struct audio_device mavb_device = {
    306 	"A3",
    307 	"",
    308 	"mavb"
    309 };
    310 
    311 int
    312 mavb_open(void *hdl, int flags)
    313 {
    314 
    315 	return 0;
    316 }
    317 
    318 void
    319 mavb_close(void *hdl)
    320 {
    321 }
    322 
    323 int
    324 mavb_query_encoding(void *hdl, struct audio_encoding *ae)
    325 {
    326 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    327 
    328 	return auconv_query_encoding(sc->sc_encodings, ae);
    329 }
    330 
    331 static int
    332 mavb_set_play_rate(struct mavb_softc *sc, u_long sample_rate)
    333 {
    334 
    335 	if (sample_rate < 4000 || sample_rate > 48000)
    336 		return EINVAL;
    337 
    338 	if (sc->sc_play_rate != sample_rate) {
    339 		ad1843_reg_write(sc, AD1843_CLOCK2_SAMPLE_RATE, sample_rate);
    340 		sc->sc_play_rate = sample_rate;
    341 	}
    342 	return 0;
    343 }
    344 
    345 static int
    346 mavb_set_play_format(struct mavb_softc *sc, u_int encoding)
    347 {
    348 	uint16_t value;
    349 	u_int format;
    350 
    351 	switch(encoding) {
    352 	case AUDIO_ENCODING_ULINEAR_BE:
    353 		format = AD1843_PCM8;
    354 		break;
    355 	case AUDIO_ENCODING_SLINEAR_BE:
    356 		format = AD1843_PCM16;
    357 		break;
    358 	case AUDIO_ENCODING_ULAW:
    359 		format = AD1843_ULAW;
    360 		break;
    361 	case AUDIO_ENCODING_ALAW:
    362 		format = AD1843_ALAW;
    363 		break;
    364 	default:
    365 		return EINVAL;
    366 	}
    367 
    368 	if (sc->sc_play_format != format) {
    369 		value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
    370 		value &= ~AD1843_DA1F_MASK;
    371 		value |= (format << AD1843_DA1F_SHIFT);
    372 		ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value);
    373 		sc->sc_play_format = format;
    374 	}
    375 	return 0;
    376 }
    377 
    378 int
    379 mavb_set_params(void *hdl, int setmode, int usemode,
    380     struct audio_params *play, struct audio_params *rec,
    381     stream_filter_list_t *pfil, stream_filter_list_t *rfil)
    382 {
    383 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    384 	struct audio_params *p;
    385 	stream_filter_list_t *fil;
    386 	int error;
    387 
    388 	DPRINTF(1, ("%s: mavb_set_params: sample=%u precision=%d "
    389 	    "channels=%d\n", device_xname(sc->sc_dev), play->sample_rate,
    390 	    play->precision, play->channels));
    391 
    392 	if (setmode & AUMODE_PLAY) {
    393 		if (play->sample_rate < 4000 || play->sample_rate > 48000)
    394 			return EINVAL;
    395 
    396 		p = play;
    397 		fil = pfil;
    398 		if (auconv_set_converter(sc->sc_formats, MAVB_NFORMATS,
    399 		    AUMODE_PLAY, p, TRUE, fil) < 0)
    400 			return EINVAL;
    401 
    402 		fil->append(fil, mavb_16to24, p);
    403 		if (p->channels == 1)
    404 			fil->append(fil, mavb_mts, p);
    405 		if (fil->req_size > 0)
    406 			p = &fil->filters[0].param;
    407 
    408 		error = mavb_set_play_rate(sc, p->sample_rate);
    409 		if (error)
    410 			return error;
    411 
    412 		error = mavb_set_play_format(sc, p->encoding);
    413 		if (error)
    414 			return error;
    415 	}
    416 
    417 #if 0
    418 	if (setmode & AUMODE_RECORD) {
    419 		if (rec->sample_rate < 4000 || rec->sample_rate > 48000)
    420 			return EINVAL;
    421 	}
    422 #endif
    423 
    424 	return 0;
    425 }
    426 
    427 int
    428 mavb_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *p)
    429 {
    430 
    431 	/* Block size should be a multiple of 32.  */
    432 	return (bs + 0x1f) & ~0x1f;
    433 }
    434 
    435 int
    436 mavb_halt_output(void *hdl)
    437 {
    438 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    439 
    440 	DPRINTF(1, ("%s: mavb_halt_output called\n", device_xname(sc->sc_dev)));
    441 
    442 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
    443 	return 0;
    444 }
    445 
    446 int
    447 mavb_halt_input(void *hdl)
    448 {
    449 
    450 	return 0;
    451 }
    452 
    453 int
    454 mavb_getdev(void *hdl, struct audio_device *ret)
    455 {
    456 
    457 	*ret = mavb_device;
    458 	return 0;
    459 }
    460 
    461 int
    462 mavb_set_port(void *hdl, struct mixer_ctrl *mc)
    463 {
    464 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    465 	u_char left, right;
    466 	ad1843_addr_t reg;
    467 	uint16_t value;
    468 
    469 	DPRINTF(1, ("%s: mavb_set_port: dev=%d\n", device_xname(sc->sc_dev),
    470 	    mc->dev));
    471 
    472 	switch (mc->dev) {
    473 	case AD1843_ADC_SOURCE:
    474 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    475 		value &= ~(AD1843_LSS_MASK | AD1843_RSS_MASK);
    476 		value |= ((mc->un.ord << AD1843_LSS_SHIFT) & AD1843_LSS_MASK);
    477 		value |= ((mc->un.ord << AD1843_RSS_SHIFT) & AD1843_RSS_MASK);
    478 		ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
    479 		break;
    480 	case AD1843_ADC_GAIN:
    481 		left = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    482 		right = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    483 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    484 		value &= ~(AD1843_LIG_MASK | AD1843_RIG_MASK);
    485 		value |= ((left >> 4) << AD1843_LIG_SHIFT);
    486 		value |= ((right >> 4) << AD1843_RIG_SHIFT);
    487 		ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
    488 		break;
    489 
    490 	case AD1843_DAC1_GAIN:
    491 		left = AUDIO_MAX_GAIN -
    492 		    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    493 		right = AUDIO_MAX_GAIN -
    494                     mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    495 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    496 		value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
    497 		value |= ((left >> 2) << AD1843_LDA1G_SHIFT);
    498 		value |= ((right >> 2) << AD1843_RDA1G_SHIFT);
    499 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    500 		break;
    501 	case AD1843_DAC1_MUTE:
    502 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    503 		if (mc->un.ord == 0)
    504 			value &= ~(AD1843_LDA1GM | AD1843_RDA1GM);
    505 		else
    506 			value |= (AD1843_LDA1GM | AD1843_RDA1GM);
    507 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    508 		break;
    509 
    510 	case AD1843_DAC2_GAIN:
    511 	case AD1843_AUX1_GAIN:
    512 	case AD1843_AUX2_GAIN:
    513 	case AD1843_AUX3_GAIN:
    514 	case AD1843_MIC_GAIN:
    515 		left = AUDIO_MAX_GAIN -
    516 		    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    517 		right = AUDIO_MAX_GAIN -
    518                     mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    519 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
    520 		value = ad1843_reg_read(sc, reg);
    521 		value &= ~(AD1843_LD2M_MASK | AD1843_RD2M_MASK);
    522 		value |= ((left >> 3) << AD1843_LD2M_SHIFT);
    523 		value |= ((right >> 3) << AD1843_RD2M_SHIFT);
    524 		ad1843_reg_write(sc, reg, value);
    525 		break;
    526 	case AD1843_MONO_GAIN:
    527 		left = AUDIO_MAX_GAIN -
    528 		    mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    529 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    530 		value &= ~AD1843_MNM_MASK;
    531 		value |= ((left >> 3) << AD1843_MNM_SHIFT);
    532 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    533 		break;
    534 	case AD1843_DAC2_MUTE:
    535 	case AD1843_AUX1_MUTE:
    536 	case AD1843_AUX2_MUTE:
    537 	case AD1843_AUX3_MUTE:
    538 	case AD1843_MIC_MUTE:
    539 	case AD1843_MONO_MUTE:	/* matches left channel */
    540 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
    541 		value = ad1843_reg_read(sc, reg);
    542 		if (mc->un.ord == 0)
    543 			value &= ~(AD1843_LD2MM | AD1843_RD2MM);
    544 		else
    545 			value |= (AD1843_LD2MM | AD1843_RD2MM);
    546 		ad1843_reg_write(sc, reg, value);
    547 		break;
    548 
    549 	case AD1843_SUM_MUTE:
    550 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    551 		if (mc->un.ord == 0)
    552 			value &= ~AD1843_SUMM;
    553 		else
    554 			value |= AD1843_SUMM;
    555 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    556 		break;
    557 
    558 	case AD1843_MNO_MUTE:
    559 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    560 		if (mc->un.ord == 0)
    561 			value &= ~AD1843_MNOM;
    562 		else
    563 			value |= AD1843_MNOM;
    564 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    565 		break;
    566 
    567 	case AD1843_HPO_MUTE:
    568 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    569 		if (mc->un.ord == 0)
    570 			value &= ~AD1843_HPOM;
    571 		else
    572 			value |= AD1843_HPOM;
    573 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    574 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    575 		break;
    576 
    577 	default:
    578 		return EINVAL;
    579 	}
    580 
    581 	return 0;
    582 }
    583 
    584 int
    585 mavb_get_port(void *hdl, struct mixer_ctrl *mc)
    586 {
    587 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    588 	u_char left, right;
    589 	ad1843_addr_t reg;
    590 	uint16_t value;
    591 
    592 	DPRINTF(1, ("%s: mavb_get_port: dev=%d\n", device_xname(sc->sc_dev),
    593 	    mc->dev));
    594 
    595 	switch (mc->dev) {
    596 	case AD1843_ADC_SOURCE:
    597 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    598 		mc->un.ord = (value & AD1843_LSS_MASK) >> AD1843_LSS_SHIFT;
    599 		break;
    600 	case AD1843_ADC_GAIN:
    601 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    602 		left = (value & AD1843_LIG_MASK) >> AD1843_LIG_SHIFT;
    603 		right = (value & AD1843_RIG_MASK) >> AD1843_RIG_SHIFT;
    604 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    605 		    (left << 4) | left;
    606 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    607 		    (right << 2) | right;
    608 		break;
    609 
    610 	case AD1843_DAC1_GAIN:
    611 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    612 		left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
    613 		right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
    614 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    615 		    AUDIO_MAX_GAIN - (left << 2);
    616 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    617 		    AUDIO_MAX_GAIN - (right << 2);
    618 		break;
    619 	case AD1843_DAC1_MUTE:
    620 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    621 		mc->un.ord = (value & AD1843_LDA1GM) ? 1 : 0;
    622 		break;
    623 
    624 	case AD1843_DAC2_GAIN:
    625 	case AD1843_AUX1_GAIN:
    626 	case AD1843_AUX2_GAIN:
    627 	case AD1843_AUX3_GAIN:
    628 	case AD1843_MIC_GAIN:
    629 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
    630 		value = ad1843_reg_read(sc, reg);
    631 		left = (value & AD1843_LD2M_MASK) >> AD1843_LD2M_SHIFT;
    632 		right = (value & AD1843_RD2M_MASK) >> AD1843_RD2M_SHIFT;
    633 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    634 		    AUDIO_MAX_GAIN - (left << 3);
    635 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    636 		    AUDIO_MAX_GAIN - (right << 3);
    637 		break;
    638 	case AD1843_MONO_GAIN:
    639 		if (mc->un.value.num_channels != 1)
    640 			return EINVAL;
    641 
    642 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    643 		left = (value & AD1843_MNM_MASK) >> AD1843_MNM_SHIFT;
    644 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    645 		    AUDIO_MAX_GAIN - (left << 3);
    646 		break;
    647 	case AD1843_DAC2_MUTE:
    648 	case AD1843_AUX1_MUTE:
    649 	case AD1843_AUX2_MUTE:
    650 	case AD1843_AUX3_MUTE:
    651 	case AD1843_MIC_MUTE:
    652 	case AD1843_MONO_MUTE:	/* matches left channel */
    653 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
    654 		value = ad1843_reg_read(sc, reg);
    655 		mc->un.ord = (value & AD1843_LD2MM) ? 1 : 0;
    656 		break;
    657 
    658 	case AD1843_SUM_MUTE:
    659 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    660 		mc->un.ord = (value & AD1843_SUMM) ? 1 : 0;
    661 		break;
    662 
    663 	case AD1843_MNO_MUTE:
    664 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    665 		mc->un.ord = (value & AD1843_MNOM) ? 1 : 0;
    666 		break;
    667 
    668 	case AD1843_HPO_MUTE:
    669 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    670 		mc->un.ord = (value & AD1843_HPOM) ? 1 : 0;
    671 		break;
    672 
    673 	default:
    674 		return EINVAL;
    675 	}
    676 
    677 	return 0;
    678 }
    679 
    680 int
    681 mavb_query_devinfo(void *hdl, struct mixer_devinfo *di)
    682 {
    683 	int i;
    684 
    685 	di->prev = di->next = AUDIO_MIXER_LAST;
    686 
    687 	switch (di->index) {
    688 	case AD1843_RECORD_CLASS:
    689 		di->type = AUDIO_MIXER_CLASS;
    690 		di->mixer_class = AD1843_RECORD_CLASS;
    691 		strlcpy(di->label.name, AudioCrecord, sizeof di->label.name);
    692 		break;
    693 
    694 	case AD1843_ADC_SOURCE:
    695 		di->type = AUDIO_MIXER_ENUM;
    696 		di->mixer_class = AD1843_RECORD_CLASS;
    697 		di->next = AD1843_ADC_GAIN;
    698 		strlcpy(di->label.name, AudioNsource, sizeof di->label.name);
    699 		di->un.e.num_mem =
    700 			sizeof ad1843_source / sizeof ad1843_source[1];
    701 		for (i = 0; i < di->un.e.num_mem; i++) {
    702 			strlcpy(di->un.e.member[i].label.name,
    703                             ad1843_source[i],
    704 			    sizeof di->un.e.member[0].label.name);
    705 			di->un.e.member[i].ord = i;
    706 		}
    707 		break;
    708 	case AD1843_ADC_GAIN:
    709 		di->type = AUDIO_MIXER_VALUE;
    710 		di->mixer_class = AD1843_RECORD_CLASS;
    711 		di->prev = AD1843_ADC_SOURCE;
    712 		strlcpy(di->label.name, AudioNvolume, sizeof di->label.name);
    713 		di->un.v.num_channels = 2;
    714 		strlcpy(di->un.v.units.name, AudioNvolume,
    715 		    sizeof di->un.v.units.name);
    716 		break;
    717 
    718 	case AD1843_INPUT_CLASS:
    719 		di->type = AUDIO_MIXER_CLASS;
    720 		di->mixer_class = AD1843_INPUT_CLASS;
    721 		strlcpy(di->label.name, AudioCinputs, sizeof di->label.name);
    722 		break;
    723 
    724 	case AD1843_DAC1_GAIN:
    725 		di->type = AUDIO_MIXER_VALUE;
    726 		di->mixer_class = AD1843_OUTPUT_CLASS;
    727 		di->next = AD1843_DAC1_MUTE;
    728 		strlcpy(di->label.name, AudioNmaster, sizeof di->label.name);
    729 		di->un.v.num_channels = 2;
    730 		strlcpy(di->un.v.units.name, AudioNvolume,
    731 		    sizeof di->un.v.units.name);
    732 		break;
    733 	case AD1843_DAC1_MUTE:
    734 		di->type = AUDIO_MIXER_ENUM;
    735 		di->mixer_class = AD1843_OUTPUT_CLASS;
    736 		di->prev = AD1843_DAC1_GAIN;
    737 		strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
    738 		di->un.e.num_mem = 2;
    739 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    740 		    sizeof di->un.e.member[0].label.name);
    741 		di->un.e.member[0].ord = 0;
    742 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    743 		    sizeof di->un.e.member[1].label.name);
    744 		di->un.e.member[1].ord = 1;
    745 		break;
    746 
    747 	case AD1843_DAC2_GAIN:
    748 	case AD1843_AUX1_GAIN:
    749 	case AD1843_AUX2_GAIN:
    750 	case AD1843_AUX3_GAIN:
    751 	case AD1843_MIC_GAIN:
    752 	case AD1843_MONO_GAIN:
    753 		di->type = AUDIO_MIXER_VALUE;
    754 		di->mixer_class = AD1843_INPUT_CLASS;
    755 		di->next = di->index + AD1843_DAC2_MUTE - AD1843_DAC2_GAIN;
    756 		strlcpy(di->label.name,
    757                     ad1843_input[di->index - AD1843_DAC2_GAIN],
    758 		    sizeof di->label.name);
    759 		if (di->index == AD1843_MONO_GAIN)
    760 			di->un.v.num_channels = 1;
    761 		else
    762 			di->un.v.num_channels = 2;
    763 		strlcpy(di->un.v.units.name, AudioNvolume,
    764 		    sizeof di->un.v.units.name);
    765 		break;
    766 	case AD1843_DAC2_MUTE:
    767 	case AD1843_AUX1_MUTE:
    768 	case AD1843_AUX2_MUTE:
    769 	case AD1843_AUX3_MUTE:
    770 	case AD1843_MIC_MUTE:
    771 	case AD1843_MONO_MUTE:
    772 		di->type = AUDIO_MIXER_ENUM;
    773 		di->mixer_class = AD1843_INPUT_CLASS;
    774 		di->prev = di->index + AD1843_DAC2_GAIN - AD1843_DAC2_MUTE;
    775 		strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
    776 		di->un.e.num_mem = 2;
    777 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    778 		    sizeof di->un.e.member[0].label.name);
    779 		di->un.e.member[0].ord = 0;
    780 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    781 		    sizeof di->un.e.member[1].label.name);
    782 		di->un.e.member[1].ord = 1;
    783 		break;
    784 
    785 	case AD1843_SUM_MUTE:
    786 		di->type = AUDIO_MIXER_ENUM;
    787 		di->mixer_class = AD1843_INPUT_CLASS;
    788 		strlcpy(di->label.name, "sum." AudioNmute,
    789 		    sizeof di->label.name);
    790 		di->un.e.num_mem = 2;
    791 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    792 		    sizeof di->un.e.member[0].label.name);
    793 		di->un.e.member[0].ord = 0;
    794 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    795 		    sizeof di->un.e.member[1].label.name);
    796 		di->un.e.member[1].ord = 1;
    797 		break;
    798 
    799 	case AD1843_OUTPUT_CLASS:
    800 		di->type = AUDIO_MIXER_CLASS;
    801 		di->mixer_class = AD1843_OUTPUT_CLASS;
    802 		strlcpy(di->label.name, AudioCoutputs, sizeof di->label.name);
    803 		break;
    804 
    805 	case AD1843_MNO_MUTE:
    806 		di->type = AUDIO_MIXER_ENUM;
    807 		di->mixer_class = AD1843_OUTPUT_CLASS;
    808 		strlcpy(di->label.name, AudioNmono "." AudioNmute,
    809 		    sizeof di->label.name);
    810 		di->un.e.num_mem = 2;
    811 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    812 		    sizeof di->un.e.member[0].label.name);
    813 		di->un.e.member[0].ord = 0;
    814 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    815 		    sizeof di->un.e.member[1].label.name);
    816 		di->un.e.member[1].ord = 1;
    817 		break;
    818 
    819 	case AD1843_HPO_MUTE:
    820 		di->type = AUDIO_MIXER_ENUM;
    821 		di->mixer_class = AD1843_OUTPUT_CLASS;
    822 		strlcpy(di->label.name, AudioNheadphone "." AudioNmute,
    823 		    sizeof di->label.name);
    824 		di->un.e.num_mem = 2;
    825 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    826 		    sizeof di->un.e.member[0].label.name);
    827 		di->un.e.member[0].ord = 0;
    828 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    829 		    sizeof di->un.e.member[1].label.name);
    830 		di->un.e.member[1].ord = 1;
    831 		break;
    832 
    833 	default:
    834 		return EINVAL;
    835 	}
    836 
    837 	return 0;
    838 }
    839 
    840 size_t
    841 mavb_round_buffersize(void *hdl, int dir, size_t bufsize)
    842 {
    843 
    844 	return bufsize;
    845 }
    846 
    847 int
    848 mavb_get_props(void *hdl)
    849 {
    850 
    851 	return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT;
    852 }
    853 
    854 static void
    855 mavb_dma_output(struct mavb_softc *sc)
    856 {
    857 	bus_space_tag_t st = sc->sc_st;
    858 	bus_space_handle_t sh = sc->sc_sh;
    859 	uint64_t write_ptr;
    860 	uint64_t depth;
    861 	uint8_t *src, *dst;
    862 	int count;
    863 
    864 	KASSERT(mutex_owned(&sc->sc_intr_lock));
    865 
    866 	write_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL2_WRITE_PTR);
    867 	depth = bus_space_read_8(st, sh, MAVB_CHANNEL2_DEPTH);
    868 
    869 	dst = sc->sc_ring + write_ptr;
    870 	src = sc->sc_get;
    871 
    872 	count = (MAVB_ISA_RING_SIZE - depth - 32);
    873 	while (--count >= 0) {
    874 		*dst++ = *src++;
    875 		if (dst >= sc->sc_ring + MAVB_ISA_RING_SIZE)
    876 			dst = sc->sc_ring;
    877 		if (src >= sc->sc_end)
    878 			src = sc->sc_start;
    879 		if (++sc->sc_count >= sc->sc_blksize) {
    880 			if (sc->sc_intr)
    881 				sc->sc_intr(sc->sc_intrarg);
    882 			sc->sc_count = 0;
    883 		}
    884 	}
    885 
    886 	write_ptr = dst - sc->sc_ring;
    887 	bus_space_write_8(st, sh, MAVB_CHANNEL2_WRITE_PTR, write_ptr);
    888 	sc->sc_get = src;
    889 }
    890 
    891 int
    892 mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
    893 		    void (*intr)(void *), void *intrarg,
    894 		    const audio_params_t *param)
    895 {
    896 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    897 
    898 	DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
    899 	    "blksize=%d intr=%p(%p)\n", device_xname(sc->sc_dev),
    900 	    start, end, blksize, intr, intrarg));
    901 
    902 	sc->sc_blksize = blksize;
    903 	sc->sc_intr = intr;
    904 	sc->sc_intrarg = intrarg;
    905 
    906 	sc->sc_start = sc->sc_get = start;
    907 	sc->sc_end = end;
    908 
    909 	sc->sc_count = 0;
    910 
    911 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
    912 	    MAVB_CHANNEL_RESET);
    913 	delay(1000);
    914 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
    915 
    916 	mavb_dma_output(sc);
    917 
    918 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
    919 	    MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
    920 
    921 	return 0;
    922 }
    923 
    924 int
    925 mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
    926 		   void (*intr)(void *), void *intrarg,
    927 		   const audio_params_t *param)
    928 {
    929 
    930 	return 0;
    931 }
    932 
    933 void
    934 mavb_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread)
    935 {
    936 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    937 
    938 	*intr = &sc->sc_intr_lock;
    939 	*thread = &sc->sc_lock;
    940 }
    941 
    942 static void
    943 mavb_button_repeat(void *hdl)
    944 {
    945 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    946 	uint64_t intmask, control;
    947 	uint16_t value, left, right;
    948 
    949 	DPRINTF(1, ("%s: mavb_repeat called\n", device_xname(sc->sc_dev)));
    950 
    951 #define  MAVB_CONTROL_VOLUME_BUTTONS \
    952     (MAVB_CONTROL_VOLUME_BUTTON_UP | MAVB_CONTROL_VOLUME_BUTTON_DOWN)
    953 
    954 	control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
    955 	if (control & MAVB_CONTROL_VOLUME_BUTTONS) {
    956 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    957 		left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
    958 		right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
    959 		if (control & MAVB_CONTROL_VOLUME_BUTTON_UP) {
    960 			control &= ~MAVB_CONTROL_VOLUME_BUTTON_UP;
    961 			if (left > 0)
    962 				left--;		/* attenuation! */
    963 			if (right > 0)
    964 				right--;
    965 		}
    966 		if (control & MAVB_CONTROL_VOLUME_BUTTON_DOWN) {
    967 			control &= ~MAVB_CONTROL_VOLUME_BUTTON_DOWN;
    968 			if (left < 63)
    969 				left++;
    970 			if (right < 63)
    971 				right++;
    972 		}
    973 		bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, control);
    974 
    975 		value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
    976 		value |= (left << AD1843_LDA1G_SHIFT);
    977 		value |= (right << AD1843_RDA1G_SHIFT);
    978 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    979 
    980 		callout_reset(&sc->sc_volume_button_ch,
    981 		    (hz * MAVB_VOLUME_BUTTON_REPEAT_DELN) / 1000,
    982 		    mavb_button_repeat, sc);
    983 	} else {
    984 		/* Enable volume button interrupts again.  */
    985 		intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
    986 		     MACE_ISA_INT_MASK);
    987 		bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
    988 		     intmask | MACE_ISA_INT_AUDIO_SC);
    989 	}
    990 }
    991 
    992 static int
    993 mavb_intr(void *arg)
    994 {
    995 	struct mavb_softc *sc = arg;
    996 	uint64_t stat, intmask;
    997 
    998 	mutex_spin_enter(&sc->sc_intr_lock);
    999 
   1000 	stat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STATUS);
   1001 	DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: stat = 0x%llx\n",
   1002             device_xname(sc->sc_dev), stat));
   1003 
   1004 	if (stat & MACE_ISA_INT_AUDIO_SC) {
   1005 		/* Disable volume button interrupts.  */
   1006 		intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
   1007 		     MACE_ISA_INT_MASK);
   1008 		bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
   1009 		     intmask & ~MACE_ISA_INT_AUDIO_SC);
   1010 
   1011 		callout_reset(&sc->sc_volume_button_ch,
   1012 		    (hz * MAVB_VOLUME_BUTTON_REPEAT_DEL1) / 1000,
   1013 		    mavb_button_repeat, sc);
   1014 	}
   1015 
   1016 	if (stat & MACE_ISA_INT_AUDIO_DMA2)
   1017 		mavb_dma_output(sc);
   1018 
   1019 	mutex_spin_exit(&sc->sc_intr_lock);
   1020 
   1021 	return 1;
   1022 }
   1023 
   1024 int
   1025 mavb_match(device_t parent, cfdata_t match, void *aux)
   1026 {
   1027 
   1028 	return 1;
   1029 }
   1030 
   1031 void
   1032 mavb_attach(device_t parent, device_t self, void *aux)
   1033 {
   1034 	struct mavb_softc *sc = device_private(self);
   1035 	struct mace_attach_args *maa = aux;
   1036 	bus_dma_segment_t seg;
   1037 	uint64_t control;
   1038 	uint16_t value;
   1039 	int rseg, err;
   1040 
   1041 	sc->sc_dev = self;
   1042 
   1043 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
   1044 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
   1045 
   1046 	sc->sc_st = maa->maa_st;
   1047 	if (bus_space_subregion(sc->sc_st, maa->maa_sh, maa->maa_offset,
   1048 	    0, &sc->sc_sh) != 0) {
   1049 		printf(": can't map i/o space\n");
   1050 		return;
   1051 	}
   1052 
   1053 	/* XXX We need access to some of the MACE ISA registers.  */
   1054 	if (bus_space_subregion(sc->sc_st, maa->maa_sh, 0, 0,
   1055 	    &sc->sc_isash) != 0) {
   1056 		printf(": can't map isa i/o space\n");
   1057 		return;
   1058 	}
   1059 
   1060 	/* Set up DMA structures.  */
   1061 	sc->sc_dmat = maa->maa_dmat;
   1062 	if (bus_dmamap_create(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE, 1,
   1063 	    4 * MAVB_ISA_RING_SIZE, 0, 0, &sc->sc_dmamap)) {
   1064 		printf(": can't create MACE ISA DMA map\n");
   1065 		return;
   1066 	}
   1067 
   1068 	if (bus_dmamem_alloc(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE,
   1069 	    MACE_ISA_RING_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
   1070 		printf(": can't allocate ring buffer\n");
   1071 		return;
   1072 	}
   1073 
   1074 	if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, 4 * MAVB_ISA_RING_SIZE,
   1075 	    (void *)&sc->sc_ring, BUS_DMA_COHERENT)) {
   1076 		printf(": can't map ring buffer\n");
   1077 		return;
   1078 	}
   1079 
   1080 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ring,
   1081 	    4 * MAVB_ISA_RING_SIZE, NULL, BUS_DMA_NOWAIT)) {
   1082 		printf(": can't load MACE ISA DMA map\n");
   1083 		return;
   1084 	}
   1085 
   1086 	sc->sc_ring += MAVB_ISA_RING_SIZE; /* XXX */
   1087 
   1088 	bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_RINGBASE,
   1089 	    sc->sc_dmamap->dm_segs[0].ds_addr);
   1090 
   1091 	/* Establish interrupt.  */
   1092 	cpu_intr_establish(maa->maa_intr, maa->maa_intrmask,
   1093 	    mavb_intr, sc);
   1094 
   1095 	control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
   1096 	if (!(control & MAVB_CONTROL_CODEC_PRESENT)) {
   1097 		printf(": no codec present\n");
   1098 		return;
   1099 	}
   1100 
   1101 	/* 2. Assert the RESET signal.  */
   1102 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL,
   1103 	    MAVB_CONTROL_RESET);
   1104 	delay(1);		/* at least 100 ns */
   1105 
   1106 	/* 3. Deassert the RESET signal and enter a wait period to
   1107               allow the AD1843 internal clocks and the external
   1108               crystal oscillator to stabilize.  */
   1109 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, 0);
   1110 	delay(800);		/* typically 400 us to 800 us */
   1111 	if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_INIT) {
   1112 		printf(": codec not ready\n");
   1113 		return;
   1114 	}
   1115 
   1116 	/* 4. Put the conversion sources into standby.  */
   1117 	value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
   1118 	ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
   1119 	    value & ~AD1843_PDNI);
   1120 	delay (500000);		/* approximately 474 ms */
   1121 	if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_PDNO) {
   1122 		printf(": can't power up conversion resources\n");
   1123 		return;
   1124 	}
   1125 
   1126 	/* 5. Power up the clock generators and enable clock output pins.  */
   1127 	value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
   1128 	ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS, value | AD1843_C2EN);
   1129 
   1130 	/* 6. Configure conversion resources while they are in standby.  */
   1131 	value = ad1843_reg_read(sc, AD1843_CHANNEL_SAMPLE_RATE);
   1132 	ad1843_reg_write(sc, AD1843_CHANNEL_SAMPLE_RATE,
   1133 	     value | (2 << AD1843_DA1C_SHIFT));
   1134 
   1135 	/* 7. Enable conversion resources.  */
   1136 	value = ad1843_reg_read(sc, AD1843_CHANNEL_POWER_DOWN);
   1137 	ad1843_reg_write(sc, AD1843_CHANNEL_POWER_DOWN,
   1138 	     value | (AD1843_DA1EN | AD1843_AAMEN));
   1139 
   1140 	/* 8. Configure conversion resources while they are enabled.  */
   1141 	value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
   1142 	ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN,
   1143             value & ~(AD1843_LDA1GM | AD1843_RDA1GM));
   1144 	value = ad1843_reg_read(sc, AD1843_DAC1_DIGITAL_GAIN);
   1145 	ad1843_reg_write(sc, AD1843_DAC1_DIGITAL_GAIN,
   1146             value & ~(AD1843_LDA1AM | AD1843_RDA1AM));
   1147 	value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
   1148 	ad1843_reg_write(sc, AD1843_MISC_SETTINGS,
   1149             value & ~(AD1843_HPOM | AD1843_MNOM));
   1150 
   1151 	value = ad1843_reg_read(sc, AD1843_CODEC_STATUS);
   1152 	printf(": AD1843 rev %d\n", (u_int)value & AD1843_REVISION_MASK);
   1153 
   1154 	sc->sc_play_rate = 48000;
   1155 	sc->sc_play_format = AD1843_PCM8;
   1156 
   1157 	memcpy(sc->sc_formats, mavb_formats, sizeof(mavb_formats));
   1158 	err = auconv_create_encodings(sc->sc_formats, MAVB_NFORMATS,
   1159 	    &sc->sc_encodings);
   1160 	if (err) {
   1161 		printf("%s: couldn't create encodings: %d\n",
   1162 		    device_xname(self), err);
   1163 		return;
   1164 	}
   1165 
   1166 	callout_init(&sc->sc_volume_button_ch, 0);
   1167 
   1168 	audio_attach_mi(&mavb_sa_hw_if, sc, self);
   1169 
   1170 	return;
   1171 }
   1172 
   1173 uint16_t
   1174 ad1843_reg_read(struct mavb_softc *sc, ad1843_addr_t addr)
   1175 {
   1176 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
   1177             (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
   1178 	    MAVB_CODEC_READ);
   1179 	delay(200);
   1180 	return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
   1181 }
   1182 
   1183 uint16_t
   1184 ad1843_reg_write(struct mavb_softc *sc, ad1843_addr_t addr, uint16_t value)
   1185 {
   1186 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
   1187 	    (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
   1188 	    (value & MAVB_CODEC_WORD_MASK) << MAVB_CODEC_WORD_SHIFT);
   1189 	delay(200);
   1190 	return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
   1191 }
   1192 
   1193 void
   1194 ad1843_dump_regs(struct mavb_softc *sc)
   1195 {
   1196 	uint16_t addr;
   1197 
   1198 	for (addr = 0; addr < AD1843_NREGS; addr++)
   1199 		printf("%d: 0x%04x\n", addr, ad1843_reg_read(sc, addr));
   1200 }
   1201