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