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