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