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