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