xref: /netbsd-src/sys/dev/hdaudio/hdafg.c (revision 5669537f550999e367bd91809ed0e010a0bf286c)
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)
99 static int hdafg_debug = HDAFG_DEBUG;
100 #else
101 static 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 
123 const u_int hdafg_possible_rates[] = {
124 	8000, 11025, 16000, 22050, 32000, 44100,
125 	48000, 88200, 96000, 176500, 192000, /* 384000, */
126 };
127 
128 static const char *hdafg_mixer_names[] = HDAUDIO_DEVICE_NAMES;
129 
130 static const char *hdafg_port_connectivity[] = {
131 	"Jack",
132 	"Unconnected",
133 	"Built-In",
134 	"Jack & Built-In"
135 };
136 static 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 };
154 static 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 
189 enum 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 
203 struct 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 
221 struct 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 
255 struct 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 
268 struct hdaudio_mixer {
269 	struct hdaudio_control		*mx_ctl;
270 	mixer_devinfo_t			mx_di;
271 };
272 
273 struct 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 
291 struct 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 
343 static int	hdafg_match(device_t, cfdata_t, void *);
344 static void	hdafg_attach(device_t, device_t, void *);
345 static int	hdafg_detach(device_t, int);
346 static void	hdafg_childdet(device_t, device_t);
347 static bool	hdafg_suspend(device_t, const pmf_qual_t *);
348 static bool	hdafg_resume(device_t, const pmf_qual_t *);
349 
350 static int	hdafg_unsol(device_t, uint8_t);
351 static int	hdafg_widget_info(void *, prop_dictionary_t,
352 					prop_dictionary_t);
353 static int	hdafg_codec_info(void *, prop_dictionary_t,
354 				       prop_dictionary_t);
355 static void	hdafg_enable_analog_beep(struct hdafg_softc *);
356 
357 CFATTACH_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 
368 static int	hdafg_query_format(void *, audio_format_query_t *);
369 static 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 *);
374 static int	hdafg_round_blocksize(void *, int, int,
375 					const audio_params_t *);
376 static int	hdafg_commit_settings(void *);
377 static int	hdafg_halt_output(void *);
378 static int	hdafg_halt_input(void *);
379 static int	hdafg_set_port(void *, mixer_ctrl_t *);
380 static int	hdafg_get_port(void *, mixer_ctrl_t *);
381 static int	hdafg_query_devinfo(void *, mixer_devinfo_t *);
382 static void *	hdafg_allocm(void *, int, size_t);
383 static void	hdafg_freem(void *, void *, size_t);
384 static int	hdafg_getdev(void *, struct audio_device *);
385 static int	hdafg_get_props(void *);
386 static int	hdafg_trigger_output(void *, void *, void *, int,
387 				       void (*)(void *), void *,
388 				       const audio_params_t *);
389 static int	hdafg_trigger_input(void *, void *, void *, int,
390 				      void (*)(void *), void *,
391 				      const audio_params_t *);
392 static void	hdafg_get_locks(void *, kmutex_t **, kmutex_t **);
393 
394 static 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 
413 static int
hdafg_append_formats(struct hdaudio_audiodev * ad,const struct audio_format * format)414 hdafg_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 
426 static struct hdaudio_widget *
hdafg_widget_lookup(struct hdafg_softc * sc,int nid)427 hdafg_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 
442 static struct hdaudio_control *
hdafg_control_lookup(struct hdafg_softc * sc,int nid,enum hdaudio_pindir dir,int index,int cnt)443 hdafg_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 
470 static void
hdafg_widget_connection_parse(struct hdaudio_widget * w)471 hdafg_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 
538 getconns_out:
539 	return;
540 }
541 
542 static void
hdafg_widget_pin_dump(struct hdafg_softc * sc)543 hdafg_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 
569 static void
hdafg_widget_setconfig(struct hdaudio_widget * w,uint32_t cfg)570 hdafg_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 
584 static uint32_t
hdafg_widget_getconfig(struct hdaudio_widget * w)585 hdafg_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 
612 biosconfig:
613 	return hdaudio_command(sc->sc_codec, w->w_nid,
614 	    CORB_GET_CONFIGURATION_DEFAULT, 0);
615 }
616 
617 static void
hdafg_widget_pin_parse(struct hdaudio_widget * w)618 hdafg_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 
686 static uint32_t
hdafg_widget_getcaps(struct hdaudio_widget * w)687 hdafg_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 
728 static void
hdafg_widget_parse(struct hdaudio_widget * w)729 hdafg_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 
791 static int
hdafg_assoc_count_channels(struct hdafg_softc * sc,struct hdaudio_assoc * as,enum hdaudio_pindir dir)792 hdafg_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 
823 static const char *
hdafg_assoc_type_string(struct hdaudio_assoc * as)824 hdafg_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 
845 static void
hdafg_assoc_dump_dd(struct hdafg_softc * sc,struct hdaudio_assoc * as,int pin,int lock)846 hdafg_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 
932 static char *
hdafg_mixer_mask2allname(uint32_t mask,char * buf,size_t len)933 hdafg_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 
951 static void
hdafg_dump_dst_nid(struct hdafg_softc * sc,int nid,int depth)952 hdafg_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 
993 static void
hdafg_assoc_dump(struct hdafg_softc * sc)994 hdafg_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 
1114 static void
hdafg_assoc_parse(struct hdafg_softc * sc)1115 hdafg_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 
1232 static void
hdafg_control_parse(struct hdafg_softc * sc)1233 hdafg_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 
1359 static void
hdafg_parse(struct hdafg_softc * sc)1360 hdafg_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 
1423 static void
hdafg_disable_nonaudio(struct hdafg_softc * sc)1424 hdafg_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 
1443 static void
hdafg_disable_useless(struct hdafg_softc * sc)1444 hdafg_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 
1561 static void
hdafg_assoc_trace_undo(struct hdafg_softc * sc,int as,int seq)1562 hdafg_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 
1587 static int
hdafg_assoc_trace_dac(struct hdafg_softc * sc,int as,int seq,int nid,int dupseq,int minassoc,int only,int depth)1588 hdafg_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 
1670 static int
hdafg_assoc_trace_out(struct hdafg_softc * sc,int as,int seq)1671 hdafg_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 
1712 static int
hdafg_assoc_trace_adc(struct hdafg_softc * sc,int assoc,int seq,int nid,int only,int depth)1713 hdafg_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 
1769 static int
hdafg_assoc_trace_in(struct hdafg_softc * sc,int assoc)1770 hdafg_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 
1805 static int
hdafg_assoc_trace_to_out(struct hdafg_softc * sc,int nid,int depth)1806 hdafg_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 
1865 static void
hdafg_assoc_trace_misc(struct hdafg_softc * sc)1866 hdafg_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 
1906 static void
hdafg_build_tree(struct hdafg_softc * sc)1907 hdafg_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;
1920 retry:
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 
1982 static void
hdafg_prepare_pin_controls(struct hdafg_softc * sc)1983 hdafg_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
2057 static void
hdafg_dump_ctl(const struct hdafg_softc * sc,const struct hdaudio_control * ctl)2058 hdafg_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 
2080 static void
hdafg_dump(const struct hdafg_softc * sc)2081 hdafg_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 
2089 static int
hdafg_match(device_t parent,cfdata_t match,void * opaque)2090 hdafg_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 
2103 static void
hdafg_disable_unassoc(struct hdafg_softc * sc)2104 hdafg_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 
2187 static void
hdafg_disable_unsel(struct hdafg_softc * sc)2188 hdafg_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 
2218 static void
hdafg_disable_crossassoc(struct hdafg_softc * sc)2219 hdafg_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 
2282 static struct hdaudio_control *
hdafg_control_amp_get(struct hdafg_softc * sc,int nid,enum hdaudio_pindir dir,int index,int cnt)2283 hdafg_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 
2309 static void
hdafg_control_amp_set1(struct hdaudio_control * ctl,int lmute,int rmute,int left,int right,int dir)2310 hdafg_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 
2331 static void
hdafg_control_amp_set(struct hdaudio_control * ctl,uint32_t mute,int left,int right)2332 hdafg_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  */
2367 static bool
hdafg_mixer_child_is_input(const struct hdafg_softc * sc,const struct hdaudio_control * ctl)2368 hdafg_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 
2404 static void
hdafg_control_commit(struct hdafg_softc * sc)2405 hdafg_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 
2427 static void
hdafg_widget_connection_select(struct hdaudio_widget * w,uint8_t index)2428 hdafg_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 
2440 static void
hdafg_assign_names(struct hdafg_softc * sc)2441 hdafg_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 
2587 static int
hdafg_control_source_amp(struct hdafg_softc * sc,int nid,int index,int audiodev,int ctlable,int depth,int need)2588 hdafg_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 
2677 static void
hdafg_control_dest_amp(struct hdafg_softc * sc,int nid,int audiodev,int depth,int need)2678 hdafg_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 
2755 static void
hdafg_assign_mixers(struct hdafg_softc * sc)2756 hdafg_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 
2803 static void
hdafg_build_mixers(struct hdafg_softc * sc)2804 hdafg_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 
3046 static void
hdafg_commit(struct hdafg_softc * sc)3047 hdafg_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 
3098 static void
hdafg_stream_connect_hdmi(struct hdafg_softc * sc,struct hdaudio_assoc * as,struct hdaudio_widget * w,const audio_params_t * params)3099 hdafg_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 
3154 static void
hdafg_stream_connect(struct hdafg_softc * sc,int mode)3155 hdafg_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 
3280 static int
hdafg_stream_intr(struct hdaudio_stream * st)3281 hdafg_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 
3304 static bool
hdafg_rate_supported(struct hdafg_softc * sc,u_int frequency)3305 hdafg_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 
3345 static bool
hdafg_bits_supported(struct hdafg_softc * sc,u_int bits)3346 hdafg_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 
3367 static bool
hdafg_probe_encoding(struct hdafg_softc * sc,u_int validbits,u_int precision,int encoding,bool force)3368 hdafg_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 
3423 static void
hdafg_configure_encodings(struct hdafg_softc * sc)3424 hdafg_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 
3521 static void
hdafg_hp_switch_handler(struct hdafg_softc * sc)3522 hdafg_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 
3594 static void
hdafg_hp_switch_thread(void * opaque)3595 hdafg_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 
3616 static void
hdafg_hp_switch_init(struct hdafg_softc * sc)3617 hdafg_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 
3702 static void
hdafg_attach(device_t parent,device_t self,void * opaque)3703 hdafg_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 
3856 static int
hdafg_detach(device_t self,int flags)3857 hdafg_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 
3911 static void
hdafg_childdet(device_t self,device_t child)3912 hdafg_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 
3920 static bool
hdafg_suspend(device_t self,const pmf_qual_t * qual)3921 hdafg_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 
3935 static bool
hdafg_resume(device_t self,const pmf_qual_t * qual)3936 hdafg_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 
3972 static int
hdafg_query_format(void * opaque,audio_format_query_t * afp)3973 hdafg_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 
3980 static int
hdafg_set_format(void * opaque,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)3981 hdafg_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 */
3999 static u_int gcd(u_int, u_int);
4000 static u_int lcm(u_int, u_int);
4001 
gcd(u_int a,u_int b)4002 static u_int gcd(u_int a, u_int b)
4003 {
4004 
4005 	return (b == 0) ? a : gcd(b, a % b);
4006 }
lcm(u_int a,u_int b)4007 static u_int lcm(u_int a, u_int b)
4008 {
4009 
4010 	return a * b / gcd(a, b);
4011 }
4012 
4013 static int
hdafg_round_blocksize(void * opaque,int blksize,int mode,const audio_params_t * param)4014 hdafg_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 
4057 static int
hdafg_commit_settings(void * opaque)4058 hdafg_commit_settings(void *opaque)
4059 {
4060 	return 0;
4061 }
4062 
4063 static int
hdafg_halt_output(void * opaque)4064 hdafg_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 
4101 static int
hdafg_halt_input(void * opaque)4102 hdafg_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 
4111 static int
hdafg_getdev(void * opaque,struct audio_device * audiodev)4112 hdafg_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 
4125 static int
hdafg_set_port(void * opaque,mixer_ctrl_t * mc)4126 hdafg_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 
4185 static int
hdafg_get_port(void * opaque,mixer_ctrl_t * mc)4186 hdafg_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 
4242 static int
hdafg_query_devinfo(void * opaque,mixer_devinfo_t * di)4243 hdafg_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 
4256 static void *
hdafg_allocm(void * opaque,int direction,size_t size)4257 hdafg_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 
4279 static void
hdafg_freem(void * opaque,void * addr,size_t size)4280 hdafg_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 
4297 static int
hdafg_get_props(void * opaque)4298 hdafg_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 
4315 static int
hdafg_trigger_output(void * opaque,void * start,void * end,int blksize,void (* intr)(void *),void * intrarg,const audio_params_t * param)4316 hdafg_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 
4338 static int
hdafg_trigger_input(void * opaque,void * start,void * end,int blksize,void (* intr)(void *),void * intrarg,const audio_params_t * param)4339 hdafg_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 
4361 static void
hdafg_get_locks(void * opaque,kmutex_t ** intr,kmutex_t ** thread)4362 hdafg_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 
4370 static int
hdafg_unsol(device_t self,uint8_t tag)4371 hdafg_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 
4402 static int
hdafg_widget_info(void * opaque,prop_dictionary_t request,prop_dictionary_t response)4403 hdafg_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 
4447 static int
hdafg_codec_info(void * opaque,prop_dictionary_t request,prop_dictionary_t response)4448 hdafg_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 
4459 MODULE(MODULE_CLASS_DRIVER, hdafg, "hdaudio");
4460 
4461 #ifdef _MODULE
4462 #include "ioconf.c"
4463 #endif
4464 
4465 static int
hdafg_modcmd(modcmd_t cmd,void * opaque)4466 hdafg_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 
4496 static void
hdafg_enable_analog_beep(struct hdafg_softc * sc)4497 hdafg_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