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