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