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