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