Home | History | Annotate | Line # | Download | only in gsc
      1 /*	$NetBSD: harmony.c,v 1.11 2022/05/15 00:25:15 gutteridge Exp $	*/
      2 
      3 /*	$OpenBSD: harmony.c,v 1.23 2004/02/13 21:28:19 mickey Exp $	*/
      4 
      5 /*-
      6  * Copyright (c) 2009 The NetBSD Foundation, Inc.
      7  * All rights reserved.
      8  *
      9  * This code is derived from software contributed to The NetBSD Foundation
     10  * by Matt Fleming.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31  * POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 /*
     35  * Copyright (c) 2003 Jason L. Wright (jason (at) thought.net)
     36  * All rights reserved.
     37  *
     38  * Redistribution and use in source and binary forms, with or without
     39  * modification, are permitted provided that the following conditions
     40  * are met:
     41  * 1. Redistributions of source code must retain the above copyright
     42  *    notice, this list of conditions and the following disclaimer.
     43  * 2. Redistributions in binary form must reproduce the above copyright
     44  *    notice, this list of conditions and the following disclaimer in the
     45  *    documentation and/or other materials provided with the distribution.
     46  *
     47  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     49  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     50  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     51  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     52  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     53  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     54  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     55  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     56  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     57  * POSSIBILITY OF SUCH DAMAGE.
     58  */
     59 
     60 /*
     61  * Harmony (CS4215/AD1849 LASI) audio interface.
     62  */
     63 
     64 
     65 
     66 #include <sys/param.h>
     67 #include <sys/kernel.h>
     68 #include <sys/systm.h>
     69 #include <sys/errno.h>
     70 #include <sys/ioctl.h>
     71 #include <sys/device.h>
     72 #include <sys/proc.h>
     73 #include <sys/kmem.h>
     74 #include <uvm/uvm_extern.h>
     75 
     76 #include <sys/rndsource.h>
     77 
     78 #include <sys/audioio.h>
     79 #include <dev/audio/audio_if.h>
     80 
     81 #include <machine/cpu.h>
     82 #include <machine/intr.h>
     83 #include <machine/iomod.h>
     84 #include <machine/autoconf.h>
     85 #include <sys/bus.h>
     86 
     87 #include <hppa/dev/cpudevs.h>
     88 #include <hppa/gsc/gscbusvar.h>
     89 #include <hppa/gsc/harmonyreg.h>
     90 #include <hppa/gsc/harmonyvar.h>
     91 
     92 void	harmony_close(void *);
     93 int	harmony_query_format(void *, audio_format_query_t *);
     94 int	harmony_set_format(void *, int,
     95     const audio_params_t *, const audio_params_t *,
     96     audio_filter_reg_t *, audio_filter_reg_t *);
     97 int	harmony_round_blocksize(void *, int, int, const audio_params_t *);
     98 
     99 int	harmony_control_wait(struct harmony_softc *);
    100 int	harmony_commit_settings(void *);
    101 
    102 int	harmony_halt_output(void *);
    103 int	harmony_halt_input(void *);
    104 int	harmony_getdev(void *, struct audio_device *);
    105 int	harmony_set_port(void *, mixer_ctrl_t *);
    106 int	harmony_get_port(void *, mixer_ctrl_t *);
    107 int	harmony_query_devinfo(void *, mixer_devinfo_t *);
    108 void *	harmony_allocm(void *, int, size_t);
    109 void	harmony_freem(void *, void *, size_t);
    110 size_t	harmony_round_buffersize(void *, int, size_t);
    111 int	harmony_get_props(void *);
    112 int	harmony_trigger_output(void *, void *, void *, int,
    113     void (*)(void *), void *, const audio_params_t *);
    114 int	harmony_trigger_input(void *, void *, void *, int,
    115     void (*)(void *), void *, const audio_params_t *);
    116 void	harmony_get_locks(void *, kmutex_t **, kmutex_t **);
    117 
    118 const struct audio_hw_if harmony_sa_hw_if = {
    119 	.close			= harmony_close,
    120 	.query_format		= harmony_query_format,
    121 	.set_format		= harmony_set_format,
    122 	.round_blocksize	= harmony_round_blocksize,
    123 	.commit_settings	= harmony_commit_settings,
    124 	.halt_output		= harmony_halt_output,
    125 	.halt_input		= harmony_halt_input,
    126 	.getdev			= harmony_getdev,
    127 	.set_port		= harmony_set_port,
    128 	.get_port		= harmony_get_port,
    129 	.query_devinfo		= harmony_query_devinfo,
    130 	.allocm			= harmony_allocm,
    131 	.freem			= harmony_freem,
    132 	.round_buffersize	= harmony_round_buffersize,
    133 	.get_props		= harmony_get_props,
    134 	.trigger_output		= harmony_trigger_output,
    135 	.trigger_input		= harmony_trigger_input,
    136 	.get_locks		= harmony_get_locks,
    137 };
    138 
    139 /*
    140  * The HW actually supports more frequencies, but these are the standard ones.
    141  * For the full list, see the definition of harmony_speeds below.
    142  */
    143 #define HARMONY_FORMAT(enc, prec) \
    144 	{ \
    145 		.mode		= AUMODE_PLAY | AUMODE_RECORD, \
    146 		.encoding	= (enc), \
    147 		.validbits	= (prec), \
    148 		.precision	= (prec), \
    149 		.channels	= 2, \
    150 		.channel_mask	= AUFMT_STEREO, \
    151 		.frequency_type = 4, \
    152 		.frequency	= { 16000, 32000, 44100, 48000 }, \
    153 	}
    154 static struct audio_format harmony_formats[] = {
    155 	HARMONY_FORMAT(AUDIO_ENCODING_ULAW,        8),
    156 	HARMONY_FORMAT(AUDIO_ENCODING_ALAW,        8),
    157 	HARMONY_FORMAT(AUDIO_ENCODING_SLINEAR_BE, 16),
    158 };
    159 #define HARMONY_NFORMATS __arraycount(harmony_formats)
    160 
    161 int harmony_match(device_t, struct cfdata *, void *);
    162 void harmony_attach(device_t, device_t, void *);
    163 
    164 
    165 CFATTACH_DECL_NEW(harmony, sizeof(struct harmony_softc),
    166     harmony_match, harmony_attach, NULL, NULL);
    167 
    168 int harmony_intr(void *);
    169 void harmony_intr_enable(struct harmony_softc *);
    170 void harmony_intr_disable(struct harmony_softc *);
    171 uint32_t harmony_speed_bits(struct harmony_softc *, u_int);
    172 int harmony_set_gainctl(struct harmony_softc *);
    173 void harmony_reset_codec(struct harmony_softc *);
    174 void harmony_start_cp(struct harmony_softc *, int);
    175 void harmony_start_pp(struct harmony_softc *, int);
    176 void harmony_tick_pb(void *);
    177 void harmony_tick_cp(void *);
    178 void harmony_try_more(struct harmony_softc *, int, int,
    179 	struct harmony_channel *);
    180 static void harmony_empty_input(struct harmony_softc *);
    181 static void harmony_empty_output(struct harmony_softc *);
    182 
    183 void harmony_acc_tmo(void *);
    184 #define	ADD_CLKALLICA(sc) do {						\
    185 	(sc)->sc_acc <<= 1;						\
    186 	(sc)->sc_acc |= READ_REG((sc), HARMONY_DIAG) & DIAG_CO;		\
    187 	if ((sc)->sc_acc_cnt++ && !((sc)->sc_acc_cnt % 32))		\
    188 		rnd_add_uint32(&(sc)->sc_rnd_source,			\
    189 			       (sc)->sc_acc_num ^= (sc)->sc_acc);	\
    190 } while(0)
    191 
    192 int
    193 harmony_match(device_t parent, struct cfdata *match, void *aux)
    194 {
    195 	struct gsc_attach_args *ga;
    196 
    197 	ga = aux;
    198 	if (ga->ga_type.iodc_type == HPPA_TYPE_FIO) {
    199 		if (ga->ga_type.iodc_sv_model == HPPA_FIO_A1 ||
    200 		    ga->ga_type.iodc_sv_model == HPPA_FIO_A2NB ||
    201 		    ga->ga_type.iodc_sv_model == HPPA_FIO_A1NB ||
    202 		    ga->ga_type.iodc_sv_model == HPPA_FIO_A2)
    203 			return 1;
    204 	}
    205 	return 0;
    206 }
    207 
    208 void
    209 harmony_attach(device_t parent, device_t self, void *aux)
    210 {
    211 	struct harmony_softc *sc = device_private(self);
    212 	struct gsc_attach_args *ga;
    213 	uint8_t rev;
    214 	uint32_t cntl;
    215 	int i;
    216 
    217 	sc->sc_dv = self;
    218 	ga = aux;
    219 	sc->sc_bt = ga->ga_iot;
    220 	sc->sc_dmat = ga->ga_dmatag;
    221 
    222 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    223 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
    224 
    225 	if (bus_space_map(sc->sc_bt, ga->ga_hpa, HARMONY_NREGS, 0,
    226 	    &sc->sc_bh) != 0) {
    227 		aprint_error(": couldn't map registers\n");
    228 		return;
    229 	}
    230 
    231 	cntl = READ_REG(sc, HARMONY_ID);
    232 	switch ((cntl & ID_REV_MASK)) {
    233 	case ID_REV_TS:
    234 		sc->sc_teleshare = 1;
    235 	case ID_REV_NOTS:
    236 		break;
    237 	default:
    238 		aprint_error(": unknown id == 0x%02x\n",
    239 		    (cntl & ID_REV_MASK) >> ID_REV_SHIFT);
    240 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    241 		return;
    242 	}
    243 
    244 	if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct harmony_empty),
    245 	    PAGE_SIZE, 0, &sc->sc_empty_seg, 1, &sc->sc_empty_rseg,
    246 	    BUS_DMA_WAITOK) != 0) {
    247 		aprint_error(": could not alloc DMA memory\n");
    248 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    249 		return;
    250 	}
    251 	if (bus_dmamem_map(sc->sc_dmat, &sc->sc_empty_seg, 1,
    252 	    sizeof(struct harmony_empty), (void **)&sc->sc_empty_kva,
    253 	    BUS_DMA_WAITOK) != 0) {
    254 		aprint_error(": couldn't map DMA memory\n");
    255 		bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
    256 		    sc->sc_empty_rseg);
    257 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    258 		return;
    259 	}
    260 	if (bus_dmamap_create(sc->sc_dmat, sizeof(struct harmony_empty), 1,
    261 	    sizeof(struct harmony_empty), 0, BUS_DMA_WAITOK,
    262 	    &sc->sc_empty_map) != 0) {
    263 		aprint_error(": can't create DMA map\n");
    264 		bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_empty_kva,
    265 		    sizeof(struct harmony_empty));
    266 		bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
    267 		    sc->sc_empty_rseg);
    268 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    269 		return;
    270 	}
    271 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_empty_map, sc->sc_empty_kva,
    272 	    sizeof(struct harmony_empty), NULL, BUS_DMA_WAITOK) != 0) {
    273 		aprint_error(": can't load DMA map\n");
    274 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_empty_map);
    275 		bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_empty_kva,
    276 		    sizeof(struct harmony_empty));
    277 		bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
    278 		    sc->sc_empty_rseg);
    279 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    280 		return;
    281 	}
    282 
    283 	sc->sc_playback_empty = 0;
    284 	for (i = 0; i < PLAYBACK_EMPTYS; i++)
    285 		sc->sc_playback_paddrs[i] =
    286 		    sc->sc_empty_map->dm_segs[0].ds_addr +
    287 		    offsetof(struct harmony_empty, playback[i][0]);
    288 
    289 	sc->sc_capture_empty = 0;
    290 	for (i = 0; i < CAPTURE_EMPTYS; i++)
    291 		sc->sc_capture_paddrs[i] =
    292 		    sc->sc_empty_map->dm_segs[0].ds_addr +
    293 		    offsetof(struct harmony_empty, capture[i][0]);
    294 
    295 	bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
    296 	    offsetof(struct harmony_empty, playback[0][0]),
    297 	    PLAYBACK_EMPTYS * HARMONY_BUFSIZE, BUS_DMASYNC_PREWRITE);
    298 
    299 	(void) hppa_intr_establish(IPL_AUDIO, harmony_intr, sc, ga->ga_ir,
    300 	     ga->ga_irq);
    301 
    302 	/* set defaults */
    303 	sc->sc_in_port = HARMONY_IN_LINE;
    304 	sc->sc_out_port = HARMONY_OUT_SPEAKER;
    305 	sc->sc_input_lvl.left = sc->sc_input_lvl.right = 240;
    306 	sc->sc_output_lvl.left = sc->sc_output_lvl.right = 244;
    307 	sc->sc_monitor_lvl.left = sc->sc_monitor_lvl.right = 208;
    308 	sc->sc_outputgain = 0;
    309 
    310 	/* reset chip, and push default gain controls */
    311 	harmony_reset_codec(sc);
    312 
    313 	cntl = READ_REG(sc, HARMONY_CNTL);
    314 	rev = (cntl & CNTL_CODEC_REV_MASK) >> CNTL_CODEC_REV_SHIFT;
    315 	aprint_normal(": rev %u", rev);
    316 
    317 	if (sc->sc_teleshare)
    318 		printf(", teleshare");
    319 	aprint_normal("\n");
    320 
    321 	strlcpy(sc->sc_audev.name, ga->ga_name, sizeof(sc->sc_audev.name));
    322 	snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version,
    323 	    "%u.%u;%u", ga->ga_type.iodc_sv_rev,
    324 	    ga->ga_type.iodc_model, ga->ga_type.iodc_revision);
    325 	strlcpy(sc->sc_audev.config, device_xname(sc->sc_dv),
    326 	    sizeof(sc->sc_audev.config));
    327 
    328 	audio_attach_mi(&harmony_sa_hw_if, sc, sc->sc_dv);
    329 
    330 	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dv),
    331 	    RND_TYPE_UNKNOWN, RND_FLAG_DEFAULT);
    332 
    333 	callout_init(&sc->sc_acc_tmo, 0);
    334 	callout_setfunc(&sc->sc_acc_tmo, harmony_acc_tmo, sc);
    335 	sc->sc_acc_num = 0xa5a5a5a5;
    336 }
    337 
    338 void
    339 harmony_reset_codec(struct harmony_softc *sc)
    340 {
    341 
    342 	/* silence */
    343 	WRITE_REG(sc, HARMONY_GAINCTL, GAINCTL_OUTPUT_LEFT_M |
    344 	    GAINCTL_OUTPUT_RIGHT_M | GAINCTL_MONITOR_M);
    345 
    346 	/* start reset */
    347 	WRITE_REG(sc, HARMONY_RESET, RESET_RST);
    348 
    349 	DELAY(100000);		/* wait at least 0.1 sec */
    350 
    351 	harmony_set_gainctl(sc);
    352 	WRITE_REG(sc, HARMONY_RESET, 0);
    353 }
    354 
    355 void
    356 harmony_acc_tmo(void *v)
    357 {
    358 	struct harmony_softc *sc;
    359 
    360 	sc = v;
    361 	ADD_CLKALLICA(sc);
    362 	callout_schedule(&sc->sc_acc_tmo, 1);
    363 }
    364 
    365 /*
    366  * interrupt handler
    367  */
    368 int
    369 harmony_intr(void *vsc)
    370 {
    371 	struct harmony_softc *sc;
    372 	uint32_t dstatus;
    373 	int r;
    374 
    375 	sc = vsc;
    376 	r = 0;
    377 	ADD_CLKALLICA(sc);
    378 
    379 	mutex_spin_enter(&sc->sc_intr_lock);
    380 
    381 	harmony_intr_disable(sc);
    382 
    383 	dstatus = READ_REG(sc, HARMONY_DSTATUS);
    384 
    385 	if (dstatus & DSTATUS_PN) {
    386 		r = 1;
    387 		harmony_start_pp(sc, 0);
    388 	}
    389 
    390 	if (dstatus & DSTATUS_RN) {
    391 		r = 1;
    392 		harmony_start_cp(sc, 0);
    393 	}
    394 
    395 	if (READ_REG(sc, HARMONY_OV) & OV_OV) {
    396 		sc->sc_ov = 1;
    397 		WRITE_REG(sc, HARMONY_OV, 0);
    398 	} else
    399 		sc->sc_ov = 0;
    400 
    401 	harmony_intr_enable(sc);
    402 
    403 	mutex_spin_exit(&sc->sc_intr_lock);
    404 
    405 	return r;
    406 }
    407 
    408 void
    409 harmony_intr_enable(struct harmony_softc *sc)
    410 {
    411 
    412 	WRITE_REG(sc, HARMONY_DSTATUS, DSTATUS_IE);
    413 	SYNC_REG(sc, HARMONY_DSTATUS, BUS_SPACE_BARRIER_WRITE);
    414 }
    415 
    416 void
    417 harmony_intr_disable(struct harmony_softc *sc)
    418 {
    419 
    420 	WRITE_REG(sc, HARMONY_DSTATUS, 0);
    421 	SYNC_REG(sc, HARMONY_DSTATUS, BUS_SPACE_BARRIER_WRITE);
    422 }
    423 
    424 void
    425 harmony_close(void *vsc)
    426 {
    427 	struct harmony_softc *sc;
    428 
    429 	sc = vsc;
    430 	harmony_intr_disable(sc);
    431 }
    432 
    433 int
    434 harmony_query_format(void *vsc, audio_format_query_t *afp)
    435 {
    436 
    437 	return audio_query_format(harmony_formats, HARMONY_NFORMATS, afp);
    438 }
    439 
    440 int
    441 harmony_set_format(void *vsc, int setmode,
    442     const audio_params_t *play, const audio_params_t *rec,
    443     audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
    444 {
    445 	struct harmony_softc *sc;
    446 	uint32_t bits;
    447 
    448 	sc = vsc;
    449 
    450 	/* *play and *rec are the identical because !AUDIO_PROP_INDEPENDENT. */
    451 	switch (play->encoding) {
    452 	case AUDIO_ENCODING_ULAW:
    453 		bits = CNTL_FORMAT_ULAW;
    454 		break;
    455 	case AUDIO_ENCODING_ALAW:
    456 		bits = CNTL_FORMAT_ALAW;
    457 		break;
    458 	case AUDIO_ENCODING_SLINEAR_BE:
    459 		bits = CNTL_FORMAT_SLINEAR16BE;
    460 		break;
    461 	default:
    462 		return EINVAL;
    463 	}
    464 
    465 	if (sc->sc_outputgain)
    466 		bits |= CNTL_OLB;
    467 
    468 	bits |= CNTL_CHANS_STEREO;
    469 	bits |= harmony_speed_bits(sc, play->sample_rate);
    470 	sc->sc_cntlbits = bits;
    471 	sc->sc_need_commit = 1;
    472 
    473 	return 0;
    474 }
    475 
    476 int
    477 harmony_round_blocksize(void *vsc, int blk,
    478     int mode, const audio_params_t *param)
    479 {
    480 
    481 	return HARMONY_BUFSIZE;
    482 }
    483 
    484 int
    485 harmony_control_wait(struct harmony_softc *sc)
    486 {
    487 	uint32_t reg;
    488 	int j = 0;
    489 
    490 	while (j < 10) {
    491 		/* Wait for it to come out of control mode */
    492 		reg = READ_REG(sc, HARMONY_CNTL);
    493 		if ((reg & CNTL_C) == 0)
    494 			return 0;
    495 		DELAY(50000);		/* wait 0.05 */
    496 		j++;
    497 	}
    498 
    499 	return 1;
    500 }
    501 
    502 int
    503 harmony_commit_settings(void *vsc)
    504 {
    505 	struct harmony_softc *sc;
    506 	uint32_t reg;
    507 	uint8_t quietchar;
    508 	int i;
    509 
    510 	sc = vsc;
    511 	if (sc->sc_need_commit == 0)
    512 		return 0;
    513 
    514 	harmony_intr_disable(sc);
    515 
    516 	for (;;) {
    517 		reg = READ_REG(sc, HARMONY_DSTATUS);
    518 		if ((reg & (DSTATUS_PC | DSTATUS_RC)) == 0)
    519 			break;
    520 	}
    521 
    522 	/* Setting some bits in gainctl requires a reset */
    523 	harmony_reset_codec(sc);
    524 
    525 	/* set the silence character based on the encoding type */
    526 	bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
    527 	    offsetof(struct harmony_empty, playback[0][0]),
    528 	    PLAYBACK_EMPTYS * HARMONY_BUFSIZE, BUS_DMASYNC_POSTWRITE);
    529 	switch (sc->sc_cntlbits & CNTL_FORMAT_MASK) {
    530 	case CNTL_FORMAT_ULAW:
    531 		quietchar = 0x7f;
    532 		break;
    533 	case CNTL_FORMAT_ALAW:
    534 		quietchar = 0x55;
    535 		break;
    536 	case CNTL_FORMAT_SLINEAR16BE:
    537 	case CNTL_FORMAT_ULINEAR8:
    538 	default:
    539 		quietchar = 0;
    540 		break;
    541 	}
    542 	for (i = 0; i < PLAYBACK_EMPTYS; i++)
    543 		memset(&sc->sc_empty_kva->playback[i][0],
    544 		    quietchar, HARMONY_BUFSIZE);
    545 	bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
    546 	    offsetof(struct harmony_empty, playback[0][0]),
    547 	    PLAYBACK_EMPTYS * HARMONY_BUFSIZE, BUS_DMASYNC_PREWRITE);
    548 
    549 	harmony_control_wait(sc);
    550 
    551 	bus_space_write_4(sc->sc_bt, sc->sc_bh, HARMONY_CNTL,
    552 	    sc->sc_cntlbits | CNTL_C);
    553 
    554 	harmony_control_wait(sc);
    555 
    556 	sc->sc_need_commit = 0;
    557 
    558 	if (sc->sc_playing || sc->sc_capturing)
    559 		harmony_intr_enable(sc);
    560 
    561 	return 0;
    562 }
    563 
    564 static void
    565 harmony_empty_output(struct harmony_softc *sc)
    566 {
    567 
    568 	WRITE_REG(sc, HARMONY_PNXTADD,
    569 	    sc->sc_playback_paddrs[sc->sc_playback_empty]);
    570 	SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
    571 
    572 	if (++sc->sc_playback_empty == PLAYBACK_EMPTYS)
    573 		sc->sc_playback_empty = 0;
    574 }
    575 
    576 int
    577 harmony_halt_output(void *vsc)
    578 {
    579 	struct harmony_softc *sc;
    580 
    581 	sc = vsc;
    582 	sc->sc_playing = 0;
    583 
    584 	harmony_empty_output(sc);
    585 	return 0;
    586 }
    587 
    588 static void
    589 harmony_empty_input(struct harmony_softc *sc)
    590 {
    591 
    592 	WRITE_REG(sc, HARMONY_RNXTADD,
    593 	    sc->sc_capture_paddrs[sc->sc_capture_empty]);
    594 	SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
    595 
    596 	if (++sc->sc_capture_empty == CAPTURE_EMPTYS)
    597 		sc->sc_capture_empty = 0;
    598 }
    599 
    600 int
    601 harmony_halt_input(void *vsc)
    602 {
    603 	struct harmony_softc *sc;
    604 
    605 	sc = vsc;
    606 	sc->sc_capturing = 0;
    607 
    608 	harmony_empty_input(sc);
    609 	return 0;
    610 }
    611 
    612 int
    613 harmony_getdev(void *vsc, struct audio_device *retp)
    614 {
    615 	struct harmony_softc *sc;
    616 
    617 	sc = vsc;
    618 	*retp = sc->sc_audev;
    619 	return 0;
    620 }
    621 
    622 int
    623 harmony_set_port(void *vsc, mixer_ctrl_t *cp)
    624 {
    625 	struct harmony_softc *sc;
    626 	int err;
    627 
    628 	sc = vsc;
    629 	err = EINVAL;
    630 	switch (cp->dev) {
    631 	case HARMONY_PORT_INPUT_LVL:
    632 		if (cp->type != AUDIO_MIXER_VALUE)
    633 			break;
    634 		if (cp->un.value.num_channels == 1)
    635 			sc->sc_input_lvl.left = sc->sc_input_lvl.right =
    636 			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    637 		else if (cp->un.value.num_channels == 2) {
    638 			sc->sc_input_lvl.left =
    639 			    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    640 			sc->sc_input_lvl.right =
    641 			    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    642 		} else
    643 			break;
    644 		sc->sc_need_commit = 1;
    645 		err = 0;
    646 		break;
    647 	case HARMONY_PORT_OUTPUT_LVL:
    648 		if (cp->type != AUDIO_MIXER_VALUE)
    649 			break;
    650 		if (cp->un.value.num_channels == 1)
    651 			sc->sc_output_lvl.left = sc->sc_output_lvl.right =
    652 			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    653 		else if (cp->un.value.num_channels == 2) {
    654 			sc->sc_output_lvl.left =
    655 			    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    656 			sc->sc_output_lvl.right =
    657 			    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    658 		} else
    659 			break;
    660 		sc->sc_need_commit = 1;
    661 		err = 0;
    662 		break;
    663 	case HARMONY_PORT_OUTPUT_GAIN:
    664 		if (cp->type != AUDIO_MIXER_ENUM)
    665 			break;
    666 		sc->sc_outputgain = cp->un.ord ? 1 : 0;
    667 		err = 0;
    668 		break;
    669 	case HARMONY_PORT_MONITOR_LVL:
    670 		if (cp->type != AUDIO_MIXER_VALUE)
    671 			break;
    672 		if (cp->un.value.num_channels != 1)
    673 			break;
    674 		sc->sc_monitor_lvl.left = sc->sc_input_lvl.right =
    675 		    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    676 		sc->sc_need_commit = 1;
    677 		err = 0;
    678 		break;
    679 	case HARMONY_PORT_RECORD_SOURCE:
    680 		if (cp->type != AUDIO_MIXER_ENUM)
    681 			break;
    682 		if (cp->un.ord != HARMONY_IN_LINE &&
    683 		    cp->un.ord != HARMONY_IN_MIC)
    684 			break;
    685 		sc->sc_in_port = cp->un.ord;
    686 		err = 0;
    687 		sc->sc_need_commit = 1;
    688 		break;
    689 	case HARMONY_PORT_OUTPUT_SOURCE:
    690 		if (cp->type != AUDIO_MIXER_ENUM)
    691 			break;
    692 		if (cp->un.ord != HARMONY_OUT_LINE &&
    693 		    cp->un.ord != HARMONY_OUT_SPEAKER &&
    694 		    cp->un.ord != HARMONY_OUT_HEADPHONE)
    695 			break;
    696 		sc->sc_out_port = cp->un.ord;
    697 		err = 0;
    698 		sc->sc_need_commit = 1;
    699 		break;
    700 	}
    701 
    702 	return err;
    703 }
    704 
    705 int
    706 harmony_get_port(void *vsc, mixer_ctrl_t *cp)
    707 {
    708 	struct harmony_softc *sc;
    709 	int err;
    710 
    711 	sc = vsc;
    712 	err = EINVAL;
    713 	switch (cp->dev) {
    714 	case HARMONY_PORT_INPUT_LVL:
    715 		if (cp->type != AUDIO_MIXER_VALUE)
    716 			break;
    717 		if (cp->un.value.num_channels == 1) {
    718 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    719 			    sc->sc_input_lvl.left;
    720 		} else if (cp->un.value.num_channels == 2) {
    721 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    722 			    sc->sc_input_lvl.left;
    723 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    724 			    sc->sc_input_lvl.right;
    725 		} else
    726 			break;
    727 		err = 0;
    728 		break;
    729 	case HARMONY_PORT_INPUT_OV:
    730 		if (cp->type != AUDIO_MIXER_ENUM)
    731 			break;
    732 		cp->un.ord = sc->sc_ov ? 1 : 0;
    733 		err = 0;
    734 		break;
    735 	case HARMONY_PORT_OUTPUT_LVL:
    736 		if (cp->type != AUDIO_MIXER_VALUE)
    737 			break;
    738 		if (cp->un.value.num_channels == 1) {
    739 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    740 			    sc->sc_output_lvl.left;
    741 		} else if (cp->un.value.num_channels == 2) {
    742 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    743 			    sc->sc_output_lvl.left;
    744 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    745 			    sc->sc_output_lvl.right;
    746 		} else
    747 			break;
    748 		err = 0;
    749 		break;
    750 	case HARMONY_PORT_OUTPUT_GAIN:
    751 		if (cp->type != AUDIO_MIXER_ENUM)
    752 			break;
    753 		cp->un.ord = sc->sc_outputgain ? 1 : 0;
    754 		err = 0;
    755 		break;
    756 	case HARMONY_PORT_MONITOR_LVL:
    757 		if (cp->type != AUDIO_MIXER_VALUE)
    758 			break;
    759 		if (cp->un.value.num_channels != 1)
    760 			break;
    761 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    762 		    sc->sc_monitor_lvl.left;
    763 		err = 0;
    764 		break;
    765 	case HARMONY_PORT_RECORD_SOURCE:
    766 		if (cp->type != AUDIO_MIXER_ENUM)
    767 			break;
    768 		cp->un.ord = sc->sc_in_port;
    769 		err = 0;
    770 		break;
    771 	case HARMONY_PORT_OUTPUT_SOURCE:
    772 		if (cp->type != AUDIO_MIXER_ENUM)
    773 			break;
    774 		cp->un.ord = sc->sc_out_port;
    775 		err = 0;
    776 		break;
    777 	}
    778 	return err;
    779 }
    780 
    781 int
    782 harmony_query_devinfo(void *vsc, mixer_devinfo_t *dip)
    783 {
    784 	int err;
    785 
    786 	err = 0;
    787 	switch (dip->index) {
    788 	case HARMONY_PORT_INPUT_LVL:
    789 		dip->type = AUDIO_MIXER_VALUE;
    790 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    791 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    792 		strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name);
    793 		dip->un.v.num_channels = 2;
    794 		strlcpy(dip->un.v.units.name, AudioNvolume,
    795 		    sizeof dip->un.v.units.name);
    796 		break;
    797 	case HARMONY_PORT_INPUT_OV:
    798 		dip->type = AUDIO_MIXER_ENUM;
    799 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    800 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    801 		strlcpy(dip->label.name, "overrange", sizeof dip->label.name);
    802 		dip->un.e.num_mem = 2;
    803 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
    804 		    sizeof dip->un.e.member[0].label.name);
    805 		dip->un.e.member[0].ord = 0;
    806 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
    807 		    sizeof dip->un.e.member[1].label.name);
    808 		dip->un.e.member[1].ord = 1;
    809 		break;
    810 	case HARMONY_PORT_OUTPUT_LVL:
    811 		dip->type = AUDIO_MIXER_VALUE;
    812 		dip->mixer_class = HARMONY_PORT_OUTPUT_CLASS;
    813 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    814 		strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
    815 		dip->un.v.num_channels = 2;
    816 		strlcpy(dip->un.v.units.name, AudioNvolume,
    817 		    sizeof dip->un.v.units.name);
    818 		break;
    819 	case HARMONY_PORT_OUTPUT_GAIN:
    820 		dip->type = AUDIO_MIXER_ENUM;
    821 		dip->mixer_class = HARMONY_PORT_OUTPUT_CLASS;
    822 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    823 		strlcpy(dip->label.name, "gain", sizeof dip->label.name);
    824 		dip->un.e.num_mem = 2;
    825 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
    826 		    sizeof dip->un.e.member[0].label.name);
    827 		dip->un.e.member[0].ord = 0;
    828 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
    829 		    sizeof dip->un.e.member[1].label.name);
    830 		dip->un.e.member[1].ord = 1;
    831 		break;
    832 	case HARMONY_PORT_MONITOR_LVL:
    833 		dip->type = AUDIO_MIXER_VALUE;
    834 		dip->mixer_class = HARMONY_PORT_MONITOR_CLASS;
    835 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    836 		strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
    837 		dip->un.v.num_channels = 1;
    838 		strlcpy(dip->un.v.units.name, AudioNvolume,
    839 		    sizeof dip->un.v.units.name);
    840 		break;
    841 	case HARMONY_PORT_RECORD_SOURCE:
    842 		dip->type = AUDIO_MIXER_ENUM;
    843 		dip->mixer_class = HARMONY_PORT_RECORD_CLASS;
    844 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    845 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
    846 		dip->un.e.num_mem = 2;
    847 		strlcpy(dip->un.e.member[0].label.name, AudioNmicrophone,
    848 		    sizeof dip->un.e.member[0].label.name);
    849 		dip->un.e.member[0].ord = HARMONY_IN_MIC;
    850 		strlcpy(dip->un.e.member[1].label.name, AudioNline,
    851 		    sizeof dip->un.e.member[1].label.name);
    852 		dip->un.e.member[1].ord = HARMONY_IN_LINE;
    853 		break;
    854 	case HARMONY_PORT_OUTPUT_SOURCE:
    855 		dip->type = AUDIO_MIXER_ENUM;
    856 		dip->mixer_class = HARMONY_PORT_MONITOR_CLASS;
    857 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    858 		strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
    859 		dip->un.e.num_mem = 3;
    860 		strlcpy(dip->un.e.member[0].label.name, AudioNline,
    861 		    sizeof dip->un.e.member[0].label.name);
    862 		dip->un.e.member[0].ord = HARMONY_OUT_LINE;
    863 		strlcpy(dip->un.e.member[1].label.name, AudioNspeaker,
    864 		    sizeof dip->un.e.member[1].label.name);
    865 		dip->un.e.member[1].ord = HARMONY_OUT_SPEAKER;
    866 		strlcpy(dip->un.e.member[2].label.name, AudioNheadphone,
    867 		    sizeof dip->un.e.member[2].label.name);
    868 		dip->un.e.member[2].ord = HARMONY_OUT_HEADPHONE;
    869 		break;
    870 	case HARMONY_PORT_INPUT_CLASS:
    871 		dip->type = AUDIO_MIXER_CLASS;
    872 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    873 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    874 		strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
    875 		break;
    876 	case HARMONY_PORT_OUTPUT_CLASS:
    877 		dip->type = AUDIO_MIXER_CLASS;
    878 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    879 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    880 		strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
    881 		break;
    882 	case HARMONY_PORT_MONITOR_CLASS:
    883 		dip->type = AUDIO_MIXER_CLASS;
    884 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    885 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    886 		strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
    887 		break;
    888 	case HARMONY_PORT_RECORD_CLASS:
    889 		dip->type = AUDIO_MIXER_CLASS;
    890 		dip->mixer_class = HARMONY_PORT_RECORD_CLASS;
    891 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    892 		strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
    893 		break;
    894 	default:
    895 		err = ENXIO;
    896 		break;
    897 	}
    898 
    899 	return err;
    900 }
    901 
    902 void *
    903 harmony_allocm(void *vsc, int dir, size_t size)
    904 {
    905 	struct harmony_softc *sc;
    906 	struct harmony_dma *d;
    907 	int rseg;
    908 
    909 	sc = vsc;
    910 	d = kmem_alloc(sizeof(*d), KM_SLEEP);
    911 
    912 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, BUS_DMA_WAITOK,
    913 	    &d->d_map) != 0)
    914 		goto fail1;
    915 
    916 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &d->d_seg, 1,
    917 	    &rseg, BUS_DMA_WAITOK) != 0)
    918 		goto fail2;
    919 
    920 	if (bus_dmamem_map(sc->sc_dmat, &d->d_seg, 1, size, &d->d_kva,
    921 	    BUS_DMA_WAITOK) != 0)
    922 		goto fail3;
    923 
    924 	if (bus_dmamap_load(sc->sc_dmat, d->d_map, d->d_kva, size, NULL,
    925 	    BUS_DMA_WAITOK) != 0)
    926 		goto fail4;
    927 
    928 	d->d_next = sc->sc_dmas;
    929 	sc->sc_dmas = d;
    930 	d->d_size = size;
    931 	return (d->d_kva);
    932 
    933 fail4:
    934 	bus_dmamem_unmap(sc->sc_dmat, d->d_kva, size);
    935 fail3:
    936 	bus_dmamem_free(sc->sc_dmat, &d->d_seg, 1);
    937 fail2:
    938 	bus_dmamap_destroy(sc->sc_dmat, d->d_map);
    939 fail1:
    940 	kmem_free(d, sizeof(*d));
    941 	return (NULL);
    942 }
    943 
    944 void
    945 harmony_freem(void *vsc, void *ptr, size_t size)
    946 {
    947 	struct harmony_softc *sc;
    948 	struct harmony_dma *d, **dd;
    949 
    950 	sc = vsc;
    951 	for (dd = &sc->sc_dmas; (d = *dd) != NULL; dd = &(*dd)->d_next) {
    952 		if (d->d_kva != ptr)
    953 			continue;
    954 		bus_dmamap_unload(sc->sc_dmat, d->d_map);
    955 		bus_dmamem_unmap(sc->sc_dmat, d->d_kva, d->d_size);
    956 		bus_dmamem_free(sc->sc_dmat, &d->d_seg, 1);
    957 		bus_dmamap_destroy(sc->sc_dmat, d->d_map);
    958 		kmem_free(d, sizeof(*d));
    959 		return;
    960 	}
    961 	printf("%s: free rogue pointer\n", device_xname(sc->sc_dv));
    962 }
    963 
    964 size_t
    965 harmony_round_buffersize(void *vsc, int direction, size_t size)
    966 {
    967 
    968 	return ((size + HARMONY_BUFSIZE - 1) & (size_t)(-HARMONY_BUFSIZE));
    969 }
    970 
    971 int
    972 harmony_get_props(void *vsc)
    973 {
    974 
    975 	return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE |
    976 	    AUDIO_PROP_FULLDUPLEX;
    977 }
    978 
    979 void
    980 harmony_get_locks(void *vsc, kmutex_t **intr, kmutex_t **thread)
    981 {
    982 	struct harmony_softc *sc;
    983 
    984 	sc = vsc;
    985 	*intr = &sc->sc_intr_lock;
    986 	*thread = &sc->sc_lock;
    987 }
    988 
    989 int
    990 harmony_trigger_output(void *vsc, void *start, void *end, int blksize,
    991     void (*intr)(void *), void *intrarg, const audio_params_t *param)
    992 {
    993 	struct harmony_softc *sc;
    994 	struct harmony_channel *c;
    995 	struct harmony_dma *d;
    996 
    997 	sc = vsc;
    998 	c = &sc->sc_playback;
    999 	for (d = sc->sc_dmas; d->d_kva != start; d = d->d_next)
   1000 		continue;
   1001 	if (d == NULL) {
   1002 		printf("%s: trigger_output: bad addr: %p\n",
   1003 		    device_xname(sc->sc_dv), start);
   1004 		return EINVAL;
   1005 	}
   1006 
   1007 	c->c_intr = intr;
   1008 	c->c_intrarg = intrarg;
   1009 	c->c_blksz = blksize;
   1010 	c->c_current = d;
   1011 	c->c_segsz = (char *)end - (char *)start;
   1012 	c->c_cnt = 0;
   1013 	c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
   1014 
   1015 	sc->sc_playing = 1;
   1016 
   1017 	harmony_start_pp(sc, 1);
   1018 	harmony_start_cp(sc, 0);
   1019 	harmony_intr_enable(sc);
   1020 
   1021 	return 0;
   1022 }
   1023 
   1024 void
   1025 harmony_start_cp(struct harmony_softc *sc, int start)
   1026 {
   1027 	struct harmony_channel *c;
   1028 	struct harmony_dma *d;
   1029 	bus_addr_t nextaddr;
   1030 	bus_size_t togo;
   1031 
   1032 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1033 
   1034 	c = &sc->sc_capture;
   1035 	if (sc->sc_capturing == 0)
   1036 		harmony_empty_input(sc);
   1037 	else {
   1038 		d = c->c_current;
   1039 		togo = c->c_segsz - c->c_cnt;
   1040 		if (togo == 0) {
   1041 			nextaddr = d->d_map->dm_segs[0].ds_addr;
   1042 			c->c_cnt = togo = c->c_blksz;
   1043 		} else {
   1044 			nextaddr = c->c_lastaddr;
   1045 			if (togo > c->c_blksz)
   1046 				togo = c->c_blksz;
   1047 			c->c_cnt += togo;
   1048 		}
   1049 
   1050 		bus_dmamap_sync(sc->sc_dmat, d->d_map,
   1051 		    nextaddr - d->d_map->dm_segs[0].ds_addr,
   1052 		    c->c_blksz, BUS_DMASYNC_PREWRITE);
   1053 
   1054 		WRITE_REG(sc, HARMONY_RNXTADD, nextaddr);
   1055 		if (start)
   1056 			c->c_theaddr = nextaddr;
   1057 		SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
   1058 		c->c_lastaddr = nextaddr + togo;
   1059 
   1060 		harmony_try_more(sc, HARMONY_RCURADD,
   1061 		    RCURADD_BUFMASK, &sc->sc_capture);
   1062 	}
   1063 
   1064 	callout_schedule(&sc->sc_acc_tmo, 1);
   1065 }
   1066 
   1067 void
   1068 harmony_start_pp(struct harmony_softc *sc, int start)
   1069 {
   1070 	struct harmony_channel *c;
   1071 	struct harmony_dma *d;
   1072 	bus_addr_t nextaddr;
   1073 	bus_size_t togo;
   1074 
   1075 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1076 
   1077 	c = &sc->sc_playback;
   1078 	if (sc->sc_playing == 0)
   1079 		harmony_empty_output(sc);
   1080 	else {
   1081 		d = c->c_current;
   1082 		togo = c->c_segsz - c->c_cnt;
   1083 		if (togo == 0) {
   1084 			nextaddr = d->d_map->dm_segs[0].ds_addr;
   1085 			c->c_cnt = togo = c->c_blksz;
   1086 		} else {
   1087 			nextaddr = c->c_lastaddr;
   1088 			if (togo > c->c_blksz)
   1089 				togo = c->c_blksz;
   1090 			c->c_cnt += togo;
   1091 		}
   1092 
   1093 		bus_dmamap_sync(sc->sc_dmat, d->d_map,
   1094 		    nextaddr - d->d_map->dm_segs[0].ds_addr,
   1095 		    c->c_blksz, BUS_DMASYNC_PREWRITE);
   1096 
   1097 		WRITE_REG(sc, HARMONY_PNXTADD, nextaddr);
   1098 		if (start)
   1099 			c->c_theaddr = nextaddr;
   1100 		SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
   1101 		c->c_lastaddr = nextaddr + togo;
   1102 
   1103 		harmony_try_more(sc, HARMONY_PCURADD,
   1104 		    PCURADD_BUFMASK, &sc->sc_playback);
   1105 	}
   1106 }
   1107 
   1108 int
   1109 harmony_trigger_input(void *vsc, void *start, void *end, int blksize,
   1110     void (*intr)(void *), void *intrarg, const audio_params_t *param)
   1111 {
   1112 	struct harmony_softc *sc = vsc;
   1113 	struct harmony_channel *c = &sc->sc_capture;
   1114 	struct harmony_dma *d;
   1115 
   1116 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1117 
   1118 	for (d = sc->sc_dmas; d->d_kva != start; d = d->d_next)
   1119 		continue;
   1120 	if (d == NULL) {
   1121 		printf("%s: trigger_input: bad addr: %p\n",
   1122 		    device_xname(sc->sc_dv), start);
   1123 		return EINVAL;
   1124 	}
   1125 
   1126 	c->c_intr = intr;
   1127 	c->c_intrarg = intrarg;
   1128 	c->c_blksz = blksize;
   1129 	c->c_current = d;
   1130 	c->c_segsz = (char *)end - (char *)start;
   1131 	c->c_cnt = 0;
   1132 	c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
   1133 
   1134 	sc->sc_capturing = 1;
   1135 
   1136 	harmony_start_cp(sc, 1);
   1137 	harmony_intr_enable(sc);
   1138 
   1139 	return 0;
   1140 }
   1141 
   1142 static const struct speed_struct {
   1143 	uint32_t speed;
   1144 	uint32_t bits;
   1145 } harmony_speeds[] = {
   1146 	{ 5125, CNTL_RATE_5125 },
   1147 	{ 6615, CNTL_RATE_6615 },
   1148 	{ 8000, CNTL_RATE_8000 },
   1149 	{ 9600, CNTL_RATE_9600 },
   1150 	{ 11025, CNTL_RATE_11025 },
   1151 	{ 16000, CNTL_RATE_16000 },
   1152 	{ 18900, CNTL_RATE_18900 },
   1153 	{ 22050, CNTL_RATE_22050 },
   1154 	{ 27428, CNTL_RATE_27428 },
   1155 	{ 32000, CNTL_RATE_32000 },
   1156 	{ 33075, CNTL_RATE_33075 },
   1157 	{ 37800, CNTL_RATE_37800 },
   1158 	{ 44100, CNTL_RATE_44100 },
   1159 	{ 48000, CNTL_RATE_48000 },
   1160 };
   1161 
   1162 uint32_t
   1163 harmony_speed_bits(struct harmony_softc *sc, u_int speed)
   1164 {
   1165 	int i;
   1166 
   1167 	for (i = 0; i < __arraycount(harmony_speeds); i++) {
   1168 		if (speed == harmony_speeds[i].speed) {
   1169 			return harmony_speeds[i].bits;
   1170 		}
   1171 	}
   1172 	/* If this happens, harmony_formats[] is wrong */
   1173 	panic("speed %u not supported", speed);
   1174 }
   1175 
   1176 int
   1177 harmony_set_gainctl(struct harmony_softc *sc)
   1178 {
   1179 	uint32_t bits, mask, val, old;
   1180 
   1181 	/* XXX leave these bits alone or the chip will not come out of CNTL */
   1182 	bits = GAINCTL_LE | GAINCTL_HE | GAINCTL_SE | GAINCTL_IS_MASK;
   1183 
   1184 	/* input level */
   1185 	bits |= ((sc->sc_input_lvl.left >> (8 - GAINCTL_INPUT_BITS)) <<
   1186 	    GAINCTL_INPUT_LEFT_S) & GAINCTL_INPUT_LEFT_M;
   1187 	bits |= ((sc->sc_input_lvl.right >> (8 - GAINCTL_INPUT_BITS)) <<
   1188 	    GAINCTL_INPUT_RIGHT_S) & GAINCTL_INPUT_RIGHT_M;
   1189 
   1190 	/* output level (inverted) */
   1191 	mask = (1 << GAINCTL_OUTPUT_BITS) - 1;
   1192 	val = mask - (sc->sc_output_lvl.left >> (8 - GAINCTL_OUTPUT_BITS));
   1193 	bits |= (val << GAINCTL_OUTPUT_LEFT_S) & GAINCTL_OUTPUT_LEFT_M;
   1194 	val = mask - (sc->sc_output_lvl.right >> (8 - GAINCTL_OUTPUT_BITS));
   1195 	bits |= (val << GAINCTL_OUTPUT_RIGHT_S) & GAINCTL_OUTPUT_RIGHT_M;
   1196 
   1197 	/* monitor level (inverted) */
   1198 	mask = (1 << GAINCTL_MONITOR_BITS) - 1;
   1199 	val = mask - (sc->sc_monitor_lvl.left >> (8 - GAINCTL_MONITOR_BITS));
   1200 	bits |= (val << GAINCTL_MONITOR_S) & GAINCTL_MONITOR_M;
   1201 
   1202 	/* XXX messing with these causes CNTL_C to get stuck... grr. */
   1203 	bits &= ~GAINCTL_IS_MASK;
   1204 	if (sc->sc_in_port == HARMONY_IN_MIC)
   1205 		bits |= GAINCTL_IS_LINE;
   1206 	else
   1207 		bits |= GAINCTL_IS_MICROPHONE;
   1208 
   1209 	/* XXX messing with these causes CNTL_C to get stuck... grr. */
   1210 	bits &= ~(GAINCTL_LE | GAINCTL_HE | GAINCTL_SE);
   1211 	if (sc->sc_out_port == HARMONY_OUT_LINE)
   1212 		bits |= GAINCTL_LE;
   1213 	else if (sc->sc_out_port == HARMONY_OUT_SPEAKER)
   1214 		bits |= GAINCTL_SE;
   1215 	else
   1216 		bits |= GAINCTL_HE;
   1217 
   1218 	mask = GAINCTL_LE | GAINCTL_HE | GAINCTL_SE | GAINCTL_IS_MASK;
   1219 	old = bus_space_read_4(sc->sc_bt, sc->sc_bh, HARMONY_GAINCTL);
   1220 	bus_space_write_4(sc->sc_bt, sc->sc_bh, HARMONY_GAINCTL, bits);
   1221 	if ((old & mask) != (bits & mask))
   1222 		return 1;
   1223 	return 0;
   1224 }
   1225 
   1226 void
   1227 harmony_try_more(struct harmony_softc *sc, int curadd, int bufmask,
   1228 	struct harmony_channel *c)
   1229 {
   1230 	struct harmony_dma *d;
   1231 	uint32_t cur;
   1232 	int i, nsegs;
   1233 
   1234 	d = c->c_current;
   1235 	cur = bus_space_read_4(sc->sc_bt, sc->sc_bh, curadd);
   1236 	cur &= bufmask;
   1237 	nsegs = 0;
   1238 
   1239 #ifdef DIAGNOSTIC
   1240 	if (cur < d->d_map->dm_segs[0].ds_addr ||
   1241 	    cur >= (d->d_map->dm_segs[0].ds_addr + c->c_segsz))
   1242 		panic("%s: bad current %x < %lx || %x > %lx",
   1243 		    device_xname(sc->sc_dv), cur,
   1244 		    d->d_map->dm_segs[0].ds_addr, cur,
   1245 		    d->d_map->dm_segs[0].ds_addr + c->c_segsz);
   1246 #endif /* DIAGNOSTIC */
   1247 
   1248 	if (cur > c->c_theaddr) {
   1249 		nsegs = (cur - c->c_theaddr) / HARMONY_BUFSIZE;
   1250 	} else if (cur < c->c_theaddr) {
   1251 		nsegs = (d->d_map->dm_segs[0].ds_addr + c->c_segsz -
   1252 		    c->c_theaddr) / HARMONY_BUFSIZE;
   1253 		nsegs += (cur - d->d_map->dm_segs[0].ds_addr) /
   1254 		    HARMONY_BUFSIZE;
   1255 	}
   1256 
   1257 	if (nsegs != 0 && c->c_intr != NULL) {
   1258 		for (i = 0; i < nsegs; i++)
   1259 			(*c->c_intr)(c->c_intrarg);
   1260 		c->c_theaddr = cur;
   1261 	}
   1262 }
   1263