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