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