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