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