hdafg.c revision 1.25 1 /* $NetBSD: hdafg.c,v 1.25 2021/12/17 17:02:40 kre 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.25 2021/12/17 17:02:40 kre 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 /
2891 (masterctl->ctl_step ? masterctl->ctl_step : 1);
2892 strcpy(mx[index].mx_di.label.name, AudioNmaster);
2893 strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
2894 hda_trace(sc, " adding outputs.%s\n",
2895 mx[index].mx_di.label.name);
2896 ++index;
2897 if (masterctl->ctl_mute) {
2898 mx[index] = mx[index - 1];
2899 mx[index].mx_di.index = index;
2900 mx[index].mx_di.type = AUDIO_MIXER_ENUM;
2901 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2902 strcpy(mx[index].mx_di.label.name, AudioNmaster "." AudioNmute);
2903 mx[index].mx_di.un.e.num_mem = 2;
2904 strcpy(mx[index].mx_di.un.e.member[0].label.name, AudioNoff);
2905 mx[index].mx_di.un.e.member[0].ord = 0;
2906 strcpy(mx[index].mx_di.un.e.member[1].label.name, AudioNon);
2907 mx[index].mx_di.un.e.member[1].ord = 1;
2908 ++index;
2909 }
2910 }
2911
2912 /* Build volume mixers */
2913 for (i = 0; i < sc->sc_nctls; i++) {
2914 uint32_t audiodev;
2915
2916 ctl = &sc->sc_ctls[i];
2917 if (ctl->ctl_enable == false ||
2918 ctl->ctl_audiomask == 0)
2919 continue;
2920 audiodev = ffs(ctl->ctl_audiomask) - 1;
2921 mx[index].mx_ctl = ctl;
2922 mx[index].mx_di.index = index;
2923 mx[index].mx_di.type = AUDIO_MIXER_VALUE;
2924 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2925 mx[index].mx_di.un.v.num_channels = 2; /* XXX */
2926 mx[index].mx_di.un.v.delta = 256 /
2927 (ctl->ctl_step ? ctl->ctl_step : 1);
2928 if (ctrlcnt[audiodev] > 0)
2929 snprintf(mx[index].mx_di.label.name,
2930 sizeof(mx[index].mx_di.label.name),
2931 "%s%d",
2932 hdafg_mixer_names[audiodev],
2933 ctrlcnt[audiodev] + 1);
2934 else
2935 strcpy(mx[index].mx_di.label.name,
2936 hdafg_mixer_names[audiodev]);
2937 ctrlcnt[audiodev]++;
2938
2939 switch (audiodev) {
2940 case HDAUDIO_MIXER_VOLUME:
2941 case HDAUDIO_MIXER_BASS:
2942 case HDAUDIO_MIXER_TREBLE:
2943 case HDAUDIO_MIXER_OGAIN:
2944 mx[index].mx_di.mixer_class =
2945 HDAUDIO_MIXER_CLASS_OUTPUTS;
2946 hda_trace(sc, " adding outputs.%s\n",
2947 mx[index].mx_di.label.name);
2948 break;
2949 case HDAUDIO_MIXER_MIC:
2950 case HDAUDIO_MIXER_MONITOR:
2951 mx[index].mx_di.mixer_class =
2952 HDAUDIO_MIXER_CLASS_RECORD;
2953 hda_trace(sc, " adding record.%s\n",
2954 mx[index].mx_di.label.name);
2955 break;
2956 default:
2957 mx[index].mx_di.mixer_class =
2958 HDAUDIO_MIXER_CLASS_INPUTS;
2959 hda_trace(sc, " adding inputs.%s\n",
2960 mx[index].mx_di.label.name);
2961 break;
2962 }
2963 strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
2964
2965 ++index;
2966
2967 if (ctl->ctl_mute) {
2968 mx[index] = mx[index - 1];
2969 mx[index].mx_di.index = index;
2970 mx[index].mx_di.type = AUDIO_MIXER_ENUM;
2971 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2972 snprintf(mx[index].mx_di.label.name,
2973 sizeof(mx[index].mx_di.label.name),
2974 "%s." AudioNmute,
2975 mx[index - 1].mx_di.label.name);
2976 mx[index].mx_di.un.e.num_mem = 2;
2977 strcpy(mx[index].mx_di.un.e.member[0].label.name, AudioNoff);
2978 mx[index].mx_di.un.e.member[0].ord = 0;
2979 strcpy(mx[index].mx_di.un.e.member[1].label.name, AudioNon);
2980 mx[index].mx_di.un.e.member[1].ord = 1;
2981 ++index;
2982 }
2983 }
2984
2985 /* DAC selector */
2986 if (ndac > 0) {
2987 mx[index].mx_ctl = NULL;
2988 mx[index].mx_di.index = index;
2989 mx[index].mx_di.type = AUDIO_MIXER_SET;
2990 mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_OUTPUTS;
2991 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2992 strcpy(mx[index].mx_di.label.name, "dacsel"); /* AudioNselect */
2993 mx[index].mx_di.un.s.num_mem = ndac;
2994 for (i = 0, j = 0; i < sc->sc_nassocs; i++) {
2995 if (sc->sc_assocs[i].as_enable == false)
2996 continue;
2997 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_OUT)
2998 continue;
2999 mx[index].mx_di.un.s.member[j].mask = 1 << i;
3000 snprintf(mx[index].mx_di.un.s.member[j].label.name,
3001 sizeof(mx[index].mx_di.un.s.member[j].label.name),
3002 "%s%02X",
3003 hdafg_assoc_type_string(&sc->sc_assocs[i]), i);
3004 ++j;
3005 }
3006 ++index;
3007 }
3008
3009 /* ADC selector */
3010 if (nadc > 0) {
3011 mx[index].mx_ctl = NULL;
3012 mx[index].mx_di.index = index;
3013 mx[index].mx_di.type = AUDIO_MIXER_SET;
3014 mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_RECORD;
3015 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
3016 strcpy(mx[index].mx_di.label.name, AudioNsource);
3017 mx[index].mx_di.un.s.num_mem = nadc;
3018 for (i = 0, j = 0; i < sc->sc_nassocs; i++) {
3019 if (sc->sc_assocs[i].as_enable == false)
3020 continue;
3021 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_IN)
3022 continue;
3023 mx[index].mx_di.un.s.member[j].mask = 1 << i;
3024 snprintf(mx[index].mx_di.un.s.member[j].label.name,
3025 sizeof(mx[index].mx_di.un.s.member[j].label.name),
3026 "%s%02X",
3027 hdafg_assoc_type_string(&sc->sc_assocs[i]), i);
3028 ++j;
3029 }
3030 ++index;
3031 }
3032
3033 sc->sc_mixers = mx;
3034 }
3035
3036 static void
3037 hdafg_commit(struct hdafg_softc *sc)
3038 {
3039 struct hdaudio_widget *w;
3040 uint32_t gdata, gmask, gdir;
3041 int commitgpio;
3042 int i;
3043
3044 /* Commit controls */
3045 hdafg_control_commit(sc);
3046
3047 /* Commit selectors, pins, and EAPD */
3048 for (i = 0; i < sc->sc_nwidgets; i++) {
3049 w = &sc->sc_widgets[i];
3050 if (w->w_selconn == -1)
3051 w->w_selconn = 0;
3052 if (w->w_nconns > 0)
3053 hdafg_widget_connection_select(w, w->w_selconn);
3054 if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
3055 hdaudio_command(sc->sc_codec, w->w_nid,
3056 CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3057 if (w->w_p.eapdbtl != 0xffffffff)
3058 hdaudio_command(sc->sc_codec, w->w_nid,
3059 CORB_SET_EAPD_BTL_ENABLE, w->w_p.eapdbtl);
3060 }
3061
3062 gdata = gmask = gdir = commitgpio = 0;
3063 #ifdef notyet
3064 int numgpio = COP_GPIO_COUNT_NUM_GPIO(sc->sc_p.gpio_cnt);
3065
3066 hda_trace(sc, "found %d GPIOs\n", numgpio);
3067 for (i = 0; i < numgpio && i < 8; i++) {
3068 if (commitgpio == 0)
3069 commitgpio = 1;
3070 gdata |= 1 << i;
3071 gmask |= 1 << i;
3072 gdir |= 1 << i;
3073 }
3074 #endif
3075
3076 if (commitgpio) {
3077 hda_trace(sc, "GPIO commit: data=%08X mask=%08X dir=%08X\n",
3078 gdata, gmask, gdir);
3079 hdaudio_command(sc->sc_codec, sc->sc_nid,
3080 CORB_SET_GPIO_ENABLE_MASK, gmask);
3081 hdaudio_command(sc->sc_codec, sc->sc_nid,
3082 CORB_SET_GPIO_DIRECTION, gdir);
3083 hdaudio_command(sc->sc_codec, sc->sc_nid,
3084 CORB_SET_GPIO_DATA, gdata);
3085 }
3086 }
3087
3088 static void
3089 hdafg_stream_connect_hdmi(struct hdafg_softc *sc, struct hdaudio_assoc *as,
3090 struct hdaudio_widget *w, const audio_params_t *params)
3091 {
3092 struct hdmi_audio_infoframe hdmi;
3093 /* TODO struct displayport_audio_infoframe dp; */
3094 uint8_t *dip = NULL;
3095 size_t diplen = 0;
3096 int i;
3097
3098 #ifdef HDAFG_HDMI_DEBUG
3099 uint32_t res;
3100 res = hdaudio_command(sc->sc_codec, w->w_nid,
3101 CORB_GET_HDMI_DIP_XMIT_CTRL, 0);
3102 hda_print(sc, "connect HDMI nid %02X, xmitctrl = 0x%08X\n",
3103 w->w_nid, res);
3104 #endif
3105
3106 /* disable infoframe transmission */
3107 hdaudio_command(sc->sc_codec, w->w_nid,
3108 CORB_SET_HDMI_DIP_XMIT_CTRL, COP_DIP_XMIT_CTRL_DISABLE);
3109
3110 if (sc->sc_disable_dip)
3111 return;
3112
3113 /* build new infoframe */
3114 if (as->as_digital == HDAFG_AS_HDMI) {
3115 dip = (uint8_t *)&hdmi;
3116 diplen = sizeof(hdmi);
3117 memset(&hdmi, 0, sizeof(hdmi));
3118 hdmi.header.packet_type = HDMI_AI_PACKET_TYPE;
3119 hdmi.header.version = HDMI_AI_VERSION;
3120 hdmi.header.length = HDMI_AI_LENGTH;
3121 hdmi.ct_cc = params->channels - 1;
3122 if (params->channels > 2) {
3123 hdmi.ca = 0x1f;
3124 } else {
3125 hdmi.ca = 0x00;
3126 }
3127 hdafg_dd_hdmi_ai_cksum(&hdmi);
3128 }
3129 /* update data island with new audio infoframe */
3130 if (dip) {
3131 hdaudio_command(sc->sc_codec, w->w_nid,
3132 CORB_SET_HDMI_DIP_INDEX, 0);
3133 for (i = 0; i < diplen; i++) {
3134 hdaudio_command(sc->sc_codec, w->w_nid,
3135 CORB_SET_HDMI_DIP_DATA, dip[i]);
3136 }
3137 }
3138
3139 /* enable infoframe transmission */
3140 hdaudio_command(sc->sc_codec, w->w_nid,
3141 CORB_SET_HDMI_DIP_XMIT_CTRL, COP_DIP_XMIT_CTRL_BEST_EFFORT);
3142 }
3143
3144 static void
3145 hdafg_stream_connect(struct hdafg_softc *sc, int mode)
3146 {
3147 struct hdaudio_assoc *as = sc->sc_assocs;
3148 struct hdaudio_widget *w;
3149 const audio_params_t *params;
3150 uint16_t fmt, dfmt;
3151 int tag, chn, maxchan, c;
3152 int i, j, k;
3153
3154 KASSERT(mode == AUMODE_PLAY || mode == AUMODE_RECORD);
3155
3156 if (mode == AUMODE_PLAY) {
3157 fmt = hdaudio_stream_param(sc->sc_audiodev.ad_playback,
3158 &sc->sc_pparam);
3159 params = &sc->sc_pparam;
3160 } else {
3161 fmt = hdaudio_stream_param(sc->sc_audiodev.ad_capture,
3162 &sc->sc_rparam);
3163 params = &sc->sc_rparam;
3164 }
3165
3166 for (i = 0; i < sc->sc_nassocs; i++) {
3167 if (as[i].as_enable == false)
3168 continue;
3169
3170 if (mode == AUMODE_PLAY && as[i].as_dir != HDAUDIO_PINDIR_OUT)
3171 continue;
3172 if (mode == AUMODE_RECORD && as[i].as_dir != HDAUDIO_PINDIR_IN)
3173 continue;
3174
3175 fmt &= ~HDAUDIO_FMT_CHAN_MASK;
3176 if (as[i].as_dir == HDAUDIO_PINDIR_OUT &&
3177 sc->sc_audiodev.ad_playback != NULL) {
3178 tag = hdaudio_stream_tag(sc->sc_audiodev.ad_playback);
3179 fmt |= HDAUDIO_FMT_CHAN(sc->sc_pparam.channels);
3180 maxchan = sc->sc_pparam.channels;
3181 } else if (as[i].as_dir == HDAUDIO_PINDIR_IN &&
3182 sc->sc_audiodev.ad_capture != NULL) {
3183 tag = hdaudio_stream_tag(sc->sc_audiodev.ad_capture);
3184 fmt |= HDAUDIO_FMT_CHAN(sc->sc_rparam.channels);
3185 maxchan = sc->sc_rparam.channels;
3186 } else {
3187 tag = 0;
3188 if (as[i].as_dir == HDAUDIO_PINDIR_OUT) {
3189 fmt |= HDAUDIO_FMT_CHAN(sc->sc_pchan);
3190 maxchan = sc->sc_pchan;
3191 } else {
3192 fmt |= HDAUDIO_FMT_CHAN(sc->sc_rchan);
3193 maxchan = sc->sc_rchan;
3194 }
3195 }
3196
3197 chn = 0;
3198 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3199 if (as[i].as_dacs[j] == 0)
3200 continue;
3201 w = hdafg_widget_lookup(sc, as[i].as_dacs[j]);
3202 if (w == NULL || w->w_enable == FALSE)
3203 continue;
3204 if (as[i].as_hpredir >= 0 && i == as[i].as_pincnt)
3205 chn = 0;
3206 if (chn >= maxchan)
3207 chn = 0; /* XXX */
3208 c = (tag << 4) | chn;
3209
3210 if (as[i].as_activated == false)
3211 c = 0;
3212
3213 /*
3214 * If a non-PCM stream is being connected, and the
3215 * analog converter doesn't support non-PCM streams,
3216 * then don't decode it
3217 */
3218 if (!(w->w_p.aw_cap & COP_AWCAP_DIGITAL) &&
3219 !(w->w_p.stream_format & COP_STREAM_FORMAT_AC3) &&
3220 (fmt & HDAUDIO_FMT_TYPE_NONPCM)) {
3221 hdaudio_command(sc->sc_codec, w->w_nid,
3222 CORB_SET_CONVERTER_STREAM_CHANNEL, 0);
3223 continue;
3224 }
3225
3226 hdaudio_command(sc->sc_codec, w->w_nid,
3227 CORB_SET_CONVERTER_FORMAT, fmt);
3228 if (w->w_p.aw_cap & COP_AWCAP_DIGITAL) {
3229 dfmt = hdaudio_command(sc->sc_codec, w->w_nid,
3230 CORB_GET_DIGITAL_CONVERTER_CONTROL, 0) &
3231 0xff;
3232 dfmt |= COP_DIGITAL_CONVCTRL1_DIGEN;
3233 if (fmt & HDAUDIO_FMT_TYPE_NONPCM)
3234 dfmt |= COP_DIGITAL_CONVCTRL1_NAUDIO;
3235 else
3236 dfmt &= ~COP_DIGITAL_CONVCTRL1_NAUDIO;
3237 if (sc->sc_vendor == HDAUDIO_VENDOR_NVIDIA)
3238 dfmt |= COP_DIGITAL_CONVCTRL1_COPY;
3239 hdaudio_command(sc->sc_codec, w->w_nid,
3240 CORB_SET_DIGITAL_CONVERTER_CONTROL_1, dfmt);
3241 }
3242 if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP)) {
3243 hdaudio_command(sc->sc_codec, w->w_nid,
3244 CORB_SET_CONVERTER_CHANNEL_COUNT,
3245 maxchan - 1);
3246 for (k = 0; k < maxchan; k++) {
3247 hdaudio_command(sc->sc_codec, w->w_nid,
3248 CORB_ASP_SET_CHANNEL_MAPPING,
3249 (k << 4) | k);
3250 }
3251 }
3252 hdaudio_command(sc->sc_codec, w->w_nid,
3253 CORB_SET_CONVERTER_STREAM_CHANNEL, c);
3254 chn += COP_AWCAP_CHANNEL_COUNT(w->w_p.aw_cap);
3255 }
3256
3257 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3258 if (as[i].as_pins[j] == 0)
3259 continue;
3260 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3261 if (w == NULL || w->w_enable == FALSE)
3262 continue;
3263 if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
3264 hdafg_stream_connect_hdmi(sc, &as[i],
3265 w, params);
3266 }
3267 }
3268 }
3269
3270 static int
3271 hdafg_stream_intr(struct hdaudio_stream *st)
3272 {
3273 struct hdaudio_audiodev *ad = st->st_cookie;
3274 int handled = 0;
3275
3276 (void)hda_read1(ad->ad_sc->sc_host, HDAUDIO_SD_STS(st->st_shift));
3277 hda_write1(ad->ad_sc->sc_host, HDAUDIO_SD_STS(st->st_shift),
3278 HDAUDIO_STS_DESE | HDAUDIO_STS_FIFOE | HDAUDIO_STS_BCIS);
3279
3280 mutex_spin_enter(&ad->ad_sc->sc_intr_lock);
3281 /* XXX test (sts & HDAUDIO_STS_BCIS)? */
3282 if (st == ad->ad_playback && ad->ad_playbackintr) {
3283 ad->ad_playbackintr(ad->ad_playbackintrarg);
3284 handled = 1;
3285 } else if (st == ad->ad_capture && ad->ad_captureintr) {
3286 ad->ad_captureintr(ad->ad_captureintrarg);
3287 handled = 1;
3288 }
3289 mutex_spin_exit(&ad->ad_sc->sc_intr_lock);
3290
3291 return handled;
3292 }
3293
3294 static bool
3295 hdafg_rate_supported(struct hdafg_softc *sc, u_int frequency)
3296 {
3297 uint32_t caps = sc->sc_p.pcm_size_rate;
3298
3299 if (sc->sc_fixed_rate)
3300 return frequency == sc->sc_fixed_rate;
3301
3302 #define ISFREQOK(shift) ((caps & (1 << (shift))) ? true : false)
3303 switch (frequency) {
3304 case 8000:
3305 return ISFREQOK(0);
3306 case 11025:
3307 return ISFREQOK(1);
3308 case 16000:
3309 return ISFREQOK(2);
3310 case 22050:
3311 return ISFREQOK(3);
3312 case 32000:
3313 return ISFREQOK(4);
3314 case 44100:
3315 return ISFREQOK(5);
3316 return true;
3317 case 48000:
3318 return true; /* Must be supported by all codecs */
3319 case 88200:
3320 return ISFREQOK(7);
3321 case 96000:
3322 return ISFREQOK(8);
3323 case 176400:
3324 return ISFREQOK(9);
3325 case 192000:
3326 return ISFREQOK(10);
3327 case 384000:
3328 return ISFREQOK(11);
3329 default:
3330 return false;
3331 }
3332 #undef ISFREQOK
3333 }
3334
3335 static bool
3336 hdafg_bits_supported(struct hdafg_softc *sc, u_int bits)
3337 {
3338 uint32_t caps = sc->sc_p.pcm_size_rate;
3339 #define ISBITSOK(shift) ((caps & (1 << (shift))) ? true : false)
3340 switch (bits) {
3341 case 8:
3342 return ISBITSOK(16);
3343 case 16:
3344 return ISBITSOK(17);
3345 case 20:
3346 return ISBITSOK(18);
3347 case 24:
3348 return ISBITSOK(19);
3349 case 32:
3350 return ISBITSOK(20);
3351 default:
3352 return false;
3353 }
3354 #undef ISBITSOK
3355 }
3356
3357 static bool
3358 hdafg_probe_encoding(struct hdafg_softc *sc,
3359 u_int validbits, u_int precision, int encoding, bool force)
3360 {
3361 struct audio_format f;
3362 int i;
3363
3364 if (!force && hdafg_bits_supported(sc, validbits) == false)
3365 return false;
3366
3367 memset(&f, 0, sizeof(f));
3368 f.driver_data = NULL;
3369 f.mode = 0;
3370 f.encoding = encoding;
3371 f.validbits = validbits;
3372 f.precision = precision;
3373 f.channels = 0;
3374 f.channel_mask = 0;
3375 f.frequency_type = 0;
3376 for (i = 0; i < __arraycount(hdafg_possible_rates); i++) {
3377 u_int rate = hdafg_possible_rates[i];
3378 if (hdafg_rate_supported(sc, rate))
3379 f.frequency[f.frequency_type++] = rate;
3380 }
3381 /* XXX ad hoc.. */
3382 if (encoding == AUDIO_ENCODING_AC3)
3383 f.priority = -1;
3384
3385 #define HDAUDIO_INITFMT(ch, chmask) \
3386 do { \
3387 f.channels = (ch); \
3388 f.channel_mask = (chmask); \
3389 f.mode = 0; \
3390 if (sc->sc_pchan >= (ch)) \
3391 f.mode |= AUMODE_PLAY; \
3392 if (sc->sc_rchan >= (ch)) \
3393 f.mode |= AUMODE_RECORD; \
3394 if (f.mode != 0) \
3395 hdafg_append_formats(&sc->sc_audiodev, &f); \
3396 } while (0)
3397
3398 /* Commented out, otherwise monaural samples play through left
3399 * channel only
3400 */
3401 /* HDAUDIO_INITFMT(1, AUFMT_MONAURAL); */
3402 HDAUDIO_INITFMT(2, AUFMT_STEREO);
3403 HDAUDIO_INITFMT(4, AUFMT_SURROUND4);
3404 HDAUDIO_INITFMT(6, AUFMT_DOLBY_5_1);
3405 HDAUDIO_INITFMT(8, AUFMT_SURROUND_7_1);
3406
3407 #undef HDAUDIO_INITFMT
3408
3409 return true;
3410 }
3411
3412
3413 static void
3414 hdafg_configure_encodings(struct hdafg_softc *sc)
3415 {
3416 struct hdaudio_assoc *as = sc->sc_assocs;
3417 struct hdaudio_widget *w;
3418 struct audio_format f;
3419 uint32_t stream_format, caps;
3420 int nchan, i, nid;
3421
3422 sc->sc_pchan = sc->sc_rchan = 0;
3423
3424 for (i = 0; i < sc->sc_nassocs; i++) {
3425 nchan = hdafg_assoc_count_channels(sc, &as[i],
3426 HDAUDIO_PINDIR_OUT);
3427 if (nchan > sc->sc_pchan)
3428 sc->sc_pchan = nchan;
3429 }
3430 for (i = 0; i < sc->sc_nassocs; i++) {
3431 nchan = hdafg_assoc_count_channels(sc, &as[i],
3432 HDAUDIO_PINDIR_IN);
3433 if (nchan > sc->sc_rchan)
3434 sc->sc_rchan = nchan;
3435 }
3436 hda_print(sc, "%dch/%dch", sc->sc_pchan, sc->sc_rchan);
3437
3438 for (i = 0; i < __arraycount(hdafg_possible_rates); i++)
3439 if (hdafg_rate_supported(sc,
3440 hdafg_possible_rates[i]))
3441 hda_print1(sc, " %uHz", hdafg_possible_rates[i]);
3442
3443 stream_format = sc->sc_p.stream_format;
3444 caps = 0;
3445 for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3446 w = hdafg_widget_lookup(sc, nid);
3447 if (w == NULL)
3448 continue;
3449 stream_format |= w->w_p.stream_format;
3450 caps |= w->w_p.aw_cap;
3451 }
3452 if (stream_format == 0) {
3453 hda_print(sc,
3454 "WARNING: unsupported stream format mask 0x%X, assuming PCM\n",
3455 stream_format);
3456 stream_format |= COP_STREAM_FORMAT_PCM;
3457 }
3458
3459 if (stream_format & COP_STREAM_FORMAT_PCM) {
3460 int e = AUDIO_ENCODING_SLINEAR_LE;
3461 if (hdafg_probe_encoding(sc, 8, 16, e, false))
3462 hda_print1(sc, " PCM8");
3463 if (hdafg_probe_encoding(sc, 16, 16, e, false))
3464 hda_print1(sc, " PCM16");
3465 if (hdafg_probe_encoding(sc, 20, 32, e, false))
3466 hda_print1(sc, " PCM20");
3467 if (hdafg_probe_encoding(sc, 24, 32, e, false))
3468 hda_print1(sc, " PCM24");
3469 if (hdafg_probe_encoding(sc, 32, 32, e, false))
3470 hda_print1(sc, " PCM32");
3471 }
3472
3473 if ((stream_format & COP_STREAM_FORMAT_AC3) ||
3474 (caps & COP_AWCAP_DIGITAL)) {
3475 int e = AUDIO_ENCODING_AC3;
3476 if (hdafg_probe_encoding(sc, 16, 16, e, false))
3477 hda_print1(sc, " AC3");
3478 }
3479
3480 if (sc->sc_audiodev.ad_nformats == 0) {
3481 hdafg_probe_encoding(sc, 16, 16, AUDIO_ENCODING_SLINEAR_LE, true);
3482 hda_print1(sc, " PCM16*");
3483 }
3484
3485 /*
3486 * XXX JDM 20090614
3487 * MI audio assumes that at least one playback and one capture format
3488 * is reported by the hw driver; until this bug is resolved just
3489 * report 2ch capabilities if the function group does not support
3490 * the direction.
3491 */
3492 if (sc->sc_rchan == 0 || sc->sc_pchan == 0) {
3493 memset(&f, 0, sizeof(f));
3494 f.driver_data = NULL;
3495 f.mode = 0;
3496 f.encoding = AUDIO_ENCODING_SLINEAR_LE;
3497 f.validbits = 16;
3498 f.precision = 16;
3499 f.channels = 2;
3500 f.channel_mask = AUFMT_STEREO;
3501 f.frequency_type = 0;
3502 f.frequency[0] = f.frequency[1] = sc->sc_fixed_rate ?
3503 sc->sc_fixed_rate : 48000;
3504 f.mode = AUMODE_PLAY|AUMODE_RECORD;
3505 hdafg_append_formats(&sc->sc_audiodev, &f);
3506 }
3507
3508 hda_print1(sc, "\n");
3509 }
3510
3511 static void
3512 hdafg_hp_switch_handler(void *opaque)
3513 {
3514 struct hdafg_softc *sc = opaque;
3515 struct hdaudio_assoc *as = sc->sc_assocs;
3516 struct hdaudio_widget *w;
3517 uint32_t res = 0;
3518 int i, j;
3519
3520 if (!device_is_active(sc->sc_dev))
3521 goto resched;
3522
3523 for (i = 0; i < sc->sc_nassocs; i++) {
3524 if (as[i].as_digital != HDAFG_AS_ANALOG &&
3525 as[i].as_digital != HDAFG_AS_SPDIF)
3526 continue;
3527 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3528 if (as[i].as_pins[j] == 0)
3529 continue;
3530 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3531 if (w == NULL || w->w_enable == false)
3532 continue;
3533 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3534 continue;
3535 if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) !=
3536 COP_DEVICE_HP_OUT)
3537 continue;
3538 res |= hdaudio_command(sc->sc_codec, as[i].as_pins[j],
3539 CORB_GET_PIN_SENSE, 0) &
3540 COP_GET_PIN_SENSE_PRESENSE_DETECT;
3541 }
3542 }
3543
3544 for (i = 0; i < sc->sc_nassocs; i++) {
3545 if (as[i].as_digital != HDAFG_AS_ANALOG &&
3546 as[i].as_digital != HDAFG_AS_SPDIF)
3547 continue;
3548 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3549 if (as[i].as_pins[j] == 0)
3550 continue;
3551 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3552 if (w == NULL || w->w_enable == false)
3553 continue;
3554 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3555 continue;
3556 switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
3557 case COP_DEVICE_HP_OUT:
3558 if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
3559 w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
3560 else
3561 w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
3562 hdaudio_command(sc->sc_codec, w->w_nid,
3563 CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3564 break;
3565 case COP_DEVICE_LINE_OUT:
3566 case COP_DEVICE_SPEAKER:
3567 case COP_DEVICE_AUX:
3568 if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
3569 w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
3570 else
3571 w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
3572 hdaudio_command(sc->sc_codec, w->w_nid,
3573 CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3574 break;
3575 default:
3576 break;
3577 }
3578 }
3579 }
3580
3581 resched:
3582 callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD);
3583 }
3584
3585 static void
3586 hdafg_hp_switch_init(struct hdafg_softc *sc)
3587 {
3588 struct hdaudio_assoc *as = sc->sc_assocs;
3589 struct hdaudio_widget *w;
3590 bool enable = false;
3591 int i, j;
3592
3593 for (i = 0; i < sc->sc_nassocs; i++) {
3594 if (as[i].as_hpredir < 0 && as[i].as_displaydev == false)
3595 continue;
3596 if (as[i].as_displaydev == false)
3597 w = hdafg_widget_lookup(sc, as[i].as_pins[15]);
3598 else {
3599 w = NULL;
3600 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3601 if (as[i].as_pins[j] == 0)
3602 continue;
3603 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3604 if (w && w->w_enable &&
3605 w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
3606 break;
3607 w = NULL;
3608 }
3609 }
3610 if (w == NULL || w->w_enable == false)
3611 continue;
3612 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3613 continue;
3614 if (!(w->w_pin.cap & COP_PINCAP_PRESENSE_DETECT_CAPABLE)) {
3615 continue;
3616 }
3617 if (COP_CFG_MISC(w->w_pin.config) & 1) {
3618 hda_trace(sc, "no presence detect on pin %02X\n",
3619 w->w_nid);
3620 continue;
3621 }
3622 if ((w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP)) == 0)
3623 enable = true;
3624
3625 if (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) {
3626 uint8_t val = COP_SET_UNSOLICITED_RESPONSE_ENABLE;
3627 if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
3628 val |= HDAUDIO_UNSOLTAG_EVENT_DD;
3629 else
3630 val |= HDAUDIO_UNSOLTAG_EVENT_HP;
3631
3632 hdaudio_command(sc->sc_codec, w->w_nid,
3633 CORB_SET_UNSOLICITED_RESPONSE, val);
3634
3635 hdaudio_command(sc->sc_codec, w->w_nid,
3636 CORB_SET_AMPLIFIER_GAIN_MUTE, 0xb000);
3637 }
3638
3639 hda_trace(sc, "presence detect [pin=%02X,%s",
3640 w->w_nid,
3641 (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) ?
3642 "unsol" : "poll"
3643 );
3644 if (w->w_pin.cap & COP_PINCAP_HDMI)
3645 hda_trace1(sc, ",hdmi");
3646 if (w->w_pin.cap & COP_PINCAP_DP)
3647 hda_trace1(sc, ",displayport");
3648 hda_trace1(sc, "]\n");
3649 }
3650 if (enable) {
3651 sc->sc_jack_polling = true;
3652 hdafg_hp_switch_handler(sc);
3653 } else
3654 hda_trace(sc, "jack detect not enabled\n");
3655 }
3656
3657 static void
3658 hdafg_attach(device_t parent, device_t self, void *opaque)
3659 {
3660 struct hdafg_softc *sc = device_private(self);
3661 audio_params_t defparams;
3662 prop_dictionary_t args = opaque;
3663 char vendor[MAX_AUDIO_DEV_LEN], product[MAX_AUDIO_DEV_LEN];
3664 uint64_t fgptr = 0;
3665 uint32_t astype = 0;
3666 uint8_t nid = 0;
3667 int i;
3668 bool rv;
3669
3670 aprint_naive("\n");
3671 sc->sc_dev = self;
3672
3673 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
3674 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
3675
3676 callout_init(&sc->sc_jack_callout, 0);
3677 callout_setfunc(&sc->sc_jack_callout,
3678 hdafg_hp_switch_handler, sc);
3679
3680 if (!pmf_device_register(self, hdafg_suspend, hdafg_resume))
3681 aprint_error_dev(self, "couldn't establish power handler\n");
3682
3683 sc->sc_config = prop_dictionary_get(args, "pin-config");
3684 if (sc->sc_config && prop_object_type(sc->sc_config) != PROP_TYPE_ARRAY)
3685 sc->sc_config = NULL;
3686
3687 prop_dictionary_get_uint16(args, "vendor-id", &sc->sc_vendor);
3688 prop_dictionary_get_uint16(args, "product-id", &sc->sc_product);
3689 hdaudio_findvendor(vendor, sizeof(vendor), sc->sc_vendor);
3690 hdaudio_findproduct(product, sizeof(product), sc->sc_vendor,
3691 sc->sc_product);
3692 hda_print1(sc, ": %s %s%s\n", vendor, product,
3693 sc->sc_config ? " (custom configuration)" : "");
3694
3695 switch (sc->sc_vendor) {
3696 case HDAUDIO_VENDOR_NVIDIA:
3697 switch (sc->sc_product) {
3698 case HDAUDIO_PRODUCT_NVIDIA_TEGRA124_HDMI:
3699 sc->sc_fixed_rate = 44100;
3700 sc->sc_disable_dip = true;
3701 break;
3702 }
3703 break;
3704 }
3705
3706 rv = prop_dictionary_get_uint64(args, "function-group", &fgptr);
3707 if (rv == false || fgptr == 0) {
3708 hda_error(sc, "missing function-group property\n");
3709 return;
3710 }
3711 rv = prop_dictionary_get_uint8(args, "node-id", &nid);
3712 if (rv == false || nid == 0) {
3713 hda_error(sc, "missing node-id property\n");
3714 return;
3715 }
3716
3717 prop_dictionary_set_uint64(device_properties(self),
3718 "codecinfo-callback",
3719 (uint64_t)(uintptr_t)hdafg_codec_info);
3720 prop_dictionary_set_uint64(device_properties(self),
3721 "widgetinfo-callback",
3722 (uint64_t)(uintptr_t)hdafg_widget_info);
3723
3724 sc->sc_nid = nid;
3725 sc->sc_fg = (struct hdaudio_function_group *)(vaddr_t)fgptr;
3726 sc->sc_fg->fg_unsol = hdafg_unsol;
3727 sc->sc_codec = sc->sc_fg->fg_codec;
3728 KASSERT(sc->sc_codec != NULL);
3729 sc->sc_host = sc->sc_codec->co_host;
3730 KASSERT(sc->sc_host != NULL);
3731
3732 hda_debug(sc, "parsing widgets\n");
3733 hdafg_parse(sc);
3734 hda_debug(sc, "parsing controls\n");
3735 hdafg_control_parse(sc);
3736 hda_debug(sc, "disabling non-audio devices\n");
3737 hdafg_disable_nonaudio(sc);
3738 hda_debug(sc, "disabling useless devices\n");
3739 hdafg_disable_useless(sc);
3740 hda_debug(sc, "parsing associations\n");
3741 hdafg_assoc_parse(sc);
3742 hda_debug(sc, "building tree\n");
3743 hdafg_build_tree(sc);
3744 hda_debug(sc, "disabling unassociated pins\n");
3745 hdafg_disable_unassoc(sc);
3746 hda_debug(sc, "disabling unselected pins\n");
3747 hdafg_disable_unsel(sc);
3748 hda_debug(sc, "disabling useless devices\n");
3749 hdafg_disable_useless(sc);
3750 hda_debug(sc, "disabling cross-associated pins\n");
3751 hdafg_disable_crossassoc(sc);
3752 hda_debug(sc, "disabling useless devices\n");
3753 hdafg_disable_useless(sc);
3754
3755 hda_debug(sc, "assigning mixer names to sound sources\n");
3756 hdafg_assign_names(sc);
3757 hda_debug(sc, "assigning mixers to device tree\n");
3758 hdafg_assign_mixers(sc);
3759
3760 hda_debug(sc, "preparing pin controls\n");
3761 hdafg_prepare_pin_controls(sc);
3762 hda_debug(sc, "commiting settings\n");
3763 hdafg_commit(sc);
3764
3765 hda_debug(sc, "setup jack sensing\n");
3766 hdafg_hp_switch_init(sc);
3767
3768 hda_debug(sc, "building mixer controls\n");
3769 hdafg_build_mixers(sc);
3770
3771 hdafg_dump(sc);
3772 if (1) hdafg_widget_pin_dump(sc);
3773 hdafg_assoc_dump(sc);
3774
3775 hda_debug(sc, "enabling analog beep\n");
3776 hdafg_enable_analog_beep(sc);
3777
3778 hda_debug(sc, "configuring encodings\n");
3779 sc->sc_audiodev.ad_sc = sc;
3780 hdafg_configure_encodings(sc);
3781
3782 hda_debug(sc, "reserving streams\n");
3783 sc->sc_audiodev.ad_capture = hdaudio_stream_establish(sc->sc_host,
3784 HDAUDIO_STREAM_ISS, hdafg_stream_intr, &sc->sc_audiodev);
3785 sc->sc_audiodev.ad_playback = hdaudio_stream_establish(sc->sc_host,
3786 HDAUDIO_STREAM_OSS, hdafg_stream_intr, &sc->sc_audiodev);
3787
3788 if (sc->sc_audiodev.ad_capture == NULL &&
3789 sc->sc_audiodev.ad_playback == NULL) {
3790 hda_error(sc, "couldn't find any input or output streams\n");
3791 return;
3792 }
3793
3794 hda_debug(sc, "connecting streams\n");
3795 defparams.channels = 2;
3796 defparams.sample_rate = sc->sc_fixed_rate ? sc->sc_fixed_rate : 48000;
3797 defparams.precision = defparams.validbits = 16;
3798 defparams.encoding = AUDIO_ENCODING_SLINEAR_LE;
3799 sc->sc_pparam = sc->sc_rparam = defparams;
3800 hdafg_stream_connect(sc, AUMODE_PLAY);
3801 hdafg_stream_connect(sc, AUMODE_RECORD);
3802
3803 for (i = 0; i < sc->sc_nassocs; i++) {
3804 astype |= (1 << sc->sc_assocs[i].as_digital);
3805 }
3806 hda_debug(sc, "assoc type mask: %x\n", astype);
3807
3808 #ifndef HDAUDIO_ENABLE_HDMI
3809 astype &= ~(1 << HDAFG_AS_HDMI);
3810 #endif
3811 #ifndef HDAUDIO_ENABLE_DISPLAYPORT
3812 astype &= ~(1 << HDAFG_AS_DISPLAYPORT);
3813 #endif
3814
3815 if (astype == 0)
3816 return;
3817
3818 hda_debug(sc, "attaching audio device\n");
3819 sc->sc_audiodev.ad_audiodev = audio_attach_mi(&hdafg_hw_if,
3820 &sc->sc_audiodev, self);
3821 }
3822
3823 static int
3824 hdafg_detach(device_t self, int flags)
3825 {
3826 struct hdafg_softc *sc = device_private(self);
3827 struct hdaudio_widget *wl, *w = sc->sc_widgets;
3828 struct hdaudio_assoc *as = sc->sc_assocs;
3829 struct hdaudio_control *ctl = sc->sc_ctls;
3830 struct hdaudio_mixer *mx = sc->sc_mixers;
3831 int nid;
3832
3833 callout_halt(&sc->sc_jack_callout, NULL);
3834 callout_destroy(&sc->sc_jack_callout);
3835
3836 if (sc->sc_config)
3837 prop_object_release(sc->sc_config);
3838 if (sc->sc_audiodev.ad_audiodev)
3839 config_detach(sc->sc_audiodev.ad_audiodev, flags);
3840 if (sc->sc_audiodev.ad_playback)
3841 hdaudio_stream_disestablish(sc->sc_audiodev.ad_playback);
3842 if (sc->sc_audiodev.ad_capture)
3843 hdaudio_stream_disestablish(sc->sc_audiodev.ad_capture);
3844
3845 /* restore bios pin widget configuration */
3846 for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3847 wl = hdafg_widget_lookup(sc, nid);
3848 if (wl == NULL || wl->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3849 continue;
3850 hdafg_widget_setconfig(wl, wl->w_pin.biosconfig);
3851 }
3852
3853 if (w)
3854 kmem_free(w, sc->sc_nwidgets * sizeof(*w));
3855 if (as)
3856 kmem_free(as, sc->sc_nassocs * sizeof(*as));
3857 if (ctl)
3858 kmem_free(ctl, sc->sc_nctls * sizeof(*ctl));
3859 if (mx)
3860 kmem_free(mx, sc->sc_nmixers * sizeof(*mx));
3861
3862 mutex_destroy(&sc->sc_lock);
3863 mutex_destroy(&sc->sc_intr_lock);
3864
3865 pmf_device_deregister(self);
3866
3867 return 0;
3868 }
3869
3870 static void
3871 hdafg_childdet(device_t self, device_t child)
3872 {
3873 struct hdafg_softc *sc = device_private(self);
3874
3875 if (child == sc->sc_audiodev.ad_audiodev)
3876 sc->sc_audiodev.ad_audiodev = NULL;
3877 }
3878
3879 static bool
3880 hdafg_suspend(device_t self, const pmf_qual_t *qual)
3881 {
3882 struct hdafg_softc *sc = device_private(self);
3883
3884 callout_halt(&sc->sc_jack_callout, NULL);
3885
3886 return true;
3887 }
3888
3889 static bool
3890 hdafg_resume(device_t self, const pmf_qual_t *qual)
3891 {
3892 struct hdafg_softc *sc = device_private(self);
3893 struct hdaudio_widget *w;
3894 int nid;
3895
3896 hdaudio_command(sc->sc_codec, sc->sc_nid,
3897 CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
3898 hda_delay(100);
3899 for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3900 hdaudio_command(sc->sc_codec, nid,
3901 CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
3902 w = hdafg_widget_lookup(sc, nid);
3903
3904 /* restore pin widget configuration */
3905 if (w == NULL || w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3906 continue;
3907 hdafg_widget_setconfig(w, w->w_pin.config);
3908 }
3909 hda_delay(1000);
3910
3911 hdafg_commit(sc);
3912 hdafg_stream_connect(sc, AUMODE_PLAY);
3913 hdafg_stream_connect(sc, AUMODE_RECORD);
3914
3915 if (sc->sc_jack_polling)
3916 hdafg_hp_switch_handler(sc);
3917
3918 return true;
3919 }
3920
3921 static int
3922 hdafg_query_format(void *opaque, audio_format_query_t *afp)
3923 {
3924 struct hdaudio_audiodev *ad = opaque;
3925
3926 return audio_query_format(ad->ad_formats, ad->ad_nformats, afp);
3927 }
3928
3929 static int
3930 hdafg_set_format(void *opaque, int setmode,
3931 const audio_params_t *play, const audio_params_t *rec,
3932 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
3933 {
3934 struct hdaudio_audiodev *ad = opaque;
3935
3936 if (play && (setmode & AUMODE_PLAY)) {
3937 ad->ad_sc->sc_pparam = *play;
3938 hdafg_stream_connect(ad->ad_sc, AUMODE_PLAY);
3939 }
3940 if (rec && (setmode & AUMODE_RECORD)) {
3941 ad->ad_sc->sc_rparam = *rec;
3942 hdafg_stream_connect(ad->ad_sc, AUMODE_RECORD);
3943 }
3944 return 0;
3945 }
3946
3947 /* LCM for round_blocksize */
3948 static u_int gcd(u_int, u_int);
3949 static u_int lcm(u_int, u_int);
3950
3951 static u_int gcd(u_int a, u_int b)
3952 {
3953
3954 return (b == 0) ? a : gcd(b, a % b);
3955 }
3956 static u_int lcm(u_int a, u_int b)
3957 {
3958
3959 return a * b / gcd(a, b);
3960 }
3961
3962 static int
3963 hdafg_round_blocksize(void *opaque, int blksize, int mode,
3964 const audio_params_t *param)
3965 {
3966 struct hdaudio_audiodev *ad = opaque;
3967 struct hdaudio_stream *st;
3968 u_int minblksize;
3969 int bufsize;
3970
3971 st = (mode == AUMODE_PLAY) ? ad->ad_playback : ad->ad_capture;
3972 if (st == NULL) {
3973 hda_trace(ad->ad_sc,
3974 "round_blocksize called for invalid stream\n");
3975 return 128;
3976 }
3977
3978 if (blksize > 8192)
3979 blksize = 8192;
3980
3981 /* Make sure there are enough BDL descriptors */
3982 bufsize = st->st_data.dma_size;
3983 if (bufsize > HDAUDIO_BDL_MAX * blksize) {
3984 blksize = bufsize / HDAUDIO_BDL_MAX;
3985 }
3986
3987 /*
3988 * HD audio's buffer constraint looks like following:
3989 * - The buffer MUST start on a 128bytes boundary.
3990 * - The buffer size MUST be one sample or more.
3991 * - The buffer size is preferred multiple of 128bytes for efficiency.
3992 *
3993 * https://www.intel.co.jp/content/www/jp/ja/standards/high-definition-audio-specification.html , p70.
3994 *
3995 * Also, the audio layer requires that the blocksize must be a
3996 * multiple of the number of channels.
3997 */
3998 minblksize = lcm(128, param->channels);
3999 blksize = rounddown(blksize, minblksize);
4000 if (blksize < minblksize)
4001 blksize = minblksize;
4002
4003 return blksize;
4004 }
4005
4006 static int
4007 hdafg_commit_settings(void *opaque)
4008 {
4009 return 0;
4010 }
4011
4012 static int
4013 hdafg_halt_output(void *opaque)
4014 {
4015 struct hdaudio_audiodev *ad = opaque;
4016 struct hdafg_softc *sc = ad->ad_sc;
4017 struct hdaudio_assoc *as = ad->ad_sc->sc_assocs;
4018 struct hdaudio_widget *w;
4019 uint16_t dfmt;
4020 int i, j;
4021
4022 /* Disable digital outputs */
4023 for (i = 0; i < sc->sc_nassocs; i++) {
4024 if (as[i].as_enable == false)
4025 continue;
4026 if (as[i].as_dir != HDAUDIO_PINDIR_OUT)
4027 continue;
4028 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
4029 if (as[i].as_dacs[j] == 0)
4030 continue;
4031 w = hdafg_widget_lookup(sc, as[i].as_dacs[j]);
4032 if (w == NULL || w->w_enable == false)
4033 continue;
4034 if (w->w_p.aw_cap & COP_AWCAP_DIGITAL) {
4035 dfmt = hdaudio_command(sc->sc_codec, w->w_nid,
4036 CORB_GET_DIGITAL_CONVERTER_CONTROL, 0) &
4037 0xff;
4038 dfmt &= ~COP_DIGITAL_CONVCTRL1_DIGEN;
4039 hdaudio_command(sc->sc_codec, w->w_nid,
4040 CORB_SET_DIGITAL_CONVERTER_CONTROL_1, dfmt);
4041 }
4042 }
4043 }
4044
4045 hdaudio_stream_stop(ad->ad_playback);
4046
4047 return 0;
4048 }
4049
4050 static int
4051 hdafg_halt_input(void *opaque)
4052 {
4053 struct hdaudio_audiodev *ad = opaque;
4054
4055 hdaudio_stream_stop(ad->ad_capture);
4056
4057 return 0;
4058 }
4059
4060 static int
4061 hdafg_getdev(void *opaque, struct audio_device *audiodev)
4062 {
4063 struct hdaudio_audiodev *ad = opaque;
4064 struct hdafg_softc *sc = ad->ad_sc;
4065
4066 hdaudio_findvendor(audiodev->name, sizeof(audiodev->name),
4067 sc->sc_vendor);
4068 hdaudio_findproduct(audiodev->version, sizeof(audiodev->version),
4069 sc->sc_vendor, sc->sc_product);
4070 snprintf(audiodev->config, sizeof(audiodev->config),
4071 "%02Xh", sc->sc_nid);
4072
4073 return 0;
4074 }
4075
4076 static int
4077 hdafg_set_port(void *opaque, mixer_ctrl_t *mc)
4078 {
4079 struct hdaudio_audiodev *ad = opaque;
4080 struct hdafg_softc *sc = ad->ad_sc;
4081 struct hdaudio_mixer *mx;
4082 struct hdaudio_control *ctl;
4083 int i, divisor;
4084
4085 if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
4086 return EINVAL;
4087 mx = &sc->sc_mixers[mc->dev];
4088 ctl = mx->mx_ctl;
4089 if (ctl == NULL) {
4090 if (mx->mx_di.type != AUDIO_MIXER_SET)
4091 return ENXIO;
4092 if (mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_OUTPUTS &&
4093 mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_RECORD)
4094 return ENXIO;
4095 for (i = 0; i < sc->sc_nassocs; i++) {
4096 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_OUT &&
4097 mx->mx_di.mixer_class ==
4098 HDAUDIO_MIXER_CLASS_OUTPUTS)
4099 continue;
4100 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_IN &&
4101 mx->mx_di.mixer_class ==
4102 HDAUDIO_MIXER_CLASS_RECORD)
4103 continue;
4104 sc->sc_assocs[i].as_activated =
4105 (mc->un.mask & (1 << i)) ? true : false;
4106 }
4107 hdafg_stream_connect(ad->ad_sc,
4108 mx->mx_di.mixer_class == HDAUDIO_MIXER_CLASS_OUTPUTS ?
4109 AUMODE_PLAY : AUMODE_RECORD);
4110 return 0;
4111 }
4112
4113 switch (mx->mx_di.type) {
4114 case AUDIO_MIXER_VALUE:
4115 if (ctl->ctl_step == 0)
4116 divisor = 128; /* ??? - just avoid div by 0 */
4117 else
4118 divisor = 255 / ctl->ctl_step;
4119
4120 hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_NONE,
4121 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] / divisor,
4122 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] / divisor);
4123 break;
4124 case AUDIO_MIXER_ENUM:
4125 hdafg_control_amp_set(ctl,
4126 mc->un.ord ? HDAUDIO_AMP_MUTE_ALL : HDAUDIO_AMP_MUTE_NONE,
4127 ctl->ctl_left, ctl->ctl_right);
4128 break;
4129 default:
4130 return ENXIO;
4131 }
4132
4133 return 0;
4134 }
4135
4136 static int
4137 hdafg_get_port(void *opaque, mixer_ctrl_t *mc)
4138 {
4139 struct hdaudio_audiodev *ad = opaque;
4140 struct hdafg_softc *sc = ad->ad_sc;
4141 struct hdaudio_mixer *mx;
4142 struct hdaudio_control *ctl;
4143 u_int mask = 0;
4144 int i, factor;
4145
4146 if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
4147 return EINVAL;
4148 mx = &sc->sc_mixers[mc->dev];
4149 ctl = mx->mx_ctl;
4150 if (ctl == NULL) {
4151 if (mx->mx_di.type != AUDIO_MIXER_SET)
4152 return ENXIO;
4153 if (mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_OUTPUTS &&
4154 mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_RECORD)
4155 return ENXIO;
4156 for (i = 0; i < sc->sc_nassocs; i++) {
4157 if (sc->sc_assocs[i].as_enable == false)
4158 continue;
4159 if (sc->sc_assocs[i].as_activated == false)
4160 continue;
4161 if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_OUT &&
4162 mx->mx_di.mixer_class ==
4163 HDAUDIO_MIXER_CLASS_OUTPUTS)
4164 mask |= (1 << i);
4165 if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_IN &&
4166 mx->mx_di.mixer_class ==
4167 HDAUDIO_MIXER_CLASS_RECORD)
4168 mask |= (1 << i);
4169 }
4170 mc->un.mask = mask;
4171 return 0;
4172 }
4173
4174 switch (mx->mx_di.type) {
4175 case AUDIO_MIXER_VALUE:
4176 if (ctl->ctl_step == 0)
4177 factor = 128; /* ??? - just avoid div by 0 */
4178 else
4179 factor = 255 / ctl->ctl_step;
4180
4181 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = ctl->ctl_left * factor;
4182 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = ctl->ctl_right * factor;
4183 break;
4184 case AUDIO_MIXER_ENUM:
4185 mc->un.ord = (ctl->ctl_muted || ctl->ctl_forcemute) ? 1 : 0;
4186 break;
4187 default:
4188 return ENXIO;
4189 }
4190 return 0;
4191 }
4192
4193 static int
4194 hdafg_query_devinfo(void *opaque, mixer_devinfo_t *di)
4195 {
4196 struct hdaudio_audiodev *ad = opaque;
4197 struct hdafg_softc *sc = ad->ad_sc;
4198
4199 if (di->index < 0 || di->index >= sc->sc_nmixers)
4200 return ENXIO;
4201
4202 *di = sc->sc_mixers[di->index].mx_di;
4203
4204 return 0;
4205 }
4206
4207 static void *
4208 hdafg_allocm(void *opaque, int direction, size_t size)
4209 {
4210 struct hdaudio_audiodev *ad = opaque;
4211 struct hdaudio_stream *st;
4212 int err;
4213
4214 st = (direction == AUMODE_PLAY) ? ad->ad_playback : ad->ad_capture;
4215 if (st == NULL)
4216 return NULL;
4217
4218 if (st->st_data.dma_valid == true)
4219 hda_error(ad->ad_sc, "WARNING: allocm leak\n");
4220
4221 st->st_data.dma_size = size;
4222 err = hdaudio_dma_alloc(st->st_host, &st->st_data,
4223 BUS_DMA_COHERENT | BUS_DMA_NOCACHE);
4224 if (err || st->st_data.dma_valid == false)
4225 return NULL;
4226
4227 return DMA_KERNADDR(&st->st_data);
4228 }
4229
4230 static void
4231 hdafg_freem(void *opaque, void *addr, size_t size)
4232 {
4233 struct hdaudio_audiodev *ad = opaque;
4234 struct hdaudio_stream *st;
4235
4236 if (addr == DMA_KERNADDR(&ad->ad_playback->st_data))
4237 st = ad->ad_playback;
4238 else if (addr == DMA_KERNADDR(&ad->ad_capture->st_data))
4239 st = ad->ad_capture;
4240 else
4241 return;
4242
4243 hdaudio_dma_free(st->st_host, &st->st_data);
4244 }
4245
4246 static int
4247 hdafg_get_props(void *opaque)
4248 {
4249 struct hdaudio_audiodev *ad = opaque;
4250 int props = 0;
4251
4252 if (ad->ad_playback)
4253 props |= AUDIO_PROP_PLAYBACK;
4254 if (ad->ad_capture)
4255 props |= AUDIO_PROP_CAPTURE;
4256 if (ad->ad_playback && ad->ad_capture) {
4257 props |= AUDIO_PROP_FULLDUPLEX;
4258 props |= AUDIO_PROP_INDEPENDENT;
4259 }
4260
4261 return props;
4262 }
4263
4264 static int
4265 hdafg_trigger_output(void *opaque, void *start, void *end, int blksize,
4266 void (*intr)(void *), void *intrarg, const audio_params_t *param)
4267 {
4268 struct hdaudio_audiodev *ad = opaque;
4269 bus_size_t dmasize;
4270
4271 if (ad->ad_playback == NULL)
4272 return ENXIO;
4273 if (ad->ad_playback->st_data.dma_valid == false)
4274 return ENOMEM;
4275
4276 ad->ad_playbackintr = intr;
4277 ad->ad_playbackintrarg = intrarg;
4278
4279 dmasize = (char *)end - (char *)start;
4280 hdafg_stream_connect(ad->ad_sc, AUMODE_PLAY);
4281 hdaudio_stream_start(ad->ad_playback, blksize, dmasize,
4282 &ad->ad_sc->sc_pparam);
4283
4284 return 0;
4285 }
4286
4287 static int
4288 hdafg_trigger_input(void *opaque, void *start, void *end, int blksize,
4289 void (*intr)(void *), void *intrarg, const audio_params_t *param)
4290 {
4291 struct hdaudio_audiodev *ad = opaque;
4292 bus_size_t dmasize;
4293
4294 if (ad->ad_capture == NULL)
4295 return ENXIO;
4296 if (ad->ad_capture->st_data.dma_valid == false)
4297 return ENOMEM;
4298
4299 ad->ad_captureintr = intr;
4300 ad->ad_captureintrarg = intrarg;
4301
4302 dmasize = (char *)end - (char *)start;
4303 hdafg_stream_connect(ad->ad_sc, AUMODE_RECORD);
4304 hdaudio_stream_start(ad->ad_capture, blksize, dmasize,
4305 &ad->ad_sc->sc_rparam);
4306
4307 return 0;
4308 }
4309
4310 static void
4311 hdafg_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
4312 {
4313 struct hdaudio_audiodev *ad = opaque;
4314
4315 *intr = &ad->ad_sc->sc_intr_lock;
4316 *thread = &ad->ad_sc->sc_lock;
4317 }
4318
4319 static int
4320 hdafg_unsol(device_t self, uint8_t tag)
4321 {
4322 struct hdafg_softc *sc = device_private(self);
4323 struct hdaudio_assoc *as = sc->sc_assocs;
4324 int i, j;
4325
4326 switch (tag) {
4327 case HDAUDIO_UNSOLTAG_EVENT_DD:
4328 #ifdef HDAFG_HDMI_DEBUG
4329 hda_print(sc, "unsol: display device hotplug\n");
4330 #endif
4331 for (i = 0; i < sc->sc_nassocs; i++) {
4332 if (as[i].as_displaydev == false)
4333 continue;
4334 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
4335 if (as[i].as_pins[j] == 0)
4336 continue;
4337 hdafg_assoc_dump_dd(sc, &as[i], j, 0);
4338 }
4339 }
4340 break;
4341 default:
4342 #ifdef HDAFG_HDMI_DEBUG
4343 hda_print(sc, "unsol: tag=%u\n", tag);
4344 #endif
4345 break;
4346 }
4347
4348 return 0;
4349 }
4350
4351 static int
4352 hdafg_widget_info(void *opaque, prop_dictionary_t request,
4353 prop_dictionary_t response)
4354 {
4355 struct hdafg_softc *sc = opaque;
4356 struct hdaudio_widget *w;
4357 prop_array_t connlist;
4358 uint32_t config, wcap;
4359 uint16_t index;
4360 int nid;
4361 int i;
4362
4363 if (prop_dictionary_get_uint16(request, "index", &index) == false)
4364 return EINVAL;
4365
4366 nid = sc->sc_startnode + index;
4367 if (nid >= sc->sc_endnode)
4368 return EINVAL;
4369
4370 w = hdafg_widget_lookup(sc, nid);
4371 if (w == NULL)
4372 return ENXIO;
4373 wcap = hda_get_wparam(w, PIN_CAPABILITIES);
4374 config = hdaudio_command(sc->sc_codec, w->w_nid,
4375 CORB_GET_CONFIGURATION_DEFAULT, 0);
4376 prop_dictionary_set_string_nocopy(response, "name", w->w_name);
4377 prop_dictionary_set_bool(response, "enable", w->w_enable);
4378 prop_dictionary_set_uint8(response, "nid", w->w_nid);
4379 prop_dictionary_set_uint8(response, "type", w->w_type);
4380 prop_dictionary_set_uint32(response, "config", config);
4381 prop_dictionary_set_uint32(response, "cap", wcap);
4382 if (w->w_nconns == 0)
4383 return 0;
4384 connlist = prop_array_create();
4385 for (i = 0; i < w->w_nconns; i++) {
4386 if (w->w_conns[i] == 0)
4387 continue;
4388 prop_array_add_and_rel(connlist,
4389 prop_number_create_unsigned(w->w_conns[i]));
4390 }
4391 prop_dictionary_set(response, "connlist", connlist);
4392 prop_object_release(connlist);
4393 return 0;
4394 }
4395
4396 static int
4397 hdafg_codec_info(void *opaque, prop_dictionary_t request,
4398 prop_dictionary_t response)
4399 {
4400 struct hdafg_softc *sc = opaque;
4401 prop_dictionary_set_uint16(response, "vendor-id",
4402 sc->sc_vendor);
4403 prop_dictionary_set_uint16(response, "product-id",
4404 sc->sc_product);
4405 return 0;
4406 }
4407
4408 MODULE(MODULE_CLASS_DRIVER, hdafg, "hdaudio");
4409
4410 #ifdef _MODULE
4411 #include "ioconf.c"
4412 #endif
4413
4414 static int
4415 hdafg_modcmd(modcmd_t cmd, void *opaque)
4416 {
4417 int error = 0;
4418
4419 switch (cmd) {
4420 case MODULE_CMD_INIT:
4421 #ifdef _MODULE
4422 error = config_init_component(cfdriver_ioconf_hdafg,
4423 cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
4424 #endif
4425 return error;
4426 case MODULE_CMD_FINI:
4427 #ifdef _MODULE
4428 error = config_fini_component(cfdriver_ioconf_hdafg,
4429 cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
4430 #endif
4431 return error;
4432 default:
4433 return ENOTTY;
4434 }
4435 }
4436
4437 #define HDAFG_GET_ANACTRL 0xfe0
4438 #define HDAFG_SET_ANACTRL 0x7e0
4439 #define HDAFG_ANALOG_BEEP_EN __BIT(5)
4440 #define HDAFG_ALC231_MONO_OUT_MIXER 0xf
4441 #define HDAFG_STAC9200_AFG 0x1
4442 #define HDAFG_STAC9200_GET_ANACTRL_PAYLOAD 0x0
4443 #define HDAFG_ALC231_INPUT_BOTH_CHANNELS_UNMUTE 0x7100
4444
4445 static void
4446 hdafg_enable_analog_beep(struct hdafg_softc *sc)
4447 {
4448 int nid;
4449 uint32_t response;
4450
4451 switch (sc->sc_vendor) {
4452 case HDAUDIO_VENDOR_SIGMATEL:
4453 switch (sc->sc_product) {
4454 case HDAUDIO_PRODUCT_SIGMATEL_STAC9200:
4455 case HDAUDIO_PRODUCT_SIGMATEL_STAC9200D:
4456 case HDAUDIO_PRODUCT_SIGMATEL_STAC9202:
4457 case HDAUDIO_PRODUCT_SIGMATEL_STAC9202D:
4458 case HDAUDIO_PRODUCT_SIGMATEL_STAC9204:
4459 case HDAUDIO_PRODUCT_SIGMATEL_STAC9204D:
4460 case HDAUDIO_PRODUCT_SIGMATEL_STAC9205:
4461 case HDAUDIO_PRODUCT_SIGMATEL_STAC9205_1:
4462 case HDAUDIO_PRODUCT_SIGMATEL_STAC9205D:
4463 nid = HDAFG_STAC9200_AFG;
4464
4465 response = hdaudio_command(sc->sc_codec, nid,
4466 HDAFG_GET_ANACTRL,
4467 HDAFG_STAC9200_GET_ANACTRL_PAYLOAD);
4468 hda_delay(100);
4469
4470 response |= HDAFG_ANALOG_BEEP_EN;
4471
4472 hdaudio_command(sc->sc_codec, nid, HDAFG_SET_ANACTRL,
4473 response);
4474 hda_delay(100);
4475 break;
4476 default:
4477 break;
4478 }
4479 break;
4480 case HDAUDIO_VENDOR_REALTEK:
4481 switch (sc->sc_product) {
4482 case HDAUDIO_PRODUCT_REALTEK_ALC269:
4483 /* The Panasonic Toughbook CF19 - Mk 5 uses a Realtek
4484 * ALC231 that identifies as an ALC269.
4485 * This unmutes the PCBEEP on the speaker.
4486 */
4487 nid = HDAFG_ALC231_MONO_OUT_MIXER;
4488 response = hdaudio_command(sc->sc_codec, nid,
4489 CORB_SET_AMPLIFIER_GAIN_MUTE,
4490 HDAFG_ALC231_INPUT_BOTH_CHANNELS_UNMUTE);
4491 hda_delay(100);
4492 break;
4493 default:
4494 break;
4495 }
4496 default:
4497 break;
4498 }
4499 }
4500