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