hdafg.c revision 1.6 1 /* $NetBSD: hdafg.c,v 1.6 2015/11/04 18:04:28 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.6 2015/11/04 18:04:28 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 bool
2356 hdafg_widget_is_input(const struct hdafg_softc *sc,
2357 const struct hdaudio_widget *w)
2358 {
2359 const struct hdaudio_assoc *as = sc->sc_assocs;
2360
2361 switch (w->w_type) {
2362 case COP_AWCAP_TYPE_AUDIO_INPUT:
2363 return true;
2364 case COP_AWCAP_TYPE_PIN_COMPLEX:
2365 if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2366 return false;
2367 switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
2368 case COP_DEVICE_MIC_IN:
2369 case COP_DEVICE_LINE_IN:
2370 case COP_DEVICE_SPDIF_IN:
2371 case COP_DEVICE_DIGITAL_OTHER_IN:
2372 return true;
2373 default:
2374 return false;
2375 }
2376 default:
2377 return false;
2378 }
2379 }
2380
2381 static void
2382 hdafg_control_commit(struct hdafg_softc *sc)
2383 {
2384 struct hdaudio_control *ctl;
2385 int i, z;
2386
2387 for (i = 0; i < sc->sc_nctls; i++) {
2388 ctl = &sc->sc_ctls[i];
2389 //if (ctl->ctl_enable == false || ctl->ctl_audiomask != 0)
2390 if (ctl->ctl_enable == false)
2391 continue;
2392 /* Init fixed controls to 0dB amplification */
2393 z = ctl->ctl_offset;
2394 if (z > ctl->ctl_step)
2395 z = ctl->ctl_step;
2396
2397 if ((ctl->ctl_dir & HDAUDIO_PINDIR_IN) &&
2398 hdafg_widget_is_input(sc, ctl->ctl_widget))
2399 hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_ALL, z, z);
2400 else
2401 hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_NONE, z, z);
2402 }
2403 }
2404
2405 static void
2406 hdafg_widget_connection_select(struct hdaudio_widget *w, uint8_t index)
2407 {
2408 struct hdafg_softc *sc = w->w_afg;
2409
2410 if (w->w_nconns < 1 || index > (w->w_nconns - 1))
2411 return;
2412
2413 hdaudio_command(sc->sc_codec, w->w_nid,
2414 CORB_SET_CONNECTION_SELECT_CONTROL, index);
2415 w->w_selconn = index;
2416 }
2417
2418 static void
2419 hdafg_assign_names(struct hdafg_softc *sc)
2420 {
2421 struct hdaudio_assoc *as = sc->sc_assocs;
2422 struct hdaudio_widget *w;
2423 int i, j;
2424 int type = -1, use, used =0;
2425 static const int types[7][13] = {
2426 { HDAUDIO_MIXER_LINE, HDAUDIO_MIXER_LINE1, HDAUDIO_MIXER_LINE2,
2427 HDAUDIO_MIXER_LINE3, -1 },
2428 { HDAUDIO_MIXER_MONITOR, HDAUDIO_MIXER_MIC, -1 }, /* int mic */
2429 { HDAUDIO_MIXER_MIC, HDAUDIO_MIXER_MONITOR, -1 }, /* ext mic */
2430 { HDAUDIO_MIXER_CD, -1 },
2431 { HDAUDIO_MIXER_SPEAKER, -1 },
2432 { HDAUDIO_MIXER_DIGITAL1, HDAUDIO_MIXER_DIGITAL2,
2433 HDAUDIO_MIXER_DIGITAL3, -1 },
2434 { HDAUDIO_MIXER_LINE, HDAUDIO_MIXER_LINE1, HDAUDIO_MIXER_LINE2,
2435 HDAUDIO_MIXER_LINE3, HDAUDIO_MIXER_PHONEIN,
2436 HDAUDIO_MIXER_PHONEOUT, HDAUDIO_MIXER_VIDEO, HDAUDIO_MIXER_RADIO,
2437 HDAUDIO_MIXER_DIGITAL1, HDAUDIO_MIXER_DIGITAL2,
2438 HDAUDIO_MIXER_DIGITAL3, HDAUDIO_MIXER_MONITOR, -1 } /* others */
2439 };
2440
2441 /* Surely known names */
2442 for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2443 w = hdafg_widget_lookup(sc, i);
2444 if (w == NULL || w->w_enable == false)
2445 continue;
2446 if (w->w_bindas == -1)
2447 continue;
2448 use = -1;
2449 switch (w->w_type) {
2450 case COP_AWCAP_TYPE_PIN_COMPLEX:
2451 if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2452 break;
2453 type = -1;
2454 switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
2455 case COP_DEVICE_LINE_IN:
2456 type = 0;
2457 break;
2458 case COP_DEVICE_MIC_IN:
2459 if (COP_CFG_PORT_CONNECTIVITY(w->w_pin.config)
2460 == COP_PORT_JACK)
2461 break;
2462 type = 1;
2463 break;
2464 case COP_DEVICE_CD:
2465 type = 3;
2466 break;
2467 case COP_DEVICE_SPEAKER:
2468 type = 4;
2469 break;
2470 case COP_DEVICE_SPDIF_IN:
2471 case COP_DEVICE_DIGITAL_OTHER_IN:
2472 type = 5;
2473 break;
2474 }
2475 if (type == -1)
2476 break;
2477 j = 0;
2478 while (types[type][j] >= 0 &&
2479 (used & (1 << types[type][j])) != 0) {
2480 j++;
2481 }
2482 if (types[type][j] >= 0)
2483 use = types[type][j];
2484 break;
2485 case COP_AWCAP_TYPE_AUDIO_OUTPUT:
2486 use = HDAUDIO_MIXER_PCM;
2487 break;
2488 case COP_AWCAP_TYPE_BEEP_GENERATOR:
2489 use = HDAUDIO_MIXER_SPEAKER;
2490 break;
2491 default:
2492 break;
2493 }
2494 if (use >= 0) {
2495 w->w_audiodev = use;
2496 used |= (1 << use);
2497 }
2498 }
2499 /* Semi-known names */
2500 for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2501 w = hdafg_widget_lookup(sc, i);
2502 if (w == NULL || w->w_enable == false)
2503 continue;
2504 if (w->w_audiodev >= 0)
2505 continue;
2506 if (w->w_bindas == -1)
2507 continue;
2508 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
2509 continue;
2510 if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2511 continue;
2512 type = -1;
2513 switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
2514 case COP_DEVICE_LINE_OUT:
2515 case COP_DEVICE_SPEAKER:
2516 case COP_DEVICE_HP_OUT:
2517 case COP_DEVICE_AUX:
2518 type = 0;
2519 break;
2520 case COP_DEVICE_MIC_IN:
2521 type = 2;
2522 break;
2523 case COP_DEVICE_SPDIF_OUT:
2524 case COP_DEVICE_DIGITAL_OTHER_OUT:
2525 type = 5;
2526 break;
2527 }
2528 if (type == -1)
2529 break;
2530 j = 0;
2531 while (types[type][j] >= 0 &&
2532 (used & (1 << types[type][j])) != 0) {
2533 j++;
2534 }
2535 if (types[type][j] >= 0) {
2536 w->w_audiodev = types[type][j];
2537 used |= (1 << types[type][j]);
2538 }
2539 }
2540 /* Others */
2541 for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2542 w = hdafg_widget_lookup(sc, i);
2543 if (w == NULL || w->w_enable == false)
2544 continue;
2545 if (w->w_audiodev >= 0)
2546 continue;
2547 if (w->w_bindas == -1)
2548 continue;
2549 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
2550 continue;
2551 if (as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT)
2552 continue;
2553 j = 0;
2554 while (types[6][j] >= 0 &&
2555 (used & (1 << types[6][j])) != 0) {
2556 j++;
2557 }
2558 if (types[6][j] >= 0) {
2559 w->w_audiodev = types[6][j];
2560 used |= (1 << types[6][j]);
2561 }
2562 }
2563 }
2564
2565 static int
2566 hdafg_control_source_amp(struct hdafg_softc *sc, int nid, int index,
2567 int audiodev, int ctlable, int depth, int need)
2568 {
2569 struct hdaudio_widget *w, *wc;
2570 struct hdaudio_control *ctl;
2571 int i, j, conns = 0, rneed;
2572
2573 if (depth >= HDAUDIO_PARSE_MAXDEPTH)
2574 return need;
2575
2576 w = hdafg_widget_lookup(sc, nid);
2577 if (w == NULL || w->w_enable == false)
2578 return need;
2579
2580 /* Count number of active inputs */
2581 if (depth > 0) {
2582 for (j = 0; j < w->w_nconns; j++) {
2583 if (w->w_connsenable[j])
2584 ++conns;
2585 }
2586 }
2587
2588 /*
2589 * If this is not a first step, use input mixer. Pins have common
2590 * input ctl so care must be taken
2591 */
2592 if (depth > 0 && ctlable && (conns == 1 ||
2593 w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)) {
2594 ctl = hdafg_control_amp_get(sc, w->w_nid,
2595 HDAUDIO_PINDIR_IN, index, 1);
2596 if (ctl) {
2597 if (HDAUDIO_CONTROL_GIVE(ctl) & need)
2598 ctl->ctl_audiomask |= (1 << audiodev);
2599 else
2600 ctl->ctl_paudiomask |= (1 << audiodev);
2601 need &= ~HDAUDIO_CONTROL_GIVE(ctl);
2602 }
2603 }
2604
2605 /* If widget has own audiodev, don't traverse it. */
2606 if (w->w_audiodev >= 0 && depth > 0)
2607 return need;
2608
2609 /* We must not traverse pins */
2610 if ((w->w_type == COP_AWCAP_TYPE_AUDIO_INPUT ||
2611 w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX) && depth > 0)
2612 return need;
2613
2614 /* Record that this widget exports such signal */
2615 w->w_audiomask |= (1 << audiodev);
2616
2617 /*
2618 * If signals mixed, we can't assign controls further. Ignore this
2619 * on depth zero. Caller must know why. Ignore this for static
2620 * selectors if this input is selected.
2621 */
2622 if (conns > 1)
2623 ctlable = 0;
2624
2625 if (ctlable) {
2626 ctl = hdafg_control_amp_get(sc, w->w_nid,
2627 HDAUDIO_PINDIR_OUT, -1, 1);
2628 if (ctl) {
2629 if (HDAUDIO_CONTROL_GIVE(ctl) & need)
2630 ctl->ctl_audiomask |= (1 << audiodev);
2631 else
2632 ctl->ctl_paudiomask |= (1 << audiodev);
2633 need &= ~HDAUDIO_CONTROL_GIVE(ctl);
2634 }
2635 }
2636
2637 rneed = 0;
2638 for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2639 wc = hdafg_widget_lookup(sc, i);
2640 if (wc == NULL || wc->w_enable == false)
2641 continue;
2642 for (j = 0; j < wc->w_nconns; j++) {
2643 if (wc->w_connsenable[j] && wc->w_conns[j] == nid) {
2644 rneed |= hdafg_control_source_amp(sc,
2645 wc->w_nid, j, audiodev, ctlable, depth + 1,
2646 need);
2647 }
2648 }
2649 }
2650 rneed &= need;
2651
2652 return rneed;
2653 }
2654
2655 static void
2656 hdafg_control_dest_amp(struct hdafg_softc *sc, int nid,
2657 int audiodev, int depth, int need)
2658 {
2659 struct hdaudio_assoc *as = sc->sc_assocs;
2660 struct hdaudio_widget *w, *wc;
2661 struct hdaudio_control *ctl;
2662 int i, j, consumers;
2663
2664 if (depth > HDAUDIO_PARSE_MAXDEPTH)
2665 return;
2666
2667 w = hdafg_widget_lookup(sc, nid);
2668 if (w == NULL || w->w_enable == false)
2669 return;
2670
2671 if (depth > 0) {
2672 /*
2673 * If this node produces output for several consumers,
2674 * we can't touch it
2675 */
2676 consumers = 0;
2677 for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2678 wc = hdafg_widget_lookup(sc, i);
2679 if (wc == NULL || wc->w_enable == false)
2680 continue;
2681 for (j = 0; j < wc->w_nconns; j++) {
2682 if (wc->w_connsenable[j] &&
2683 wc->w_conns[j] == nid)
2684 ++consumers;
2685 }
2686 }
2687 /*
2688 * The only exception is if real HP redirection is configured
2689 * and this is a duplication point.
2690 * XXX: Not completely correct.
2691 */
2692 if ((consumers == 2 && (w->w_bindas < 0 ||
2693 as[w->w_bindas].as_hpredir < 0 ||
2694 as[w->w_bindas].as_fakeredir ||
2695 (w->w_bindseqmask & (1 << 15)) == 0)) ||
2696 consumers > 2)
2697 return;
2698
2699 /* Else use its output mixer */
2700 ctl = hdafg_control_amp_get(sc, w->w_nid,
2701 HDAUDIO_PINDIR_OUT, -1, 1);
2702 if (ctl) {
2703 if (HDAUDIO_CONTROL_GIVE(ctl) & need)
2704 ctl->ctl_audiomask |= (1 << audiodev);
2705 else
2706 ctl->ctl_paudiomask |= (1 << audiodev);
2707 need &= ~HDAUDIO_CONTROL_GIVE(ctl);
2708 }
2709 }
2710
2711 /* We must not traverse pin */
2712 if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX && depth > 0)
2713 return;
2714
2715 for (i = 0; i < w->w_nconns; i++) {
2716 int tneed = need;
2717 if (w->w_connsenable[i] == false)
2718 continue;
2719 ctl = hdafg_control_amp_get(sc, w->w_nid,
2720 HDAUDIO_PINDIR_IN, i, 1);
2721 if (ctl) {
2722 if (HDAUDIO_CONTROL_GIVE(ctl) & tneed)
2723 ctl->ctl_audiomask |= (1 << audiodev);
2724 else
2725 ctl->ctl_paudiomask |= (1 << audiodev);
2726 tneed &= ~HDAUDIO_CONTROL_GIVE(ctl);
2727 }
2728 hdafg_control_dest_amp(sc, w->w_conns[i], audiodev,
2729 depth + 1, tneed);
2730 }
2731 }
2732
2733 static void
2734 hdafg_assign_mixers(struct hdafg_softc *sc)
2735 {
2736 struct hdaudio_assoc *as = sc->sc_assocs;
2737 struct hdaudio_control *ctl;
2738 struct hdaudio_widget *w;
2739 int i;
2740
2741 /* Assign mixers to the tree */
2742 for (i = sc->sc_startnode; i < sc->sc_endnode; i++) {
2743 w = hdafg_widget_lookup(sc, i);
2744 if (w == NULL || w->w_enable == FALSE)
2745 continue;
2746 if (w->w_type == COP_AWCAP_TYPE_AUDIO_OUTPUT ||
2747 w->w_type == COP_AWCAP_TYPE_BEEP_GENERATOR ||
2748 (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX &&
2749 as[w->w_bindas].as_dir == HDAUDIO_PINDIR_IN)) {
2750 if (w->w_audiodev < 0)
2751 continue;
2752 hdafg_control_source_amp(sc, w->w_nid, -1,
2753 w->w_audiodev, 1, 0, 1);
2754 } else if (w->w_pflags & HDAUDIO_ADC_MONITOR) {
2755 if (w->w_audiodev < 0)
2756 continue;
2757 if (hdafg_control_source_amp(sc, w->w_nid, -1,
2758 w->w_audiodev, 1, 0, 1)) {
2759 /* If we are unable to control input monitor
2760 as source, try to control it as dest */
2761 hdafg_control_dest_amp(sc, w->w_nid,
2762 w->w_audiodev, 0, 1);
2763 }
2764 } else if (w->w_type == COP_AWCAP_TYPE_AUDIO_INPUT) {
2765 hdafg_control_dest_amp(sc, w->w_nid,
2766 HDAUDIO_MIXER_RECLEV, 0, 1);
2767 } else if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX &&
2768 as[w->w_bindas].as_dir == HDAUDIO_PINDIR_OUT) {
2769 hdafg_control_dest_amp(sc, w->w_nid,
2770 HDAUDIO_MIXER_VOLUME, 0, 1);
2771 }
2772 }
2773 /* Treat unrequired as possible */
2774 i = 0;
2775 for (i = 0; i < sc->sc_nctls; i++) {
2776 ctl = &sc->sc_ctls[i];
2777 if (ctl->ctl_audiomask == 0)
2778 ctl->ctl_audiomask = ctl->ctl_paudiomask;
2779 }
2780 }
2781
2782 static void
2783 hdafg_build_mixers(struct hdafg_softc *sc)
2784 {
2785 struct hdaudio_mixer *mx;
2786 struct hdaudio_control *ctl, *masterctl = NULL;
2787 uint32_t audiomask = 0;
2788 int nmixers = 0;
2789 int i, j, index = 0;
2790 int ndac, nadc;
2791 int ctrlcnt[HDAUDIO_MIXER_NRDEVICES];
2792
2793 memset(ctrlcnt, 0, sizeof(ctrlcnt));
2794
2795 /* Count the number of required mixers */
2796 for (i = 0; i < sc->sc_nctls; i++) {
2797 ctl = &sc->sc_ctls[i];
2798 if (ctl->ctl_enable == false ||
2799 ctl->ctl_audiomask == 0)
2800 continue;
2801 audiomask |= ctl->ctl_audiomask;
2802 ++nmixers;
2803 if (ctl->ctl_mute)
2804 ++nmixers;
2805 }
2806
2807 /* XXXJDM TODO: softvol */
2808 /* Declare master volume if needed */
2809 if ((audiomask & (HDAUDIO_MASK(VOLUME) | HDAUDIO_MASK(PCM))) ==
2810 HDAUDIO_MASK(PCM)) {
2811 audiomask |= HDAUDIO_MASK(VOLUME);
2812 for (i = 0; i < sc->sc_nctls; i++) {
2813 if (sc->sc_ctls[i].ctl_audiomask == HDAUDIO_MASK(PCM)) {
2814 masterctl = &sc->sc_ctls[i];
2815 ++nmixers;
2816 if (masterctl->ctl_mute)
2817 ++nmixers;
2818 break;
2819 }
2820 }
2821 }
2822
2823 /* Make room for mixer classes */
2824 nmixers += (HDAUDIO_MIXER_CLASS_LAST + 1);
2825
2826 /* count DACs and ADCs for selectors */
2827 ndac = nadc = 0;
2828 for (i = 0; i < sc->sc_nassocs; i++) {
2829 if (sc->sc_assocs[i].as_enable == false)
2830 continue;
2831 if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_OUT)
2832 ++ndac;
2833 else if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_IN)
2834 ++nadc;
2835 }
2836
2837 /* Make room for selectors */
2838 if (ndac > 0)
2839 ++nmixers;
2840 if (nadc > 0)
2841 ++nmixers;
2842
2843 hda_trace(sc, " need %d mixers (3 classes%s)\n",
2844 nmixers, masterctl ? " + fake master" : "");
2845
2846 /* Allocate memory for the mixers */
2847 mx = kmem_zalloc(nmixers * sizeof(*mx), KM_SLEEP);
2848 sc->sc_nmixers = nmixers;
2849
2850 /* Build class mixers */
2851 for (i = 0; i <= HDAUDIO_MIXER_CLASS_LAST; i++) {
2852 mx[index].mx_ctl = NULL;
2853 mx[index].mx_di.index = index;
2854 mx[index].mx_di.type = AUDIO_MIXER_CLASS;
2855 mx[index].mx_di.mixer_class = i;
2856 mx[index].mx_di.next = mx[index].mx_di.prev = AUDIO_MIXER_LAST;
2857 switch (i) {
2858 case HDAUDIO_MIXER_CLASS_OUTPUTS:
2859 strcpy(mx[index].mx_di.label.name, AudioCoutputs);
2860 break;
2861 case HDAUDIO_MIXER_CLASS_INPUTS:
2862 strcpy(mx[index].mx_di.label.name, AudioCinputs);
2863 break;
2864 case HDAUDIO_MIXER_CLASS_RECORD:
2865 strcpy(mx[index].mx_di.label.name, AudioCrecord);
2866 break;
2867 }
2868 ++index;
2869 }
2870
2871 /* Shadow master control */
2872 if (masterctl != NULL) {
2873 mx[index].mx_ctl = masterctl;
2874 mx[index].mx_di.index = index;
2875 mx[index].mx_di.type = AUDIO_MIXER_VALUE;
2876 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2877 mx[index].mx_di.un.v.num_channels = 2; /* XXX */
2878 mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_OUTPUTS;
2879 mx[index].mx_di.un.v.delta = 256 / (masterctl->ctl_step + 1);
2880 strcpy(mx[index].mx_di.label.name, AudioNmaster);
2881 strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
2882 hda_trace(sc, " adding outputs.%s\n",
2883 mx[index].mx_di.label.name);
2884 ++index;
2885 if (masterctl->ctl_mute) {
2886 mx[index] = mx[index - 1];
2887 mx[index].mx_di.index = index;
2888 mx[index].mx_di.type = AUDIO_MIXER_ENUM;
2889 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2890 strcpy(mx[index].mx_di.label.name, AudioNmaster "." AudioNmute);
2891 mx[index].mx_di.un.e.num_mem = 2;
2892 strcpy(mx[index].mx_di.un.e.member[0].label.name, AudioNoff);
2893 mx[index].mx_di.un.e.member[0].ord = 0;
2894 strcpy(mx[index].mx_di.un.e.member[1].label.name, AudioNon);
2895 mx[index].mx_di.un.e.member[1].ord = 1;
2896 ++index;
2897 }
2898 }
2899
2900 /* Build volume mixers */
2901 for (i = 0; i < sc->sc_nctls; i++) {
2902 uint32_t audiodev;
2903
2904 ctl = &sc->sc_ctls[i];
2905 if (ctl->ctl_enable == false ||
2906 ctl->ctl_audiomask == 0)
2907 continue;
2908 audiodev = ffs(ctl->ctl_audiomask) - 1;
2909 mx[index].mx_ctl = ctl;
2910 mx[index].mx_di.index = index;
2911 mx[index].mx_di.type = AUDIO_MIXER_VALUE;
2912 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2913 mx[index].mx_di.un.v.num_channels = 2; /* XXX */
2914 mx[index].mx_di.un.v.delta = 256 / (ctl->ctl_step + 1);
2915 if (ctrlcnt[audiodev] > 0)
2916 snprintf(mx[index].mx_di.label.name,
2917 sizeof(mx[index].mx_di.label.name),
2918 "%s%d",
2919 hdafg_mixer_names[audiodev],
2920 ctrlcnt[audiodev] + 1);
2921 else
2922 strcpy(mx[index].mx_di.label.name,
2923 hdafg_mixer_names[audiodev]);
2924 ctrlcnt[audiodev]++;
2925
2926 switch (audiodev) {
2927 case HDAUDIO_MIXER_VOLUME:
2928 case HDAUDIO_MIXER_BASS:
2929 case HDAUDIO_MIXER_TREBLE:
2930 case HDAUDIO_MIXER_OGAIN:
2931 mx[index].mx_di.mixer_class =
2932 HDAUDIO_MIXER_CLASS_OUTPUTS;
2933 hda_trace(sc, " adding outputs.%s\n",
2934 mx[index].mx_di.label.name);
2935 break;
2936 case HDAUDIO_MIXER_MIC:
2937 case HDAUDIO_MIXER_MONITOR:
2938 mx[index].mx_di.mixer_class =
2939 HDAUDIO_MIXER_CLASS_RECORD;
2940 hda_trace(sc, " adding record.%s\n",
2941 mx[index].mx_di.label.name);
2942 break;
2943 default:
2944 mx[index].mx_di.mixer_class =
2945 HDAUDIO_MIXER_CLASS_INPUTS;
2946 hda_trace(sc, " adding inputs.%s\n",
2947 mx[index].mx_di.label.name);
2948 break;
2949 }
2950 strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
2951
2952 ++index;
2953
2954 if (ctl->ctl_mute) {
2955 mx[index] = mx[index - 1];
2956 mx[index].mx_di.index = index;
2957 mx[index].mx_di.type = AUDIO_MIXER_ENUM;
2958 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2959 snprintf(mx[index].mx_di.label.name,
2960 sizeof(mx[index].mx_di.label.name),
2961 "%s." AudioNmute,
2962 mx[index - 1].mx_di.label.name);
2963 mx[index].mx_di.un.e.num_mem = 2;
2964 strcpy(mx[index].mx_di.un.e.member[0].label.name, AudioNoff);
2965 mx[index].mx_di.un.e.member[0].ord = 0;
2966 strcpy(mx[index].mx_di.un.e.member[1].label.name, AudioNon);
2967 mx[index].mx_di.un.e.member[1].ord = 1;
2968 ++index;
2969 }
2970 }
2971
2972 /* DAC selector */
2973 if (ndac > 0) {
2974 mx[index].mx_ctl = NULL;
2975 mx[index].mx_di.index = index;
2976 mx[index].mx_di.type = AUDIO_MIXER_SET;
2977 mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_OUTPUTS;
2978 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
2979 strcpy(mx[index].mx_di.label.name, "dacsel"); /* AudioNselect */
2980 mx[index].mx_di.un.s.num_mem = ndac;
2981 for (i = 0, j = 0; i < sc->sc_nassocs; i++) {
2982 if (sc->sc_assocs[i].as_enable == false)
2983 continue;
2984 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_OUT)
2985 continue;
2986 mx[index].mx_di.un.s.member[j].mask = 1 << i;
2987 snprintf(mx[index].mx_di.un.s.member[j].label.name,
2988 sizeof(mx[index].mx_di.un.s.member[j].label.name),
2989 "%s%02X",
2990 hdafg_assoc_type_string(&sc->sc_assocs[i]), i);
2991 ++j;
2992 }
2993 ++index;
2994 }
2995
2996 /* ADC selector */
2997 if (nadc > 0) {
2998 mx[index].mx_ctl = NULL;
2999 mx[index].mx_di.index = index;
3000 mx[index].mx_di.type = AUDIO_MIXER_SET;
3001 mx[index].mx_di.mixer_class = HDAUDIO_MIXER_CLASS_RECORD;
3002 mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
3003 strcpy(mx[index].mx_di.label.name, AudioNsource);
3004 mx[index].mx_di.un.s.num_mem = nadc;
3005 for (i = 0, j = 0; i < sc->sc_nassocs; i++) {
3006 if (sc->sc_assocs[i].as_enable == false)
3007 continue;
3008 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_IN)
3009 continue;
3010 mx[index].mx_di.un.s.member[j].mask = 1 << i;
3011 snprintf(mx[index].mx_di.un.s.member[j].label.name,
3012 sizeof(mx[index].mx_di.un.s.member[j].label.name),
3013 "%s%02X",
3014 hdafg_assoc_type_string(&sc->sc_assocs[i]), i);
3015 ++j;
3016 }
3017 ++index;
3018 }
3019
3020 sc->sc_mixers = mx;
3021 }
3022
3023 static void
3024 hdafg_commit(struct hdafg_softc *sc)
3025 {
3026 struct hdaudio_widget *w;
3027 uint32_t gdata, gmask, gdir;
3028 int commitgpio;
3029 int i;
3030
3031 /* Commit controls */
3032 hdafg_control_commit(sc);
3033
3034 /* Commit selectors, pins, and EAPD */
3035 for (i = 0; i < sc->sc_nwidgets; i++) {
3036 w = &sc->sc_widgets[i];
3037 if (w->w_selconn == -1)
3038 w->w_selconn = 0;
3039 if (w->w_nconns > 0)
3040 hdafg_widget_connection_select(w, w->w_selconn);
3041 if (w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
3042 hdaudio_command(sc->sc_codec, w->w_nid,
3043 CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3044 if (w->w_p.eapdbtl != 0xffffffff)
3045 hdaudio_command(sc->sc_codec, w->w_nid,
3046 CORB_SET_EAPD_BTL_ENABLE, w->w_p.eapdbtl);
3047 }
3048
3049 gdata = gmask = gdir = commitgpio = 0;
3050 #ifdef notyet
3051 int numgpio = COP_GPIO_COUNT_NUM_GPIO(sc->sc_p.gpio_cnt);
3052
3053 hda_trace(sc, "found %d GPIOs\n", numgpio);
3054 for (i = 0; i < numgpio && i < 8; i++) {
3055 if (commitgpio == 0)
3056 commitgpio = 1;
3057 gdata |= 1 << i;
3058 gmask |= 1 << i;
3059 gdir |= 1 << i;
3060 }
3061 #endif
3062
3063 if (commitgpio) {
3064 hda_trace(sc, "GPIO commit: data=%08X mask=%08X dir=%08X\n",
3065 gdata, gmask, gdir);
3066 hdaudio_command(sc->sc_codec, sc->sc_nid,
3067 CORB_SET_GPIO_ENABLE_MASK, gmask);
3068 hdaudio_command(sc->sc_codec, sc->sc_nid,
3069 CORB_SET_GPIO_DIRECTION, gdir);
3070 hdaudio_command(sc->sc_codec, sc->sc_nid,
3071 CORB_SET_GPIO_DATA, gdata);
3072 }
3073 }
3074
3075 static void
3076 hdafg_stream_connect_hdmi(struct hdafg_softc *sc, struct hdaudio_assoc *as,
3077 struct hdaudio_widget *w, const audio_params_t *params)
3078 {
3079 struct hdmi_audio_infoframe hdmi;
3080 /* TODO struct displayport_audio_infoframe dp; */
3081 uint8_t *dip = NULL;
3082 size_t diplen = 0;
3083 int i;
3084
3085 #ifdef HDAFG_HDMI_DEBUG
3086 uint32_t res;
3087 res = hdaudio_command(sc->sc_codec, w->w_nid,
3088 CORB_GET_HDMI_DIP_XMIT_CTRL, 0);
3089 hda_print(sc, "connect HDMI nid %02X, xmitctrl = 0x%08X\n",
3090 w->w_nid, res);
3091 #endif
3092
3093 /* disable infoframe transmission */
3094 hdaudio_command(sc->sc_codec, w->w_nid,
3095 CORB_SET_HDMI_DIP_XMIT_CTRL, COP_DIP_XMIT_CTRL_DISABLE);
3096
3097 /* build new infoframe */
3098 if (as->as_digital == HDAFG_AS_HDMI) {
3099 dip = (uint8_t *)&hdmi;
3100 diplen = sizeof(hdmi);
3101 memset(&hdmi, 0, sizeof(hdmi));
3102 hdmi.header.packet_type = HDMI_AI_PACKET_TYPE;
3103 hdmi.header.version = HDMI_AI_VERSION;
3104 hdmi.header.length = HDMI_AI_LENGTH;
3105 hdmi.ct_cc = params->channels - 1;
3106 if (params->channels > 2) {
3107 hdmi.ca = 0x1f;
3108 } else {
3109 hdmi.ca = 0x00;
3110 }
3111 hdafg_dd_hdmi_ai_cksum(&hdmi);
3112 }
3113 /* update data island with new audio infoframe */
3114 if (dip) {
3115 hdaudio_command(sc->sc_codec, w->w_nid,
3116 CORB_SET_HDMI_DIP_INDEX, 0);
3117 for (i = 0; i < diplen; i++) {
3118 hdaudio_command(sc->sc_codec, w->w_nid,
3119 CORB_SET_HDMI_DIP_DATA, dip[i]);
3120 }
3121 }
3122
3123 /* enable infoframe transmission */
3124 hdaudio_command(sc->sc_codec, w->w_nid,
3125 CORB_SET_HDMI_DIP_XMIT_CTRL, COP_DIP_XMIT_CTRL_BEST_EFFORT);
3126 }
3127
3128 static void
3129 hdafg_stream_connect(struct hdafg_softc *sc, int mode)
3130 {
3131 struct hdaudio_assoc *as = sc->sc_assocs;
3132 struct hdaudio_widget *w;
3133 const audio_params_t *params;
3134 uint16_t fmt, dfmt;
3135 int tag, chn, maxchan, c;
3136 int i, j, k;
3137
3138 KASSERT(mode == AUMODE_PLAY || mode == AUMODE_RECORD);
3139
3140 if (mode == AUMODE_PLAY) {
3141 fmt = hdaudio_stream_param(sc->sc_audiodev.ad_playback,
3142 &sc->sc_pparam);
3143 params = &sc->sc_pparam;
3144 } else {
3145 fmt = hdaudio_stream_param(sc->sc_audiodev.ad_capture,
3146 &sc->sc_rparam);
3147 params = &sc->sc_rparam;
3148 }
3149
3150 for (i = 0; i < sc->sc_nassocs; i++) {
3151 if (as[i].as_enable == false)
3152 continue;
3153
3154 if (mode == AUMODE_PLAY && as[i].as_dir != HDAUDIO_PINDIR_OUT)
3155 continue;
3156 if (mode == AUMODE_RECORD && as[i].as_dir != HDAUDIO_PINDIR_IN)
3157 continue;
3158
3159 fmt &= ~HDAUDIO_FMT_CHAN_MASK;
3160 if (as[i].as_dir == HDAUDIO_PINDIR_OUT &&
3161 sc->sc_audiodev.ad_playback != NULL) {
3162 tag = hdaudio_stream_tag(sc->sc_audiodev.ad_playback);
3163 fmt |= HDAUDIO_FMT_CHAN(sc->sc_pparam.channels);
3164 maxchan = sc->sc_pparam.channels;
3165 } else if (as[i].as_dir == HDAUDIO_PINDIR_IN &&
3166 sc->sc_audiodev.ad_capture != NULL) {
3167 tag = hdaudio_stream_tag(sc->sc_audiodev.ad_capture);
3168 fmt |= HDAUDIO_FMT_CHAN(sc->sc_rparam.channels);
3169 maxchan = sc->sc_rparam.channels;
3170 } else {
3171 tag = 0;
3172 if (as[i].as_dir == HDAUDIO_PINDIR_OUT) {
3173 fmt |= HDAUDIO_FMT_CHAN(sc->sc_pchan);
3174 maxchan = sc->sc_pchan;
3175 } else {
3176 fmt |= HDAUDIO_FMT_CHAN(sc->sc_rchan);
3177 maxchan = sc->sc_rchan;
3178 }
3179 }
3180
3181 chn = 0;
3182 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3183 if (as[i].as_dacs[j] == 0)
3184 continue;
3185 w = hdafg_widget_lookup(sc, as[i].as_dacs[j]);
3186 if (w == NULL || w->w_enable == FALSE)
3187 continue;
3188 if (as[i].as_hpredir >= 0 && i == as[i].as_pincnt)
3189 chn = 0;
3190 if (chn >= maxchan)
3191 chn = 0; /* XXX */
3192 c = (tag << 4) | chn;
3193
3194 if (as[i].as_activated == false)
3195 c = 0;
3196
3197 /*
3198 * If a non-PCM stream is being connected, and the
3199 * analog converter doesn't support non-PCM streams,
3200 * then don't decode it
3201 */
3202 if (!(w->w_p.aw_cap & COP_AWCAP_DIGITAL) &&
3203 !(w->w_p.stream_format & COP_STREAM_FORMAT_AC3) &&
3204 (fmt & HDAUDIO_FMT_TYPE_NONPCM)) {
3205 hdaudio_command(sc->sc_codec, w->w_nid,
3206 CORB_SET_CONVERTER_STREAM_CHANNEL, 0);
3207 continue;
3208 }
3209
3210 hdaudio_command(sc->sc_codec, w->w_nid,
3211 CORB_SET_CONVERTER_FORMAT, fmt);
3212 if (w->w_p.aw_cap & COP_AWCAP_DIGITAL) {
3213 dfmt = hdaudio_command(sc->sc_codec, w->w_nid,
3214 CORB_GET_DIGITAL_CONVERTER_CONTROL, 0) &
3215 0xff;
3216 dfmt |= COP_DIGITAL_CONVCTRL1_DIGEN;
3217 if (fmt & HDAUDIO_FMT_TYPE_NONPCM)
3218 dfmt |= COP_DIGITAL_CONVCTRL1_NAUDIO;
3219 else
3220 dfmt &= ~COP_DIGITAL_CONVCTRL1_NAUDIO;
3221 if (sc->sc_vendor == HDAUDIO_VENDOR_NVIDIA)
3222 dfmt |= COP_DIGITAL_CONVCTRL1_COPY;
3223 hdaudio_command(sc->sc_codec, w->w_nid,
3224 CORB_SET_DIGITAL_CONVERTER_CONTROL_1, dfmt);
3225 }
3226 if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP)) {
3227 hdaudio_command(sc->sc_codec, w->w_nid,
3228 CORB_SET_CONVERTER_CHANNEL_COUNT,
3229 maxchan - 1);
3230 for (k = 0; k < maxchan; k++) {
3231 hdaudio_command(sc->sc_codec, w->w_nid,
3232 CORB_ASP_SET_CHANNEL_MAPPING,
3233 (k << 4) | k);
3234 }
3235 }
3236 hdaudio_command(sc->sc_codec, w->w_nid,
3237 CORB_SET_CONVERTER_STREAM_CHANNEL, c);
3238 chn += COP_AWCAP_CHANNEL_COUNT(w->w_p.aw_cap);
3239 }
3240
3241 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3242 if (as[i].as_pins[j] == 0)
3243 continue;
3244 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3245 if (w == NULL || w->w_enable == FALSE)
3246 continue;
3247 if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
3248 hdafg_stream_connect_hdmi(sc, &as[i],
3249 w, params);
3250 }
3251 }
3252 }
3253
3254 static int
3255 hdafg_stream_intr(struct hdaudio_stream *st)
3256 {
3257 struct hdaudio_audiodev *ad = st->st_cookie;
3258 int handled = 0;
3259
3260 (void)hda_read1(ad->ad_sc->sc_host, HDAUDIO_SD_STS(st->st_shift));
3261 hda_write1(ad->ad_sc->sc_host, HDAUDIO_SD_STS(st->st_shift),
3262 HDAUDIO_STS_DESE | HDAUDIO_STS_FIFOE | HDAUDIO_STS_BCIS);
3263
3264 mutex_spin_enter(&ad->ad_sc->sc_intr_lock);
3265 /* XXX test (sts & HDAUDIO_STS_BCIS)? */
3266 if (st == ad->ad_playback && ad->ad_playbackintr) {
3267 ad->ad_playbackintr(ad->ad_playbackintrarg);
3268 handled = 1;
3269 } else if (st == ad->ad_capture && ad->ad_captureintr) {
3270 ad->ad_captureintr(ad->ad_captureintrarg);
3271 handled = 1;
3272 }
3273 mutex_spin_exit(&ad->ad_sc->sc_intr_lock);
3274
3275 return handled;
3276 }
3277
3278 static bool
3279 hdafg_rate_supported(struct hdafg_softc *sc, u_int frequency)
3280 {
3281 uint32_t caps = sc->sc_p.pcm_size_rate;
3282
3283 if (sc->sc_fixed_rate)
3284 return frequency == sc->sc_fixed_rate;
3285
3286 #define ISFREQOK(shift) ((caps & (1 << (shift))) ? true : false)
3287 switch (frequency) {
3288 case 8000:
3289 return ISFREQOK(0);
3290 case 11025:
3291 return ISFREQOK(1);
3292 case 16000:
3293 return ISFREQOK(2);
3294 case 22050:
3295 return ISFREQOK(3);
3296 case 32000:
3297 return ISFREQOK(4);
3298 case 44100:
3299 return ISFREQOK(5);
3300 return true;
3301 case 48000:
3302 return true; /* Must be supported by all codecs */
3303 case 88200:
3304 return ISFREQOK(7);
3305 case 96000:
3306 return ISFREQOK(8);
3307 case 176400:
3308 return ISFREQOK(9);
3309 case 192000:
3310 return ISFREQOK(10);
3311 case 384000:
3312 return ISFREQOK(11);
3313 default:
3314 return false;
3315 }
3316 #undef ISFREQOK
3317 }
3318
3319 static bool
3320 hdafg_bits_supported(struct hdafg_softc *sc, u_int bits)
3321 {
3322 uint32_t caps = sc->sc_p.pcm_size_rate;
3323 #define ISBITSOK(shift) ((caps & (1 << (shift))) ? true : false)
3324 switch (bits) {
3325 case 8:
3326 return ISBITSOK(16);
3327 case 16:
3328 return ISBITSOK(17);
3329 case 20:
3330 return ISBITSOK(18);
3331 case 24:
3332 return ISBITSOK(19);
3333 case 32:
3334 return ISBITSOK(20);
3335 default:
3336 return false;
3337 }
3338 #undef ISBITSOK
3339 }
3340
3341 static bool
3342 hdafg_probe_encoding(struct hdafg_softc *sc,
3343 u_int validbits, u_int precision, int encoding, bool force)
3344 {
3345 struct audio_format f;
3346 int i;
3347
3348 if (!force && hdafg_bits_supported(sc, validbits) == false)
3349 return false;
3350
3351 memset(&f, 0, sizeof(f));
3352 f.driver_data = NULL;
3353 f.mode = 0;
3354 f.encoding = encoding;
3355 f.validbits = validbits;
3356 f.precision = precision;
3357 f.channels = 0;
3358 f.channel_mask = 0;
3359 f.frequency_type = 0;
3360 for (i = 0; i < __arraycount(hdafg_possible_rates); i++) {
3361 u_int rate = hdafg_possible_rates[i];
3362 if (hdafg_rate_supported(sc, rate))
3363 f.frequency[f.frequency_type++] = rate;
3364 }
3365
3366 #define HDAUDIO_INITFMT(ch, chmask) \
3367 do { \
3368 f.channels = (ch); \
3369 f.channel_mask = (chmask); \
3370 f.mode = 0; \
3371 if (sc->sc_pchan >= (ch)) \
3372 f.mode |= AUMODE_PLAY; \
3373 if (sc->sc_rchan >= (ch)) \
3374 f.mode |= AUMODE_RECORD; \
3375 if (f.mode != 0) \
3376 hdafg_append_formats(&sc->sc_audiodev, &f); \
3377 } while (0)
3378
3379 /* Commented out, otherwise monaural samples play through left
3380 * channel only
3381 */
3382 /* HDAUDIO_INITFMT(1, AUFMT_MONAURAL); */
3383 HDAUDIO_INITFMT(2, AUFMT_STEREO);
3384 HDAUDIO_INITFMT(4, AUFMT_SURROUND4);
3385 HDAUDIO_INITFMT(6, AUFMT_DOLBY_5_1);
3386 HDAUDIO_INITFMT(8, AUFMT_SURROUND_7_1);
3387
3388 #undef HDAUDIO_INITFMT
3389
3390 return true;
3391 }
3392
3393
3394 static void
3395 hdafg_configure_encodings(struct hdafg_softc *sc)
3396 {
3397 struct hdaudio_assoc *as = sc->sc_assocs;
3398 struct hdaudio_widget *w;
3399 struct audio_format f;
3400 uint32_t stream_format, caps;
3401 int nchan, i, nid;
3402
3403 sc->sc_pchan = sc->sc_rchan = 0;
3404
3405 for (nchan = 0, i = 0; i < sc->sc_nassocs; i++) {
3406 nchan = hdafg_assoc_count_channels(sc, &as[i],
3407 HDAUDIO_PINDIR_OUT);
3408 if (nchan > sc->sc_pchan)
3409 sc->sc_pchan = nchan;
3410 }
3411 for (nchan = 0, i = 0; i < sc->sc_nassocs; i++) {
3412 nchan = hdafg_assoc_count_channels(sc, &as[i],
3413 HDAUDIO_PINDIR_IN);
3414 if (nchan > sc->sc_rchan)
3415 sc->sc_rchan = nchan;
3416 }
3417 hda_print(sc, "%dch/%dch", sc->sc_pchan, sc->sc_rchan);
3418
3419 for (i = 0; i < __arraycount(hdafg_possible_rates); i++)
3420 if (hdafg_rate_supported(sc,
3421 hdafg_possible_rates[i]))
3422 hda_print1(sc, " %uHz", hdafg_possible_rates[i]);
3423
3424 stream_format = sc->sc_p.stream_format;
3425 caps = 0;
3426 for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3427 w = hdafg_widget_lookup(sc, nid);
3428 if (w == NULL)
3429 continue;
3430 stream_format |= w->w_p.stream_format;
3431 caps |= w->w_p.aw_cap;
3432 }
3433 if (stream_format == 0) {
3434 hda_print(sc,
3435 "WARNING: unsupported stream format mask 0x%X, assuming PCM\n",
3436 stream_format);
3437 stream_format |= COP_STREAM_FORMAT_PCM;
3438 }
3439
3440 if (stream_format & COP_STREAM_FORMAT_PCM) {
3441 int e = AUDIO_ENCODING_SLINEAR_LE;
3442 if (hdafg_probe_encoding(sc, 8, 16, e, false))
3443 hda_print1(sc, " PCM8");
3444 if (hdafg_probe_encoding(sc, 16, 16, e, false))
3445 hda_print1(sc, " PCM16");
3446 if (hdafg_probe_encoding(sc, 20, 32, e, false))
3447 hda_print1(sc, " PCM20");
3448 if (hdafg_probe_encoding(sc, 24, 32, e, false))
3449 hda_print1(sc, " PCM24");
3450 if (hdafg_probe_encoding(sc, 32, 32, e, false))
3451 hda_print1(sc, " PCM32");
3452 }
3453
3454 if ((stream_format & COP_STREAM_FORMAT_AC3) ||
3455 (caps & COP_AWCAP_DIGITAL)) {
3456 int e = AUDIO_ENCODING_AC3;
3457 if (hdafg_probe_encoding(sc, 16, 16, e, false))
3458 hda_print1(sc, " AC3");
3459 }
3460
3461 if (sc->sc_audiodev.ad_nformats == 0) {
3462 hdafg_probe_encoding(sc, 16, 16, AUDIO_ENCODING_SLINEAR_LE, true);
3463 hda_print1(sc, " PCM16*");
3464 }
3465
3466 /*
3467 * XXX JDM 20090614
3468 * MI audio assumes that at least one playback and one capture format
3469 * is reported by the hw driver; until this bug is resolved just
3470 * report 2ch capabilities if the function group does not support
3471 * the direction.
3472 */
3473 if (sc->sc_rchan == 0 || sc->sc_pchan == 0) {
3474 memset(&f, 0, sizeof(f));
3475 f.driver_data = NULL;
3476 f.mode = 0;
3477 f.encoding = AUDIO_ENCODING_SLINEAR_LE;
3478 f.validbits = 16;
3479 f.precision = 16;
3480 f.channels = 2;
3481 f.channel_mask = AUFMT_STEREO;
3482 f.frequency_type = 0;
3483 f.frequency[0] = f.frequency[1] = sc->sc_fixed_rate ?
3484 sc->sc_fixed_rate : 48000;
3485 f.mode = AUMODE_PLAY|AUMODE_RECORD;
3486 hdafg_append_formats(&sc->sc_audiodev, &f);
3487 }
3488
3489 hda_print1(sc, "\n");
3490 }
3491
3492 static void
3493 hdafg_hp_switch_handler(void *opaque)
3494 {
3495 struct hdafg_softc *sc = opaque;
3496 struct hdaudio_assoc *as = sc->sc_assocs;
3497 struct hdaudio_widget *w;
3498 uint32_t res = 0;
3499 int i, j;
3500
3501 if (!device_is_active(sc->sc_dev))
3502 goto resched;
3503
3504 for (i = 0; i < sc->sc_nassocs; i++) {
3505 if (as[i].as_digital != HDAFG_AS_ANALOG &&
3506 as[i].as_digital != HDAFG_AS_SPDIF)
3507 continue;
3508 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3509 if (as[i].as_pins[j] == 0)
3510 continue;
3511 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3512 if (w == NULL || w->w_enable == false)
3513 continue;
3514 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3515 continue;
3516 if (COP_CFG_DEFAULT_DEVICE(w->w_pin.config) !=
3517 COP_DEVICE_HP_OUT)
3518 continue;
3519 res |= hdaudio_command(sc->sc_codec, as[i].as_pins[j],
3520 CORB_GET_PIN_SENSE, 0) &
3521 COP_GET_PIN_SENSE_PRESENSE_DETECT;
3522 }
3523 }
3524
3525 for (i = 0; i < sc->sc_nassocs; i++) {
3526 if (as[i].as_digital != HDAFG_AS_ANALOG &&
3527 as[i].as_digital != HDAFG_AS_SPDIF)
3528 continue;
3529 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3530 if (as[i].as_pins[j] == 0)
3531 continue;
3532 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3533 if (w == NULL || w->w_enable == false)
3534 continue;
3535 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3536 continue;
3537 switch (COP_CFG_DEFAULT_DEVICE(w->w_pin.config)) {
3538 case COP_DEVICE_HP_OUT:
3539 if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
3540 w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
3541 else
3542 w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
3543 hdaudio_command(sc->sc_codec, w->w_nid,
3544 CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3545 break;
3546 case COP_DEVICE_LINE_OUT:
3547 case COP_DEVICE_SPEAKER:
3548 case COP_DEVICE_AUX:
3549 if (res & COP_GET_PIN_SENSE_PRESENSE_DETECT)
3550 w->w_pin.ctrl &= ~COP_PWC_OUT_ENABLE;
3551 else
3552 w->w_pin.ctrl |= COP_PWC_OUT_ENABLE;
3553 hdaudio_command(sc->sc_codec, w->w_nid,
3554 CORB_SET_PIN_WIDGET_CONTROL, w->w_pin.ctrl);
3555 break;
3556 default:
3557 break;
3558 }
3559 }
3560 }
3561
3562 resched:
3563 callout_schedule(&sc->sc_jack_callout, HDAUDIO_HP_SENSE_PERIOD);
3564 }
3565
3566 static void
3567 hdafg_hp_switch_init(struct hdafg_softc *sc)
3568 {
3569 struct hdaudio_assoc *as = sc->sc_assocs;
3570 struct hdaudio_widget *w;
3571 bool enable = false;
3572 int i, j;
3573
3574 for (i = 0; i < sc->sc_nassocs; i++) {
3575 if (as[i].as_hpredir < 0 && as[i].as_displaydev == false)
3576 continue;
3577 if (as[i].as_displaydev == false)
3578 w = hdafg_widget_lookup(sc, as[i].as_pins[15]);
3579 else {
3580 w = NULL;
3581 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3582 if (as[i].as_pins[j] == 0)
3583 continue;
3584 w = hdafg_widget_lookup(sc, as[i].as_pins[j]);
3585 if (w && w->w_enable &&
3586 w->w_type == COP_AWCAP_TYPE_PIN_COMPLEX)
3587 break;
3588 w = NULL;
3589 }
3590 }
3591 if (w == NULL || w->w_enable == false)
3592 continue;
3593 if (w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3594 continue;
3595 if (!(w->w_pin.cap & COP_PINCAP_PRESENSE_DETECT_CAPABLE)) {
3596 continue;
3597 }
3598 if (COP_CFG_MISC(w->w_pin.config) & 1) {
3599 hda_trace(sc, "no presence detect on pin %02X\n",
3600 w->w_nid);
3601 continue;
3602 }
3603 if ((w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP)) == 0)
3604 enable = true;
3605
3606 if (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) {
3607 uint8_t val = COP_SET_UNSOLICITED_RESPONSE_ENABLE;
3608 if (w->w_pin.cap & (COP_PINCAP_HDMI|COP_PINCAP_DP))
3609 val |= HDAUDIO_UNSOLTAG_EVENT_DD;
3610 else
3611 val |= HDAUDIO_UNSOLTAG_EVENT_HP;
3612
3613 hdaudio_command(sc->sc_codec, w->w_nid,
3614 CORB_SET_UNSOLICITED_RESPONSE, val);
3615
3616 hdaudio_command(sc->sc_codec, w->w_nid,
3617 CORB_SET_AMPLIFIER_GAIN_MUTE, 0xb000);
3618 }
3619
3620 hda_trace(sc, "presence detect [pin=%02X,%s",
3621 w->w_nid,
3622 (w->w_p.aw_cap & COP_AWCAP_UNSOL_CAPABLE) ?
3623 "unsol" : "poll"
3624 );
3625 if (w->w_pin.cap & COP_PINCAP_HDMI)
3626 hda_trace1(sc, ",hdmi");
3627 if (w->w_pin.cap & COP_PINCAP_DP)
3628 hda_trace1(sc, ",displayport");
3629 hda_trace1(sc, "]\n");
3630 }
3631 if (enable) {
3632 sc->sc_jack_polling = true;
3633 hdafg_hp_switch_handler(sc);
3634 } else
3635 hda_trace(sc, "jack detect not enabled\n");
3636 }
3637
3638 static void
3639 hdafg_attach(device_t parent, device_t self, void *opaque)
3640 {
3641 struct hdafg_softc *sc = device_private(self);
3642 audio_params_t defparams;
3643 prop_dictionary_t args = opaque;
3644 char vendor[16], product[16];
3645 uint64_t fgptr = 0;
3646 uint32_t astype = 0;
3647 uint8_t nid = 0;
3648 int err, i;
3649 bool rv;
3650
3651 aprint_naive("\n");
3652 sc->sc_dev = self;
3653
3654 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
3655 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
3656
3657 callout_init(&sc->sc_jack_callout, 0);
3658 callout_setfunc(&sc->sc_jack_callout,
3659 hdafg_hp_switch_handler, sc);
3660
3661 if (!pmf_device_register(self, hdafg_suspend, hdafg_resume))
3662 aprint_error_dev(self, "couldn't establish power handler\n");
3663
3664 sc->sc_config = prop_dictionary_get(args, "pin-config");
3665 if (sc->sc_config && prop_object_type(sc->sc_config) != PROP_TYPE_ARRAY)
3666 sc->sc_config = NULL;
3667
3668 prop_dictionary_get_uint16(args, "vendor-id", &sc->sc_vendor);
3669 prop_dictionary_get_uint16(args, "product-id", &sc->sc_product);
3670 hdaudio_findvendor(vendor, sizeof(vendor), sc->sc_vendor);
3671 hdaudio_findproduct(product, sizeof(product), sc->sc_vendor,
3672 sc->sc_product);
3673 hda_print1(sc, ": %s %s%s\n", vendor, product,
3674 sc->sc_config ? " (custom configuration)" : "");
3675
3676 switch (sc->sc_vendor) {
3677 case HDAUDIO_VENDOR_NVIDIA:
3678 switch (sc->sc_product) {
3679 case HDAUDIO_PRODUCT_NVIDIA_TEGRA124_HDMI:
3680 sc->sc_fixed_rate = 44100;
3681 break;
3682 }
3683 break;
3684 }
3685
3686 rv = prop_dictionary_get_uint64(args, "function-group", &fgptr);
3687 if (rv == false || fgptr == 0) {
3688 hda_error(sc, "missing function-group property\n");
3689 return;
3690 }
3691 rv = prop_dictionary_get_uint8(args, "node-id", &nid);
3692 if (rv == false || nid == 0) {
3693 hda_error(sc, "missing node-id property\n");
3694 return;
3695 }
3696
3697 prop_dictionary_set_uint64(device_properties(self),
3698 "codecinfo-callback",
3699 (uint64_t)(uintptr_t)hdafg_codec_info);
3700 prop_dictionary_set_uint64(device_properties(self),
3701 "widgetinfo-callback",
3702 (uint64_t)(uintptr_t)hdafg_widget_info);
3703
3704 sc->sc_nid = nid;
3705 sc->sc_fg = (struct hdaudio_function_group *)(vaddr_t)fgptr;
3706 sc->sc_fg->fg_unsol = hdafg_unsol;
3707 sc->sc_codec = sc->sc_fg->fg_codec;
3708 KASSERT(sc->sc_codec != NULL);
3709 sc->sc_host = sc->sc_codec->co_host;
3710 KASSERT(sc->sc_host != NULL);
3711
3712 hda_debug(sc, "parsing widgets\n");
3713 hdafg_parse(sc);
3714 hda_debug(sc, "parsing controls\n");
3715 hdafg_control_parse(sc);
3716 hda_debug(sc, "disabling non-audio devices\n");
3717 hdafg_disable_nonaudio(sc);
3718 hda_debug(sc, "disabling useless devices\n");
3719 hdafg_disable_useless(sc);
3720 hda_debug(sc, "parsing associations\n");
3721 hdafg_assoc_parse(sc);
3722 hda_debug(sc, "building tree\n");
3723 hdafg_build_tree(sc);
3724 hda_debug(sc, "disabling unassociated pins\n");
3725 hdafg_disable_unassoc(sc);
3726 hda_debug(sc, "disabling unselected pins\n");
3727 hdafg_disable_unsel(sc);
3728 hda_debug(sc, "disabling useless devices\n");
3729 hdafg_disable_useless(sc);
3730 hda_debug(sc, "disabling cross-associated pins\n");
3731 hdafg_disable_crossassoc(sc);
3732 hda_debug(sc, "disabling useless devices\n");
3733 hdafg_disable_useless(sc);
3734
3735 hda_debug(sc, "assigning mixer names to sound sources\n");
3736 hdafg_assign_names(sc);
3737 hda_debug(sc, "assigning mixers to device tree\n");
3738 hdafg_assign_mixers(sc);
3739
3740 hda_debug(sc, "preparing pin controls\n");
3741 hdafg_prepare_pin_controls(sc);
3742 hda_debug(sc, "commiting settings\n");
3743 hdafg_commit(sc);
3744
3745 hda_debug(sc, "setup jack sensing\n");
3746 hdafg_hp_switch_init(sc);
3747
3748 hda_debug(sc, "building mixer controls\n");
3749 hdafg_build_mixers(sc);
3750
3751 hdafg_dump(sc);
3752 if (1) hdafg_widget_pin_dump(sc);
3753 hdafg_assoc_dump(sc);
3754
3755 hda_debug(sc, "enabling analog beep\n");
3756 hdafg_enable_analog_beep(sc);
3757
3758 hda_debug(sc, "configuring encodings\n");
3759 sc->sc_audiodev.ad_sc = sc;
3760 hdafg_configure_encodings(sc);
3761 err = auconv_create_encodings(sc->sc_audiodev.ad_formats,
3762 sc->sc_audiodev.ad_nformats, &sc->sc_audiodev.ad_encodings);
3763 if (err) {
3764 hda_error(sc, "couldn't create encodings\n");
3765 return;
3766 }
3767
3768 hda_debug(sc, "reserving streams\n");
3769 sc->sc_audiodev.ad_capture = hdaudio_stream_establish(sc->sc_host,
3770 HDAUDIO_STREAM_ISS, hdafg_stream_intr, &sc->sc_audiodev);
3771 sc->sc_audiodev.ad_playback = hdaudio_stream_establish(sc->sc_host,
3772 HDAUDIO_STREAM_OSS, hdafg_stream_intr, &sc->sc_audiodev);
3773
3774 hda_debug(sc, "connecting streams\n");
3775 defparams.channels = 2;
3776 defparams.sample_rate = sc->sc_fixed_rate ? sc->sc_fixed_rate : 48000;
3777 defparams.precision = defparams.validbits = 16;
3778 defparams.encoding = AUDIO_ENCODING_SLINEAR_LE;
3779 sc->sc_pparam = sc->sc_rparam = defparams;
3780 hdafg_stream_connect(sc, AUMODE_PLAY);
3781 hdafg_stream_connect(sc, AUMODE_RECORD);
3782
3783 for (i = 0; i < sc->sc_nassocs; i++) {
3784 astype |= (1 << sc->sc_assocs[i].as_digital);
3785 }
3786 hda_debug(sc, "assoc type mask: %x\n", astype);
3787
3788 #ifndef HDAUDIO_ENABLE_HDMI
3789 astype &= ~(1 << HDAFG_AS_HDMI);
3790 #endif
3791 #ifndef HDAUDIO_ENABLE_DISPLAYPORT
3792 astype &= ~(1 << HDAFG_AS_DISPLAYPORT);
3793 #endif
3794
3795 if (astype == 0)
3796 return;
3797
3798 hda_debug(sc, "attaching audio device\n");
3799 sc->sc_audiodev.ad_audiodev = audio_attach_mi(&hdafg_hw_if,
3800 &sc->sc_audiodev, self);
3801 }
3802
3803 static int
3804 hdafg_detach(device_t self, int flags)
3805 {
3806 struct hdafg_softc *sc = device_private(self);
3807 struct hdaudio_widget *wl, *w = sc->sc_widgets;
3808 struct hdaudio_assoc *as = sc->sc_assocs;
3809 struct hdaudio_control *ctl = sc->sc_ctls;
3810 struct hdaudio_mixer *mx = sc->sc_mixers;
3811 int nid;
3812
3813 callout_halt(&sc->sc_jack_callout, NULL);
3814 callout_destroy(&sc->sc_jack_callout);
3815
3816 if (sc->sc_config)
3817 prop_object_release(sc->sc_config);
3818 if (sc->sc_audiodev.ad_audiodev)
3819 config_detach(sc->sc_audiodev.ad_audiodev, flags);
3820 if (sc->sc_audiodev.ad_encodings)
3821 auconv_delete_encodings(sc->sc_audiodev.ad_encodings);
3822 if (sc->sc_audiodev.ad_playback)
3823 hdaudio_stream_disestablish(sc->sc_audiodev.ad_playback);
3824 if (sc->sc_audiodev.ad_capture)
3825 hdaudio_stream_disestablish(sc->sc_audiodev.ad_capture);
3826
3827 /* restore bios pin widget configuration */
3828 for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3829 wl = hdafg_widget_lookup(sc, nid);
3830 if (wl == NULL || wl->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3831 continue;
3832 hdafg_widget_setconfig(wl, wl->w_pin.biosconfig);
3833 }
3834
3835 if (w)
3836 kmem_free(w, sc->sc_nwidgets * sizeof(*w));
3837 if (as)
3838 kmem_free(as, sc->sc_nassocs * sizeof(*as));
3839 if (ctl)
3840 kmem_free(ctl, sc->sc_nctls * sizeof(*ctl));
3841 if (mx)
3842 kmem_free(mx, sc->sc_nmixers * sizeof(*mx));
3843
3844 mutex_destroy(&sc->sc_lock);
3845 mutex_destroy(&sc->sc_intr_lock);
3846
3847 pmf_device_deregister(self);
3848
3849 return 0;
3850 }
3851
3852 static void
3853 hdafg_childdet(device_t self, device_t child)
3854 {
3855 struct hdafg_softc *sc = device_private(self);
3856
3857 if (child == sc->sc_audiodev.ad_audiodev)
3858 sc->sc_audiodev.ad_audiodev = NULL;
3859 }
3860
3861 static bool
3862 hdafg_suspend(device_t self, const pmf_qual_t *qual)
3863 {
3864 struct hdafg_softc *sc = device_private(self);
3865
3866 callout_halt(&sc->sc_jack_callout, NULL);
3867
3868 return true;
3869 }
3870
3871 static bool
3872 hdafg_resume(device_t self, const pmf_qual_t *qual)
3873 {
3874 struct hdafg_softc *sc = device_private(self);
3875 struct hdaudio_widget *w;
3876 int nid;
3877
3878 hdaudio_command(sc->sc_codec, sc->sc_nid,
3879 CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
3880 hda_delay(100);
3881 for (nid = sc->sc_startnode; nid < sc->sc_endnode; nid++) {
3882 hdaudio_command(sc->sc_codec, nid,
3883 CORB_SET_POWER_STATE, COP_POWER_STATE_D0);
3884 w = hdafg_widget_lookup(sc, nid);
3885
3886 /* restore pin widget configuration */
3887 if (w == NULL || w->w_type != COP_AWCAP_TYPE_PIN_COMPLEX)
3888 continue;
3889 hdafg_widget_setconfig(w, w->w_pin.config);
3890 }
3891 hda_delay(1000);
3892
3893 hdafg_commit(sc);
3894 hdafg_stream_connect(sc, AUMODE_PLAY);
3895 hdafg_stream_connect(sc, AUMODE_RECORD);
3896
3897 if (sc->sc_jack_polling)
3898 hdafg_hp_switch_handler(sc);
3899
3900 return true;
3901 }
3902
3903 static int
3904 hdafg_query_encoding(void *opaque, struct audio_encoding *ae)
3905 {
3906 struct hdaudio_audiodev *ad = opaque;
3907 return auconv_query_encoding(ad->ad_encodings, ae);
3908 }
3909
3910 static int
3911 hdafg_set_params(void *opaque, int setmode, int usemode,
3912 audio_params_t *play, audio_params_t *rec,
3913 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
3914 {
3915 struct hdaudio_audiodev *ad = opaque;
3916 int index;
3917
3918 if (play && (setmode & AUMODE_PLAY)) {
3919 index = auconv_set_converter(ad->ad_formats, ad->ad_nformats,
3920 AUMODE_PLAY, play, TRUE, pfil);
3921 if (index < 0)
3922 return EINVAL;
3923 ad->ad_sc->sc_pparam = pfil->req_size > 0 ?
3924 pfil->filters[0].param : *play;
3925 hdafg_stream_connect(ad->ad_sc, AUMODE_PLAY);
3926 }
3927 if (rec && (setmode & AUMODE_RECORD)) {
3928 index = auconv_set_converter(ad->ad_formats, ad->ad_nformats,
3929 AUMODE_RECORD, rec, TRUE, rfil);
3930 if (index < 0)
3931 return EINVAL;
3932 ad->ad_sc->sc_rparam = rfil->req_size > 0 ?
3933 rfil->filters[0].param : *rec;
3934 hdafg_stream_connect(ad->ad_sc, AUMODE_RECORD);
3935 }
3936 return 0;
3937 }
3938
3939 static int
3940 hdafg_round_blocksize(void *opaque, int blksize, int mode,
3941 const audio_params_t *param)
3942 {
3943 struct hdaudio_audiodev *ad = opaque;
3944 struct hdaudio_stream *st;
3945 int bufsize, nblksize;
3946
3947 st = (mode == AUMODE_PLAY) ? ad->ad_playback : ad->ad_capture;
3948 if (st == NULL) {
3949 hda_trace(ad->ad_sc,
3950 "round_blocksize called for invalid stream\n");
3951 return 128;
3952 }
3953
3954 if (blksize > 8192)
3955 blksize = 8192;
3956 else if (blksize < 0)
3957 blksize = 128;
3958
3959 /* HD audio wants a multiple of 128, and OSS wants a power of 2 */
3960 for (nblksize = 128; nblksize < blksize; nblksize <<= 1)
3961 ;
3962
3963 /* Make sure there are enough BDL descriptors */
3964 bufsize = st->st_data.dma_size;
3965 if (bufsize > HDAUDIO_BDL_MAX * nblksize) {
3966 blksize = bufsize / HDAUDIO_BDL_MAX;
3967 for (nblksize = 128; nblksize < blksize; nblksize <<= 1)
3968 ;
3969 }
3970
3971 return nblksize;
3972 }
3973
3974 static int
3975 hdafg_commit_settings(void *opaque)
3976 {
3977 return 0;
3978 }
3979
3980 static int
3981 hdafg_halt_output(void *opaque)
3982 {
3983 struct hdaudio_audiodev *ad = opaque;
3984 struct hdafg_softc *sc = ad->ad_sc;
3985 struct hdaudio_assoc *as = ad->ad_sc->sc_assocs;
3986 struct hdaudio_widget *w;
3987 uint16_t dfmt;
3988 int i, j;
3989
3990 /* Disable digital outputs */
3991 for (i = 0; i < sc->sc_nassocs; i++) {
3992 if (as[i].as_enable == false)
3993 continue;
3994 if (as[i].as_dir != HDAUDIO_PINDIR_OUT)
3995 continue;
3996 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
3997 if (as[i].as_dacs[j] == 0)
3998 continue;
3999 w = hdafg_widget_lookup(sc, as[i].as_dacs[j]);
4000 if (w == NULL || w->w_enable == false)
4001 continue;
4002 if (w->w_p.aw_cap & COP_AWCAP_DIGITAL) {
4003 dfmt = hdaudio_command(sc->sc_codec, w->w_nid,
4004 CORB_GET_DIGITAL_CONVERTER_CONTROL, 0) &
4005 0xff;
4006 dfmt &= ~COP_DIGITAL_CONVCTRL1_DIGEN;
4007 hdaudio_command(sc->sc_codec, w->w_nid,
4008 CORB_SET_DIGITAL_CONVERTER_CONTROL_1, dfmt);
4009 }
4010 }
4011 }
4012
4013 hdaudio_stream_stop(ad->ad_playback);
4014
4015 return 0;
4016 }
4017
4018 static int
4019 hdafg_halt_input(void *opaque)
4020 {
4021 struct hdaudio_audiodev *ad = opaque;
4022
4023 hdaudio_stream_stop(ad->ad_capture);
4024
4025 return 0;
4026 }
4027
4028 static int
4029 hdafg_getdev(void *opaque, struct audio_device *audiodev)
4030 {
4031 struct hdaudio_audiodev *ad = opaque;
4032 struct hdafg_softc *sc = ad->ad_sc;
4033
4034 hdaudio_findvendor(audiodev->name, sizeof(audiodev->name),
4035 sc->sc_vendor);
4036 hdaudio_findproduct(audiodev->version, sizeof(audiodev->version),
4037 sc->sc_vendor, sc->sc_product);
4038 snprintf(audiodev->config, sizeof(audiodev->config) - 1,
4039 "%02Xh", sc->sc_nid);
4040
4041 return 0;
4042 }
4043
4044 static int
4045 hdafg_set_port(void *opaque, mixer_ctrl_t *mc)
4046 {
4047 struct hdaudio_audiodev *ad = opaque;
4048 struct hdafg_softc *sc = ad->ad_sc;
4049 struct hdaudio_mixer *mx;
4050 struct hdaudio_control *ctl;
4051 int i, divisor;
4052
4053 if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
4054 return EINVAL;
4055 mx = &sc->sc_mixers[mc->dev];
4056 ctl = mx->mx_ctl;
4057 if (ctl == NULL) {
4058 if (mx->mx_di.type != AUDIO_MIXER_SET)
4059 return ENXIO;
4060 if (mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_OUTPUTS &&
4061 mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_RECORD)
4062 return ENXIO;
4063 for (i = 0; i < sc->sc_nassocs; i++) {
4064 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_OUT &&
4065 mx->mx_di.mixer_class ==
4066 HDAUDIO_MIXER_CLASS_OUTPUTS)
4067 continue;
4068 if (sc->sc_assocs[i].as_dir != HDAUDIO_PINDIR_IN &&
4069 mx->mx_di.mixer_class ==
4070 HDAUDIO_MIXER_CLASS_RECORD)
4071 continue;
4072 sc->sc_assocs[i].as_activated =
4073 (mc->un.mask & (1 << i)) ? true : false;
4074 }
4075 hdafg_stream_connect(ad->ad_sc,
4076 mx->mx_di.mixer_class == HDAUDIO_MIXER_CLASS_OUTPUTS ?
4077 AUMODE_PLAY : AUMODE_RECORD);
4078 return 0;
4079 }
4080
4081 switch (mx->mx_di.type) {
4082 case AUDIO_MIXER_VALUE:
4083 if (ctl->ctl_step == 0)
4084 divisor = 128; /* ??? - just avoid div by 0 */
4085 else
4086 divisor = 255 / ctl->ctl_step;
4087
4088 hdafg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_NONE,
4089 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] / divisor,
4090 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] / divisor);
4091 break;
4092 case AUDIO_MIXER_ENUM:
4093 hdafg_control_amp_set(ctl,
4094 mc->un.ord ? HDAUDIO_AMP_MUTE_ALL : HDAUDIO_AMP_MUTE_NONE,
4095 ctl->ctl_left, ctl->ctl_right);
4096 break;
4097 default:
4098 return ENXIO;
4099 }
4100
4101 return 0;
4102 }
4103
4104 static int
4105 hdafg_get_port(void *opaque, mixer_ctrl_t *mc)
4106 {
4107 struct hdaudio_audiodev *ad = opaque;
4108 struct hdafg_softc *sc = ad->ad_sc;
4109 struct hdaudio_mixer *mx;
4110 struct hdaudio_control *ctl;
4111 u_int mask = 0;
4112 int i, factor;
4113
4114 if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
4115 return EINVAL;
4116 mx = &sc->sc_mixers[mc->dev];
4117 ctl = mx->mx_ctl;
4118 if (ctl == NULL) {
4119 if (mx->mx_di.type != AUDIO_MIXER_SET)
4120 return ENXIO;
4121 if (mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_OUTPUTS &&
4122 mx->mx_di.mixer_class != HDAUDIO_MIXER_CLASS_RECORD)
4123 return ENXIO;
4124 for (i = 0; i < sc->sc_nassocs; i++) {
4125 if (sc->sc_assocs[i].as_enable == false)
4126 continue;
4127 if (sc->sc_assocs[i].as_activated == false)
4128 continue;
4129 if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_OUT &&
4130 mx->mx_di.mixer_class ==
4131 HDAUDIO_MIXER_CLASS_OUTPUTS)
4132 mask |= (1 << i);
4133 if (sc->sc_assocs[i].as_dir == HDAUDIO_PINDIR_IN &&
4134 mx->mx_di.mixer_class ==
4135 HDAUDIO_MIXER_CLASS_RECORD)
4136 mask |= (1 << i);
4137 }
4138 mc->un.mask = mask;
4139 return 0;
4140 }
4141
4142 switch (mx->mx_di.type) {
4143 case AUDIO_MIXER_VALUE:
4144 if (ctl->ctl_step == 0)
4145 factor = 128; /* ??? - just avoid div by 0 */
4146 else
4147 factor = 255 / ctl->ctl_step;
4148
4149 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = ctl->ctl_left * factor;
4150 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = ctl->ctl_right * factor;
4151 break;
4152 case AUDIO_MIXER_ENUM:
4153 mc->un.ord = (ctl->ctl_muted || ctl->ctl_forcemute) ? 1 : 0;
4154 break;
4155 default:
4156 return ENXIO;
4157 }
4158 return 0;
4159 }
4160
4161 static int
4162 hdafg_query_devinfo(void *opaque, mixer_devinfo_t *di)
4163 {
4164 struct hdaudio_audiodev *ad = opaque;
4165 struct hdafg_softc *sc = ad->ad_sc;
4166
4167 if (di->index < 0 || di->index >= sc->sc_nmixers)
4168 return ENXIO;
4169
4170 *di = sc->sc_mixers[di->index].mx_di;
4171
4172 return 0;
4173 }
4174
4175 static void *
4176 hdafg_allocm(void *opaque, int direction, size_t size)
4177 {
4178 struct hdaudio_audiodev *ad = opaque;
4179 struct hdaudio_stream *st;
4180 int err;
4181
4182 st = (direction == AUMODE_PLAY) ? ad->ad_playback : ad->ad_capture;
4183 if (st == NULL)
4184 return NULL;
4185
4186 if (st->st_data.dma_valid == true)
4187 hda_error(ad->ad_sc, "WARNING: allocm leak\n");
4188
4189 st->st_data.dma_size = size;
4190 err = hdaudio_dma_alloc(st->st_host, &st->st_data,
4191 BUS_DMA_COHERENT | BUS_DMA_NOCACHE);
4192 if (err || st->st_data.dma_valid == false)
4193 return NULL;
4194
4195 return DMA_KERNADDR(&st->st_data);
4196 }
4197
4198 static void
4199 hdafg_freem(void *opaque, void *addr, size_t size)
4200 {
4201 struct hdaudio_audiodev *ad = opaque;
4202 struct hdaudio_stream *st;
4203
4204 if (addr == DMA_KERNADDR(&ad->ad_playback->st_data))
4205 st = ad->ad_playback;
4206 else if (addr == DMA_KERNADDR(&ad->ad_capture->st_data))
4207 st = ad->ad_capture;
4208 else
4209 return;
4210
4211 hdaudio_dma_free(st->st_host, &st->st_data);
4212 }
4213
4214 static size_t
4215 hdafg_round_buffersize(void *opaque, int direction, size_t bufsize)
4216 {
4217 /* Multiple of 128 */
4218 bufsize &= ~127;
4219 if (bufsize <= 0)
4220 bufsize = 128;
4221 return bufsize;
4222 }
4223
4224 static paddr_t
4225 hdafg_mappage(void *opaque, void *addr, off_t off, int prot)
4226 {
4227 struct hdaudio_audiodev *ad = opaque;
4228 struct hdaudio_stream *st;
4229
4230 if (addr == DMA_KERNADDR(&ad->ad_playback->st_data))
4231 st = ad->ad_playback;
4232 else if (addr == DMA_KERNADDR(&ad->ad_capture->st_data))
4233 st = ad->ad_capture;
4234 else
4235 return -1;
4236
4237 if (st->st_data.dma_valid == false)
4238 return -1;
4239
4240 return bus_dmamem_mmap(st->st_host->sc_dmat, st->st_data.dma_segs,
4241 st->st_data.dma_nsegs, off, prot, BUS_DMA_WAITOK);
4242 }
4243
4244 static int
4245 hdafg_get_props(void *opaque)
4246 {
4247 struct hdaudio_audiodev *ad = opaque;
4248 int props = AUDIO_PROP_MMAP;
4249
4250 if (ad->ad_playback)
4251 props |= AUDIO_PROP_PLAYBACK;
4252 if (ad->ad_capture)
4253 props |= AUDIO_PROP_CAPTURE;
4254 if (ad->ad_playback && ad->ad_capture) {
4255 props |= AUDIO_PROP_FULLDUPLEX;
4256 props |= AUDIO_PROP_INDEPENDENT;
4257 }
4258
4259 return props;
4260 }
4261
4262 static int
4263 hdafg_trigger_output(void *opaque, void *start, void *end, int blksize,
4264 void (*intr)(void *), void *intrarg, const audio_params_t *param)
4265 {
4266 struct hdaudio_audiodev *ad = opaque;
4267 bus_size_t dmasize;
4268
4269 if (ad->ad_playback == NULL)
4270 return ENXIO;
4271 if (ad->ad_playback->st_data.dma_valid == false)
4272 return ENOMEM;
4273
4274 ad->ad_playbackintr = intr;
4275 ad->ad_playbackintrarg = intrarg;
4276
4277 dmasize = (char *)end - (char *)start;
4278 hdafg_stream_connect(ad->ad_sc, AUMODE_PLAY);
4279 hdaudio_stream_start(ad->ad_playback, blksize, dmasize,
4280 &ad->ad_sc->sc_pparam);
4281
4282 return 0;
4283 }
4284
4285 static int
4286 hdafg_trigger_input(void *opaque, void *start, void *end, int blksize,
4287 void (*intr)(void *), void *intrarg, const audio_params_t *param)
4288 {
4289 struct hdaudio_audiodev *ad = opaque;
4290 bus_size_t dmasize;
4291
4292 if (ad->ad_capture == NULL)
4293 return ENXIO;
4294 if (ad->ad_capture->st_data.dma_valid == false)
4295 return ENOMEM;
4296
4297 ad->ad_captureintr = intr;
4298 ad->ad_captureintrarg = intrarg;
4299
4300 dmasize = (char *)end - (char *)start;
4301 hdafg_stream_connect(ad->ad_sc, AUMODE_RECORD);
4302 hdaudio_stream_start(ad->ad_capture, blksize, dmasize,
4303 &ad->ad_sc->sc_rparam);
4304
4305 return 0;
4306 }
4307
4308 static void
4309 hdafg_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
4310 {
4311 struct hdaudio_audiodev *ad = opaque;
4312
4313 *intr = &ad->ad_sc->sc_intr_lock;
4314 *thread = &ad->ad_sc->sc_lock;
4315 }
4316
4317 static int
4318 hdafg_unsol(device_t self, uint8_t tag)
4319 {
4320 struct hdafg_softc *sc = device_private(self);
4321 struct hdaudio_assoc *as = sc->sc_assocs;
4322 int i, j;
4323
4324 switch (tag) {
4325 case HDAUDIO_UNSOLTAG_EVENT_DD:
4326 hda_print(sc, "unsol: display device hotplug\n");
4327 for (i = 0; i < sc->sc_nassocs; i++) {
4328 if (as[i].as_displaydev == false)
4329 continue;
4330 for (j = 0; j < HDAUDIO_MAXPINS; j++) {
4331 if (as[i].as_pins[j] == 0)
4332 continue;
4333 hdafg_assoc_dump_dd(sc, &as[i], j, 0);
4334 }
4335 }
4336 break;
4337 default:
4338 hda_print(sc, "unsol: tag=%u\n", tag);
4339 break;
4340 }
4341
4342 return 0;
4343 }
4344
4345 static int
4346 hdafg_widget_info(void *opaque, prop_dictionary_t request,
4347 prop_dictionary_t response)
4348 {
4349 struct hdafg_softc *sc = opaque;
4350 struct hdaudio_widget *w;
4351 prop_array_t connlist;
4352 uint32_t config, wcap;
4353 uint16_t index;
4354 int nid;
4355 int i;
4356
4357 if (prop_dictionary_get_uint16(request, "index", &index) == false)
4358 return EINVAL;
4359
4360 nid = sc->sc_startnode + index;
4361 if (nid >= sc->sc_endnode)
4362 return EINVAL;
4363
4364 w = hdafg_widget_lookup(sc, nid);
4365 if (w == NULL)
4366 return ENXIO;
4367 wcap = hda_get_wparam(w, PIN_CAPABILITIES);
4368 config = hdaudio_command(sc->sc_codec, w->w_nid,
4369 CORB_GET_CONFIGURATION_DEFAULT, 0);
4370 prop_dictionary_set_cstring_nocopy(response, "name", w->w_name);
4371 prop_dictionary_set_bool(response, "enable", w->w_enable);
4372 prop_dictionary_set_uint8(response, "nid", w->w_nid);
4373 prop_dictionary_set_uint8(response, "type", w->w_type);
4374 prop_dictionary_set_uint32(response, "config", config);
4375 prop_dictionary_set_uint32(response, "cap", wcap);
4376 if (w->w_nconns == 0)
4377 return 0;
4378 connlist = prop_array_create();
4379 for (i = 0; i < w->w_nconns; i++) {
4380 if (w->w_conns[i] == 0)
4381 continue;
4382 prop_array_add(connlist,
4383 prop_number_create_unsigned_integer(w->w_conns[i]));
4384 }
4385 prop_dictionary_set(response, "connlist", connlist);
4386 prop_object_release(connlist);
4387 return 0;
4388 }
4389
4390 static int
4391 hdafg_codec_info(void *opaque, prop_dictionary_t request,
4392 prop_dictionary_t response)
4393 {
4394 struct hdafg_softc *sc = opaque;
4395 prop_dictionary_set_uint16(response, "vendor-id",
4396 sc->sc_vendor);
4397 prop_dictionary_set_uint16(response, "product-id",
4398 sc->sc_product);
4399 return 0;
4400 }
4401
4402 MODULE(MODULE_CLASS_DRIVER, hdafg, "hdaudio");
4403
4404 #ifdef _MODULE
4405 #include "ioconf.c"
4406 #endif
4407
4408 static int
4409 hdafg_modcmd(modcmd_t cmd, void *opaque)
4410 {
4411 int error = 0;
4412
4413 switch (cmd) {
4414 case MODULE_CMD_INIT:
4415 #ifdef _MODULE
4416 error = config_init_component(cfdriver_ioconf_hdafg,
4417 cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
4418 #endif
4419 return error;
4420 case MODULE_CMD_FINI:
4421 #ifdef _MODULE
4422 error = config_fini_component(cfdriver_ioconf_hdafg,
4423 cfattach_ioconf_hdafg, cfdata_ioconf_hdafg);
4424 #endif
4425 return error;
4426 default:
4427 return ENOTTY;
4428 }
4429 }
4430
4431 #define HDAFG_GET_ANACTRL 0xfe0
4432 #define HDAFG_SET_ANACTRL 0x7e0
4433 #define HDAFG_ANALOG_BEEP_EN __BIT(5)
4434 #define HDAFG_ALC231_MONO_OUT_MIXER 0xf
4435 #define HDAFG_STAC9200_AFG 0x1
4436 #define HDAFG_STAC9200_GET_ANACTRL_PAYLOAD 0x0
4437 #define HDAFG_ALC231_INPUT_BOTH_CHANNELS_UNMUTE 0x7100
4438
4439 static void
4440 hdafg_enable_analog_beep(struct hdafg_softc *sc)
4441 {
4442 int nid;
4443 uint32_t response;
4444
4445 switch (sc->sc_vendor) {
4446 case HDAUDIO_VENDOR_SIGMATEL:
4447 switch (sc->sc_product) {
4448 case HDAUDIO_PRODUCT_SIGMATEL_STAC9200:
4449 case HDAUDIO_PRODUCT_SIGMATEL_STAC9200D:
4450 case HDAUDIO_PRODUCT_SIGMATEL_STAC9202:
4451 case HDAUDIO_PRODUCT_SIGMATEL_STAC9202D:
4452 case HDAUDIO_PRODUCT_SIGMATEL_STAC9204:
4453 case HDAUDIO_PRODUCT_SIGMATEL_STAC9204D:
4454 case HDAUDIO_PRODUCT_SIGMATEL_STAC9205:
4455 case HDAUDIO_PRODUCT_SIGMATEL_STAC9205_1:
4456 case HDAUDIO_PRODUCT_SIGMATEL_STAC9205D:
4457 nid = HDAFG_STAC9200_AFG;
4458
4459 response = hdaudio_command(sc->sc_codec, nid,
4460 HDAFG_GET_ANACTRL,
4461 HDAFG_STAC9200_GET_ANACTRL_PAYLOAD);
4462 hda_delay(100);
4463
4464 response |= HDAFG_ANALOG_BEEP_EN;
4465
4466 hdaudio_command(sc->sc_codec, nid, HDAFG_SET_ANACTRL,
4467 response);
4468 hda_delay(100);
4469 break;
4470 default:
4471 break;
4472 }
4473 break;
4474 case HDAUDIO_VENDOR_REALTEK:
4475 switch (sc->sc_product) {
4476 case HDAUDIO_PRODUCT_REALTEK_ALC269:
4477 /* The Panasonic Toughbook CF19 - Mk 5 uses a Realtek
4478 * ALC231 that identifies as an ALC269.
4479 * This unmutes the PCBEEP on the speaker.
4480 */
4481 nid = HDAFG_ALC231_MONO_OUT_MIXER;
4482 response = hdaudio_command(sc->sc_codec, nid,
4483 CORB_SET_AMPLIFIER_GAIN_MUTE,
4484 HDAFG_ALC231_INPUT_BOTH_CHANNELS_UNMUTE);
4485 hda_delay(100);
4486 break;
4487 default:
4488 break;
4489 }
4490 default:
4491 break;
4492 }
4493 }
4494