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