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