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