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