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