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