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