Home | History | Annotate | Line # | Download | only in voyager
vac.c revision 1.1
      1 /* $NetBSD: vac.c,v 1.1 2026/06/18 00:44:21 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.1 2026/06/18 00:44:21 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 	if (!sc->sc_8051_ok)
    470 		return ENXIO;
    471 
    472 	/*
    473 	 * Restart the 8051 cleanly for this playback
    474 	 */
    475 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    476 	for (i = 0; i < 16; i++)
    477 		VAC_DP_W8(sc, i, 0);
    478 	VAC_WRITE(sc, SM502_uC_RESET, SM502_uC_ENABLE);
    479 	for (i = 0; i < 5000 &&
    480 	    VAC_DP_R8(sc, VAC_DP_H_ALIVE) != VAC_DP_ALIVE_MAGIC; i++)
    481 		DELAY(10);
    482 
    483 	mutex_enter(&sc->sc_intr_lock);
    484 	sc->sc_pstart = start;
    485 	sc->sc_pend = end;
    486 	sc->sc_pcur = start;
    487 	sc->sc_pblksize = blksize;
    488 	sc->sc_pint = intr;
    489 	sc->sc_pintarg = intrarg;
    490 
    491 	sc->sc_cmd_seq = 0;
    492 	sc->sc_done_seen = 0;
    493 	sc->sc_underruns = 0;
    494 	sc->sc_active = true;
    495 
    496 	/* Prime both buffers, then poll for completion from the callout. */
    497 	vac_dp_queue(sc);
    498 	vac_dp_queue(sc);
    499 	callout_schedule(&sc->sc_feed_ch, sc->sc_feed_ticks);
    500 	mutex_exit(&sc->sc_intr_lock);
    501 
    502 	return 0;
    503 }
    504 
    505 static int
    506 vac_halt_output(void *priv)
    507 {
    508 	struct vac_softc * const sc = priv;
    509 
    510 	mutex_enter(&sc->sc_intr_lock);
    511 	sc->sc_active = false;
    512 	sc->sc_pint = NULL;
    513 	mutex_exit(&sc->sc_intr_lock);
    514 
    515 	callout_halt(&sc->sc_feed_ch, NULL);
    516 
    517 	/* Park the 8051 so the host codec/mixer path is live while idle. */
    518 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    519 	return 0;
    520 }
    521 
    522 static void
    523 vac_get_locks(void *priv, kmutex_t **intr, kmutex_t **thread)
    524 {
    525 	struct vac_softc * const sc = priv;
    526 
    527 	*intr = &sc->sc_intr_lock;
    528 	*thread = &sc->sc_lock;
    529 }
    530 
    531 static const struct audio_hw_if vac_hw_if = {
    532 	.query_format = vac_query_format,
    533 	.set_format = vac_set_format,
    534 	.getdev = vac_getdev,
    535 	.set_port = vac_set_port,
    536 	.get_port = vac_get_port,
    537 	.query_devinfo = vac_query_devinfo,
    538 	.get_props = vac_get_props,
    539 	.round_blocksize = vac_round_blocksize,
    540 	.trigger_output = vac_trigger_output,
    541 	.halt_output = vac_halt_output,
    542 	.get_locks = vac_get_locks,
    543 };
    544 
    545 /* Load the firmware blob as 32-bit LE words at (h, base). */
    546 static void
    547 vac_load_fw(struct vac_softc *sc, bus_space_handle_t h, bus_size_t base)
    548 {
    549 	size_t i;
    550 
    551 	for (i = 0; i < sizeof(vac8051_fw); i += 4) {
    552 		uint8_t b0 = vac8051_fw[i];
    553 		uint8_t b1 = (i + 1 < sizeof(vac8051_fw)) ? vac8051_fw[i + 1] : 0;
    554 		uint8_t b2 = (i + 2 < sizeof(vac8051_fw)) ? vac8051_fw[i + 2] : 0;
    555 		uint8_t b3 = (i + 3 < sizeof(vac8051_fw)) ? vac8051_fw[i + 3] : 0;
    556 
    557 		bus_space_write_4(sc->sc_memt, h, base + i,
    558 		    b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
    559 	}
    560 }
    561 
    562 static void
    563 vac_8051_bringup(struct vac_softc *sc)
    564 {
    565 	uint32_t v;
    566 	uint8_t alive;
    567 	int i;
    568 
    569 	/* Hold the 8051 in reset... mode = SRAM on, AC97, fastest clock (div2). */
    570 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    571 	v = VAC_READ(sc, SM502_uC_MODE_SELECT);
    572 	v &= ~(SM502_uC_SRAM_DISABLE | SM502_uC_CODEC_I2S | SM502_uC_CLOCK_MASK);
    573 	VAC_WRITE(sc, SM502_uC_MODE_SELECT, v);
    574 
    575 	/* Load the feeder into the program SRAM (host R/W only while in reset). */
    576 	vac_load_fw(sc, sc->sc_regh, SM502_uC_SRAM_PROG);
    577 
    578 	/* Clear the dual-port protocol header before the 8051 starts. */
    579 	for (i = 0; i < 16; i++)
    580 		VAC_DP_W8(sc, i, 0);
    581 
    582 	/* Release the 8051 and give it time to post its alive marker. */
    583 	VAC_WRITE(sc, SM502_uC_RESET, SM502_uC_ENABLE);
    584 	DELAY(2000);
    585 
    586 	alive = VAC_DP_R8(sc, VAC_DP_H_ALIVE);
    587 	sc->sc_8051_ok = (alive == VAC_DP_ALIVE_MAGIC);
    588 	aprint_verbose_dev(sc->sc_dev, "8051 feeder %s (alive=0x%02x)\n",
    589 	    sc->sc_8051_ok ? "loaded" : "not responding", alive);
    590 	if (!sc->sc_8051_ok)
    591 		aprint_error_dev(sc->sc_dev,
    592 		    "8051 feeder did not start; playback unavailable\n");
    593 
    594 	/* Park the 8051 while idle (keeps the host codec/mixer path live). */
    595 	VAC_WRITE(sc, SM502_uC_RESET, 0);
    596 }
    597 
    598 #ifdef VAC_DEBUG
    599 /*
    600  * Diagnostics: dump the AC97 link control + key codec registers (read while the
    601  * 8051 is idle; codec access is dead while it runs).
    602  */
    603 static int
    604 vac_sysctl_diag(SYSCTLFN_ARGS)
    605 {
    606 	struct sysctlnode node = *rnode;
    607 	struct vac_softc * const sc = node.sysctl_data;
    608 	uint16_t r02 = 0, r04 = 0, r18 = 0, r26 = 0, r2a = 0, r2c = 0, r7a = 0;
    609 	char buf[200];
    610 
    611 	vac_ac97_read(sc, 0x02, &r02);	/* master volume */
    612 	vac_ac97_read(sc, 0x04, &r04);	/* aux/headphone volume */
    613 	vac_ac97_read(sc, 0x18, &r18);	/* PCM out volume */
    614 	vac_ac97_read(sc, 0x26, &r26);	/* powerdown ctrl/status */
    615 	vac_ac97_read(sc, 0x2a, &r2a);	/* extended audio ctrl (VRA) */
    616 	vac_ac97_read(sc, 0x2c, &r2c);	/* PCM front DAC rate */
    617 	vac_ac97_read(sc, 0x7a, &r7a);	/* ALC655 vendor (EAPD etc.) */
    618 
    619 	snprintf(buf, sizeof(buf),
    620 	    "acctl=%08x mode=%08x reset=%08x | "
    621 	    "m02=%04x hp04=%04x pcm18=%04x pwr26=%04x ext2a=%04x rate2c=%04x ven7a=%04x",
    622 	    VAC_READ(sc, SM502_AC97_CONTROL),
    623 	    VAC_READ(sc, SM502_uC_MODE_SELECT),
    624 	    VAC_READ(sc, SM502_uC_RESET),
    625 	    r02, r04, r18, r26, r2a, r2c, r7a);
    626 	node.sysctl_data = buf;
    627 	node.sysctl_size = strlen(buf) + 1;
    628 	return sysctl_lookup(SYSCTLFN_CALL(&node));
    629 }
    630 #endif /* VAC_DEBUG */
    631 
    632 static void
    633 vac_sysctl_setup(struct vac_softc *sc)
    634 {
    635 	const struct sysctlnode *node = NULL;
    636 
    637 	if (sysctl_createv(&sc->sc_sysctllog, 0, NULL, &node,
    638 	    0, CTLTYPE_NODE, "vac", SYSCTL_DESCR("SM502 AC97-link audio"),
    639 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL) != 0 || node == NULL)
    640 		return;
    641 
    642 	sysctl_createv(&sc->sc_sysctllog, 0, NULL, NULL,
    643 	    CTLFLAG_READONLY, CTLTYPE_INT, "underruns",
    644 	    SYSCTL_DESCR("times the 8051 ran dry during the last playback"),
    645 	    NULL, 0, &sc->sc_underruns, 0, CTL_HW, node->sysctl_num,
    646 	    CTL_CREATE, CTL_EOL);
    647 #ifdef VAC_DEBUG
    648 	sysctl_createv(&sc->sc_sysctllog, 0, NULL, NULL,
    649 	    CTLFLAG_READONLY, CTLTYPE_STRING, "diag",
    650 	    SYSCTL_DESCR("AC97 link + codec register dump (read while idle)"),
    651 	    vac_sysctl_diag, 0, (void *)sc, 0, CTL_HW, node->sysctl_num,
    652 	    CTL_CREATE, CTL_EOL);
    653 #endif
    654 }
    655 
    656 static int
    657 vac_match(device_t parent, cfdata_t match, void *aux)
    658 {
    659 	struct voyager_attach_args *vaa = aux;
    660 
    661 	if (strcmp(vaa->vaa_name, "vac") == 0)
    662 		return 100;
    663 	return 0;
    664 }
    665 
    666 static void
    667 vac_attach(device_t parent, device_t self, void *aux)
    668 {
    669 	struct vac_softc * const sc = device_private(self);
    670 	struct voyager_attach_args *vaa = aux;
    671 	int error;
    672 
    673 	sc->sc_dev = self;
    674 	sc->sc_memt = vaa->vaa_tag;
    675 	sc->sc_regh = vaa->vaa_regh;
    676 	sc->sc_parent = device_private(parent);
    677 
    678 	aprint_naive("\n");
    679 	aprint_normal(": SM502 AC97-link\n");
    680 
    681 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    682 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
    683 
    684 	callout_init(&sc->sc_feed_ch, CALLOUT_MPSAFE);
    685 	callout_setfunc(&sc->sc_feed_ch, vac_feed_callout, sc);
    686 	sc->sc_feed_ticks = mstohz(5);
    687 	if (sc->sc_feed_ticks < 1)
    688 		sc->sc_feed_ticks = 1;
    689 	sc->sc_dpstage = kmem_alloc(VAC_DP_BUFBYTES, KM_SLEEP);
    690 
    691 	aprint_debug_dev(self,
    692 	    "power: ctrl 0x%08x cur-gate 0x%08x gate0 0x%08x gate1 0x%08x\n",
    693 	    VAC_READ(sc, SM502_POWER_MODE_CONTROL),
    694 	    VAC_READ(sc, SM502_CURRENT_GATE),
    695 	    VAC_READ(sc, SM502_POWER_MODE0_GATE),
    696 	    VAC_READ(sc, SM502_POWER_MODE1_GATE));
    697 
    698 	VAC_WRITE(sc, SM502_POWER_MODE0_GATE,
    699 	    VAC_READ(sc, SM502_POWER_MODE0_GATE) |
    700 	    SM502_GATE_AUDIO_ENABLE | SM502_GATE_8051_ENABLE);
    701 	VAC_WRITE(sc, SM502_POWER_MODE1_GATE,
    702 	    VAC_READ(sc, SM502_POWER_MODE1_GATE) |
    703 	    SM502_GATE_AUDIO_ENABLE | SM502_GATE_8051_ENABLE);
    704 	DELAY(1000);
    705 
    706 	/* Route the shared audio pins to the AC97-link (not GPIO). */
    707 	voyager_control_gpio(sc->sc_parent, 0xffffffff, SM502_AUDIO_GPIO_MASK);
    708 
    709 	/* Select AC97 mode for the link (CODEC_I2S clear). */
    710 	VAC_WRITE(sc, SM502_uC_MODE_SELECT,
    711 	    VAC_READ(sc, SM502_uC_MODE_SELECT) & ~SM502_uC_CODEC_I2S);
    712 
    713 	sc->sc_ac97_host.arg = sc;
    714 	sc->sc_ac97_host.attach = vac_ac97_attach;
    715 	sc->sc_ac97_host.read = vac_ac97_read;
    716 	sc->sc_ac97_host.write = vac_ac97_write;
    717 	sc->sc_ac97_host.reset = vac_ac97_reset;
    718 
    719 	error = ac97_attach(&sc->sc_ac97_host, self, &sc->sc_lock);
    720 	if (error) {
    721 		aprint_error_dev(self, "couldn't attach codec (%d)\n", error);
    722 		return;
    723 	}
    724 
    725 	vac_sysctl_setup(sc);
    726 
    727 	/* Load the 8051 binary. */
    728 	vac_8051_bringup(sc);
    729 
    730 	sc->sc_audiodev = audio_attach_mi(&vac_hw_if, sc, self);
    731 
    732 	/* Unmute master + DAC now that the codec/mixer stack is up (8051 idle). */
    733 	vac_unmute(sc);
    734 }
    735