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