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