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