Home | History | Annotate | Line # | Download | only in voyager
      1 /* $NetBSD: vac.c,v 1.2 2026/06/22 15:12:59 rkujawa Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2026 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 /*
     30  * Driver for the SM502 AC'97 audio interface
     31  */
     32 
     33 #include <sys/cdefs.h>
     34 __KERNEL_RCSID(0, "$NetBSD: vac.c,v 1.2 2026/06/22 15:12:59 rkujawa Exp $");
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/device.h>
     39 #include <sys/kmem.h>
     40 #include <sys/bus.h>
     41 #include <sys/callout.h>
     42 #include <sys/sysctl.h>
     43 #include <sys/audioio.h>
     44 
     45 #include <dev/audio/audio_if.h>
     46 
     47 #include <dev/ic/ac97var.h>
     48 #include <dev/ic/ac97reg.h>
     49 
     50 #include <dev/ic/sm502reg.h>
     51 #include <dev/pci/voyagervar.h>
     52 
     53 /* PCM playback format: AC'97 fixed 48 kHz, 16-bit, stereo. */
     54 #define	VAC_RATE	48000
     55 #define	VAC_CHANNELS	2
     56 #define	VAC_PRECISION	16
     57 #define	VAC_FRAMESIZE	(VAC_CHANNELS * (VAC_PRECISION / 8))	/* 4 bytes */
     58 
     59 /* poll when waiting on the codec */
     60 #define	VAC_CODEC_TIMEOUT	1000
     61 
     62 /*
     63  * 8051 polled protocol, via 4KB dual-port SRAM
     64  *
     65  * Two PCM buffers selected by command parity
     66  */
     67 #define	VAC_DP_BASE		SM502_uC_SRAM_DUALPORT
     68 #define	VAC_DP_H_CMD		0x00	/* u8  host: command sequence */
     69 #define	VAC_DP_H_DONE		0x01	/* u8  8051: last finished command */
     70 #define	VAC_DP_H_ALIVE		0x03	/* u8  8051: VAC_DP_ALIVE_MAGIC when up */
     71 #define	VAC_DP_H_FC0L		0x04	/* u16 host: buf0 frame count, LE */
     72 #define	VAC_DP_H_FC0H		0x05
     73 #define	VAC_DP_H_FC1L		0x06	/* u16 host: buf1 frame count, LE */
     74 #define	VAC_DP_H_FC1H		0x07
     75 #define	VAC_DP_BUF0		0x10
     76 #define	VAC_DP_MAXFRAMES	504	/* per buffer; 504*4=0x7e0, both fit 4KB */
     77 #define	VAC_DP_BUFBYTES		(VAC_DP_MAXFRAMES * VAC_FRAMESIZE)
     78 #define	VAC_DP_BUF1		(VAC_DP_BUF0 + VAC_DP_BUFBYTES)	/* 0x7f0 */
     79 #define	VAC_DP_ALIVE_MAGIC	0x51
     80 
     81 struct vac_softc {
     82 	device_t		sc_dev;
     83 	bus_space_tag_t		sc_memt;
     84 	bus_space_handle_t	sc_regh;	/* BAR 0x14: MMIO registers */
     85 	void			*sc_parent;	/* voyager softc, for gpio/power */
     86 
     87 	kmutex_t		sc_lock;	/* thread context */
     88 	kmutex_t		sc_intr_lock;	/* "interrupt" context */
     89 
     90 	struct ac97_host_if	sc_ac97_host;
     91 	struct ac97_codec_if	*sc_ac97_codec;
     92 	device_t		sc_audiodev;
     93 
     94 	/* MI playback ring (filled by the audio layer, consumed by the feeder) */
     95 	bool			sc_active;	/* playback in progress */
     96 	uint8_t			*sc_pstart;
     97 	uint8_t			*sc_pend;
     98 	uint8_t			*sc_pcur;
     99 	int			sc_pblksize;
    100 	void			(*sc_pint)(void *);
    101 	void			*sc_pintarg;
    102 
    103 	/* 8051 interface */
    104 	callout_t		sc_feed_ch;	/* polls H_DONE, refills buffers */
    105 	int			sc_feed_ticks;	/* callout period */
    106 	uint8_t			*sc_dpstage;	/* staging for one dual-port buf */
    107 	uint8_t			sc_cmd_seq;	/* last command we queued */
    108 	uint8_t			sc_done_seen;	/* last H_DONE we acted on */
    109 	bool			sc_8051_ok;	/* feeder firmware responded */
    110 	int			sc_underruns;	/* 8051 ran dry while playing */
    111 
    112 	struct sysctllog	*sc_sysctllog;
    113 };
    114 
    115 #define	VAC_READ(sc, reg)		\
    116 	bus_space_read_4((sc)->sc_memt, (sc)->sc_regh, (reg))
    117 #define	VAC_WRITE(sc, reg, val)		\
    118 	bus_space_write_4((sc)->sc_memt, (sc)->sc_regh, (reg), (val))
    119 #define	VAC_DP_R8(sc, off) \
    120 	bus_space_read_1((sc)->sc_memt, (sc)->sc_regh, VAC_DP_BASE + (off))
    121 #define	VAC_DP_W8(sc, off, v) \
    122 	bus_space_write_1((sc)->sc_memt, (sc)->sc_regh, VAC_DP_BASE + (off), (v))
    123 
    124 /*
    125  * Embedded 8051 firmware
    126  * assemble from vac8051.asm with naken_asm (-type bin)
    127  */
    128 static const uint8_t vac8051_fw[] = {
    129 	0x90, 0x30, 0x03, 0x74, 0x51, 0xf0, 0x90, 0x30, 0x01, 0xe4, 0xf0, 0x7f,
    130 	0x00, 0x90, 0x30, 0x00, 0xe0, 0xfe, 0x6f, 0x60, 0xf8, 0xee, 0x54, 0x01,
    131 	0x60, 0x10, 0x90, 0x30, 0x06, 0xe0, 0xfc, 0x90, 0x30, 0x07, 0xe0, 0xfd,
    132 	0x7a, 0xf0, 0x7b, 0x37, 0x80, 0x0e, 0x90, 0x30, 0x04, 0xe0, 0xfc, 0x90,
    133 	0x30, 0x05, 0xe0, 0xfd, 0x7a, 0x10, 0x7b, 0x30, 0x78, 0x00, 0x79, 0x00,
    134 	0x90, 0x91, 0x45, 0xe0, 0x54, 0x08, 0x60, 0x04, 0xd9, 0xf6, 0xd8, 0xf4,
    135 	0x8a, 0x82, 0x8b, 0x83, 0xe0, 0xf5, 0x20, 0xa3, 0xe0, 0xf5, 0x21, 0xa3,
    136 	0xe0, 0xf5, 0x24, 0xa3, 0xe0, 0xf5, 0x25, 0xa3, 0xaa, 0x82, 0xab, 0x83,
    137 	0x90, 0x91, 0x00, 0xe4, 0xf0, 0xa3, 0x74, 0x98, 0xf0, 0xe5, 0x20, 0xc4,
    138 	0xf5, 0x22, 0xe5, 0x21, 0xc4, 0xf5, 0x23, 0x90, 0x91, 0x0c, 0xe5, 0x22,
    139 	0x54, 0xf0, 0xf0, 0xa3, 0xe5, 0x22, 0x54, 0x0f, 0xf5, 0x26, 0xe5, 0x23,
    140 	0x54, 0xf0, 0x45, 0x26, 0xf0, 0xa3, 0xe5, 0x23, 0x54, 0x0f, 0xf0, 0xa3,
    141 	0xe4, 0xf0, 0xe5, 0x24, 0xc4, 0xf5, 0x22, 0xe5, 0x25, 0xc4, 0xf5, 0x23,
    142 	0x90, 0x91, 0x10, 0xe5, 0x22, 0x54, 0xf0, 0xf0, 0xa3, 0xe5, 0x22, 0x54,
    143 	0x0f, 0xf5, 0x26, 0xe5, 0x23, 0x54, 0xf0, 0x45, 0x26, 0xf0, 0xa3, 0xe5,
    144 	0x23, 0x54, 0x0f, 0xf0, 0xa3, 0xe4, 0xf0, 0xec, 0x70, 0x01, 0x1d, 0x1c,
    145 	0xec, 0x4d, 0x60, 0x03, 0x02, 0x00, 0x38, 0x90, 0x30, 0x01, 0xee, 0xf0,
    146 	0xff, 0x02, 0x00, 0x0d
    147 };
    148 
    149 static int	vac_match(device_t, cfdata_t, void *);
    150 static void	vac_attach(device_t, device_t, void *);
    151 
    152 CFATTACH_DECL_NEW(vac, sizeof(struct vac_softc),
    153     vac_match, vac_attach, NULL, NULL);
    154 
    155 static const struct audio_format vac_format = {
    156 	.mode = AUMODE_PLAY,
    157 	.encoding = AUDIO_ENCODING_SLINEAR_LE,
    158 	.validbits = VAC_PRECISION,
    159 	.precision = VAC_PRECISION,
    160 	.channels = VAC_CHANNELS,
    161 	.channel_mask = AUFMT_STEREO,
    162 	.frequency_type = 1,
    163 	.frequency = { VAC_RATE }
    164 };
    165 
    166 /*
    167  * AC'97 codec register access.
    168  */
    169 static int
    170 vac_ac97_read(void *priv, uint8_t reg, uint16_t *val)
    171 {
    172 	struct vac_softc * const sc = priv;
    173 	uint32_t addr, rx;
    174 	int i;
    175 
    176 	addr = ((uint32_t)reg << SM502_AC97_ADDR_SHIFT) & SM502_AC97_ADDR_MASK;
    177 
    178 	/* Mark frame + slot 1 valid and issue a read of the register. */
    179 	VAC_WRITE(sc, SM502_AC97_TX_TAG,
    180 	    SM502_AC97_FRAME_VALID | SM502_AC97_S1_VALID);
    181 	VAC_WRITE(sc, SM502_AC97_TX_ADDR, addr | SM502_AC97_READ);
    182 
    183 	/* Wait for the codec to echo the register index back in RX slot 1. */
    184 	for (i = 0; i < VAC_CODEC_TIMEOUT; i++) {
    185 		rx = VAC_READ(sc, SM502_AC97_RX_ADDR);
    186 		if ((rx & SM502_AC97_ADDR_MASK) == addr)
    187 			break;
    188 		DELAY(1);
    189 	}
    190 	if (i == VAC_CODEC_TIMEOUT)
    191 		return 1;
    192 
    193 	*val = (VAC_READ(sc, SM502_AC97_RX_DATA) & SM502_AC97_DATA_MASK) >> 4;
    194 	return 0;
    195 }
    196 
    197 static int
    198 vac_ac97_write(void *priv, uint8_t reg, uint16_t val)
    199 {
    200 	struct vac_softc * const sc = priv;
    201 	uint32_t addr;
    202 
    203 	addr = ((uint32_t)reg << SM502_AC97_ADDR_SHIFT) & SM502_AC97_ADDR_MASK;
    204 
    205 	/* Mark frame + slots 1 (address) and 2 (data) valid. */
    206 	VAC_WRITE(sc, SM502_AC97_TX_TAG,
    207 	    SM502_AC97_FRAME_VALID | SM502_AC97_S1_VALID | SM502_AC97_S2_VALID);
    208 	VAC_WRITE(sc, SM502_AC97_TX_DATA,
    209 	    ((uint32_t)val << 4) & SM502_AC97_DATA_MASK);
    210 	VAC_WRITE(sc, SM502_AC97_TX_ADDR, addr);
    211 
    212 	DELAY(100);
    213 	return 0;
    214 }
    215 
    216 static int
    217 vac_ac97_reset(void *priv)
    218 {
    219 	struct vac_softc * const sc = priv;
    220 	uint32_t reg;
    221 	int i;
    222 
    223 	aprint_debug_dev(sc->sc_dev, "ac97 control at reset entry 0x%08x\n",
    224 	    VAC_READ(sc, SM502_AC97_CONTROL));
    225 
    226 	/*
    227 	 * Cold reset the codec with the controller enabled: assert RESET#
    228 	 * (COLD_RESET) for well over the 1us minimum, then release it.
    229 	 */
    230 	VAC_WRITE(sc, SM502_AC97_CONTROL,
    231 	    SM502_AC97_ENABLE | SM502_AC97_COLD_RESET);
    232 	DELAY(20);
    233 	VAC_WRITE(sc, SM502_AC97_CONTROL, SM502_AC97_ENABLE);
    234 
    235 	/*
    236 	 * Wait (up to ~250ms) for the codec to start the bit clock and the
    237 	 * link to reach the active state.
    238 	 */
    239 	for (i = 0; i < 2500; i++) {
    240 		reg = VAC_READ(sc, SM502_AC97_CONTROL);
    241 		if ((reg & SM502_AC97_BCLK_RUNNING) != 0 &&
    242 		    (reg & SM502_AC97_STATUS_MASK) == SM502_AC97_STATUS_ON) {
    243 			aprint_debug_dev(sc->sc_dev,
    244 			    "AC-link up (control 0x%08x)\n", reg);
    245 			return 0;
    246 		}
    247 		DELAY(100);
    248 	}
    249 
    250 	aprint_error_dev(sc->sc_dev,
    251 	    "AC-link did not come ready (control 0x%08x)\n", reg);
    252 	return 1;
    253 }
    254 
    255 static int
    256 vac_ac97_attach(void *priv, struct ac97_codec_if *codec)
    257 {
    258 	struct vac_softc * const sc = priv;
    259 
    260 	sc->sc_ac97_codec = codec;
    261 	return 0;
    262 }
    263 
    264 static void
    265 vac_unmute(struct vac_softc *sc)
    266 {
    267 	struct ac97_codec_if * const codec = sc->sc_ac97_codec;
    268 	static const struct {
    269 		const char *class;
    270 		const char *device;
    271 	} ports[] = {
    272 		{ AudioCoutputs, AudioNmaster },
    273 		{ AudioCinputs,  AudioNdac },
    274 	};
    275 	mixer_ctrl_t mc;
    276 	int i, idx;
    277 
    278 	mutex_enter(&sc->sc_lock);
    279 	for (i = 0; i < (int)__arraycount(ports); i++) {
    280 		idx = codec->vtbl->get_portnum_by_name(codec,
    281 		    ports[i].class, ports[i].device, NULL);
    282 		if (idx >= 0) {
    283 			memset(&mc, 0, sizeof(mc));
    284 			mc.dev = idx;
    285 			mc.type = AUDIO_MIXER_VALUE;
    286 			mc.un.value.num_channels = 2;
    287 			mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 200;
    288 			mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 200;
    289 			(void)codec->vtbl->mixer_set_port(codec, &mc);
    290 		}
    291 		idx = codec->vtbl->get_portnum_by_name(codec,
    292 		    ports[i].class, ports[i].device, AudioNmute);
    293 		if (idx >= 0) {
    294 			memset(&mc, 0, sizeof(mc));
    295 			mc.dev = idx;
    296 			mc.type = AUDIO_MIXER_ENUM;
    297 			mc.un.ord = 0;		/* off = not muted */
    298 			(void)codec->vtbl->mixer_set_port(codec, &mc);
    299 		}
    300 	}
    301 	mutex_exit(&sc->sc_lock);
    302 }
    303 
    304 /*
    305  * MI audio interface.
    306  */
    307 
    308 static int
    309 vac_query_format(void *priv, audio_format_query_t *afp)
    310 {
    311 
    312 	return audio_query_format(&vac_format, 1, afp);
    313 }
    314 
    315 static int
    316 vac_set_format(void *priv, int setmode,
    317     const audio_params_t *play, const audio_params_t *rec,
    318     audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
    319 {
    320 
    321 	/* Only one format; nothing to do. */
    322 	return 0;
    323 }
    324 
    325 static int
    326 vac_getdev(void *priv, struct audio_device *ad)
    327 {
    328 
    329 	snprintf(ad->name, sizeof(ad->name), "SM502");
    330 	snprintf(ad->version, sizeof(ad->version), "AC97");
    331 	snprintf(ad->config, sizeof(ad->config), "vac");
    332 	return 0;
    333 }
    334 
    335 static int
    336 vac_set_port(void *priv, mixer_ctrl_t *mc)
    337 {
    338 	struct vac_softc * const sc = priv;
    339 
    340 	return sc->sc_ac97_codec->vtbl->mixer_set_port(sc->sc_ac97_codec, mc);
    341 }
    342 
    343 static int
    344 vac_get_port(void *priv, mixer_ctrl_t *mc)
    345 {
    346 	struct vac_softc * const sc = priv;
    347 
    348 	return sc->sc_ac97_codec->vtbl->mixer_get_port(sc->sc_ac97_codec, mc);
    349 }
    350 
    351 static int
    352 vac_query_devinfo(void *priv, mixer_devinfo_t *di)
    353 {
    354 	struct vac_softc * const sc = priv;
    355 
    356 	return sc->sc_ac97_codec->vtbl->query_devinfo(sc->sc_ac97_codec, di);
    357 }
    358 
    359 static int
    360 vac_get_props(void *priv)
    361 {
    362 
    363 	return AUDIO_PROP_PLAYBACK;
    364 }
    365 
    366 static int
    367 vac_round_blocksize(void *priv, int blk, int mode,
    368     const audio_params_t *param)
    369 {
    370 
    371 	/*
    372 	 * Play one MI block per dual-port buffer
    373 	 */
    374 	if (blk > VAC_DP_BUFBYTES)
    375 		blk = VAC_DP_BUFBYTES;
    376 	blk &= ~(VAC_FRAMESIZE - 1);
    377 	if (blk < VAC_FRAMESIZE)
    378 		blk = VAC_FRAMESIZE;
    379 	return blk;
    380 }
    381 
    382 /*
    383  * Queue one block from the MI ring
    384  */
    385 static void
    386 vac_dp_queue(struct vac_softc *sc)
    387 {
    388 	const uint8_t cmd = sc->sc_cmd_seq + 1;
    389 	uint8_t *p = sc->sc_pcur;
    390 	bus_size_t base;
    391 	int n, i;
    392 
    393 	n = sc->sc_pblksize / VAC_FRAMESIZE;
    394 	if (n > VAC_DP_MAXFRAMES)
    395 		n = VAC_DP_MAXFRAMES;
    396 
    397 	/* Copy PCM into the staging buffer (raw 16-bit LE), handling wrap. */
    398 	for (i = 0; i < n; i++) {
    399 		uint8_t * const d = sc->sc_dpstage + i * VAC_FRAMESIZE;
    400 
    401 		d[0] = p[0];	/* left low */
    402 		d[1] = p[1];	/* left high */
    403 		d[2] = p[2];	/* right low */
    404 		d[3] = p[3];	/* right high */
    405 		p += VAC_FRAMESIZE;
    406 		if (p >= sc->sc_pend)
    407 			p = sc->sc_pstart;
    408 	}
    409 	sc->sc_pcur = p;
    410 
    411 	base = VAC_DP_BASE + ((cmd & 1) ? VAC_DP_BUF1 : VAC_DP_BUF0);
    412 	bus_space_write_region_1(sc->sc_memt, sc->sc_regh, base,
    413 	    sc->sc_dpstage, n * VAC_FRAMESIZE);
    414 
    415 	if (cmd & 1) {
    416 		VAC_DP_W8(sc, VAC_DP_H_FC1L, n & 0xff);
    417 		VAC_DP_W8(sc, VAC_DP_H_FC1H, (n >> 8) & 0xff);
    418 	} else {
    419 		VAC_DP_W8(sc, VAC_DP_H_FC0L, n & 0xff);
    420 		VAC_DP_W8(sc, VAC_DP_H_FC0H, (n >> 8) & 0xff);
    421 	}
    422 
    423 	/* The data and count must be visible before the command bump. */
    424 	bus_space_barrier(sc->sc_memt, sc->sc_regh, VAC_DP_BASE, 0x1000,
    425 	    BUS_SPACE_BARRIER_WRITE);
    426 	VAC_DP_W8(sc, VAC_DP_H_CMD, cmd);
    427 	sc->sc_cmd_seq = cmd;
    428 }
    429 
    430 /*
    431  * Poll the 8051's done counter
    432  */
    433 static void
    434 vac_feed_callout(void *arg)
    435 {
    436 	struct vac_softc * const sc = arg;
    437 	uint8_t done;
    438 	int n;
    439 
    440 	mutex_enter(&sc->sc_intr_lock);
    441 	if (!sc->sc_active) {
    442 		mutex_exit(&sc->sc_intr_lock);
    443 		return;
    444 	}
    445 
    446 	done = VAC_DP_R8(sc, VAC_DP_H_DONE);
    447 	if (sc->sc_cmd_seq == done)
    448 		sc->sc_underruns++;	/* 8051 caught up: nothing queued */
    449 
    450 	n = (uint8_t)(done - sc->sc_done_seen);
    451 	sc->sc_done_seen = done;
    452 	while (n-- > 0 && sc->sc_active && sc->sc_pint != NULL)
    453 		sc->sc_pint(sc->sc_pintarg);
    454 
    455 	while ((uint8_t)(sc->sc_cmd_seq - done) <= 1 && sc->sc_active)
    456 		vac_dp_queue(sc);
    457 
    458 	callout_schedule(&sc->sc_feed_ch, sc->sc_feed_ticks);
    459 	mutex_exit(&sc->sc_intr_lock);
    460 }
    461 
    462 static int
    463 vac_trigger_output(void *priv, void *start, void *end, int blksize,
    464     void (*intr)(void *), void *intrarg, const audio_params_t *params)
    465 {
    466 	struct vac_softc * const sc = priv;
    467 	int i;
    468 
    469 	/*
    470 	 * audio calls trigger_output with both sc_lock and sc_intr_lock held
    471 	 */
    472 	KASSERT(mutex_owned(&sc->sc_intr_lock));
    473 	KASSERT(mutex_owned(&sc->sc_lock));
    474 
    475 	if (!sc->sc_8051_ok)
    476 		return ENXIO;
    477 
    478 	/*
    479 	 * Restart the 8051 cleanly for this playback
    480 	 */
    481 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    482 	for (i = 0; i < 16; i++)
    483 		VAC_DP_W8(sc, i, 0);
    484 	VAC_WRITE(sc, SM502_uC_RESET, SM502_uC_ENABLE);
    485 	for (i = 0; i < 5000 &&
    486 	    VAC_DP_R8(sc, VAC_DP_H_ALIVE) != VAC_DP_ALIVE_MAGIC; i++)
    487 		DELAY(10);
    488 
    489 	sc->sc_pstart = start;
    490 	sc->sc_pend = end;
    491 	sc->sc_pcur = start;
    492 	sc->sc_pblksize = blksize;
    493 	sc->sc_pint = intr;
    494 	sc->sc_pintarg = intrarg;
    495 
    496 	sc->sc_cmd_seq = 0;
    497 	sc->sc_done_seen = 0;
    498 	sc->sc_underruns = 0;
    499 	sc->sc_active = true;
    500 
    501 	/* Prime both buffers, then poll for completion from the callout. */
    502 	vac_dp_queue(sc);
    503 	vac_dp_queue(sc);
    504 	callout_schedule(&sc->sc_feed_ch, sc->sc_feed_ticks);
    505 
    506 	return 0;
    507 }
    508 
    509 static int
    510 vac_halt_output(void *priv)
    511 {
    512 	struct vac_softc * const sc = priv;
    513 
    514 	/*
    515 	 * called with both sc_lock and sc_intr_lock held
    516 	 */
    517 	KASSERT(mutex_owned(&sc->sc_intr_lock));
    518 
    519 	sc->sc_active = false;
    520 	sc->sc_pint = NULL;
    521 	callout_stop(&sc->sc_feed_ch);
    522 
    523 	/* Park the 8051 so the host codec/mixer path is live while idle. */
    524 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    525 	return 0;
    526 }
    527 
    528 static void
    529 vac_get_locks(void *priv, kmutex_t **intr, kmutex_t **thread)
    530 {
    531 	struct vac_softc * const sc = priv;
    532 
    533 	*intr = &sc->sc_intr_lock;
    534 	*thread = &sc->sc_lock;
    535 }
    536 
    537 static const struct audio_hw_if vac_hw_if = {
    538 	.query_format = vac_query_format,
    539 	.set_format = vac_set_format,
    540 	.getdev = vac_getdev,
    541 	.set_port = vac_set_port,
    542 	.get_port = vac_get_port,
    543 	.query_devinfo = vac_query_devinfo,
    544 	.get_props = vac_get_props,
    545 	.round_blocksize = vac_round_blocksize,
    546 	.trigger_output = vac_trigger_output,
    547 	.halt_output = vac_halt_output,
    548 	.get_locks = vac_get_locks,
    549 };
    550 
    551 /* Load the firmware blob as 32-bit LE words at (h, base). */
    552 static void
    553 vac_load_fw(struct vac_softc *sc, bus_space_handle_t h, bus_size_t base)
    554 {
    555 	size_t i;
    556 
    557 	for (i = 0; i < sizeof(vac8051_fw); i += 4) {
    558 		uint8_t b0 = vac8051_fw[i];
    559 		uint8_t b1 = (i + 1 < sizeof(vac8051_fw)) ? vac8051_fw[i + 1] : 0;
    560 		uint8_t b2 = (i + 2 < sizeof(vac8051_fw)) ? vac8051_fw[i + 2] : 0;
    561 		uint8_t b3 = (i + 3 < sizeof(vac8051_fw)) ? vac8051_fw[i + 3] : 0;
    562 
    563 		bus_space_write_4(sc->sc_memt, h, base + i,
    564 		    b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
    565 	}
    566 }
    567 
    568 static void
    569 vac_8051_bringup(struct vac_softc *sc)
    570 {
    571 	uint32_t v;
    572 	uint8_t alive;
    573 	int i;
    574 
    575 	/* Hold the 8051 in reset... mode = SRAM on, AC97, fastest clock (div2). */
    576 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    577 	v = VAC_READ(sc, SM502_uC_MODE_SELECT);
    578 	v &= ~(SM502_uC_SRAM_DISABLE | SM502_uC_CODEC_I2S | SM502_uC_CLOCK_MASK);
    579 	VAC_WRITE(sc, SM502_uC_MODE_SELECT, v);
    580 
    581 	/* Load the feeder into the program SRAM (host R/W only while in reset). */
    582 	vac_load_fw(sc, sc->sc_regh, SM502_uC_SRAM_PROG);
    583 
    584 	/* Clear the dual-port protocol header before the 8051 starts. */
    585 	for (i = 0; i < 16; i++)
    586 		VAC_DP_W8(sc, i, 0);
    587 
    588 	/* Release the 8051 and give it time to post its alive marker. */
    589 	VAC_WRITE(sc, SM502_uC_RESET, SM502_uC_ENABLE);
    590 	DELAY(2000);
    591 
    592 	alive = VAC_DP_R8(sc, VAC_DP_H_ALIVE);
    593 	sc->sc_8051_ok = (alive == VAC_DP_ALIVE_MAGIC);
    594 	aprint_verbose_dev(sc->sc_dev, "8051 feeder %s (alive=0x%02x)\n",
    595 	    sc->sc_8051_ok ? "loaded" : "not responding", alive);
    596 	if (!sc->sc_8051_ok)
    597 		aprint_error_dev(sc->sc_dev,
    598 		    "8051 feeder did not start; playback unavailable\n");
    599 
    600 	/* Park the 8051 while idle (keeps the host codec/mixer path live). */
    601 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    602 }
    603 
    604 #ifdef VAC_DEBUG
    605 /*
    606  * Diagnostics: dump the AC97 link control + key codec registers (read while the
    607  * 8051 is idle; codec access is dead while it runs).
    608  */
    609 static int
    610 vac_sysctl_diag(SYSCTLFN_ARGS)
    611 {
    612 	struct sysctlnode node = *rnode;
    613 	struct vac_softc * const sc = node.sysctl_data;
    614 	uint16_t r02 = 0, r04 = 0, r18 = 0, r26 = 0, r2a = 0, r2c = 0, r7a = 0;
    615 	char buf[200];
    616 
    617 	vac_ac97_read(sc, 0x02, &r02);	/* master volume */
    618 	vac_ac97_read(sc, 0x04, &r04);	/* aux/headphone volume */
    619 	vac_ac97_read(sc, 0x18, &r18);	/* PCM out volume */
    620 	vac_ac97_read(sc, 0x26, &r26);	/* powerdown ctrl/status */
    621 	vac_ac97_read(sc, 0x2a, &r2a);	/* extended audio ctrl (VRA) */
    622 	vac_ac97_read(sc, 0x2c, &r2c);	/* PCM front DAC rate */
    623 	vac_ac97_read(sc, 0x7a, &r7a);	/* ALC655 vendor (EAPD etc.) */
    624 
    625 	snprintf(buf, sizeof(buf),
    626 	    "acctl=%08x mode=%08x reset=%08x | "
    627 	    "m02=%04x hp04=%04x pcm18=%04x pwr26=%04x ext2a=%04x rate2c=%04x ven7a=%04x",
    628 	    VAC_READ(sc, SM502_AC97_CONTROL),
    629 	    VAC_READ(sc, SM502_uC_MODE_SELECT),
    630 	    VAC_READ(sc, SM502_uC_RESET),
    631 	    r02, r04, r18, r26, r2a, r2c, r7a);
    632 	node.sysctl_data = buf;
    633 	node.sysctl_size = strlen(buf) + 1;
    634 	return sysctl_lookup(SYSCTLFN_CALL(&node));
    635 }
    636 #endif /* VAC_DEBUG */
    637 
    638 static void
    639 vac_sysctl_setup(struct vac_softc *sc)
    640 {
    641 	const struct sysctlnode *node = NULL;
    642 
    643 	if (sysctl_createv(&sc->sc_sysctllog, 0, NULL, &node,
    644 	    0, CTLTYPE_NODE, "vac", SYSCTL_DESCR("SM502 AC97-link audio"),
    645 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL) != 0 || node == NULL)
    646 		return;
    647 
    648 	sysctl_createv(&sc->sc_sysctllog, 0, NULL, NULL,
    649 	    CTLFLAG_READONLY, CTLTYPE_INT, "underruns",
    650 	    SYSCTL_DESCR("times the 8051 ran dry during the last playback"),
    651 	    NULL, 0, &sc->sc_underruns, 0, CTL_HW, node->sysctl_num,
    652 	    CTL_CREATE, CTL_EOL);
    653 #ifdef VAC_DEBUG
    654 	sysctl_createv(&sc->sc_sysctllog, 0, NULL, NULL,
    655 	    CTLFLAG_READONLY, CTLTYPE_STRING, "diag",
    656 	    SYSCTL_DESCR("AC97 link + codec register dump (read while idle)"),
    657 	    vac_sysctl_diag, 0, (void *)sc, 0, CTL_HW, node->sysctl_num,
    658 	    CTL_CREATE, CTL_EOL);
    659 #endif
    660 }
    661 
    662 static int
    663 vac_match(device_t parent, cfdata_t match, void *aux)
    664 {
    665 	struct voyager_attach_args *vaa = aux;
    666 
    667 	if (strcmp(vaa->vaa_name, "vac") == 0)
    668 		return 100;
    669 	return 0;
    670 }
    671 
    672 static void
    673 vac_attach(device_t parent, device_t self, void *aux)
    674 {
    675 	struct vac_softc * const sc = device_private(self);
    676 	struct voyager_attach_args *vaa = aux;
    677 	int error;
    678 
    679 	sc->sc_dev = self;
    680 	sc->sc_memt = vaa->vaa_tag;
    681 	sc->sc_regh = vaa->vaa_regh;
    682 	sc->sc_parent = device_private(parent);
    683 
    684 	aprint_naive("\n");
    685 	aprint_normal(": SM502 AC97-link\n");
    686 
    687 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    688 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
    689 
    690 	callout_init(&sc->sc_feed_ch, CALLOUT_MPSAFE);
    691 	callout_setfunc(&sc->sc_feed_ch, vac_feed_callout, sc);
    692 	sc->sc_feed_ticks = mstohz(5);
    693 	if (sc->sc_feed_ticks < 1)
    694 		sc->sc_feed_ticks = 1;
    695 	sc->sc_dpstage = kmem_alloc(VAC_DP_BUFBYTES, KM_SLEEP);
    696 
    697 	aprint_debug_dev(self,
    698 	    "power: ctrl 0x%08x cur-gate 0x%08x gate0 0x%08x gate1 0x%08x\n",
    699 	    VAC_READ(sc, SM502_POWER_MODE_CONTROL),
    700 	    VAC_READ(sc, SM502_CURRENT_GATE),
    701 	    VAC_READ(sc, SM502_POWER_MODE0_GATE),
    702 	    VAC_READ(sc, SM502_POWER_MODE1_GATE));
    703 
    704 	VAC_WRITE(sc, SM502_POWER_MODE0_GATE,
    705 	    VAC_READ(sc, SM502_POWER_MODE0_GATE) |
    706 	    SM502_GATE_AUDIO_ENABLE | SM502_GATE_8051_ENABLE);
    707 	VAC_WRITE(sc, SM502_POWER_MODE1_GATE,
    708 	    VAC_READ(sc, SM502_POWER_MODE1_GATE) |
    709 	    SM502_GATE_AUDIO_ENABLE | SM502_GATE_8051_ENABLE);
    710 	DELAY(1000);
    711 
    712 	/* Route the shared audio pins to the AC97-link (not GPIO). */
    713 	voyager_control_gpio(sc->sc_parent, 0xffffffff, SM502_AUDIO_GPIO_MASK);
    714 
    715 	/* Select AC97 mode for the link (CODEC_I2S clear). */
    716 	VAC_WRITE(sc, SM502_uC_MODE_SELECT,
    717 	    VAC_READ(sc, SM502_uC_MODE_SELECT) & ~SM502_uC_CODEC_I2S);
    718 
    719 	sc->sc_ac97_host.arg = sc;
    720 	sc->sc_ac97_host.attach = vac_ac97_attach;
    721 	sc->sc_ac97_host.read = vac_ac97_read;
    722 	sc->sc_ac97_host.write = vac_ac97_write;
    723 	sc->sc_ac97_host.reset = vac_ac97_reset;
    724 
    725 	error = ac97_attach(&sc->sc_ac97_host, self, &sc->sc_lock);
    726 	if (error) {
    727 		aprint_error_dev(self, "couldn't attach codec (%d)\n", error);
    728 		return;
    729 	}
    730 
    731 	vac_sysctl_setup(sc);
    732 
    733 	/* Load the 8051 binary. */
    734 	vac_8051_bringup(sc);
    735 
    736 	sc->sc_audiodev = audio_attach_mi(&vac_hw_if, sc, self);
    737 
    738 	/* Unmute master + DAC now that the codec/mixer stack is up (8051 idle). */
    739 	vac_unmute(sc);
    740 }
    741