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