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