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