Home | History | Annotate | Line # | Download | only in gsc
harmony.c revision 1.2
      1 /*	$NetBSD: harmony.c,v 1.2 2014/08/10 16:44:34 tls 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/rnd.h>
     77 
     78 #include <sys/audioio.h>
     79 #include <dev/audio_if.h>
     80 #include <dev/auconv.h>
     81 
     82 #include <machine/cpu.h>
     83 #include <machine/intr.h>
     84 #include <machine/iomod.h>
     85 #include <machine/autoconf.h>
     86 #include <sys/bus.h>
     87 
     88 #include <hppa/dev/cpudevs.h>
     89 #include <hppa/gsc/gscbusvar.h>
     90 #include <hppa/gsc/harmonyreg.h>
     91 #include <hppa/gsc/harmonyvar.h>
     92 
     93 int	harmony_open(void *, int);
     94 void	harmony_close(void *);
     95 int	harmony_query_encoding(void *, struct audio_encoding *);
     96 int	harmony_set_params(void *, int, int, audio_params_t *,
     97     audio_params_t *, stream_filter_list_t *, stream_filter_list_t *);
     98 int	harmony_round_blocksize(void *, int, int, const audio_params_t *);
     99 
    100 int	harmony_control_wait(struct harmony_softc *);
    101 int	harmony_commit_settings(void *);
    102 
    103 int	harmony_halt_output(void *);
    104 int	harmony_halt_input(void *);
    105 int	harmony_getdev(void *, struct audio_device *);
    106 int	harmony_set_port(void *, mixer_ctrl_t *);
    107 int	harmony_get_port(void *, mixer_ctrl_t *);
    108 int	harmony_query_devinfo(void *, mixer_devinfo_t *);
    109 void *	harmony_allocm(void *, int, size_t);
    110 void	harmony_freem(void *, void *, size_t);
    111 size_t	harmony_round_buffersize(void *, int, size_t);
    112 int	harmony_get_props(void *);
    113 int	harmony_trigger_output(void *, void *, void *, int,
    114     void (*)(void *), void *, const audio_params_t *);
    115 int	harmony_trigger_input(void *, void *, void *, int,
    116     void (*)(void *), void *, const audio_params_t *);
    117 void	harmony_get_locks(void *, kmutex_t **, kmutex_t **);
    118 
    119 const struct audio_hw_if harmony_sa_hw_if = {
    120 	harmony_open,
    121 	harmony_close,
    122 	NULL,
    123 	harmony_query_encoding,
    124 	harmony_set_params,
    125 	harmony_round_blocksize,
    126 	harmony_commit_settings,
    127 	NULL,
    128 	NULL,
    129 	NULL,
    130 	NULL,
    131 	harmony_halt_output,
    132 	harmony_halt_input,
    133 	NULL,
    134 	harmony_getdev,
    135 	NULL,
    136 	harmony_set_port,
    137 	harmony_get_port,
    138 	harmony_query_devinfo,
    139 	harmony_allocm,
    140 	harmony_freem,
    141 	harmony_round_buffersize,
    142 	NULL,
    143 	harmony_get_props,
    144 	harmony_trigger_output,
    145 	harmony_trigger_input,
    146 	NULL,
    147 	harmony_get_locks,
    148 };
    149 
    150 int harmony_match(device_t, struct cfdata *, void *);
    151 void harmony_attach(device_t, device_t, void *);
    152 
    153 
    154 CFATTACH_DECL_NEW(harmony, sizeof(struct harmony_softc),
    155     harmony_match, harmony_attach, NULL, NULL);
    156 
    157 int harmony_intr(void *);
    158 void harmony_intr_enable(struct harmony_softc *);
    159 void harmony_intr_disable(struct harmony_softc *);
    160 uint32_t harmony_speed_bits(struct harmony_softc *, u_int *);
    161 int harmony_set_gainctl(struct harmony_softc *);
    162 void harmony_reset_codec(struct harmony_softc *);
    163 void harmony_start_cp(struct harmony_softc *, int);
    164 void harmony_start_pp(struct harmony_softc *, int);
    165 void harmony_tick_pb(void *);
    166 void harmony_tick_cp(void *);
    167 void harmony_try_more(struct harmony_softc *, int, int,
    168 	struct harmony_channel *);
    169 static void harmony_empty_input(struct harmony_softc *);
    170 static void harmony_empty_output(struct harmony_softc *);
    171 
    172 void harmony_acc_tmo(void *);
    173 #define	ADD_CLKALLICA(sc) do {						\
    174 	(sc)->sc_acc <<= 1;						\
    175 	(sc)->sc_acc |= READ_REG((sc), HARMONY_DIAG) & DIAG_CO;		\
    176 	if ((sc)->sc_acc_cnt++ && !((sc)->sc_acc_cnt % 32))		\
    177 		rnd_add_uint32(&(sc)->sc_rnd_source,			\
    178 			       (sc)->sc_acc_num ^= (sc)->sc_acc);	\
    179 } while(0)
    180 
    181 int
    182 harmony_match(device_t parent, struct cfdata *match, void *aux)
    183 {
    184 	struct gsc_attach_args *ga;
    185 
    186 	ga = aux;
    187 	if (ga->ga_type.iodc_type == HPPA_TYPE_FIO) {
    188 		if (ga->ga_type.iodc_sv_model == HPPA_FIO_A1 ||
    189 		    ga->ga_type.iodc_sv_model == HPPA_FIO_A2NB ||
    190 		    ga->ga_type.iodc_sv_model == HPPA_FIO_A1NB ||
    191 		    ga->ga_type.iodc_sv_model == HPPA_FIO_A2)
    192 			return 1;
    193 	}
    194 	return 0;
    195 }
    196 
    197 void
    198 harmony_attach(device_t parent, device_t self, void *aux)
    199 {
    200 	struct harmony_softc *sc = device_private(self);
    201 	struct gsc_attach_args *ga;
    202 	uint8_t rev;
    203 	uint32_t cntl;
    204 	int i;
    205 
    206 	sc->sc_dv = self;
    207 	ga = aux;
    208 	sc->sc_bt = ga->ga_iot;
    209 	sc->sc_dmat = ga->ga_dmatag;
    210 
    211 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    212 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
    213 
    214 	if (bus_space_map(sc->sc_bt, ga->ga_hpa, HARMONY_NREGS, 0,
    215 	    &sc->sc_bh) != 0) {
    216 		aprint_error(": couldn't map registers\n");
    217 		return;
    218 	}
    219 
    220 	cntl = READ_REG(sc, HARMONY_ID);
    221 	switch ((cntl & ID_REV_MASK)) {
    222 	case ID_REV_TS:
    223 		sc->sc_teleshare = 1;
    224 	case ID_REV_NOTS:
    225 		break;
    226 	default:
    227 		aprint_error(": unknown id == 0x%02x\n",
    228 		    (cntl & ID_REV_MASK) >> ID_REV_SHIFT);
    229 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    230 		return;
    231 	}
    232 
    233 	if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct harmony_empty),
    234 	    PAGE_SIZE, 0, &sc->sc_empty_seg, 1, &sc->sc_empty_rseg,
    235 	    BUS_DMA_WAITOK) != 0) {
    236 		aprint_error(": could not alloc DMA memory\n");
    237 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    238 		return;
    239 	}
    240 	if (bus_dmamem_map(sc->sc_dmat, &sc->sc_empty_seg, 1,
    241 	    sizeof(struct harmony_empty), (void **)&sc->sc_empty_kva,
    242 	    BUS_DMA_WAITOK) != 0) {
    243 		aprint_error(": couldn't map DMA memory\n");
    244 		bus_dmamem_free(sc->sc_dmat, &sc->sc_empty_seg,
    245 		    sc->sc_empty_rseg);
    246 		bus_space_unmap(sc->sc_bt, sc->sc_bh, HARMONY_NREGS);
    247 		return;
    248 	}
    249 	if (bus_dmamap_create(sc->sc_dmat, sizeof(struct harmony_empty), 1,
    250 	    sizeof(struct harmony_empty), 0, BUS_DMA_WAITOK,
    251 	    &sc->sc_empty_map) != 0) {
    252 		aprint_error(": can't create DMA map\n");
    253 		bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_empty_kva,
    254 		    sizeof(struct harmony_empty));
    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_load(sc->sc_dmat, sc->sc_empty_map, sc->sc_empty_kva,
    261 	    sizeof(struct harmony_empty), NULL, BUS_DMA_WAITOK) != 0) {
    262 		aprint_error(": can't load DMA map\n");
    263 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_empty_map);
    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 
    272 	sc->sc_playback_empty = 0;
    273 	for (i = 0; i < PLAYBACK_EMPTYS; i++)
    274 		sc->sc_playback_paddrs[i] =
    275 		    sc->sc_empty_map->dm_segs[0].ds_addr +
    276 		    offsetof(struct harmony_empty, playback[i][0]);
    277 
    278 	sc->sc_capture_empty = 0;
    279 	for (i = 0; i < CAPTURE_EMPTYS; i++)
    280 		sc->sc_capture_paddrs[i] =
    281 		    sc->sc_empty_map->dm_segs[0].ds_addr +
    282 		    offsetof(struct harmony_empty, capture[i][0]);
    283 
    284 	bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
    285 	    offsetof(struct harmony_empty, playback[0][0]),
    286 	    PLAYBACK_EMPTYS * HARMONY_BUFSIZE, BUS_DMASYNC_PREWRITE);
    287 
    288 	(void) hppa_intr_establish(IPL_AUDIO, harmony_intr, sc, ga->ga_ir,
    289 	     ga->ga_irq);
    290 
    291 	/* set defaults */
    292 	sc->sc_in_port = HARMONY_IN_LINE;
    293 	sc->sc_out_port = HARMONY_OUT_SPEAKER;
    294 	sc->sc_input_lvl.left = sc->sc_input_lvl.right = 240;
    295 	sc->sc_output_lvl.left = sc->sc_output_lvl.right = 244;
    296 	sc->sc_monitor_lvl.left = sc->sc_monitor_lvl.right = 208;
    297 	sc->sc_outputgain = 0;
    298 
    299 	/* reset chip, and push default gain controls */
    300 	harmony_reset_codec(sc);
    301 
    302 	cntl = READ_REG(sc, HARMONY_CNTL);
    303 	rev = (cntl & CNTL_CODEC_REV_MASK) >> CNTL_CODEC_REV_SHIFT;
    304 	aprint_normal(": rev %u", rev);
    305 
    306 	if (sc->sc_teleshare)
    307 		printf(", teleshare");
    308 	aprint_normal("\n");
    309 
    310 	if ((rev & CS4215_REV_VER) >= CS4215_REV_VER_E)
    311 		sc->sc_hasulinear8 = 1;
    312 
    313 	strlcpy(sc->sc_audev.name, ga->ga_name, sizeof(sc->sc_audev.name));
    314 	snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version,
    315 	    "%u.%u;%u", ga->ga_type.iodc_sv_rev,
    316 	    ga->ga_type.iodc_model, ga->ga_type.iodc_revision);
    317 	strlcpy(sc->sc_audev.config, device_xname(sc->sc_dv),
    318 	    sizeof(sc->sc_audev.config));
    319 
    320 	audio_attach_mi(&harmony_sa_hw_if, sc, sc->sc_dv);
    321 
    322 	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dv),
    323 	    RND_TYPE_UNKNOWN, RND_FLAG_DEFAULT);
    324 
    325 	callout_init(&sc->sc_acc_tmo, 0);
    326 	callout_setfunc(&sc->sc_acc_tmo, harmony_acc_tmo, sc);
    327 	sc->sc_acc_num = 0xa5a5a5a5;
    328 }
    329 
    330 void
    331 harmony_reset_codec(struct harmony_softc *sc)
    332 {
    333 
    334 	/* silence */
    335 	WRITE_REG(sc, HARMONY_GAINCTL, GAINCTL_OUTPUT_LEFT_M |
    336 	    GAINCTL_OUTPUT_RIGHT_M | GAINCTL_MONITOR_M);
    337 
    338 	/* start reset */
    339 	WRITE_REG(sc, HARMONY_RESET, RESET_RST);
    340 
    341 	DELAY(100000);		/* wait at least 0.05 sec */
    342 
    343 	harmony_set_gainctl(sc);
    344 	WRITE_REG(sc, HARMONY_RESET, 0);
    345 }
    346 
    347 void
    348 harmony_acc_tmo(void *v)
    349 {
    350 	struct harmony_softc *sc;
    351 
    352 	sc = v;
    353 	ADD_CLKALLICA(sc);
    354 	callout_schedule(&sc->sc_acc_tmo, 1);
    355 }
    356 
    357 /*
    358  * interrupt handler
    359  */
    360 int
    361 harmony_intr(void *vsc)
    362 {
    363 	struct harmony_softc *sc;
    364 	uint32_t dstatus;
    365 	int r;
    366 
    367 	sc = vsc;
    368 	r = 0;
    369 	ADD_CLKALLICA(sc);
    370 
    371 	mutex_spin_enter(&sc->sc_intr_lock);
    372 
    373 	harmony_intr_disable(sc);
    374 
    375 	dstatus = READ_REG(sc, HARMONY_DSTATUS);
    376 
    377 	if (dstatus & DSTATUS_PN) {
    378 		r = 1;
    379 		harmony_start_pp(sc, 0);
    380 	}
    381 
    382 	if (dstatus & DSTATUS_RN) {
    383 		r = 1;
    384 		harmony_start_cp(sc, 0);
    385 	}
    386 
    387 	if (READ_REG(sc, HARMONY_OV) & OV_OV) {
    388 		sc->sc_ov = 1;
    389 		WRITE_REG(sc, HARMONY_OV, 0);
    390 	} else
    391 		sc->sc_ov = 0;
    392 
    393 	harmony_intr_enable(sc);
    394 
    395 	mutex_spin_exit(&sc->sc_intr_lock);
    396 
    397 	return r;
    398 }
    399 
    400 void
    401 harmony_intr_enable(struct harmony_softc *sc)
    402 {
    403 
    404 	WRITE_REG(sc, HARMONY_DSTATUS, DSTATUS_IE);
    405 	SYNC_REG(sc, HARMONY_DSTATUS, BUS_SPACE_BARRIER_WRITE);
    406 }
    407 
    408 void
    409 harmony_intr_disable(struct harmony_softc *sc)
    410 {
    411 
    412 	WRITE_REG(sc, HARMONY_DSTATUS, 0);
    413 	SYNC_REG(sc, HARMONY_DSTATUS, BUS_SPACE_BARRIER_WRITE);
    414 }
    415 
    416 int
    417 harmony_open(void *vsc, int flags)
    418 {
    419 	struct harmony_softc *sc;
    420 
    421 	sc = vsc;
    422 	if (sc->sc_open)
    423 		return EBUSY;
    424 	sc->sc_open = 1;
    425 	return 0;
    426 }
    427 
    428 void
    429 harmony_close(void *vsc)
    430 {
    431 	struct harmony_softc *sc;
    432 
    433 	sc = vsc;
    434 	harmony_halt_input(sc);
    435 	harmony_halt_output(sc);
    436 	harmony_intr_disable(sc);
    437 	sc->sc_open = 0;
    438 }
    439 
    440 int
    441 harmony_query_encoding(void *vsc, struct audio_encoding *fp)
    442 {
    443 	struct harmony_softc *sc;
    444 	int err;
    445 
    446 	sc = vsc;
    447 	err = 0;
    448 	switch (fp->index) {
    449 	case 0:
    450 		strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
    451 		fp->encoding = AUDIO_ENCODING_ULAW;
    452 		fp->precision = 8;
    453 		fp->flags = 0;
    454 		break;
    455 	case 1:
    456 		strlcpy(fp->name, AudioEalaw, sizeof fp->name);
    457 		fp->encoding = AUDIO_ENCODING_ALAW;
    458 		fp->precision = 8;
    459 		fp->flags = 0;
    460 		break;
    461 	case 2:
    462 		strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
    463 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
    464 		fp->precision = 16;
    465 		fp->flags = 0;
    466 		break;
    467 	case 3:
    468 		strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
    469 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
    470 		fp->precision = 16;
    471 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    472 		break;
    473 	case 4:
    474 		strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
    475 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
    476 		fp->precision = 16;
    477 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    478 		break;
    479 	case 5:
    480 		strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
    481 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
    482 		fp->precision = 16;
    483 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    484 		break;
    485 	case 6:
    486 		if (sc->sc_hasulinear8) {
    487 			strlcpy(fp->name, AudioEulinear, sizeof fp->name);
    488 			fp->encoding = AUDIO_ENCODING_ULINEAR;
    489 			fp->precision = 8;
    490 			fp->flags = 0;
    491 			break;
    492 		}
    493 		/*FALLTHROUGH*/
    494 	case 7:
    495 		if (sc->sc_hasulinear8) {
    496 			strlcpy(fp->name, AudioEslinear, sizeof fp->name);
    497 			fp->encoding = AUDIO_ENCODING_SLINEAR;
    498 			fp->precision = 8;
    499 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
    500 			break;
    501 		}
    502 		/*FALLTHROUGH*/
    503 	default:
    504 		err = EINVAL;
    505 	}
    506 	return err;
    507 }
    508 
    509 int
    510 harmony_set_params(void *vsc, int setmode, int usemode,
    511     audio_params_t *p, audio_params_t *r,
    512     stream_filter_list_t *pfil, stream_filter_list_t *rfil)
    513 {
    514 	audio_params_t hw;
    515 	struct harmony_softc *sc;
    516 	uint32_t bits;
    517 	stream_filter_factory_t *pswcode = NULL;
    518 	stream_filter_factory_t *rswcode = NULL;
    519 
    520 	sc = vsc;
    521 	/* assume p.equals(r) */
    522 	hw = *p;
    523 	switch (p->encoding) {
    524 	case AUDIO_ENCODING_ULAW:
    525 		if (p->precision != 8)
    526 			return EINVAL;
    527 		bits = CNTL_FORMAT_ULAW;
    528 		break;
    529 	case AUDIO_ENCODING_ALAW:
    530 		if (p->precision != 8)
    531 			return EINVAL;
    532 		bits = CNTL_FORMAT_ALAW;
    533 		break;
    534 	case AUDIO_ENCODING_SLINEAR_BE:
    535 		if (p->precision == 8) {
    536 			bits = CNTL_FORMAT_ULINEAR8;
    537 			hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
    538 			rswcode = pswcode = change_sign8;
    539 			break;
    540 		}
    541 		if (p->precision == 16) {
    542 			bits = CNTL_FORMAT_SLINEAR16BE;
    543 			break;
    544 		}
    545 		return EINVAL;
    546 	case AUDIO_ENCODING_ULINEAR:
    547 		if (p->precision != 8)
    548 			return EINVAL;
    549 		bits = CNTL_FORMAT_ULINEAR8;
    550 		break;
    551 	case AUDIO_ENCODING_SLINEAR:
    552 		if (p->precision != 8)
    553 			return EINVAL;
    554 		bits = CNTL_FORMAT_ULINEAR8;
    555 		hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
    556 		rswcode = pswcode = change_sign8;
    557 		break;
    558 	case AUDIO_ENCODING_SLINEAR_LE:
    559 		if (p->precision == 8) {
    560 			bits = CNTL_FORMAT_ULINEAR8;
    561 			hw.encoding = AUDIO_ENCODING_ULINEAR_LE;
    562 			rswcode = pswcode = change_sign8;
    563 			break;
    564 		}
    565 		if (p->precision == 16) {
    566 			bits = CNTL_FORMAT_SLINEAR16BE;
    567 			hw.encoding = AUDIO_ENCODING_SLINEAR_BE;
    568 			rswcode = pswcode = swap_bytes;
    569 			break;
    570 		}
    571 		return EINVAL;
    572 	case AUDIO_ENCODING_ULINEAR_BE:
    573 		if (p->precision == 8) {
    574 			bits = CNTL_FORMAT_ULINEAR8;
    575 			break;
    576 		}
    577 		if (p->precision == 16) {
    578 			bits = CNTL_FORMAT_SLINEAR16BE;
    579 			rswcode = pswcode = change_sign16;
    580 			break;
    581 		}
    582 		return EINVAL;
    583 	case AUDIO_ENCODING_ULINEAR_LE:
    584 		if (p->precision == 8) {
    585 			bits = CNTL_FORMAT_ULINEAR8;
    586 			break;
    587 		}
    588 		if (p->precision == 16) {
    589 			bits = CNTL_FORMAT_SLINEAR16BE;
    590 			hw.encoding = AUDIO_ENCODING_SLINEAR_BE;
    591 			rswcode = pswcode = swap_bytes_change_sign16;
    592 			break;
    593 		}
    594 		return EINVAL;
    595 	default:
    596 		return EINVAL;
    597 	}
    598 
    599 	if (sc->sc_outputgain)
    600 		bits |= CNTL_OLB;
    601 
    602 	if (p->channels == 1)
    603 		bits |= CNTL_CHANS_MONO;
    604 	else if (p->channels == 2)
    605 		bits |= CNTL_CHANS_STEREO;
    606 	else
    607 		return EINVAL;
    608 
    609 	bits |= harmony_speed_bits(sc, &p->sample_rate);
    610 	if (pswcode != NULL)
    611 		pfil->append(pfil, pswcode, &hw);
    612 	if (rswcode != NULL)
    613 		rfil->append(rfil, rswcode, &hw);
    614 	sc->sc_cntlbits = bits;
    615 	sc->sc_need_commit = 1;
    616 
    617 	return 0;
    618 }
    619 
    620 int
    621 harmony_round_blocksize(void *vsc, int blk,
    622     int mode, const audio_params_t *param)
    623 {
    624 
    625 	return HARMONY_BUFSIZE;
    626 }
    627 
    628 int
    629 harmony_control_wait(struct harmony_softc *sc)
    630 {
    631 	uint32_t reg;
    632 	int j = 0;
    633 
    634 	while (j < 10) {
    635 		/* Wait for it to come out of control mode */
    636 		reg = READ_REG(sc, HARMONY_CNTL);
    637 		if ((reg & CNTL_C) == 0)
    638 			return 0;
    639 		DELAY(50000);		/* wait 0.05 */
    640 		j++;
    641 	}
    642 
    643 	return 1;
    644 }
    645 
    646 int
    647 harmony_commit_settings(void *vsc)
    648 {
    649 	struct harmony_softc *sc;
    650 	uint32_t reg;
    651 	uint8_t quietchar;
    652 	int i;
    653 
    654 	sc = vsc;
    655 	if (sc->sc_need_commit == 0)
    656 		return 0;
    657 
    658 	harmony_intr_disable(sc);
    659 
    660 	for (;;) {
    661 		reg = READ_REG(sc, HARMONY_DSTATUS);
    662 		if ((reg & (DSTATUS_PC | DSTATUS_RC)) == 0)
    663 			break;
    664 	}
    665 
    666 	/* Setting some bits in gainctl requires a reset */
    667 	harmony_reset_codec(sc);
    668 
    669 	/* set the silence character based on the encoding type */
    670 	bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
    671 	    offsetof(struct harmony_empty, playback[0][0]),
    672 	    PLAYBACK_EMPTYS * HARMONY_BUFSIZE, BUS_DMASYNC_POSTWRITE);
    673 	switch (sc->sc_cntlbits & CNTL_FORMAT_MASK) {
    674 	case CNTL_FORMAT_ULAW:
    675 		quietchar = 0x7f;
    676 		break;
    677 	case CNTL_FORMAT_ALAW:
    678 		quietchar = 0x55;
    679 		break;
    680 	case CNTL_FORMAT_SLINEAR16BE:
    681 	case CNTL_FORMAT_ULINEAR8:
    682 	default:
    683 		quietchar = 0;
    684 		break;
    685 	}
    686 	for (i = 0; i < PLAYBACK_EMPTYS; i++)
    687 		memset(&sc->sc_empty_kva->playback[i][0],
    688 		    quietchar, HARMONY_BUFSIZE);
    689 	bus_dmamap_sync(sc->sc_dmat, sc->sc_empty_map,
    690 	    offsetof(struct harmony_empty, playback[0][0]),
    691 	    PLAYBACK_EMPTYS * HARMONY_BUFSIZE, BUS_DMASYNC_PREWRITE);
    692 
    693 	harmony_control_wait(sc);
    694 
    695 	bus_space_write_4(sc->sc_bt, sc->sc_bh, HARMONY_CNTL,
    696 	    sc->sc_cntlbits | CNTL_C);
    697 
    698 	harmony_control_wait(sc);
    699 
    700 	sc->sc_need_commit = 0;
    701 
    702 	if (sc->sc_playing || sc->sc_capturing)
    703 		harmony_intr_enable(sc);
    704 
    705 	return 0;
    706 }
    707 
    708 static void
    709 harmony_empty_output(struct harmony_softc *sc)
    710 {
    711 
    712 	WRITE_REG(sc, HARMONY_PNXTADD,
    713 	    sc->sc_playback_paddrs[sc->sc_playback_empty]);
    714 	SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
    715 
    716 	if (++sc->sc_playback_empty == PLAYBACK_EMPTYS)
    717 		sc->sc_playback_empty = 0;
    718 }
    719 
    720 int
    721 harmony_halt_output(void *vsc)
    722 {
    723 	struct harmony_softc *sc;
    724 
    725 	sc = vsc;
    726 	sc->sc_playing = 0;
    727 
    728 	harmony_empty_output(sc);
    729 	return 0;
    730 }
    731 
    732 static void
    733 harmony_empty_input(struct harmony_softc *sc)
    734 {
    735 
    736 	WRITE_REG(sc, HARMONY_RNXTADD,
    737 	    sc->sc_capture_paddrs[sc->sc_capture_empty]);
    738 	SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
    739 
    740 	if (++sc->sc_capture_empty == CAPTURE_EMPTYS)
    741 		sc->sc_capture_empty = 0;
    742 }
    743 
    744 int
    745 harmony_halt_input(void *vsc)
    746 {
    747 	struct harmony_softc *sc;
    748 
    749 	sc = vsc;
    750 	sc->sc_capturing = 0;
    751 
    752 	harmony_empty_input(sc);
    753 	return 0;
    754 }
    755 
    756 int
    757 harmony_getdev(void *vsc, struct audio_device *retp)
    758 {
    759 	struct harmony_softc *sc;
    760 
    761 	sc = vsc;
    762 	*retp = sc->sc_audev;
    763 	return 0;
    764 }
    765 
    766 int
    767 harmony_set_port(void *vsc, mixer_ctrl_t *cp)
    768 {
    769 	struct harmony_softc *sc;
    770 	int err;
    771 
    772 	sc = vsc;
    773 	err = EINVAL;
    774 	switch (cp->dev) {
    775 	case HARMONY_PORT_INPUT_LVL:
    776 		if (cp->type != AUDIO_MIXER_VALUE)
    777 			break;
    778 		if (cp->un.value.num_channels == 1)
    779 			sc->sc_input_lvl.left = sc->sc_input_lvl.right =
    780 			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    781 		else if (cp->un.value.num_channels == 2) {
    782 			sc->sc_input_lvl.left =
    783 			    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    784 			sc->sc_input_lvl.right =
    785 			    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    786 		} else
    787 			break;
    788 		sc->sc_need_commit = 1;
    789 		err = 0;
    790 		break;
    791 	case HARMONY_PORT_OUTPUT_LVL:
    792 		if (cp->type != AUDIO_MIXER_VALUE)
    793 			break;
    794 		if (cp->un.value.num_channels == 1)
    795 			sc->sc_output_lvl.left = sc->sc_output_lvl.right =
    796 			    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    797 		else if (cp->un.value.num_channels == 2) {
    798 			sc->sc_output_lvl.left =
    799 			    cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    800 			sc->sc_output_lvl.right =
    801 			    cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    802 		} else
    803 			break;
    804 		sc->sc_need_commit = 1;
    805 		err = 0;
    806 		break;
    807 	case HARMONY_PORT_OUTPUT_GAIN:
    808 		if (cp->type != AUDIO_MIXER_ENUM)
    809 			break;
    810 		sc->sc_outputgain = cp->un.ord ? 1 : 0;
    811 		err = 0;
    812 		break;
    813 	case HARMONY_PORT_MONITOR_LVL:
    814 		if (cp->type != AUDIO_MIXER_VALUE)
    815 			break;
    816 		if (cp->un.value.num_channels != 1)
    817 			break;
    818 		sc->sc_monitor_lvl.left = sc->sc_input_lvl.right =
    819 		    cp->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    820 		sc->sc_need_commit = 1;
    821 		err = 0;
    822 		break;
    823 	case HARMONY_PORT_RECORD_SOURCE:
    824 		if (cp->type != AUDIO_MIXER_ENUM)
    825 			break;
    826 		if (cp->un.ord != HARMONY_IN_LINE &&
    827 		    cp->un.ord != HARMONY_IN_MIC)
    828 			break;
    829 		sc->sc_in_port = cp->un.ord;
    830 		err = 0;
    831 		sc->sc_need_commit = 1;
    832 		break;
    833 	case HARMONY_PORT_OUTPUT_SOURCE:
    834 		if (cp->type != AUDIO_MIXER_ENUM)
    835 			break;
    836 		if (cp->un.ord != HARMONY_OUT_LINE &&
    837 		    cp->un.ord != HARMONY_OUT_SPEAKER &&
    838 		    cp->un.ord != HARMONY_OUT_HEADPHONE)
    839 			break;
    840 		sc->sc_out_port = cp->un.ord;
    841 		err = 0;
    842 		sc->sc_need_commit = 1;
    843 		break;
    844 	}
    845 
    846 	return err;
    847 }
    848 
    849 int
    850 harmony_get_port(void *vsc, mixer_ctrl_t *cp)
    851 {
    852 	struct harmony_softc *sc;
    853 	int err;
    854 
    855 	sc = vsc;
    856 	err = EINVAL;
    857 	switch (cp->dev) {
    858 	case HARMONY_PORT_INPUT_LVL:
    859 		if (cp->type != AUDIO_MIXER_VALUE)
    860 			break;
    861 		if (cp->un.value.num_channels == 1) {
    862 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    863 			    sc->sc_input_lvl.left;
    864 		} else if (cp->un.value.num_channels == 2) {
    865 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    866 			    sc->sc_input_lvl.left;
    867 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    868 			    sc->sc_input_lvl.right;
    869 		} else
    870 			break;
    871 		err = 0;
    872 		break;
    873 	case HARMONY_PORT_INPUT_OV:
    874 		if (cp->type != AUDIO_MIXER_ENUM)
    875 			break;
    876 		cp->un.ord = sc->sc_ov ? 1 : 0;
    877 		err = 0;
    878 		break;
    879 	case HARMONY_PORT_OUTPUT_LVL:
    880 		if (cp->type != AUDIO_MIXER_VALUE)
    881 			break;
    882 		if (cp->un.value.num_channels == 1) {
    883 			cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    884 			    sc->sc_output_lvl.left;
    885 		} else if (cp->un.value.num_channels == 2) {
    886 			cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    887 			    sc->sc_output_lvl.left;
    888 			cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    889 			    sc->sc_output_lvl.right;
    890 		} else
    891 			break;
    892 		err = 0;
    893 		break;
    894 	case HARMONY_PORT_OUTPUT_GAIN:
    895 		if (cp->type != AUDIO_MIXER_ENUM)
    896 			break;
    897 		cp->un.ord = sc->sc_outputgain ? 1 : 0;
    898 		err = 0;
    899 		break;
    900 	case HARMONY_PORT_MONITOR_LVL:
    901 		if (cp->type != AUDIO_MIXER_VALUE)
    902 			break;
    903 		if (cp->un.value.num_channels != 1)
    904 			break;
    905 		cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    906 		    sc->sc_monitor_lvl.left;
    907 		err = 0;
    908 		break;
    909 	case HARMONY_PORT_RECORD_SOURCE:
    910 		if (cp->type != AUDIO_MIXER_ENUM)
    911 			break;
    912 		cp->un.ord = sc->sc_in_port;
    913 		err = 0;
    914 		break;
    915 	case HARMONY_PORT_OUTPUT_SOURCE:
    916 		if (cp->type != AUDIO_MIXER_ENUM)
    917 			break;
    918 		cp->un.ord = sc->sc_out_port;
    919 		err = 0;
    920 		break;
    921 	}
    922 	return err;
    923 }
    924 
    925 int
    926 harmony_query_devinfo(void *vsc, mixer_devinfo_t *dip)
    927 {
    928 	int err;
    929 
    930 	err = 0;
    931 	switch (dip->index) {
    932 	case HARMONY_PORT_INPUT_LVL:
    933 		dip->type = AUDIO_MIXER_VALUE;
    934 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    935 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    936 		strlcpy(dip->label.name, AudioNinput, sizeof dip->label.name);
    937 		dip->un.v.num_channels = 2;
    938 		strlcpy(dip->un.v.units.name, AudioNvolume,
    939 		    sizeof dip->un.v.units.name);
    940 		break;
    941 	case HARMONY_PORT_INPUT_OV:
    942 		dip->type = AUDIO_MIXER_ENUM;
    943 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
    944 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    945 		strlcpy(dip->label.name, "overrange", sizeof dip->label.name);
    946 		dip->un.e.num_mem = 2;
    947 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
    948 		    sizeof dip->un.e.member[0].label.name);
    949 		dip->un.e.member[0].ord = 0;
    950 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
    951 		    sizeof dip->un.e.member[1].label.name);
    952 		dip->un.e.member[1].ord = 1;
    953 		break;
    954 	case HARMONY_PORT_OUTPUT_LVL:
    955 		dip->type = AUDIO_MIXER_VALUE;
    956 		dip->mixer_class = HARMONY_PORT_OUTPUT_CLASS;
    957 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    958 		strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
    959 		dip->un.v.num_channels = 2;
    960 		strlcpy(dip->un.v.units.name, AudioNvolume,
    961 		    sizeof dip->un.v.units.name);
    962 		break;
    963 	case HARMONY_PORT_OUTPUT_GAIN:
    964 		dip->type = AUDIO_MIXER_ENUM;
    965 		dip->mixer_class = HARMONY_PORT_OUTPUT_CLASS;
    966 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    967 		strlcpy(dip->label.name, "gain", sizeof dip->label.name);
    968 		dip->un.e.num_mem = 2;
    969 		strlcpy(dip->un.e.member[0].label.name, AudioNoff,
    970 		    sizeof dip->un.e.member[0].label.name);
    971 		dip->un.e.member[0].ord = 0;
    972 		strlcpy(dip->un.e.member[1].label.name, AudioNon,
    973 		    sizeof dip->un.e.member[1].label.name);
    974 		dip->un.e.member[1].ord = 1;
    975 		break;
    976 	case HARMONY_PORT_MONITOR_LVL:
    977 		dip->type = AUDIO_MIXER_VALUE;
    978 		dip->mixer_class = HARMONY_PORT_MONITOR_CLASS;
    979 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    980 		strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
    981 		dip->un.v.num_channels = 1;
    982 		strlcpy(dip->un.v.units.name, AudioNvolume,
    983 		    sizeof dip->un.v.units.name);
    984 		break;
    985 	case HARMONY_PORT_RECORD_SOURCE:
    986 		dip->type = AUDIO_MIXER_ENUM;
    987 		dip->mixer_class = HARMONY_PORT_RECORD_CLASS;
    988 		dip->prev = dip->next = AUDIO_MIXER_LAST;
    989 		strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
    990 		dip->un.e.num_mem = 2;
    991 		strlcpy(dip->un.e.member[0].label.name, AudioNmicrophone,
    992 		    sizeof dip->un.e.member[0].label.name);
    993 		dip->un.e.member[0].ord = HARMONY_IN_MIC;
    994 		strlcpy(dip->un.e.member[1].label.name, AudioNline,
    995 		    sizeof dip->un.e.member[1].label.name);
    996 		dip->un.e.member[1].ord = HARMONY_IN_LINE;
    997 		break;
    998 	case HARMONY_PORT_OUTPUT_SOURCE:
    999 		dip->type = AUDIO_MIXER_ENUM;
   1000 		dip->mixer_class = HARMONY_PORT_MONITOR_CLASS;
   1001 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   1002 		strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
   1003 		dip->un.e.num_mem = 3;
   1004 		strlcpy(dip->un.e.member[0].label.name, AudioNline,
   1005 		    sizeof dip->un.e.member[0].label.name);
   1006 		dip->un.e.member[0].ord = HARMONY_OUT_LINE;
   1007 		strlcpy(dip->un.e.member[1].label.name, AudioNspeaker,
   1008 		    sizeof dip->un.e.member[1].label.name);
   1009 		dip->un.e.member[1].ord = HARMONY_OUT_SPEAKER;
   1010 		strlcpy(dip->un.e.member[2].label.name, AudioNheadphone,
   1011 		    sizeof dip->un.e.member[2].label.name);
   1012 		dip->un.e.member[2].ord = HARMONY_OUT_HEADPHONE;
   1013 		break;
   1014 	case HARMONY_PORT_INPUT_CLASS:
   1015 		dip->type = AUDIO_MIXER_CLASS;
   1016 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
   1017 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   1018 		strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
   1019 		break;
   1020 	case HARMONY_PORT_OUTPUT_CLASS:
   1021 		dip->type = AUDIO_MIXER_CLASS;
   1022 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
   1023 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   1024 		strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
   1025 		break;
   1026 	case HARMONY_PORT_MONITOR_CLASS:
   1027 		dip->type = AUDIO_MIXER_CLASS;
   1028 		dip->mixer_class = HARMONY_PORT_INPUT_CLASS;
   1029 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   1030 		strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
   1031 		break;
   1032 	case HARMONY_PORT_RECORD_CLASS:
   1033 		dip->type = AUDIO_MIXER_CLASS;
   1034 		dip->mixer_class = HARMONY_PORT_RECORD_CLASS;
   1035 		dip->prev = dip->next = AUDIO_MIXER_LAST;
   1036 		strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
   1037 		break;
   1038 	default:
   1039 		err = ENXIO;
   1040 		break;
   1041 	}
   1042 
   1043 	return err;
   1044 }
   1045 
   1046 void *
   1047 harmony_allocm(void *vsc, int dir, size_t size)
   1048 {
   1049 	struct harmony_softc *sc;
   1050 	struct harmony_dma *d;
   1051 	int rseg;
   1052 
   1053 	sc = vsc;
   1054 	d = kmem_alloc(sizeof(*d), KM_SLEEP);
   1055 	if (d == NULL)
   1056 		goto fail;
   1057 
   1058 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, BUS_DMA_WAITOK,
   1059 	    &d->d_map) != 0)
   1060 		goto fail1;
   1061 
   1062 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &d->d_seg, 1,
   1063 	    &rseg, BUS_DMA_WAITOK) != 0)
   1064 		goto fail2;
   1065 
   1066 	if (bus_dmamem_map(sc->sc_dmat, &d->d_seg, 1, size, &d->d_kva,
   1067 	    BUS_DMA_WAITOK) != 0)
   1068 		goto fail3;
   1069 
   1070 	if (bus_dmamap_load(sc->sc_dmat, d->d_map, d->d_kva, size, NULL,
   1071 	    BUS_DMA_WAITOK) != 0)
   1072 		goto fail4;
   1073 
   1074 	d->d_next = sc->sc_dmas;
   1075 	sc->sc_dmas = d;
   1076 	d->d_size = size;
   1077 	return (d->d_kva);
   1078 
   1079 fail4:
   1080 	bus_dmamem_unmap(sc->sc_dmat, d->d_kva, size);
   1081 fail3:
   1082 	bus_dmamem_free(sc->sc_dmat, &d->d_seg, 1);
   1083 fail2:
   1084 	bus_dmamap_destroy(sc->sc_dmat, d->d_map);
   1085 fail1:
   1086 	kmem_free(d, sizeof(*d));
   1087 fail:
   1088 	return (NULL);
   1089 }
   1090 
   1091 void
   1092 harmony_freem(void *vsc, void *ptr, size_t size)
   1093 {
   1094 	struct harmony_softc *sc;
   1095 	struct harmony_dma *d, **dd;
   1096 
   1097 	sc = vsc;
   1098 	for (dd = &sc->sc_dmas; (d = *dd) != NULL; dd = &(*dd)->d_next) {
   1099 		if (d->d_kva != ptr)
   1100 			continue;
   1101 		bus_dmamap_unload(sc->sc_dmat, d->d_map);
   1102 		bus_dmamem_unmap(sc->sc_dmat, d->d_kva, d->d_size);
   1103 		bus_dmamem_free(sc->sc_dmat, &d->d_seg, 1);
   1104 		bus_dmamap_destroy(sc->sc_dmat, d->d_map);
   1105 		kmem_free(d, sizeof(*d));
   1106 		return;
   1107 	}
   1108 	printf("%s: free rogue pointer\n", device_xname(sc->sc_dv));
   1109 }
   1110 
   1111 size_t
   1112 harmony_round_buffersize(void *vsc, int direction, size_t size)
   1113 {
   1114 
   1115 	return ((size + HARMONY_BUFSIZE - 1) & (size_t)(-HARMONY_BUFSIZE));
   1116 }
   1117 
   1118 int
   1119 harmony_get_props(void *vsc)
   1120 {
   1121 
   1122 	return AUDIO_PROP_FULLDUPLEX;
   1123 }
   1124 
   1125 void
   1126 harmony_get_locks(void *vsc, kmutex_t **intr, kmutex_t **thread)
   1127 {
   1128 	struct harmony_softc *sc;
   1129 
   1130 	sc = vsc;
   1131 	*intr = &sc->sc_intr_lock;
   1132 	*thread = &sc->sc_lock;
   1133 }
   1134 
   1135 int
   1136 harmony_trigger_output(void *vsc, void *start, void *end, int blksize,
   1137     void (*intr)(void *), void *intrarg, const audio_params_t *param)
   1138 {
   1139 	struct harmony_softc *sc;
   1140 	struct harmony_channel *c;
   1141 	struct harmony_dma *d;
   1142 
   1143 	sc = vsc;
   1144 	c = &sc->sc_playback;
   1145 	for (d = sc->sc_dmas; d->d_kva != start; d = d->d_next)
   1146 		continue;
   1147 	if (d == NULL) {
   1148 		printf("%s: trigger_output: bad addr: %p\n",
   1149 		    device_xname(sc->sc_dv), start);
   1150 		return EINVAL;
   1151 	}
   1152 
   1153 	mutex_spin_enter(&sc->sc_intr_lock);
   1154 
   1155 	c->c_intr = intr;
   1156 	c->c_intrarg = intrarg;
   1157 	c->c_blksz = blksize;
   1158 	c->c_current = d;
   1159 	c->c_segsz = (char *)end - (char *)start;
   1160 	c->c_cnt = 0;
   1161 	c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
   1162 
   1163 	sc->sc_playing = 1;
   1164 
   1165 	harmony_start_pp(sc, 1);
   1166 	harmony_start_cp(sc, 0);
   1167 	harmony_intr_enable(sc);
   1168 
   1169 	mutex_spin_exit(&sc->sc_intr_lock);
   1170 
   1171 	return 0;
   1172 }
   1173 
   1174 void
   1175 harmony_start_cp(struct harmony_softc *sc, int start)
   1176 {
   1177 	struct harmony_channel *c;
   1178 	struct harmony_dma *d;
   1179 	bus_addr_t nextaddr;
   1180 	bus_size_t togo;
   1181 
   1182 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1183 
   1184 	c = &sc->sc_capture;
   1185 	if (sc->sc_capturing == 0)
   1186 		harmony_empty_input(sc);
   1187 	else {
   1188 		d = c->c_current;
   1189 		togo = c->c_segsz - c->c_cnt;
   1190 		if (togo == 0) {
   1191 			nextaddr = d->d_map->dm_segs[0].ds_addr;
   1192 			c->c_cnt = togo = c->c_blksz;
   1193 		} else {
   1194 			nextaddr = c->c_lastaddr;
   1195 			if (togo > c->c_blksz)
   1196 				togo = c->c_blksz;
   1197 			c->c_cnt += togo;
   1198 		}
   1199 
   1200 		bus_dmamap_sync(sc->sc_dmat, d->d_map,
   1201 		    nextaddr - d->d_map->dm_segs[0].ds_addr,
   1202 		    c->c_blksz, BUS_DMASYNC_PREWRITE);
   1203 
   1204 		WRITE_REG(sc, HARMONY_RNXTADD, nextaddr);
   1205 		if (start)
   1206 			c->c_theaddr = nextaddr;
   1207 		SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
   1208 		c->c_lastaddr = nextaddr + togo;
   1209 
   1210 		harmony_try_more(sc, HARMONY_RCURADD,
   1211 		    RCURADD_BUFMASK, &sc->sc_capture);
   1212 	}
   1213 
   1214 	callout_schedule(&sc->sc_acc_tmo, 1);
   1215 }
   1216 
   1217 void
   1218 harmony_start_pp(struct harmony_softc *sc, int start)
   1219 {
   1220 	struct harmony_channel *c;
   1221 	struct harmony_dma *d;
   1222 	bus_addr_t nextaddr;
   1223 	bus_size_t togo;
   1224 
   1225 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1226 
   1227 	c = &sc->sc_playback;
   1228 	if (sc->sc_playing == 0)
   1229 		harmony_empty_output(sc);
   1230 	else {
   1231 		d = c->c_current;
   1232 		togo = c->c_segsz - c->c_cnt;
   1233 		if (togo == 0) {
   1234 			nextaddr = d->d_map->dm_segs[0].ds_addr;
   1235 			c->c_cnt = togo = c->c_blksz;
   1236 		} else {
   1237 			nextaddr = c->c_lastaddr;
   1238 			if (togo > c->c_blksz)
   1239 				togo = c->c_blksz;
   1240 			c->c_cnt += togo;
   1241 		}
   1242 
   1243 		bus_dmamap_sync(sc->sc_dmat, d->d_map,
   1244 		    nextaddr - d->d_map->dm_segs[0].ds_addr,
   1245 		    c->c_blksz, BUS_DMASYNC_PREWRITE);
   1246 
   1247 		WRITE_REG(sc, HARMONY_PNXTADD, nextaddr);
   1248 		if (start)
   1249 			c->c_theaddr = nextaddr;
   1250 		SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
   1251 		c->c_lastaddr = nextaddr + togo;
   1252 
   1253 		harmony_try_more(sc, HARMONY_PCURADD,
   1254 		    PCURADD_BUFMASK, &sc->sc_playback);
   1255 	}
   1256 }
   1257 
   1258 int
   1259 harmony_trigger_input(void *vsc, void *start, void *end, int blksize,
   1260     void (*intr)(void *), void *intrarg, const audio_params_t *param)
   1261 {
   1262 	struct harmony_softc *sc = vsc;
   1263 	struct harmony_channel *c = &sc->sc_capture;
   1264 	struct harmony_dma *d;
   1265 
   1266 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1267 
   1268 	for (d = sc->sc_dmas; d->d_kva != start; d = d->d_next)
   1269 		continue;
   1270 	if (d == NULL) {
   1271 		printf("%s: trigger_input: bad addr: %p\n",
   1272 		    device_xname(sc->sc_dv), start);
   1273 		return EINVAL;
   1274 	}
   1275 
   1276 	c->c_intr = intr;
   1277 	c->c_intrarg = intrarg;
   1278 	c->c_blksz = blksize;
   1279 	c->c_current = d;
   1280 	c->c_segsz = (char *)end - (char *)start;
   1281 	c->c_cnt = 0;
   1282 	c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
   1283 
   1284 	sc->sc_capturing = 1;
   1285 
   1286 	harmony_start_cp(sc, 1);
   1287 	harmony_intr_enable(sc);
   1288 
   1289 	return 0;
   1290 }
   1291 
   1292 static const struct speed_struct {
   1293 	uint32_t speed;
   1294 	uint32_t bits;
   1295 } harmony_speeds[] = {
   1296 	{ 5125, CNTL_RATE_5125 },
   1297 	{ 6615, CNTL_RATE_6615 },
   1298 	{ 8000, CNTL_RATE_8000 },
   1299 	{ 9600, CNTL_RATE_9600 },
   1300 	{ 11025, CNTL_RATE_11025 },
   1301 	{ 16000, CNTL_RATE_16000 },
   1302 	{ 18900, CNTL_RATE_18900 },
   1303 	{ 22050, CNTL_RATE_22050 },
   1304 	{ 27428, CNTL_RATE_27428 },
   1305 	{ 32000, CNTL_RATE_32000 },
   1306 	{ 33075, CNTL_RATE_33075 },
   1307 	{ 37800, CNTL_RATE_37800 },
   1308 	{ 44100, CNTL_RATE_44100 },
   1309 	{ 48000, CNTL_RATE_48000 },
   1310 };
   1311 
   1312 uint32_t
   1313 harmony_speed_bits(struct harmony_softc *sc, u_int *speedp)
   1314 {
   1315 	int i, n, selected;
   1316 
   1317 	selected = -1;
   1318 	n = sizeof(harmony_speeds) / sizeof(harmony_speeds[0]);
   1319 
   1320 	if ((*speedp) <= harmony_speeds[0].speed)
   1321 		selected = 0;
   1322 	else if ((*speedp) >= harmony_speeds[n - 1].speed)
   1323 		selected = n - 1;
   1324 	else {
   1325 		for (i = 1; selected == -1 && i < n; i++) {
   1326 			if ((*speedp) == harmony_speeds[i].speed)
   1327 				selected = i;
   1328 			else if ((*speedp) < harmony_speeds[i].speed) {
   1329 				int diff1, diff2;
   1330 
   1331 				diff1 = (*speedp) - harmony_speeds[i - 1].speed;
   1332 				diff2 = harmony_speeds[i].speed - (*speedp);
   1333 				if (diff1 < diff2)
   1334 					selected = i - 1;
   1335 				else
   1336 					selected = i;
   1337 			}
   1338 		}
   1339 	}
   1340 
   1341 	if (selected == -1)
   1342 		selected = 2;
   1343 
   1344 	*speedp = harmony_speeds[selected].speed;
   1345 	return harmony_speeds[selected].bits;
   1346 }
   1347 
   1348 int
   1349 harmony_set_gainctl(struct harmony_softc *sc)
   1350 {
   1351 	uint32_t bits, mask, val, old;
   1352 
   1353 	/* XXX leave these bits alone or the chip will not come out of CNTL */
   1354 	bits = GAINCTL_LE | GAINCTL_HE | GAINCTL_SE | GAINCTL_IS_MASK;
   1355 
   1356 	/* input level */
   1357 	bits |= ((sc->sc_input_lvl.left >> (8 - GAINCTL_INPUT_BITS)) <<
   1358 	    GAINCTL_INPUT_LEFT_S) & GAINCTL_INPUT_LEFT_M;
   1359 	bits |= ((sc->sc_input_lvl.right >> (8 - GAINCTL_INPUT_BITS)) <<
   1360 	    GAINCTL_INPUT_RIGHT_S) & GAINCTL_INPUT_RIGHT_M;
   1361 
   1362 	/* output level (inverted) */
   1363 	mask = (1 << GAINCTL_OUTPUT_BITS) - 1;
   1364 	val = mask - (sc->sc_output_lvl.left >> (8 - GAINCTL_OUTPUT_BITS));
   1365 	bits |= (val << GAINCTL_OUTPUT_LEFT_S) & GAINCTL_OUTPUT_LEFT_M;
   1366 	val = mask - (sc->sc_output_lvl.right >> (8 - GAINCTL_OUTPUT_BITS));
   1367 	bits |= (val << GAINCTL_OUTPUT_RIGHT_S) & GAINCTL_OUTPUT_RIGHT_M;
   1368 
   1369 	/* monitor level (inverted) */
   1370 	mask = (1 << GAINCTL_MONITOR_BITS) - 1;
   1371 	val = mask - (sc->sc_monitor_lvl.left >> (8 - GAINCTL_MONITOR_BITS));
   1372 	bits |= (val << GAINCTL_MONITOR_S) & GAINCTL_MONITOR_M;
   1373 
   1374 	/* XXX messing with these causes CNTL_C to get stuck... grr. */
   1375 	bits &= ~GAINCTL_IS_MASK;
   1376 	if (sc->sc_in_port == HARMONY_IN_MIC)
   1377 		bits |= GAINCTL_IS_LINE;
   1378 	else
   1379 		bits |= GAINCTL_IS_MICROPHONE;
   1380 
   1381 	/* XXX messing with these causes CNTL_C to get stuck... grr. */
   1382 	bits &= ~(GAINCTL_LE | GAINCTL_HE | GAINCTL_SE);
   1383 	if (sc->sc_out_port == HARMONY_OUT_LINE)
   1384 		bits |= GAINCTL_LE;
   1385 	else if (sc->sc_out_port == HARMONY_OUT_SPEAKER)
   1386 		bits |= GAINCTL_SE;
   1387 	else
   1388 		bits |= GAINCTL_HE;
   1389 
   1390 	mask = GAINCTL_LE | GAINCTL_HE | GAINCTL_SE | GAINCTL_IS_MASK;
   1391 	old = bus_space_read_4(sc->sc_bt, sc->sc_bh, HARMONY_GAINCTL);
   1392 	bus_space_write_4(sc->sc_bt, sc->sc_bh, HARMONY_GAINCTL, bits);
   1393 	if ((old & mask) != (bits & mask))
   1394 		return 1;
   1395 	return 0;
   1396 }
   1397 
   1398 void
   1399 harmony_try_more(struct harmony_softc *sc, int curadd, int bufmask,
   1400 	struct harmony_channel *c)
   1401 {
   1402 	struct harmony_dma *d;
   1403 	uint32_t cur;
   1404 	int i, nsegs;
   1405 
   1406 	d = c->c_current;
   1407 	cur = bus_space_read_4(sc->sc_bt, sc->sc_bh, curadd);
   1408 	cur &= bufmask;
   1409 	nsegs = 0;
   1410 
   1411 #ifdef DIAGNOSTIC
   1412 	if (cur < d->d_map->dm_segs[0].ds_addr ||
   1413 	    cur >= (d->d_map->dm_segs[0].ds_addr + c->c_segsz))
   1414 		panic("%s: bad current %x < %lx || %x > %lx",
   1415 		    device_xname(sc->sc_dv), cur,
   1416 		    d->d_map->dm_segs[0].ds_addr, cur,
   1417 		    d->d_map->dm_segs[0].ds_addr + c->c_segsz);
   1418 #endif /* DIAGNOSTIC */
   1419 
   1420 	if (cur > c->c_theaddr) {
   1421 		nsegs = (cur - c->c_theaddr) / HARMONY_BUFSIZE;
   1422 	} else if (cur < c->c_theaddr) {
   1423 		nsegs = (d->d_map->dm_segs[0].ds_addr + c->c_segsz -
   1424 		    c->c_theaddr) / HARMONY_BUFSIZE;
   1425 		nsegs += (cur - d->d_map->dm_segs[0].ds_addr) /
   1426 		    HARMONY_BUFSIZE;
   1427 	}
   1428 
   1429 	if (nsegs != 0 && c->c_intr != NULL) {
   1430 		for (i = 0; i < nsegs; i++)
   1431 			(*c->c_intr)(c->c_intrarg);
   1432 		c->c_theaddr = cur;
   1433 	}
   1434 }
   1435