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