1/* $OpenBSD: azalia.c,v 1.287 2024/05/17 19:43:45 kettenis Exp $ */ 2/* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ 3 4/*- 5 * Copyright (c) 2005 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by TAMURA Kent 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. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/* 34 * High Definition Audio Specification 35 * 36 * http://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf 37 * 38 * 39 * TO DO: 40 * - multiple codecs (needed?) 41 * - multiple streams (needed?) 42 */ 43 44#include <sys/param.h> 45#include <sys/fcntl.h> 46#include <sys/device.h> 47#include <sys/malloc.h> 48#include <sys/systm.h> 49#include <sys/timeout.h> 50#include <dev/audio_if.h> 51#include <dev/pci/pcidevs.h> 52#include <dev/pci/pcivar.h> 53 54#include <dev/pci/azalia.h> 55 56typedef struct audio_params audio_params_t; 57 58struct audio_format { 59 void *driver_data; 60 int32_t mode; 61 u_int encoding; 62 u_int precision; 63 u_int channels; 64 65 /** 66 * 0: frequency[0] is lower limit, and frequency[1] is higher limit. 67 * 1-16: frequency[0] to frequency[frequency_type-1] are valid. 68 */ 69 u_int frequency_type; 70 71#define AUFMT_MAX_FREQUENCIES 16 72 /** 73 * sampling rates 74 */ 75 u_int frequency[AUFMT_MAX_FREQUENCIES]; 76}; 77 78 79#ifdef AZALIA_DEBUG 80# define DPRINTFN(n,x) do { if (az_debug > (n)) printf x; } while (0/*CONSTCOND*/) 81int az_debug = 0; 82#else 83# define DPRINTFN(n,x) do {} while (0/*CONSTCOND*/) 84#endif 85 86 87/* ---------------------------------------------------------------- 88 * ICH6/ICH7 constant values 89 * ---------------------------------------------------------------- */ 90 91/* PCI registers */ 92#define ICH_PCI_HDBARL 0x10 93#define ICH_PCI_HDBARU 0x14 94#define ICH_PCI_HDCTL 0x40 95#define ICH_PCI_HDCTL_CLKDETCLR 0x08 96#define ICH_PCI_HDCTL_CLKDETEN 0x04 97#define ICH_PCI_HDCTL_CLKDETINV 0x02 98#define ICH_PCI_HDCTL_SIGNALMODE 0x01 99#define ICH_PCI_HDTCSEL 0x44 100#define ICH_PCI_HDTCSEL_MASK 0x7 101#define ICH_PCI_MMC 0x62 102#define ICH_PCI_MMC_ME 0x1 103 104/* internal types */ 105 106typedef struct { 107 bus_dmamap_t map; 108 caddr_t addr; /* kernel virtual address */ 109 bus_dma_segment_t segments[1]; 110 size_t size; 111} azalia_dma_t; 112#define AZALIA_DMA_DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 113 114typedef struct { 115 struct azalia_t *az; 116 int regbase; 117 int number; 118 int dir; /* AUMODE_PLAY or AUMODE_RECORD */ 119 uint32_t intr_bit; 120 azalia_dma_t bdlist; 121 azalia_dma_t buffer; 122 void (*intr)(void*); 123 void *intr_arg; 124 int bufsize; 125 uint16_t fmt; 126 int blk; 127 unsigned int swpos; /* position in the audio(4) layer */ 128} stream_t; 129#define STR_READ_1(s, r) \ 130 bus_space_read_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r) 131#define STR_READ_2(s, r) \ 132 bus_space_read_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r) 133#define STR_READ_4(s, r) \ 134 bus_space_read_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r) 135#define STR_WRITE_1(s, r, v) \ 136 bus_space_write_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v) 137#define STR_WRITE_2(s, r, v) \ 138 bus_space_write_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v) 139#define STR_WRITE_4(s, r, v) \ 140 bus_space_write_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v) 141 142typedef struct azalia_t { 143 struct device dev; 144 145 pci_chipset_tag_t pc; 146 pcitag_t tag; 147 void *ih; 148 bus_space_tag_t iot; 149 bus_space_handle_t ioh; 150 bus_size_t map_size; 151 bus_dma_tag_t dmat; 152 pcireg_t pciid; 153 uint32_t subid; 154 155 codec_t *codecs; 156 int ncodecs; /* number of codecs */ 157 int codecno; /* index of the using codec */ 158 int detached; /* 1 if failed to initialize, 2 if 159 * azalia_pci_detach has run 160 */ 161 azalia_dma_t corb_dma; 162 int corb_entries; 163 uint8_t corbsize; 164 azalia_dma_t rirb_dma; 165 int rirb_entries; 166 uint8_t rirbsize; 167 int rirb_rp; 168#define UNSOLQ_SIZE 256 169 rirb_entry_t *unsolq; 170 int unsolq_wp; 171 int unsolq_rp; 172 int unsolq_kick; 173 struct timeout unsol_to; 174 175 int ok64; 176 int nistreams, nostreams, nbstreams; 177 stream_t pstream; 178 stream_t rstream; 179 uint32_t intctl; 180} azalia_t; 181#define XNAME(sc) ((sc)->dev.dv_xname) 182#define AZ_READ_1(z, r) bus_space_read_1((z)->iot, (z)->ioh, HDA_##r) 183#define AZ_READ_2(z, r) bus_space_read_2((z)->iot, (z)->ioh, HDA_##r) 184#define AZ_READ_4(z, r) bus_space_read_4((z)->iot, (z)->ioh, HDA_##r) 185#define AZ_WRITE_1(z, r, v) bus_space_write_1((z)->iot, (z)->ioh, HDA_##r, v) 186#define AZ_WRITE_2(z, r, v) bus_space_write_2((z)->iot, (z)->ioh, HDA_##r, v) 187#define AZ_WRITE_4(z, r, v) bus_space_write_4((z)->iot, (z)->ioh, HDA_##r, v) 188 189 190/* prototypes */ 191uint8_t azalia_pci_read(pci_chipset_tag_t, pcitag_t, int); 192void azalia_pci_write(pci_chipset_tag_t, pcitag_t, int, uint8_t); 193int azalia_pci_match(struct device *, void *, void *); 194void azalia_pci_attach(struct device *, struct device *, void *); 195int azalia_pci_activate(struct device *, int); 196int azalia_pci_detach(struct device *, int); 197void azalia_configure_pci(azalia_t *); 198int azalia_intr(void *); 199void azalia_print_codec(codec_t *); 200int azalia_reset(azalia_t *); 201int azalia_get_ctrlr_caps(azalia_t *); 202int azalia_init(azalia_t *, int); 203int azalia_init_codecs(azalia_t *); 204int azalia_init_streams(azalia_t *); 205void azalia_shutdown(void *); 206int azalia_halt_corb(azalia_t *); 207int azalia_init_corb(azalia_t *, int); 208int azalia_halt_rirb(azalia_t *); 209int azalia_init_rirb(azalia_t *, int); 210int azalia_set_command(azalia_t *, nid_t, int, uint32_t, uint32_t); 211int azalia_get_response(azalia_t *, uint32_t *); 212void azalia_rirb_kick_unsol_events(void *); 213void azalia_rirb_intr(azalia_t *); 214int azalia_alloc_dmamem(azalia_t *, size_t, size_t, azalia_dma_t *); 215void azalia_free_dmamem(const azalia_t *, azalia_dma_t*); 216 217int azalia_codec_init(codec_t *); 218int azalia_codec_delete(codec_t *); 219void azalia_codec_add_bits(codec_t *, int, uint32_t, int); 220void azalia_codec_add_format(codec_t *, int, int, uint32_t, int32_t); 221int azalia_codec_connect_stream(stream_t *); 222int azalia_codec_disconnect_stream(stream_t *); 223void azalia_codec_print_audiofunc(const codec_t *); 224void azalia_codec_print_groups(const codec_t *); 225int azalia_codec_find_defdac(codec_t *, int, int); 226int azalia_codec_find_defadc(codec_t *, int, int); 227int azalia_codec_find_defadc_sub(codec_t *, nid_t, int, int); 228int azalia_codec_init_volgroups(codec_t *); 229int azalia_codec_sort_pins(codec_t *); 230int azalia_codec_select_micadc(codec_t *); 231int azalia_codec_select_dacs(codec_t *); 232int azalia_codec_select_spkrdac(codec_t *); 233int azalia_codec_find_inputmixer(codec_t *); 234 235int azalia_widget_init(widget_t *, const codec_t *, int); 236int azalia_widget_label_widgets(codec_t *); 237int azalia_widget_init_audio(widget_t *, const codec_t *); 238int azalia_widget_init_pin(widget_t *, const codec_t *); 239int azalia_widget_init_connection(widget_t *, const codec_t *); 240int azalia_widget_check_conn(codec_t *, int, int); 241int azalia_widget_sole_conn(codec_t *, nid_t); 242void azalia_widget_print_widget(const widget_t *, const codec_t *); 243void azalia_widget_print_audio(const widget_t *, const char *); 244void azalia_widget_print_pin(const widget_t *); 245 246int azalia_stream_init(stream_t *, azalia_t *, int, int, int); 247int azalia_stream_reset(stream_t *); 248int azalia_stream_start(stream_t *); 249int azalia_stream_halt(stream_t *); 250int azalia_stream_intr(stream_t *); 251 252int azalia_open(void *, int); 253void azalia_close(void *); 254int azalia_set_params(void *, int, int, audio_params_t *, 255 audio_params_t *); 256unsigned int azalia_set_blksz(void *, int, 257 struct audio_params *, struct audio_params *, unsigned int); 258unsigned int azalia_set_nblks(void *, int, 259 struct audio_params *, unsigned int, unsigned int); 260int azalia_halt_output(void *); 261int azalia_halt_input(void *); 262int azalia_set_port(void *, mixer_ctrl_t *); 263int azalia_get_port(void *, mixer_ctrl_t *); 264int azalia_query_devinfo(void *, mixer_devinfo_t *); 265void *azalia_allocm(void *, int, size_t, int, int); 266void azalia_freem(void *, void *, int); 267size_t azalia_round_buffersize(void *, int, size_t); 268int azalia_trigger_output(void *, void *, void *, int, 269 void (*)(void *), void *, audio_params_t *); 270int azalia_trigger_input(void *, void *, void *, int, 271 void (*)(void *), void *, audio_params_t *); 272 273int azalia_params2fmt(const audio_params_t *, uint16_t *); 274 275int azalia_match_format(codec_t *, int, audio_params_t *); 276int azalia_set_params_sub(codec_t *, int, audio_params_t *); 277 278int azalia_suspend(azalia_t *); 279int azalia_resume(azalia_t *); 280int azalia_resume_codec(codec_t *); 281 282/* variables */ 283const struct cfattach azalia_ca = { 284 sizeof(azalia_t), azalia_pci_match, azalia_pci_attach, 285 azalia_pci_detach, azalia_pci_activate 286}; 287 288struct cfdriver azalia_cd = { 289 NULL, "azalia", DV_DULL, CD_SKIPHIBERNATE 290}; 291 292const struct audio_hw_if azalia_hw_if = { 293 .open = azalia_open, 294 .close = azalia_close, 295 .set_params = azalia_set_params, 296 .halt_output = azalia_halt_output, 297 .halt_input = azalia_halt_input, 298 .set_port = azalia_set_port, 299 .get_port = azalia_get_port, 300 .query_devinfo = azalia_query_devinfo, 301 .allocm = azalia_allocm, 302 .freem = azalia_freem, 303 .round_buffersize = azalia_round_buffersize, 304 .trigger_output = azalia_trigger_output, 305 .trigger_input = azalia_trigger_input, 306 .set_blksz = azalia_set_blksz, 307 .set_nblks = azalia_set_nblks, 308}; 309 310static const char *pin_devices[16] = { 311 AudioNline, AudioNspeaker, AudioNheadphone, AudioNcd, 312 "SPDIF", "digital-out", "modem-line", "modem-handset", 313 "line-in", AudioNaux, AudioNmicrophone, "telephony", 314 "SPDIF-in", "digital-in", "beep", "other"}; 315static const char *wtypes[16] = { 316 "dac", "adc", "mix", "sel", "pin", "pow", "volume", 317 "beep", "wid08", "wid09", "wid0a", "wid0b", "wid0c", 318 "wid0d", "wid0e", "vendor"}; 319static const char *line_colors[16] = { 320 "unk", "blk", "gry", "blu", "grn", "red", "org", "yel", 321 "pur", "pnk", "0xa", "0xb", "0xc", "0xd", "wht", "oth"}; 322 323/* ================================================================ 324 * PCI functions 325 * ================================================================ */ 326 327#define ATI_PCIE_SNOOP_REG 0x42 328#define ATI_PCIE_SNOOP_MASK 0xf8 329#define ATI_PCIE_SNOOP_ENABLE 0x02 330#define NVIDIA_PCIE_SNOOP_REG 0x4e 331#define NVIDIA_PCIE_SNOOP_MASK 0xf0 332#define NVIDIA_PCIE_SNOOP_ENABLE 0x0f 333#define NVIDIA_HDA_ISTR_COH_REG 0x4d 334#define NVIDIA_HDA_OSTR_COH_REG 0x4c 335#define NVIDIA_HDA_STR_COH_ENABLE 0x01 336#define INTEL_PCIE_NOSNOOP_REG 0x79 337#define INTEL_PCIE_NOSNOOP_MASK 0xf7 338#define INTEL_PCIE_NOSNOOP_ENABLE 0x08 339 340uint8_t 341azalia_pci_read(pci_chipset_tag_t pc, pcitag_t pa, int reg) 342{ 343 return (pci_conf_read(pc, pa, (reg & ~0x03)) >> 344 ((reg & 0x03) * 8) & 0xff); 345} 346 347void 348azalia_pci_write(pci_chipset_tag_t pc, pcitag_t pa, int reg, uint8_t val) 349{ 350 pcireg_t pcival; 351 352 pcival = pci_conf_read(pc, pa, (reg & ~0x03)); 353 pcival &= ~(0xff << ((reg & 0x03) * 8)); 354 pcival |= (val << ((reg & 0x03) * 8)); 355 pci_conf_write(pc, pa, (reg & ~0x03), pcival); 356} 357 358void 359azalia_configure_pci(azalia_t *az) 360{ 361 pcireg_t v; 362 uint8_t reg; 363 364 /* enable back-to-back */ 365 v = pci_conf_read(az->pc, az->tag, PCI_COMMAND_STATUS_REG); 366 pci_conf_write(az->pc, az->tag, PCI_COMMAND_STATUS_REG, 367 v | PCI_COMMAND_BACKTOBACK_ENABLE); 368 369 /* traffic class select */ 370 v = pci_conf_read(az->pc, az->tag, ICH_PCI_HDTCSEL); 371 pci_conf_write(az->pc, az->tag, ICH_PCI_HDTCSEL, 372 v & ~(ICH_PCI_HDTCSEL_MASK)); 373 374 /* enable PCIe snoop */ 375 switch (PCI_PRODUCT(az->pciid)) { 376 case PCI_PRODUCT_ATI_SB450_HDA: 377 case PCI_PRODUCT_ATI_SBX00_HDA: 378 case PCI_PRODUCT_AMD_15_6X_AUDIO: 379 case PCI_PRODUCT_AMD_17_HDA: 380 case PCI_PRODUCT_AMD_17_1X_HDA: 381 case PCI_PRODUCT_AMD_17_3X_HDA: 382 case PCI_PRODUCT_AMD_HUDSON2_HDA: 383 reg = azalia_pci_read(az->pc, az->tag, ATI_PCIE_SNOOP_REG); 384 reg &= ATI_PCIE_SNOOP_MASK; 385 reg |= ATI_PCIE_SNOOP_ENABLE; 386 azalia_pci_write(az->pc, az->tag, ATI_PCIE_SNOOP_REG, reg); 387 break; 388 case PCI_PRODUCT_NVIDIA_MCP51_HDA: 389 case PCI_PRODUCT_NVIDIA_MCP55_HDA: 390 case PCI_PRODUCT_NVIDIA_MCP61_HDA_1: 391 case PCI_PRODUCT_NVIDIA_MCP61_HDA_2: 392 case PCI_PRODUCT_NVIDIA_MCP65_HDA_1: 393 case PCI_PRODUCT_NVIDIA_MCP65_HDA_2: 394 case PCI_PRODUCT_NVIDIA_MCP67_HDA_1: 395 case PCI_PRODUCT_NVIDIA_MCP67_HDA_2: 396 case PCI_PRODUCT_NVIDIA_MCP73_HDA_1: 397 case PCI_PRODUCT_NVIDIA_MCP73_HDA_2: 398 case PCI_PRODUCT_NVIDIA_MCP77_HDA_1: 399 case PCI_PRODUCT_NVIDIA_MCP77_HDA_2: 400 case PCI_PRODUCT_NVIDIA_MCP77_HDA_3: 401 case PCI_PRODUCT_NVIDIA_MCP77_HDA_4: 402 case PCI_PRODUCT_NVIDIA_MCP79_HDA_1: 403 case PCI_PRODUCT_NVIDIA_MCP79_HDA_2: 404 case PCI_PRODUCT_NVIDIA_MCP79_HDA_3: 405 case PCI_PRODUCT_NVIDIA_MCP79_HDA_4: 406 case PCI_PRODUCT_NVIDIA_MCP89_HDA_1: 407 case PCI_PRODUCT_NVIDIA_MCP89_HDA_2: 408 case PCI_PRODUCT_NVIDIA_MCP89_HDA_3: 409 case PCI_PRODUCT_NVIDIA_MCP89_HDA_4: 410 reg = azalia_pci_read(az->pc, az->tag, 411 NVIDIA_HDA_OSTR_COH_REG); 412 reg |= NVIDIA_HDA_STR_COH_ENABLE; 413 azalia_pci_write(az->pc, az->tag, 414 NVIDIA_HDA_OSTR_COH_REG, reg); 415 416 reg = azalia_pci_read(az->pc, az->tag, 417 NVIDIA_HDA_ISTR_COH_REG); 418 reg |= NVIDIA_HDA_STR_COH_ENABLE; 419 azalia_pci_write(az->pc, az->tag, 420 NVIDIA_HDA_ISTR_COH_REG, reg); 421 422 reg = azalia_pci_read(az->pc, az->tag, 423 NVIDIA_PCIE_SNOOP_REG); 424 reg &= NVIDIA_PCIE_SNOOP_MASK; 425 reg |= NVIDIA_PCIE_SNOOP_ENABLE; 426 azalia_pci_write(az->pc, az->tag, 427 NVIDIA_PCIE_SNOOP_REG, reg); 428 429 reg = azalia_pci_read(az->pc, az->tag, 430 NVIDIA_PCIE_SNOOP_REG); 431 if ((reg & NVIDIA_PCIE_SNOOP_ENABLE) != 432 NVIDIA_PCIE_SNOOP_ENABLE) { 433 printf(": could not enable PCIe cache snooping!\n"); 434 } 435 break; 436 case PCI_PRODUCT_INTEL_82801FB_HDA: 437 case PCI_PRODUCT_INTEL_82801GB_HDA: 438 case PCI_PRODUCT_INTEL_82801H_HDA: 439 case PCI_PRODUCT_INTEL_82801I_HDA: 440 case PCI_PRODUCT_INTEL_82801JI_HDA: 441 case PCI_PRODUCT_INTEL_82801JD_HDA: 442 case PCI_PRODUCT_INTEL_6321ESB_HDA: 443 case PCI_PRODUCT_INTEL_3400_HDA: 444 case PCI_PRODUCT_INTEL_QS57_HDA: 445 case PCI_PRODUCT_INTEL_6SERIES_HDA: 446 case PCI_PRODUCT_INTEL_7SERIES_HDA: 447 case PCI_PRODUCT_INTEL_8SERIES_HDA: 448 case PCI_PRODUCT_INTEL_8SERIES_LP_HDA: 449 case PCI_PRODUCT_INTEL_9SERIES_HDA: 450 case PCI_PRODUCT_INTEL_9SERIES_LP_HDA: 451 case PCI_PRODUCT_INTEL_100SERIES_HDA: 452 case PCI_PRODUCT_INTEL_100SERIES_H_HDA: 453 case PCI_PRODUCT_INTEL_100SERIES_LP_HDA: 454 case PCI_PRODUCT_INTEL_200SERIES_HDA: 455 case PCI_PRODUCT_INTEL_200SERIES_U_HDA: 456 case PCI_PRODUCT_INTEL_300SERIES_CAVS: 457 case PCI_PRODUCT_INTEL_300SERIES_U_HDA: 458 case PCI_PRODUCT_INTEL_400SERIES_CAVS: 459 case PCI_PRODUCT_INTEL_400SERIES_LP_HDA: 460 case PCI_PRODUCT_INTEL_495SERIES_LP_HDA: 461 case PCI_PRODUCT_INTEL_500SERIES_HDA: 462 case PCI_PRODUCT_INTEL_500SERIES_HDA_2: 463 case PCI_PRODUCT_INTEL_500SERIES_LP_HDA: 464 case PCI_PRODUCT_INTEL_600SERIES_HDA: 465 case PCI_PRODUCT_INTEL_600SERIES_LP_HDA: 466 case PCI_PRODUCT_INTEL_700SERIES_HDA: 467 case PCI_PRODUCT_INTEL_700SERIES_LP_HDA: 468 case PCI_PRODUCT_INTEL_C600_HDA: 469 case PCI_PRODUCT_INTEL_C610_HDA_1: 470 case PCI_PRODUCT_INTEL_C610_HDA_2: 471 case PCI_PRODUCT_INTEL_C620_HDA_1: 472 case PCI_PRODUCT_INTEL_C620_HDA_2: 473 case PCI_PRODUCT_INTEL_APOLLOLAKE_HDA: 474 case PCI_PRODUCT_INTEL_BAYTRAIL_HDA: 475 case PCI_PRODUCT_INTEL_BSW_HDA: 476 case PCI_PRODUCT_INTEL_GLK_HDA: 477 case PCI_PRODUCT_INTEL_JSL_HDA: 478 case PCI_PRODUCT_INTEL_EHL_HDA: 479 case PCI_PRODUCT_INTEL_ADL_N_HDA: 480 case PCI_PRODUCT_INTEL_MTL_HDA: 481 reg = azalia_pci_read(az->pc, az->tag, 482 INTEL_PCIE_NOSNOOP_REG); 483 reg &= INTEL_PCIE_NOSNOOP_MASK; 484 azalia_pci_write(az->pc, az->tag, 485 INTEL_PCIE_NOSNOOP_REG, reg); 486 break; 487 } 488} 489 490const struct pci_matchid azalia_pci_devices[] = { 491 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_200SERIES_U_HDA }, 492 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_CAVS }, 493 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_300SERIES_U_HDA }, 494 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_400SERIES_CAVS }, 495 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_400SERIES_LP_HDA }, 496 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_500SERIES_HDA }, 497 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_500SERIES_LP_HDA }, 498 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_600SERIES_LP_HDA }, 499 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_700SERIES_LP_HDA }, 500 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_APOLLOLAKE_HDA }, 501 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_GLK_HDA }, 502 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_JSL_HDA }, 503 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_HDA }, 504 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ADL_N_HDA }, 505 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MTL_HDA }, 506}; 507 508int 509azalia_pci_match(struct device *parent, void *match, void *aux) 510{ 511 struct pci_attach_args *pa; 512 513 pa = aux; 514 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MULTIMEDIA 515 && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MULTIMEDIA_HDAUDIO) 516 return 1; 517 return pci_matchbyid((struct pci_attach_args *)aux, azalia_pci_devices, 518 nitems(azalia_pci_devices)); 519} 520 521void 522azalia_pci_attach(struct device *parent, struct device *self, void *aux) 523{ 524 azalia_t *sc; 525 struct pci_attach_args *pa; 526 pcireg_t v; 527 uint8_t reg; 528 pci_intr_handle_t ih; 529 const char *interrupt_str; 530 531 sc = (azalia_t*)self; 532 pa = aux; 533 534 sc->dmat = pa->pa_dmat; 535 536 pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); 537 538 v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_PCI_HDBARL); 539 v &= PCI_MAPREG_TYPE_MASK | PCI_MAPREG_MEM_TYPE_MASK; 540 if (pci_mapreg_map(pa, ICH_PCI_HDBARL, v, 0, 541 &sc->iot, &sc->ioh, NULL, &sc->map_size, 0)) { 542 printf(": can't map device i/o space\n"); 543 return; 544 } 545 546 sc->pc = pa->pa_pc; 547 sc->tag = pa->pa_tag; 548 sc->pciid = pa->pa_id; 549 sc->subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 550 551 azalia_configure_pci(sc); 552 553 /* disable MSI, use INTx instead */ 554 if (PCI_VENDOR(sc->pciid) == PCI_VENDOR_INTEL) { 555 reg = azalia_pci_read(sc->pc, sc->tag, ICH_PCI_MMC); 556 reg &= ~(ICH_PCI_MMC_ME); 557 azalia_pci_write(sc->pc, sc->tag, ICH_PCI_MMC, reg); 558 } 559 560 /* interrupt */ 561 if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) { 562 printf(": can't map interrupt\n"); 563 return; 564 } 565 interrupt_str = pci_intr_string(pa->pa_pc, ih); 566 sc->ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO | IPL_MPSAFE, 567 azalia_intr, sc, sc->dev.dv_xname); 568 if (sc->ih == NULL) { 569 printf(": can't establish interrupt"); 570 if (interrupt_str != NULL) 571 printf(" at %s", interrupt_str); 572 printf("\n"); 573 return; 574 } 575 printf(": %s\n", interrupt_str); 576 577 if (azalia_init(sc, 0)) 578 goto err_exit; 579 580 if (azalia_init_codecs(sc)) 581 goto err_exit; 582 583 if (azalia_init_streams(sc)) 584 goto err_exit; 585 586 audio_attach_mi(&azalia_hw_if, sc, NULL, &sc->dev); 587 588 return; 589 590err_exit: 591 sc->detached = 1; 592 azalia_pci_detach(self, 0); 593} 594 595int 596azalia_pci_activate(struct device *self, int act) 597{ 598 azalia_t *sc = (azalia_t*)self; 599 int rv = 0; 600 601 switch (act) { 602 case DVACT_SUSPEND: 603 azalia_suspend(sc); 604 break; 605 case DVACT_POWERDOWN: 606 azalia_shutdown(sc); 607 break; 608 case DVACT_RESUME: 609 azalia_resume(sc); 610 rv = config_activate_children(self, act); 611 break; 612 default: 613 rv = config_activate_children(self, act); 614 break; 615 } 616 return (rv); 617} 618 619int 620azalia_pci_detach(struct device *self, int flags) 621{ 622 azalia_t *az = (azalia_t*)self; 623 uint32_t gctl; 624 int i; 625 626 DPRINTF(("%s\n", __func__)); 627 628 /* 629 * this function is called if the device could not be supported, 630 * in which case az->detached == 1. check if this function has 631 * already cleaned up. 632 */ 633 if (az->detached > 1) 634 return 0; 635 636 config_detach_children(self, flags); 637 638 /* disable unsolicited responses if soft detaching */ 639 if (az->detached == 1) { 640 gctl = AZ_READ_4(az, GCTL); 641 AZ_WRITE_4(az, GCTL, gctl &~(HDA_GCTL_UNSOL)); 642 } 643 644 timeout_del(&az->unsol_to); 645 646 DPRINTF(("%s: delete streams\n", __func__)); 647 if (az->rstream.bdlist.addr != NULL) 648 azalia_free_dmamem(az, &az->rstream.bdlist); 649 if (az->pstream.bdlist.addr != NULL) 650 azalia_free_dmamem(az, &az->pstream.bdlist); 651 652 DPRINTF(("%s: delete codecs\n", __func__)); 653 for (i = 0; i < az->ncodecs; i++) { 654 azalia_codec_delete(&az->codecs[i]); 655 } 656 az->ncodecs = 0; 657 if (az->codecs != NULL) { 658 free(az->codecs, M_DEVBUF, 0); 659 az->codecs = NULL; 660 } 661 662 DPRINTF(("%s: delete CORB and RIRB\n", __func__)); 663 if (az->corb_dma.addr != NULL) 664 azalia_free_dmamem(az, &az->corb_dma); 665 if (az->rirb_dma.addr != NULL) 666 azalia_free_dmamem(az, &az->rirb_dma); 667 if (az->unsolq != NULL) { 668 free(az->unsolq, M_DEVBUF, 0); 669 az->unsolq = NULL; 670 } 671 672 /* disable interrupts if soft detaching */ 673 if (az->detached == 1) { 674 DPRINTF(("%s: disable interrupts\n", __func__)); 675 AZ_WRITE_4(az, INTCTL, 0); 676 677 DPRINTF(("%s: clear interrupts\n", __func__)); 678 AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE); 679 AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS); 680 } 681 682 DPRINTF(("%s: delete PCI resources\n", __func__)); 683 if (az->ih != NULL) { 684 pci_intr_disestablish(az->pc, az->ih); 685 az->ih = NULL; 686 } 687 if (az->map_size != 0) { 688 bus_space_unmap(az->iot, az->ioh, az->map_size); 689 az->map_size = 0; 690 } 691 692 az->detached = 2; 693 return 0; 694} 695 696int 697azalia_intr(void *v) 698{ 699 azalia_t *az = v; 700 uint32_t intsts; 701 int ret = 0; 702 703 mtx_enter(&audio_lock); 704 for (;;) { 705 intsts = AZ_READ_4(az, INTSTS); 706 if ((intsts & az->intctl) == 0 || intsts == 0xffffffff) 707 break; 708 709 if (intsts & az->pstream.intr_bit) { 710 azalia_stream_intr(&az->pstream); 711 ret = 1; 712 } 713 714 if (intsts & az->rstream.intr_bit) { 715 azalia_stream_intr(&az->rstream); 716 ret = 1; 717 } 718 719 if ((intsts & HDA_INTSTS_CIS) && 720 (AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RINTCTL) && 721 (AZ_READ_1(az, RIRBSTS) & HDA_RIRBSTS_RINTFL)) { 722 azalia_rirb_intr(az); 723 ret = 1; 724 } 725 } 726 mtx_leave(&audio_lock); 727 return (ret); 728} 729 730void 731azalia_shutdown(void *v) 732{ 733 azalia_t *az = (azalia_t *)v; 734 uint32_t gctl; 735 736 if (az->detached) 737 return; 738 739 /* disable unsolicited response */ 740 gctl = AZ_READ_4(az, GCTL); 741 AZ_WRITE_4(az, GCTL, gctl & ~(HDA_GCTL_UNSOL)); 742 743 timeout_del(&az->unsol_to); 744 745 /* halt CORB/RIRB */ 746 azalia_halt_corb(az); 747 azalia_halt_rirb(az); 748} 749 750/* ================================================================ 751 * HDA controller functions 752 * ================================================================ */ 753 754void 755azalia_print_codec(codec_t *codec) 756{ 757 const char *vendor; 758 759 if (codec->name == NULL) { 760 vendor = pci_findvendor(codec->vid >> 16); 761 if (vendor == NULL) 762 printf("0x%04x/0x%04x", 763 codec->vid >> 16, codec->vid & 0xffff); 764 else 765 printf("%s/0x%04x", vendor, codec->vid & 0xffff); 766 } else 767 printf("%s", codec->name); 768} 769 770int 771azalia_reset(azalia_t *az) 772{ 773 uint32_t gctl; 774 int i; 775 776 /* 4.2.2 Starting the High Definition Audio Controller */ 777 DPRINTF(("%s: resetting\n", __func__)); 778 gctl = AZ_READ_4(az, GCTL); 779 AZ_WRITE_4(az, GCTL, gctl & ~HDA_GCTL_CRST); 780 for (i = 5000; i > 0; i--) { 781 DELAY(10); 782 if ((AZ_READ_4(az, GCTL) & HDA_GCTL_CRST) == 0) 783 break; 784 } 785 DPRINTF(("%s: reset counter = %d\n", __func__, i)); 786 if (i == 0) { 787 DPRINTF(("%s: reset failure\n", XNAME(az))); 788 return(ETIMEDOUT); 789 } 790 DELAY(1000); 791 gctl = AZ_READ_4(az, GCTL); 792 AZ_WRITE_4(az, GCTL, gctl | HDA_GCTL_CRST); 793 for (i = 5000; i > 0; i--) { 794 DELAY(10); 795 if (AZ_READ_4(az, GCTL) & HDA_GCTL_CRST) 796 break; 797 } 798 DPRINTF(("%s: reset counter = %d\n", __func__, i)); 799 if (i == 0) { 800 DPRINTF(("%s: reset-exit failure\n", XNAME(az))); 801 return(ETIMEDOUT); 802 } 803 DELAY(1000); 804 805 return(0); 806} 807 808int 809azalia_get_ctrlr_caps(azalia_t *az) 810{ 811 int i, n; 812 uint16_t gcap; 813 uint16_t statests; 814 uint8_t cap; 815 816 DPRINTF(("%s: host: High Definition Audio rev. %d.%d\n", 817 XNAME(az), AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN))); 818 gcap = AZ_READ_2(az, GCAP); 819 az->nistreams = HDA_GCAP_ISS(gcap); 820 az->nostreams = HDA_GCAP_OSS(gcap); 821 az->nbstreams = HDA_GCAP_BSS(gcap); 822 az->ok64 = (gcap & HDA_GCAP_64OK) != 0; 823 DPRINTF(("%s: host: %d output, %d input, and %d bidi streams\n", 824 XNAME(az), az->nostreams, az->nistreams, az->nbstreams)); 825 826 /* 4.3 Codec discovery */ 827 statests = AZ_READ_2(az, STATESTS); 828 for (i = 0, n = 0; i < HDA_MAX_CODECS; i++) { 829 if ((statests >> i) & 1) { 830 DPRINTF(("%s: found a codec at #%d\n", XNAME(az), i)); 831 n++; 832 } 833 } 834 az->ncodecs = n; 835 if (az->ncodecs < 1) { 836 printf("%s: no HD-Audio codecs\n", XNAME(az)); 837 return -1; 838 } 839 az->codecs = mallocarray(az->ncodecs, sizeof(codec_t), M_DEVBUF, 840 M_NOWAIT | M_ZERO); 841 if (az->codecs == NULL) { 842 printf("%s: can't allocate memory for codecs\n", XNAME(az)); 843 return ENOMEM; 844 } 845 for (i = 0, n = 0; n < az->ncodecs; i++) { 846 if ((statests >> i) & 1) { 847 az->codecs[n].address = i; 848 az->codecs[n++].az = az; 849 } 850 } 851 852 /* determine CORB size */ 853 az->corbsize = AZ_READ_1(az, CORBSIZE); 854 cap = az->corbsize & HDA_CORBSIZE_CORBSZCAP_MASK; 855 az->corbsize &= ~HDA_CORBSIZE_CORBSIZE_MASK; 856 if (cap & HDA_CORBSIZE_CORBSZCAP_256) { 857 az->corb_entries = 256; 858 az->corbsize |= HDA_CORBSIZE_CORBSIZE_256; 859 } else if (cap & HDA_CORBSIZE_CORBSZCAP_16) { 860 az->corb_entries = 16; 861 az->corbsize |= HDA_CORBSIZE_CORBSIZE_16; 862 } else if (cap & HDA_CORBSIZE_CORBSZCAP_2) { 863 az->corb_entries = 2; 864 az->corbsize |= HDA_CORBSIZE_CORBSIZE_2; 865 } else { 866 printf("%s: invalid CORBSZCAP: 0x%2x\n", XNAME(az), cap); 867 return(-1); 868 } 869 870 /* determine RIRB size */ 871 az->rirbsize = AZ_READ_1(az, RIRBSIZE); 872 cap = az->rirbsize & HDA_RIRBSIZE_RIRBSZCAP_MASK; 873 az->rirbsize &= ~HDA_RIRBSIZE_RIRBSIZE_MASK; 874 if (cap & HDA_RIRBSIZE_RIRBSZCAP_256) { 875 az->rirb_entries = 256; 876 az->rirbsize |= HDA_RIRBSIZE_RIRBSIZE_256; 877 } else if (cap & HDA_RIRBSIZE_RIRBSZCAP_16) { 878 az->rirb_entries = 16; 879 az->rirbsize |= HDA_RIRBSIZE_RIRBSIZE_16; 880 } else if (cap & HDA_RIRBSIZE_RIRBSZCAP_2) { 881 az->rirb_entries = 2; 882 az->rirbsize |= HDA_RIRBSIZE_RIRBSIZE_2; 883 } else { 884 printf("%s: invalid RIRBSZCAP: 0x%2x\n", XNAME(az), cap); 885 return(-1); 886 } 887 888 return(0); 889} 890 891int 892azalia_init(azalia_t *az, int resuming) 893{ 894 int err; 895 896 err = azalia_reset(az); 897 if (err) 898 return(err); 899 900 if (!resuming) { 901 err = azalia_get_ctrlr_caps(az); 902 if (err) 903 return(err); 904 } 905 906 /* clear interrupt status */ 907 AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE); 908 AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS); 909 AZ_WRITE_4(az, DPLBASE, 0); 910 AZ_WRITE_4(az, DPUBASE, 0); 911 912 /* 4.4.1 Command Outbound Ring Buffer */ 913 err = azalia_init_corb(az, resuming); 914 if (err) 915 return(err); 916 917 /* 4.4.2 Response Inbound Ring Buffer */ 918 err = azalia_init_rirb(az, resuming); 919 if (err) 920 return(err); 921 922 az->intctl = HDA_INTCTL_CIE | HDA_INTCTL_GIE; 923 AZ_WRITE_4(az, INTCTL, az->intctl); 924 925 return(0); 926} 927 928int 929azalia_init_codecs(azalia_t *az) 930{ 931 codec_t *codec; 932 int c, i; 933 934 c = 0; 935 for (i = 0; i < az->ncodecs; i++) { 936 if (!azalia_codec_init(&az->codecs[i])) 937 c++; 938 } 939 if (c == 0) { 940 printf("%s: No codecs found\n", XNAME(az)); 941 return(1); 942 } 943 944 /* Use the first codec capable of analog I/O. If there are none, 945 * use the first codec capable of digital I/O. Skip HDMI codecs. 946 */ 947 c = -1; 948 for (i = 0; i < az->ncodecs; i++) { 949 codec = &az->codecs[i]; 950 if ((codec->audiofunc < 0) || 951 (codec->codec_type == AZ_CODEC_TYPE_HDMI)) 952 continue; 953 if (codec->codec_type == AZ_CODEC_TYPE_DIGITAL) { 954 if (c < 0) 955 c = i; 956 } else { 957 c = i; 958 break; 959 } 960 } 961 az->codecno = c; 962 if (az->codecno < 0) { 963 printf("%s: no supported codecs\n", XNAME(az)); 964 return(1); 965 } 966 967 printf("%s: codecs: ", XNAME(az)); 968 for (i = 0; i < az->ncodecs; i++) { 969 azalia_print_codec(&az->codecs[i]); 970 if (i < az->ncodecs - 1) 971 printf(", "); 972 } 973 if (az->ncodecs > 1) { 974 printf(", using "); 975 azalia_print_codec(&az->codecs[az->codecno]); 976 } 977 printf("\n"); 978 979 /* All codecs with audio are enabled, but only one will be used. */ 980 for (i = 0; i < az->ncodecs; i++) { 981 codec = &az->codecs[i]; 982 if (i != az->codecno) { 983 if (codec->audiofunc < 0) 984 continue; 985 azalia_comresp(codec, codec->audiofunc, 986 CORB_SET_POWER_STATE, CORB_PS_D3, NULL); 987 DELAY(100); 988 azalia_codec_delete(codec); 989 } 990 } 991 992 /* Enable unsolicited responses now that az->codecno is set. */ 993 AZ_WRITE_4(az, GCTL, AZ_READ_4(az, GCTL) | HDA_GCTL_UNSOL); 994 995 return(0); 996} 997 998int 999azalia_init_streams(azalia_t *az) 1000{ 1001 int err; 1002 1003 /* Use stream#1 and #2. Don't use stream#0. */ 1004 err = azalia_stream_init(&az->pstream, az, az->nistreams + 0, 1005 1, AUMODE_PLAY); 1006 if (err) 1007 return(err); 1008 err = azalia_stream_init(&az->rstream, az, 0, 2, AUMODE_RECORD); 1009 if (err) 1010 return(err); 1011 1012 return(0); 1013} 1014 1015int 1016azalia_halt_corb(azalia_t *az) 1017{ 1018 uint8_t corbctl; 1019 codec_t *codec; 1020 int i; 1021 1022 corbctl = AZ_READ_1(az, CORBCTL); 1023 if (corbctl & HDA_CORBCTL_CORBRUN) { /* running? */ 1024 /* power off all codecs */ 1025 for (i = 0; i < az->ncodecs; i++) { 1026 codec = &az->codecs[i]; 1027 if (codec->audiofunc < 0) 1028 continue; 1029 azalia_comresp(codec, codec->audiofunc, 1030 CORB_SET_POWER_STATE, CORB_PS_D3, NULL); 1031 } 1032 1033 AZ_WRITE_1(az, CORBCTL, corbctl & ~HDA_CORBCTL_CORBRUN); 1034 for (i = 5000; i > 0; i--) { 1035 DELAY(10); 1036 corbctl = AZ_READ_1(az, CORBCTL); 1037 if ((corbctl & HDA_CORBCTL_CORBRUN) == 0) 1038 break; 1039 } 1040 if (i == 0) { 1041 DPRINTF(("%s: CORB is running\n", XNAME(az))); 1042 return EBUSY; 1043 } 1044 } 1045 return(0); 1046} 1047 1048int 1049azalia_init_corb(azalia_t *az, int resuming) 1050{ 1051 int err, i; 1052 uint16_t corbrp, corbwp; 1053 uint8_t corbctl; 1054 1055 err = azalia_halt_corb(az); 1056 if (err) 1057 return(err); 1058 1059 if (!resuming) { 1060 err = azalia_alloc_dmamem(az, 1061 az->corb_entries * sizeof(corb_entry_t), 128, 1062 &az->corb_dma); 1063 if (err) { 1064 printf("%s: can't allocate CORB buffer\n", XNAME(az)); 1065 return(err); 1066 } 1067 DPRINTF(("%s: CORB allocation succeeded.\n", __func__)); 1068 } 1069 timeout_set(&az->unsol_to, azalia_rirb_kick_unsol_events, az); 1070 1071 AZ_WRITE_4(az, CORBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->corb_dma)); 1072 AZ_WRITE_4(az, CORBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->corb_dma))); 1073 AZ_WRITE_1(az, CORBSIZE, az->corbsize); 1074 1075 /* reset CORBRP */ 1076 corbrp = AZ_READ_2(az, CORBRP); 1077 AZ_WRITE_2(az, CORBRP, corbrp | HDA_CORBRP_CORBRPRST); 1078 AZ_WRITE_2(az, CORBRP, corbrp & ~HDA_CORBRP_CORBRPRST); 1079 for (i = 5000; i > 0; i--) { 1080 DELAY(10); 1081 corbrp = AZ_READ_2(az, CORBRP); 1082 if ((corbrp & HDA_CORBRP_CORBRPRST) == 0) 1083 break; 1084 } 1085 if (i == 0) { 1086 DPRINTF(("%s: CORBRP reset failure\n", XNAME(az))); 1087 return -1; 1088 } 1089 DPRINTF(("%s: CORBWP=%d; size=%d\n", __func__, 1090 AZ_READ_2(az, CORBRP) & HDA_CORBRP_CORBRP, az->corb_entries)); 1091 1092 /* clear CORBWP */ 1093 corbwp = AZ_READ_2(az, CORBWP); 1094 AZ_WRITE_2(az, CORBWP, corbwp & ~HDA_CORBWP_CORBWP); 1095 1096 /* Run! */ 1097 corbctl = AZ_READ_1(az, CORBCTL); 1098 AZ_WRITE_1(az, CORBCTL, corbctl | HDA_CORBCTL_CORBRUN); 1099 return 0; 1100} 1101 1102int 1103azalia_halt_rirb(azalia_t *az) 1104{ 1105 int i; 1106 uint8_t rirbctl; 1107 1108 rirbctl = AZ_READ_1(az, RIRBCTL); 1109 if (rirbctl & HDA_RIRBCTL_RIRBDMAEN) { /* running? */ 1110 AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RIRBDMAEN); 1111 for (i = 5000; i > 0; i--) { 1112 DELAY(10); 1113 rirbctl = AZ_READ_1(az, RIRBCTL); 1114 if ((rirbctl & HDA_RIRBCTL_RIRBDMAEN) == 0) 1115 break; 1116 } 1117 if (i == 0) { 1118 DPRINTF(("%s: RIRB is running\n", XNAME(az))); 1119 return(EBUSY); 1120 } 1121 } 1122 return(0); 1123} 1124 1125int 1126azalia_init_rirb(azalia_t *az, int resuming) 1127{ 1128 int err, i; 1129 uint16_t rirbwp; 1130 uint8_t rirbctl; 1131 1132 err = azalia_halt_rirb(az); 1133 if (err) 1134 return(err); 1135 1136 if (!resuming) { 1137 err = azalia_alloc_dmamem(az, 1138 az->rirb_entries * sizeof(rirb_entry_t), 128, 1139 &az->rirb_dma); 1140 if (err) { 1141 printf("%s: can't allocate RIRB buffer\n", XNAME(az)); 1142 return err; 1143 } 1144 DPRINTF(("%s: RIRB allocation succeeded.\n", __func__)); 1145 1146 /* setup the unsolicited response queue */ 1147 az->unsolq = malloc(sizeof(rirb_entry_t) * UNSOLQ_SIZE, 1148 M_DEVBUF, M_NOWAIT | M_ZERO); 1149 if (az->unsolq == NULL) { 1150 DPRINTF(("%s: can't allocate unsolicited response queue.\n", 1151 XNAME(az))); 1152 azalia_free_dmamem(az, &az->rirb_dma); 1153 return ENOMEM; 1154 } 1155 } 1156 AZ_WRITE_4(az, RIRBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->rirb_dma)); 1157 AZ_WRITE_4(az, RIRBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->rirb_dma))); 1158 AZ_WRITE_1(az, RIRBSIZE, az->rirbsize); 1159 1160 /* reset the write pointer */ 1161 rirbwp = AZ_READ_2(az, RIRBWP); 1162 AZ_WRITE_2(az, RIRBWP, rirbwp | HDA_RIRBWP_RIRBWPRST); 1163 1164 /* clear the read pointer */ 1165 az->rirb_rp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP; 1166 DPRINTF(("%s: RIRBRP=%d, size=%d\n", __func__, az->rirb_rp, 1167 az->rirb_entries)); 1168 1169 az->unsolq_rp = 0; 1170 az->unsolq_wp = 0; 1171 az->unsolq_kick = 0; 1172 1173 AZ_WRITE_2(az, RINTCNT, 1); 1174 1175 /* Run! */ 1176 rirbctl = AZ_READ_1(az, RIRBCTL); 1177 AZ_WRITE_1(az, RIRBCTL, rirbctl | 1178 HDA_RIRBCTL_RIRBDMAEN | HDA_RIRBCTL_RINTCTL); 1179 for (i = 5000; i > 0; i--) { 1180 DELAY(10); 1181 rirbctl = AZ_READ_1(az, RIRBCTL); 1182 if (rirbctl & HDA_RIRBCTL_RIRBDMAEN) 1183 break; 1184 } 1185 if (i == 0) { 1186 DPRINTF(("%s: RIRB is not running\n", XNAME(az))); 1187 return(EBUSY); 1188 } 1189 1190 return (0); 1191} 1192 1193int 1194azalia_comresp(const codec_t *codec, nid_t nid, uint32_t control, 1195 uint32_t param, uint32_t* result) 1196{ 1197 int err; 1198 1199 mtx_enter(&audio_lock); 1200 err = azalia_set_command(codec->az, codec->address, nid, control, 1201 param); 1202 if (err) 1203 goto exit; 1204 err = azalia_get_response(codec->az, result); 1205exit: 1206 mtx_leave(&audio_lock); 1207 return(err); 1208} 1209 1210int 1211azalia_set_command(azalia_t *az, int caddr, nid_t nid, uint32_t control, 1212 uint32_t param) 1213{ 1214 corb_entry_t *corb; 1215 int wp; 1216 uint32_t verb; 1217 uint16_t corbwp; 1218 1219 if ((AZ_READ_1(az, CORBCTL) & HDA_CORBCTL_CORBRUN) == 0) { 1220 printf("%s: CORB is not running.\n", XNAME(az)); 1221 return(-1); 1222 } 1223 verb = (caddr << 28) | (nid << 20) | (control << 8) | param; 1224 corbwp = AZ_READ_2(az, CORBWP); 1225 wp = corbwp & HDA_CORBWP_CORBWP; 1226 corb = (corb_entry_t*)az->corb_dma.addr; 1227 if (++wp >= az->corb_entries) 1228 wp = 0; 1229 corb[wp] = verb; 1230 1231 AZ_WRITE_2(az, CORBWP, (corbwp & ~HDA_CORBWP_CORBWP) | wp); 1232 1233 return(0); 1234} 1235 1236int 1237azalia_get_response(azalia_t *az, uint32_t *result) 1238{ 1239 const rirb_entry_t *rirb; 1240 int i; 1241 uint16_t wp; 1242 1243 if ((AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RIRBDMAEN) == 0) { 1244 printf("%s: RIRB is not running.\n", XNAME(az)); 1245 return(-1); 1246 } 1247 1248 rirb = (rirb_entry_t*)az->rirb_dma.addr; 1249 i = 5000; 1250 for (;;) { 1251 while (i > 0) { 1252 wp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP; 1253 if (az->rirb_rp != wp) 1254 break; 1255 DELAY(10); 1256 i--; 1257 } 1258 if (i == 0) { 1259 DPRINTF(("%s: RIRB time out\n", XNAME(az))); 1260 return(ETIMEDOUT); 1261 } 1262 if (++az->rirb_rp >= az->rirb_entries) 1263 az->rirb_rp = 0; 1264 if (rirb[az->rirb_rp].resp_ex & RIRB_RESP_UNSOL) { 1265 az->unsolq[az->unsolq_wp].resp = rirb[az->rirb_rp].resp; 1266 az->unsolq[az->unsolq_wp++].resp_ex = rirb[az->rirb_rp].resp_ex; 1267 az->unsolq_wp %= UNSOLQ_SIZE; 1268 } else 1269 break; 1270 } 1271 if (result != NULL) 1272 *result = rirb[az->rirb_rp].resp; 1273 1274 return(0); 1275} 1276 1277void 1278azalia_rirb_kick_unsol_events(void *v) 1279{ 1280 azalia_t *az = v; 1281 int addr, tag; 1282 1283 if (az->unsolq_kick) 1284 return; 1285 az->unsolq_kick = 1; 1286 while (az->unsolq_rp != az->unsolq_wp) { 1287 addr = RIRB_RESP_CODEC(az->unsolq[az->unsolq_rp].resp_ex); 1288 tag = RIRB_UNSOL_TAG(az->unsolq[az->unsolq_rp].resp); 1289 DPRINTF(("%s: codec address=%d tag=%d\n", __func__, addr, tag)); 1290 1291 az->unsolq_rp++; 1292 az->unsolq_rp %= UNSOLQ_SIZE; 1293 1294 /* We only care about events on the using codec. */ 1295 if (az->codecs[az->codecno].address == addr) 1296 azalia_unsol_event(&az->codecs[az->codecno], tag); 1297 } 1298 az->unsolq_kick = 0; 1299} 1300 1301void 1302azalia_rirb_intr(azalia_t *az) 1303{ 1304 const rirb_entry_t *rirb; 1305 uint16_t wp; 1306 uint8_t rirbsts; 1307 1308 rirbsts = AZ_READ_1(az, RIRBSTS); 1309 1310 wp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP; 1311 rirb = (rirb_entry_t*)az->rirb_dma.addr; 1312 while (az->rirb_rp != wp) { 1313 if (++az->rirb_rp >= az->rirb_entries) 1314 az->rirb_rp = 0; 1315 if (rirb[az->rirb_rp].resp_ex & RIRB_RESP_UNSOL) { 1316 az->unsolq[az->unsolq_wp].resp = rirb[az->rirb_rp].resp; 1317 az->unsolq[az->unsolq_wp++].resp_ex = rirb[az->rirb_rp].resp_ex; 1318 az->unsolq_wp %= UNSOLQ_SIZE; 1319 } else { 1320 DPRINTF(("%s: dropped solicited response\n", __func__)); 1321 } 1322 } 1323 timeout_add_msec(&az->unsol_to, 1); 1324 1325 AZ_WRITE_1(az, RIRBSTS, 1326 rirbsts | HDA_RIRBSTS_RIRBOIS | HDA_RIRBSTS_RINTFL); 1327} 1328 1329int 1330azalia_alloc_dmamem(azalia_t *az, size_t size, size_t align, azalia_dma_t *d) 1331{ 1332 int err; 1333 int nsegs; 1334 1335 d->size = size; 1336 err = bus_dmamem_alloc(az->dmat, size, align, 0, d->segments, 1, 1337 &nsegs, BUS_DMA_NOWAIT); 1338 if (err) 1339 return err; 1340 if (nsegs != 1) 1341 goto free; 1342 err = bus_dmamem_map(az->dmat, d->segments, 1, size, 1343 &d->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 1344 if (err) 1345 goto free; 1346 err = bus_dmamap_create(az->dmat, size, 1, size, 0, 1347 BUS_DMA_NOWAIT, &d->map); 1348 if (err) 1349 goto unmap; 1350 err = bus_dmamap_load(az->dmat, d->map, d->addr, size, 1351 NULL, BUS_DMA_NOWAIT); 1352 if (err) 1353 goto destroy; 1354 1355 if (!az->ok64 && PTR_UPPER32(AZALIA_DMA_DMAADDR(d)) != 0) { 1356 azalia_free_dmamem(az, d); 1357 return -1; 1358 } 1359 return 0; 1360 1361destroy: 1362 bus_dmamap_destroy(az->dmat, d->map); 1363unmap: 1364 bus_dmamem_unmap(az->dmat, d->addr, size); 1365free: 1366 bus_dmamem_free(az->dmat, d->segments, 1); 1367 d->addr = NULL; 1368 return err; 1369} 1370 1371void 1372azalia_free_dmamem(const azalia_t *az, azalia_dma_t* d) 1373{ 1374 if (d->addr == NULL) 1375 return; 1376 bus_dmamap_unload(az->dmat, d->map); 1377 bus_dmamap_destroy(az->dmat, d->map); 1378 bus_dmamem_unmap(az->dmat, d->addr, d->size); 1379 bus_dmamem_free(az->dmat, d->segments, 1); 1380 d->addr = NULL; 1381} 1382 1383int 1384azalia_suspend(azalia_t *az) 1385{ 1386 int err; 1387 1388 if (az->detached) 1389 return 0; 1390 1391 /* disable unsolicited responses */ 1392 AZ_WRITE_4(az, GCTL, AZ_READ_4(az, GCTL) & ~HDA_GCTL_UNSOL); 1393 1394 timeout_del(&az->unsol_to); 1395 1396 /* azalia_halt_{corb,rirb}() only fail if the {CORB,RIRB} can't 1397 * be stopped and azalia_init_{corb,rirb}(), which starts the 1398 * {CORB,RIRB}, first calls azalia_halt_{corb,rirb}(). If halt 1399 * fails, don't try to restart. 1400 */ 1401 err = azalia_halt_corb(az); 1402 if (err) 1403 goto corb_fail; 1404 1405 err = azalia_halt_rirb(az); 1406 if (err) 1407 goto rirb_fail; 1408 1409 /* stop interrupts and clear status registers */ 1410 AZ_WRITE_4(az, INTCTL, 0); 1411 AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE); 1412 AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS); 1413 1414 return 0; 1415 1416rirb_fail: 1417 azalia_init_corb(az, 1); 1418corb_fail: 1419 AZ_WRITE_4(az, GCTL, AZ_READ_4(az, GCTL) | HDA_GCTL_UNSOL); 1420 1421 return err; 1422} 1423 1424int 1425azalia_resume_codec(codec_t *this) 1426{ 1427 widget_t *w; 1428 uint32_t result; 1429 int i, err; 1430 1431 err = azalia_comresp(this, this->audiofunc, CORB_SET_POWER_STATE, 1432 CORB_PS_D0, &result); 1433 if (err) { 1434 DPRINTF(("%s: power audio func error: result=0x%8.8x\n", 1435 __func__, result)); 1436 } 1437 DELAY(100); 1438 1439 if (this->qrks & AZ_QRK_DOLBY_ATMOS) 1440 azalia_codec_init_dolby_atmos(this); 1441 1442 FOR_EACH_WIDGET(this, i) { 1443 w = &this->w[i]; 1444 if (w->widgetcap & COP_AWCAP_POWER) { 1445 azalia_comresp(this, w->nid, CORB_SET_POWER_STATE, 1446 CORB_PS_D0, &result); 1447 DELAY(100); 1448 } 1449 if (w->type == COP_AWTYPE_PIN_COMPLEX) 1450 azalia_widget_init_pin(w, this); 1451 if (this->qrks & AZ_QRK_WID_MASK) 1452 azalia_codec_widget_quirks(this, w->nid); 1453 } 1454 1455 if (this->qrks & AZ_QRK_GPIO_MASK) { 1456 err = azalia_codec_gpio_quirks(this); 1457 if (err) 1458 return err; 1459 } 1460 1461 return(0); 1462} 1463 1464int 1465azalia_resume(azalia_t *az) 1466{ 1467 int err; 1468 1469 if (az->detached) 1470 return 0; 1471 1472 azalia_configure_pci(az); 1473 1474 /* is this necessary? */ 1475 pci_conf_write(az->pc, az->tag, PCI_SUBSYS_ID_REG, az->subid); 1476 1477 err = azalia_init(az, 1); 1478 if (err) 1479 return err; 1480 1481 /* enable unsolicited responses on the controller */ 1482 AZ_WRITE_4(az, GCTL, AZ_READ_4(az, GCTL) | HDA_GCTL_UNSOL); 1483 1484 err = azalia_resume_codec(&az->codecs[az->codecno]); 1485 if (err) 1486 return err; 1487 1488 err = azalia_codec_enable_unsol(&az->codecs[az->codecno]); 1489 if (err) 1490 return err; 1491 1492 return 0; 1493} 1494 1495/* ================================================================ 1496 * HDA codec functions 1497 * ================================================================ */ 1498 1499int 1500azalia_codec_init(codec_t *this) 1501{ 1502 widget_t *w; 1503 uint32_t rev, id, result; 1504 int err, addr, n, i, nspdif, nhdmi; 1505 1506 addr = this->address; 1507 /* codec vendor/device/revision */ 1508 err = azalia_comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER, 1509 COP_REVISION_ID, &rev); 1510 if (err) 1511 return err; 1512 err = azalia_comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER, 1513 COP_VENDOR_ID, &id); 1514 if (err) 1515 return err; 1516 this->vid = id; 1517 this->subid = this->az->subid; 1518 azalia_codec_init_vtbl(this); 1519 DPRINTF(("%s: codec[%d] vid 0x%8.8x, subid 0x%8.8x, rev. %u.%u,", 1520 XNAME(this->az), addr, this->vid, this->subid, 1521 COP_RID_REVISION(rev), COP_RID_STEPPING(rev))); 1522 DPRINTF((" HDA version %u.%u\n", 1523 COP_RID_MAJ(rev), COP_RID_MIN(rev))); 1524 1525 /* identify function nodes */ 1526 err = azalia_comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER, 1527 COP_SUBORDINATE_NODE_COUNT, &result); 1528 if (err) 1529 return err; 1530 this->nfunctions = COP_NSUBNODES(result); 1531 if (COP_NSUBNODES(result) <= 0) { 1532 DPRINTF(("%s: codec[%d]: No function groups\n", 1533 XNAME(this->az), addr)); 1534 return -1; 1535 } 1536 /* iterate function nodes and find an audio function */ 1537 n = COP_START_NID(result); 1538 DPRINTF(("%s: nidstart=%d #functions=%d\n", 1539 XNAME(this->az), n, this->nfunctions)); 1540 this->audiofunc = -1; 1541 for (i = 0; i < this->nfunctions; i++) { 1542 err = azalia_comresp(this, n + i, CORB_GET_PARAMETER, 1543 COP_FUNCTION_GROUP_TYPE, &result); 1544 if (err) 1545 continue; 1546 DPRINTF(("%s: FTYPE result = 0x%8.8x\n", __func__, result)); 1547 if (COP_FTYPE(result) == COP_FTYPE_AUDIO) { 1548 this->audiofunc = n + i; 1549 break; /* XXX multiple audio functions? */ 1550 } 1551 } 1552 if (this->audiofunc < 0) { 1553 DPRINTF(("%s: codec[%d]: No audio function groups\n", 1554 XNAME(this->az), addr)); 1555 return -1; 1556 } 1557 1558 /* power the audio function */ 1559 azalia_comresp(this, this->audiofunc, CORB_SET_POWER_STATE, 1560 CORB_PS_D0, &result); 1561 DELAY(100); 1562 1563 /* check widgets in the audio function */ 1564 err = azalia_comresp(this, this->audiofunc, CORB_GET_PARAMETER, 1565 COP_SUBORDINATE_NODE_COUNT, &result); 1566 if (err) 1567 return err; 1568 DPRINTF(("%s: There are %d widgets in the audio function.\n", 1569 __func__, COP_NSUBNODES(result))); 1570 this->wstart = COP_START_NID(result); 1571 if (this->wstart < 2) { 1572 printf("%s: invalid node structure\n", XNAME(this->az)); 1573 return -1; 1574 } 1575 this->wend = this->wstart + COP_NSUBNODES(result); 1576 this->w = mallocarray(this->wend, sizeof(widget_t), M_DEVBUF, 1577 M_NOWAIT | M_ZERO); 1578 if (this->w == NULL) { 1579 printf("%s: out of memory\n", XNAME(this->az)); 1580 return ENOMEM; 1581 } 1582 1583 if (this->qrks & AZ_QRK_DOLBY_ATMOS) 1584 azalia_codec_init_dolby_atmos(this); 1585 1586 /* query the base parameters */ 1587 azalia_comresp(this, this->audiofunc, CORB_GET_PARAMETER, 1588 COP_STREAM_FORMATS, &result); 1589 this->w[this->audiofunc].d.audio.encodings = result; 1590 azalia_comresp(this, this->audiofunc, CORB_GET_PARAMETER, 1591 COP_PCM, &result); 1592 this->w[this->audiofunc].d.audio.bits_rates = result; 1593 azalia_comresp(this, this->audiofunc, CORB_GET_PARAMETER, 1594 COP_INPUT_AMPCAP, &result); 1595 this->w[this->audiofunc].inamp_cap = result; 1596 azalia_comresp(this, this->audiofunc, CORB_GET_PARAMETER, 1597 COP_OUTPUT_AMPCAP, &result); 1598 this->w[this->audiofunc].outamp_cap = result; 1599 1600 azalia_codec_print_audiofunc(this); 1601 1602 strlcpy(this->w[CORB_NID_ROOT].name, "root", 1603 sizeof(this->w[CORB_NID_ROOT].name)); 1604 strlcpy(this->w[this->audiofunc].name, "hdaudio", 1605 sizeof(this->w[this->audiofunc].name)); 1606 this->w[this->audiofunc].enable = 1; 1607 1608 FOR_EACH_WIDGET(this, i) { 1609 w = &this->w[i]; 1610 err = azalia_widget_init(w, this, i); 1611 if (err) 1612 return err; 1613 err = azalia_widget_init_connection(w, this); 1614 if (err) 1615 return err; 1616 1617 azalia_widget_print_widget(w, this); 1618 1619 if (this->qrks & AZ_QRK_WID_MASK) { 1620 azalia_codec_widget_quirks(this, i); 1621 } 1622 } 1623 1624 this->na_dacs = this->na_dacs_d = 0; 1625 this->na_adcs = this->na_adcs_d = 0; 1626 this->speaker = this->speaker2 = this->spkr_dac = 1627 this->fhp = this->fhp_dac = 1628 this->mic = this->mic_adc = -1; 1629 this->nsense_pins = 0; 1630 this->nout_jacks = 0; 1631 nspdif = nhdmi = 0; 1632 FOR_EACH_WIDGET(this, i) { 1633 w = &this->w[i]; 1634 1635 if (!w->enable) 1636 continue; 1637 1638 switch (w->type) { 1639 1640 case COP_AWTYPE_AUDIO_MIXER: 1641 case COP_AWTYPE_AUDIO_SELECTOR: 1642 if (!azalia_widget_check_conn(this, i, 0)) 1643 w->enable = 0; 1644 break; 1645 1646 case COP_AWTYPE_AUDIO_OUTPUT: 1647 if ((w->widgetcap & COP_AWCAP_DIGITAL) == 0) { 1648 if (this->na_dacs < HDA_MAX_CHANNELS) 1649 this->a_dacs[this->na_dacs++] = i; 1650 } else { 1651 if (this->na_dacs_d < HDA_MAX_CHANNELS) 1652 this->a_dacs_d[this->na_dacs_d++] = i; 1653 } 1654 break; 1655 1656 case COP_AWTYPE_AUDIO_INPUT: 1657 if ((w->widgetcap & COP_AWCAP_DIGITAL) == 0) { 1658 if (this->na_adcs < HDA_MAX_CHANNELS) 1659 this->a_adcs[this->na_adcs++] = i; 1660 } else { 1661 if (this->na_adcs_d < HDA_MAX_CHANNELS) 1662 this->a_adcs_d[this->na_adcs_d++] = i; 1663 } 1664 break; 1665 1666 case COP_AWTYPE_PIN_COMPLEX: 1667 switch (CORB_CD_PORT(w->d.pin.config)) { 1668 case CORB_CD_FIXED: 1669 switch (w->d.pin.device) { 1670 case CORB_CD_SPEAKER: 1671 if (this->speaker == -1) { 1672 this->speaker = i; 1673 } else if (w->d.pin.association < 1674 this->w[this->speaker].d.pin.association || 1675 (w->d.pin.association == 1676 this->w[this->speaker].d.pin.association && 1677 w->d.pin.sequence < 1678 this->w[this->speaker].d.pin.sequence)) { 1679 this->speaker2 = this->speaker; 1680 this->speaker = i; 1681 } else { 1682 this->speaker2 = i; 1683 } 1684 if (this->speaker == i) 1685 this->spkr_dac = 1686 azalia_codec_find_defdac(this, i, 0); 1687 break; 1688 case CORB_CD_MICIN: 1689 this->mic = i; 1690 this->mic_adc = 1691 azalia_codec_find_defadc(this, i, 0); 1692 break; 1693 } 1694 break; 1695 case CORB_CD_JACK: 1696 if (w->d.pin.device == CORB_CD_LINEOUT) 1697 this->nout_jacks++; 1698 else if (w->d.pin.device == CORB_CD_HEADPHONE && 1699 CORB_CD_LOC_GEO(w->d.pin.config) == 1700 CORB_CD_FRONT) { 1701 this->fhp = i; 1702 this->fhp_dac = 1703 azalia_codec_find_defdac(this, i, 0); 1704 } 1705 if (this->nsense_pins >= HDA_MAX_SENSE_PINS || 1706 !(w->d.pin.cap & COP_PINCAP_PRESENCE)) 1707 break; 1708 /* check override bit */ 1709 err = azalia_comresp(this, i, 1710 CORB_GET_CONFIGURATION_DEFAULT, 0, &result); 1711 if (err) 1712 break; 1713 if (!(CORB_CD_MISC(result) & CORB_CD_PRESENCEOV)) { 1714 this->sense_pins[this->nsense_pins++] = i; 1715 } 1716 break; 1717 } 1718 if ((w->d.pin.device == CORB_CD_DIGITALOUT) && 1719 (w->d.pin.cap & COP_PINCAP_HDMI)) 1720 nhdmi++; 1721 else if (w->d.pin.device == CORB_CD_SPDIFOUT || 1722 w->d.pin.device == CORB_CD_SPDIFIN) 1723 nspdif++; 1724 break; 1725 } 1726 } 1727 this->codec_type = AZ_CODEC_TYPE_ANALOG; 1728 if ((this->na_dacs == 0) && (this->na_adcs == 0)) { 1729 this->codec_type = AZ_CODEC_TYPE_DIGITAL; 1730 if (nspdif == 0 && nhdmi > 0) 1731 this->codec_type = AZ_CODEC_TYPE_HDMI; 1732 } 1733 1734 /* make sure built-in mic is connected to an adc */ 1735 if (this->mic != -1 && this->mic_adc == -1) { 1736 if (azalia_codec_select_micadc(this)) { 1737 DPRINTF(("%s: could not select mic adc\n", __func__)); 1738 } 1739 } 1740 1741 err = azalia_codec_sort_pins(this); 1742 if (err) 1743 return err; 1744 1745 err = azalia_codec_find_inputmixer(this); 1746 if (err) 1747 return err; 1748 1749 /* If the codec can do multichannel, select different DACs for 1750 * the multichannel jack group. Also be sure to keep track of 1751 * which DAC the front headphone is connected to. 1752 */ 1753 if (this->na_dacs >= 3 && this->nopins >= 3) { 1754 err = azalia_codec_select_dacs(this); 1755 if (err) 1756 return err; 1757 } 1758 1759 err = azalia_codec_select_spkrdac(this); 1760 if (err) 1761 return err; 1762 1763 err = azalia_init_dacgroup(this); 1764 if (err) 1765 return err; 1766 1767 azalia_codec_print_groups(this); 1768 1769 err = azalia_widget_label_widgets(this); 1770 if (err) 1771 return err; 1772 1773 err = azalia_codec_construct_format(this, 0, 0); 1774 if (err) 1775 return err; 1776 1777 err = azalia_codec_init_volgroups(this); 1778 if (err) 1779 return err; 1780 1781 if (this->qrks & AZ_QRK_GPIO_MASK) { 1782 err = azalia_codec_gpio_quirks(this); 1783 if (err) 1784 return err; 1785 } 1786 1787 err = azalia_mixer_init(this); 1788 if (err) 1789 return err; 1790 1791 return 0; 1792} 1793 1794int 1795azalia_codec_find_inputmixer(codec_t *this) 1796{ 1797 widget_t *w; 1798 int i, j; 1799 1800 this->input_mixer = -1; 1801 1802 FOR_EACH_WIDGET(this, i) { 1803 w = &this->w[i]; 1804 if (w->type != COP_AWTYPE_AUDIO_MIXER) 1805 continue; 1806 1807 /* can input from a pin */ 1808 for (j = 0; j < this->nipins; j++) { 1809 if (azalia_codec_fnode(this, this->ipins[j].nid, 1810 w->nid, 0) != -1) 1811 break; 1812 } 1813 if (j == this->nipins) 1814 continue; 1815 1816 /* can output to a pin */ 1817 for (j = 0; j < this->nopins; j++) { 1818 if (azalia_codec_fnode(this, w->nid, 1819 this->opins[j].nid, 0) != -1) 1820 break; 1821 } 1822 if (j == this->nopins) 1823 continue; 1824 1825 /* can output to an ADC */ 1826 for (j = 0; j < this->na_adcs; j++) { 1827 if (azalia_codec_fnode(this, w->nid, 1828 this->a_adcs[j], 0) != -1) 1829 break; 1830 } 1831 if (j == this->na_adcs) 1832 continue; 1833 1834 this->input_mixer = i; 1835 break; 1836 } 1837 return(0); 1838} 1839 1840int 1841azalia_codec_select_micadc(codec_t *this) 1842{ 1843 widget_t *w; 1844 int i, j, conv, err; 1845 1846 for (i = 0; i < this->na_adcs; i++) { 1847 if (azalia_codec_fnode(this, this->mic, 1848 this->a_adcs[i], 0) >= 0) 1849 break; 1850 } 1851 if (i >= this->na_adcs) 1852 return(-1); 1853 conv = this->a_adcs[i]; 1854 1855 w = &this->w[conv]; 1856 for (j = 0; j < 10; j++) { 1857 for (i = 0; i < w->nconnections; i++) { 1858 if (!azalia_widget_enabled(this, w->connections[i])) 1859 continue; 1860 if (azalia_codec_fnode(this, this->mic, 1861 w->connections[i], j + 1) >= 0) { 1862 break; 1863 } 1864 } 1865 if (i >= w->nconnections) 1866 return(-1); 1867 err = azalia_comresp(this, w->nid, 1868 CORB_SET_CONNECTION_SELECT_CONTROL, i, 0); 1869 if (err) 1870 return(err); 1871 w->selected = i; 1872 if (w->connections[i] == this->mic) { 1873 this->mic_adc = conv; 1874 return(0); 1875 } 1876 w = &this->w[w->connections[i]]; 1877 } 1878 return(-1); 1879} 1880 1881int 1882azalia_codec_sort_pins(codec_t *this) 1883{ 1884#define MAX_PINS 16 1885 const widget_t *w; 1886 struct io_pin opins[MAX_PINS], opins_d[MAX_PINS]; 1887 struct io_pin ipins[MAX_PINS], ipins_d[MAX_PINS]; 1888 int nopins, nopins_d, nipins, nipins_d; 1889 int prio, loc, add, nd, conv; 1890 int i, j, k; 1891 1892 nopins = nopins_d = nipins = nipins_d = 0; 1893 1894 FOR_EACH_WIDGET(this, i) { 1895 w = &this->w[i]; 1896 if (!w->enable || w->type != COP_AWTYPE_PIN_COMPLEX) 1897 continue; 1898 1899 loc = 0; 1900 if (this->na_dacs >= 3 && this->nout_jacks < 3) 1901 loc = CORB_CD_LOC_GEO(w->d.pin.config); 1902 1903 prio = w->d.pin.association << 4 | w->d.pin.sequence; 1904 conv = -1; 1905 1906 /* analog out */ 1907 if ((w->d.pin.cap & COP_PINCAP_OUTPUT) && 1908 !(w->widgetcap & COP_AWCAP_DIGITAL)) { 1909 add = nd = 0; 1910 conv = azalia_codec_find_defdac(this, w->nid, 0); 1911 switch(w->d.pin.device) { 1912 /* primary - output by default */ 1913 case CORB_CD_SPEAKER: 1914 if (w->nid == this->speaker || 1915 w->nid == this->speaker2) 1916 break; 1917 /* FALLTHROUGH */ 1918 case CORB_CD_HEADPHONE: 1919 case CORB_CD_LINEOUT: 1920 add = 1; 1921 break; 1922 /* secondary - input by default */ 1923 case CORB_CD_MICIN: 1924 if (w->nid == this->mic) 1925 break; 1926 /* FALLTHROUGH */ 1927 case CORB_CD_LINEIN: 1928 add = nd = 1; 1929 break; 1930 } 1931 if (add && nopins < MAX_PINS) { 1932 opins[nopins].nid = w->nid; 1933 opins[nopins].conv = conv; 1934 prio |= (nd << 8) | (loc << 9); 1935 opins[nopins].prio = prio; 1936 nopins++; 1937 } 1938 } 1939 /* digital out */ 1940 if ((w->d.pin.cap & COP_PINCAP_OUTPUT) && 1941 (w->widgetcap & COP_AWCAP_DIGITAL)) { 1942 conv = azalia_codec_find_defdac(this, w->nid, 0); 1943 switch(w->d.pin.device) { 1944 case CORB_CD_SPDIFOUT: 1945 case CORB_CD_DIGITALOUT: 1946 if (nopins_d < MAX_PINS) { 1947 opins_d[nopins_d].nid = w->nid; 1948 opins_d[nopins_d].conv = conv; 1949 opins_d[nopins_d].prio = prio; 1950 nopins_d++; 1951 } 1952 break; 1953 } 1954 } 1955 /* analog in */ 1956 if ((w->d.pin.cap & COP_PINCAP_INPUT) && 1957 !(w->widgetcap & COP_AWCAP_DIGITAL)) { 1958 add = nd = 0; 1959 conv = azalia_codec_find_defadc(this, w->nid, 0); 1960 switch(w->d.pin.device) { 1961 /* primary - input by default */ 1962 case CORB_CD_MICIN: 1963 case CORB_CD_LINEIN: 1964 add = 1; 1965 break; 1966 /* secondary - output by default */ 1967 case CORB_CD_SPEAKER: 1968 if (w->nid == this->speaker || 1969 w->nid == this->speaker2) 1970 break; 1971 /* FALLTHROUGH */ 1972 case CORB_CD_HEADPHONE: 1973 case CORB_CD_LINEOUT: 1974 add = nd = 1; 1975 break; 1976 } 1977 if (add && nipins < MAX_PINS) { 1978 ipins[nipins].nid = w->nid; 1979 ipins[nipins].prio = prio | (nd << 8); 1980 ipins[nipins].conv = conv; 1981 nipins++; 1982 } 1983 } 1984 /* digital in */ 1985 if ((w->d.pin.cap & COP_PINCAP_INPUT) && 1986 (w->widgetcap & COP_AWCAP_DIGITAL)) { 1987 conv = azalia_codec_find_defadc(this, w->nid, 0); 1988 switch(w->d.pin.device) { 1989 case CORB_CD_SPDIFIN: 1990 case CORB_CD_DIGITALIN: 1991 case CORB_CD_MICIN: 1992 if (nipins_d < MAX_PINS) { 1993 ipins_d[nipins_d].nid = w->nid; 1994 ipins_d[nipins_d].prio = prio; 1995 ipins_d[nipins_d].conv = conv; 1996 nipins_d++; 1997 } 1998 break; 1999 } 2000 } 2001 } 2002 2003 this->opins = mallocarray(nopins, sizeof(struct io_pin), M_DEVBUF, 2004 M_NOWAIT | M_ZERO); 2005 if (this->opins == NULL) 2006 return(ENOMEM); 2007 this->nopins = 0; 2008 for (i = 0; i < nopins; i++) { 2009 for (j = 0; j < this->nopins; j++) 2010 if (this->opins[j].prio > opins[i].prio) 2011 break; 2012 for (k = this->nopins; k > j; k--) 2013 this->opins[k] = this->opins[k - 1]; 2014 if (j < nopins) 2015 this->opins[j] = opins[i]; 2016 this->nopins++; 2017 if (this->nopins == nopins) 2018 break; 2019 } 2020 2021 this->opins_d = mallocarray(nopins_d, sizeof(struct io_pin), M_DEVBUF, 2022 M_NOWAIT | M_ZERO); 2023 if (this->opins_d == NULL) 2024 return(ENOMEM); 2025 this->nopins_d = 0; 2026 for (i = 0; i < nopins_d; i++) { 2027 for (j = 0; j < this->nopins_d; j++) 2028 if (this->opins_d[j].prio > opins_d[i].prio) 2029 break; 2030 for (k = this->nopins_d; k > j; k--) 2031 this->opins_d[k] = this->opins_d[k - 1]; 2032 if (j < nopins_d) 2033 this->opins_d[j] = opins_d[i]; 2034 this->nopins_d++; 2035 if (this->nopins_d == nopins_d) 2036 break; 2037 } 2038 2039 this->ipins = mallocarray(nipins, sizeof(struct io_pin), M_DEVBUF, 2040 M_NOWAIT | M_ZERO); 2041 if (this->ipins == NULL) 2042 return(ENOMEM); 2043 this->nipins = 0; 2044 for (i = 0; i < nipins; i++) { 2045 for (j = 0; j < this->nipins; j++) 2046 if (this->ipins[j].prio > ipins[i].prio) 2047 break; 2048 for (k = this->nipins; k > j; k--) 2049 this->ipins[k] = this->ipins[k - 1]; 2050 if (j < nipins) 2051 this->ipins[j] = ipins[i]; 2052 this->nipins++; 2053 if (this->nipins == nipins) 2054 break; 2055 } 2056 2057 this->ipins_d = mallocarray(nipins_d, sizeof(struct io_pin), M_DEVBUF, 2058 M_NOWAIT | M_ZERO); 2059 if (this->ipins_d == NULL) 2060 return(ENOMEM); 2061 this->nipins_d = 0; 2062 for (i = 0; i < nipins_d; i++) { 2063 for (j = 0; j < this->nipins_d; j++) 2064 if (this->ipins_d[j].prio > ipins_d[i].prio) 2065 break; 2066 for (k = this->nipins_d; k > j; k--) 2067 this->ipins_d[k] = this->ipins_d[k - 1]; 2068 if (j < nipins_d) 2069 this->ipins_d[j] = ipins_d[i]; 2070 this->nipins_d++; 2071 if (this->nipins_d == nipins_d) 2072 break; 2073 } 2074 2075#ifdef AZALIA_DEBUG 2076 printf("%s: analog out pins:", __func__); 2077 for (i = 0; i < this->nopins; i++) 2078 printf(" 0x%2.2x->0x%2.2x", this->opins[i].nid, 2079 this->opins[i].conv); 2080 printf("\n"); 2081 printf("%s: digital out pins:", __func__); 2082 for (i = 0; i < this->nopins_d; i++) 2083 printf(" 0x%2.2x->0x%2.2x", this->opins_d[i].nid, 2084 this->opins_d[i].conv); 2085 printf("\n"); 2086 printf("%s: analog in pins:", __func__); 2087 for (i = 0; i < this->nipins; i++) 2088 printf(" 0x%2.2x->0x%2.2x", this->ipins[i].nid, 2089 this->ipins[i].conv); 2090 printf("\n"); 2091 printf("%s: digital in pins:", __func__); 2092 for (i = 0; i < this->nipins_d; i++) 2093 printf(" 0x%2.2x->0x%2.2x", this->ipins_d[i].nid, 2094 this->ipins_d[i].conv); 2095 printf("\n"); 2096#endif 2097 2098 return 0; 2099#undef MAX_PINS 2100} 2101 2102int 2103azalia_codec_select_dacs(codec_t *this) 2104{ 2105 widget_t *w; 2106 nid_t *convs; 2107 int nconv, conv; 2108 int i, j, k, err; 2109 2110 convs = mallocarray(this->na_dacs, sizeof(nid_t), M_DEVBUF, 2111 M_NOWAIT | M_ZERO); 2112 if (convs == NULL) 2113 return(ENOMEM); 2114 2115 err = 0; 2116 nconv = 0; 2117 for (i = 0; i < this->nopins; i++) { 2118 w = &this->w[this->opins[i].nid]; 2119 2120 conv = this->opins[i].conv; 2121 for (j = 0; j < nconv; j++) { 2122 if (conv == convs[j]) 2123 break; 2124 } 2125 if (j == nconv) { 2126 convs[nconv++] = conv; 2127 if (w->nid == this->fhp) 2128 this->fhp_dac = conv; 2129 if (nconv >= this->na_dacs) { 2130 break; 2131 } 2132 } else { 2133 /* find a different dac */ 2134 conv = -1; 2135 for (j = 0; j < w->nconnections; j++) { 2136 if (!azalia_widget_enabled(this, 2137 w->connections[j])) 2138 continue; 2139 conv = azalia_codec_find_defdac(this, 2140 w->connections[j], 1); 2141 if (conv == -1) 2142 continue; 2143 for (k = 0; k < nconv; k++) { 2144 if (conv == convs[k]) 2145 break; 2146 } 2147 if (k == nconv) 2148 break; 2149 } 2150 if (j < w->nconnections && conv != -1) { 2151 err = azalia_comresp(this, w->nid, 2152 CORB_SET_CONNECTION_SELECT_CONTROL, j, 0); 2153 if (err) 2154 break; 2155 w->selected = j; 2156 this->opins[i].conv = conv; 2157 if (w->nid == this->fhp) 2158 this->fhp_dac = conv; 2159 convs[nconv++] = conv; 2160 if (nconv >= this->na_dacs) 2161 break; 2162 } 2163 } 2164 } 2165 2166 free(convs, M_DEVBUF, this->na_dacs * sizeof(nid_t)); 2167 return(err); 2168} 2169 2170/* Connect the speaker to a DAC that no other output pin is connected 2171 * to by default. If that is not possible, connect to a DAC other 2172 * than the one the first output pin is connected to. 2173 */ 2174int 2175azalia_codec_select_spkrdac(codec_t *this) 2176{ 2177 widget_t *w; 2178 nid_t convs[HDA_MAX_CHANNELS]; 2179 int nconv, conv; 2180 int i, j, err, fspkr, conn; 2181 2182 nconv = fspkr = 0; 2183 for (i = 0; i < this->nopins; i++) { 2184 conv = this->opins[i].conv; 2185 for (j = 0; j < nconv; j++) { 2186 if (conv == convs[j]) 2187 break; 2188 } 2189 if (j == nconv) { 2190 if (conv == this->spkr_dac) 2191 fspkr = 1; 2192 convs[nconv++] = conv; 2193 if (nconv == this->na_dacs) 2194 break; 2195 } 2196 } 2197 2198 if (fspkr) { 2199 conn = conv = -1; 2200 w = &this->w[this->speaker]; 2201 for (i = 0; i < w->nconnections; i++) { 2202 conv = azalia_codec_find_defdac(this, 2203 w->connections[i], 1); 2204 for (j = 0; j < nconv; j++) 2205 if (conv == convs[j]) 2206 break; 2207 if (j == nconv) 2208 break; 2209 } 2210 if (i < w->nconnections) { 2211 conn = i; 2212 } else { 2213 /* Couldn't get a unique DAC. Try to get a different 2214 * DAC than the first pin's DAC. 2215 */ 2216 if (this->spkr_dac == this->opins[0].conv) { 2217 /* If the speaker connection can't be changed, 2218 * change the first pin's connection. 2219 */ 2220 if (w->nconnections == 1) 2221 w = &this->w[this->opins[0].nid]; 2222 for (j = 0; j < w->nconnections; j++) { 2223 conv = azalia_codec_find_defdac(this, 2224 w->connections[j], 1); 2225 if (conv != this->opins[0].conv) { 2226 conn = j; 2227 break; 2228 } 2229 } 2230 } 2231 } 2232 if (conn != -1 && conv != -1) { 2233 err = azalia_comresp(this, w->nid, 2234 CORB_SET_CONNECTION_SELECT_CONTROL, conn, 0); 2235 if (err) 2236 return(err); 2237 w->selected = conn; 2238 if (w->nid == this->speaker) 2239 this->spkr_dac = conv; 2240 else 2241 this->opins[0].conv = conv; 2242 } 2243 } 2244 2245 /* If there is a speaker2, try to connect it to spkr_dac. */ 2246 if (this->speaker2 != -1) { 2247 conn = conv = -1; 2248 w = &this->w[this->speaker2]; 2249 for (i = 0; i < w->nconnections; i++) { 2250 conv = azalia_codec_find_defdac(this, 2251 w->connections[i], 1); 2252 if (this->qrks & AZ_QRK_ROUTE_SPKR2_DAC) { 2253 if (conv != this->spkr_dac) { 2254 conn = i; 2255 break; 2256 } 2257 } else if (conv == this->spkr_dac) { 2258 conn = i; 2259 break; 2260 } 2261 } 2262 if (conn != -1) { 2263 err = azalia_comresp(this, w->nid, 2264 CORB_SET_CONNECTION_SELECT_CONTROL, conn, 0); 2265 if (err) 2266 return(err); 2267 w->selected = conn; 2268 } 2269 } 2270 2271 return(0); 2272} 2273 2274int 2275azalia_codec_find_defdac(codec_t *this, int index, int depth) 2276{ 2277 const widget_t *w; 2278 int i, ret; 2279 2280 w = &this->w[index]; 2281 if (w->enable == 0) 2282 return -1; 2283 2284 if (w->type == COP_AWTYPE_AUDIO_OUTPUT) 2285 return index; 2286 2287 if (depth > 0 && 2288 (w->type == COP_AWTYPE_PIN_COMPLEX || 2289 w->type == COP_AWTYPE_BEEP_GENERATOR || 2290 w->type == COP_AWTYPE_AUDIO_INPUT)) 2291 return -1; 2292 if (++depth >= 10) 2293 return -1; 2294 2295 if (w->nconnections > 0) { 2296 /* by default, all mixer connections are active */ 2297 if (w->type == COP_AWTYPE_AUDIO_MIXER) { 2298 for (i = 0; i < w->nconnections; i++) { 2299 index = w->connections[i]; 2300 if (!azalia_widget_enabled(this, index)) 2301 continue; 2302 ret = azalia_codec_find_defdac(this, index, 2303 depth); 2304 if (ret >= 0) 2305 return ret; 2306 } 2307 /* 7.3.3.2 Connection Select Control 2308 * If an attempt is made to Set an index value greater than 2309 * the number of list entries (index is equal to or greater 2310 * than the Connection List Length property for the widget) 2311 * the behavior is not predictable. 2312 */ 2313 2314 /* negative index values are wrong too */ 2315 } else if (w->selected >= 0 && 2316 w->selected < sizeof(w->connections)) { 2317 index = w->connections[w->selected]; 2318 if (VALID_WIDGET_NID(index, this)) { 2319 ret = azalia_codec_find_defdac(this, 2320 index, depth); 2321 if (ret >= 0) 2322 return ret; 2323 } 2324 } 2325 } 2326 2327 return -1; 2328} 2329 2330int 2331azalia_codec_find_defadc_sub(codec_t *this, nid_t node, int index, int depth) 2332{ 2333 const widget_t *w; 2334 int i, ret; 2335 2336 w = &this->w[index]; 2337 if (w->nid == node) { 2338 return index; 2339 } 2340 /* back at the beginning or a bad end */ 2341 if (depth > 0 && 2342 (w->type == COP_AWTYPE_PIN_COMPLEX || 2343 w->type == COP_AWTYPE_BEEP_GENERATOR || 2344 w->type == COP_AWTYPE_AUDIO_OUTPUT || 2345 w->type == COP_AWTYPE_AUDIO_INPUT)) 2346 return -1; 2347 if (++depth >= 10) 2348 return -1; 2349 2350 if (w->nconnections > 0) { 2351 /* by default, all mixer connections are active */ 2352 if (w->type == COP_AWTYPE_AUDIO_MIXER) { 2353 for (i = 0; i < w->nconnections; i++) { 2354 if (!azalia_widget_enabled(this, w->connections[i])) 2355 continue; 2356 ret = azalia_codec_find_defadc_sub(this, node, 2357 w->connections[i], depth); 2358 if (ret >= 0) 2359 return ret; 2360 } 2361 /* 7.3.3.2 Connection Select Control 2362 * If an attempt is made to Set an index value greater than 2363 * the number of list entries (index is equal to or greater 2364 * than the Connection List Length property for the widget) 2365 * the behavior is not predictable. 2366 */ 2367 2368 /* negative index values are wrong too */ 2369 } else if (w->selected >= 0 && 2370 w->selected < sizeof(w->connections)) { 2371 index = w->connections[w->selected]; 2372 if (VALID_WIDGET_NID(index, this)) { 2373 ret = azalia_codec_find_defadc_sub(this, 2374 node, index, depth); 2375 if (ret >= 0) 2376 return ret; 2377 } 2378 } 2379 } 2380 return -1; 2381} 2382 2383int 2384azalia_codec_find_defadc(codec_t *this, int index, int depth) 2385{ 2386 int i, j, conv; 2387 2388 conv = -1; 2389 for (i = 0; i < this->na_adcs; i++) { 2390 j = azalia_codec_find_defadc_sub(this, index, 2391 this->a_adcs[i], 0); 2392 if (j >= 0) { 2393 conv = this->a_adcs[i]; 2394 break; 2395 } 2396 } 2397 return(conv); 2398} 2399 2400int 2401azalia_codec_init_volgroups(codec_t *this) 2402{ 2403 const widget_t *w; 2404 uint32_t cap, result; 2405 int i, j, dac, err; 2406 2407 j = 0; 2408 this->playvols.mask = 0; 2409 FOR_EACH_WIDGET(this, i) { 2410 w = &this->w[i]; 2411 if (w->enable == 0) 2412 continue; 2413 if (w->mixer_class == AZ_CLASS_RECORD) 2414 continue; 2415 if (!(w->widgetcap & COP_AWCAP_OUTAMP)) 2416 continue; 2417 if ((COP_AMPCAP_NUMSTEPS(w->outamp_cap) == 0) && 2418 !(w->outamp_cap & COP_AMPCAP_MUTE)) 2419 continue; 2420 this->playvols.mask |= (1 << j); 2421 this->playvols.slaves[j++] = w->nid; 2422 if (j >= AZ_MAX_VOL_SLAVES) 2423 break; 2424 } 2425 this->playvols.nslaves = j; 2426 2427 this->playvols.cur = 0; 2428 for (i = 0; i < this->playvols.nslaves; i++) { 2429 w = &this->w[this->playvols.slaves[i]]; 2430 if (w->nid == this->input_mixer || 2431 w->parent == this->input_mixer || 2432 WIDGET_CHANNELS(w) < 2) 2433 continue; 2434 j = 0; 2435 /* azalia_codec_find_defdac only goes 10 connections deep. 2436 * Start the connection depth at 7 so it doesn't go more 2437 * than 3 connections deep. 2438 */ 2439 if (w->type == COP_AWTYPE_AUDIO_MIXER || 2440 w->type == COP_AWTYPE_AUDIO_SELECTOR) 2441 j = 7; 2442 dac = azalia_codec_find_defdac(this, w->nid, j); 2443 if (dac == -1) 2444 continue; 2445 if (dac != this->dacs.groups[this->dacs.cur].conv[0] && 2446 dac != this->spkr_dac && dac != this->fhp_dac) 2447 continue; 2448 cap = w->outamp_cap; 2449 if ((cap & COP_AMPCAP_MUTE) && COP_AMPCAP_NUMSTEPS(cap)) { 2450 if (w->type == COP_AWTYPE_BEEP_GENERATOR) { 2451 continue; 2452 } else if (w->type == COP_AWTYPE_PIN_COMPLEX) { 2453 err = azalia_comresp(this, w->nid, 2454 CORB_GET_PIN_WIDGET_CONTROL, 0, &result); 2455 if (!err && (result & CORB_PWC_OUTPUT)) 2456 this->playvols.cur |= (1 << i); 2457 } else 2458 this->playvols.cur |= (1 << i); 2459 } 2460 } 2461 if (this->playvols.cur == 0) { 2462 for (i = 0; i < this->playvols.nslaves; i++) { 2463 w = &this->w[this->playvols.slaves[i]]; 2464 j = 0; 2465 if (w->type == COP_AWTYPE_AUDIO_MIXER || 2466 w->type == COP_AWTYPE_AUDIO_SELECTOR) 2467 j = 7; 2468 dac = azalia_codec_find_defdac(this, w->nid, j); 2469 if (dac == -1) 2470 continue; 2471 if (dac != this->dacs.groups[this->dacs.cur].conv[0] && 2472 dac != this->spkr_dac && dac != this->fhp_dac) 2473 continue; 2474 if (w->type == COP_AWTYPE_BEEP_GENERATOR) 2475 continue; 2476 if (w->type == COP_AWTYPE_PIN_COMPLEX) { 2477 err = azalia_comresp(this, w->nid, 2478 CORB_GET_PIN_WIDGET_CONTROL, 0, &result); 2479 if (!err && (result & CORB_PWC_OUTPUT)) 2480 this->playvols.cur |= (1 << i); 2481 } else { 2482 this->playvols.cur |= (1 << i); 2483 } 2484 } 2485 } 2486 2487 this->playvols.master = this->audiofunc; 2488 if (this->playvols.nslaves > 0) { 2489 FOR_EACH_WIDGET(this, i) { 2490 w = &this->w[i]; 2491 if (w->type != COP_AWTYPE_VOLUME_KNOB) 2492 continue; 2493 if (!COP_VKCAP_NUMSTEPS(w->d.volume.cap)) 2494 continue; 2495 this->playvols.master = w->nid; 2496 break; 2497 } 2498 } 2499 2500 j = 0; 2501 this->recvols.mask = 0; 2502 FOR_EACH_WIDGET(this, i) { 2503 w = &this->w[i]; 2504 if (w->enable == 0) 2505 continue; 2506 if (w->type == COP_AWTYPE_AUDIO_INPUT || 2507 w->type == COP_AWTYPE_PIN_COMPLEX) { 2508 if (!(w->widgetcap & COP_AWCAP_INAMP)) 2509 continue; 2510 if ((COP_AMPCAP_NUMSTEPS(w->inamp_cap) == 0) && 2511 !(w->inamp_cap & COP_AMPCAP_MUTE)) 2512 continue; 2513 } else if (w->type == COP_AWTYPE_AUDIO_MIXER || 2514 w->type == COP_AWTYPE_AUDIO_SELECTOR) { 2515 if (w->mixer_class != AZ_CLASS_RECORD) 2516 continue; 2517 if (!(w->widgetcap & COP_AWCAP_OUTAMP)) 2518 continue; 2519 if ((COP_AMPCAP_NUMSTEPS(w->outamp_cap) == 0) && 2520 !(w->outamp_cap & COP_AMPCAP_MUTE)) 2521 continue; 2522 } else { 2523 continue; 2524 } 2525 this->recvols.mask |= (1 << j); 2526 this->recvols.slaves[j++] = w->nid; 2527 if (j >= AZ_MAX_VOL_SLAVES) 2528 break; 2529 } 2530 this->recvols.nslaves = j; 2531 2532 this->recvols.cur = 0; 2533 for (i = 0; i < this->recvols.nslaves; i++) { 2534 w = &this->w[this->recvols.slaves[i]]; 2535 cap = w->outamp_cap; 2536 if (w->type == COP_AWTYPE_AUDIO_INPUT || 2537 w->type != COP_AWTYPE_PIN_COMPLEX) 2538 cap = w->inamp_cap; 2539 else 2540 if (w->mixer_class != AZ_CLASS_RECORD) 2541 continue; 2542 if ((cap & COP_AMPCAP_MUTE) && COP_AMPCAP_NUMSTEPS(cap)) { 2543 if (w->type == COP_AWTYPE_PIN_COMPLEX) { 2544 err = azalia_comresp(this, w->nid, 2545 CORB_GET_PIN_WIDGET_CONTROL, 0, &result); 2546 if (!err && !(result & CORB_PWC_OUTPUT)) 2547 this->recvols.cur |= (1 << i); 2548 } else 2549 this->recvols.cur |= (1 << i); 2550 } 2551 } 2552 if (this->recvols.cur == 0) { 2553 for (i = 0; i < this->recvols.nslaves; i++) { 2554 w = &this->w[this->recvols.slaves[i]]; 2555 cap = w->outamp_cap; 2556 if (w->type == COP_AWTYPE_AUDIO_INPUT || 2557 w->type != COP_AWTYPE_PIN_COMPLEX) 2558 cap = w->inamp_cap; 2559 else 2560 if (w->mixer_class != AZ_CLASS_RECORD) 2561 continue; 2562 if (w->type == COP_AWTYPE_PIN_COMPLEX) { 2563 err = azalia_comresp(this, w->nid, 2564 CORB_GET_PIN_WIDGET_CONTROL, 0, &result); 2565 if (!err && !(result & CORB_PWC_OUTPUT)) 2566 this->recvols.cur |= (1 << i); 2567 } else { 2568 this->recvols.cur |= (1 << i); 2569 } 2570 } 2571 } 2572 2573 this->recvols.master = this->audiofunc; 2574 2575 return 0; 2576} 2577 2578int 2579azalia_codec_delete(codec_t *this) 2580{ 2581 azalia_mixer_delete(this); 2582 2583 if (this->formats != NULL) { 2584 free(this->formats, M_DEVBUF, 2585 this->nformats * sizeof(struct audio_format)); 2586 this->formats = NULL; 2587 } 2588 this->nformats = 0; 2589 2590 if (this->opins != NULL) { 2591 free(this->opins, M_DEVBUF, 2592 this->nopins * sizeof(struct io_pin)); 2593 this->opins = NULL; 2594 } 2595 this->nopins = 0; 2596 2597 if (this->opins_d != NULL) { 2598 free(this->opins_d, M_DEVBUF, 2599 this->nopins_d * sizeof(struct io_pin)); 2600 this->opins_d = NULL; 2601 } 2602 this->nopins_d = 0; 2603 2604 if (this->ipins != NULL) { 2605 free(this->ipins, M_DEVBUF, 2606 this->nipins * sizeof(struct io_pin)); 2607 this->ipins = NULL; 2608 } 2609 this->nipins = 0; 2610 2611 if (this->ipins_d != NULL) { 2612 free(this->ipins_d, M_DEVBUF, 2613 this->nipins_d * sizeof(struct io_pin)); 2614 this->ipins_d = NULL; 2615 } 2616 this->nipins_d = 0; 2617 2618 if (this->w != NULL) { 2619 free(this->w, M_DEVBUF, 2620 this->wend * sizeof(widget_t)); 2621 this->w = NULL; 2622 } 2623 2624 return 0; 2625} 2626 2627int 2628azalia_codec_construct_format(codec_t *this, int newdac, int newadc) 2629{ 2630 const convgroup_t *group; 2631 uint32_t bits_rates; 2632 int variation; 2633 int nbits, c, chan, i; 2634 nid_t nid; 2635 2636 variation = 0; 2637 2638 if (this->dacs.ngroups > 0 && newdac < this->dacs.ngroups && 2639 newdac >= 0) { 2640 this->dacs.cur = newdac; 2641 group = &this->dacs.groups[this->dacs.cur]; 2642 bits_rates = this->w[group->conv[0]].d.audio.bits_rates; 2643 nbits = 0; 2644 if (bits_rates & COP_PCM_B8) 2645 nbits++; 2646 if (bits_rates & COP_PCM_B16) 2647 nbits++; 2648 if (bits_rates & COP_PCM_B20) 2649 nbits++; 2650 if (bits_rates & COP_PCM_B24) 2651 nbits++; 2652 if ((bits_rates & COP_PCM_B32) && 2653 !(this->w[group->conv[0]].widgetcap & COP_AWCAP_DIGITAL)) 2654 nbits++; 2655 if (nbits == 0) { 2656 printf("%s: invalid DAC PCM format: 0x%8.8x\n", 2657 XNAME(this->az), bits_rates); 2658 return -1; 2659 } 2660 variation += group->nconv * nbits; 2661 } 2662 2663 if (this->adcs.ngroups > 0 && newadc < this->adcs.ngroups && 2664 newadc >= 0) { 2665 this->adcs.cur = newadc; 2666 group = &this->adcs.groups[this->adcs.cur]; 2667 bits_rates = this->w[group->conv[0]].d.audio.bits_rates; 2668 nbits = 0; 2669 if (bits_rates & COP_PCM_B8) 2670 nbits++; 2671 if (bits_rates & COP_PCM_B16) 2672 nbits++; 2673 if (bits_rates & COP_PCM_B20) 2674 nbits++; 2675 if (bits_rates & COP_PCM_B24) 2676 nbits++; 2677 if ((bits_rates & COP_PCM_B32) && 2678 !(this->w[group->conv[0]].widgetcap & COP_AWCAP_DIGITAL)) 2679 nbits++; 2680 if (nbits == 0) { 2681 printf("%s: invalid ADC PCM format: 0x%8.8x\n", 2682 XNAME(this->az), bits_rates); 2683 return -1; 2684 } 2685 variation += group->nconv * nbits; 2686 } 2687 2688 if (variation == 0) { 2689 DPRINTF(("%s: no converter groups\n", XNAME(this->az))); 2690 return -1; 2691 } 2692 2693 if (this->formats != NULL) 2694 free(this->formats, M_DEVBUF, 0); 2695 this->nformats = 0; 2696 this->formats = mallocarray(variation, sizeof(struct audio_format), 2697 M_DEVBUF, M_NOWAIT | M_ZERO); 2698 if (this->formats == NULL) { 2699 printf("%s: out of memory in %s\n", 2700 XNAME(this->az), __func__); 2701 return ENOMEM; 2702 } 2703 2704 /* register formats for playback */ 2705 if (this->dacs.ngroups > 0) { 2706 group = &this->dacs.groups[this->dacs.cur]; 2707 for (c = 0; c < group->nconv; c++) { 2708 chan = 0; 2709 bits_rates = ~0; 2710 if (this->w[group->conv[0]].widgetcap & 2711 COP_AWCAP_DIGITAL) 2712 bits_rates &= ~(COP_PCM_B32); 2713 for (i = 0; i <= c; i++) { 2714 nid = group->conv[i]; 2715 chan += WIDGET_CHANNELS(&this->w[nid]); 2716 bits_rates &= this->w[nid].d.audio.bits_rates; 2717 } 2718 azalia_codec_add_bits(this, chan, bits_rates, 2719 AUMODE_PLAY); 2720 } 2721 } 2722 2723 /* register formats for recording */ 2724 if (this->adcs.ngroups > 0) { 2725 group = &this->adcs.groups[this->adcs.cur]; 2726 for (c = 0; c < group->nconv; c++) { 2727 chan = 0; 2728 bits_rates = ~0; 2729 if (this->w[group->conv[0]].widgetcap & 2730 COP_AWCAP_DIGITAL) 2731 bits_rates &= ~(COP_PCM_B32); 2732 for (i = 0; i <= c; i++) { 2733 nid = group->conv[i]; 2734 chan += WIDGET_CHANNELS(&this->w[nid]); 2735 bits_rates &= this->w[nid].d.audio.bits_rates; 2736 } 2737 azalia_codec_add_bits(this, chan, bits_rates, 2738 AUMODE_RECORD); 2739 } 2740 } 2741 2742 return 0; 2743} 2744 2745void 2746azalia_codec_add_bits(codec_t *this, int chan, uint32_t bits_rates, int mode) 2747{ 2748 if (bits_rates & COP_PCM_B8) 2749 azalia_codec_add_format(this, chan, 8, bits_rates, mode); 2750 if (bits_rates & COP_PCM_B16) 2751 azalia_codec_add_format(this, chan, 16, bits_rates, mode); 2752 if (bits_rates & COP_PCM_B20) 2753 azalia_codec_add_format(this, chan, 20, bits_rates, mode); 2754 if (bits_rates & COP_PCM_B24) 2755 azalia_codec_add_format(this, chan, 24, bits_rates, mode); 2756 if (bits_rates & COP_PCM_B32) 2757 azalia_codec_add_format(this, chan, 32, bits_rates, mode); 2758} 2759 2760void 2761azalia_codec_add_format(codec_t *this, int chan, int prec, uint32_t rates, 2762 int32_t mode) 2763{ 2764 struct audio_format *f; 2765 2766 f = &this->formats[this->nformats++]; 2767 f->mode = mode; 2768 f->encoding = AUDIO_ENCODING_SLINEAR_LE; 2769 if (prec == 8) 2770 f->encoding = AUDIO_ENCODING_ULINEAR_LE; 2771 f->precision = prec; 2772 f->channels = chan; 2773 f->frequency_type = 0; 2774 if (rates & COP_PCM_R80) 2775 f->frequency[f->frequency_type++] = 8000; 2776 if (rates & COP_PCM_R110) 2777 f->frequency[f->frequency_type++] = 11025; 2778 if (rates & COP_PCM_R160) 2779 f->frequency[f->frequency_type++] = 16000; 2780 if (rates & COP_PCM_R220) 2781 f->frequency[f->frequency_type++] = 22050; 2782 if (rates & COP_PCM_R320) 2783 f->frequency[f->frequency_type++] = 32000; 2784 if (rates & COP_PCM_R441) 2785 f->frequency[f->frequency_type++] = 44100; 2786 if (rates & COP_PCM_R480) 2787 f->frequency[f->frequency_type++] = 48000; 2788 if (rates & COP_PCM_R882) 2789 f->frequency[f->frequency_type++] = 88200; 2790 if (rates & COP_PCM_R960) 2791 f->frequency[f->frequency_type++] = 96000; 2792 if (rates & COP_PCM_R1764) 2793 f->frequency[f->frequency_type++] = 176400; 2794 if (rates & COP_PCM_R1920) 2795 f->frequency[f->frequency_type++] = 192000; 2796 if (rates & COP_PCM_R3840) 2797 f->frequency[f->frequency_type++] = 384000; 2798} 2799 2800int 2801azalia_codec_connect_stream(stream_t *this) 2802{ 2803 const codec_t *codec = &this->az->codecs[this->az->codecno]; 2804 const convgroup_t *group; 2805 widget_t *w; 2806 uint32_t digital, stream_chan; 2807 int i, err, curchan, nchan, widchan; 2808 2809 err = 0; 2810 nchan = (this->fmt & HDA_SD_FMT_CHAN) + 1; 2811 2812 if (this->dir == AUMODE_RECORD) 2813 group = &codec->adcs.groups[codec->adcs.cur]; 2814 else 2815 group = &codec->dacs.groups[codec->dacs.cur]; 2816 2817 curchan = 0; 2818 for (i = 0; i < group->nconv; i++) { 2819 w = &codec->w[group->conv[i]]; 2820 widchan = WIDGET_CHANNELS(w); 2821 2822 stream_chan = (this->number << 4); 2823 if (curchan < nchan) { 2824 stream_chan |= curchan; 2825 } else if (w->nid == codec->spkr_dac || 2826 w->nid == codec->fhp_dac) { 2827 stream_chan |= 0; /* first channel(s) */ 2828 } else 2829 stream_chan = 0; /* idle stream */ 2830 2831 if (stream_chan == 0) { 2832 DPRINTFN(0, ("%s: %2.2x is idle\n", __func__, w->nid)); 2833 } else { 2834 DPRINTFN(0, ("%s: %2.2x on stream chan %d\n", __func__, 2835 w->nid, stream_chan & ~(this->number << 4))); 2836 } 2837 2838 err = azalia_comresp(codec, w->nid, CORB_SET_CONVERTER_FORMAT, 2839 this->fmt, NULL); 2840 if (err) { 2841 DPRINTF(("%s: nid %2.2x fmt %2.2x: %d\n", 2842 __func__, w->nid, this->fmt, err)); 2843 break; 2844 } 2845 err = azalia_comresp(codec, w->nid, 2846 CORB_SET_CONVERTER_STREAM_CHANNEL, stream_chan, NULL); 2847 if (err) { 2848 DPRINTF(("%s: nid %2.2x chan %d: %d\n", 2849 __func__, w->nid, stream_chan, err)); 2850 break; 2851 } 2852 2853 if (w->widgetcap & COP_AWCAP_DIGITAL) { 2854 err = azalia_comresp(codec, w->nid, 2855 CORB_GET_DIGITAL_CONTROL, 0, &digital); 2856 if (err) { 2857 DPRINTF(("%s: nid %2.2x get digital: %d\n", 2858 __func__, w->nid, err)); 2859 break; 2860 } 2861 digital = (digital & 0xff) | CORB_DCC_DIGEN; 2862 err = azalia_comresp(codec, w->nid, 2863 CORB_SET_DIGITAL_CONTROL_L, digital, NULL); 2864 if (err) { 2865 DPRINTF(("%s: nid %2.2x set digital: %d\n", 2866 __func__, w->nid, err)); 2867 break; 2868 } 2869 } 2870 curchan += widchan; 2871 } 2872 2873 return err; 2874} 2875 2876int 2877azalia_codec_disconnect_stream(stream_t *this) 2878{ 2879 const codec_t *codec = &this->az->codecs[this->az->codecno]; 2880 const convgroup_t *group; 2881 uint32_t v; 2882 int i; 2883 nid_t nid; 2884 2885 if (this->dir == AUMODE_RECORD) 2886 group = &codec->adcs.groups[codec->adcs.cur]; 2887 else 2888 group = &codec->dacs.groups[codec->dacs.cur]; 2889 for (i = 0; i < group->nconv; i++) { 2890 nid = group->conv[i]; 2891 azalia_comresp(codec, nid, CORB_SET_CONVERTER_STREAM_CHANNEL, 2892 0, NULL); /* stream#0 */ 2893 if (codec->w[nid].widgetcap & COP_AWCAP_DIGITAL) { 2894 /* disable S/PDIF */ 2895 azalia_comresp(codec, nid, CORB_GET_DIGITAL_CONTROL, 2896 0, &v); 2897 v = (v & ~CORB_DCC_DIGEN) & 0xff; 2898 azalia_comresp(codec, nid, CORB_SET_DIGITAL_CONTROL_L, 2899 v, NULL); 2900 } 2901 } 2902 return 0; 2903} 2904 2905/* ================================================================ 2906 * HDA widget functions 2907 * ================================================================ */ 2908 2909int 2910azalia_widget_init(widget_t *this, const codec_t *codec, nid_t nid) 2911{ 2912 uint32_t result; 2913 int err; 2914 2915 err = azalia_comresp(codec, nid, CORB_GET_PARAMETER, 2916 COP_AUDIO_WIDGET_CAP, &result); 2917 if (err) 2918 return err; 2919 this->nid = nid; 2920 this->widgetcap = result; 2921 this->type = COP_AWCAP_TYPE(result); 2922 if (this->widgetcap & COP_AWCAP_POWER) { 2923 azalia_comresp(codec, nid, CORB_SET_POWER_STATE, CORB_PS_D0, 2924 &result); 2925 DELAY(100); 2926 } 2927 2928 this->enable = 1; 2929 this->mixer_class = -1; 2930 this->parent = codec->audiofunc; 2931 2932 switch (this->type) { 2933 case COP_AWTYPE_AUDIO_OUTPUT: 2934 /* FALLTHROUGH */ 2935 case COP_AWTYPE_AUDIO_INPUT: 2936 azalia_widget_init_audio(this, codec); 2937 break; 2938 case COP_AWTYPE_PIN_COMPLEX: 2939 azalia_widget_init_pin(this, codec); 2940 break; 2941 case COP_AWTYPE_VOLUME_KNOB: 2942 err = azalia_comresp(codec, this->nid, CORB_GET_PARAMETER, 2943 COP_VOLUME_KNOB_CAPABILITIES, &result); 2944 if (err) 2945 return err; 2946 this->d.volume.cap = result; 2947 break; 2948 case COP_AWTYPE_POWER: 2949 /* FALLTHROUGH */ 2950 case COP_AWTYPE_VENDOR_DEFINED: 2951 this->enable = 0; 2952 break; 2953 } 2954 2955 /* amplifier information */ 2956 /* XXX (ab)use bits 24-30 to store the "control offset", which is 2957 * the number of steps, starting at 0, that have no effect. these 2958 * bits are reserved in HDA 1.0. 2959 */ 2960 if (this->widgetcap & COP_AWCAP_INAMP) { 2961 if (this->widgetcap & COP_AWCAP_AMPOV) 2962 azalia_comresp(codec, nid, CORB_GET_PARAMETER, 2963 COP_INPUT_AMPCAP, &this->inamp_cap); 2964 else 2965 this->inamp_cap = codec->w[codec->audiofunc].inamp_cap; 2966 this->inamp_cap &= ~(0x7f << 24); 2967 } 2968 if (this->widgetcap & COP_AWCAP_OUTAMP) { 2969 if (this->widgetcap & COP_AWCAP_AMPOV) 2970 azalia_comresp(codec, nid, CORB_GET_PARAMETER, 2971 COP_OUTPUT_AMPCAP, &this->outamp_cap); 2972 else 2973 this->outamp_cap = codec->w[codec->audiofunc].outamp_cap; 2974 this->outamp_cap &= ~(0x7f << 24); 2975 } 2976 return 0; 2977} 2978 2979int 2980azalia_widget_sole_conn(codec_t *this, nid_t nid) 2981{ 2982 int i, j, target, nconn, has_target; 2983 2984 /* connected to ADC */ 2985 for (i = 0; i < this->adcs.ngroups; i++) { 2986 for (j = 0; j < this->adcs.groups[i].nconv; j++) { 2987 target = this->adcs.groups[i].conv[j]; 2988 if (this->w[target].nconnections == 1 && 2989 this->w[target].connections[0] == nid) { 2990 return target; 2991 } 2992 } 2993 } 2994 /* connected to DAC */ 2995 for (i = 0; i < this->dacs.ngroups; i++) { 2996 for (j = 0; j < this->dacs.groups[i].nconv; j++) { 2997 target = this->dacs.groups[i].conv[j]; 2998 if (this->w[target].nconnections == 1 && 2999 this->w[target].connections[0] == nid) { 3000 return target; 3001 } 3002 } 3003 } 3004 /* connected to pin complex */ 3005 target = -1; 3006 FOR_EACH_WIDGET(this, i) { 3007 if (this->w[i].type != COP_AWTYPE_PIN_COMPLEX) 3008 continue; 3009 if (this->w[i].nconnections == 1 && 3010 this->w[i].connections[0] == nid) { 3011 if (target != -1) 3012 return -1; 3013 target = i; 3014 } else { 3015 nconn = 0; 3016 has_target = 0; 3017 for (j = 0; j < this->w[i].nconnections; j++) { 3018 if (!this->w[this->w[i].connections[j]].enable) 3019 continue; 3020 nconn++; 3021 if (this->w[i].connections[j] == nid) 3022 has_target = 1; 3023 } 3024 if (has_target == 1) { 3025 if (nconn == 1) { 3026 if (target != -1) 3027 return -1; 3028 target = i; 3029 } else { 3030 /* not sole connection at least once */ 3031 return -1; 3032 } 3033 } 3034 } 3035 } 3036 if (target != -1) 3037 return target; 3038 3039 return -1; 3040} 3041 3042int 3043azalia_widget_label_widgets(codec_t *codec) 3044{ 3045 widget_t *w; 3046 convgroup_t *group; 3047 int types[16]; 3048 int pins[16]; 3049 int colors_used, use_colors, schan; 3050 int i, j; 3051 3052 bzero(&pins, sizeof(pins)); 3053 bzero(&types, sizeof(types)); 3054 3055 /* If codec has more than one line-out jack, check if the jacks 3056 * have unique colors. If so, use the colors in the mixer names. 3057 */ 3058 use_colors = 1; 3059 colors_used = 0; 3060 if (codec->nout_jacks < 2) 3061 use_colors = 0; 3062 for (i = 0; use_colors && i < codec->nopins; i++) { 3063 w = &codec->w[codec->opins[i].nid]; 3064 if (w->d.pin.device != CORB_CD_LINEOUT) 3065 continue; 3066 if (colors_used & (1 << w->d.pin.color)) 3067 use_colors = 0; 3068 else 3069 colors_used |= (1 << w->d.pin.color); 3070 } 3071 3072 FOR_EACH_WIDGET(codec, i) { 3073 w = &codec->w[i]; 3074 /* default for disabled/unused widgets */ 3075 snprintf(w->name, sizeof(w->name), "u-wid%2.2x", w->nid); 3076 if (w->enable == 0) 3077 continue; 3078 switch (w->type) { 3079 case COP_AWTYPE_PIN_COMPLEX: 3080 pins[w->d.pin.device]++; 3081 if (use_colors && w->d.pin.device == CORB_CD_LINEOUT) { 3082 snprintf(w->name, sizeof(w->name), "%s-%s", 3083 pin_devices[w->d.pin.device], 3084 line_colors[w->d.pin.color]); 3085 } else if (pins[w->d.pin.device] > 1) { 3086 snprintf(w->name, sizeof(w->name), "%s%d", 3087 pin_devices[w->d.pin.device], 3088 pins[w->d.pin.device]); 3089 } else { 3090 snprintf(w->name, sizeof(w->name), "%s", 3091 pin_devices[w->d.pin.device]); 3092 } 3093 break; 3094 case COP_AWTYPE_AUDIO_OUTPUT: 3095 if (codec->dacs.ngroups < 1) 3096 break; 3097 group = &codec->dacs.groups[0]; 3098 schan = 0; 3099 for (j = 0; j < group->nconv; j++) { 3100 if (w->nid == group->conv[j]) { 3101 snprintf(w->name, sizeof(w->name), 3102 "%s-%d:%d", wtypes[w->type], schan, 3103 schan + WIDGET_CHANNELS(w) - 1); 3104 } 3105 schan += WIDGET_CHANNELS(w); 3106 } 3107 if (codec->dacs.ngroups < 2) 3108 break; 3109 group = &codec->dacs.groups[1]; 3110 schan = 0; 3111 for (j = 0; j < group->nconv; j++) { 3112 if (w->nid == group->conv[j]) { 3113 snprintf(w->name, sizeof(w->name), 3114 "dig-%s-%d:%d", wtypes[w->type], 3115 schan, 3116 schan + WIDGET_CHANNELS(w) - 1); 3117 } 3118 schan += WIDGET_CHANNELS(w); 3119 } 3120 break; 3121 case COP_AWTYPE_AUDIO_INPUT: 3122 w->mixer_class = AZ_CLASS_RECORD; 3123 if (codec->adcs.ngroups < 1) 3124 break; 3125 group = &codec->adcs.groups[0]; 3126 schan = 0; 3127 for (j = 0; j < group->nconv; j++) { 3128 if (w->nid == group->conv[j]) { 3129 snprintf(w->name, sizeof(w->name), 3130 "%s-%d:%d", wtypes[w->type], schan, 3131 schan + WIDGET_CHANNELS(w) - 1); 3132 } 3133 schan += WIDGET_CHANNELS(w); 3134 } 3135 if (codec->adcs.ngroups < 2) 3136 break; 3137 group = &codec->adcs.groups[1]; 3138 schan = 0; 3139 for (j = 0; j < group->nconv; j++) { 3140 if (w->nid == group->conv[j]) { 3141 snprintf(w->name, sizeof(w->name), 3142 "dig-%s-%d:%d", wtypes[w->type], 3143 schan, 3144 schan + WIDGET_CHANNELS(w) - 1); 3145 } 3146 schan += WIDGET_CHANNELS(w); 3147 } 3148 break; 3149 default: 3150 types[w->type]++; 3151 if (types[w->type] > 1) 3152 snprintf(w->name, sizeof(w->name), "%s%d", 3153 wtypes[w->type], types[w->type]); 3154 else 3155 snprintf(w->name, sizeof(w->name), "%s", 3156 wtypes[w->type]); 3157 break; 3158 } 3159 } 3160 3161 /* Mixers and selectors that connect to only one other widget are 3162 * functionally part of the widget they are connected to. Show that 3163 * relationship in the name. 3164 */ 3165 FOR_EACH_WIDGET(codec, i) { 3166 if (codec->w[i].type != COP_AWTYPE_AUDIO_MIXER && 3167 codec->w[i].type != COP_AWTYPE_AUDIO_SELECTOR) 3168 continue; 3169 if (codec->w[i].enable == 0) 3170 continue; 3171 j = azalia_widget_sole_conn(codec, i); 3172 if (j == -1) { 3173 /* Special case. A selector with outamp capabilities 3174 * and is connected to a single widget that has either 3175 * no input or no output capabilities. This widget 3176 * serves as the input or output amp for the widget 3177 * it is connected to. 3178 */ 3179 if (codec->w[i].type == COP_AWTYPE_AUDIO_SELECTOR && 3180 (codec->w[i].widgetcap & COP_AWCAP_OUTAMP) && 3181 codec->w[i].nconnections == 1) { 3182 j = codec->w[i].connections[0]; 3183 if (!azalia_widget_enabled(codec, j)) 3184 continue; 3185 if (!(codec->w[j].widgetcap & COP_AWCAP_INAMP)) 3186 codec->w[i].mixer_class = 3187 AZ_CLASS_INPUT; 3188 else if (!(codec->w[j].widgetcap & COP_AWCAP_OUTAMP)) 3189 codec->w[i].mixer_class = 3190 AZ_CLASS_OUTPUT; 3191 else 3192 continue; 3193 } 3194 } 3195 if (j >= 0) { 3196 /* As part of a disabled widget, this widget 3197 * should be disabled as well. 3198 */ 3199 if (codec->w[j].enable == 0) { 3200 codec->w[i].enable = 0; 3201 snprintf(codec->w[i].name, 3202 sizeof(codec->w[i].name), 3203 "u-wid%2.2x", i); 3204 continue; 3205 } 3206 snprintf(codec->w[i].name, sizeof(codec->w[i].name), 3207 "%s", codec->w[j].name); 3208 if (codec->w[j].mixer_class == AZ_CLASS_RECORD) 3209 codec->w[i].mixer_class = AZ_CLASS_RECORD; 3210 codec->w[i].parent = j; 3211 } 3212 } 3213 3214 return 0; 3215} 3216 3217int 3218azalia_widget_init_audio(widget_t *this, const codec_t *codec) 3219{ 3220 uint32_t result; 3221 int err; 3222 3223 /* check audio format */ 3224 if (this->widgetcap & COP_AWCAP_FORMATOV) { 3225 err = azalia_comresp(codec, this->nid, CORB_GET_PARAMETER, 3226 COP_STREAM_FORMATS, &result); 3227 if (err) 3228 return err; 3229 this->d.audio.encodings = result; 3230 if (result == 0) { /* quirk for CMI9880. 3231 * This must not occur usually... */ 3232 this->d.audio.encodings = 3233 codec->w[codec->audiofunc].d.audio.encodings; 3234 this->d.audio.bits_rates = 3235 codec->w[codec->audiofunc].d.audio.bits_rates; 3236 } else { 3237 if ((result & COP_STREAM_FORMAT_PCM) == 0) { 3238 printf("%s: %s: No PCM support: %x\n", 3239 XNAME(codec->az), this->name, result); 3240 return -1; 3241 } 3242 err = azalia_comresp(codec, this->nid, 3243 CORB_GET_PARAMETER, COP_PCM, &result); 3244 if (err) 3245 return err; 3246 this->d.audio.bits_rates = result; 3247 } 3248 } else { 3249 this->d.audio.encodings = 3250 codec->w[codec->audiofunc].d.audio.encodings; 3251 this->d.audio.bits_rates = 3252 codec->w[codec->audiofunc].d.audio.bits_rates; 3253 } 3254 return 0; 3255} 3256 3257int 3258azalia_widget_init_pin(widget_t *this, const codec_t *codec) 3259{ 3260 uint32_t result, dir; 3261 int err; 3262 3263 err = azalia_comresp(codec, this->nid, CORB_GET_CONFIGURATION_DEFAULT, 3264 0, &result); 3265 if (err) 3266 return err; 3267 this->d.pin.config = result; 3268 this->d.pin.sequence = CORB_CD_SEQUENCE(result); 3269 this->d.pin.association = CORB_CD_ASSOCIATION(result); 3270 this->d.pin.color = CORB_CD_COLOR(result); 3271 this->d.pin.device = CORB_CD_DEVICE(result); 3272 3273 err = azalia_comresp(codec, this->nid, CORB_GET_PARAMETER, 3274 COP_PINCAP, &result); 3275 if (err) 3276 return err; 3277 this->d.pin.cap = result; 3278 3279 dir = CORB_PWC_INPUT; 3280 switch (this->d.pin.device) { 3281 case CORB_CD_LINEOUT: 3282 case CORB_CD_SPEAKER: 3283 case CORB_CD_HEADPHONE: 3284 case CORB_CD_SPDIFOUT: 3285 case CORB_CD_DIGITALOUT: 3286 dir = CORB_PWC_OUTPUT; 3287 break; 3288 } 3289 3290 if (dir == CORB_PWC_INPUT && !(this->d.pin.cap & COP_PINCAP_INPUT)) 3291 dir = CORB_PWC_OUTPUT; 3292 if (dir == CORB_PWC_OUTPUT && !(this->d.pin.cap & COP_PINCAP_OUTPUT)) 3293 dir = CORB_PWC_INPUT; 3294 3295 if (dir == CORB_PWC_INPUT && this->d.pin.device == CORB_CD_MICIN) { 3296 if (COP_PINCAP_VREF(this->d.pin.cap) & (1 << CORB_PWC_VREF_80)) 3297 dir |= CORB_PWC_VREF_80; 3298 else if (COP_PINCAP_VREF(this->d.pin.cap) & 3299 (1 << CORB_PWC_VREF_50)) 3300 dir |= CORB_PWC_VREF_50; 3301 } 3302 3303 if ((codec->qrks & AZ_QRK_WID_OVREF50) && (dir == CORB_PWC_OUTPUT)) 3304 dir |= CORB_PWC_VREF_50; 3305 3306 azalia_comresp(codec, this->nid, CORB_SET_PIN_WIDGET_CONTROL, 3307 dir, NULL); 3308 3309 if (this->d.pin.cap & COP_PINCAP_EAPD) { 3310 err = azalia_comresp(codec, this->nid, 3311 CORB_GET_EAPD_BTL_ENABLE, 0, &result); 3312 if (err) 3313 return err; 3314 result &= 0xff; 3315 result |= CORB_EAPD_EAPD; 3316 err = azalia_comresp(codec, this->nid, 3317 CORB_SET_EAPD_BTL_ENABLE, result, &result); 3318 if (err) 3319 return err; 3320 } 3321 3322 /* Disable unconnected pins */ 3323 if (CORB_CD_PORT(this->d.pin.config) == CORB_CD_NONE) 3324 this->enable = 0; 3325 3326 return 0; 3327} 3328 3329int 3330azalia_widget_init_connection(widget_t *this, const codec_t *codec) 3331{ 3332 uint32_t result; 3333 int err; 3334 int i, j, k; 3335 int length, nconn, bits, conn, last; 3336 3337 this->selected = -1; 3338 if ((this->widgetcap & COP_AWCAP_CONNLIST) == 0) 3339 return 0; 3340 3341 err = azalia_comresp(codec, this->nid, CORB_GET_PARAMETER, 3342 COP_CONNECTION_LIST_LENGTH, &result); 3343 if (err) 3344 return err; 3345 3346 bits = 8; 3347 if (result & COP_CLL_LONG) 3348 bits = 16; 3349 3350 length = COP_CLL_LENGTH(result); 3351 if (length == 0) 3352 return 0; 3353 3354 /* 3355 * 'length' is the number of entries, not the number of 3356 * connections. Find the number of connections, 'nconn', so 3357 * enough space can be allocated for the list of connected 3358 * nids. 3359 */ 3360 nconn = last = 0; 3361 for (i = 0; i < length;) { 3362 err = azalia_comresp(codec, this->nid, 3363 CORB_GET_CONNECTION_LIST_ENTRY, i, &result); 3364 if (err) 3365 return err; 3366 for (k = 0; i < length && (k < 32 / bits); k++) { 3367 conn = (result >> (k * bits)) & ((1 << bits) - 1); 3368 /* If high bit is set, this is the end of a continuous 3369 * list that started with the last connection. 3370 */ 3371 if ((nconn > 0) && (conn & (1 << (bits - 1)))) 3372 nconn += (conn & ~(1 << (bits - 1))) - last; 3373 else 3374 nconn++; 3375 last = conn; 3376 i++; 3377 } 3378 } 3379 3380 this->connections = mallocarray(nconn, sizeof(nid_t), M_DEVBUF, M_NOWAIT); 3381 if (this->connections == NULL) { 3382 printf("%s: out of memory\n", XNAME(codec->az)); 3383 return ENOMEM; 3384 } 3385 for (i = 0; i < nconn;) { 3386 err = azalia_comresp(codec, this->nid, 3387 CORB_GET_CONNECTION_LIST_ENTRY, i, &result); 3388 if (err) 3389 return err; 3390 for (k = 0; i < nconn && (k < 32 / bits); k++) { 3391 conn = (result >> (k * bits)) & ((1 << bits) - 1); 3392 /* If high bit is set, this is the end of a continuous 3393 * list that started with the last connection. 3394 */ 3395 if ((i > 0) && (conn & (1 << (bits - 1)))) { 3396 for (j = 1; i < nconn && j <= conn - last; j++) 3397 this->connections[i++] = last + j; 3398 } else { 3399 this->connections[i++] = conn; 3400 } 3401 last = conn; 3402 } 3403 } 3404 this->nconnections = nconn; 3405 3406 if (nconn > 0) { 3407 err = azalia_comresp(codec, this->nid, 3408 CORB_GET_CONNECTION_SELECT_CONTROL, 0, &result); 3409 if (err) 3410 return err; 3411 this->selected = CORB_CSC_INDEX(result); 3412 } 3413 return 0; 3414} 3415 3416int 3417azalia_widget_check_conn(codec_t *codec, int index, int depth) 3418{ 3419 const widget_t *w; 3420 int i; 3421 3422 w = &codec->w[index]; 3423 3424 if (w->type == COP_AWTYPE_BEEP_GENERATOR) 3425 return 0; 3426 3427 if (depth > 0 && 3428 (w->type == COP_AWTYPE_PIN_COMPLEX || 3429 w->type == COP_AWTYPE_AUDIO_OUTPUT || 3430 w->type == COP_AWTYPE_AUDIO_INPUT)) { 3431 if (w->enable) 3432 return 1; 3433 else 3434 return 0; 3435 } 3436 if (++depth >= 10) 3437 return 0; 3438 for (i = 0; i < w->nconnections; i++) { 3439 if (!azalia_widget_enabled(codec, w->connections[i])) 3440 continue; 3441 if (azalia_widget_check_conn(codec, w->connections[i], depth)) 3442 return 1; 3443 } 3444 return 0; 3445} 3446 3447#ifdef AZALIA_DEBUG 3448 3449#define WIDGETCAP_BITS \ 3450 "\20\014LRSWAP\013POWER\012DIGITAL" \ 3451 "\011CONNLIST\010UNSOL\07PROC\06STRIPE\05FORMATOV\04AMPOV\03OUTAMP" \ 3452 "\02INAMP\01STEREO" 3453 3454#define PINCAP_BITS "\20\021EAPD\16VREF100\15VREF80" \ 3455 "\13VREFGND\12VREF50\11VREFHIZ\07BALANCE\06INPUT" \ 3456 "\05OUTPUT\04HEADPHONE\03PRESENCE\02TRIGGER\01IMPEDANCE" 3457 3458#define ENCODING_BITS "\20\3AC3\2FLOAT32\1PCM" 3459 3460#define BITSRATES_BITS "\20\x15""32bit\x14""24bit\x13""20bit" \ 3461 "\x12""16bit\x11""8bit""\x0c""384kHz\x0b""192kHz\x0a""176.4kHz" \ 3462 "\x09""96kHz\x08""88.2kHz\x07""48kHz\x06""44.1kHz\x05""32kHz\x04" \ 3463 "22.05kHz\x03""16kHz\x02""11.025kHz\x01""8kHz" 3464 3465static const char *pin_colors[16] = { 3466 "unknown", "black", "gray", "blue", 3467 "green", "red", "orange", "yellow", 3468 "purple", "pink", "col0a", "col0b", 3469 "col0c", "col0d", "white", "other"}; 3470static const char *pin_conn[4] = { 3471 "jack", "none", "fixed", "combined"}; 3472static const char *pin_conntype[16] = { 3473 "unknown", "1/8", "1/4", "atapi", "rca", "optical", 3474 "digital", "analog", "din", "xlr", "rj-11", "combination", 3475 "con0c", "con0d", "con0e", "other"}; 3476static const char *pin_geo[15] = { 3477 "n/a", "rear", "front", "left", 3478 "right", "top", "bottom", "spec0", "spec1", "spec2", 3479 "loc0a", "loc0b", "loc0c", "loc0d", "loc0f"}; 3480static const char *pin_chass[4] = { 3481 "external", "internal", "separate", "other"}; 3482 3483void 3484azalia_codec_print_audiofunc(const codec_t *this) 3485{ 3486 uint32_t result; 3487 3488 azalia_widget_print_audio(&this->w[this->audiofunc], "\t"); 3489 3490 result = this->w[this->audiofunc].inamp_cap; 3491 DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n", 3492 (result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result), 3493 COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result))); 3494 result = this->w[this->audiofunc].outamp_cap; 3495 DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n", 3496 (result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result), 3497 COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result))); 3498 azalia_comresp(this, this->audiofunc, CORB_GET_PARAMETER, 3499 COP_GPIO_COUNT, &result); 3500 DPRINTF(("\tgpio: wake=%u unsol=%u gpis=%u gpos=%u gpios=%u\n", 3501 (result & COP_GPIO_WAKE) != 0, (result & COP_GPIO_UNSOL) != 0, 3502 COP_GPIO_GPIS(result), COP_GPIO_GPOS(result), 3503 COP_GPIO_GPIOS(result))); 3504} 3505 3506void 3507azalia_codec_print_groups(const codec_t *this) 3508{ 3509 int i, n; 3510 3511 for (i = 0; i < this->dacs.ngroups; i++) { 3512 printf("%s: dacgroup[%d]:", XNAME(this->az), i); 3513 for (n = 0; n < this->dacs.groups[i].nconv; n++) { 3514 printf(" %2.2x", this->dacs.groups[i].conv[n]); 3515 } 3516 printf("\n"); 3517 } 3518 for (i = 0; i < this->adcs.ngroups; i++) { 3519 printf("%s: adcgroup[%d]:", XNAME(this->az), i); 3520 for (n = 0; n < this->adcs.groups[i].nconv; n++) { 3521 printf(" %2.2x", this->adcs.groups[i].conv[n]); 3522 } 3523 printf("\n"); 3524 } 3525} 3526 3527void 3528azalia_widget_print_audio(const widget_t *this, const char *lead) 3529{ 3530 printf("%sencodings=%b\n", lead, this->d.audio.encodings, 3531 ENCODING_BITS); 3532 printf("%sPCM formats=%b\n", lead, this->d.audio.bits_rates, 3533 BITSRATES_BITS); 3534} 3535 3536void 3537azalia_widget_print_widget(const widget_t *w, const codec_t *codec) 3538{ 3539 int i; 3540 3541 printf("%s: ", XNAME(codec->az)); 3542 printf("%s%2.2x wcap=%b\n", w->type == COP_AWTYPE_PIN_COMPLEX ? 3543 pin_colors[w->d.pin.color] : wtypes[w->type], 3544 w->nid, w->widgetcap, WIDGETCAP_BITS); 3545 if (w->widgetcap & COP_AWCAP_FORMATOV) 3546 azalia_widget_print_audio(w, "\t"); 3547 if (w->type == COP_AWTYPE_PIN_COMPLEX) 3548 azalia_widget_print_pin(w); 3549 3550 if (w->type == COP_AWTYPE_VOLUME_KNOB) 3551 printf("\tdelta=%d steps=%d\n", 3552 !!(w->d.volume.cap & COP_VKCAP_DELTA), 3553 COP_VKCAP_NUMSTEPS(w->d.volume.cap)); 3554 3555 if ((w->widgetcap & COP_AWCAP_INAMP) && 3556 (w->widgetcap & COP_AWCAP_AMPOV)) 3557 printf("\tinamp: mute=%u size=%u steps=%u offset=%u\n", 3558 (w->inamp_cap & COP_AMPCAP_MUTE) != 0, 3559 COP_AMPCAP_STEPSIZE(w->inamp_cap), 3560 COP_AMPCAP_NUMSTEPS(w->inamp_cap), 3561 COP_AMPCAP_OFFSET(w->inamp_cap)); 3562 3563 if ((w->widgetcap & COP_AWCAP_OUTAMP) && 3564 (w->widgetcap & COP_AWCAP_AMPOV)) 3565 printf("\toutamp: mute=%u size=%u steps=%u offset=%u\n", 3566 (w->outamp_cap & COP_AMPCAP_MUTE) != 0, 3567 COP_AMPCAP_STEPSIZE(w->outamp_cap), 3568 COP_AMPCAP_NUMSTEPS(w->outamp_cap), 3569 COP_AMPCAP_OFFSET(w->outamp_cap)); 3570 3571 if (w->nconnections > 0) { 3572 printf("\tconnections=0x%x", w->connections[0]); 3573 for (i = 1; i < w->nconnections; i++) 3574 printf(",0x%x", w->connections[i]); 3575 printf("; selected=0x%x\n", w->connections[w->selected]); 3576 } 3577} 3578 3579void 3580azalia_widget_print_pin(const widget_t *this) 3581{ 3582 printf("\tcap=%b\n", this->d.pin.cap, PINCAP_BITS); 3583 printf("\t[%2.2d/%2.2d] ", CORB_CD_ASSOCIATION(this->d.pin.config), 3584 CORB_CD_SEQUENCE(this->d.pin.config)); 3585 printf("color=%s ", pin_colors[CORB_CD_COLOR(this->d.pin.config)]); 3586 printf("device=%s ", pin_devices[CORB_CD_DEVICE(this->d.pin.config)]); 3587 printf("conn=%s ", pin_conn[CORB_CD_PORT(this->d.pin.config)]); 3588 printf("conntype=%s\n", pin_conntype[CORB_CD_CONNECTION(this->d.pin.config)]); 3589 printf("\tlocation=%s ", pin_geo[CORB_CD_LOC_GEO(this->d.pin.config)]); 3590 printf("chassis=%s ", pin_chass[CORB_CD_LOC_CHASS(this->d.pin.config)]); 3591 printf("special="); 3592 if (CORB_CD_LOC_GEO(this->d.pin.config) == CORB_CD_LOC_SPEC0) { 3593 if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_EXTERNAL) 3594 printf("rear-panel"); 3595 else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_INTERNAL) 3596 printf("riser"); 3597 else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_LOC_OTHER) 3598 printf("mobile-lid-internal"); 3599 } else if (CORB_CD_LOC_GEO(this->d.pin.config) == CORB_CD_LOC_SPEC1) { 3600 if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_EXTERNAL) 3601 printf("drive-bay"); 3602 else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_INTERNAL) 3603 printf("hdmi"); 3604 else if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_LOC_OTHER) 3605 printf("mobile-lid-external"); 3606 } else if (CORB_CD_LOC_GEO(this->d.pin.config) == CORB_CD_LOC_SPEC2) { 3607 if (CORB_CD_LOC_CHASS(this->d.pin.config) == CORB_CD_INTERNAL) 3608 printf("atapi"); 3609 } else 3610 printf("none"); 3611 printf("\n"); 3612} 3613 3614#else /* AZALIA_DEBUG */ 3615 3616void 3617azalia_codec_print_audiofunc(const codec_t *this) {} 3618 3619void 3620azalia_codec_print_groups(const codec_t *this) {} 3621 3622void 3623azalia_widget_print_audio(const widget_t *this, const char *lead) {} 3624 3625void 3626azalia_widget_print_widget(const widget_t *w, const codec_t *codec) {} 3627 3628void 3629azalia_widget_print_pin(const widget_t *this) {} 3630 3631#endif /* AZALIA_DEBUG */ 3632 3633/* ================================================================ 3634 * Stream functions 3635 * ================================================================ */ 3636 3637int 3638azalia_stream_init(stream_t *this, azalia_t *az, int regindex, int strnum, 3639 int dir) 3640{ 3641 int err; 3642 3643 this->az = az; 3644 this->regbase = HDA_SD_BASE + regindex * HDA_SD_SIZE; 3645 this->intr_bit = 1 << regindex; 3646 this->number = strnum; 3647 this->dir = dir; 3648 3649 /* setup BDL buffers */ 3650 err = azalia_alloc_dmamem(az, sizeof(bdlist_entry_t) * HDA_BDL_MAX, 3651 128, &this->bdlist); 3652 if (err) { 3653 printf("%s: can't allocate a BDL buffer\n", XNAME(az)); 3654 return err; 3655 } 3656 return 0; 3657} 3658 3659int 3660azalia_stream_reset(stream_t *this) 3661{ 3662 int i; 3663 uint16_t ctl; 3664 uint8_t sts; 3665 3666 /* Make sure RUN bit is zero before resetting */ 3667 ctl = STR_READ_2(this, CTL); 3668 ctl &= ~HDA_SD_CTL_RUN; 3669 STR_WRITE_2(this, CTL, ctl); 3670 DELAY(40); 3671 3672 /* Start reset and wait for chip to enter. */ 3673 ctl = STR_READ_2(this, CTL); 3674 STR_WRITE_2(this, CTL, ctl | HDA_SD_CTL_SRST); 3675 for (i = 5000; i > 0; i--) { 3676 DELAY(10); 3677 ctl = STR_READ_2(this, CTL); 3678 if (ctl & HDA_SD_CTL_SRST) 3679 break; 3680 } 3681 if (i == 0) { 3682 DPRINTF(("%s: stream reset failure 1\n", XNAME(this->az))); 3683 return -1; 3684 } 3685 3686 /* Clear reset and wait for chip to finish */ 3687 STR_WRITE_2(this, CTL, ctl & ~HDA_SD_CTL_SRST); 3688 for (i = 5000; i > 0; i--) { 3689 DELAY(10); 3690 ctl = STR_READ_2(this, CTL); 3691 if ((ctl & HDA_SD_CTL_SRST) == 0) 3692 break; 3693 } 3694 if (i == 0) { 3695 DPRINTF(("%s: stream reset failure 2\n", XNAME(this->az))); 3696 return -1; 3697 } 3698 3699 sts = STR_READ_1(this, STS); 3700 sts |= HDA_SD_STS_DESE | HDA_SD_STS_FIFOE | HDA_SD_STS_BCIS; 3701 STR_WRITE_1(this, STS, sts); 3702 3703 return (0); 3704} 3705 3706int 3707azalia_stream_start(stream_t *this) 3708{ 3709 bdlist_entry_t *bdlist; 3710 bus_addr_t dmaaddr, dmaend; 3711 int err, index; 3712 uint8_t ctl2; 3713 3714 err = azalia_stream_reset(this); 3715 if (err) { 3716 DPRINTF(("%s: stream reset failed\n", "azalia")); 3717 return err; 3718 } 3719 3720 STR_WRITE_4(this, BDPL, 0); 3721 STR_WRITE_4(this, BDPU, 0); 3722 3723 /* setup BDL */ 3724 dmaaddr = AZALIA_DMA_DMAADDR(&this->buffer); 3725 dmaend = dmaaddr + this->bufsize; 3726 bdlist = (bdlist_entry_t*)this->bdlist.addr; 3727 for (index = 0; index < HDA_BDL_MAX; index++) { 3728 bdlist[index].low = htole32(dmaaddr); 3729 bdlist[index].high = htole32(PTR_UPPER32(dmaaddr)); 3730 bdlist[index].length = htole32(this->blk); 3731 bdlist[index].flags = htole32(BDLIST_ENTRY_IOC); 3732 dmaaddr += this->blk; 3733 if (dmaaddr >= dmaend) { 3734 index++; 3735 break; 3736 } 3737 } 3738 3739 DPRINTFN(1, ("%s: size=%d fmt=0x%4.4x index=%d\n", 3740 __func__, this->bufsize, this->fmt, index)); 3741 3742 dmaaddr = AZALIA_DMA_DMAADDR(&this->bdlist); 3743 STR_WRITE_4(this, BDPL, dmaaddr); 3744 STR_WRITE_4(this, BDPU, PTR_UPPER32(dmaaddr)); 3745 STR_WRITE_2(this, LVI, (index - 1) & HDA_SD_LVI_LVI); 3746 ctl2 = STR_READ_1(this, CTL2); 3747 STR_WRITE_1(this, CTL2, 3748 (ctl2 & ~HDA_SD_CTL2_STRM) | (this->number << HDA_SD_CTL2_STRM_SHIFT)); 3749 STR_WRITE_4(this, CBL, this->bufsize); 3750 STR_WRITE_2(this, FMT, this->fmt); 3751 3752 err = azalia_codec_connect_stream(this); 3753 if (err) 3754 return EINVAL; 3755 3756 this->az->intctl |= this->intr_bit; 3757 AZ_WRITE_4(this->az, INTCTL, this->az->intctl); 3758 3759 STR_WRITE_1(this, CTL, STR_READ_1(this, CTL) | 3760 HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | 3761 HDA_SD_CTL_RUN); 3762 return (0); 3763} 3764 3765int 3766azalia_stream_halt(stream_t *this) 3767{ 3768 uint16_t ctl; 3769 3770 ctl = STR_READ_2(this, CTL); 3771 ctl &= ~(HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | HDA_SD_CTL_RUN); 3772 STR_WRITE_2(this, CTL, ctl); 3773 this->az->intctl &= ~this->intr_bit; 3774 AZ_WRITE_4(this->az, INTCTL, this->az->intctl); 3775 azalia_codec_disconnect_stream(this); 3776 3777 return (0); 3778} 3779 3780#define HDA_SD_STS_BITS "\20\3BCIS\4FIFOE\5DESE\6FIFORDY" 3781 3782int 3783azalia_stream_intr(stream_t *this) 3784{ 3785 unsigned int lpib, fifos, hwpos, cnt; 3786 u_int8_t sts; 3787 3788 sts = STR_READ_1(this, STS); 3789 STR_WRITE_1(this, STS, sts | 3790 HDA_SD_STS_DESE | HDA_SD_STS_FIFOE | HDA_SD_STS_BCIS); 3791 3792 if (sts & (HDA_SD_STS_DESE | HDA_SD_STS_FIFOE)) 3793 DPRINTF(("%s: stream %d: sts=%b\n", XNAME(this->az), 3794 this->number, sts, HDA_SD_STS_BITS)); 3795 3796 if (sts & HDA_SD_STS_BCIS) { 3797 lpib = STR_READ_4(this, LPIB); 3798 fifos = STR_READ_2(this, FIFOS); 3799 if (fifos & 1) 3800 fifos++; 3801 hwpos = lpib; 3802 if (this->dir == AUMODE_PLAY) 3803 hwpos += fifos + 1; 3804 if (hwpos >= this->bufsize) 3805 hwpos -= this->bufsize; 3806 DPRINTFN(2, ("%s: stream %d, pos = %d -> %d, " 3807 "lpib = %u, fifos = %u\n", __func__, 3808 this->number, this->swpos, hwpos, lpib, fifos)); 3809 cnt = 0; 3810 while (hwpos - this->swpos >= this->blk) { 3811 this->intr(this->intr_arg); 3812 this->swpos += this->blk; 3813 if (this->swpos == this->bufsize) 3814 this->swpos = 0; 3815 cnt++; 3816 } 3817 if (cnt != 1) { 3818 DPRINTF(("%s: stream %d: hwpos %u, %u intrs\n", 3819 __func__, this->number, this->swpos, cnt)); 3820 } 3821 } 3822 return (1); 3823} 3824 3825/* ================================================================ 3826 * MI audio entries 3827 * ================================================================ */ 3828 3829int 3830azalia_open(void *v, int flags) 3831{ 3832 azalia_t *az; 3833 codec_t *codec; 3834 3835 DPRINTFN(1, ("%s: flags=0x%x\n", __func__, flags)); 3836 az = v; 3837 codec = &az->codecs[az->codecno]; 3838 if ((flags & FWRITE) && codec->dacs.ngroups == 0) 3839 return ENODEV; 3840 if ((flags & FREAD) && codec->adcs.ngroups == 0) 3841 return ENODEV; 3842 codec->running++; 3843 return 0; 3844} 3845 3846void 3847azalia_close(void *v) 3848{ 3849 azalia_t *az; 3850 codec_t *codec; 3851 3852 DPRINTFN(1, ("%s\n", __func__)); 3853 az = v; 3854 codec = &az->codecs[az->codecno]; 3855 codec->running--; 3856} 3857 3858int 3859azalia_match_format(codec_t *codec, int mode, audio_params_t *par) 3860{ 3861 int i; 3862 3863 DPRINTFN(1, ("%s: mode=%d, want: enc=%d, prec=%d, chans=%d\n", __func__, 3864 mode, par->encoding, par->precision, par->channels)); 3865 3866 for (i = 0; i < codec->nformats; i++) { 3867 if (mode != codec->formats[i].mode) 3868 continue; 3869 if (par->encoding != codec->formats[i].encoding) 3870 continue; 3871 if (par->precision != codec->formats[i].precision) 3872 continue; 3873 if (par->channels != codec->formats[i].channels) 3874 continue; 3875 break; 3876 } 3877 3878 DPRINTFN(1, ("%s: return: enc=%d, prec=%d, chans=%d\n", __func__, 3879 codec->formats[i].encoding, codec->formats[i].precision, 3880 codec->formats[i].channels)); 3881 3882 return (i); 3883} 3884 3885int 3886azalia_set_params_sub(codec_t *codec, int mode, audio_params_t *par) 3887{ 3888 int i, j; 3889 uint ochan, oenc, opre; 3890#ifdef AZALIA_DEBUG 3891 char *cmode = (mode == AUMODE_PLAY) ? "play" : "record"; 3892#endif 3893 3894 ochan = par->channels; 3895 oenc = par->encoding; 3896 opre = par->precision; 3897 3898 if ((mode == AUMODE_PLAY && codec->dacs.ngroups == 0) || 3899 (mode == AUMODE_RECORD && codec->adcs.ngroups == 0)) 3900 return 0; 3901 3902 i = azalia_match_format(codec, mode, par); 3903 if (i == codec->nformats && (par->precision != 16 || par->encoding != 3904 AUDIO_ENCODING_SLINEAR_LE)) { 3905 /* try with default encoding/precision */ 3906 par->encoding = AUDIO_ENCODING_SLINEAR_LE; 3907 par->precision = 16; 3908 i = azalia_match_format(codec, mode, par); 3909 } 3910 if (i == codec->nformats && par->channels != 2) { 3911 /* try with default channels */ 3912 par->encoding = oenc; 3913 par->precision = opre; 3914 par->channels = 2; 3915 i = azalia_match_format(codec, mode, par); 3916 } 3917 /* try with default everything */ 3918 if (i == codec->nformats) { 3919 par->encoding = AUDIO_ENCODING_SLINEAR_LE; 3920 par->precision = 16; 3921 par->channels = 2; 3922 i = azalia_match_format(codec, mode, par); 3923 if (i == codec->nformats) { 3924 DPRINTF(("%s: can't find %s format %u/%u/%u\n", 3925 __func__, cmode, par->encoding, 3926 par->precision, par->channels)); 3927 return EINVAL; 3928 } 3929 } 3930 if (codec->formats[i].frequency_type == 0) { 3931 DPRINTF(("%s: matched %s format %d has 0 frequencies\n", 3932 __func__, cmode, i)); 3933 return EINVAL; 3934 } 3935 3936 for (j = 0; j < codec->formats[i].frequency_type; j++) { 3937 if (par->sample_rate != codec->formats[i].frequency[j]) 3938 continue; 3939 break; 3940 } 3941 if (j == codec->formats[i].frequency_type) { 3942 /* try again with default */ 3943 par->sample_rate = 48000; 3944 for (j = 0; j < codec->formats[i].frequency_type; j++) { 3945 if (par->sample_rate != codec->formats[i].frequency[j]) 3946 continue; 3947 break; 3948 } 3949 if (j == codec->formats[i].frequency_type) { 3950 DPRINTF(("%s: can't find %s rate %lu\n", 3951 __func__, cmode, par->sample_rate)); 3952 return EINVAL; 3953 } 3954 } 3955 par->bps = AUDIO_BPS(par->precision); 3956 par->msb = 1; 3957 3958 return (0); 3959} 3960 3961int 3962azalia_set_params(void *v, int smode, int umode, audio_params_t *p, 3963 audio_params_t *r) 3964{ 3965 azalia_t *az; 3966 codec_t *codec; 3967 int ret; 3968 3969 az = v; 3970 codec = &az->codecs[az->codecno]; 3971 if (codec->nformats == 0) { 3972 DPRINTF(("%s: codec has no formats\n", __func__)); 3973 return EINVAL; 3974 } 3975 3976 if (smode & AUMODE_RECORD && r != NULL) { 3977 ret = azalia_set_params_sub(codec, AUMODE_RECORD, r); 3978 if (ret) 3979 return (ret); 3980 } 3981 3982 if (smode & AUMODE_PLAY && p != NULL) { 3983 ret = azalia_set_params_sub(codec, AUMODE_PLAY, p); 3984 if (ret) 3985 return (ret); 3986 } 3987 3988 return (0); 3989} 3990 3991unsigned int 3992azalia_set_blksz(void *v, int mode, 3993 struct audio_params *p, struct audio_params *r, unsigned int blksz) 3994{ 3995 int mult; 3996 3997 /* must be multiple of 128 bytes */ 3998 mult = audio_blksz_bytes(mode, p, r, 128); 3999 4000 blksz -= blksz % mult; 4001 if (blksz == 0) 4002 blksz = mult; 4003 4004 return blksz; 4005} 4006 4007unsigned int 4008azalia_set_nblks(void *v, int mode, 4009 struct audio_params *params, unsigned int blksz, unsigned int nblks) 4010{ 4011 /* number of blocks must be <= HDA_BDL_MAX */ 4012 if (nblks > HDA_BDL_MAX) 4013 nblks = HDA_BDL_MAX; 4014 4015 return nblks; 4016} 4017 4018int 4019azalia_halt_output(void *v) 4020{ 4021 azalia_t *az; 4022 4023 DPRINTFN(1, ("%s\n", __func__)); 4024 az = v; 4025 return azalia_stream_halt(&az->pstream); 4026} 4027 4028int 4029azalia_halt_input(void *v) 4030{ 4031 azalia_t *az; 4032 4033 DPRINTFN(1, ("%s\n", __func__)); 4034 az = v; 4035 return azalia_stream_halt(&az->rstream); 4036} 4037 4038int 4039azalia_set_port(void *v, mixer_ctrl_t *mc) 4040{ 4041 azalia_t *az; 4042 codec_t *co; 4043 const mixer_item_t *m; 4044 4045 az = v; 4046 co = &az->codecs[az->codecno]; 4047 if (mc->dev < 0 || mc->dev >= co->nmixers) 4048 return EINVAL; 4049 4050 m = &co->mixers[mc->dev]; 4051 if (mc->type != m->devinfo.type) 4052 return EINVAL; 4053 4054 return azalia_mixer_set(co, m->nid, m->target, mc); 4055} 4056 4057int 4058azalia_get_port(void *v, mixer_ctrl_t *mc) 4059{ 4060 azalia_t *az; 4061 codec_t *co; 4062 const mixer_item_t *m; 4063 4064 az = v; 4065 co = &az->codecs[az->codecno]; 4066 if (mc->dev < 0 || mc->dev >= co->nmixers) 4067 return EINVAL; 4068 4069 m = &co->mixers[mc->dev]; 4070 mc->type = m->devinfo.type; 4071 4072 return azalia_mixer_get(co, m->nid, m->target, mc); 4073} 4074 4075int 4076azalia_query_devinfo(void *v, mixer_devinfo_t *mdev) 4077{ 4078 azalia_t *az; 4079 const codec_t *co; 4080 4081 az = v; 4082 co = &az->codecs[az->codecno]; 4083 if (mdev->index < 0 || mdev->index >= co->nmixers) 4084 return ENXIO; 4085 *mdev = co->mixers[mdev->index].devinfo; 4086 return 0; 4087} 4088 4089void * 4090azalia_allocm(void *v, int dir, size_t size, int pool, int flags) 4091{ 4092 azalia_t *az; 4093 stream_t *stream; 4094 int err; 4095 4096 az = v; 4097 stream = dir == AUMODE_PLAY ? &az->pstream : &az->rstream; 4098 err = azalia_alloc_dmamem(az, size, 128, &stream->buffer); 4099 if (err) { 4100 printf("%s: allocm failed\n", az->dev.dv_xname); 4101 return NULL; 4102 } 4103 return stream->buffer.addr; 4104} 4105 4106void 4107azalia_freem(void *v, void *addr, int pool) 4108{ 4109 azalia_t *az; 4110 stream_t *stream; 4111 4112 az = v; 4113 if (addr == az->pstream.buffer.addr) { 4114 stream = &az->pstream; 4115 } else if (addr == az->rstream.buffer.addr) { 4116 stream = &az->rstream; 4117 } else { 4118 return; 4119 } 4120 azalia_free_dmamem(az, &stream->buffer); 4121} 4122 4123size_t 4124azalia_round_buffersize(void *v, int dir, size_t size) 4125{ 4126 size &= ~0x7f; /* must be multiple of 128 */ 4127 if (size <= 0) 4128 size = 128; 4129 return size; 4130} 4131 4132int 4133azalia_trigger_output(void *v, void *start, void *end, int blk, 4134 void (*intr)(void *), void *arg, audio_params_t *param) 4135{ 4136 azalia_t *az; 4137 int err; 4138 uint16_t fmt; 4139 4140 az = v; 4141 4142 if (az->codecs[az->codecno].dacs.ngroups == 0) { 4143 DPRINTF(("%s: can't play without a DAC\n", __func__)); 4144 return ENXIO; 4145 } 4146 4147 err = azalia_params2fmt(param, &fmt); 4148 if (err) 4149 return(EINVAL); 4150 4151 az->pstream.bufsize = (caddr_t)end - (caddr_t)start; 4152 az->pstream.blk = blk; 4153 az->pstream.fmt = fmt; 4154 az->pstream.intr = intr; 4155 az->pstream.intr_arg = arg; 4156 az->pstream.swpos = 0; 4157 4158 return azalia_stream_start(&az->pstream); 4159} 4160 4161int 4162azalia_trigger_input(void *v, void *start, void *end, int blk, 4163 void (*intr)(void *), void *arg, audio_params_t *param) 4164{ 4165 azalia_t *az; 4166 int err; 4167 uint16_t fmt; 4168 4169 DPRINTFN(1, ("%s: this=%p start=%p end=%p blk=%d {enc=%u %uch %ubit %luHz}\n", 4170 __func__, v, start, end, blk, param->encoding, param->channels, 4171 param->precision, param->sample_rate)); 4172 4173 az = v; 4174 4175 if (az->codecs[az->codecno].adcs.ngroups == 0) { 4176 DPRINTF(("%s: can't record without an ADC\n", __func__)); 4177 return ENXIO; 4178 } 4179 4180 err = azalia_params2fmt(param, &fmt); 4181 if (err) 4182 return(EINVAL); 4183 4184 az->rstream.bufsize = (caddr_t)end - (caddr_t)start; 4185 az->rstream.blk = blk; 4186 az->rstream.fmt = fmt; 4187 az->rstream.intr = intr; 4188 az->rstream.intr_arg = arg; 4189 az->rstream.swpos = 0; 4190 4191 return azalia_stream_start(&az->rstream); 4192} 4193 4194/* -------------------------------- 4195 * helpers for MI audio functions 4196 * -------------------------------- */ 4197int 4198azalia_params2fmt(const audio_params_t *param, uint16_t *fmt) 4199{ 4200 uint16_t ret; 4201 4202 ret = 0; 4203 if (param->channels > HDA_MAX_CHANNELS) { 4204 printf("%s: too many channels: %u\n", __func__, 4205 param->channels); 4206 return EINVAL; 4207 } 4208 4209 DPRINTFN(1, ("%s: prec=%d, chan=%d, rate=%ld\n", __func__, 4210 param->precision, param->channels, param->sample_rate)); 4211 4212 /* XXX: can channels be >2 ? */ 4213 ret |= param->channels - 1; 4214 4215 switch (param->precision) { 4216 case 8: 4217 ret |= HDA_SD_FMT_BITS_8_16; 4218 break; 4219 case 16: 4220 ret |= HDA_SD_FMT_BITS_16_16; 4221 break; 4222 case 20: 4223 ret |= HDA_SD_FMT_BITS_20_32; 4224 break; 4225 case 24: 4226 ret |= HDA_SD_FMT_BITS_24_32; 4227 break; 4228 case 32: 4229 ret |= HDA_SD_FMT_BITS_32_32; 4230 break; 4231 } 4232 4233 switch (param->sample_rate) { 4234 default: 4235 case 384000: 4236 printf("%s: invalid sample_rate: %lu\n", __func__, 4237 param->sample_rate); 4238 return EINVAL; 4239 case 192000: 4240 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X4 | HDA_SD_FMT_DIV_BY1; 4241 break; 4242 case 176400: 4243 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X4 | HDA_SD_FMT_DIV_BY1; 4244 break; 4245 case 96000: 4246 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY1; 4247 break; 4248 case 88200: 4249 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY1; 4250 break; 4251 case 48000: 4252 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY1; 4253 break; 4254 case 44100: 4255 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY1; 4256 break; 4257 case 32000: 4258 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY3; 4259 break; 4260 case 22050: 4261 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY2; 4262 break; 4263 case 16000: 4264 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY3; 4265 break; 4266 case 11025: 4267 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY4; 4268 break; 4269 case 8000: 4270 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY6; 4271 break; 4272 } 4273 *fmt = ret; 4274 return 0; 4275} 4276