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