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