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