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