Home | History | Annotate | Line # | Download | only in gsc
harmony.c revision 1.2.4.3
      1 /*	$NetBSD: harmony.c,v 1.2.4.3 2017/12/03 11:36:16 jdolecek 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_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 
   1056 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, BUS_DMA_WAITOK,
   1057 	    &d->d_map) != 0)
   1058 		goto fail1;
   1059 
   1060 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &d->d_seg, 1,
   1061 	    &rseg, BUS_DMA_WAITOK) != 0)
   1062 		goto fail2;
   1063 
   1064 	if (bus_dmamem_map(sc->sc_dmat, &d->d_seg, 1, size, &d->d_kva,
   1065 	    BUS_DMA_WAITOK) != 0)
   1066 		goto fail3;
   1067 
   1068 	if (bus_dmamap_load(sc->sc_dmat, d->d_map, d->d_kva, size, NULL,
   1069 	    BUS_DMA_WAITOK) != 0)
   1070 		goto fail4;
   1071 
   1072 	d->d_next = sc->sc_dmas;
   1073 	sc->sc_dmas = d;
   1074 	d->d_size = size;
   1075 	return (d->d_kva);
   1076 
   1077 fail4:
   1078 	bus_dmamem_unmap(sc->sc_dmat, d->d_kva, size);
   1079 fail3:
   1080 	bus_dmamem_free(sc->sc_dmat, &d->d_seg, 1);
   1081 fail2:
   1082 	bus_dmamap_destroy(sc->sc_dmat, d->d_map);
   1083 fail1:
   1084 	kmem_free(d, sizeof(*d));
   1085 	return (NULL);
   1086 }
   1087 
   1088 void
   1089 harmony_freem(void *vsc, void *ptr, size_t size)
   1090 {
   1091 	struct harmony_softc *sc;
   1092 	struct harmony_dma *d, **dd;
   1093 
   1094 	sc = vsc;
   1095 	for (dd = &sc->sc_dmas; (d = *dd) != NULL; dd = &(*dd)->d_next) {
   1096 		if (d->d_kva != ptr)
   1097 			continue;
   1098 		bus_dmamap_unload(sc->sc_dmat, d->d_map);
   1099 		bus_dmamem_unmap(sc->sc_dmat, d->d_kva, d->d_size);
   1100 		bus_dmamem_free(sc->sc_dmat, &d->d_seg, 1);
   1101 		bus_dmamap_destroy(sc->sc_dmat, d->d_map);
   1102 		kmem_free(d, sizeof(*d));
   1103 		return;
   1104 	}
   1105 	printf("%s: free rogue pointer\n", device_xname(sc->sc_dv));
   1106 }
   1107 
   1108 size_t
   1109 harmony_round_buffersize(void *vsc, int direction, size_t size)
   1110 {
   1111 
   1112 	return ((size + HARMONY_BUFSIZE - 1) & (size_t)(-HARMONY_BUFSIZE));
   1113 }
   1114 
   1115 int
   1116 harmony_get_props(void *vsc)
   1117 {
   1118 
   1119 	return AUDIO_PROP_FULLDUPLEX;
   1120 }
   1121 
   1122 void
   1123 harmony_get_locks(void *vsc, kmutex_t **intr, kmutex_t **thread)
   1124 {
   1125 	struct harmony_softc *sc;
   1126 
   1127 	sc = vsc;
   1128 	*intr = &sc->sc_intr_lock;
   1129 	*thread = &sc->sc_lock;
   1130 }
   1131 
   1132 int
   1133 harmony_trigger_output(void *vsc, void *start, void *end, int blksize,
   1134     void (*intr)(void *), void *intrarg, const audio_params_t *param)
   1135 {
   1136 	struct harmony_softc *sc;
   1137 	struct harmony_channel *c;
   1138 	struct harmony_dma *d;
   1139 
   1140 	sc = vsc;
   1141 	c = &sc->sc_playback;
   1142 	for (d = sc->sc_dmas; d->d_kva != start; d = d->d_next)
   1143 		continue;
   1144 	if (d == NULL) {
   1145 		printf("%s: trigger_output: bad addr: %p\n",
   1146 		    device_xname(sc->sc_dv), start);
   1147 		return EINVAL;
   1148 	}
   1149 
   1150 	mutex_spin_enter(&sc->sc_intr_lock);
   1151 
   1152 	c->c_intr = intr;
   1153 	c->c_intrarg = intrarg;
   1154 	c->c_blksz = blksize;
   1155 	c->c_current = d;
   1156 	c->c_segsz = (char *)end - (char *)start;
   1157 	c->c_cnt = 0;
   1158 	c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
   1159 
   1160 	sc->sc_playing = 1;
   1161 
   1162 	harmony_start_pp(sc, 1);
   1163 	harmony_start_cp(sc, 0);
   1164 	harmony_intr_enable(sc);
   1165 
   1166 	mutex_spin_exit(&sc->sc_intr_lock);
   1167 
   1168 	return 0;
   1169 }
   1170 
   1171 void
   1172 harmony_start_cp(struct harmony_softc *sc, int start)
   1173 {
   1174 	struct harmony_channel *c;
   1175 	struct harmony_dma *d;
   1176 	bus_addr_t nextaddr;
   1177 	bus_size_t togo;
   1178 
   1179 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1180 
   1181 	c = &sc->sc_capture;
   1182 	if (sc->sc_capturing == 0)
   1183 		harmony_empty_input(sc);
   1184 	else {
   1185 		d = c->c_current;
   1186 		togo = c->c_segsz - c->c_cnt;
   1187 		if (togo == 0) {
   1188 			nextaddr = d->d_map->dm_segs[0].ds_addr;
   1189 			c->c_cnt = togo = c->c_blksz;
   1190 		} else {
   1191 			nextaddr = c->c_lastaddr;
   1192 			if (togo > c->c_blksz)
   1193 				togo = c->c_blksz;
   1194 			c->c_cnt += togo;
   1195 		}
   1196 
   1197 		bus_dmamap_sync(sc->sc_dmat, d->d_map,
   1198 		    nextaddr - d->d_map->dm_segs[0].ds_addr,
   1199 		    c->c_blksz, BUS_DMASYNC_PREWRITE);
   1200 
   1201 		WRITE_REG(sc, HARMONY_RNXTADD, nextaddr);
   1202 		if (start)
   1203 			c->c_theaddr = nextaddr;
   1204 		SYNC_REG(sc, HARMONY_RNXTADD, BUS_SPACE_BARRIER_WRITE);
   1205 		c->c_lastaddr = nextaddr + togo;
   1206 
   1207 		harmony_try_more(sc, HARMONY_RCURADD,
   1208 		    RCURADD_BUFMASK, &sc->sc_capture);
   1209 	}
   1210 
   1211 	callout_schedule(&sc->sc_acc_tmo, 1);
   1212 }
   1213 
   1214 void
   1215 harmony_start_pp(struct harmony_softc *sc, int start)
   1216 {
   1217 	struct harmony_channel *c;
   1218 	struct harmony_dma *d;
   1219 	bus_addr_t nextaddr;
   1220 	bus_size_t togo;
   1221 
   1222 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1223 
   1224 	c = &sc->sc_playback;
   1225 	if (sc->sc_playing == 0)
   1226 		harmony_empty_output(sc);
   1227 	else {
   1228 		d = c->c_current;
   1229 		togo = c->c_segsz - c->c_cnt;
   1230 		if (togo == 0) {
   1231 			nextaddr = d->d_map->dm_segs[0].ds_addr;
   1232 			c->c_cnt = togo = c->c_blksz;
   1233 		} else {
   1234 			nextaddr = c->c_lastaddr;
   1235 			if (togo > c->c_blksz)
   1236 				togo = c->c_blksz;
   1237 			c->c_cnt += togo;
   1238 		}
   1239 
   1240 		bus_dmamap_sync(sc->sc_dmat, d->d_map,
   1241 		    nextaddr - d->d_map->dm_segs[0].ds_addr,
   1242 		    c->c_blksz, BUS_DMASYNC_PREWRITE);
   1243 
   1244 		WRITE_REG(sc, HARMONY_PNXTADD, nextaddr);
   1245 		if (start)
   1246 			c->c_theaddr = nextaddr;
   1247 		SYNC_REG(sc, HARMONY_PNXTADD, BUS_SPACE_BARRIER_WRITE);
   1248 		c->c_lastaddr = nextaddr + togo;
   1249 
   1250 		harmony_try_more(sc, HARMONY_PCURADD,
   1251 		    PCURADD_BUFMASK, &sc->sc_playback);
   1252 	}
   1253 }
   1254 
   1255 int
   1256 harmony_trigger_input(void *vsc, void *start, void *end, int blksize,
   1257     void (*intr)(void *), void *intrarg, const audio_params_t *param)
   1258 {
   1259 	struct harmony_softc *sc = vsc;
   1260 	struct harmony_channel *c = &sc->sc_capture;
   1261 	struct harmony_dma *d;
   1262 
   1263 	KASSERT(mutex_owned(&sc->sc_intr_lock));
   1264 
   1265 	for (d = sc->sc_dmas; d->d_kva != start; d = d->d_next)
   1266 		continue;
   1267 	if (d == NULL) {
   1268 		printf("%s: trigger_input: bad addr: %p\n",
   1269 		    device_xname(sc->sc_dv), start);
   1270 		return EINVAL;
   1271 	}
   1272 
   1273 	c->c_intr = intr;
   1274 	c->c_intrarg = intrarg;
   1275 	c->c_blksz = blksize;
   1276 	c->c_current = d;
   1277 	c->c_segsz = (char *)end - (char *)start;
   1278 	c->c_cnt = 0;
   1279 	c->c_lastaddr = d->d_map->dm_segs[0].ds_addr;
   1280 
   1281 	sc->sc_capturing = 1;
   1282 
   1283 	harmony_start_cp(sc, 1);
   1284 	harmony_intr_enable(sc);
   1285 
   1286 	return 0;
   1287 }
   1288 
   1289 static const struct speed_struct {
   1290 	uint32_t speed;
   1291 	uint32_t bits;
   1292 } harmony_speeds[] = {
   1293 	{ 5125, CNTL_RATE_5125 },
   1294 	{ 6615, CNTL_RATE_6615 },
   1295 	{ 8000, CNTL_RATE_8000 },
   1296 	{ 9600, CNTL_RATE_9600 },
   1297 	{ 11025, CNTL_RATE_11025 },
   1298 	{ 16000, CNTL_RATE_16000 },
   1299 	{ 18900, CNTL_RATE_18900 },
   1300 	{ 22050, CNTL_RATE_22050 },
   1301 	{ 27428, CNTL_RATE_27428 },
   1302 	{ 32000, CNTL_RATE_32000 },
   1303 	{ 33075, CNTL_RATE_33075 },
   1304 	{ 37800, CNTL_RATE_37800 },
   1305 	{ 44100, CNTL_RATE_44100 },
   1306 	{ 48000, CNTL_RATE_48000 },
   1307 };
   1308 
   1309 uint32_t
   1310 harmony_speed_bits(struct harmony_softc *sc, u_int *speedp)
   1311 {
   1312 	int i, n, selected;
   1313 
   1314 	selected = -1;
   1315 	n = sizeof(harmony_speeds) / sizeof(harmony_speeds[0]);
   1316 
   1317 	if ((*speedp) <= harmony_speeds[0].speed)
   1318 		selected = 0;
   1319 	else if ((*speedp) >= harmony_speeds[n - 1].speed)
   1320 		selected = n - 1;
   1321 	else {
   1322 		for (i = 1; selected == -1 && i < n; i++) {
   1323 			if ((*speedp) == harmony_speeds[i].speed)
   1324 				selected = i;
   1325 			else if ((*speedp) < harmony_speeds[i].speed) {
   1326 				int diff1, diff2;
   1327 
   1328 				diff1 = (*speedp) - harmony_speeds[i - 1].speed;
   1329 				diff2 = harmony_speeds[i].speed - (*speedp);
   1330 				if (diff1 < diff2)
   1331 					selected = i - 1;
   1332 				else
   1333 					selected = i;
   1334 			}
   1335 		}
   1336 	}
   1337 
   1338 	if (selected == -1)
   1339 		selected = 2;
   1340 
   1341 	*speedp = harmony_speeds[selected].speed;
   1342 	return harmony_speeds[selected].bits;
   1343 }
   1344 
   1345 int
   1346 harmony_set_gainctl(struct harmony_softc *sc)
   1347 {
   1348 	uint32_t bits, mask, val, old;
   1349 
   1350 	/* XXX leave these bits alone or the chip will not come out of CNTL */
   1351 	bits = GAINCTL_LE | GAINCTL_HE | GAINCTL_SE | GAINCTL_IS_MASK;
   1352 
   1353 	/* input level */
   1354 	bits |= ((sc->sc_input_lvl.left >> (8 - GAINCTL_INPUT_BITS)) <<
   1355 	    GAINCTL_INPUT_LEFT_S) & GAINCTL_INPUT_LEFT_M;
   1356 	bits |= ((sc->sc_input_lvl.right >> (8 - GAINCTL_INPUT_BITS)) <<
   1357 	    GAINCTL_INPUT_RIGHT_S) & GAINCTL_INPUT_RIGHT_M;
   1358 
   1359 	/* output level (inverted) */
   1360 	mask = (1 << GAINCTL_OUTPUT_BITS) - 1;
   1361 	val = mask - (sc->sc_output_lvl.left >> (8 - GAINCTL_OUTPUT_BITS));
   1362 	bits |= (val << GAINCTL_OUTPUT_LEFT_S) & GAINCTL_OUTPUT_LEFT_M;
   1363 	val = mask - (sc->sc_output_lvl.right >> (8 - GAINCTL_OUTPUT_BITS));
   1364 	bits |= (val << GAINCTL_OUTPUT_RIGHT_S) & GAINCTL_OUTPUT_RIGHT_M;
   1365 
   1366 	/* monitor level (inverted) */
   1367 	mask = (1 << GAINCTL_MONITOR_BITS) - 1;
   1368 	val = mask - (sc->sc_monitor_lvl.left >> (8 - GAINCTL_MONITOR_BITS));
   1369 	bits |= (val << GAINCTL_MONITOR_S) & GAINCTL_MONITOR_M;
   1370 
   1371 	/* XXX messing with these causes CNTL_C to get stuck... grr. */
   1372 	bits &= ~GAINCTL_IS_MASK;
   1373 	if (sc->sc_in_port == HARMONY_IN_MIC)
   1374 		bits |= GAINCTL_IS_LINE;
   1375 	else
   1376 		bits |= GAINCTL_IS_MICROPHONE;
   1377 
   1378 	/* XXX messing with these causes CNTL_C to get stuck... grr. */
   1379 	bits &= ~(GAINCTL_LE | GAINCTL_HE | GAINCTL_SE);
   1380 	if (sc->sc_out_port == HARMONY_OUT_LINE)
   1381 		bits |= GAINCTL_LE;
   1382 	else if (sc->sc_out_port == HARMONY_OUT_SPEAKER)
   1383 		bits |= GAINCTL_SE;
   1384 	else
   1385 		bits |= GAINCTL_HE;
   1386 
   1387 	mask = GAINCTL_LE | GAINCTL_HE | GAINCTL_SE | GAINCTL_IS_MASK;
   1388 	old = bus_space_read_4(sc->sc_bt, sc->sc_bh, HARMONY_GAINCTL);
   1389 	bus_space_write_4(sc->sc_bt, sc->sc_bh, HARMONY_GAINCTL, bits);
   1390 	if ((old & mask) != (bits & mask))
   1391 		return 1;
   1392 	return 0;
   1393 }
   1394 
   1395 void
   1396 harmony_try_more(struct harmony_softc *sc, int curadd, int bufmask,
   1397 	struct harmony_channel *c)
   1398 {
   1399 	struct harmony_dma *d;
   1400 	uint32_t cur;
   1401 	int i, nsegs;
   1402 
   1403 	d = c->c_current;
   1404 	cur = bus_space_read_4(sc->sc_bt, sc->sc_bh, curadd);
   1405 	cur &= bufmask;
   1406 	nsegs = 0;
   1407 
   1408 #ifdef DIAGNOSTIC
   1409 	if (cur < d->d_map->dm_segs[0].ds_addr ||
   1410 	    cur >= (d->d_map->dm_segs[0].ds_addr + c->c_segsz))
   1411 		panic("%s: bad current %x < %lx || %x > %lx",
   1412 		    device_xname(sc->sc_dv), cur,
   1413 		    d->d_map->dm_segs[0].ds_addr, cur,
   1414 		    d->d_map->dm_segs[0].ds_addr + c->c_segsz);
   1415 #endif /* DIAGNOSTIC */
   1416 
   1417 	if (cur > c->c_theaddr) {
   1418 		nsegs = (cur - c->c_theaddr) / HARMONY_BUFSIZE;
   1419 	} else if (cur < c->c_theaddr) {
   1420 		nsegs = (d->d_map->dm_segs[0].ds_addr + c->c_segsz -
   1421 		    c->c_theaddr) / HARMONY_BUFSIZE;
   1422 		nsegs += (cur - d->d_map->dm_segs[0].ds_addr) /
   1423 		    HARMONY_BUFSIZE;
   1424 	}
   1425 
   1426 	if (nsegs != 0 && c->c_intr != NULL) {
   1427 		for (i = 0; i < nsegs; i++)
   1428 			(*c->c_intr)(c->c_intrarg);
   1429 		c->c_theaddr = cur;
   1430 	}
   1431 }
   1432