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