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