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