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