xref: /netbsd-src/sys/dev/hdaudio/hdafg.c (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1 /* $NetBSD: hdafg.c,v 1.15 2018/02/14 18:28:43 maya Exp $ */
2 
3 /*
4  * Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
5  * Copyright (c) 2009-2011 Jared D. McNeill <jmcneill@invisible.ca>
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Precedence Technologies Ltd
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * Widget parsing from FreeBSD hdac.c:
34  *
35  * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca>
36  * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org>
37  * Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org>
38  * All rights reserved.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  */
61 
62 #include <sys/cdefs.h>
63 __KERNEL_RCSID(0, "$NetBSD: hdafg.c,v 1.15 2018/02/14 18:28:43 maya Exp $");
64 
65 #include <sys/types.h>
66 #include <sys/param.h>
67 #include <sys/systm.h>
68 #include <sys/kernel.h>
69 #include <sys/device.h>
70 #include <sys/conf.h>
71 #include <sys/bus.h>
72 #include <sys/kmem.h>
73 #include <sys/module.h>
74 
75 #include <sys/audioio.h>
76 #include <dev/audio_if.h>
77 #include <dev/auconv.h>
78 
79 #ifdef _KERNEL_OPT
80 #include "opt_hdaudio.h"
81 #endif
82 
83 #include "hdaudiovar.h"
84 #include "hdaudioreg.h"
85 #include "hdaudio_mixer.h"
86 #include "hdaudioio.h"
87 #include "hdaudio_verbose.h"
88 #include "hdaudiodevs.h"
89 #include "hdafg_dd.h"
90 #include "hdmireg.h"
91 
92 #ifndef AUFMT_SURROUND_7_1
93 #define AUFMT_SURROUND_7_1 (AUFMT_DOLBY_5_1|AUFMT_SIDE_LEFT|AUFMT_SIDE_RIGHT)
94 #endif
95 
96 #if defined(HDAFG_DEBUG)
97 static int hdafg_debug = HDAFG_DEBUG;
98 #else
99 static int hdafg_debug = 0;
100 #endif
101 
102 #define hda_debug(sc, ...)		\
103 	if (hdafg_debug) hda_print(sc, __VA_ARGS__)
104 #define hda_debug1(sc, ...)		\
105 	if (hdafg_debug) hda_print1(sc, __VA_ARGS__)
106 
107 #define HDAUDIO_MIXER_CLASS_OUTPUTS	0
108 #define HDAUDIO_MIXER_CLASS_INPUTS	1
109 #define HDAUDIO_MIXER_CLASS_RECORD	2
110 #define HDAUDIO_MIXER_CLASS_LAST	HDAUDIO_MIXER_CLASS_RECORD
111 
112 #define HDAUDIO_GPIO_MASK	0
113 #define HDAUDIO_GPIO_DIR	1
114 #define HDAUDIO_GPIO_DATA	2
115 
116 #define HDAUDIO_UNSOLTAG_EVENT_HP	0x01
117 #define HDAUDIO_UNSOLTAG_EVENT_DD	0x02
118 
119 #define HDAUDIO_HP_SENSE_PERIOD		hz
120 
121 const u_int hdafg_possible_rates[] = {
122 	8000, 11025, 16000, 22050, 32000, 44100,
123 	48000, 88200, 96000, 176500, 192000, /* 384000, */
124 };
125 
126 static const char *hdafg_mixer_names[] = HDAUDIO_DEVICE_NAMES;
127 
128 static const char *hdafg_port_connectivity[] = {
129 	"Jack",
130 	"Unconnected",
131 	"Built-In",
132 	"Jack & Built-In"
133 };
134 static const char *hdafg_default_device[] = {
135 	"Line Out",
136 	"Speaker",
137 	"HP Out",
138 	"CD",
139 	"SPDIF Out",
140 	"Digital Out",
141 	"Modem Line Side",
142 	"Modem Handset Side",
143 	"Line In",
144 	"AUX",
145 	"Mic In",
146 	"Telephony",
147 	"SPDIF In",
148 	"Digital In",
149 	"Reserved",
150 	"Other"
151 };
152 static const char *hdafg_color[] = {
153 	"Unknown",
154 	"Black",
155 	"Grey",
156 	"Blue",
157 	"Green",
158 	"Red",
159 	"Orange",
160 	"Yellow",
161 	"Purple",
162 	"Pink",
163 	"ReservedA",
164 	"ReservedB",
165 	"ReservedC",
166 	"ReservedD",
167 	"White",
168 	"Other"
169 };
170 
171 #define HDAUDIO_MAXFORMATS	24
172 #define HDAUDIO_MAXCONNECTIONS	32
173 #define HDAUDIO_MAXPINS		16
174 #define HDAUDIO_PARSE_MAXDEPTH	10
175 
176 #define HDAUDIO_AMP_VOL_DEFAULT (-1)
177 #define HDAUDIO_AMP_MUTE_DEFAULT (0xffffffff)
178 #define HDAUDIO_AMP_MUTE_NONE	0
179 #define HDAUDIO_AMP_MUTE_LEFT	(1 << 0)
180 #define HDAUDIO_AMP_MUTE_RIGHT	(1 << 1)
181 #define HDAUDIO_AMP_MUTE_ALL	(HDAUDIO_AMP_MUTE_LEFT | HDAUDIO_AMP_MUTE_RIGHT)
182 #define HDAUDIO_AMP_LEFT_MUTED(x)	((x) & HDAUDIO_AMP_MUTE_LEFT)
183 #define HDAUDIO_AMP_RIGHT_MUTED(x)	(((x) & HDAUDIO_AMP_MUTE_RIGHT) >> 1)
184 
185 #define HDAUDIO_ADC_MONITOR	1
186 
187 enum hdaudio_pindir {
188 	HDAUDIO_PINDIR_NONE = 0,
189 	HDAUDIO_PINDIR_OUT = 1,
190 	HDAUDIO_PINDIR_IN = 2,
191 	HDAUDIO_PINDIR_INOUT = 3,
192 };
193 
194 #define hda_get_param(sc, cop)					\
195 	hdaudio_command((sc)->sc_codec, (sc)->sc_nid,		\
196 	  CORB_GET_PARAMETER, COP_##cop)
197 #define hda_get_wparam(w, cop)					\
198 	hdaudio_command((w)->w_afg->sc_codec, (w)->w_nid,	\
199 	  CORB_GET_PARAMETER, COP_##cop)
200 
201 struct hdaudio_assoc {
202 	bool			as_enable;
203 	bool			as_activated;
204 	u_char			as_index;
205 	enum hdaudio_pindir	as_dir;
206 	u_char			as_pincnt;
207 	u_char			as_fakeredir;
208 	int			as_digital;
209 #define HDAFG_AS_ANALOG		0
210 #define HDAFG_AS_SPDIF		1
211 #define HDAFG_AS_HDMI		2
212 #define HDAFG_AS_DISPLAYPORT	3
213 	bool			as_displaydev;
214 	int			as_hpredir;
215 	int			as_pins[HDAUDIO_MAXPINS];
216 	int			as_dacs[HDAUDIO_MAXPINS];
217 };
218 
219 struct hdaudio_widget {
220 	struct hdafg_softc	*w_afg;
221 	char				w_name[32];
222 	int				w_nid;
223 	bool				w_enable;
224 	bool				w_waspin;
225 	int				w_selconn;
226 	int				w_bindas;
227 	int				w_bindseqmask;
228 	int				w_pflags;
229 	int				w_audiodev;
230 	uint32_t			w_audiomask;
231 
232 	int				w_nconns;
233 	int				w_conns[HDAUDIO_MAXCONNECTIONS];
234 	bool				w_connsenable[HDAUDIO_MAXCONNECTIONS];
235 
236 	int				w_type;
237 	struct {
238 		uint32_t		aw_cap;
239 		uint32_t		pcm_size_rate;
240 		uint32_t		stream_format;
241 		uint32_t		outamp_cap;
242 		uint32_t		inamp_cap;
243 		uint32_t		eapdbtl;
244 	} w_p;
245 	struct {
246 		uint32_t		config;
247 		uint32_t		biosconfig;
248 		uint32_t		cap;
249 		uint32_t		ctrl;
250 	} w_pin;
251 };
252 
253 struct hdaudio_control {
254 	struct hdaudio_widget	*ctl_widget, *ctl_childwidget;
255 	bool			ctl_enable;
256 	int			ctl_index;
257 	enum hdaudio_pindir	ctl_dir, ctl_ndir;
258 	int			ctl_mute, ctl_step, ctl_size, ctl_offset;
259 	int			ctl_left, ctl_right, ctl_forcemute;
260 	uint32_t		ctl_muted;
261 	uint32_t		ctl_audiomask, ctl_paudiomask;
262 };
263 
264 #define HDAUDIO_CONTROL_GIVE(ctl)	((ctl)->ctl_step ? 1 : 0)
265 
266 struct hdaudio_mixer {
267 	struct hdaudio_control		*mx_ctl;
268 	mixer_devinfo_t			mx_di;
269 };
270 
271 struct hdaudio_audiodev {
272 	struct hdafg_softc	*ad_sc;
273 	device_t			ad_audiodev;
274 	struct audio_encoding_set	*ad_encodings;
275 	int				ad_nformats;
276 	struct audio_format		ad_formats[HDAUDIO_MAXFORMATS];
277 
278 	struct hdaudio_stream		*ad_playback;
279 	void				(*ad_playbackintr)(void *);
280 	void				*ad_playbackintrarg;
281 	int				ad_playbacknid[HDAUDIO_MAXPINS];
282 	struct hdaudio_assoc		*ad_playbackassoc;
283 	struct hdaudio_stream		*ad_capture;
284 	void				(*ad_captureintr)(void *);
285 	void				*ad_captureintrarg;
286 	int				ad_capturenid[HDAUDIO_MAXPINS];
287 	struct hdaudio_assoc		*ad_captureassoc;
288 };
289 
290 struct hdafg_softc {
291 	device_t			sc_dev;
292 	kmutex_t			sc_lock;
293 	kmutex_t			sc_intr_lock;
294 	struct hdaudio_softc		*sc_host;
295 	struct hdaudio_codec		*sc_codec;
296 	struct hdaudio_function_group	*sc_fg;
297 	int				sc_nid;
298 	uint16_t			sc_vendor, sc_product;
299 
300 	prop_array_t			sc_config;
301 
302 	int				sc_startnode, sc_endnode;
303 	int				sc_nwidgets;
304 	struct hdaudio_widget		*sc_widgets;
305 	int				sc_nassocs;
306 	struct hdaudio_assoc		*sc_assocs;
307 	int				sc_nctls;
308 	struct hdaudio_control		*sc_ctls;
309 	int				sc_nmixers;
310 	struct hdaudio_mixer		*sc_mixers;
311 	bool				sc_has_beepgen;
312 
313 	int				sc_pchan, sc_rchan;
314 	audio_params_t			sc_pparam, sc_rparam;
315 
316 	struct callout			sc_jack_callout;
317 	bool				sc_jack_polling;
318 
319 	struct {
320 		uint32_t		afg_cap;
321 		uint32_t		pcm_size_rate;
322 		uint32_t		stream_format;
323 		uint32_t		outamp_cap;
324 		uint32_t		inamp_cap;
325 		uint32_t		power_states;
326 		uint32_t		gpio_cnt;
327 	} sc_p;
328 
329 	struct hdaudio_audiodev		sc_audiodev;
330 
331 	uint16_t			sc_fixed_rate;
332 	bool				sc_disable_dip;
333 };
334 
335 static int	hdafg_match(device_t, cfdata_t, void *);
336 static void	hdafg_attach(device_t, device_t, void *);
337 static int	hdafg_detach(device_t, int);
338 static void	hdafg_childdet(device_t, device_t);
339 static bool	hdafg_suspend(device_t, const pmf_qual_t *);
340 static bool	hdafg_resume(device_t, const pmf_qual_t *);
341 
342 static int	hdafg_unsol(device_t, uint8_t);
343 static int	hdafg_widget_info(void *, prop_dictionary_t,
344 					prop_dictionary_t);
345 static int	hdafg_codec_info(void *, prop_dictionary_t,
346 				       prop_dictionary_t);
347 static void	hdafg_enable_analog_beep(struct hdafg_softc *);
348 
349 CFATTACH_DECL2_NEW(
350     hdafg,
351     sizeof(struct hdafg_softc),
352     hdafg_match,
353     hdafg_attach,
354     hdafg_detach,
355     NULL,
356     NULL,
357     hdafg_childdet
358 );
359 
360 static int	hdafg_query_encoding(void *, struct audio_encoding *);
361 static int	hdafg_set_params(void *, int, int,
362 				   audio_params_t *,
363 				   audio_params_t *,
364 				   stream_filter_list_t *,
365 				   stream_filter_list_t *);
366 static int	hdafg_round_blocksize(void *, int, int,
367 					const audio_params_t *);
368 static int	hdafg_commit_settings(void *);
369 static int	hdafg_halt_output(void *);
370 static int	hdafg_halt_input(void *);
371 static int	hdafg_set_port(void *, mixer_ctrl_t *);
372 static int	hdafg_get_port(void *, mixer_ctrl_t *);
373 static int	hdafg_query_devinfo(void *, mixer_devinfo_t *);
374 static void *	hdafg_allocm(void *, int, size_t);
375 static void	hdafg_freem(void *, void *, size_t);
376 static int	hdafg_getdev(void *, struct audio_device *);
377 static size_t	hdafg_round_buffersize(void *, int, size_t);
378 static paddr_t	hdafg_mappage(void *, void *, off_t, int);
379 static int	hdafg_get_props(void *);
380 static int	hdafg_trigger_output(void *, void *, void *, int,
381 				       void (*)(void *), void *,
382 				       const audio_params_t *);
383 static int	hdafg_trigger_input(void *, void *, void *, int,
384 				      void (*)(void *), void *,
385 				      const audio_params_t *);
386 static void	hdafg_get_locks(void *, kmutex_t **, kmutex_t **);
387 
388 static const struct audio_hw_if hdafg_hw_if = {
389 	.query_encoding		= hdafg_query_encoding,
390 	.set_params		= hdafg_set_params,
391 	.round_blocksize	= hdafg_round_blocksize,
392 	.commit_settings	= hdafg_commit_settings,
393 	.halt_output		= hdafg_halt_output,
394 	.halt_input		= hdafg_halt_input,
395 	.getdev			= hdafg_getdev,
396 	.set_port		= hdafg_set_port,
397 	.get_port		= hdafg_get_port,
398 	.query_devinfo		= hdafg_query_devinfo,
399 	.allocm			= hdafg_allocm,
400 	.freem			= hdafg_freem,
401 	.round_buffersize	= hdafg_round_buffersize,
402 	.mappage		= hdafg_mappage,
403 	.get_props		= hdafg_get_props,
404 	.trigger_output		= hdafg_trigger_output,
405 	.trigger_input		= hdafg_trigger_input,
406 	.get_locks		= hdafg_get_locks,
407 };
408 
409 static int
410 hdafg_append_formats(struct hdaudio_audiodev *ad,
411     const struct audio_format *format)
412 {
413 	if (ad->ad_nformats + 1 >= HDAUDIO_MAXFORMATS) {
414 		hda_print1(ad->ad_sc, "[ENOMEM] ");
415 		return ENOMEM;
416 	}
417 	ad->ad_formats[ad->ad_nformats++] = *format;
418 
419 	return 0;
420 }
421 
422 static struct hdaudio_widget *
423 hdafg_widget_lookup(struct hdafg_softc *sc, int nid)
424 {
425 	if (sc->sc_widgets == NULL || sc->sc_nwidgets == 0) {
426 		hda_error(sc, "lookup failed; widgets %p nwidgets %d\n",
427 		    sc->sc_widgets, sc->sc_nwidgets);
428 		return NULL;
429 	}
430 	if (nid < sc->sc_startnode || nid >= sc->sc_endnode) {
431 		hda_debug(sc, "nid %02X out of range (%02X-%02X)\n",
432 		    nid, sc->sc_startnode, sc->sc_endnode);
433 		return NULL;
434 	}
435 	return &sc->sc_widgets[nid - sc->sc_startnode];
436 }
437 
438 static struct hdaudio_control *
439 hdafg_control_lookup(struct hdafg_softc *sc, int nid,
440     enum hdaudio_pindir dir, int index, int cnt)
441 {
442 	struct hdaudio_control *ctl;
443 	int i, found = 0;
444 
445 	if (sc->sc_ctls == NULL)
446 		return NULL;
447 	for (i = 0; i < sc->sc_nctls; i++) {
448 		ctl = &sc->sc_ctls[i];
449 		if (ctl->ctl_enable == false)
450 			continue;
451 		if (ctl->ctl_widget->w_nid != nid)
452 			continue;
453 		if (dir && ctl->ctl_ndir != dir)
454 			continue;
455 		if (index >= 0 && ctl->ctl_ndir == HDAUDIO_PINDIR_IN &&
456 		    ctl->ctl_dir == ctl->ctl_ndir && ctl->ctl_index != index)
457 			continue;
458 		found++;
459 		if (found == cnt || cnt <= 0)
460 			return ctl;
461 	}
462 
463 	return NULL;
464 }
465 
466 static void
467 hdafg_widget_connection_parse(struct hdaudio_widget *w)
468 {
469 	struct hdafg_softc *sc = w->w_afg;
470 	uint32_t res;
471 	int i, j, maxconns, ents, entnum;
472 	int cnid, addcnid, prevcnid;
473 
474 	w->w_nconns = 0;
475 
476 	res = hda_get_wparam(w, CONNECTION_LIST_LENGTH);
477 	ents = COP_CONNECTION_LIST_LENGTH_LEN(res);
478 	if (ents < 1)
479 		return;
480 	if (res & COP_CONNECTION_LIST_LENGTH_LONG_FORM)
481 		entnum = 2;
482 	else
483 		entnum = 4;
484 	maxconns = (sizeof(w->w_conns) / sizeof(w->w_conns[0])) - 1;
485 	prevcnid = 0;
486 
487 #define CONN_RMASK(e)		(1 << ((32 / (e)) - 1))
488 #define CONN_NMASK(e)		(CONN_RMASK(e) - 1)
489 #define CONN_RESVAL(r, e, n)	((r) >> ((32 / (e)) * (n)))
490 #define CONN_RANGE(r, e, n)	(CONN_RESVAL(r, e, n) & CONN_RMASK(e))
491 #define CONN_CNID(r, e, n)	(CONN_RESVAL(r, e, n) & CONN_NMASK(e))
492 
493 	for (i = 0; i < ents; i += entnum) {
494 		res = hdaudio_command(sc->sc_codec, w->w_nid,
495 		    CORB_GET_CONNECTION_LIST_ENTRY, i);
496 		for (j = 0; j < entnum; j++) {
497 			cnid = CONN_CNID(res, entnum, j);
498 			if (cnid == 0) {
499 				if (w->w_nconns < ents) {
500 					hda_error(sc, "WARNING: zero cnid\n");
501 				} else {
502 					goto getconns_out;
503 				}
504 			}
505 			if (cnid < sc->sc_startnode || cnid >= sc->sc_endnode)
506 				hda_debug(sc, "ghost nid=%02X\n", cnid);
507 			if (CONN_RANGE(res, entnum, j) == 0)
508 				addcnid = cnid;
509 			else if (prevcnid == 0 || prevcnid >= cnid) {
510 				hda_error(sc, "invalid child range\n");
511 				addcnid = cnid;
512 			} else
513 				addcnid = prevcnid + 1;
514 			while (addcnid <= cnid) {
515 				if (w->w_nconns > maxconns) {
516 					hda_error(sc,
517 					    "max connections reached\n");
518 					goto getconns_out;
519 				}
520 				w->w_connsenable[w->w_nconns] = true;
521 				w->w_conns[w->w_nconns++] = addcnid++;
522 				hda_trace(sc, "add connection %02X->%02X\n",
523 				    w->w_nid, addcnid - 1);
524 			}
525 			prevcnid = cnid;
526 		}
527 	}
528 #undef CONN_RMASK
529 #undef CONN_NMASK
530 #undef CONN_RESVAL
531 #undef CONN_RANGE
532 #undef CONN_CNID
533 
534 getconns_out:
535 	return;
536 }
537 
538 static void
539 hdafg_widget_pin_dump(struct hdafg_softc *sc)
540 {
541 	struct hdaudio_widget *w;
542 	int i, conn;
543 
544 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
545 		w = hdafg_widget_lookup(sc, i);
546 		if (w == NULL || w->w_enable == false)
547 			continue;
548 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
549 			continue;
550 		conn = COP_CFG_PORT_CONNECTIVITY(w->w_pin.config);
551 		if (conn != 1) {
552 #ifdef HDAUDIO_DEBUG
553 			int color = COP_CFG_COLOR(w->w_pin.config);
554 			int defdev = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
555 			hda_trace(sc, "io %02X: %s (%s, %s)\n",
556 			    w->w_nid,
557 			    hdafg_default_device[defdev],
558 			    hdafg_color[color],
559 			    hdafg_port_connectivity[conn]);
560 #endif
561 		}
562 	}
563 }
564 
565 static void
566 hdafg_widget_setconfig(struct hdaudio_widget *w, uint32_t cfg)
567 {
568 	struct hdafg_softc *sc = w->w_afg;
569 
570 	hdaudio_command(sc->sc_codec, w->w_nid,
571 	    CORB_SET_CONFIGURATION_DEFAULT_1, (cfg >>  0) & 0xff);
572 	hdaudio_command(sc->sc_codec, w->w_nid,
573 	    CORB_SET_CONFIGURATION_DEFAULT_2, (cfg >>  8) & 0xff);
574 	hdaudio_command(sc->sc_codec, w->w_nid,
575 	    CORB_SET_CONFIGURATION_DEFAULT_3, (cfg >> 16) & 0xff);
576 	hdaudio_command(sc->sc_codec, w->w_nid,
577 	    CORB_SET_CONFIGURATION_DEFAULT_4, (cfg >> 24) & 0xff);
578 }
579 
580 static uint32_t
581 hdafg_widget_getconfig(struct hdaudio_widget *w)
582 {
583 	struct hdafg_softc *sc = w->w_afg;
584 	uint32_t config = 0;
585 	prop_object_iterator_t iter;
586 	prop_dictionary_t dict;
587 	prop_object_t obj;
588 	int16_t nid;
589 
590 	if (sc->sc_config == NULL)
591 		goto biosconfig;
592 
593 	iter = prop_array_iterator(sc->sc_config);
594 	if (iter == NULL)
595 		goto biosconfig;
596 	prop_object_iterator_reset(iter);
597 	while ((obj = prop_object_iterator_next(iter)) != NULL) {
598 		if (prop_object_type(obj) != PROP_TYPE_DICTIONARY)
599 			continue;
600 		dict = (prop_dictionary_t)obj;
601 		if (!prop_dictionary_get_int16(dict, "nid", &nid) ||
602 		    !prop_dictionary_get_uint32(dict, "config", &config))
603 			continue;
604 		if (nid == w->w_nid)
605 			return config;
606 	}
607 
608 biosconfig:
609 	return hdaudio_command(sc->sc_codec, w->w_nid,
610 	    CORB_GET_CONFIGURATION_DEFAULT, 0);
611 }
612 
613 static void
614 hdafg_widget_pin_parse(struct hdaudio_widget *w)
615 {
616 	struct hdafg_softc *sc = w->w_afg;
617 	int conn, color, defdev;
618 
619 	w->w_pin.cap = hda_get_wparam(w, PIN_CAPABILITIES);
620 	w->w_pin.config = hdafg_widget_getconfig(w);
621 	w->w_pin.biosconfig = hdaudio_command(sc->sc_codec, w->w_nid,
622 	    CORB_GET_CONFIGURATION_DEFAULT, 0);
623 	w->w_pin.ctrl = hdaudio_command(sc->sc_codec, w->w_nid,
624 	    CORB_GET_PIN_WIDGET_CONTROL, 0);
625 
626 	/* treat line-out as speaker, unless connection type is RCA */
627 	if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) == COP_DEVICE_LINE_OUT &&
628 	    COP_CFG_CONNECTION_TYPE(w->w_pin.config) != COP_CONN_TYPE_RCA) {
629 		w->w_pin.config &= ~COP_DEVICE_MASK;
630 		w->w_pin.config |= (COP_DEVICE_SPEAKER << COP_DEVICE_SHIFT);
631 	}
632 
633 	if (w->w_pin.cap & COP_PINCAP_EAPD_CAPABLE) {
634 		w->w_p.eapdbtl = hdaudio_command(sc->sc_codec, w->w_nid,
635 		    CORB_GET_EAPD_BTL_ENABLE, 0);
636 		w->w_p.eapdbtl &= 0x7;
637 		w->w_p.eapdbtl |= COP_EAPD_ENABLE_EAPD;
638 	} else
639 		w->w_p.eapdbtl = 0xffffffff;
640 
641 #if 0
642 	/* XXX VT1708 */
643 	if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) == COP_DEVICE_SPEAKER &&
644 	    COP_CFG_DEFAULT_ASSOCIATION(w->w_pin.config) == 15) {
645 		hda_trace(sc, "forcing speaker nid %02X to assoc=14\n",
646 		    w->w_nid);
647 		/* set assoc=14 */
648 		w->w_pin.config &= ~0xf0;
649 		w->w_pin.config |= 0xe0;
650 	}
651 	if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) == COP_DEVICE_HP_OUT &&
652 	    COP_CFG_PORT_CONNECTIVITY(w->w_pin.config) == COP_PORT_NONE) {
653 		hda_trace(sc, "forcing hp out nid %02X to assoc=14\n",
654 		    w->w_nid);
655 		/* set connectivity to 'jack' */
656 		w->w_pin.config &= ~(COP_PORT_BOTH << 30);
657 		w->w_pin.config |= (COP_PORT_JACK << 30);
658 		/* set seq=15 */
659 		w->w_pin.config &= ~0xf;
660 		w->w_pin.config |= 15;
661 		/* set assoc=14 */
662 		w->w_pin.config &= ~0xf0;
663 		w->w_pin.config |= 0xe0;
664 	}
665 #endif
666 
667 	conn = COP_CFG_PORT_CONNECTIVITY(w->w_pin.config);
668 	color = COP_CFG_COLOR(w->w_pin.config);
669 	defdev = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
670 
671 	strlcat(w->w_name, ": ", sizeof(w->w_name));
672 	strlcat(w->w_name, hdafg_default_device[defdev], sizeof(w->w_name));
673 	strlcat(w->w_name, " (", sizeof(w->w_name));
674 	if (conn == 0 && color != 0 && color != 15) {
675 		strlcat(w->w_name, hdafg_color[color], sizeof(w->w_name));
676 		strlcat(w->w_name, " ", sizeof(w->w_name));
677 	}
678 	strlcat(w->w_name, hdafg_port_connectivity[conn], sizeof(w->w_name));
679 	strlcat(w->w_name, ")", sizeof(w->w_name));
680 }
681 
682 static uint32_t
683 hdafg_widget_getcaps(struct hdaudio_widget *w)
684 {
685 	struct hdafg_softc *sc = w->w_afg;
686 	uint32_t wcap, config;
687 	bool pcbeep = false;
688 
689 	wcap = hda_get_wparam(w, AUDIO_WIDGET_CAPABILITIES);
690 	config = hdafg_widget_getconfig(w);
691 
692 	w->w_waspin = false;
693 
694 	switch (sc->sc_vendor) {
695 	case HDAUDIO_VENDOR_ANALOG:
696 		/*
697 		 * help the parser by marking the analog
698 		 * beeper as a beep generator
699 		 */
700 		if (w->w_nid == 0x1a &&
701 		    COP_CFG_SEQUENCE(config) == 0x0 &&
702 		    COP_CFG_DEFAULT_ASSOCIATION(config) == 0xf &&
703 		    COP_CFG_PORT_CONNECTIVITY(config) ==
704 		      COP_PORT_FIXED_FUNCTION &&
705 		    COP_CFG_DEFAULT_DEVICE(config) ==
706 		      COP_DEVICE_OTHER) {
707 			pcbeep = true;
708 		}
709 		break;
710 	}
711 
712 	if (pcbeep ||
713 	    (sc->sc_has_beepgen == false &&
714 	    COP_CFG_DEFAULT_DEVICE(config) == COP_DEVICE_SPEAKER &&
715 	    (wcap & (COP_AWCAP_INAMP_PRESENT|COP_AWCAP_OUTAMP_PRESENT)) == 0)) {
716 		wcap &= ~COP_AWCAP_TYPE_MASK;
717 		wcap |= (COP_AWCAP_TYPE_BEEP_GENERATOR << COP_AWCAP_TYPE_SHIFT);
718 		w->w_waspin = true;
719 	}
720 
721 	return wcap;
722 }
723 
724 static void
725 hdafg_widget_parse(struct hdaudio_widget *w)
726 {
727 	struct hdafg_softc *sc = w->w_afg;
728 	const char *tstr;
729 
730 	w->w_p.aw_cap = hdafg_widget_getcaps(w);
731 	w->w_type = COP_AWCAP_TYPE(w->w_p.aw_cap);
732 
733 	switch (w->w_type) {
734 	case COP_AWCAP_TYPE_AUDIO_OUTPUT:	tstr = "audio output"; break;
735 	case COP_AWCAP_TYPE_AUDIO_INPUT:	tstr = "audio input"; break;
736 	case COP_AWCAP_TYPE_AUDIO_MIXER:	tstr = "audio mixer"; break;
737 	case COP_AWCAP_TYPE_AUDIO_SELECTOR:	tstr = "audio selector"; break;
738 	case COP_AWCAP_TYPE_PIN_COMPLEX:	tstr = "pin"; break;
739 	case COP_AWCAP_TYPE_POWER_WIDGET:	tstr = "power widget"; break;
740 	case COP_AWCAP_TYPE_VOLUME_KNOB:	tstr = "volume knob"; break;
741 	case COP_AWCAP_TYPE_BEEP_GENERATOR:	tstr = "beep generator"; break;
742 	case COP_AWCAP_TYPE_VENDOR_DEFINED:	tstr = "vendor defined"; break;
743 	default:				tstr = "unknown"; break;
744 	}
745 
746 	strlcpy(w->w_name, tstr, sizeof(w->w_name));
747 
748 	hdafg_widget_connection_parse(w);
749 
750 	if (w->w_p.aw_cap & COP_AWCAP_INAMP_PRESENT) {
751 		if (w->w_p.aw_cap & COP_AWCAP_AMP_PARAM_OVERRIDE)
752 			w->w_p.inamp_cap = hda_get_wparam(w,
753 			    AMPLIFIER_CAPABILITIES_INAMP);
754 		else
755 			w->w_p.inamp_cap = sc->sc_p.inamp_cap;
756 	}
757 	if (w->w_p.aw_cap & COP_AWCAP_OUTAMP_PRESENT) {
758 		if (w->w_p.aw_cap & COP_AWCAP_AMP_PARAM_OVERRIDE)
759 			w->w_p.outamp_cap = hda_get_wparam(w,
760 			    AMPLIFIER_CAPABILITIES_OUTAMP);
761 		else
762 			w->w_p.outamp_cap = sc->sc_p.outamp_cap;
763 	}
764 
765 	w->w_p.stream_format = 0;
766 	w->w_p.pcm_size_rate = 0;
767 	switch (w->w_type) {
768 	case COP_AWCAP_TYPE_AUDIO_OUTPUT:
769 	case COP_AWCAP_TYPE_AUDIO_INPUT:
770 		if (w->w_p.aw_cap & COP_AWCAP_FORMAT_OVERRIDE) {
771 			w->w_p.stream_format = hda_get_wparam(w,
772 			    SUPPORTED_STREAM_FORMATS);
773 			w->w_p.pcm_size_rate = hda_get_wparam(w,
774 			    SUPPORTED_PCM_SIZE_RATES);
775 		} else {
776 			w->w_p.stream_format = sc->sc_p.stream_format;
777 			w->w_p.pcm_size_rate = sc->sc_p.pcm_size_rate;
778 		}
779 		break;
780 	case COP_AWCAP_TYPE_PIN_COMPLEX:
781 		hdafg_widget_pin_parse(w);
782 		hdafg_widget_setconfig(w, w->w_pin.config);
783 		break;
784 	}
785 }
786 
787 static int
788 hdafg_assoc_count_channels(struct hdafg_softc *sc,
789     struct hdaudio_assoc *as, enum hdaudio_pindir dir)
790 {
791 	struct hdaudio_widget *w;
792 	int *dacmap;
793 	int i, dacmapsz = sizeof(*dacmap) * sc->sc_endnode;
794 	int nchans = 0;
795 
796 	if (as->as_enable == false || as->as_dir != dir)
797 		return 0;
798 
799 	dacmap = kmem_zalloc(dacmapsz, KM_SLEEP);
800 
801 	for (i = 0; i < HDAUDIO_MAXPINS; i++)
802 		if (as->as_dacs[i])
803 			dacmap[as->as_dacs[i]] = 1;
804 
805 	for (i = 1; i < sc->sc_endnode; i++) {
806 		if (!dacmap[i])
807 			continue;
808 		w = hdafg_widget_lookup(sc, i);
809 		if (w == NULL || w->w_enable == false)
810 			continue;
811 		nchans += COP_AWCAP_CHANNEL_COUNT(w->w_p.aw_cap);
812 	}
813 
814 	kmem_free(dacmap, dacmapsz);
815 
816 	return nchans;
817 }
818 
819 static const char *
820 hdafg_assoc_type_string(struct hdaudio_assoc *as)
821 {
822 	switch (as->as_digital) {
823 	case HDAFG_AS_ANALOG:
824 		return as->as_dir == HDAUDIO_PINDIR_IN ?
825 		    "ADC" : "DAC";
826 	case HDAFG_AS_SPDIF:
827 		return as->as_dir == HDAUDIO_PINDIR_IN ?
828 		    "DIG-In" : "DIG";
829 	case HDAFG_AS_HDMI:
830 		return as->as_dir == HDAUDIO_PINDIR_IN ?
831 		    "HDMI-In" : "HDMI";
832 	case HDAFG_AS_DISPLAYPORT:
833 		return as->as_dir == HDAUDIO_PINDIR_IN ?
834 		    "DP-In" : "DP";
835 	default:
836 		return as->as_dir == HDAUDIO_PINDIR_IN ?
837 		    "Unknown-In" : "Unknown-Out";
838 	}
839 }
840 
841 static void
842 hdafg_assoc_dump_dd(struct hdafg_softc *sc, struct hdaudio_assoc *as, int pin,
843 	int lock)
844 {
845 	struct hdafg_dd_info hdi;
846 	struct hdaudio_widget *w;
847 	uint8_t elddata[256];
848 	unsigned int elddatalen = 0, i;
849 	uint32_t res;
850 	uint32_t (*cmd)(struct hdaudio_codec *, int, uint32_t, uint32_t) =
851 	    lock ? hdaudio_command : hdaudio_command_unlocked;
852 
853 	w = hdafg_widget_lookup(sc, as->as_pins[pin]);
854 
855 	if (w->w_pin.cap & COP_PINCAP_TRIGGER_REQD) {
856 		(*cmd)(sc->sc_codec, as->as_pins[pin],
857 		    CORB_SET_PIN_SENSE, 0);
858 	}
859 	res = (*cmd)(sc->sc_codec, as->as_pins[pin],
860 	    CORB_GET_PIN_SENSE, 0);
861 
862 #ifdef HDAFG_HDMI_DEBUG
863 	hda_print(sc, "Display Device, pin=%02X\n", as->as_pins[pin]);
864 	hda_print(sc, "  COP_GET_PIN_SENSE_PRESENSE_DETECT=%d\n",
865 	    !!(res & COP_GET_PIN_SENSE_PRESENSE_DETECT));
866 	hda_print(sc, "  COP_GET_PIN_SENSE_ELD_VALID=%d\n",
867 	    !!(res & COP_GET_PIN_SENSE_ELD_VALID));
868 #endif
869 
870 	if ((res &
871 	    (COP_GET_PIN_SENSE_PRESENSE_DETECT|COP_GET_PIN_SENSE_ELD_VALID)) ==
872 	    (COP_GET_PIN_SENSE_PRESENSE_DETECT|COP_GET_PIN_SENSE_ELD_VALID)) {
873 		res = (*cmd)(sc->sc_codec, as->as_pins[pin],
874 		    CORB_GET_HDMI_DIP_SIZE, COP_DIP_ELD_SIZE);
875 		elddatalen = COP_DIP_BUFFER_SIZE(res);
876 		if (elddatalen == 0)
877 			elddatalen = sizeof(elddata); /* paranoid */
878 		for (i = 0; i < elddatalen; i++) {
879 			res = (*cmd)(sc->sc_codec, as->as_pins[pin],
880 			    CORB_GET_HDMI_ELD_DATA, i);
881 			if (!(res & COP_ELD_VALID)) {
882 #ifdef HDAFG_HDMI_DEBUG
883 				hda_error(sc, "bad ELD size (%u/%u)\n",
884 				    i, elddatalen);
885 #endif
886 				break;
887 			}
888 			elddata[i] = COP_ELD_DATA(res);
889 		}
890 
891 		if (hdafg_dd_parse_info(elddata, elddatalen, &hdi) != 0) {
892 #ifdef HDAFG_HDMI_DEBUG
893 			hda_error(sc, "failed to parse ELD data\n");
894 #endif
895 			return;
896 		}
897 
898 		hda_print(sc, "  ELD version=0x%x", ELD_VER(&hdi.eld));
899 		hda_print1(sc, ",len=%u", hdi.eld.header.baseline_eld_len * 4);
900 		hda_print1(sc, ",edid=0x%x", ELD_CEA_EDID_VER(&hdi.eld));
901 		hda_print1(sc, ",port=0x%" PRIx64, hdi.eld.port_id);
902 		hda_print1(sc, ",vendor=0x%04x", hdi.eld.vendor);
903 		hda_print1(sc, ",product=0x%04x", hdi.eld.product);
904 		hda_print1(sc, "\n");
905 		hda_print(sc, "  Monitor = '%s'\n", hdi.monitor);
906 		for (i = 0; i < hdi.nsad; i++) {
907 			hda_print(sc, "  SAD id=%u", i);
908 			hda_print1(sc, ",format=%u",
909 			    CEA_AUDIO_FORMAT(&hdi.sad[i]));
910 			hda_print1(sc, ",channels=%u",
911 			    CEA_MAX_CHANNELS(&hdi.sad[i]));
912 			hda_print1(sc, ",rate=0x%02x",
913 			    CEA_SAMPLE_RATE(&hdi.sad[i]));
914 			if (CEA_AUDIO_FORMAT(&hdi.sad[i]) ==
915 			    CEA_AUDIO_FORMAT_LPCM)
916 				hda_print1(sc, ",precision=0x%x",
917 				    CEA_PRECISION(&hdi.sad[i]));
918 			else
919 				hda_print1(sc, ",maxbitrate=%u",
920 				    CEA_MAX_BITRATE(&hdi.sad[i]));
921 			hda_print1(sc, "\n");
922 		}
923 	}
924 }
925 
926 static char *
927 hdafg_mixer_mask2allname(uint32_t mask, char *buf, size_t len)
928 {
929 	static const char *audioname[] = HDAUDIO_DEVICE_NAMES;
930 	int i, first = 1;
931 
932 	memset(buf, 0, len);
933 	for (i = 0; i < HDAUDIO_MIXER_NRDEVICES; i++) {
934 		if (mask & (1 << i)) {
935 			if (first == 0)
936 				strlcat(buf, ", ", len);
937 			strlcat(buf, audioname[i], len);
938 			first = 0;
939 		}
940 	}
941 
942 	return buf;
943 }
944 
945 static void
946 hdafg_dump_dst_nid(struct hdafg_softc *sc, int nid, int depth)
947 {
948 	struct hdaudio_widget *w, *cw;
949 	char buf[64];
950 	int i;
951 
952 	if (depth > HDAUDIO_PARSE_MAXDEPTH)
953 		return;
954 
955 	w = hdafg_widget_lookup(sc, nid);
956 	if (w == NULL || w->w_enable == false)
957 		return;
958 
959 	aprint_debug("%*s", 4 + depth * 7, "");
960 	aprint_debug("nid=%02X [%s]", w->w_nid, w->w_name);
961 
962 	if (depth > 0) {
963 		if (w->w_audiomask == 0) {
964 			aprint_debug("\n");
965 			return;
966 		}
967 		aprint_debug(" [source: %s]",
968 		    hdafg_mixer_mask2allname(w->w_audiomask, buf, sizeof(buf)));
969 		if (w->w_audiodev >= 0) {
970 			aprint_debug("\n");
971 			return;
972 		}
973 	}
974 
975 	aprint_debug("\n");
976 
977 	for (i = 0; i < w->w_nconns; i++) {
978 		if (w->w_connsenable[i] == 0)
979 			continue;
980 		cw = hdafg_widget_lookup(sc, w->w_conns[i]);
981 		if (cw == NULL || cw->w_enable == false || cw->w_bindas == -1)
982 			continue;
983 		hdafg_dump_dst_nid(sc, w->w_conns[i], depth + 1);
984 	}
985 }
986 
987 static void
988 hdafg_assoc_dump(struct hdafg_softc *sc)
989 {
990 	struct hdaudio_assoc *as = sc->sc_assocs;
991 	struct hdaudio_widget *w;
992 	uint32_t conn, defdev, curdev, curport;
993 	int maxassocs = sc->sc_nassocs;
994 	int i, j;
995 
996 	for (i = 0; i < maxassocs; i++) {
997 		uint32_t devmask = 0, portmask = 0;
998 		bool firstdev = true;
999 		int nchan;
1000 
1001 		if (as[i].as_enable == false)
1002 			continue;
1003 
1004 		hda_print(sc, "%s%02X",
1005 		    hdafg_assoc_type_string(&as[i]), i);
1006 
1007 		nchan = hdafg_assoc_count_channels(sc, &as[i],
1008 		    as[i].as_dir);
1009 		hda_print1(sc, " %dch:", nchan);
1010 
1011 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
1012 			if (as[i].as_dacs[j] == 0)
1013 				continue;
1014 			w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
1015 			if (w == NULL)
1016 				continue;
1017 			conn = COP_CFG_PORT_CONNECTIVITY(w->w_pin.config);
1018 			defdev = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
1019 			if (conn != COP_PORT_NONE) {
1020 				devmask |= (1 << defdev);
1021 				portmask |= (1 << conn);
1022 			}
1023 		}
1024 		for (curdev = 0; curdev < 16; curdev++) {
1025 			bool firstport = true;
1026 			if ((devmask & (1 << curdev)) == 0)
1027 				continue;
1028 
1029 			if (firstdev == false)
1030 				hda_print1(sc, ",");
1031 			firstdev = false;
1032 			hda_print1(sc, " %s",
1033 			    hdafg_default_device[curdev]);
1034 
1035 			for (curport = 0; curport < 4; curport++) {
1036 				bool devonport = false;
1037 				if ((portmask & (1 << curport)) == 0)
1038 					continue;
1039 
1040 				for (j = 0; j < HDAUDIO_MAXPINS; j++) {
1041 					if (as[i].as_dacs[j] == 0)
1042 						continue;
1043 
1044 					w = hdafg_widget_lookup(sc,
1045 					    as[i].as_pins[j]);
1046 					if (w == NULL)
1047 						continue;
1048 					conn = COP_CFG_PORT_CONNECTIVITY(w->w_pin.config);
1049 					defdev = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
1050 					if (conn != curport || defdev != curdev)
1051 						continue;
1052 
1053 					devonport = true;
1054 				}
1055 
1056 				if (devonport == false)
1057 					continue;
1058 
1059 				hda_print1(sc, " [%s",
1060 				    hdafg_port_connectivity[curport]);
1061 				for (j = 0; j < HDAUDIO_MAXPINS; j++) {
1062 					if (as[i].as_dacs[j] == 0)
1063 						continue;
1064 
1065 					w = hdafg_widget_lookup(sc,
1066 					    as[i].as_pins[j]);
1067 					if (w == NULL)
1068 						continue;
1069 					conn = COP_CFG_PORT_CONNECTIVITY(w->w_pin.config);
1070 					defdev = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
1071 					if (conn != curport || defdev != curdev)
1072 						continue;
1073 
1074 					if (firstport == false)
1075 						hda_trace1(sc, ",");
1076 					else
1077 						hda_trace1(sc, " ");
1078 					firstport = false;
1079 #ifdef HDAUDIO_DEBUG
1080 					int color =
1081 					    COP_CFG_COLOR(w->w_pin.config);
1082 					hda_trace1(sc, "%s",
1083 					    hdafg_color[color]);
1084 #endif
1085 					hda_trace1(sc, "(%02X)", w->w_nid);
1086 				}
1087 				hda_print1(sc, "]");
1088 			}
1089 		}
1090 		hda_print1(sc, "\n");
1091 
1092 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
1093 			if (as[i].as_pins[j] == 0)
1094 				continue;
1095 			hdafg_dump_dst_nid(sc, as[i].as_pins[j], 0);
1096 		}
1097 
1098 		if (as[i].as_displaydev == true) {
1099 			for (j = 0; j < HDAUDIO_MAXPINS; j++) {
1100 				if (as[i].as_pins[j] == 0)
1101 					continue;
1102 				hdafg_assoc_dump_dd(sc, &as[i], j, 1);
1103 			}
1104 		}
1105 	}
1106 }
1107 
1108 static void
1109 hdafg_assoc_parse(struct hdafg_softc *sc)
1110 {
1111 	struct hdaudio_assoc *as;
1112 	struct hdaudio_widget *w;
1113 	int i, j, cnt, maxassocs, type, assoc, seq, first, hpredir;
1114 	enum hdaudio_pindir dir;
1115 
1116 	hda_debug(sc, "  count present associations\n");
1117 	/* Count present associations */
1118 	maxassocs = 0;
1119 	for (j = 1; j < HDAUDIO_MAXPINS; j++) {
1120 		for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1121 			w = hdafg_widget_lookup(sc, i);
1122 			if (w == NULL || w->w_enable == false)
1123 				continue;
1124 			if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
1125 				continue;
1126 			if (COP_CFG_DEFAULT_ASSOCIATION(w->w_pin.config) != j)
1127 				continue;
1128 			maxassocs++;
1129 			if (j != 15) /* There could be many 1-pin assocs #15 */
1130 				break;
1131 		}
1132 	}
1133 
1134 	hda_debug(sc, "  maxassocs %d\n", maxassocs);
1135 	sc->sc_nassocs = maxassocs;
1136 
1137 	if (maxassocs < 1)
1138 		return;
1139 
1140 	hda_debug(sc, "  allocating memory\n");
1141 	as = kmem_zalloc(maxassocs * sizeof(*as), KM_SLEEP);
1142 	for (i = 0; i < maxassocs; i++) {
1143 		as[i].as_hpredir = -1;
1144 		/* as[i].as_chan = NULL; */
1145 		as[i].as_digital = HDAFG_AS_SPDIF;
1146 	}
1147 
1148 	hda_debug(sc, "  scan associations, skipping as=0\n");
1149 	/* Scan associations skipping as=0 */
1150 	cnt = 0;
1151 	for (j = 1; j < HDAUDIO_MAXPINS && cnt < maxassocs; j++) {
1152 		first = 16;
1153 		hpredir = 0;
1154 		for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1155 			w = hdafg_widget_lookup(sc, i);
1156 			if (w == NULL || w->w_enable == false)
1157 				continue;
1158 			if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
1159 				continue;
1160 			assoc = COP_CFG_DEFAULT_ASSOCIATION(w->w_pin.config);
1161 			seq = COP_CFG_SEQUENCE(w->w_pin.config);
1162 			if (assoc != j)
1163 				continue;
1164 			KASSERT(cnt < maxassocs);
1165 			type = COP_CFG_DEFAULT_DEVICE(w->w_pin.config);
1166 			/* Get pin direction */
1167 			switch (type) {
1168 			case COP_DEVICE_LINE_OUT:
1169 			case COP_DEVICE_SPEAKER:
1170 			case COP_DEVICE_HP_OUT:
1171 			case COP_DEVICE_SPDIF_OUT:
1172 			case COP_DEVICE_DIGITAL_OTHER_OUT:
1173 				dir = HDAUDIO_PINDIR_OUT;
1174 				break;
1175 			default:
1176 				dir = HDAUDIO_PINDIR_IN;
1177 				break;
1178 			}
1179 			/* If this is a first pin, create new association */
1180 			if (as[cnt].as_pincnt == 0) {
1181 				as[cnt].as_enable = true;
1182 				as[cnt].as_activated = true;
1183 				as[cnt].as_index = j;
1184 				as[cnt].as_dir = dir;
1185 			}
1186 			if (seq < first)
1187 				first = seq;
1188 			/* Check association correctness */
1189 			if (as[cnt].as_pins[seq] != 0) {
1190 				hda_error(sc, "duplicate pin in association\n");
1191 				as[cnt].as_enable = false;
1192 			}
1193 			if (dir != as[cnt].as_dir) {
1194 				hda_error(sc,
1195 				    "pin %02X has wrong direction for %02X\n",
1196 				    w->w_nid, j);
1197 				as[cnt].as_enable = false;
1198 			}
1199 			if ((w->w_p.aw_cap & COP_AWCAP_DIGITAL) == 0)
1200 				as[cnt].as_digital = HDAFG_AS_ANALOG;
1201 			if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
1202 				as[cnt].as_displaydev = true;
1203 			if (w->w_pin.cap & COP_PINCAP_HDMI)
1204 				as[cnt].as_digital = HDAFG_AS_HDMI;
1205 			if (w->w_pin.cap & COP_PINCAP_DP)
1206 				as[cnt].as_digital = HDAFG_AS_DISPLAYPORT;
1207 			/* Headphones with seq=15 may mean redirection */
1208 			if (type == COP_DEVICE_HP_OUT && seq == 15)
1209 				hpredir = 1;
1210 			as[cnt].as_pins[seq] = w->w_nid;
1211 			as[cnt].as_pincnt++;
1212 			if (j == 15)
1213 				cnt++;
1214 		}
1215 		if (j != 15 && cnt < maxassocs && as[cnt].as_pincnt > 0) {
1216 			if (hpredir && as[cnt].as_pincnt > 1)
1217 				as[cnt].as_hpredir = first;
1218 			cnt++;
1219 		}
1220 	}
1221 
1222 	hda_debug(sc, "  all done\n");
1223 	sc->sc_assocs = as;
1224 }
1225 
1226 static void
1227 hdafg_control_parse(struct hdafg_softc *sc)
1228 {
1229 	struct hdaudio_control *ctl;
1230 	struct hdaudio_widget *w, *cw;
1231 	int i, j, cnt, maxctls, ocap, icap;
1232 	int mute, offset, step, size;
1233 
1234 	maxctls = 0;
1235 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1236 		w = hdafg_widget_lookup(sc, i);
1237 		if (w == NULL || w->w_enable == false)
1238 			continue;
1239 		if (w->w_p.outamp_cap)
1240 			maxctls++;
1241 		if (w->w_p.inamp_cap) {
1242 			switch (w->w_type) {
1243 			case COP_AWCAP_TYPE_AUDIO_SELECTOR:
1244 			case COP_AWCAP_TYPE_AUDIO_MIXER:
1245 				for (j = 0; j < w->w_nconns; j++) {
1246 					cw = hdafg_widget_lookup(sc,
1247 					    w->w_conns[j]);
1248 					if (cw == NULL || cw->w_enable == false)
1249 						continue;
1250 					maxctls++;
1251 				}
1252 				break;
1253 			default:
1254 				maxctls++;
1255 				break;
1256 			}
1257 		}
1258 	}
1259 
1260 	sc->sc_nctls = maxctls;
1261 	if (maxctls < 1)
1262 		return;
1263 
1264 	ctl = kmem_zalloc(sc->sc_nctls * sizeof(*ctl), KM_SLEEP);
1265 
1266 	cnt = 0;
1267 	for (i = sc->sc_startnode; cnt < maxctls && i < sc->sc_endnode; i++) {
1268 		w = hdafg_widget_lookup(sc, i);
1269 		if (w == NULL || w->w_enable == false)
1270 			continue;
1271 		ocap = w->w_p.outamp_cap;
1272 		icap = w->w_p.inamp_cap;
1273 		if (ocap) {
1274 			hda_trace(sc, "add ctrl outamp %d:%02X:FF\n",
1275 			    cnt, w->w_nid);
1276 			mute = COP_AMPCAP_MUTE_CAPABLE(ocap);
1277 			step = COP_AMPCAP_NUM_STEPS(ocap);
1278 			size = COP_AMPCAP_STEP_SIZE(ocap);
1279 			offset = COP_AMPCAP_OFFSET(ocap);
1280 			ctl[cnt].ctl_enable = true;
1281 			ctl[cnt].ctl_widget = w;
1282 			ctl[cnt].ctl_mute = mute;
1283 			ctl[cnt].ctl_step = step;
1284 			ctl[cnt].ctl_size = size;
1285 			ctl[cnt].ctl_offset = offset;
1286 			ctl[cnt].ctl_left = offset;
1287 			ctl[cnt].ctl_right = offset;
1288 			if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX ||
1289 			    w->w_waspin == true)
1290 				ctl[cnt].ctl_ndir = HDAUDIO_PINDIR_IN;
1291 			else
1292 				ctl[cnt].ctl_ndir = HDAUDIO_PINDIR_OUT;
1293 			ctl[cnt++].ctl_dir = HDAUDIO_PINDIR_OUT;
1294 		}
1295 		if (icap) {
1296 			mute = COP_AMPCAP_MUTE_CAPABLE(icap);
1297 			step = COP_AMPCAP_NUM_STEPS(icap);
1298 			size = COP_AMPCAP_STEP_SIZE(icap);
1299 			offset = COP_AMPCAP_OFFSET(icap);
1300 			switch (w->w_type) {
1301 			case COP_AWCAP_TYPE_AUDIO_SELECTOR:
1302 			case COP_AWCAP_TYPE_AUDIO_MIXER:
1303 				for (j = 0; j < w->w_nconns; j++) {
1304 					if (cnt >= maxctls)
1305 						break;
1306 					cw = hdafg_widget_lookup(sc,
1307 					    w->w_conns[j]);
1308 					if (cw == NULL || cw->w_enable == false)
1309 						continue;
1310 					hda_trace(sc, "add ctrl inamp selmix "
1311 					    "%d:%02X:%02X\n", cnt, w->w_nid,
1312 					    cw->w_nid);
1313 					ctl[cnt].ctl_enable = true;
1314 					ctl[cnt].ctl_widget = w;
1315 					ctl[cnt].ctl_childwidget = cw;
1316 					ctl[cnt].ctl_index = j;
1317 					ctl[cnt].ctl_mute = mute;
1318 					ctl[cnt].ctl_step = step;
1319 					ctl[cnt].ctl_size = size;
1320 					ctl[cnt].ctl_offset = offset;
1321 					ctl[cnt].ctl_left = offset;
1322 					ctl[cnt].ctl_right = offset;
1323 					ctl[cnt].ctl_ndir = HDAUDIO_PINDIR_IN;
1324 					ctl[cnt++].ctl_dir = HDAUDIO_PINDIR_IN;
1325 				}
1326 				break;
1327 			default:
1328 				if (cnt >= maxctls)
1329 					break;
1330 				hda_trace(sc, "add ctrl inamp "
1331 				    "%d:%02X:FF\n", cnt, w->w_nid);
1332 				ctl[cnt].ctl_enable = true;
1333 				ctl[cnt].ctl_widget = w;
1334 				ctl[cnt].ctl_mute = mute;
1335 				ctl[cnt].ctl_step = step;
1336 				ctl[cnt].ctl_size = size;
1337 				ctl[cnt].ctl_offset = offset;
1338 				ctl[cnt].ctl_left = offset;
1339 				ctl[cnt].ctl_right = offset;
1340 				if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
1341 					ctl[cnt].ctl_ndir = HDAUDIO_PINDIR_OUT;
1342 				else
1343 					ctl[cnt].ctl_ndir = HDAUDIO_PINDIR_IN;
1344 				ctl[cnt++].ctl_dir = HDAUDIO_PINDIR_IN;
1345 				break;
1346 			}
1347 		}
1348 	}
1349 
1350 	sc->sc_ctls = ctl;
1351 }
1352 
1353 static void
1354 hdafg_parse(struct hdafg_softc *sc)
1355 {
1356 	struct hdaudio_widget *w;
1357 	uint32_t nodecnt, wcap;
1358 	int nid;
1359 
1360 	nodecnt = hda_get_param(sc, SUBORDINATE_NODE_COUNT);
1361 	sc->sc_startnode = COP_NODECNT_STARTNODE(nodecnt);
1362 	sc->sc_nwidgets = COP_NODECNT_NUMNODES(nodecnt);
1363 	sc->sc_endnode = sc->sc_startnode + sc->sc_nwidgets;
1364 	hda_debug(sc, "afg start %02X end %02X nwidgets %d\n",
1365 	    sc->sc_startnode, sc->sc_endnode, sc->sc_nwidgets);
1366 
1367 	hda_debug(sc, "powering up widgets\n");
1368 	hdaudio_command(sc->sc_codec, sc->sc_nid,
1369 	    CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
1370 	hda_delay(100);
1371 	for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++)
1372 		hdaudio_command(sc->sc_codec, nid,
1373 		    CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
1374 	hda_delay(1000);
1375 
1376 	sc->sc_p.afg_cap = hda_get_param(sc, AUDIO_FUNCTION_GROUP_CAPABILITIES);
1377 	sc->sc_p.stream_format = hda_get_param(sc, SUPPORTED_STREAM_FORMATS);
1378 	sc->sc_p.pcm_size_rate = hda_get_param(sc, SUPPORTED_PCM_SIZE_RATES);
1379 	sc->sc_p.outamp_cap = hda_get_param(sc, AMPLIFIER_CAPABILITIES_OUTAMP);
1380 	sc->sc_p.inamp_cap = hda_get_param(sc, AMPLIFIER_CAPABILITIES_INAMP);
1381 	sc->sc_p.power_states = hda_get_param(sc, SUPPORTED_POWER_STATES);
1382 	sc->sc_p.gpio_cnt = hda_get_param(sc, GPIO_COUNT);
1383 
1384 	sc->sc_widgets = kmem_zalloc(sc->sc_nwidgets * sizeof(*w), KM_SLEEP);
1385 	hda_debug(sc, "afg widgets %p-%p\n",
1386 	    sc->sc_widgets, sc->sc_widgets + sc->sc_nwidgets);
1387 
1388 	for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
1389 		w = hdafg_widget_lookup(sc, nid);
1390 		if (w == NULL)
1391 			continue;
1392 		wcap = hdaudio_command(sc->sc_codec, nid, CORB_GET_PARAMETER,
1393 		    COP_AUDIO_WIDGET_CAPABILITIES);
1394 		switch (COP_AWCAP_TYPE(wcap)) {
1395 		case COP_AWCAP_TYPE_BEEP_GENERATOR:
1396 			sc->sc_has_beepgen = true;
1397 			break;
1398 		}
1399 	}
1400 
1401 	for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
1402 		w = hdafg_widget_lookup(sc, nid);
1403 		if (w == NULL)
1404 			continue;
1405 		w->w_afg = sc;
1406 		w->w_nid = nid;
1407 		w->w_enable = true;
1408 		w->w_pflags = 0;
1409 		w->w_audiodev = -1;
1410 		w->w_selconn = -1;
1411 		w->w_bindas = -1;
1412 		w->w_p.eapdbtl = 0xffffffff;
1413 		hdafg_widget_parse(w);
1414 	}
1415 }
1416 
1417 static void
1418 hdafg_disable_nonaudio(struct hdafg_softc *sc)
1419 {
1420 	struct hdaudio_widget *w;
1421 	int i;
1422 
1423 	/* Disable power and volume widgets */
1424 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1425 		w = hdafg_widget_lookup(sc, i);
1426 		if (w == NULL || w->w_enable == false)
1427 			continue;
1428 		if (w->w_type == COP_AWCAP_TYPE_POWER_WIDGET ||
1429 		    w->w_type == COP_AWCAP_TYPE_VOLUME_KNOB) {
1430 			hda_trace(w->w_afg, "disable %02X [nonaudio]\n",
1431 			    w->w_nid);
1432 			w->w_enable = false;
1433 		}
1434 	}
1435 }
1436 
1437 static void
1438 hdafg_disable_useless(struct hdafg_softc *sc)
1439 {
1440 	struct hdaudio_widget *w, *cw;
1441 	struct hdaudio_control *ctl;
1442 	int done, found, i, j, k;
1443 	int conn, assoc;
1444 
1445 	/* Disable useless pins */
1446 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1447 		w = hdafg_widget_lookup(sc, i);
1448 		if (w == NULL || w->w_enable == false)
1449 			continue;
1450 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
1451 			continue;
1452 		conn = COP_CFG_PORT_CONNECTIVITY(w->w_pin.config);
1453 		assoc = COP_CFG_DEFAULT_ASSOCIATION(w->w_pin.config);
1454 		if (conn == COP_PORT_NONE) {
1455 			hda_trace(w->w_afg, "disable %02X [no connectivity]\n",
1456 			    w->w_nid);
1457 			w->w_enable = false;
1458 		}
1459 		if (assoc == 0) {
1460 			hda_trace(w->w_afg, "disable %02X [no association]\n",
1461 			    w->w_nid);
1462 			w->w_enable = false;
1463 		}
1464 	}
1465 
1466 	do {
1467 		done = 1;
1468 		/* Disable and mute controls for disabled widgets */
1469 		for (i = 0; i < sc->sc_nctls; i++) {
1470 			ctl = &sc->sc_ctls[i];
1471 			if (ctl->ctl_enable == false)
1472 				continue;
1473 			if (ctl->ctl_widget->w_enable == false ||
1474 			    (ctl->ctl_childwidget != NULL &&
1475 			     ctl->ctl_childwidget->w_enable == false)) {
1476 				ctl->ctl_forcemute = 1;
1477 				ctl->ctl_muted = HDAUDIO_AMP_MUTE_ALL;
1478 				ctl->ctl_left = ctl->ctl_right = 0;
1479 				ctl->ctl_enable = false;
1480 				if (ctl->ctl_ndir == HDAUDIO_PINDIR_IN)
1481 					ctl->ctl_widget->w_connsenable[
1482 					    ctl->ctl_index] = false;
1483 				done = 0;
1484 				hda_trace(ctl->ctl_widget->w_afg,
1485 				    "disable ctl %d:%02X:%02X [widget disabled]\n",
1486 				    i, ctl->ctl_widget->w_nid,
1487 				    ctl->ctl_childwidget ?
1488 				    ctl->ctl_childwidget->w_nid : 0xff);
1489 			}
1490 		}
1491 		/* Disable useless widgets */
1492 		for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1493 			w = hdafg_widget_lookup(sc, i);
1494 			if (w == NULL || w->w_enable == false)
1495 				continue;
1496 			/* Disable inputs with disabled child widgets */
1497 			for (j = 0; j < w->w_nconns; j++) {
1498 				if (!w->w_connsenable[j])
1499 					continue;
1500 				cw = hdafg_widget_lookup(sc,
1501 				    w->w_conns[j]);
1502 				if (cw == NULL || cw->w_enable == false) {
1503 					w->w_connsenable[j] = false;
1504 					hda_trace(w->w_afg,
1505 					    "disable conn %02X->%02X "
1506 					    "[disabled child]\n",
1507 					    w->w_nid, w->w_conns[j]);
1508 				}
1509 			}
1510 			if (w->w_type != COP_AWCAP_TYPE_AUDIO_SELECTOR &&
1511 			    w->w_type != COP_AWCAP_TYPE_AUDIO_MIXER)
1512 				continue;
1513 			/* Disable mixers and selectors without inputs */
1514 			found = 0;
1515 			for (j = 0; j < w->w_nconns; j++)
1516 				if (w->w_connsenable[j]) {
1517 					found = 1;
1518 					break;
1519 				}
1520 			if (found == 0) {
1521 				w->w_enable = false;
1522 				done = 0;
1523 				hda_trace(w->w_afg,
1524 				    "disable %02X [inputs disabled]\n",
1525 				    w->w_nid);
1526 			}
1527 			/* Disable nodes without consumers */
1528 			if (w->w_type != COP_AWCAP_TYPE_AUDIO_SELECTOR &&
1529 			    w->w_type != COP_AWCAP_TYPE_AUDIO_MIXER)
1530 				continue;
1531 			found = 0;
1532 			for (k = sc->sc_startnode; k < sc->sc_endnode; k++) {
1533 				cw = hdafg_widget_lookup(sc, k);
1534 				if (cw == NULL || cw->w_enable == false)
1535 					continue;
1536 				for (j = 0; j < cw->w_nconns; j++) {
1537 					if (cw->w_connsenable[j] &&
1538 					    cw->w_conns[j] == i) {
1539 						found = 1;
1540 						break;
1541 					}
1542 				}
1543 			}
1544 			if (found == 0) {
1545 				w->w_enable = false;
1546 				done = 0;
1547 				hda_trace(w->w_afg,
1548 				    "disable %02X [consumers disabled]\n",
1549 				    w->w_nid);
1550 			}
1551 		}
1552 	} while (done == 0);
1553 }
1554 
1555 static void
1556 hdafg_assoc_trace_undo(struct hdafg_softc *sc, int as, int seq)
1557 {
1558 	struct hdaudio_widget *w;
1559 	int i;
1560 
1561 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
1562 		w = hdafg_widget_lookup(sc, i);
1563 		if (w == NULL || w->w_enable == false)
1564 			continue;
1565 		if (w->w_bindas != as)
1566 			continue;
1567 		if (seq >= 0) {
1568 			w->w_bindseqmask &= ~(1 << seq);
1569 			if (w->w_bindseqmask == 0) {
1570 				w->w_bindas = -1;
1571 				w->w_selconn = -1;
1572 			}
1573 		} else {
1574 			w->w_bindas = -1;
1575 			w->w_bindseqmask = 0;
1576 			w->w_selconn = -1;
1577 		}
1578 	}
1579 }
1580 
1581 static int
1582 hdafg_assoc_trace_dac(struct hdafg_softc *sc, int as, int seq,
1583     int nid, int dupseq, int minassoc, int only, int depth)
1584 {
1585 	struct hdaudio_widget *w;
1586 	int i, im = -1;
1587 	int m = 0, ret;
1588 
1589 	if (depth >= HDAUDIO_PARSE_MAXDEPTH)
1590 		return 0;
1591 	w = hdafg_widget_lookup(sc, nid);
1592 	if (w == NULL || w->w_enable == false)
1593 		return 0;
1594 	/* We use only unused widgets */
1595 	if (w->w_bindas >= 0 && w->w_bindas != as) {
1596 		if (!only)
1597 			hda_trace(sc, "depth %d nid %02X busy by assoc %d\n",
1598 			    depth + 1, nid, w->w_bindas);
1599 		return 0;
1600 	}
1601 	if (dupseq < 0) {
1602 		if (w->w_bindseqmask != 0) {
1603 			if (!only)
1604 				hda_trace(sc,
1605 				    "depth %d nid %02X busy by seqmask %x\n",
1606 				    depth + 1, nid, w->w_bindas);
1607 			return 0;
1608 		}
1609 	} else {
1610 		/* If this is headphones, allow duplicate first pin */
1611 		if (w->w_bindseqmask != 0 &&
1612 		    (w->w_bindseqmask & (1 << dupseq)) == 0)
1613 			return 0;
1614 	}
1615 
1616 	switch (w->w_type) {
1617 	case COP_AWCAP_TYPE_AUDIO_INPUT:
1618 		break;
1619 	case COP_AWCAP_TYPE_AUDIO_OUTPUT:
1620 		/* If we are tracing HP take only dac of first pin */
1621 		if ((only == 0 || only == w->w_nid) &&
1622 		    (w->w_nid >= minassoc) && (dupseq < 0 || w->w_nid ==
1623 		    sc->sc_assocs[as].as_dacs[dupseq]))
1624 			m = w->w_nid;
1625 		break;
1626 	case COP_AWCAP_TYPE_PIN_COMPLEX:
1627 		if (depth > 0)
1628 			break;
1629 		/* FALLTHROUGH */
1630 	default:
1631 		for (i = 0; i < w->w_nconns; i++) {
1632 			if (w->w_connsenable[i] == false)
1633 				continue;
1634 			if (w->w_selconn != -1 && w->w_selconn != i)
1635 				continue;
1636 			ret = hdafg_assoc_trace_dac(sc, as, seq,
1637 			    w->w_conns[i], dupseq, minassoc, only, depth + 1);
1638 			if (ret) {
1639 				if (m == 0 || ret < m) {
1640 					m = ret;
1641 					im = i;
1642 				}
1643 				if (only || dupseq >= 0)
1644 					break;
1645 			}
1646 		}
1647 		if (m && only && ((w->w_nconns > 1 &&
1648 		    w->w_type != COP_AWCAP_TYPE_AUDIO_MIXER) ||
1649 		    w->w_type == COP_AWCAP_TYPE_AUDIO_SELECTOR))
1650 			w->w_selconn = im;
1651 		break;
1652 	}
1653 	if (m && only) {
1654 		w->w_bindas = as;
1655 		w->w_bindseqmask |= (1 << seq);
1656 	}
1657 	if (!only)
1658 		hda_trace(sc, "depth %d nid %02X dupseq %d returned %02X\n",
1659 		    depth + 1, nid, dupseq, m);
1660 
1661 	return m;
1662 }
1663 
1664 static int
1665 hdafg_assoc_trace_out(struct hdafg_softc *sc, int as, int seq)
1666 {
1667 	struct hdaudio_assoc *assocs = sc->sc_assocs;
1668 	int i, hpredir;
1669 	int minassoc, res;
1670 
1671 	/* Find next pin */
1672 	for (i = seq; i < HDAUDIO_MAXPINS && assocs[as].as_pins[i] == 0; i++)
1673 		;
1674 	/* Check if there is any left, if not then we have succeeded */
1675 	if (i == HDAUDIO_MAXPINS)
1676 		return 1;
1677 
1678 	hpredir = (i == 15 && assocs[as].as_fakeredir == 0) ?
1679 	    assocs[as].as_hpredir : -1;
1680 	minassoc = res = 0;
1681 	do {
1682 		/* Trace this pin taking min nid into account */
1683 		res = hdafg_assoc_trace_dac(sc, as, i,
1684 		    assocs[as].as_pins[i], hpredir, minassoc, 0, 0);
1685 		if (res == 0) {
1686 			/* If we failed, return to previous and redo it */
1687 			hda_trace(sc, "  trace failed as=%d seq=%d pin=%02X "
1688 			    "hpredir=%d minassoc=%d\n",
1689 			    as, seq, assocs[as].as_pins[i], hpredir, minassoc);
1690 			return 0;
1691 		}
1692 		/* Trace again to mark the path */
1693 		hdafg_assoc_trace_dac(sc, as, i,
1694 		    assocs[as].as_pins[i], hpredir, minassoc, res, 0);
1695 		assocs[as].as_dacs[i] = res;
1696 		/* We succeeded, so call next */
1697 		if (hdafg_assoc_trace_out(sc, as, i + 1))
1698 			return 1;
1699 		/* If next failed, we should retry with next min */
1700 		hdafg_assoc_trace_undo(sc, as, i);
1701 		assocs[as].as_dacs[i] = 0;
1702 		minassoc = res + 1;
1703 	} while (1);
1704 }
1705 
1706 static int
1707 hdafg_assoc_trace_adc(struct hdafg_softc *sc, int assoc, int seq,
1708     int nid, int only, int depth)
1709 {
1710 	struct hdaudio_widget *w, *wc;
1711 	int i, j;
1712 	int res = 0;
1713 
1714 	if (depth > HDAUDIO_PARSE_MAXDEPTH)
1715 		return 0;
1716 	w = hdafg_widget_lookup(sc, nid);
1717 	if (w == NULL || w->w_enable == false)
1718 		return 0;
1719 	/* Use only unused widgets */
1720 	if (w->w_bindas >= 0 && w->w_bindas != assoc)
1721 		return 0;
1722 
1723 	switch (w->w_type) {
1724 	case COP_AWCAP_TYPE_AUDIO_INPUT:
1725 		if (only == w->w_nid)
1726 			res = 1;
1727 		break;
1728 	case COP_AWCAP_TYPE_PIN_COMPLEX:
1729 		if (depth > 0)
1730 			break;
1731 		/* FALLTHROUGH */
1732 	default:
1733 		/* Try to find reachable ADCs with specified nid */
1734 		for (j = sc->sc_startnode; j < sc->sc_endnode; j++) {
1735 			wc = hdafg_widget_lookup(sc, j);
1736 			if (w == NULL || w->w_enable == false)
1737 				continue;
1738 			for (i = 0; i < wc->w_nconns; i++) {
1739 				if (wc->w_connsenable[i] == false)
1740 					continue;
1741 				if (wc->w_conns[i] != nid)
1742 					continue;
1743 				if (hdafg_assoc_trace_adc(sc, assoc, seq,
1744 				    j, only, depth + 1) != 0) {
1745 					res = 1;
1746 					if (((wc->w_nconns > 1 &&
1747 					    wc->w_type != COP_AWCAP_TYPE_AUDIO_MIXER) ||
1748 					    wc->w_type != COP_AWCAP_TYPE_AUDIO_SELECTOR)
1749 					    && wc->w_selconn == -1)
1750 						wc->w_selconn = i;
1751 				}
1752 			}
1753 		}
1754 		break;
1755 	}
1756 	if (res) {
1757 		w->w_bindas = assoc;
1758 		w->w_bindseqmask |= (1 << seq);
1759 	}
1760 	return res;
1761 }
1762 
1763 static int
1764 hdafg_assoc_trace_in(struct hdafg_softc *sc, int assoc)
1765 {
1766 	struct hdaudio_assoc *as = sc->sc_assocs;
1767 	struct hdaudio_widget *w;
1768 	int i, j, k;
1769 
1770 	for (j = sc->sc_startnode; j < sc->sc_endnode; j++) {
1771 		w = hdafg_widget_lookup(sc, j);
1772 		if (w == NULL || w->w_enable == false)
1773 			continue;
1774 		if (w->w_type != COP_AWCAP_TYPE_AUDIO_INPUT)
1775 			continue;
1776 		if (w->w_bindas >= 0 && w->w_bindas != assoc)
1777 			continue;
1778 
1779 		/* Find next pin */
1780 		for (i = 0; i < HDAUDIO_MAXPINS; i++) {
1781 			if (as[assoc].as_pins[i] == 0)
1782 				continue;
1783 			/* Trace this pin taking goal into account */
1784 			if (hdafg_assoc_trace_adc(sc, assoc, i,
1785 			    as[assoc].as_pins[i], j, 0) == 0) {
1786 				hdafg_assoc_trace_undo(sc, assoc, -1);
1787 				for (k = 0; k < HDAUDIO_MAXPINS; k++)
1788 					as[assoc].as_dacs[k] = 0;
1789 				break;
1790 			}
1791 			as[assoc].as_dacs[i] = j;
1792 		}
1793 		if (i == HDAUDIO_MAXPINS)
1794 			return 1;
1795 	}
1796 	return 0;
1797 }
1798 
1799 static int
1800 hdafg_assoc_trace_to_out(struct hdafg_softc *sc, int nid, int depth)
1801 {
1802 	struct hdaudio_assoc *as = sc->sc_assocs;
1803 	struct hdaudio_widget *w, *wc;
1804 	int i, j;
1805 	int res = 0;
1806 
1807 	if (depth > HDAUDIO_PARSE_MAXDEPTH)
1808 		return 0;
1809 	w = hdafg_widget_lookup(sc, nid);
1810 	if (w == NULL || w->w_enable == false)
1811 		return 0;
1812 
1813 	/* Use only unused widgets */
1814 	if (depth > 0 && w->w_bindas != -1) {
1815 		if (w->w_bindas < 0 ||
1816 		    as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT) {
1817 			return 1;
1818 		} else {
1819 			return 0;
1820 		}
1821 	}
1822 
1823 	switch (w->w_type) {
1824 	case COP_AWCAP_TYPE_AUDIO_INPUT:
1825 		/* Do not traverse input (not yet supported) */
1826 		break;
1827 	case COP_AWCAP_TYPE_PIN_COMPLEX:
1828 		if (depth > 0)
1829 			break;
1830 		/* FALLTHROUGH */
1831 	default:
1832 		/* Try to find reachable ADCs with specified nid */
1833 		for (j = sc->sc_startnode; j < sc->sc_endnode; j++) {
1834 			wc = hdafg_widget_lookup(sc, j);
1835 			if (wc == NULL || wc->w_enable == false)
1836 				continue;
1837 			for (i = 0; i < wc->w_nconns; i++) {
1838 				if (wc->w_connsenable[i] == false)
1839 					continue;
1840 				if (wc->w_conns[i] != nid)
1841 					continue;
1842 				if (hdafg_assoc_trace_to_out(sc,
1843 				    j, depth + 1) != 0) {
1844 					res = 1;
1845 					if (wc->w_type ==
1846 					    COP_AWCAP_TYPE_AUDIO_SELECTOR &&
1847 					    wc->w_selconn == -1)
1848 						wc->w_selconn = i;
1849 				}
1850 			}
1851 		}
1852 		break;
1853 	}
1854 	if (res)
1855 		w->w_bindas = -2;
1856 	return res;
1857 }
1858 
1859 static void
1860 hdafg_assoc_trace_misc(struct hdafg_softc *sc)
1861 {
1862 	struct hdaudio_assoc *as = sc->sc_assocs;
1863 	struct hdaudio_widget *w;
1864 	int j;
1865 
1866 	/* Input monitor */
1867 	/*
1868 	 * Find mixer associated with input, but supplying signal
1869 	 * for output associations. Hope it will be input monitor.
1870 	 */
1871 	for (j = sc->sc_startnode; j < sc->sc_endnode; j++) {
1872 		w = hdafg_widget_lookup(sc, j);
1873 		if (w == NULL || w->w_enable == false)
1874 			continue;
1875 		if (w->w_type != COP_AWCAP_TYPE_AUDIO_MIXER)
1876 			continue;
1877 		if (w->w_bindas < 0 ||
1878 		    as[w->w_bindas].as_dir != HDAUDIO_PINDIR_IN)
1879 			continue;
1880 		if (hdafg_assoc_trace_to_out(sc, w->w_nid, 0)) {
1881 			w->w_pflags |= HDAUDIO_ADC_MONITOR;
1882 			w->w_audiodev = HDAUDIO_MIXER_IMIX;
1883 		}
1884 	}
1885 
1886 	/* Beeper */
1887 	for (j = sc->sc_startnode; j < sc->sc_endnode; j++) {
1888 		w = hdafg_widget_lookup(sc, j);
1889 		if (w == NULL || w->w_enable == false)
1890 			continue;
1891 		if (w->w_type != COP_AWCAP_TYPE_BEEP_GENERATOR)
1892 			continue;
1893 		if (hdafg_assoc_trace_to_out(sc, w->w_nid, 0)) {
1894 			hda_debug(sc, "beeper %02X traced to out\n", w->w_nid);
1895 		}
1896 		w->w_bindas = -2;
1897 	}
1898 }
1899 
1900 static void
1901 hdafg_build_tree(struct hdafg_softc *sc)
1902 {
1903 	struct hdaudio_assoc *as = sc->sc_assocs;
1904 	int i, j, res;
1905 
1906 	/* Trace all associations in order of their numbers */
1907 
1908 	/* Trace DACs first */
1909 	for (j = 0; j < sc->sc_nassocs; j++) {
1910 		if (as[j].as_enable == false)
1911 			continue;
1912 		if (as[j].as_dir != HDAUDIO_PINDIR_OUT)
1913 			continue;
1914 retry:
1915 		res = hdafg_assoc_trace_out(sc, j, 0);
1916 		if (res == 0 && as[j].as_hpredir >= 0 &&
1917 		    as[j].as_fakeredir == 0) {
1918 			/*
1919 			 * If codec can't do analog HP redirection
1920 			 * try to make it using one more DAC
1921 			 */
1922 			as[j].as_fakeredir = 1;
1923 			goto retry;
1924 		}
1925 		if (!res) {
1926 			hda_debug(sc, "disable assoc %d (%d) [trace failed]\n",
1927 			    j, as[j].as_index);
1928 			for (i = 0; i < HDAUDIO_MAXPINS; i++) {
1929 				if (as[j].as_pins[i] == 0)
1930 					continue;
1931 				hda_debug(sc, "  assoc %d pin%d: %02X\n", j, i,
1932 				    as[j].as_pins[i]);
1933 			}
1934 			for (i = 0; i < HDAUDIO_MAXPINS; i++) {
1935 				if (as[j].as_dacs[i] == 0)
1936 					continue;
1937 				hda_debug(sc, "  assoc %d dac%d: %02X\n", j, i,
1938 				    as[j].as_dacs[i]);
1939 			}
1940 
1941 			as[j].as_enable = false;
1942 		}
1943 	}
1944 
1945 	/* Trace ADCs */
1946 	for (j = 0; j < sc->sc_nassocs; j++) {
1947 		if (as[j].as_enable == false)
1948 			continue;
1949 		if (as[j].as_dir != HDAUDIO_PINDIR_IN)
1950 			continue;
1951 		res = hdafg_assoc_trace_in(sc, j);
1952 		if (!res) {
1953 			hda_debug(sc, "disable assoc %d (%d) [trace failed]\n",
1954 			    j, as[j].as_index);
1955 			for (i = 0; i < HDAUDIO_MAXPINS; i++) {
1956 				if (as[j].as_pins[i] == 0)
1957 					continue;
1958 				hda_debug(sc, "  assoc %d pin%d: %02X\n", j, i,
1959 				    as[j].as_pins[i]);
1960 			}
1961 			for (i = 0; i < HDAUDIO_MAXPINS; i++) {
1962 				if (as[j].as_dacs[i] == 0)
1963 					continue;
1964 				hda_debug(sc, "  assoc %d adc%d: %02X\n", j, i,
1965 				    as[j].as_dacs[i]);
1966 			}
1967 
1968 			as[j].as_enable = false;
1969 		}
1970 	}
1971 
1972 	/* Trace mixer and beeper pseudo associations */
1973 	hdafg_assoc_trace_misc(sc);
1974 }
1975 
1976 static void
1977 hdafg_prepare_pin_controls(struct hdafg_softc *sc)
1978 {
1979 	struct hdaudio_assoc *as = sc->sc_assocs;
1980 	struct hdaudio_widget *w;
1981 	uint32_t pincap;
1982 	int i;
1983 
1984 	hda_debug(sc, "*** prepare pin controls, nwidgets = %d\n",
1985 	    sc->sc_nwidgets);
1986 
1987 	for (i = 0; i < sc->sc_nwidgets; i++) {
1988 		w = &sc->sc_widgets[i];
1989 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX) {
1990 			hda_debug(sc, "  skipping pin %02X type 0x%x\n",
1991 			    w->w_nid, w->w_type);
1992 			continue;
1993 		}
1994 		pincap = w->w_pin.cap;
1995 
1996 		/* Disable everything */
1997 		w->w_pin.ctrl &= ~(
1998 		    COP_PWC_VREF_ENABLE_MASK |
1999 		    COP_PWC_IN_ENABLE |
2000 		    COP_PWC_OUT_ENABLE |
2001 		    COP_PWC_HPHN_ENABLE);
2002 
2003 		if (w->w_enable == false ||
2004 		    w->w_bindas < 0 || as[w->w_bindas].as_enable == false) {
2005 			/* Pin is unused so leave it disabled */
2006 			if ((pincap & (COP_PINCAP_OUTPUT_CAPABLE |
2007 			    COP_PINCAP_INPUT_CAPABLE)) ==
2008 			    (COP_PINCAP_OUTPUT_CAPABLE |
2009 			    COP_PINCAP_INPUT_CAPABLE)) {
2010 				hda_debug(sc, "pin %02X off, "
2011 				    "in/out capable (bindas=%d "
2012 				    "enable=%d as_enable=%d)\n",
2013 				    w->w_nid, w->w_bindas, w->w_enable,
2014 				    w->w_bindas >= 0 ?
2015 				    as[w->w_bindas].as_enable : -1);
2016 				w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
2017 			} else
2018 				hda_debug(sc, "pin %02X off\n", w->w_nid);
2019 			continue;
2020 		} else if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_IN) {
2021 			/* Input pin, configure for input */
2022 			if (pincap & COP_PINCAP_INPUT_CAPABLE)
2023 				w->w_pin.ctrl |= COP_PWC_IN_ENABLE;
2024 
2025 			hda_debug(sc, "pin %02X in ctrl 0x%x\n", w->w_nid,
2026 			    w->w_pin.ctrl);
2027 
2028 			if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) !=
2029 			    COP_DEVICE_MIC_IN)
2030 				continue;
2031 			if (COP_PINCAP_VREF_CONTROL(pincap) & COP_VREF_80)
2032 				w->w_pin.ctrl |= COP_PWC_VREF_80;
2033 			else if (COP_PINCAP_VREF_CONTROL(pincap) & COP_VREF_50)
2034 				w->w_pin.ctrl |= COP_PWC_VREF_50;
2035 		} else {
2036 			/* Output pin, configure for output */
2037 			if (pincap & COP_PINCAP_OUTPUT_CAPABLE)
2038 				w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
2039 			if ((pincap & COP_PINCAP_HEADPHONE_DRIVE_CAPABLE) &&
2040 			    (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) ==
2041 			    COP_DEVICE_HP_OUT))
2042 				w->w_pin.ctrl |= COP_PWC_HPHN_ENABLE;
2043 			/* XXX VREF */
2044 			hda_debug(sc, "pin %02X out ctrl 0x%x\n", w->w_nid,
2045 			    w->w_pin.ctrl);
2046 		}
2047 	}
2048 }
2049 
2050 #if defined(HDAFG_DEBUG) && HDAFG_DEBUG > 1
2051 static void
2052 hdafg_dump_ctl(const struct hdafg_softc *sc, const struct hdaudio_control *ctl)
2053 {
2054 	int type = ctl->ctl_widget ? ctl->ctl_widget->w_type : -1;
2055 	int i = (int)(ctl - sc->sc_ctls);
2056 
2057 	hda_print(sc, "%03X: nid %02X type %d %s (%s) index %d",
2058 	    i, (ctl->ctl_widget ? ctl->ctl_widget->w_nid : -1), type,
2059 	    ctl->ctl_ndir == HDAUDIO_PINDIR_IN ? "in " : "out",
2060 	    ctl->ctl_dir == HDAUDIO_PINDIR_IN ? "in " : "out",
2061 	    ctl->ctl_index);
2062 
2063 	if (ctl->ctl_childwidget)
2064 		hda_print1(sc, " cnid %02X", ctl->ctl_childwidget->w_nid);
2065 	else
2066 		hda_print1(sc, "          ");
2067 	hda_print1(sc, "\n");
2068 	hda_print(sc, "     mute: %d step: %3d size: %3d off: %3d%s\n",
2069 	    ctl->ctl_mute, ctl->ctl_step, ctl->ctl_size,
2070 	    ctl->ctl_offset, ctl->ctl_enable == false ? " [DISABLED]" : "");
2071 }
2072 #endif
2073 
2074 static void
2075 hdafg_dump(const struct hdafg_softc *sc)
2076 {
2077 #if defined(HDAFG_DEBUG) && HDAFG_DEBUG > 1
2078 	for (int i = 0; i < sc->sc_nctls; i++)
2079 		hdafg_dump_ctl(sc, &sc->sc_ctls[i]);
2080 #endif
2081 }
2082 
2083 static int
2084 hdafg_match(device_t parent, cfdata_t match, void *opaque)
2085 {
2086 	prop_dictionary_t args = opaque;
2087 	uint8_t fgtype;
2088 	bool rv;
2089 
2090 	rv = prop_dictionary_get_uint8(args, "function-group-type", &fgtype);
2091 	if (rv == false || fgtype != HDAUDIO_GROUP_TYPE_AFG)
2092 		return 0;
2093 
2094 	return 1;
2095 }
2096 
2097 static void
2098 hdafg_disable_unassoc(struct hdafg_softc *sc)
2099 {
2100 	struct hdaudio_assoc *as = sc->sc_assocs;
2101 	struct hdaudio_widget *w, *cw;
2102 	struct hdaudio_control *ctl;
2103 	int i, j, k;
2104 
2105 	/* Disable unassociated widgets */
2106 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2107 		w = hdafg_widget_lookup(sc, i);
2108 		if (w == NULL || w->w_enable == false)
2109 			continue;
2110 		if (w->w_bindas == -1) {
2111 			w->w_enable = 0;
2112 			hda_trace(sc, "disable %02X [unassociated]\n",
2113 			    w->w_nid);
2114 		}
2115 	}
2116 
2117 	/* Disable input connections on input pin and output on output */
2118 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2119 		w = hdafg_widget_lookup(sc, i);
2120 		if (w == NULL || w->w_enable == false)
2121 			continue;
2122 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
2123 			continue;
2124 		if (w->w_bindas < 0)
2125 			continue;
2126 		if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_IN) {
2127 			hda_trace(sc, "disable %02X input connections\n",
2128 			    w->w_nid);
2129 			for (j = 0; j < w->w_nconns; j++)
2130 				w->w_connsenable[j] = false;
2131 			ctl = hdafg_control_lookup(sc, w->w_nid,
2132 			    HDAUDIO_PINDIR_IN, -1, 1);
2133 			if (ctl && ctl->ctl_enable == true) {
2134 				ctl->ctl_forcemute = 1;
2135 				ctl->ctl_muted = HDAUDIO_AMP_MUTE_ALL;
2136 				ctl->ctl_left = ctl->ctl_right = 0;
2137 				ctl->ctl_enable = false;
2138 			}
2139 		} else {
2140 			ctl = hdafg_control_lookup(sc, w->w_nid,
2141 			    HDAUDIO_PINDIR_OUT, -1, 1);
2142 			if (ctl && ctl->ctl_enable == true) {
2143 				ctl->ctl_forcemute = 1;
2144 				ctl->ctl_muted = HDAUDIO_AMP_MUTE_ALL;
2145 				ctl->ctl_left = ctl->ctl_right = 0;
2146 				ctl->ctl_enable = false;
2147 			}
2148 			for (k = sc->sc_startnode; k < sc->sc_endnode; k++) {
2149 				cw = hdafg_widget_lookup(sc, k);
2150 				if (cw == NULL || cw->w_enable == false)
2151 					continue;
2152 				for (j = 0; j < cw->w_nconns; j++) {
2153 					if (!cw->w_connsenable[j])
2154 						continue;
2155 					if (cw->w_conns[j] != i)
2156 						continue;
2157 					hda_trace(sc, "disable %02X -> %02X "
2158 					    "output connection\n",
2159 					    cw->w_nid, cw->w_conns[j]);
2160 					cw->w_connsenable[j] = false;
2161 					if (cw->w_type ==
2162 					    COP_AWCAP_TYPE_PIN_COMPLEX &&
2163 					    cw->w_nconns > 1)
2164 						continue;
2165 					ctl = hdafg_control_lookup(sc,
2166 					    k, HDAUDIO_PINDIR_IN, j, 1);
2167 					if (ctl && ctl->ctl_enable == true) {
2168 						ctl->ctl_forcemute = 1;
2169 						ctl->ctl_muted =
2170 						    HDAUDIO_AMP_MUTE_ALL;
2171 						ctl->ctl_left =
2172 						    ctl->ctl_right = 0;
2173 						ctl->ctl_enable = false;
2174 					}
2175 				}
2176 			}
2177 		}
2178 	}
2179 }
2180 
2181 static void
2182 hdafg_disable_unsel(struct hdafg_softc *sc)
2183 {
2184 	struct hdaudio_assoc *as = sc->sc_assocs;
2185 	struct hdaudio_widget *w;
2186 	int i, j;
2187 
2188 	/* On playback path we can safely disable all unselected inputs */
2189 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2190 		w = hdafg_widget_lookup(sc, i);
2191 		if (w == NULL || w->w_enable == false)
2192 			continue;
2193 		if (w->w_nconns <= 1)
2194 			continue;
2195 		if (w->w_type == COP_AWCAP_TYPE_AUDIO_MIXER)
2196 			continue;
2197 		if (w->w_bindas < 0 ||
2198 		    as[w->w_bindas].as_dir == HDAUDIO_PINDIR_IN)
2199 			continue;
2200 		for (j = 0; j < w->w_nconns; j++) {
2201 			if (w->w_connsenable[j] == false)
2202 				continue;
2203 			if (w->w_selconn < 0 || w->w_selconn == j)
2204 				continue;
2205 			hda_trace(sc, "disable %02X->%02X [unselected]\n",
2206 			    w->w_nid, w->w_conns[j]);
2207 			w->w_connsenable[j] = false;
2208 		}
2209 	}
2210 }
2211 
2212 static void
2213 hdafg_disable_crossassoc(struct hdafg_softc *sc)
2214 {
2215 	struct hdaudio_widget *w, *cw;
2216 	struct hdaudio_control *ctl;
2217 	int i, j;
2218 
2219 	/* Disable cross associated and unwanted cross channel connections */
2220 
2221 	/* ... using selectors */
2222 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2223 		w = hdafg_widget_lookup(sc, i);
2224 		if (w == NULL || w->w_enable == false)
2225 			continue;
2226 		if (w->w_nconns <= 1)
2227 			continue;
2228 		if (w->w_type == COP_AWCAP_TYPE_AUDIO_MIXER)
2229 			continue;
2230 		if (w->w_bindas == -2)
2231 			continue;
2232 		for (j = 0; j < w->w_nconns; j++) {
2233 			if (w->w_connsenable[j] == false)
2234 				continue;
2235 			cw = hdafg_widget_lookup(sc, w->w_conns[j]);
2236 			if (cw == NULL || cw->w_enable == false)
2237 				continue;
2238 			if (cw->w_bindas == -2)
2239 				continue;
2240 			if (w->w_bindas == cw->w_bindas &&
2241 			    (w->w_bindseqmask & cw->w_bindseqmask) != 0)
2242 				continue;
2243 			hda_trace(sc, "disable %02X->%02X [crossassoc]\n",
2244 			    w->w_nid, w->w_conns[j]);
2245 			w->w_connsenable[j] = false;
2246 		}
2247 	}
2248 	/* ... using controls */
2249 	for (i = 0; i < sc->sc_nctls; i++) {
2250 		ctl = &sc->sc_ctls[i];
2251 		if (ctl->ctl_enable == false || ctl->ctl_childwidget == NULL)
2252 			continue;
2253 		if (ctl->ctl_widget->w_bindas == -2 ||
2254 		    ctl->ctl_childwidget->w_bindas == -2)
2255 			continue;
2256 		if (ctl->ctl_widget->w_bindas !=
2257 		    ctl->ctl_childwidget->w_bindas ||
2258 		    (ctl->ctl_widget->w_bindseqmask &
2259 		    ctl->ctl_childwidget->w_bindseqmask) == 0) {
2260 			ctl->ctl_forcemute = 1;
2261 			ctl->ctl_muted = HDAUDIO_AMP_MUTE_ALL;
2262 			ctl->ctl_left = ctl->ctl_right = 0;
2263 			ctl->ctl_enable = false;
2264 			if (ctl->ctl_ndir == HDAUDIO_PINDIR_IN) {
2265 				hda_trace(sc, "disable ctl %d:%02X:%02X "
2266 				    "[crossassoc]\n",
2267 				    i, ctl->ctl_widget->w_nid,
2268 				    ctl->ctl_widget->w_conns[ctl->ctl_index]);
2269 				ctl->ctl_widget->w_connsenable[
2270 				    ctl->ctl_index] = false;
2271 			}
2272 		}
2273 	}
2274 }
2275 
2276 static struct hdaudio_control *
2277 hdafg_control_amp_get(struct hdafg_softc *sc, int nid,
2278     enum hdaudio_pindir dir, int index, int cnt)
2279 {
2280 	struct hdaudio_control *ctl;
2281 	int i, found = 0;
2282 
2283 	for (i = 0; i < sc->sc_nctls; i++) {
2284 		ctl = &sc->sc_ctls[i];
2285 		if (ctl->ctl_enable == false)
2286 			continue;
2287 		if (ctl->ctl_widget->w_nid != nid)
2288 			continue;
2289 		if (dir && ctl->ctl_ndir != dir)
2290 			continue;
2291 		if (index >= 0 && ctl->ctl_ndir == HDAUDIO_PINDIR_IN &&
2292 		    ctl->ctl_dir == ctl->ctl_ndir &&
2293 		    ctl->ctl_index != index)
2294 			continue;
2295 		++found;
2296 		if (found == cnt || cnt <= 0)
2297 			return ctl;
2298 	}
2299 
2300 	return NULL;
2301 }
2302 
2303 static void
2304 hdafg_control_amp_set1(struct hdaudio_control *ctl, int lmute, int rmute,
2305     int left, int right, int dir)
2306 {
2307 	struct hdafg_softc *sc = ctl->ctl_widget->w_afg;
2308 	int index = ctl->ctl_index;
2309 	uint16_t v = 0;
2310 
2311 	if (left != right || lmute != rmute) {
2312 		v = (1 << (15 - dir)) | (1 << 13) | (index << 8) |
2313 		    (lmute << 7) | left;
2314 		hdaudio_command(sc->sc_codec, ctl->ctl_widget->w_nid,
2315 		    CORB_SET_AMPLIFIER_GAIN_MUTE, v);
2316 		v = (1 << (15 - dir)) | (1 << 12) | (index << 8) |
2317 		    (rmute << 7) | right;
2318 	} else
2319 		v = (1 << (15 - dir)) | (3 << 12) | (index << 8) |
2320 		    (lmute << 7) | left;
2321 	hdaudio_command(sc->sc_codec, ctl->ctl_widget->w_nid,
2322 	    CORB_SET_AMPLIFIER_GAIN_MUTE, v);
2323 }
2324 
2325 static void
2326 hdafg_control_amp_set(struct hdaudio_control *ctl, uint32_t mute,
2327     int left, int right)
2328 {
2329 	int lmute, rmute;
2330 
2331 	/* Save new values if valid */
2332 	if (mute != HDAUDIO_AMP_MUTE_DEFAULT)
2333 		ctl->ctl_muted = mute;
2334 	if (left != HDAUDIO_AMP_VOL_DEFAULT)
2335 		ctl->ctl_left = left;
2336 	if (right != HDAUDIO_AMP_VOL_DEFAULT)
2337 		ctl->ctl_right = right;
2338 
2339 	/* Prepare effective values */
2340 	if (ctl->ctl_forcemute) {
2341 		lmute = rmute = 1;
2342 		left = right = 0;
2343 	} else {
2344 		lmute = HDAUDIO_AMP_LEFT_MUTED(ctl->ctl_muted);
2345 		rmute = HDAUDIO_AMP_RIGHT_MUTED(ctl->ctl_muted);
2346 		left = ctl->ctl_left;
2347 		right = ctl->ctl_right;
2348 	}
2349 
2350 	/* Apply effective values */
2351 	if (ctl->ctl_dir & HDAUDIO_PINDIR_OUT)
2352 		hdafg_control_amp_set1(ctl, lmute, rmute, left, right, 0);
2353 	if (ctl->ctl_dir & HDAUDIO_PINDIR_IN)
2354 		hdafg_control_amp_set1(ctl, lmute, rmute, left, right, 1);
2355 }
2356 
2357 /*
2358  * Muting the input pins directly does not work, we mute the mixers which
2359  * are parents to them
2360  */
2361 static bool
2362 hdafg_mixer_child_is_input(const struct hdafg_softc *sc,
2363     const struct hdaudio_control *ctl)
2364 {
2365 	const struct hdaudio_widget *w;
2366 	const struct hdaudio_assoc *as = sc->sc_assocs;
2367 
2368 	switch (ctl->ctl_widget->w_type) {
2369 	case COP_AWCAP_TYPE_AUDIO_INPUT:
2370 		return true;
2371 
2372 	case COP_AWCAP_TYPE_AUDIO_MIXER:
2373 		w = ctl->ctl_childwidget;
2374 		if (w == NULL)
2375 			return false;
2376 
2377 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
2378 			return false;
2379 
2380 		if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2381 			return false;
2382 
2383 		switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
2384 		case COP_DEVICE_MIC_IN:
2385 		case COP_DEVICE_LINE_IN:
2386 		case COP_DEVICE_SPDIF_IN:
2387 		case COP_DEVICE_DIGITAL_OTHER_IN:
2388 			return true;
2389 		default:
2390 			return false;
2391 		}
2392 
2393 	default:
2394 		return false;
2395 	}
2396 }
2397 
2398 static void
2399 hdafg_control_commit(struct hdafg_softc *sc)
2400 {
2401 	struct hdaudio_control *ctl;
2402 	int i, z;
2403 
2404 	for (i = 0; i < sc->sc_nctls; i++) {
2405 		ctl = &sc->sc_ctls[i];
2406 		//if (ctl->ctl_enable == false || ctl->ctl_audiomask != 0)
2407 		if (ctl->ctl_enable == false)
2408 			continue;
2409 		/* Init fixed controls to 0dB amplification */
2410 		z = ctl->ctl_offset;
2411 		if (z > ctl->ctl_step)
2412 			z = ctl->ctl_step;
2413 
2414 		if (hdafg_mixer_child_is_input(sc, ctl))
2415 			hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_ALL, z, z);
2416 		else
2417 			hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_NONE, z, z);
2418 	}
2419 }
2420 
2421 static void
2422 hdafg_widget_connection_select(struct hdaudio_widget *w, uint8_t index)
2423 {
2424 	struct hdafg_softc *sc = w->w_afg;
2425 
2426 	if (w->w_nconns < 1 || index > (w->w_nconns - 1))
2427 		return;
2428 
2429 	hdaudio_command(sc->sc_codec, w->w_nid,
2430 	    CORB_SET_CONNECTION_SELECT_CONTROL, index);
2431 	w->w_selconn = index;
2432 }
2433 
2434 static void
2435 hdafg_assign_names(struct hdafg_softc *sc)
2436 {
2437 	struct hdaudio_assoc *as = sc->sc_assocs;
2438 	struct hdaudio_widget *w;
2439 	int i, j;
2440 	int type = -1, use, used =0;
2441 	static const int types[7][13] = {
2442 	    { HDAUDIO_MIXER_LINE, HDAUDIO_MIXER_LINE1, HDAUDIO_MIXER_LINE2,
2443 	      HDAUDIO_MIXER_LINE3, -1 },
2444 	    { HDAUDIO_MIXER_MONITOR, HDAUDIO_MIXER_MIC, -1 }, /* int mic */
2445 	    { HDAUDIO_MIXER_MIC, HDAUDIO_MIXER_MONITOR, -1 }, /* ext mic */
2446 	    { HDAUDIO_MIXER_CD, -1 },
2447 	    { HDAUDIO_MIXER_SPEAKER, -1 },
2448 	    { HDAUDIO_MIXER_DIGITAL1, HDAUDIO_MIXER_DIGITAL2,
2449 	      HDAUDIO_MIXER_DIGITAL3, -1 },
2450 	    { HDAUDIO_MIXER_LINE, HDAUDIO_MIXER_LINE1, HDAUDIO_MIXER_LINE2,
2451 	      HDAUDIO_MIXER_LINE3, HDAUDIO_MIXER_PHONEIN,
2452 	      HDAUDIO_MIXER_PHONEOUT, HDAUDIO_MIXER_VIDEO, HDAUDIO_MIXER_RADIO,
2453 	      HDAUDIO_MIXER_DIGITAL1, HDAUDIO_MIXER_DIGITAL2,
2454 	      HDAUDIO_MIXER_DIGITAL3, HDAUDIO_MIXER_MONITOR, -1 } /* others */
2455 	};
2456 
2457 	/* Surely known names */
2458 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2459 		w = hdafg_widget_lookup(sc, i);
2460 		if (w == NULL || w->w_enable == false)
2461 			continue;
2462 		if (w->w_bindas == -1)
2463 			continue;
2464 		use = -1;
2465 		switch (w->w_type) {
2466 		case COP_AWCAP_TYPE_PIN_COMPLEX:
2467 			if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2468 				break;
2469 			type = -1;
2470 			switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
2471 			case COP_DEVICE_LINE_IN:
2472 				type = 0;
2473 				break;
2474 			case COP_DEVICE_MIC_IN:
2475 				if (COP_CFG_PORT_CONNECTIVITY(w->w_pin.config)
2476 				    == COP_PORT_JACK)
2477 					break;
2478 				type = 1;
2479 				break;
2480 			case COP_DEVICE_CD:
2481 				type = 3;
2482 				break;
2483 			case COP_DEVICE_SPEAKER:
2484 				type = 4;
2485 				break;
2486 			case COP_DEVICE_SPDIF_IN:
2487 			case COP_DEVICE_DIGITAL_OTHER_IN:
2488 				type = 5;
2489 				break;
2490 			}
2491 			if (type == -1)
2492 				break;
2493 			j = 0;
2494 			while (types[type][j] >= 0 &&
2495 			    (used & (1 << types[type][j])) != 0) {
2496 				j++;
2497 			}
2498 			if (types[type][j] >= 0)
2499 				use = types[type][j];
2500 			break;
2501 		case COP_AWCAP_TYPE_AUDIO_OUTPUT:
2502 			use = HDAUDIO_MIXER_PCM;
2503 			break;
2504 		case COP_AWCAP_TYPE_BEEP_GENERATOR:
2505 			use = HDAUDIO_MIXER_SPEAKER;
2506 			break;
2507 		default:
2508 			break;
2509 		}
2510 		if (use >= 0) {
2511 			w->w_audiodev = use;
2512 			used |= (1 << use);
2513 		}
2514 	}
2515 	/* Semi-known names */
2516 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2517 		w = hdafg_widget_lookup(sc, i);
2518 		if (w == NULL || w->w_enable == false)
2519 			continue;
2520 		if (w->w_audiodev >= 0)
2521 			continue;
2522 		if (w->w_bindas == -1)
2523 			continue;
2524 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
2525 			continue;
2526 		if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2527 			continue;
2528 		type = -1;
2529 		switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
2530 		case COP_DEVICE_LINE_OUT:
2531 		case COP_DEVICE_SPEAKER:
2532 		case COP_DEVICE_HP_OUT:
2533 		case COP_DEVICE_AUX:
2534 			type = 0;
2535 			break;
2536 		case COP_DEVICE_MIC_IN:
2537 			type = 2;
2538 			break;
2539 		case COP_DEVICE_SPDIF_OUT:
2540 		case COP_DEVICE_DIGITAL_OTHER_OUT:
2541 			type = 5;
2542 			break;
2543 		}
2544 		if (type == -1)
2545 			break;
2546 		j = 0;
2547 		while (types[type][j] >= 0 &&
2548 		    (used & (1 << types[type][j])) != 0) {
2549 			j++;
2550 		}
2551 		if (types[type][j] >= 0) {
2552 			w->w_audiodev = types[type][j];
2553 			used |= (1 << types[type][j]);
2554 		}
2555 	}
2556 	/* Others */
2557 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2558 		w = hdafg_widget_lookup(sc, i);
2559 		if (w == NULL || w->w_enable == false)
2560 			continue;
2561 		if (w->w_audiodev >= 0)
2562 			continue;
2563 		if (w->w_bindas == -1)
2564 			continue;
2565 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
2566 			continue;
2567 		if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2568 			continue;
2569 		j = 0;
2570 		while (types[6][j] >= 0 &&
2571 		    (used & (1 << types[6][j])) != 0) {
2572 			j++;
2573 		}
2574 		if (types[6][j] >= 0) {
2575 			w->w_audiodev = types[6][j];
2576 			used |= (1 << types[6][j]);
2577 		}
2578 	}
2579 }
2580 
2581 static int
2582 hdafg_control_source_amp(struct hdafg_softc *sc, int nid, int index,
2583     int audiodev, int ctlable, int depth, int need)
2584 {
2585 	struct hdaudio_widget *w, *wc;
2586 	struct hdaudio_control *ctl;
2587 	int i, j, conns = 0, rneed;
2588 
2589 	if (depth >= HDAUDIO_PARSE_MAXDEPTH)
2590 		return need;
2591 
2592 	w = hdafg_widget_lookup(sc, nid);
2593 	if (w == NULL || w->w_enable == false)
2594 		return need;
2595 
2596 	/* Count number of active inputs */
2597 	if (depth > 0) {
2598 		for (j = 0; j < w->w_nconns; j++) {
2599 			if (w->w_connsenable[j])
2600 				++conns;
2601 		}
2602 	}
2603 
2604 	/*
2605 	 * If this is not a first step, use input mixer. Pins have common
2606 	 * input ctl so care must be taken
2607 	 */
2608 	if (depth > 0 && ctlable && (conns == 1 ||
2609 	    w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)) {
2610 		ctl = hdafg_control_amp_get(sc, w->w_nid,
2611 		    HDAUDIO_PINDIR_IN, index, 1);
2612 		if (ctl) {
2613 			if (HDAUDIO_CONTROL_GIVE(ctl) & need)
2614 				ctl->ctl_audiomask |= (1 << audiodev);
2615 			else
2616 				ctl->ctl_paudiomask |= (1 << audiodev);
2617 			need &= ~HDAUDIO_CONTROL_GIVE(ctl);
2618 		}
2619 	}
2620 
2621 	/* If widget has own audiodev, don't traverse it. */
2622 	if (w->w_audiodev >= 0 && depth > 0)
2623 		return need;
2624 
2625 	/* We must not traverse pins */
2626 	if ((w->w_type == COP_AWCAP_TYPE_AUDIO_INPUT ||
2627 	    w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX) && depth > 0)
2628 		return need;
2629 
2630 	/* Record that this widget exports such signal */
2631 	w->w_audiomask |= (1 << audiodev);
2632 
2633 	/*
2634 	 * If signals mixed, we can't assign controls further. Ignore this
2635 	 * on depth zero. Caller must know why. Ignore this for static
2636 	 * selectors if this input is selected.
2637 	 */
2638 	if (conns > 1)
2639 		ctlable = 0;
2640 
2641 	if (ctlable) {
2642 		ctl = hdafg_control_amp_get(sc, w->w_nid,
2643 		    HDAUDIO_PINDIR_OUT, -1, 1);
2644 		if (ctl) {
2645 			if (HDAUDIO_CONTROL_GIVE(ctl) & need)
2646 				ctl->ctl_audiomask |= (1 << audiodev);
2647 			else
2648 				ctl->ctl_paudiomask |= (1 << audiodev);
2649 			need &= ~HDAUDIO_CONTROL_GIVE(ctl);
2650 		}
2651 	}
2652 
2653 	rneed = 0;
2654 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2655 		wc = hdafg_widget_lookup(sc, i);
2656 		if (wc == NULL || wc->w_enable == false)
2657 			continue;
2658 		for (j = 0; j < wc->w_nconns; j++) {
2659 			if (wc->w_connsenable[j] && wc->w_conns[j] == nid) {
2660 				rneed |= hdafg_control_source_amp(sc,
2661 				    wc->w_nid, j, audiodev, ctlable, depth + 1,
2662 				    need);
2663 			}
2664 		}
2665 	}
2666 	rneed &= need;
2667 
2668 	return rneed;
2669 }
2670 
2671 static void
2672 hdafg_control_dest_amp(struct hdafg_softc *sc, int nid,
2673     int audiodev, int depth, int need)
2674 {
2675 	struct hdaudio_assoc *as = sc->sc_assocs;
2676 	struct hdaudio_widget *w, *wc;
2677 	struct hdaudio_control *ctl;
2678 	int i, j, consumers;
2679 
2680 	if (depth > HDAUDIO_PARSE_MAXDEPTH)
2681 		return;
2682 
2683 	w = hdafg_widget_lookup(sc, nid);
2684 	if (w == NULL || w->w_enable == false)
2685 		return;
2686 
2687 	if (depth > 0) {
2688 		/*
2689 		 * If this node produces output for several consumers,
2690 		 * we can't touch it
2691 		 */
2692 		consumers = 0;
2693 		for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2694 			wc = hdafg_widget_lookup(sc, i);
2695 			if (wc == NULL || wc->w_enable == false)
2696 				continue;
2697 			for (j = 0; j < wc->w_nconns; j++) {
2698 				if (wc->w_connsenable[j] &&
2699 				    wc->w_conns[j] == nid)
2700 					++consumers;
2701 			}
2702 		}
2703 		/*
2704 		 * The only exception is if real HP redirection is configured
2705 		 * and this is a duplication point.
2706 		 * XXX: Not completely correct.
2707 		 */
2708 		if ((consumers == 2 && (w->w_bindas < 0 ||
2709 		    as[w->w_bindas].as_hpredir < 0 ||
2710 		    as[w->w_bindas].as_fakeredir ||
2711 		    (w->w_bindseqmask & (1 << 15)) == 0)) ||
2712 		    consumers > 2)
2713 			return;
2714 
2715 		/* Else use its output mixer */
2716 		ctl = hdafg_control_amp_get(sc, w->w_nid,
2717 		    HDAUDIO_PINDIR_OUT, -1, 1);
2718 		if (ctl) {
2719 			if (HDAUDIO_CONTROL_GIVE(ctl) & need)
2720 				ctl->ctl_audiomask |= (1 << audiodev);
2721 			else
2722 				ctl->ctl_paudiomask |= (1 << audiodev);
2723 			need &= ~HDAUDIO_CONTROL_GIVE(ctl);
2724 		}
2725 	}
2726 
2727 	/* We must not traverse pin */
2728 	if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX && depth > 0)
2729 		return;
2730 
2731 	for (i = 0; i < w->w_nconns; i++) {
2732 		int tneed = need;
2733 		if (w->w_connsenable[i] == false)
2734 			continue;
2735 		ctl = hdafg_control_amp_get(sc, w->w_nid,
2736 		    HDAUDIO_PINDIR_IN, i, 1);
2737 		if (ctl) {
2738 			if (HDAUDIO_CONTROL_GIVE(ctl) & tneed)
2739 				ctl->ctl_audiomask |= (1 << audiodev);
2740 			else
2741 				ctl->ctl_paudiomask |= (1 << audiodev);
2742 			tneed &= ~HDAUDIO_CONTROL_GIVE(ctl);
2743 		}
2744 		hdafg_control_dest_amp(sc, w->w_conns[i], audiodev,
2745 		    depth + 1, tneed);
2746 	}
2747 }
2748 
2749 static void
2750 hdafg_assign_mixers(struct hdafg_softc *sc)
2751 {
2752 	struct hdaudio_assoc *as = sc->sc_assocs;
2753 	struct hdaudio_control *ctl;
2754 	struct hdaudio_widget *w;
2755 	int i;
2756 
2757 	/* Assign mixers to the tree */
2758 	for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2759 		w = hdafg_widget_lookup(sc, i);
2760 		if (w == NULL || w->w_enable == FALSE)
2761 			continue;
2762 		if (w->w_type == COP_AWCAP_TYPE_AUDIO_OUTPUT ||
2763 		    w->w_type == COP_AWCAP_TYPE_BEEP_GENERATOR ||
2764 		    (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX &&
2765 		    as[w->w_bindas].as_dir == HDAUDIO_PINDIR_IN)) {
2766 			if (w->w_audiodev < 0)
2767 				continue;
2768 			hdafg_control_source_amp(sc, w->w_nid, -1,
2769 			    w->w_audiodev, 1, 0, 1);
2770 		} else if (w->w_pflags & HDAUDIO_ADC_MONITOR) {
2771 			if (w->w_audiodev < 0)
2772 				continue;
2773 			if (hdafg_control_source_amp(sc, w->w_nid, -1,
2774 			    w->w_audiodev, 1, 0, 1)) {
2775 				/* If we are unable to control input monitor
2776 				   as source, try to control it as dest */
2777 				hdafg_control_dest_amp(sc, w->w_nid,
2778 				    w->w_audiodev, 0, 1);
2779 			}
2780 		} else if (w->w_type == COP_AWCAP_TYPE_AUDIO_INPUT) {
2781 			hdafg_control_dest_amp(sc, w->w_nid,
2782 			    HDAUDIO_MIXER_RECLEV, 0, 1);
2783 		} else if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX &&
2784 		    as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT) {
2785 			hdafg_control_dest_amp(sc, w->w_nid,
2786 			    HDAUDIO_MIXER_VOLUME, 0, 1);
2787 		}
2788 	}
2789 	/* Treat unrequired as possible */
2790 	for (i = 0; i < sc->sc_nctls; i++) {
2791 		ctl = &sc->sc_ctls[i];
2792 		if (ctl->ctl_audiomask == 0)
2793 			ctl->ctl_audiomask = ctl->ctl_paudiomask;
2794 	}
2795 }
2796 
2797 static void
2798 hdafg_build_mixers(struct hdafg_softc *sc)
2799 {
2800 	struct hdaudio_mixer *mx;
2801 	struct hdaudio_control *ctl, *masterctl = NULL;
2802 	uint32_t audiomask = 0;
2803 	int nmixers = 0;
2804 	int i, j, index = 0;
2805 	int ndac, nadc;
2806 	int ctrlcnt[HDAUDIO_MIXER_NRDEVICES];
2807 
2808 	memset(ctrlcnt, 0, sizeof(ctrlcnt));
2809 
2810 	/* Count the number of required mixers */
2811 	for (i = 0; i < sc->sc_nctls; i++) {
2812 		ctl = &sc->sc_ctls[i];
2813 		if (ctl->ctl_enable == false ||
2814 		    ctl->ctl_audiomask == 0)
2815 			continue;
2816 		audiomask |= ctl->ctl_audiomask;
2817 		++nmixers;
2818 		if (ctl->ctl_mute)
2819 			++nmixers;
2820 	}
2821 
2822 	/* XXXJDM TODO: softvol */
2823 	/* Declare master volume if needed */
2824 	if ((audiomask & (HDAUDIO_MASK(VOLUME) | HDAUDIO_MASK(PCM))) ==
2825 	    HDAUDIO_MASK(PCM)) {
2826 		audiomask |= HDAUDIO_MASK(VOLUME);
2827 		for (i = 0; i < sc->sc_nctls; i++) {
2828 			if (sc->sc_ctls[i].ctl_audiomask == HDAUDIO_MASK(PCM)) {
2829 				masterctl = &sc->sc_ctls[i];
2830 				++nmixers;
2831 				if (masterctl->ctl_mute)
2832 					++nmixers;
2833 				break;
2834 			}
2835 		}
2836 	}
2837 
2838 	/* Make room for mixer classes */
2839 	nmixers += (HDAUDIO_MIXER_CLASS_LAST + 1);
2840 
2841 	/* count DACs and ADCs for selectors */
2842 	ndac = nadc = 0;
2843 	for (i = 0; i < sc->sc_nassocs; i++) {
2844 		if (sc->sc_assocs[i].as_enable == false)
2845 			continue;
2846 		if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_OUT)
2847 			++ndac;
2848 		else if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_IN)
2849 			++nadc;
2850 	}
2851 
2852 	/* Make room for selectors */
2853 	if (ndac > 0)
2854 		++nmixers;
2855 	if (nadc > 0)
2856 		++nmixers;
2857 
2858 	hda_trace(sc, "  need %d mixers (3 classes%s)\n",
2859 	    nmixers, masterctl ? " + fake master" : "");
2860 
2861 	/* Allocate memory for the mixers */
2862 	mx = kmem_zalloc(nmixers * sizeof(*mx), KM_SLEEP);
2863 	sc->sc_nmixers = nmixers;
2864 
2865 	/* Build class mixers */
2866 	for (i = 0; i <= HDAUDIO_MIXER_CLASS_LAST; i++) {
2867 		mx[index].mx_ctl = NULL;
2868 		mx[index].mx_di.index = index;
2869 		mx[index].mx_di.type = AUDIO_MIXER_CLASS;
2870 		mx[index].mx_di.mixer_class = i;
2871 		mx[index].mx_di.next = mx[index].mx_di.prev = AUDIO_MIXER_LAST;
2872 		switch (i) {
2873 		case HDAUDIO_MIXER_CLASS_OUTPUTS:
2874 			strcpy(mx[index].mx_di.label.name, AudioCoutputs);
2875 			break;
2876 		case HDAUDIO_MIXER_CLASS_INPUTS:
2877 			strcpy(mx[index].mx_di.label.name, AudioCinputs);
2878 			break;
2879 		case HDAUDIO_MIXER_CLASS_RECORD:
2880 			strcpy(mx[index].mx_di.label.name, AudioCrecord);
2881 			break;
2882 		}
2883 		++index;
2884 	}
2885 
2886 	/* Shadow master control */
2887 	if (masterctl != NULL) {
2888 		mx[index].mx_ctl = masterctl;
2889 		mx[index].mx_di.index = index;
2890 		mx[index].mx_di.type = AUDIO_MIXER_VALUE;
2891 		mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2892 		mx[index].mx_di.un.v.num_channels = 2;	/* XXX */
2893 		mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_OUTPUTS;
2894 		mx[index].mx_di.un.v.delta = 256 / (masterctl->ctl_step + 1);
2895 		strcpy(mx[index].mx_di.label.name, AudioNmaster);
2896 		strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
2897 		hda_trace(sc, "  adding outputs.%s\n",
2898 		    mx[index].mx_di.label.name);
2899 		++index;
2900 		if (masterctl->ctl_mute) {
2901 			mx[index] = mx[index - 1];
2902 			mx[index].mx_di.index = index;
2903 			mx[index].mx_di.type = AUDIO_MIXER_ENUM;
2904 			mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2905 			strcpy(mx[index].mx_di.label.name, AudioNmaster "." AudioNmute);
2906 			mx[index].mx_di.un.e.num_mem = 2;
2907 			strcpy(mx[index].mx_di.un.e.member[0].label.name, AudioNoff);
2908 			mx[index].mx_di.un.e.member[0].ord = 0;
2909 			strcpy(mx[index].mx_di.un.e.member[1].label.name, AudioNon);
2910 			mx[index].mx_di.un.e.member[1].ord = 1;
2911 			++index;
2912 		}
2913 	}
2914 
2915 	/* Build volume mixers */
2916 	for (i = 0; i < sc->sc_nctls; i++) {
2917 		uint32_t audiodev;
2918 
2919 		ctl = &sc->sc_ctls[i];
2920 		if (ctl->ctl_enable == false ||
2921 		    ctl->ctl_audiomask == 0)
2922 			continue;
2923 		audiodev = ffs(ctl->ctl_audiomask) - 1;
2924 		mx[index].mx_ctl = ctl;
2925 		mx[index].mx_di.index = index;
2926 		mx[index].mx_di.type = AUDIO_MIXER_VALUE;
2927 		mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2928 		mx[index].mx_di.un.v.num_channels = 2;	/* XXX */
2929 		mx[index].mx_di.un.v.delta = 256 / (ctl->ctl_step + 1);
2930 		if (ctrlcnt[audiodev] > 0)
2931 			snprintf(mx[index].mx_di.label.name,
2932 			    sizeof(mx[index].mx_di.label.name),
2933 			    "%s%d",
2934 			    hdafg_mixer_names[audiodev],
2935 			    ctrlcnt[audiodev] + 1);
2936 		else
2937 			strcpy(mx[index].mx_di.label.name,
2938 			    hdafg_mixer_names[audiodev]);
2939 		ctrlcnt[audiodev]++;
2940 
2941 		switch (audiodev) {
2942 		case HDAUDIO_MIXER_VOLUME:
2943 		case HDAUDIO_MIXER_BASS:
2944 		case HDAUDIO_MIXER_TREBLE:
2945 		case HDAUDIO_MIXER_OGAIN:
2946 			mx[index].mx_di.mixer_class =
2947 			    HDAUDIO_MIXER_CLASS_OUTPUTS;
2948 			hda_trace(sc, "  adding outputs.%s\n",
2949 			    mx[index].mx_di.label.name);
2950 			break;
2951 		case HDAUDIO_MIXER_MIC:
2952 		case HDAUDIO_MIXER_MONITOR:
2953 			mx[index].mx_di.mixer_class =
2954 			    HDAUDIO_MIXER_CLASS_RECORD;
2955 			hda_trace(sc, "  adding record.%s\n",
2956 			    mx[index].mx_di.label.name);
2957 			break;
2958 		default:
2959 			mx[index].mx_di.mixer_class =
2960 			    HDAUDIO_MIXER_CLASS_INPUTS;
2961 			hda_trace(sc, "  adding inputs.%s\n",
2962 			    mx[index].mx_di.label.name);
2963 			break;
2964 		}
2965 		strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
2966 
2967 		++index;
2968 
2969 		if (ctl->ctl_mute) {
2970 			mx[index] = mx[index - 1];
2971 			mx[index].mx_di.index = index;
2972 			mx[index].mx_di.type = AUDIO_MIXER_ENUM;
2973 			mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2974 			snprintf(mx[index].mx_di.label.name,
2975 			    sizeof(mx[index].mx_di.label.name),
2976 			    "%s." AudioNmute,
2977 			    mx[index - 1].mx_di.label.name);
2978 			mx[index].mx_di.un.e.num_mem = 2;
2979 			strcpy(mx[index].mx_di.un.e.member[0].label.name, AudioNoff);
2980 			mx[index].mx_di.un.e.member[0].ord = 0;
2981 			strcpy(mx[index].mx_di.un.e.member[1].label.name, AudioNon);
2982 			mx[index].mx_di.un.e.member[1].ord = 1;
2983 			++index;
2984 		}
2985 	}
2986 
2987 	/* DAC selector */
2988 	if (ndac > 0) {
2989 		mx[index].mx_ctl = NULL;
2990 		mx[index].mx_di.index = index;
2991 		mx[index].mx_di.type = AUDIO_MIXER_SET;
2992 		mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_OUTPUTS;
2993 		mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2994 		strcpy(mx[index].mx_di.label.name, "dacsel"); /* AudioNselect */
2995 		mx[index].mx_di.un.s.num_mem = ndac;
2996 		for (i = 0, j = 0; i < sc->sc_nassocs; i++) {
2997 			if (sc->sc_assocs[i].as_enable == false)
2998 				continue;
2999 			if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_OUT)
3000 				continue;
3001 			mx[index].mx_di.un.s.member[j].mask = 1 << i;
3002 			snprintf(mx[index].mx_di.un.s.member[j].label.name,
3003 			    sizeof(mx[index].mx_di.un.s.member[j].label.name),
3004 			    "%s%02X",
3005 			    hdafg_assoc_type_string(&sc->sc_assocs[i]), i);
3006 			++j;
3007 		}
3008 		++index;
3009 	}
3010 
3011 	/* ADC selector */
3012 	if (nadc > 0) {
3013 		mx[index].mx_ctl = NULL;
3014 		mx[index].mx_di.index = index;
3015 		mx[index].mx_di.type = AUDIO_MIXER_SET;
3016 		mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_RECORD;
3017 		mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
3018 		strcpy(mx[index].mx_di.label.name, AudioNsource);
3019 		mx[index].mx_di.un.s.num_mem = nadc;
3020 		for (i = 0, j = 0; i < sc->sc_nassocs; i++) {
3021 			if (sc->sc_assocs[i].as_enable == false)
3022 				continue;
3023 			if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_IN)
3024 				continue;
3025 			mx[index].mx_di.un.s.member[j].mask = 1 << i;
3026 			snprintf(mx[index].mx_di.un.s.member[j].label.name,
3027 			    sizeof(mx[index].mx_di.un.s.member[j].label.name),
3028 			    "%s%02X",
3029 			    hdafg_assoc_type_string(&sc->sc_assocs[i]), i);
3030 			++j;
3031 		}
3032 		++index;
3033 	}
3034 
3035 	sc->sc_mixers = mx;
3036 }
3037 
3038 static void
3039 hdafg_commit(struct hdafg_softc *sc)
3040 {
3041 	struct hdaudio_widget *w;
3042 	uint32_t gdata, gmask, gdir;
3043 	int commitgpio;
3044 	int i;
3045 
3046 	/* Commit controls */
3047 	hdafg_control_commit(sc);
3048 
3049 	/* Commit selectors, pins, and EAPD */
3050 	for (i = 0; i < sc->sc_nwidgets; i++) {
3051 		w = &sc->sc_widgets[i];
3052 		if (w->w_selconn == -1)
3053 			w->w_selconn = 0;
3054 		if (w->w_nconns > 0)
3055 			hdafg_widget_connection_select(w, w->w_selconn);
3056 		if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
3057 			hdaudio_command(sc->sc_codec, w->w_nid,
3058 			    CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3059 		if (w->w_p.eapdbtl != 0xffffffff)
3060 			hdaudio_command(sc->sc_codec, w->w_nid,
3061 			    CORB_SET_EAPD_BTL_ENABLE, w->w_p.eapdbtl);
3062 	}
3063 
3064 	gdata = gmask = gdir = commitgpio = 0;
3065 #ifdef notyet
3066 	int numgpio = COP_GPIO_COUNT_NUM_GPIO(sc->sc_p.gpio_cnt);
3067 
3068 	hda_trace(sc, "found %d GPIOs\n", numgpio);
3069 	for (i = 0; i < numgpio && i < 8; i++) {
3070 		if (commitgpio == 0)
3071 			commitgpio = 1;
3072 		gdata |= 1 << i;
3073 		gmask |= 1 << i;
3074 		gdir |= 1 << i;
3075 	}
3076 #endif
3077 
3078 	if (commitgpio) {
3079 		hda_trace(sc, "GPIO commit: data=%08X mask=%08X dir=%08X\n",
3080 		    gdata, gmask, gdir);
3081 		hdaudio_command(sc->sc_codec, sc->sc_nid,
3082 		    CORB_SET_GPIO_ENABLE_MASK, gmask);
3083 		hdaudio_command(sc->sc_codec, sc->sc_nid,
3084 		    CORB_SET_GPIO_DIRECTION, gdir);
3085 		hdaudio_command(sc->sc_codec, sc->sc_nid,
3086 		    CORB_SET_GPIO_DATA, gdata);
3087 	}
3088 }
3089 
3090 static void
3091 hdafg_stream_connect_hdmi(struct hdafg_softc *sc, struct hdaudio_assoc *as,
3092     struct hdaudio_widget *w, const audio_params_t *params)
3093 {
3094 	struct hdmi_audio_infoframe hdmi;
3095 	/* TODO struct displayport_audio_infoframe dp; */
3096 	uint8_t *dip = NULL;
3097 	size_t diplen = 0;
3098 	int i;
3099 
3100 #ifdef HDAFG_HDMI_DEBUG
3101 	uint32_t res;
3102 	res = hdaudio_command(sc->sc_codec, w->w_nid,
3103 	    CORB_GET_HDMI_DIP_XMIT_CTRL, 0);
3104 	hda_print(sc, "connect HDMI nid %02X, xmitctrl = 0x%08X\n",
3105 	    w->w_nid, res);
3106 #endif
3107 
3108 	/* disable infoframe transmission */
3109 	hdaudio_command(sc->sc_codec, w->w_nid,
3110 	    CORB_SET_HDMI_DIP_XMIT_CTRL, COP_DIP_XMIT_CTRL_DISABLE);
3111 
3112 	if (sc->sc_disable_dip)
3113 		return;
3114 
3115 	/* build new infoframe */
3116 	if (as->as_digital == HDAFG_AS_HDMI) {
3117 		dip = (uint8_t *)&hdmi;
3118 		diplen = sizeof(hdmi);
3119 		memset(&hdmi, 0, sizeof(hdmi));
3120 		hdmi.header.packet_type = HDMI_AI_PACKET_TYPE;
3121 		hdmi.header.version = HDMI_AI_VERSION;
3122 		hdmi.header.length = HDMI_AI_LENGTH;
3123 		hdmi.ct_cc = params->channels - 1;
3124 		if (params->channels > 2) {
3125 			hdmi.ca = 0x1f;
3126 		} else {
3127 			hdmi.ca = 0x00;
3128 		}
3129 		hdafg_dd_hdmi_ai_cksum(&hdmi);
3130 	}
3131 	/* update data island with new audio infoframe */
3132 	if (dip) {
3133 		hdaudio_command(sc->sc_codec, w->w_nid,
3134 		    CORB_SET_HDMI_DIP_INDEX, 0);
3135 		for (i = 0; i < diplen; i++) {
3136 			hdaudio_command(sc->sc_codec, w->w_nid,
3137 			    CORB_SET_HDMI_DIP_DATA, dip[i]);
3138 		}
3139 	}
3140 
3141 	/* enable infoframe transmission */
3142 	hdaudio_command(sc->sc_codec, w->w_nid,
3143 	    CORB_SET_HDMI_DIP_XMIT_CTRL, COP_DIP_XMIT_CTRL_BEST_EFFORT);
3144 }
3145 
3146 static void
3147 hdafg_stream_connect(struct hdafg_softc *sc, int mode)
3148 {
3149 	struct hdaudio_assoc *as = sc->sc_assocs;
3150 	struct hdaudio_widget *w;
3151 	const audio_params_t *params;
3152 	uint16_t fmt, dfmt;
3153 	int tag, chn, maxchan, c;
3154 	int i, j, k;
3155 
3156 	KASSERT(mode == AUMODE_PLAY || mode == AUMODE_RECORD);
3157 
3158 	if (mode == AUMODE_PLAY) {
3159 		fmt = hdaudio_stream_param(sc->sc_audiodev.ad_playback,
3160 		    &sc->sc_pparam);
3161 		params = &sc->sc_pparam;
3162 	} else {
3163 		fmt = hdaudio_stream_param(sc->sc_audiodev.ad_capture,
3164 		    &sc->sc_rparam);
3165 		params = &sc->sc_rparam;
3166 	}
3167 
3168 	for (i = 0; i < sc->sc_nassocs; i++) {
3169 		if (as[i].as_enable == false)
3170 			continue;
3171 
3172 		if (mode == AUMODE_PLAY && as[i].as_dir != HDAUDIO_PINDIR_OUT)
3173 			continue;
3174 		if (mode == AUMODE_RECORD && as[i].as_dir != HDAUDIO_PINDIR_IN)
3175 			continue;
3176 
3177 		fmt &= ~HDAUDIO_FMT_CHAN_MASK;
3178 		if (as[i].as_dir == HDAUDIO_PINDIR_OUT &&
3179 		    sc->sc_audiodev.ad_playback != NULL) {
3180 			tag = hdaudio_stream_tag(sc->sc_audiodev.ad_playback);
3181 			fmt |= HDAUDIO_FMT_CHAN(sc->sc_pparam.channels);
3182 			maxchan = sc->sc_pparam.channels;
3183 		} else if (as[i].as_dir == HDAUDIO_PINDIR_IN &&
3184 		    sc->sc_audiodev.ad_capture != NULL) {
3185 			tag = hdaudio_stream_tag(sc->sc_audiodev.ad_capture);
3186 			fmt |= HDAUDIO_FMT_CHAN(sc->sc_rparam.channels);
3187 			maxchan = sc->sc_rparam.channels;
3188 		} else {
3189 			tag = 0;
3190 			if (as[i].as_dir == HDAUDIO_PINDIR_OUT) {
3191 				fmt |= HDAUDIO_FMT_CHAN(sc->sc_pchan);
3192 				maxchan = sc->sc_pchan;
3193 			} else {
3194 				fmt |= HDAUDIO_FMT_CHAN(sc->sc_rchan);
3195 				maxchan = sc->sc_rchan;
3196 			}
3197 		}
3198 
3199 		chn = 0;
3200 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3201 			if (as[i].as_dacs[j] == 0)
3202 				continue;
3203 			w = hdafg_widget_lookup(sc, as[i].as_dacs[j]);
3204 			if (w == NULL || w->w_enable == FALSE)
3205 				continue;
3206 			if (as[i].as_hpredir >= 0 && i == as[i].as_pincnt)
3207 				chn = 0;
3208 			if (chn >= maxchan)
3209 				chn = 0;	/* XXX */
3210 			c = (tag << 4) | chn;
3211 
3212 			if (as[i].as_activated == false)
3213 				c = 0;
3214 
3215 			/*
3216 			 * If a non-PCM stream is being connected, and the
3217 			 * analog converter doesn't support non-PCM streams,
3218 			 * then don't decode it
3219 			 */
3220 			if (!(w->w_p.aw_cap & COP_AWCAP_DIGITAL) &&
3221 			    !(w->w_p.stream_format & COP_STREAM_FORMAT_AC3) &&
3222 			    (fmt & HDAUDIO_FMT_TYPE_NONPCM)) {
3223 				hdaudio_command(sc->sc_codec, w->w_nid,
3224 				    CORB_SET_CONVERTER_STREAM_CHANNEL, 0);
3225 				continue;
3226 			}
3227 
3228 			hdaudio_command(sc->sc_codec, w->w_nid,
3229 			    CORB_SET_CONVERTER_FORMAT, fmt);
3230 			if (w->w_p.aw_cap & COP_AWCAP_DIGITAL) {
3231 				dfmt = hdaudio_command(sc->sc_codec, w->w_nid,
3232 				    CORB_GET_DIGITAL_CONVERTER_CONTROL, 0) &
3233 				    0xff;
3234 				dfmt |= COP_DIGITAL_CONVCTRL1_DIGEN;
3235 				if (fmt & HDAUDIO_FMT_TYPE_NONPCM)
3236 					dfmt |= COP_DIGITAL_CONVCTRL1_NAUDIO;
3237 				else
3238 					dfmt &= ~COP_DIGITAL_CONVCTRL1_NAUDIO;
3239 				if (sc->sc_vendor == HDAUDIO_VENDOR_NVIDIA)
3240 					dfmt |= COP_DIGITAL_CONVCTRL1_COPY;
3241 				hdaudio_command(sc->sc_codec, w->w_nid,
3242 				    CORB_SET_DIGITAL_CONVERTER_CONTROL_1, dfmt);
3243 			}
3244 			if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP)) {
3245 				hdaudio_command(sc->sc_codec, w->w_nid,
3246 				    CORB_SET_CONVERTER_CHANNEL_COUNT,
3247 				    maxchan - 1);
3248 				for (k = 0; k < maxchan; k++) {
3249 					hdaudio_command(sc->sc_codec, w->w_nid,
3250 					    CORB_ASP_SET_CHANNEL_MAPPING,
3251 					    (k << 4) | k);
3252 				}
3253 			}
3254 			hdaudio_command(sc->sc_codec, w->w_nid,
3255 			    CORB_SET_CONVERTER_STREAM_CHANNEL, c);
3256 			chn += COP_AWCAP_CHANNEL_COUNT(w->w_p.aw_cap);
3257 		}
3258 
3259 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3260 			if (as[i].as_pins[j] == 0)
3261 				continue;
3262 			w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3263 			if (w == NULL || w->w_enable == FALSE)
3264 				continue;
3265 			if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
3266 				hdafg_stream_connect_hdmi(sc, &as[i],
3267 				    w, params);
3268 		}
3269 	}
3270 }
3271 
3272 static int
3273 hdafg_stream_intr(struct hdaudio_stream *st)
3274 {
3275 	struct hdaudio_audiodev *ad = st->st_cookie;
3276 	int handled = 0;
3277 
3278 	(void)hda_read1(ad->ad_sc->sc_host, HDAUDIO_SD_STS(st->st_shift));
3279 	hda_write1(ad->ad_sc->sc_host, HDAUDIO_SD_STS(st->st_shift),
3280 	    HDAUDIO_STS_DESE | HDAUDIO_STS_FIFOE | HDAUDIO_STS_BCIS);
3281 
3282 	mutex_spin_enter(&ad->ad_sc->sc_intr_lock);
3283 	/* XXX test (sts & HDAUDIO_STS_BCIS)? */
3284 	if (st == ad->ad_playback && ad->ad_playbackintr) {
3285 		ad->ad_playbackintr(ad->ad_playbackintrarg);
3286 		handled = 1;
3287 	} else if (st == ad->ad_capture && ad->ad_captureintr) {
3288 		ad->ad_captureintr(ad->ad_captureintrarg);
3289 		handled = 1;
3290 	}
3291 	mutex_spin_exit(&ad->ad_sc->sc_intr_lock);
3292 
3293 	return handled;
3294 }
3295 
3296 static bool
3297 hdafg_rate_supported(struct hdafg_softc *sc, u_int frequency)
3298 {
3299 	uint32_t caps = sc->sc_p.pcm_size_rate;
3300 
3301 	if (sc->sc_fixed_rate)
3302 		return frequency == sc->sc_fixed_rate;
3303 
3304 #define ISFREQOK(shift) ((caps & (1 << (shift))) ? true : false)
3305 	switch (frequency) {
3306 	case 8000:
3307 		return ISFREQOK(0);
3308 	case 11025:
3309 		return ISFREQOK(1);
3310 	case 16000:
3311 		return ISFREQOK(2);
3312 	case 22050:
3313 		return ISFREQOK(3);
3314 	case 32000:
3315 		return ISFREQOK(4);
3316 	case 44100:
3317 		return ISFREQOK(5);
3318 		return true;
3319 	case 48000:
3320 		return true;	/* Must be supported by all codecs */
3321 	case 88200:
3322 		return ISFREQOK(7);
3323 	case 96000:
3324 		return ISFREQOK(8);
3325 	case 176400:
3326 		return ISFREQOK(9);
3327 	case 192000:
3328 		return ISFREQOK(10);
3329 	case 384000:
3330 		return ISFREQOK(11);
3331 	default:
3332 		return false;
3333 	}
3334 #undef ISFREQOK
3335 }
3336 
3337 static bool
3338 hdafg_bits_supported(struct hdafg_softc *sc, u_int bits)
3339 {
3340 	uint32_t caps = sc->sc_p.pcm_size_rate;
3341 #define ISBITSOK(shift) ((caps & (1 << (shift))) ? true : false)
3342 	switch (bits) {
3343 	case 8:
3344 		return ISBITSOK(16);
3345 	case 16:
3346 		return ISBITSOK(17);
3347 	case 20:
3348 		return ISBITSOK(18);
3349 	case 24:
3350 		return ISBITSOK(19);
3351 	case 32:
3352 		return ISBITSOK(20);
3353 	default:
3354 		return false;
3355 	}
3356 #undef ISBITSOK
3357 }
3358 
3359 static bool
3360 hdafg_probe_encoding(struct hdafg_softc *sc,
3361     u_int validbits, u_int precision, int encoding, bool force)
3362 {
3363 	struct audio_format f;
3364 	int i;
3365 
3366 	if (!force && hdafg_bits_supported(sc, validbits) == false)
3367 		return false;
3368 
3369 	memset(&f, 0, sizeof(f));
3370 	f.driver_data = NULL;
3371 	f.mode = 0;
3372 	f.encoding = encoding;
3373 	f.validbits = validbits;
3374 	f.precision = precision;
3375 	f.channels = 0;
3376 	f.channel_mask = 0;
3377 	f.frequency_type = 0;
3378 	for (i = 0; i < __arraycount(hdafg_possible_rates); i++) {
3379 		u_int rate = hdafg_possible_rates[i];
3380 		if (hdafg_rate_supported(sc, rate))
3381 			f.frequency[f.frequency_type++] = rate;
3382 	}
3383 
3384 #define HDAUDIO_INITFMT(ch, chmask)			\
3385 	do {						\
3386 		f.channels = (ch);			\
3387 		f.channel_mask = (chmask);		\
3388 		f.mode = 0;				\
3389 		if (sc->sc_pchan >= (ch))		\
3390 			f.mode |= AUMODE_PLAY;		\
3391 		if (sc->sc_rchan >= (ch))		\
3392 			f.mode |= AUMODE_RECORD;	\
3393 		if (f.mode != 0)			\
3394 			hdafg_append_formats(&sc->sc_audiodev, &f); \
3395 	} while (0)
3396 
3397 	/* Commented out, otherwise monaural samples play through left
3398 	 * channel only
3399 	 */
3400 	/* HDAUDIO_INITFMT(1, AUFMT_MONAURAL); */
3401 	HDAUDIO_INITFMT(2, AUFMT_STEREO);
3402 	HDAUDIO_INITFMT(4, AUFMT_SURROUND4);
3403 	HDAUDIO_INITFMT(6, AUFMT_DOLBY_5_1);
3404 	HDAUDIO_INITFMT(8, AUFMT_SURROUND_7_1);
3405 
3406 #undef HDAUDIO_INITFMT
3407 
3408 	return true;
3409 }
3410 
3411 
3412 static void
3413 hdafg_configure_encodings(struct hdafg_softc *sc)
3414 {
3415 	struct hdaudio_assoc *as = sc->sc_assocs;
3416 	struct hdaudio_widget *w;
3417 	struct audio_format f;
3418 	uint32_t stream_format, caps;
3419 	int nchan, i, nid;
3420 
3421 	sc->sc_pchan = sc->sc_rchan = 0;
3422 
3423 	for (i = 0; i < sc->sc_nassocs; i++) {
3424 		nchan = hdafg_assoc_count_channels(sc, &as[i],
3425 		    HDAUDIO_PINDIR_OUT);
3426 		if (nchan > sc->sc_pchan)
3427 			sc->sc_pchan = nchan;
3428 	}
3429 	for (i = 0; i < sc->sc_nassocs; i++) {
3430 		nchan = hdafg_assoc_count_channels(sc, &as[i],
3431 		    HDAUDIO_PINDIR_IN);
3432 		if (nchan > sc->sc_rchan)
3433 			sc->sc_rchan = nchan;
3434 	}
3435 	hda_print(sc, "%dch/%dch", sc->sc_pchan, sc->sc_rchan);
3436 
3437 	for (i = 0; i < __arraycount(hdafg_possible_rates); i++)
3438 		if (hdafg_rate_supported(sc,
3439 		    hdafg_possible_rates[i]))
3440 			hda_print1(sc, " %uHz", hdafg_possible_rates[i]);
3441 
3442 	stream_format = sc->sc_p.stream_format;
3443 	caps = 0;
3444 	for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3445 		w = hdafg_widget_lookup(sc, nid);
3446 		if (w == NULL)
3447 			continue;
3448 		stream_format |= w->w_p.stream_format;
3449 		caps |= w->w_p.aw_cap;
3450 	}
3451 	if (stream_format == 0) {
3452 		hda_print(sc,
3453 		    "WARNING: unsupported stream format mask 0x%X, assuming PCM\n",
3454 		    stream_format);
3455 		stream_format |= COP_STREAM_FORMAT_PCM;
3456 	}
3457 
3458 	if (stream_format & COP_STREAM_FORMAT_PCM) {
3459 		int e = AUDIO_ENCODING_SLINEAR_LE;
3460 		if (hdafg_probe_encoding(sc, 8, 16, e, false))
3461 			hda_print1(sc, " PCM8");
3462 		if (hdafg_probe_encoding(sc, 16, 16, e, false))
3463 			hda_print1(sc, " PCM16");
3464 		if (hdafg_probe_encoding(sc, 20, 32, e, false))
3465 			hda_print1(sc, " PCM20");
3466 		if (hdafg_probe_encoding(sc, 24, 32, e, false))
3467 			hda_print1(sc, " PCM24");
3468 		if (hdafg_probe_encoding(sc, 32, 32, e, false))
3469 			hda_print1(sc, " PCM32");
3470 	}
3471 
3472 	if ((stream_format & COP_STREAM_FORMAT_AC3) ||
3473 	    (caps & COP_AWCAP_DIGITAL)) {
3474 		int e = AUDIO_ENCODING_AC3;
3475 		if (hdafg_probe_encoding(sc, 16, 16, e, false))
3476 			hda_print1(sc, " AC3");
3477 	}
3478 
3479 	if (sc->sc_audiodev.ad_nformats == 0) {
3480 		hdafg_probe_encoding(sc, 16, 16, AUDIO_ENCODING_SLINEAR_LE, true);
3481 		hda_print1(sc, " PCM16*");
3482 	}
3483 
3484 	/*
3485 	 * XXX JDM 20090614
3486 	 * MI audio assumes that at least one playback and one capture format
3487 	 * is reported by the hw driver; until this bug is resolved just
3488 	 * report 2ch capabilities if the function group does not support
3489 	 * the direction.
3490 	 */
3491 	if (sc->sc_rchan == 0 || sc->sc_pchan == 0) {
3492 		memset(&f, 0, sizeof(f));
3493 		f.driver_data = NULL;
3494 		f.mode = 0;
3495 		f.encoding = AUDIO_ENCODING_SLINEAR_LE;
3496 		f.validbits = 16;
3497 		f.precision = 16;
3498 		f.channels = 2;
3499 		f.channel_mask = AUFMT_STEREO;
3500 		f.frequency_type = 0;
3501 		f.frequency[0] = f.frequency[1] = sc->sc_fixed_rate ?
3502 		    sc->sc_fixed_rate : 48000;
3503 		f.mode = AUMODE_PLAY|AUMODE_RECORD;
3504 		hdafg_append_formats(&sc->sc_audiodev, &f);
3505 	}
3506 
3507 	hda_print1(sc, "\n");
3508 }
3509 
3510 static void
3511 hdafg_hp_switch_handler(void *opaque)
3512 {
3513 	struct hdafg_softc *sc = opaque;
3514 	struct hdaudio_assoc *as = sc->sc_assocs;
3515 	struct hdaudio_widget *w;
3516 	uint32_t res = 0;
3517 	int i, j;
3518 
3519 	if (!device_is_active(sc->sc_dev))
3520 		goto resched;
3521 
3522 	for (i = 0; i < sc->sc_nassocs; i++) {
3523 		if (as[i].as_digital != HDAFG_AS_ANALOG &&
3524 		    as[i].as_digital != HDAFG_AS_SPDIF)
3525 			continue;
3526 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3527 			if (as[i].as_pins[j] == 0)
3528 				continue;
3529 			w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3530 			if (w == NULL || w->w_enable == false)
3531 				continue;
3532 			if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3533 				continue;
3534 			if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) !=
3535 			    COP_DEVICE_HP_OUT)
3536 				continue;
3537 			res |= hdaudio_command(sc->sc_codec, as[i].as_pins[j],
3538 			    CORB_GET_PIN_SENSE, 0) &
3539 			    COP_GET_PIN_SENSE_PRESENSE_DETECT;
3540 		}
3541 	}
3542 
3543 	for (i = 0; i < sc->sc_nassocs; i++) {
3544 		if (as[i].as_digital != HDAFG_AS_ANALOG &&
3545 		    as[i].as_digital != HDAFG_AS_SPDIF)
3546 			continue;
3547 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3548 			if (as[i].as_pins[j] == 0)
3549 				continue;
3550 			w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3551 			if (w == NULL || w->w_enable == false)
3552 				continue;
3553 			if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3554 				continue;
3555 			switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
3556 			case COP_DEVICE_HP_OUT:
3557 				if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
3558 					w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
3559 				else
3560 					w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
3561 				hdaudio_command(sc->sc_codec, w->w_nid,
3562 				    CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3563 				break;
3564 			case COP_DEVICE_LINE_OUT:
3565 			case COP_DEVICE_SPEAKER:
3566 			case COP_DEVICE_AUX:
3567 				if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
3568 					w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
3569 				else
3570 					w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
3571 				hdaudio_command(sc->sc_codec, w->w_nid,
3572 				    CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3573 				break;
3574 			default:
3575 				break;
3576 			}
3577 		}
3578 	}
3579 
3580 resched:
3581 	callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD);
3582 }
3583 
3584 static void
3585 hdafg_hp_switch_init(struct hdafg_softc *sc)
3586 {
3587 	struct hdaudio_assoc *as = sc->sc_assocs;
3588 	struct hdaudio_widget *w;
3589 	bool enable = false;
3590 	int i, j;
3591 
3592 	for (i = 0; i < sc->sc_nassocs; i++) {
3593 		if (as[i].as_hpredir < 0 && as[i].as_displaydev == false)
3594 			continue;
3595 		if (as[i].as_displaydev == false)
3596 			w = hdafg_widget_lookup(sc, as[i].as_pins[15]);
3597 		else {
3598 			w = NULL;
3599 			for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3600 				if (as[i].as_pins[j] == 0)
3601 					continue;
3602 				w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3603 				if (w && w->w_enable &&
3604 				    w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
3605 					break;
3606 				w = NULL;
3607 			}
3608 		}
3609 		if (w == NULL || w->w_enable == false)
3610 			continue;
3611 		if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3612 			continue;
3613 		if (!(w->w_pin.cap & COP_PINCAP_PRESENSE_DETECT_CAPABLE)) {
3614 			continue;
3615 		}
3616 		if (COP_CFG_MISC(w->w_pin.config) & 1) {
3617 			hda_trace(sc, "no presence detect on pin %02X\n",
3618 			    w->w_nid);
3619 			continue;
3620 		}
3621 		if ((w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP)) == 0)
3622 			enable = true;
3623 
3624 		if (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) {
3625 			uint8_t val = COP_SET_UNSOLICITED_RESPONSE_ENABLE;
3626 			if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
3627 				val |= HDAUDIO_UNSOLTAG_EVENT_DD;
3628 			else
3629 				val |= HDAUDIO_UNSOLTAG_EVENT_HP;
3630 
3631 			hdaudio_command(sc->sc_codec, w->w_nid,
3632 			    CORB_SET_UNSOLICITED_RESPONSE, val);
3633 
3634 			hdaudio_command(sc->sc_codec, w->w_nid,
3635 			    CORB_SET_AMPLIFIER_GAIN_MUTE, 0xb000);
3636 		}
3637 
3638 		hda_trace(sc, "presence detect [pin=%02X,%s",
3639 		    w->w_nid,
3640 		    (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) ?
3641 		     "unsol" : "poll"
3642 		    );
3643 		if (w->w_pin.cap & COP_PINCAP_HDMI)
3644 			hda_trace1(sc, ",hdmi");
3645 		if (w->w_pin.cap & COP_PINCAP_DP)
3646 			hda_trace1(sc, ",displayport");
3647 		hda_trace1(sc, "]\n");
3648 	}
3649 	if (enable) {
3650 		sc->sc_jack_polling = true;
3651 		hdafg_hp_switch_handler(sc);
3652 	} else
3653 		hda_trace(sc, "jack detect not enabled\n");
3654 }
3655 
3656 static void
3657 hdafg_attach(device_t parent, device_t self, void *opaque)
3658 {
3659 	struct hdafg_softc *sc = device_private(self);
3660 	audio_params_t defparams;
3661 	prop_dictionary_t args = opaque;
3662 	char vendor[MAX_AUDIO_DEV_LEN], product[MAX_AUDIO_DEV_LEN];
3663 	uint64_t fgptr = 0;
3664 	uint32_t astype = 0;
3665 	uint8_t nid = 0;
3666 	int err, i;
3667 	bool rv;
3668 
3669 	aprint_naive("\n");
3670 	sc->sc_dev = self;
3671 
3672 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
3673 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
3674 
3675 	callout_init(&sc->sc_jack_callout, 0);
3676 	callout_setfunc(&sc->sc_jack_callout,
3677 	    hdafg_hp_switch_handler, sc);
3678 
3679 	if (!pmf_device_register(self, hdafg_suspend, hdafg_resume))
3680 		aprint_error_dev(self, "couldn't establish power handler\n");
3681 
3682 	sc->sc_config = prop_dictionary_get(args, "pin-config");
3683 	if (sc->sc_config && prop_object_type(sc->sc_config) != PROP_TYPE_ARRAY)
3684 		sc->sc_config = NULL;
3685 
3686 	prop_dictionary_get_uint16(args, "vendor-id", &sc->sc_vendor);
3687 	prop_dictionary_get_uint16(args, "product-id", &sc->sc_product);
3688 	hdaudio_findvendor(vendor, sizeof(vendor), sc->sc_vendor);
3689 	hdaudio_findproduct(product, sizeof(product), sc->sc_vendor,
3690 	    sc->sc_product);
3691 	hda_print1(sc, ": %s %s%s\n", vendor, product,
3692 	    sc->sc_config ? " (custom configuration)" : "");
3693 
3694 	switch (sc->sc_vendor) {
3695 	case HDAUDIO_VENDOR_NVIDIA:
3696 		switch (sc->sc_product) {
3697 		case HDAUDIO_PRODUCT_NVIDIA_TEGRA124_HDMI:
3698 			sc->sc_fixed_rate = 44100;
3699 			sc->sc_disable_dip = true;
3700 			break;
3701 		}
3702 		break;
3703 	}
3704 
3705 	rv = prop_dictionary_get_uint64(args, "function-group", &fgptr);
3706 	if (rv == false || fgptr == 0) {
3707 		hda_error(sc, "missing function-group property\n");
3708 		return;
3709 	}
3710 	rv = prop_dictionary_get_uint8(args, "node-id", &nid);
3711 	if (rv == false || nid == 0) {
3712 		hda_error(sc, "missing node-id property\n");
3713 		return;
3714 	}
3715 
3716 	prop_dictionary_set_uint64(device_properties(self),
3717 	    "codecinfo-callback",
3718 	    (uint64_t)(uintptr_t)hdafg_codec_info);
3719 	prop_dictionary_set_uint64(device_properties(self),
3720 	    "widgetinfo-callback",
3721 	    (uint64_t)(uintptr_t)hdafg_widget_info);
3722 
3723 	sc->sc_nid = nid;
3724 	sc->sc_fg = (struct hdaudio_function_group *)(vaddr_t)fgptr;
3725 	sc->sc_fg->fg_unsol = hdafg_unsol;
3726 	sc->sc_codec = sc->sc_fg->fg_codec;
3727 	KASSERT(sc->sc_codec != NULL);
3728 	sc->sc_host = sc->sc_codec->co_host;
3729 	KASSERT(sc->sc_host != NULL);
3730 
3731 	hda_debug(sc, "parsing widgets\n");
3732 	hdafg_parse(sc);
3733 	hda_debug(sc, "parsing controls\n");
3734 	hdafg_control_parse(sc);
3735 	hda_debug(sc, "disabling non-audio devices\n");
3736 	hdafg_disable_nonaudio(sc);
3737 	hda_debug(sc, "disabling useless devices\n");
3738 	hdafg_disable_useless(sc);
3739 	hda_debug(sc, "parsing associations\n");
3740 	hdafg_assoc_parse(sc);
3741 	hda_debug(sc, "building tree\n");
3742 	hdafg_build_tree(sc);
3743 	hda_debug(sc, "disabling unassociated pins\n");
3744 	hdafg_disable_unassoc(sc);
3745 	hda_debug(sc, "disabling unselected pins\n");
3746 	hdafg_disable_unsel(sc);
3747 	hda_debug(sc, "disabling useless devices\n");
3748 	hdafg_disable_useless(sc);
3749 	hda_debug(sc, "disabling cross-associated pins\n");
3750 	hdafg_disable_crossassoc(sc);
3751 	hda_debug(sc, "disabling useless devices\n");
3752 	hdafg_disable_useless(sc);
3753 
3754 	hda_debug(sc, "assigning mixer names to sound sources\n");
3755 	hdafg_assign_names(sc);
3756 	hda_debug(sc, "assigning mixers to device tree\n");
3757 	hdafg_assign_mixers(sc);
3758 
3759 	hda_debug(sc, "preparing pin controls\n");
3760 	hdafg_prepare_pin_controls(sc);
3761 	hda_debug(sc, "commiting settings\n");
3762 	hdafg_commit(sc);
3763 
3764 	hda_debug(sc, "setup jack sensing\n");
3765 	hdafg_hp_switch_init(sc);
3766 
3767 	hda_debug(sc, "building mixer controls\n");
3768 	hdafg_build_mixers(sc);
3769 
3770 	hdafg_dump(sc);
3771 	if (1) hdafg_widget_pin_dump(sc);
3772 	hdafg_assoc_dump(sc);
3773 
3774 	hda_debug(sc, "enabling analog beep\n");
3775 	hdafg_enable_analog_beep(sc);
3776 
3777 	hda_debug(sc, "configuring encodings\n");
3778 	sc->sc_audiodev.ad_sc = sc;
3779 	hdafg_configure_encodings(sc);
3780 	err = auconv_create_encodings(sc->sc_audiodev.ad_formats,
3781 	    sc->sc_audiodev.ad_nformats, &sc->sc_audiodev.ad_encodings);
3782 	if (err) {
3783 		hda_error(sc, "couldn't create encodings\n");
3784 		return;
3785 	}
3786 
3787 	hda_debug(sc, "reserving streams\n");
3788 	sc->sc_audiodev.ad_capture = hdaudio_stream_establish(sc->sc_host,
3789 	    HDAUDIO_STREAM_ISS, hdafg_stream_intr, &sc->sc_audiodev);
3790 	sc->sc_audiodev.ad_playback = hdaudio_stream_establish(sc->sc_host,
3791 	    HDAUDIO_STREAM_OSS, hdafg_stream_intr, &sc->sc_audiodev);
3792 
3793 	hda_debug(sc, "connecting streams\n");
3794 	defparams.channels = 2;
3795 	defparams.sample_rate = sc->sc_fixed_rate ? sc->sc_fixed_rate : 48000;
3796 	defparams.precision = defparams.validbits = 16;
3797 	defparams.encoding = AUDIO_ENCODING_SLINEAR_LE;
3798 	sc->sc_pparam = sc->sc_rparam = defparams;
3799 	hdafg_stream_connect(sc, AUMODE_PLAY);
3800 	hdafg_stream_connect(sc, AUMODE_RECORD);
3801 
3802 	for (i = 0; i < sc->sc_nassocs; i++) {
3803 		astype |= (1 << sc->sc_assocs[i].as_digital);
3804 	}
3805 	hda_debug(sc, "assoc type mask: %x\n", astype);
3806 
3807 #ifndef HDAUDIO_ENABLE_HDMI
3808 	astype &= ~(1 << HDAFG_AS_HDMI);
3809 #endif
3810 #ifndef HDAUDIO_ENABLE_DISPLAYPORT
3811 	astype &= ~(1 << HDAFG_AS_DISPLAYPORT);
3812 #endif
3813 
3814 	if (astype == 0)
3815 		return;
3816 
3817 	hda_debug(sc, "attaching audio device\n");
3818 	sc->sc_audiodev.ad_audiodev = audio_attach_mi(&hdafg_hw_if,
3819 	    &sc->sc_audiodev, self);
3820 }
3821 
3822 static int
3823 hdafg_detach(device_t self, int flags)
3824 {
3825 	struct hdafg_softc *sc = device_private(self);
3826 	struct hdaudio_widget *wl, *w = sc->sc_widgets;
3827 	struct hdaudio_assoc *as = sc->sc_assocs;
3828 	struct hdaudio_control *ctl = sc->sc_ctls;
3829 	struct hdaudio_mixer *mx = sc->sc_mixers;
3830 	int nid;
3831 
3832 	callout_halt(&sc->sc_jack_callout, NULL);
3833 	callout_destroy(&sc->sc_jack_callout);
3834 
3835 	if (sc->sc_config)
3836 		prop_object_release(sc->sc_config);
3837 	if (sc->sc_audiodev.ad_audiodev)
3838 		config_detach(sc->sc_audiodev.ad_audiodev, flags);
3839 	if (sc->sc_audiodev.ad_encodings)
3840 		auconv_delete_encodings(sc->sc_audiodev.ad_encodings);
3841 	if (sc->sc_audiodev.ad_playback)
3842 		hdaudio_stream_disestablish(sc->sc_audiodev.ad_playback);
3843 	if (sc->sc_audiodev.ad_capture)
3844 		hdaudio_stream_disestablish(sc->sc_audiodev.ad_capture);
3845 
3846 	/* restore bios pin widget configuration */
3847 	for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3848 		wl = hdafg_widget_lookup(sc, nid);
3849 		if (wl == NULL || wl->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3850 			continue;
3851 		hdafg_widget_setconfig(wl, wl->w_pin.biosconfig);
3852 	}
3853 
3854 	if (w)
3855 		kmem_free(w, sc->sc_nwidgets * sizeof(*w));
3856 	if (as)
3857 		kmem_free(as, sc->sc_nassocs * sizeof(*as));
3858 	if (ctl)
3859 		kmem_free(ctl, sc->sc_nctls * sizeof(*ctl));
3860 	if (mx)
3861 		kmem_free(mx, sc->sc_nmixers * sizeof(*mx));
3862 
3863 	mutex_destroy(&sc->sc_lock);
3864 	mutex_destroy(&sc->sc_intr_lock);
3865 
3866 	pmf_device_deregister(self);
3867 
3868 	return 0;
3869 }
3870 
3871 static void
3872 hdafg_childdet(device_t self, device_t child)
3873 {
3874 	struct hdafg_softc *sc = device_private(self);
3875 
3876 	if (child == sc->sc_audiodev.ad_audiodev)
3877 		sc->sc_audiodev.ad_audiodev = NULL;
3878 }
3879 
3880 static bool
3881 hdafg_suspend(device_t self, const pmf_qual_t *qual)
3882 {
3883 	struct hdafg_softc *sc = device_private(self);
3884 
3885 	callout_halt(&sc->sc_jack_callout, NULL);
3886 
3887 	return true;
3888 }
3889 
3890 static bool
3891 hdafg_resume(device_t self, const pmf_qual_t *qual)
3892 {
3893 	struct hdafg_softc *sc = device_private(self);
3894 	struct hdaudio_widget *w;
3895 	int nid;
3896 
3897 	hdaudio_command(sc->sc_codec, sc->sc_nid,
3898 	    CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
3899 	hda_delay(100);
3900 	for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3901 		hdaudio_command(sc->sc_codec, nid,
3902 		    CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
3903 		w = hdafg_widget_lookup(sc, nid);
3904 
3905 		/* restore pin widget configuration */
3906 		if (w == NULL || w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3907 			continue;
3908 		hdafg_widget_setconfig(w, w->w_pin.config);
3909 	}
3910 	hda_delay(1000);
3911 
3912 	hdafg_commit(sc);
3913 	hdafg_stream_connect(sc, AUMODE_PLAY);
3914 	hdafg_stream_connect(sc, AUMODE_RECORD);
3915 
3916 	if (sc->sc_jack_polling)
3917 		hdafg_hp_switch_handler(sc);
3918 
3919 	return true;
3920 }
3921 
3922 static int
3923 hdafg_query_encoding(void *opaque, struct audio_encoding *ae)
3924 {
3925 	struct hdaudio_audiodev *ad = opaque;
3926 	return auconv_query_encoding(ad->ad_encodings, ae);
3927 }
3928 
3929 static int
3930 hdafg_set_params(void *opaque, int setmode, int usemode,
3931     audio_params_t *play, audio_params_t *rec,
3932     stream_filter_list_t *pfil, stream_filter_list_t *rfil)
3933 {
3934 	struct hdaudio_audiodev *ad = opaque;
3935 	int index;
3936 
3937 	if (play && (setmode & AUMODE_PLAY)) {
3938 		index = auconv_set_converter(ad->ad_formats, ad->ad_nformats,
3939 		    AUMODE_PLAY, play, TRUE, pfil);
3940 		if (index < 0)
3941 			return EINVAL;
3942 		ad->ad_sc->sc_pparam = pfil->req_size > 0 ?
3943 		    pfil->filters[0].param : *play;
3944 		hdafg_stream_connect(ad->ad_sc, AUMODE_PLAY);
3945 	}
3946 	if (rec && (setmode & AUMODE_RECORD)) {
3947 		index = auconv_set_converter(ad->ad_formats, ad->ad_nformats,
3948 		    AUMODE_RECORD, rec, TRUE, rfil);
3949 		if (index < 0)
3950 			return EINVAL;
3951 		ad->ad_sc->sc_rparam = rfil->req_size > 0 ?
3952 		    rfil->filters[0].param : *rec;
3953 		hdafg_stream_connect(ad->ad_sc, AUMODE_RECORD);
3954 	}
3955 	return 0;
3956 }
3957 
3958 static int
3959 hdafg_round_blocksize(void *opaque, int blksize, int mode,
3960     const audio_params_t *param)
3961 {
3962 	struct hdaudio_audiodev *ad = opaque;
3963 	struct hdaudio_stream *st;
3964 	int bufsize, nblksize;
3965 
3966 	st = (mode == AUMODE_PLAY) ? ad->ad_playback : ad->ad_capture;
3967 	if (st == NULL) {
3968 		hda_trace(ad->ad_sc,
3969 		    "round_blocksize called for invalid stream\n");
3970 		return 128;
3971 	}
3972 
3973 	if (blksize > 8192)
3974 		blksize = 8192;
3975 	else if (blksize < 0)
3976 		blksize = 128;
3977 
3978 	/* HD audio wants a multiple of 128, and OSS wants a power of 2 */
3979 	for (nblksize = 128; nblksize < blksize; nblksize <<= 1)
3980 		;
3981 
3982 	/* Make sure there are enough BDL descriptors */
3983 	bufsize = st->st_data.dma_size;
3984 	if (bufsize > HDAUDIO_BDL_MAX * nblksize) {
3985 		blksize = bufsize / HDAUDIO_BDL_MAX;
3986 		for (nblksize = 128; nblksize < blksize; nblksize <<= 1)
3987 			;
3988 	}
3989 
3990 	return nblksize;
3991 }
3992 
3993 static int
3994 hdafg_commit_settings(void *opaque)
3995 {
3996 	return 0;
3997 }
3998 
3999 static int
4000 hdafg_halt_output(void *opaque)
4001 {
4002 	struct hdaudio_audiodev *ad = opaque;
4003 	struct hdafg_softc *sc = ad->ad_sc;
4004 	struct hdaudio_assoc *as = ad->ad_sc->sc_assocs;
4005 	struct hdaudio_widget *w;
4006 	uint16_t dfmt;
4007 	int i, j;
4008 
4009 	/* Disable digital outputs */
4010 	for (i = 0; i < sc->sc_nassocs; i++) {
4011 		if (as[i].as_enable == false)
4012 			continue;
4013 		if (as[i].as_dir != HDAUDIO_PINDIR_OUT)
4014 			continue;
4015 		for (j = 0; j < HDAUDIO_MAXPINS; j++) {
4016 			if (as[i].as_dacs[j] == 0)
4017 				continue;
4018 			w = hdafg_widget_lookup(sc, as[i].as_dacs[j]);
4019 			if (w == NULL || w->w_enable == false)
4020 				continue;
4021 			if (w->w_p.aw_cap & COP_AWCAP_DIGITAL) {
4022 				dfmt = hdaudio_command(sc->sc_codec, w->w_nid,
4023 				    CORB_GET_DIGITAL_CONVERTER_CONTROL, 0) &
4024 				    0xff;
4025 				dfmt &= ~COP_DIGITAL_CONVCTRL1_DIGEN;
4026 				hdaudio_command(sc->sc_codec, w->w_nid,
4027 				    CORB_SET_DIGITAL_CONVERTER_CONTROL_1, dfmt);
4028 			}
4029 		}
4030 	}
4031 
4032 	hdaudio_stream_stop(ad->ad_playback);
4033 
4034 	return 0;
4035 }
4036 
4037 static int
4038 hdafg_halt_input(void *opaque)
4039 {
4040 	struct hdaudio_audiodev *ad = opaque;
4041 
4042 	hdaudio_stream_stop(ad->ad_capture);
4043 
4044 	return 0;
4045 }
4046 
4047 static int
4048 hdafg_getdev(void *opaque, struct audio_device *audiodev)
4049 {
4050 	struct hdaudio_audiodev *ad = opaque;
4051 	struct hdafg_softc *sc = ad->ad_sc;
4052 
4053 	hdaudio_findvendor(audiodev->name, sizeof(audiodev->name),
4054 	    sc->sc_vendor);
4055 	hdaudio_findproduct(audiodev->version, sizeof(audiodev->version),
4056 	    sc->sc_vendor, sc->sc_product);
4057 	snprintf(audiodev->config, sizeof(audiodev->config),
4058 	    "%02Xh", sc->sc_nid);
4059 
4060 	return 0;
4061 }
4062 
4063 static int
4064 hdafg_set_port(void *opaque, mixer_ctrl_t *mc)
4065 {
4066 	struct hdaudio_audiodev *ad = opaque;
4067 	struct hdafg_softc *sc = ad->ad_sc;
4068 	struct hdaudio_mixer *mx;
4069 	struct hdaudio_control *ctl;
4070 	int i, divisor;
4071 
4072 	if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
4073 		return EINVAL;
4074 	mx = &sc->sc_mixers[mc->dev];
4075 	ctl = mx->mx_ctl;
4076 	if (ctl == NULL) {
4077 		if (mx->mx_di.type != AUDIO_MIXER_SET)
4078 			return ENXIO;
4079 		if (mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_OUTPUTS &&
4080 		    mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_RECORD)
4081 			return ENXIO;
4082 		for (i = 0; i < sc->sc_nassocs; i++) {
4083 			if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_OUT &&
4084 			    mx->mx_di.mixer_class ==
4085 			    HDAUDIO_MIXER_CLASS_OUTPUTS)
4086 				continue;
4087 			if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_IN &&
4088 			    mx->mx_di.mixer_class ==
4089 			    HDAUDIO_MIXER_CLASS_RECORD)
4090 				continue;
4091 			sc->sc_assocs[i].as_activated =
4092 			    (mc->un.mask & (1 << i)) ? true : false;
4093 		}
4094 		hdafg_stream_connect(ad->ad_sc,
4095 		    mx->mx_di.mixer_class == HDAUDIO_MIXER_CLASS_OUTPUTS ?
4096 		    AUMODE_PLAY : AUMODE_RECORD);
4097 		return 0;
4098 	}
4099 
4100 	switch (mx->mx_di.type) {
4101 	case AUDIO_MIXER_VALUE:
4102 		if (ctl->ctl_step == 0)
4103 			divisor = 128; /* ??? - just avoid div by 0 */
4104 		else
4105 			divisor = 255 / ctl->ctl_step;
4106 
4107 		hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_NONE,
4108 		  mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] / divisor,
4109 		  mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] / divisor);
4110 		break;
4111 	case AUDIO_MIXER_ENUM:
4112 		hdafg_control_amp_set(ctl,
4113 		    mc->un.ord ? HDAUDIO_AMP_MUTE_ALL : HDAUDIO_AMP_MUTE_NONE,
4114 		    ctl->ctl_left, ctl->ctl_right);
4115 		break;
4116 	default:
4117 		return ENXIO;
4118 	}
4119 
4120 	return 0;
4121 }
4122 
4123 static int
4124 hdafg_get_port(void *opaque, mixer_ctrl_t *mc)
4125 {
4126 	struct hdaudio_audiodev *ad = opaque;
4127 	struct hdafg_softc *sc = ad->ad_sc;
4128 	struct hdaudio_mixer *mx;
4129 	struct hdaudio_control *ctl;
4130 	u_int mask = 0;
4131 	int i, factor;
4132 
4133 	if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
4134 		return EINVAL;
4135 	mx = &sc->sc_mixers[mc->dev];
4136 	ctl = mx->mx_ctl;
4137 	if (ctl == NULL) {
4138 		if (mx->mx_di.type != AUDIO_MIXER_SET)
4139 			return ENXIO;
4140 		if (mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_OUTPUTS &&
4141 		    mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_RECORD)
4142 			return ENXIO;
4143 		for (i = 0; i < sc->sc_nassocs; i++) {
4144 			if (sc->sc_assocs[i].as_enable == false)
4145 				continue;
4146 			if (sc->sc_assocs[i].as_activated == false)
4147 				continue;
4148 			if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_OUT &&
4149 			    mx->mx_di.mixer_class ==
4150 			    HDAUDIO_MIXER_CLASS_OUTPUTS)
4151 				mask |= (1 << i);
4152 			if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_IN &&
4153 			    mx->mx_di.mixer_class ==
4154 			    HDAUDIO_MIXER_CLASS_RECORD)
4155 				mask |= (1 << i);
4156 		}
4157 		mc->un.mask = mask;
4158 		return 0;
4159 	}
4160 
4161 	switch (mx->mx_di.type) {
4162 	case AUDIO_MIXER_VALUE:
4163 		if (ctl->ctl_step == 0)
4164 			factor = 128; /* ??? - just avoid div by 0 */
4165 		else
4166 			factor = 255 / ctl->ctl_step;
4167 
4168 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = ctl->ctl_left * factor;
4169 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = ctl->ctl_right * factor;
4170 		break;
4171 	case AUDIO_MIXER_ENUM:
4172 		mc->un.ord = (ctl->ctl_muted || ctl->ctl_forcemute) ? 1 : 0;
4173 		break;
4174 	default:
4175 		return ENXIO;
4176 	}
4177 	return 0;
4178 }
4179 
4180 static int
4181 hdafg_query_devinfo(void *opaque, mixer_devinfo_t *di)
4182 {
4183 	struct hdaudio_audiodev *ad = opaque;
4184 	struct hdafg_softc *sc = ad->ad_sc;
4185 
4186 	if (di->index < 0 || di->index >= sc->sc_nmixers)
4187 		return ENXIO;
4188 
4189 	*di = sc->sc_mixers[di->index].mx_di;
4190 
4191 	return 0;
4192 }
4193 
4194 static void *
4195 hdafg_allocm(void *opaque, int direction, size_t size)
4196 {
4197 	struct hdaudio_audiodev *ad = opaque;
4198 	struct hdaudio_stream *st;
4199 	int err;
4200 
4201 	st = (direction == AUMODE_PLAY) ? ad->ad_playback : ad->ad_capture;
4202 	if (st == NULL)
4203 		return NULL;
4204 
4205 	if (st->st_data.dma_valid == true)
4206 		hda_error(ad->ad_sc, "WARNING: allocm leak\n");
4207 
4208 	st->st_data.dma_size = size;
4209 	err = hdaudio_dma_alloc(st->st_host, &st->st_data,
4210 	    BUS_DMA_COHERENT | BUS_DMA_NOCACHE);
4211 	if (err || st->st_data.dma_valid == false)
4212 		return NULL;
4213 
4214 	return DMA_KERNADDR(&st->st_data);
4215 }
4216 
4217 static void
4218 hdafg_freem(void *opaque, void *addr, size_t size)
4219 {
4220 	struct hdaudio_audiodev *ad = opaque;
4221 	struct hdaudio_stream *st;
4222 
4223 	if (addr == DMA_KERNADDR(&ad->ad_playback->st_data))
4224 		st = ad->ad_playback;
4225 	else if (addr == DMA_KERNADDR(&ad->ad_capture->st_data))
4226 		st = ad->ad_capture;
4227 	else
4228 		return;
4229 
4230 	hdaudio_dma_free(st->st_host, &st->st_data);
4231 }
4232 
4233 static size_t
4234 hdafg_round_buffersize(void *opaque, int direction, size_t bufsize)
4235 {
4236 	/* Multiple of 128 */
4237 	bufsize &= ~127;
4238 	if (bufsize <= 0)
4239 		bufsize = 128;
4240 	return bufsize;
4241 }
4242 
4243 static paddr_t
4244 hdafg_mappage(void *opaque, void *addr, off_t off, int prot)
4245 {
4246 	struct hdaudio_audiodev *ad = opaque;
4247 	struct hdaudio_stream *st;
4248 
4249 	if (addr == DMA_KERNADDR(&ad->ad_playback->st_data))
4250 		st = ad->ad_playback;
4251 	else if (addr == DMA_KERNADDR(&ad->ad_capture->st_data))
4252 		st = ad->ad_capture;
4253 	else
4254 		return -1;
4255 
4256 	if (st->st_data.dma_valid == false)
4257 		return -1;
4258 
4259 	return bus_dmamem_mmap(st->st_host->sc_dmat, st->st_data.dma_segs,
4260 	    st->st_data.dma_nsegs, off, prot, BUS_DMA_WAITOK);
4261 }
4262 
4263 static int
4264 hdafg_get_props(void *opaque)
4265 {
4266 	struct hdaudio_audiodev *ad = opaque;
4267 	int props = AUDIO_PROP_MMAP;
4268 
4269 	if (ad->ad_playback)
4270 		props |= AUDIO_PROP_PLAYBACK;
4271 	if (ad->ad_capture)
4272 		props |= AUDIO_PROP_CAPTURE;
4273 	if (ad->ad_playback && ad->ad_capture) {
4274 		props |= AUDIO_PROP_FULLDUPLEX;
4275 		props |= AUDIO_PROP_INDEPENDENT;
4276 	}
4277 
4278 	return props;
4279 }
4280 
4281 static int
4282 hdafg_trigger_output(void *opaque, void *start, void *end, int blksize,
4283     void (*intr)(void *), void *intrarg, const audio_params_t *param)
4284 {
4285 	struct hdaudio_audiodev *ad = opaque;
4286 	bus_size_t dmasize;
4287 
4288 	if (ad->ad_playback == NULL)
4289 		return ENXIO;
4290 	if (ad->ad_playback->st_data.dma_valid == false)
4291 		return ENOMEM;
4292 
4293 	ad->ad_playbackintr = intr;
4294 	ad->ad_playbackintrarg = intrarg;
4295 
4296 	dmasize = (char *)end - (char *)start;
4297 	hdafg_stream_connect(ad->ad_sc, AUMODE_PLAY);
4298 	hdaudio_stream_start(ad->ad_playback, blksize, dmasize,
4299 	    &ad->ad_sc->sc_pparam);
4300 
4301 	return 0;
4302 }
4303 
4304 static int
4305 hdafg_trigger_input(void *opaque, void *start, void *end, int blksize,
4306     void (*intr)(void *), void *intrarg, const audio_params_t *param)
4307 {
4308 	struct hdaudio_audiodev *ad = opaque;
4309 	bus_size_t dmasize;
4310 
4311 	if (ad->ad_capture == NULL)
4312 		return ENXIO;
4313 	if (ad->ad_capture->st_data.dma_valid == false)
4314 		return ENOMEM;
4315 
4316 	ad->ad_captureintr = intr;
4317 	ad->ad_captureintrarg = intrarg;
4318 
4319 	dmasize = (char *)end - (char *)start;
4320 	hdafg_stream_connect(ad->ad_sc, AUMODE_RECORD);
4321 	hdaudio_stream_start(ad->ad_capture, blksize, dmasize,
4322 	    &ad->ad_sc->sc_rparam);
4323 
4324 	return 0;
4325 }
4326 
4327 static void
4328 hdafg_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
4329 {
4330 	struct hdaudio_audiodev *ad = opaque;
4331 
4332 	*intr = &ad->ad_sc->sc_intr_lock;
4333 	*thread = &ad->ad_sc->sc_lock;
4334 }
4335 
4336 static int
4337 hdafg_unsol(device_t self, uint8_t tag)
4338 {
4339 	struct hdafg_softc *sc = device_private(self);
4340 	struct hdaudio_assoc *as = sc->sc_assocs;
4341 	int i, j;
4342 
4343 	switch (tag) {
4344 	case HDAUDIO_UNSOLTAG_EVENT_DD:
4345 #ifdef HDAFG_HDMI_DEBUG
4346 		hda_print(sc, "unsol: display device hotplug\n");
4347 #endif
4348 		for (i = 0; i < sc->sc_nassocs; i++) {
4349 			if (as[i].as_displaydev == false)
4350 				continue;
4351 			for (j = 0; j < HDAUDIO_MAXPINS; j++) {
4352 				if (as[i].as_pins[j] == 0)
4353 					continue;
4354 				hdafg_assoc_dump_dd(sc, &as[i], j, 0);
4355 			}
4356 		}
4357 		break;
4358 	default:
4359 #ifdef HDAFG_HDMI_DEBUG
4360 		hda_print(sc, "unsol: tag=%u\n", tag);
4361 #endif
4362 		break;
4363 	}
4364 
4365 	return 0;
4366 }
4367 
4368 static int
4369 hdafg_widget_info(void *opaque, prop_dictionary_t request,
4370     prop_dictionary_t response)
4371 {
4372 	struct hdafg_softc *sc = opaque;
4373 	struct hdaudio_widget *w;
4374 	prop_array_t connlist;
4375 	uint32_t config, wcap;
4376 	uint16_t index;
4377 	int nid;
4378 	int i;
4379 
4380 	if (prop_dictionary_get_uint16(request, "index", &index) == false)
4381 		return EINVAL;
4382 
4383 	nid = sc->sc_startnode + index;
4384 	if (nid >= sc->sc_endnode)
4385 		return EINVAL;
4386 
4387 	w = hdafg_widget_lookup(sc, nid);
4388 	if (w == NULL)
4389 		return ENXIO;
4390 	wcap = hda_get_wparam(w, PIN_CAPABILITIES);
4391 	config = hdaudio_command(sc->sc_codec, w->w_nid,
4392 	    CORB_GET_CONFIGURATION_DEFAULT, 0);
4393 	prop_dictionary_set_cstring_nocopy(response, "name", w->w_name);
4394 	prop_dictionary_set_bool(response, "enable", w->w_enable);
4395 	prop_dictionary_set_uint8(response, "nid", w->w_nid);
4396 	prop_dictionary_set_uint8(response, "type", w->w_type);
4397 	prop_dictionary_set_uint32(response, "config", config);
4398 	prop_dictionary_set_uint32(response, "cap", wcap);
4399 	if (w->w_nconns == 0)
4400 		return 0;
4401 	connlist = prop_array_create();
4402 	for (i = 0; i < w->w_nconns; i++) {
4403 		if (w->w_conns[i] == 0)
4404 			continue;
4405 		prop_array_add(connlist,
4406 		    prop_number_create_unsigned_integer(w->w_conns[i]));
4407 	}
4408 	prop_dictionary_set(response, "connlist", connlist);
4409 	prop_object_release(connlist);
4410 	return 0;
4411 }
4412 
4413 static int
4414 hdafg_codec_info(void *opaque, prop_dictionary_t request,
4415     prop_dictionary_t response)
4416 {
4417 	struct hdafg_softc *sc = opaque;
4418 	prop_dictionary_set_uint16(response, "vendor-id",
4419 	    sc->sc_vendor);
4420 	prop_dictionary_set_uint16(response, "product-id",
4421 	    sc->sc_product);
4422 	return 0;
4423 }
4424 
4425 MODULE(MODULE_CLASS_DRIVER, hdafg, "hdaudio");
4426 
4427 #ifdef _MODULE
4428 #include "ioconf.c"
4429 #endif
4430 
4431 static int
4432 hdafg_modcmd(modcmd_t cmd, void *opaque)
4433 {
4434 	int error = 0;
4435 
4436 	switch (cmd) {
4437 	case MODULE_CMD_INIT:
4438 #ifdef _MODULE
4439 		error = config_init_component(cfdriver_ioconf_hdafg,
4440 		    cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
4441 #endif
4442 		return error;
4443 	case MODULE_CMD_FINI:
4444 #ifdef _MODULE
4445 		error = config_fini_component(cfdriver_ioconf_hdafg,
4446 		    cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
4447 #endif
4448 		return error;
4449 	default:
4450 		return ENOTTY;
4451 	}
4452 }
4453 
4454 #define HDAFG_GET_ANACTRL		0xfe0
4455 #define HDAFG_SET_ANACTRL		0x7e0
4456 #define HDAFG_ANALOG_BEEP_EN		__BIT(5)
4457 #define HDAFG_ALC231_MONO_OUT_MIXER	0xf
4458 #define HDAFG_STAC9200_AFG		0x1
4459 #define HDAFG_STAC9200_GET_ANACTRL_PAYLOAD	0x0
4460 #define HDAFG_ALC231_INPUT_BOTH_CHANNELS_UNMUTE 0x7100
4461 
4462 static void
4463 hdafg_enable_analog_beep(struct hdafg_softc *sc)
4464 {
4465 	int nid;
4466 	uint32_t response;
4467 
4468 	switch (sc->sc_vendor) {
4469 	case HDAUDIO_VENDOR_SIGMATEL:
4470 		switch (sc->sc_product) {
4471 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9200:
4472 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9200D:
4473 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9202:
4474 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9202D:
4475 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9204:
4476 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9204D:
4477 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9205:
4478 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9205_1:
4479 		case HDAUDIO_PRODUCT_SIGMATEL_STAC9205D:
4480 			nid = HDAFG_STAC9200_AFG;
4481 
4482 			response = hdaudio_command(sc->sc_codec, nid,
4483 			    HDAFG_GET_ANACTRL,
4484 			    HDAFG_STAC9200_GET_ANACTRL_PAYLOAD);
4485 			hda_delay(100);
4486 
4487 			response |= HDAFG_ANALOG_BEEP_EN;
4488 
4489 			hdaudio_command(sc->sc_codec, nid, HDAFG_SET_ANACTRL,
4490 			    response);
4491 			hda_delay(100);
4492 			break;
4493 		default:
4494 			break;
4495 		}
4496 		break;
4497 	case HDAUDIO_VENDOR_REALTEK:
4498 		switch (sc->sc_product) {
4499 		case HDAUDIO_PRODUCT_REALTEK_ALC269:
4500 			/* The Panasonic Toughbook CF19 - Mk 5 uses a Realtek
4501 			 * ALC231 that identifies as an ALC269.
4502 			 * This unmutes the PCBEEP on the speaker.
4503 			 */
4504 			nid = HDAFG_ALC231_MONO_OUT_MIXER;
4505 			response = hdaudio_command(sc->sc_codec, nid,
4506 			    CORB_SET_AMPLIFIER_GAIN_MUTE,
4507 			    HDAFG_ALC231_INPUT_BOTH_CHANNELS_UNMUTE);
4508 			hda_delay(100);
4509 			break;
4510 		default:
4511 			break;
4512 		}
4513 	default:
4514 		break;
4515 	}
4516 }
4517