hdac.c revision 179205
162590Sitojun/*- 2122615Sume * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> 362590Sitojun * Copyright (c) 2006 Ariff Abdullah <ariff@FreeBSD.org> 455505Sshin * All rights reserved. 555505Sshin * 655505Sshin * Redistribution and use in source and binary forms, with or without 755505Sshin * modification, are permitted provided that the following conditions 855505Sshin * are met: 955505Sshin * 1. Redistributions of source code must retain the above copyright 1055505Sshin * notice, this list of conditions and the following disclaimer. 1155505Sshin * 2. Redistributions in binary form must reproduce the above copyright 1255505Sshin * notice, this list of conditions and the following disclaimer in the 1355505Sshin * documentation and/or other materials provided with the distribution. 1455505Sshin * 1555505Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1655505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1755505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1855505Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1955505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2055505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2155505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2255505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2355505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2455505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2555505Sshin * SUCH DAMAGE. 2655505Sshin */ 2755505Sshin 2855505Sshin/* 2955505Sshin * Intel High Definition Audio (Controller) driver for FreeBSD. Be advised 3055505Sshin * that this driver still in its early stage, and possible of rewrite are 3155505Sshin * pretty much guaranteed. There are supposedly several distinct parent/child 3255505Sshin * busses to make this "perfect", but as for now and for the sake of 3355505Sshin * simplicity, everything is gobble up within single source. 3455505Sshin * 3555505Sshin * List of subsys: 3655505Sshin * 1) HDA Controller support 3755505Sshin * 2) HDA Codecs support, which may include 3855505Sshin * - HDA 3955505Sshin * - Modem 4055505Sshin * - HDMI 4155505Sshin * 3) Widget parser - the real magic of why this driver works on so 4255505Sshin * many hardwares with minimal vendor specific quirk. The original 4355505Sshin * parser was written using Ruby and can be found at 4455505Sshin * http://people.freebsd.org/~ariff/HDA/parser.rb . This crude 4555505Sshin * ruby parser take the verbose dmesg dump as its input. Refer to 4655505Sshin * http://www.microsoft.com/whdc/device/audio/default.mspx for various 4755505Sshin * interesting documents, especially UAA (Universal Audio Architecture). 4855505Sshin * 4) Possible vendor specific support. 4955505Sshin * (snd_hda_intel, snd_hda_ati, etc..) 5055505Sshin * 5155505Sshin * Thanks to Ahmad Ubaidah Omar @ Defenxis Sdn. Bhd. for the 5255505Sshin * Compaq V3000 with Conexant HDA. 5355505Sshin * 5455505Sshin * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 5555505Sshin * * * 5655505Sshin * * This driver is a collaborative effort made by: * 5755505Sshin * * * 5855505Sshin * * Stephane E. Potvin <sepotvin@videotron.ca> * 5955505Sshin * * Andrea Bittau <a.bittau@cs.ucl.ac.uk> * 6055505Sshin * * Wesley Morgan <morganw@chemikals.org> * 6155505Sshin * * Daniel Eischen <deischen@FreeBSD.org> * 6255505Sshin * * Maxime Guillaud <bsd-ports@mguillaud.net> * 6355505Sshin * * Ariff Abdullah <ariff@FreeBSD.org> * 6455505Sshin * * * 6555505Sshin * * ....and various people from freebsd-multimedia@FreeBSD.org * 6655505Sshin * * * 6755505Sshin * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 6855505Sshin */ 6955505Sshin 7055505Sshin#include <dev/sound/pcm/sound.h> 7155505Sshin#include <dev/pci/pcireg.h> 7255505Sshin#include <dev/pci/pcivar.h> 7355505Sshin 7455505Sshin#include <sys/ctype.h> 7555505Sshin#include <sys/taskqueue.h> 7655505Sshin 7755505Sshin#include <dev/sound/pci/hda/hdac_private.h> 7855505Sshin#include <dev/sound/pci/hda/hdac_reg.h> 7955505Sshin#include <dev/sound/pci/hda/hda_reg.h> 8055505Sshin#include <dev/sound/pci/hda/hdac.h> 8155505Sshin 8255505Sshin#include "mixer_if.h" 8378064Sume 8455505Sshin#define HDA_DRV_TEST_REV "20080420_0052" 8555505Sshin#define HDA_WIDGET_PARSER_REV 1 8655505Sshin 8755505SshinSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/hda/hdac.c 179205 2008-05-22 09:14:12Z kevlo $"); 8855505Sshin 8955505Sshin#define HDA_BOOTVERBOSE(stmt) do { \ 9055505Sshin if (bootverbose != 0 || snd_verbose > 3) { \ 9155505Sshin stmt \ 9255505Sshin } \ 9355505Sshin} while(0) 9455505Sshin 9555505Sshin#if 1 9655505Sshin#undef HDAC_INTR_EXTRA 9755505Sshin#define HDAC_INTR_EXTRA 1 9855505Sshin#endif 9955505Sshin 10055505Sshin#define hdac_lock(sc) snd_mtxlock((sc)->lock) 10155505Sshin#define hdac_unlock(sc) snd_mtxunlock((sc)->lock) 10255505Sshin#define hdac_lockassert(sc) snd_mtxassert((sc)->lock) 10355505Sshin#define hdac_lockowned(sc) mtx_owned((sc)->lock) 10455505Sshin 10555505Sshin#undef HDAC_MSI_ENABLED 10655505Sshin#if __FreeBSD_version >= 700026 || \ 10755505Sshin (__FreeBSD_version < 700000 && __FreeBSD_version >= 602106) 10855505Sshin#define HDAC_MSI_ENABLED 1 10955505Sshin#endif 11055505Sshin 11155505Sshin#define HDA_FLAG_MATCH(fl, v) (((fl) & (v)) == (v)) 11255505Sshin#define HDA_DEV_MATCH(fl, v) ((fl) == (v) || \ 11362590Sitojun (fl) == 0xffffffff || \ 11455505Sshin (((fl) & 0xffff0000) == 0xffff0000 && \ 11562590Sitojun ((fl) & 0x0000ffff) == ((v) & 0x0000ffff)) || \ 11655505Sshin (((fl) & 0x0000ffff) == 0x0000ffff && \ 117186119Sqingli ((fl) & 0xffff0000) == ((v) & 0xffff0000))) 118186119Sqingli#define HDA_MATCH_ALL 0xffffffff 119196866Sbz#define HDAC_INVALID 0xffffffff 120186119Sqingli 121186119Sqingli/* Default controller / jack sense poll: 250ms */ 122100650Sjmallett#define HDAC_POLL_INTERVAL max(hz >> 2, 1) 12362590Sitojun 12462590Sitojun/* 12562590Sitojun * Make room for possible 4096 playback/record channels, in 100 years to come. 12662590Sitojun */ 12762590Sitojun#define HDAC_TRIGGER_NONE 0x00000000 12855505Sshin#define HDAC_TRIGGER_PLAY 0x00000fff 12962590Sitojun#define HDAC_TRIGGER_REC 0x00fff000 13062590Sitojun#define HDAC_TRIGGER_UNSOL 0x80000000 13162590Sitojun 13255505Sshin#define HDA_MODEL_CONSTRUCT(vendor, model) \ 133173412Skevlo (((uint32_t)(model) << 16) | ((vendor##_VENDORID) & 0xffff)) 134173412Skevlo 135173412Skevlo/* Controller models */ 136173412Skevlo 137173412Skevlo/* Intel */ 138173412Skevlo#define INTEL_VENDORID 0x8086 139173412Skevlo#define HDA_INTEL_82801F HDA_MODEL_CONSTRUCT(INTEL, 0x2668) 140173412Skevlo#define HDA_INTEL_63XXESB HDA_MODEL_CONSTRUCT(INTEL, 0x269a) 141173412Skevlo#define HDA_INTEL_82801G HDA_MODEL_CONSTRUCT(INTEL, 0x27d8) 142173412Skevlo#define HDA_INTEL_82801H HDA_MODEL_CONSTRUCT(INTEL, 0x284b) 143173412Skevlo#define HDA_INTEL_82801I HDA_MODEL_CONSTRUCT(INTEL, 0x293e) 144173412Skevlo#define HDA_INTEL_ALL HDA_MODEL_CONSTRUCT(INTEL, 0xffff) 145173412Skevlo 146173412Skevlo/* Nvidia */ 147173412Skevlo#define NVIDIA_VENDORID 0x10de 148173412Skevlo#define HDA_NVIDIA_MCP51 HDA_MODEL_CONSTRUCT(NVIDIA, 0x026c) 149173412Skevlo#define HDA_NVIDIA_MCP55 HDA_MODEL_CONSTRUCT(NVIDIA, 0x0371) 150173412Skevlo#define HDA_NVIDIA_MCP61_1 HDA_MODEL_CONSTRUCT(NVIDIA, 0x03e4) 15162590Sitojun#define HDA_NVIDIA_MCP61_2 HDA_MODEL_CONSTRUCT(NVIDIA, 0x03f0) 152173412Skevlo#define HDA_NVIDIA_MCP65_1 HDA_MODEL_CONSTRUCT(NVIDIA, 0x044a) 153173412Skevlo#define HDA_NVIDIA_MCP65_2 HDA_MODEL_CONSTRUCT(NVIDIA, 0x044b) 15462590Sitojun#define HDA_NVIDIA_MCP67_1 HDA_MODEL_CONSTRUCT(NVIDIA, 0x055c) 155173412Skevlo#define HDA_NVIDIA_MCP67_2 HDA_MODEL_CONSTRUCT(NVIDIA, 0x055d) 156173412Skevlo#define HDA_NVIDIA_ALL HDA_MODEL_CONSTRUCT(NVIDIA, 0xffff) 157173412Skevlo 15855505Sshin/* ATI */ 159122615Sume#define ATI_VENDORID 0x1002 16078064Sume#define HDA_ATI_SB450 HDA_MODEL_CONSTRUCT(ATI, 0x437b) 16178064Sume#define HDA_ATI_SB600 HDA_MODEL_CONSTRUCT(ATI, 0x4383) 16278064Sume#define HDA_ATI_ALL HDA_MODEL_CONSTRUCT(ATI, 0xffff) 16378064Sume 16478064Sume/* VIA */ 16578064Sume#define VIA_VENDORID 0x1106 166122615Sume#define HDA_VIA_VT82XX HDA_MODEL_CONSTRUCT(VIA, 0x3288) 16778064Sume#define HDA_VIA_ALL HDA_MODEL_CONSTRUCT(VIA, 0xffff) 168122615Sume 169122615Sume/* SiS */ 170122615Sume#define SIS_VENDORID 0x1039 17155505Sshin#define HDA_SIS_966 HDA_MODEL_CONSTRUCT(SIS, 0x7502) 17255505Sshin#define HDA_SIS_ALL HDA_MODEL_CONSTRUCT(SIS, 0xffff) 17355505Sshin 17455505Sshin/* OEM/subvendors */ 17555505Sshin 17655505Sshin/* Intel */ 17755505Sshin#define INTEL_D101GGC_SUBVENDOR HDA_MODEL_CONSTRUCT(INTEL, 0xd600) 17855505Sshin 17955505Sshin/* HP/Compaq */ 180122615Sume#define HP_VENDORID 0x103c 181121156Sume#define HP_V3000_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x30b5) 18255505Sshin#define HP_NX7400_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x30a2) 18355505Sshin#define HP_NX6310_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x30aa) 184122615Sume#define HP_NX6325_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x30b0) 185122615Sume#define HP_XW4300_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x3013) 186122615Sume#define HP_3010_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x3010) 187122615Sume#define HP_DV5000_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x30a5) 188122615Sume#define HP_DC7700S_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x2801) 189122615Sume#define HP_DC7700_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0x2802) 190122615Sume#define HP_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(HP, 0xffff) 191122615Sume/* What is wrong with XN 2563 anyway? (Got the picture ?) */ 192122615Sume#define HP_NX6325_SUBVENDORX 0x103c30b0 193122615Sume 194122615Sume/* Dell */ 195122615Sume#define DELL_VENDORID 0x1028 196122615Sume#define DELL_D820_SUBVENDOR HDA_MODEL_CONSTRUCT(DELL, 0x01cc) 19755505Sshin#define DELL_V1500_SUBVENDOR HDA_MODEL_CONSTRUCT(DELL, 0x0228) 19855505Sshin#define DELL_I1300_SUBVENDOR HDA_MODEL_CONSTRUCT(DELL, 0x01c9) 199122615Sume#define DELL_XPSM1210_SUBVENDOR HDA_MODEL_CONSTRUCT(DELL, 0x01d7) 20055505Sshin#define DELL_OPLX745_SUBVENDOR HDA_MODEL_CONSTRUCT(DELL, 0x01da) 201122615Sume#define DELL_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(DELL, 0xffff) 20255505Sshin 203122615Sume/* Clevo */ 204122615Sume#define CLEVO_VENDORID 0x1558 205122615Sume#define CLEVO_D900T_SUBVENDOR HDA_MODEL_CONSTRUCT(CLEVO, 0x0900) 206122615Sume#define CLEVO_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(CLEVO, 0xffff) 207122615Sume 20855505Sshin/* Acer */ 20955505Sshin#define ACER_VENDORID 0x1025 21055505Sshin#define ACER_A5050_SUBVENDOR HDA_MODEL_CONSTRUCT(ACER, 0x010f) 21155505Sshin#define ACER_A4520_SUBVENDOR HDA_MODEL_CONSTRUCT(ACER, 0x0127) 21255505Sshin#define ACER_A4710_SUBVENDOR HDA_MODEL_CONSTRUCT(ACER, 0x012f) 21355505Sshin#define ACER_3681WXM_SUBVENDOR HDA_MODEL_CONSTRUCT(ACER, 0x0110) 21455505Sshin#define ACER_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(ACER, 0xffff) 215122615Sume 216122615Sume/* Asus */ 217122615Sume#define ASUS_VENDORID 0x1043 218122615Sume#define ASUS_A8X_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1153) 219122615Sume#define ASUS_U5F_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1263) 22055505Sshin#define ASUS_W6F_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1263) 221122615Sume#define ASUS_A7M_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1323) 22255505Sshin#define ASUS_F3JC_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1338) 223122615Sume#define ASUS_G2K_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1339) 224122615Sume#define ASUS_A7T_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x13c2) 22555505Sshin#define ASUS_W2J_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1971) 22655505Sshin#define ASUS_M5200_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x1993) 22755505Sshin#define ASUS_P1AH2_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x81cb) 22855505Sshin#define ASUS_M2NPVMX_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x81cb) 22955505Sshin#define ASUS_M2V_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x81e7) 23055505Sshin#define ASUS_P5BWD_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x81ec) 23155505Sshin#define ASUS_M2N_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0x8234) 23255505Sshin#define ASUS_A8NVMCSM_SUBVENDOR HDA_MODEL_CONSTRUCT(NVIDIA, 0xcb84) 233122615Sume#define ASUS_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(ASUS, 0xffff) 234122615Sume 235122615Sume/* IBM / Lenovo */ 236122615Sume#define IBM_VENDORID 0x1014 23755505Sshin#define IBM_M52_SUBVENDOR HDA_MODEL_CONSTRUCT(IBM, 0x02f6) 238122615Sume#define IBM_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(IBM, 0xffff) 239122615Sume 240122615Sume/* Lenovo */ 241122615Sume#define LENOVO_VENDORID 0x17aa 242122615Sume#define LENOVO_3KN100_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x2066) 243122615Sume#define LENOVO_TCA55_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x1015) 244122615Sume#define LENOVO_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0xffff) 245122615Sume 246122615Sume/* Samsung */ 247122615Sume#define SAMSUNG_VENDORID 0x144d 248122615Sume#define SAMSUNG_Q1_SUBVENDOR HDA_MODEL_CONSTRUCT(SAMSUNG, 0xc027) 249122615Sume#define SAMSUNG_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(SAMSUNG, 0xffff) 250122615Sume 251122615Sume/* Medion ? */ 252122615Sume#define MEDION_VENDORID 0x161f 253122615Sume#define MEDION_MD95257_SUBVENDOR HDA_MODEL_CONSTRUCT(MEDION, 0x203d) 254122615Sume#define MEDION_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(MEDION, 0xffff) 255122615Sume 256122615Sume/* Apple Computer Inc. */ 257122615Sume#define APPLE_VENDORID 0x106b 258122615Sume#define APPLE_MB3_SUBVENDOR HDA_MODEL_CONSTRUCT(APPLE, 0x00a1) 259122615Sume 260122615Sume/* 261122615Sume * Apple Intel MacXXXX seems using Sigmatel codec/vendor id 262122615Sume * instead of their own, which is beyond my comprehension 263122615Sume * (see HDA_CODEC_STAC9221 below). 264122615Sume */ 265122615Sume#define APPLE_INTEL_MAC 0x76808384 266122615Sume 267122615Sume/* LG Electronics */ 268122615Sume#define LG_VENDORID 0x1854 269122615Sume#define LG_LW20_SUBVENDOR HDA_MODEL_CONSTRUCT(LG, 0x0018) 270122615Sume#define LG_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(LG, 0xffff) 271122615Sume 27255505Sshin/* Fujitsu Siemens */ 273122615Sume#define FS_VENDORID 0x1734 274122615Sume#define FS_PA1510_SUBVENDOR HDA_MODEL_CONSTRUCT(FS, 0x10b8) 275122615Sume#define FS_SI1848_SUBVENDOR HDA_MODEL_CONSTRUCT(FS, 0x10cd) 276122615Sume#define FS_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(FS, 0xffff) 277122615Sume 278122615Sume/* Fujitsu Limited */ 279122615Sume#define FL_VENDORID 0x10cf 280122615Sume#define FL_S7020D_SUBVENDOR HDA_MODEL_CONSTRUCT(FL, 0x1326) 281122615Sume#define FL_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(FL, 0xffff) 28255505Sshin 283122615Sume/* Toshiba */ 284122615Sume#define TOSHIBA_VENDORID 0x1179 28555505Sshin#define TOSHIBA_U200_SUBVENDOR HDA_MODEL_CONSTRUCT(TOSHIBA, 0x0001) 28655505Sshin#define TOSHIBA_A135_SUBVENDOR HDA_MODEL_CONSTRUCT(TOSHIBA, 0xff01) 28755505Sshin#define TOSHIBA_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(TOSHIBA, 0xffff) 288122615Sume 289122615Sume/* Micro-Star International (MSI) */ 290122615Sume#define MSI_VENDORID 0x1462 291122615Sume#define MSI_MS1034_SUBVENDOR HDA_MODEL_CONSTRUCT(MSI, 0x0349) 292122615Sume#define MSI_MS034A_SUBVENDOR HDA_MODEL_CONSTRUCT(MSI, 0x034a) 29355505Sshin#define MSI_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(MSI, 0xffff) 294122615Sume 295122615Sume/* Giga-Byte Technology */ 296122615Sume#define GB_VENDORID 0x1458 297122615Sume#define GB_G33S2H_SUBVENDOR HDA_MODEL_CONSTRUCT(GB, 0xa022) 298122615Sume#define GP_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(GB, 0xffff) 299122615Sume 30055505Sshin/* Uniwill ? */ 301122615Sume#define UNIWILL_VENDORID 0x1584 302122615Sume#define UNIWILL_9075_SUBVENDOR HDA_MODEL_CONSTRUCT(UNIWILL, 0x9075) 303122615Sume#define UNIWILL_9080_SUBVENDOR HDA_MODEL_CONSTRUCT(UNIWILL, 0x9080) 304122615Sume 305122615Sume 306122615Sume/* Misc constants.. */ 30755505Sshin#define HDA_AMP_MUTE_DEFAULT (0xffffffff) 308122615Sume#define HDA_AMP_MUTE_NONE (0) 309122615Sume#define HDA_AMP_MUTE_LEFT (1 << 0) 310122615Sume#define HDA_AMP_MUTE_RIGHT (1 << 1) 311122615Sume#define HDA_AMP_MUTE_ALL (HDA_AMP_MUTE_LEFT | HDA_AMP_MUTE_RIGHT) 312122615Sume 313122615Sume#define HDA_AMP_LEFT_MUTED(v) ((v) & (HDA_AMP_MUTE_LEFT)) 314122615Sume#define HDA_AMP_RIGHT_MUTED(v) (((v) & HDA_AMP_MUTE_RIGHT) >> 1) 315122615Sume 31655505Sshin#define HDA_DAC_PATH (1 << 0) 31755505Sshin#define HDA_ADC_PATH (1 << 1) 31855505Sshin#define HDA_ADC_RECSEL (1 << 2) 31955505Sshin 32055505Sshin#define HDA_DAC_LOCKED (1 << 3) 32155505Sshin#define HDA_ADC_LOCKED (1 << 4) 32255505Sshin 32355505Sshin#define HDA_CTL_OUT (1 << 0) 32455505Sshin#define HDA_CTL_IN (1 << 1) 32555505Sshin#define HDA_CTL_BOTH (HDA_CTL_IN | HDA_CTL_OUT) 32655505Sshin 32755505Sshin#define HDA_GPIO_MAX 8 32855505Sshin/* 0 - 7 = GPIO , 8 = Flush */ 32955505Sshin#define HDA_QUIRK_GPIO0 (1 << 0) 33055505Sshin#define HDA_QUIRK_GPIO1 (1 << 1) 33155505Sshin#define HDA_QUIRK_GPIO2 (1 << 2) 33255505Sshin#define HDA_QUIRK_GPIO3 (1 << 3) 33355505Sshin#define HDA_QUIRK_GPIO4 (1 << 4) 33455505Sshin#define HDA_QUIRK_GPIO5 (1 << 5) 33555505Sshin#define HDA_QUIRK_GPIO6 (1 << 6) 33655505Sshin#define HDA_QUIRK_GPIO7 (1 << 7) 33755505Sshin#define HDA_QUIRK_GPIOFLUSH (1 << 8) 33855505Sshin 33955505Sshin/* 9 - 25 = anything else */ 34055505Sshin#define HDA_QUIRK_SOFTPCMVOL (1 << 9) 341167260Skevlo#define HDA_QUIRK_FIXEDRATE (1 << 10) 342122615Sume#define HDA_QUIRK_FORCESTEREO (1 << 11) 343122615Sume#define HDA_QUIRK_EAPDINV (1 << 12) 34455505Sshin#define HDA_QUIRK_DMAPOS (1 << 13) 34555505Sshin 34655505Sshin/* 26 - 31 = vrefs */ 34755505Sshin#define HDA_QUIRK_IVREF50 (1 << 26) 34855505Sshin#define HDA_QUIRK_IVREF80 (1 << 27) 34955505Sshin#define HDA_QUIRK_IVREF100 (1 << 28) 35055505Sshin#define HDA_QUIRK_OVREF50 (1 << 29) 35155505Sshin#define HDA_QUIRK_OVREF80 (1 << 30) 35255505Sshin#define HDA_QUIRK_OVREF100 (1 << 31) 35355505Sshin 35455505Sshin#define HDA_QUIRK_IVREF (HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF80 | \ 35555505Sshin HDA_QUIRK_IVREF100) 35655505Sshin#define HDA_QUIRK_OVREF (HDA_QUIRK_OVREF50 | HDA_QUIRK_OVREF80 | \ 35755505Sshin HDA_QUIRK_OVREF100) 35855505Sshin#define HDA_QUIRK_VREF (HDA_QUIRK_IVREF | HDA_QUIRK_OVREF) 35955505Sshin 36055505Sshin#define SOUND_MASK_SKIP (1 << 30) 36155505Sshin#define SOUND_MASK_DISABLE (1 << 31) 362121156Sume 363121156Sume#if __FreeBSD_version < 600000 36455505Sshin#define taskqueue_drain(...) 36555505Sshin#endif 36655505Sshin 36755505Sshinstatic const struct { 36862590Sitojun char *key; 36955505Sshin uint32_t value; 37055505Sshin} hdac_quirks_tab[] = { 37155505Sshin { "gpio0", HDA_QUIRK_GPIO0 }, 37255505Sshin { "gpio1", HDA_QUIRK_GPIO1 }, 37355505Sshin { "gpio2", HDA_QUIRK_GPIO2 }, 37455505Sshin { "gpio3", HDA_QUIRK_GPIO3 }, 37555505Sshin { "gpio4", HDA_QUIRK_GPIO4 }, 37655505Sshin { "gpio5", HDA_QUIRK_GPIO5 }, 37755505Sshin { "gpio6", HDA_QUIRK_GPIO6 }, 37855505Sshin { "gpio7", HDA_QUIRK_GPIO7 }, 37955505Sshin { "gpioflush", HDA_QUIRK_GPIOFLUSH }, 38055505Sshin { "softpcmvol", HDA_QUIRK_SOFTPCMVOL }, 38155505Sshin { "fixedrate", HDA_QUIRK_FIXEDRATE }, 38255505Sshin { "forcestereo", HDA_QUIRK_FORCESTEREO }, 38355505Sshin { "eapdinv", HDA_QUIRK_EAPDINV }, 38455505Sshin { "dmapos", HDA_QUIRK_DMAPOS }, 38555505Sshin { "ivref50", HDA_QUIRK_IVREF50 }, 38655505Sshin { "ivref80", HDA_QUIRK_IVREF80 }, 38755505Sshin { "ivref100", HDA_QUIRK_IVREF100 }, 38855505Sshin { "ovref50", HDA_QUIRK_OVREF50 }, 38955505Sshin { "ovref80", HDA_QUIRK_OVREF80 }, 39055505Sshin { "ovref100", HDA_QUIRK_OVREF100 }, 39155505Sshin { "ivref", HDA_QUIRK_IVREF }, 39255505Sshin { "ovref", HDA_QUIRK_OVREF }, 39355505Sshin { "vref", HDA_QUIRK_VREF }, 39455505Sshin}; 39555505Sshin#define HDAC_QUIRKS_TAB_LEN \ 39655505Sshin (sizeof(hdac_quirks_tab) / sizeof(hdac_quirks_tab[0])) 39755505Sshin 39855505Sshin#define HDA_BDL_MIN 2 39955505Sshin#define HDA_BDL_MAX 256 40055505Sshin#define HDA_BDL_DEFAULT HDA_BDL_MIN 40155505Sshin 40255505Sshin#define HDA_BLK_MIN HDAC_DMA_ALIGNMENT 40355505Sshin#define HDA_BLK_ALIGN (~(HDA_BLK_MIN - 1)) 40455505Sshin 40555505Sshin#define HDA_BUFSZ_MIN 4096 40655505Sshin#define HDA_BUFSZ_MAX 65536 40755505Sshin#define HDA_BUFSZ_DEFAULT 16384 40862590Sitojun 40962590Sitojun#define HDA_PARSE_MAXDEPTH 10 41062590Sitojun 411121156Sume#define HDAC_UNSOLTAG_EVENT_HP 0x00 41262590Sitojun#define HDAC_UNSOLTAG_EVENT_TEST 0x01 41362590Sitojun 41455505SshinMALLOC_DEFINE(M_HDAC, "hdac", "High Definition Audio Controller"); 41555505Sshin 41655505Sshinenum { 41755505Sshin HDA_PARSE_MIXER, 41855505Sshin HDA_PARSE_DIRECT 41955505Sshin}; 42055505Sshin 421121156Sume/* Default */ 42255505Sshinstatic uint32_t hdac_fmt[] = { 42355505Sshin AFMT_STEREO | AFMT_S16_LE, 42462590Sitojun 0 42562590Sitojun}; 42655505Sshin 42755505Sshinstatic struct pcmchan_caps hdac_caps = {48000, 48000, hdac_fmt, 0}; 42855505Sshin 429121156Sumestatic const struct { 430121156Sume uint32_t model; 43155505Sshin char *desc; 43255505Sshin} hdac_devices[] = { 43355505Sshin { HDA_INTEL_82801F, "Intel 82801F" }, 43455505Sshin { HDA_INTEL_63XXESB, "Intel 631x/632xESB" }, 43555505Sshin { HDA_INTEL_82801G, "Intel 82801G" }, 436122615Sume { HDA_INTEL_82801H, "Intel 82801H" }, 437122615Sume { HDA_INTEL_82801I, "Intel 82801I" }, 438122615Sume { HDA_NVIDIA_MCP51, "NVidia MCP51" }, 439122615Sume { HDA_NVIDIA_MCP55, "NVidia MCP55" }, 440122615Sume { HDA_NVIDIA_MCP61_1, "NVidia MCP61" }, 441122615Sume { HDA_NVIDIA_MCP61_2, "NVidia MCP61" }, 44255505Sshin { HDA_NVIDIA_MCP65_1, "NVidia MCP65" }, 44362590Sitojun { HDA_NVIDIA_MCP65_2, "NVidia MCP65" }, 44462590Sitojun { HDA_NVIDIA_MCP67_1, "NVidia MCP67" }, 44562590Sitojun { HDA_NVIDIA_MCP67_2, "NVidia MCP67" }, 44662590Sitojun { HDA_ATI_SB450, "ATI SB450" }, 44762590Sitojun { HDA_ATI_SB600, "ATI SB600" }, 44855505Sshin { HDA_VIA_VT82XX, "VIA VT8251/8237A" }, 44962590Sitojun { HDA_SIS_966, "SiS 966" }, 45055505Sshin /* Unknown */ 45155505Sshin { HDA_INTEL_ALL, "Intel (Unknown)" }, 45255505Sshin { HDA_NVIDIA_ALL, "NVidia (Unknown)" }, 45355505Sshin { HDA_ATI_ALL, "ATI (Unknown)" }, 45455505Sshin { HDA_VIA_ALL, "VIA (Unknown)" }, 45555505Sshin { HDA_SIS_ALL, "SiS (Unknown)" }, 45655505Sshin}; 45755505Sshin#define HDAC_DEVICES_LEN (sizeof(hdac_devices) / sizeof(hdac_devices[0])) 45855505Sshin 45955505Sshinstatic const struct { 46055505Sshin uint16_t vendor; 46155505Sshin uint8_t reg; 46255505Sshin uint8_t mask; 46355505Sshin uint8_t enable; 46455505Sshin} hdac_pcie_snoop[] = { 46555505Sshin { INTEL_VENDORID, 0x00, 0x00, 0x00 }, 46655505Sshin { ATI_VENDORID, 0x42, 0xf8, 0x02 }, 46755505Sshin { NVIDIA_VENDORID, 0x4e, 0xf0, 0x0f }, 46855505Sshin}; 46955505Sshin#define HDAC_PCIESNOOP_LEN \ 47055505Sshin (sizeof(hdac_pcie_snoop) / sizeof(hdac_pcie_snoop[0])) 47155505Sshin 47255505Sshinstatic const struct { 47355505Sshin uint32_t rate; 47455505Sshin int valid; 47555505Sshin uint16_t base; 47655505Sshin uint16_t mul; 477121156Sume uint16_t div; 47855505Sshin} hda_rate_tab[] = { 47955505Sshin { 8000, 1, 0x0000, 0x0000, 0x0500 }, /* (48000 * 1) / 6 */ 48055505Sshin { 9600, 0, 0x0000, 0x0000, 0x0400 }, /* (48000 * 1) / 5 */ 48162590Sitojun { 12000, 0, 0x0000, 0x0000, 0x0300 }, /* (48000 * 1) / 4 */ 48262590Sitojun { 16000, 1, 0x0000, 0x0000, 0x0200 }, /* (48000 * 1) / 3 */ 48362590Sitojun { 18000, 0, 0x0000, 0x1000, 0x0700 }, /* (48000 * 3) / 8 */ 484121156Sume { 19200, 0, 0x0000, 0x0800, 0x0400 }, /* (48000 * 2) / 5 */ 48562590Sitojun { 24000, 0, 0x0000, 0x0000, 0x0100 }, /* (48000 * 1) / 2 */ 48662590Sitojun { 28800, 0, 0x0000, 0x1000, 0x0400 }, /* (48000 * 3) / 5 */ 487122615Sume { 32000, 1, 0x0000, 0x0800, 0x0200 }, /* (48000 * 2) / 3 */ 48855505Sshin { 36000, 0, 0x0000, 0x1000, 0x0300 }, /* (48000 * 3) / 4 */ 48955505Sshin { 38400, 0, 0x0000, 0x1800, 0x0400 }, /* (48000 * 4) / 5 */ 490121156Sume { 48000, 1, 0x0000, 0x0000, 0x0000 }, /* (48000 * 1) / 1 */ 491121156Sume { 64000, 0, 0x0000, 0x1800, 0x0200 }, /* (48000 * 4) / 3 */ 49255505Sshin { 72000, 0, 0x0000, 0x1000, 0x0100 }, /* (48000 * 3) / 2 */ 49355505Sshin { 96000, 1, 0x0000, 0x0800, 0x0000 }, /* (48000 * 2) / 1 */ 49455505Sshin { 144000, 0, 0x0000, 0x1000, 0x0000 }, /* (48000 * 3) / 1 */ 49555505Sshin { 192000, 1, 0x0000, 0x1800, 0x0000 }, /* (48000 * 4) / 1 */ 49655505Sshin { 8820, 0, 0x4000, 0x0000, 0x0400 }, /* (44100 * 1) / 5 */ 49755505Sshin { 11025, 1, 0x4000, 0x0000, 0x0300 }, /* (44100 * 1) / 4 */ 49855505Sshin { 12600, 0, 0x4000, 0x0800, 0x0600 }, /* (44100 * 2) / 7 */ 49955505Sshin { 14700, 0, 0x4000, 0x0000, 0x0200 }, /* (44100 * 1) / 3 */ 50055505Sshin { 17640, 0, 0x4000, 0x0800, 0x0400 }, /* (44100 * 2) / 5 */ 50155505Sshin { 18900, 0, 0x4000, 0x1000, 0x0600 }, /* (44100 * 3) / 7 */ 50255505Sshin { 22050, 1, 0x4000, 0x0000, 0x0100 }, /* (44100 * 1) / 2 */ 50355505Sshin { 25200, 0, 0x4000, 0x1800, 0x0600 }, /* (44100 * 4) / 7 */ 50455505Sshin { 26460, 0, 0x4000, 0x1000, 0x0400 }, /* (44100 * 3) / 5 */ 50555505Sshin { 29400, 0, 0x4000, 0x0800, 0x0200 }, /* (44100 * 2) / 3 */ 506186119Sqingli { 33075, 0, 0x4000, 0x1000, 0x0300 }, /* (44100 * 3) / 4 */ 50755505Sshin { 35280, 0, 0x4000, 0x1800, 0x0400 }, /* (44100 * 4) / 5 */ 50855505Sshin { 44100, 1, 0x4000, 0x0000, 0x0000 }, /* (44100 * 1) / 1 */ 50955505Sshin { 58800, 0, 0x4000, 0x1800, 0x0200 }, /* (44100 * 4) / 3 */ 51055505Sshin { 66150, 0, 0x4000, 0x1000, 0x0100 }, /* (44100 * 3) / 2 */ 51155505Sshin { 88200, 1, 0x4000, 0x0800, 0x0000 }, /* (44100 * 2) / 1 */ 51255505Sshin { 132300, 0, 0x4000, 0x1000, 0x0000 }, /* (44100 * 3) / 1 */ 51355505Sshin { 176400, 1, 0x4000, 0x1800, 0x0000 }, /* (44100 * 4) / 1 */ 51455505Sshin}; 51555505Sshin#define HDA_RATE_TAB_LEN (sizeof(hda_rate_tab) / sizeof(hda_rate_tab[0])) 51655505Sshin 51755505Sshin/* All codecs you can eat... */ 51855505Sshin#define HDA_CODEC_CONSTRUCT(vendor, id) \ 519121156Sume (((uint32_t)(vendor##_VENDORID) << 16) | ((id) & 0xffff)) 52055505Sshin 52155505Sshin/* Realtek */ 52255505Sshin#define REALTEK_VENDORID 0x10ec 52362590Sitojun#define HDA_CODEC_ALC260 HDA_CODEC_CONSTRUCT(REALTEK, 0x0260) 52462590Sitojun#define HDA_CODEC_ALC262 HDA_CODEC_CONSTRUCT(REALTEK, 0x0262) 52562590Sitojun#define HDA_CODEC_ALC268 HDA_CODEC_CONSTRUCT(REALTEK, 0x0268) 526121156Sume#define HDA_CODEC_ALC660 HDA_CODEC_CONSTRUCT(REALTEK, 0x0660) 52762590Sitojun#define HDA_CODEC_ALC861 HDA_CODEC_CONSTRUCT(REALTEK, 0x0861) 52862590Sitojun#define HDA_CODEC_ALC861VD HDA_CODEC_CONSTRUCT(REALTEK, 0x0862) 52955505Sshin#define HDA_CODEC_ALC880 HDA_CODEC_CONSTRUCT(REALTEK, 0x0880) 530121156Sume#define HDA_CODEC_ALC882 HDA_CODEC_CONSTRUCT(REALTEK, 0x0882) 531121156Sume#define HDA_CODEC_ALC883 HDA_CODEC_CONSTRUCT(REALTEK, 0x0883) 53255505Sshin#define HDA_CODEC_ALC885 HDA_CODEC_CONSTRUCT(REALTEK, 0x0885) 53355505Sshin#define HDA_CODEC_ALC888 HDA_CODEC_CONSTRUCT(REALTEK, 0x0888) 53455505Sshin#define HDA_CODEC_ALCXXXX HDA_CODEC_CONSTRUCT(REALTEK, 0xffff) 53555505Sshin 53655505Sshin/* Analog Devices */ 53762590Sitojun#define ANALOGDEVICES_VENDORID 0x11d4 53878064Sume#define HDA_CODEC_AD1981HD HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1981) 53955505Sshin#define HDA_CODEC_AD1983 HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1983) 54062590Sitojun#define HDA_CODEC_AD1984 HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1984) 54162590Sitojun#define HDA_CODEC_AD1986A HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1986) 54262590Sitojun#define HDA_CODEC_AD1988 HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x1988) 54362590Sitojun#define HDA_CODEC_AD1988B HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0x198b) 54462590Sitojun#define HDA_CODEC_ADXXXX HDA_CODEC_CONSTRUCT(ANALOGDEVICES, 0xffff) 54555505Sshin 54662590Sitojun/* CMedia */ 54755505Sshin#define CMEDIA_VENDORID 0x434d 54855505Sshin#define HDA_CODEC_CMI9880 HDA_CODEC_CONSTRUCT(CMEDIA, 0x4980) 54955505Sshin#define HDA_CODEC_CMIXXXX HDA_CODEC_CONSTRUCT(CMEDIA, 0xffff) 55055505Sshin 55155505Sshin/* Sigmatel */ 552186119Sqingli#define SIGMATEL_VENDORID 0x8384 553186119Sqingli#define HDA_CODEC_STAC9221 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7680) 554186119Sqingli#define HDA_CODEC_STAC9221D HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7683) 555186119Sqingli#define HDA_CODEC_STAC9220 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7690) 556186119Sqingli#define HDA_CODEC_STAC922XD HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7681) 557186500Sqingli#define HDA_CODEC_STAC9227 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7618) 55855505Sshin#define HDA_CODEC_STAC9271D HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7627) 55962590Sitojun#define HDA_CODEC_STAC9205 HDA_CODEC_CONSTRUCT(SIGMATEL, 0x76a0) 56062590Sitojun#define HDA_CODEC_STAC9872AK HDA_CODEC_CONSTRUCT(SIGMATEL, 0x7662) 56162590Sitojun#define HDA_CODEC_STACXXXX HDA_CODEC_CONSTRUCT(SIGMATEL, 0xffff) 56262590Sitojun 56362590Sitojun/* 56462590Sitojun * Conexant 56562590Sitojun * 56662590Sitojun * Ok, the truth is, I don't have any idea at all whether 56762590Sitojun * it is "Venice" or "Waikiki" or other unnamed CXyadayada. The only 568121156Sume * place that tell me it is "Venice" is from its Windows driver INF. 569121156Sume * 570121156Sume * Venice - CX????? 57155505Sshin * Waikiki - CX20551-22 57255505Sshin */ 57355505Sshin#define CONEXANT_VENDORID 0x14f1 57455505Sshin#define HDA_CODEC_CXVENICE HDA_CODEC_CONSTRUCT(CONEXANT, 0x5045) 57555505Sshin#define HDA_CODEC_CXWAIKIKI HDA_CODEC_CONSTRUCT(CONEXANT, 0x5047) 57655505Sshin#define HDA_CODEC_CXXXXX HDA_CODEC_CONSTRUCT(CONEXANT, 0xffff) 577122615Sume 57878064Sume/* VIA */ 57978064Sume#define HDA_CODEC_VT1708_8 HDA_CODEC_CONSTRUCT(VIA, 0x1708) 58078064Sume#define HDA_CODEC_VT1708_9 HDA_CODEC_CONSTRUCT(VIA, 0x1709) 58155505Sshin#define HDA_CODEC_VT1708_A HDA_CODEC_CONSTRUCT(VIA, 0x170a) 58255505Sshin#define HDA_CODEC_VT1708_B HDA_CODEC_CONSTRUCT(VIA, 0x170b) 58355505Sshin#define HDA_CODEC_VT1709_0 HDA_CODEC_CONSTRUCT(VIA, 0xe710) 58455505Sshin#define HDA_CODEC_VT1709_1 HDA_CODEC_CONSTRUCT(VIA, 0xe711) 585122615Sume#define HDA_CODEC_VT1709_2 HDA_CODEC_CONSTRUCT(VIA, 0xe712) 58655505Sshin#define HDA_CODEC_VT1709_3 HDA_CODEC_CONSTRUCT(VIA, 0xe713) 587122615Sume#define HDA_CODEC_VT1709_4 HDA_CODEC_CONSTRUCT(VIA, 0xe714) 58855505Sshin#define HDA_CODEC_VT1709_5 HDA_CODEC_CONSTRUCT(VIA, 0xe715) 58955505Sshin#define HDA_CODEC_VT1709_6 HDA_CODEC_CONSTRUCT(VIA, 0xe716) 59055505Sshin#define HDA_CODEC_VT1709_7 HDA_CODEC_CONSTRUCT(VIA, 0xe717) 59162590Sitojun#define HDA_CODEC_VTXXXX HDA_CODEC_CONSTRUCT(VIA, 0xffff) 59255505Sshin 59355505Sshin 59455505Sshin/* Codecs */ 59555505Sshinstatic const struct { 59655505Sshin uint32_t id; 59755505Sshin char *name; 59855505Sshin} hdac_codecs[] = { 59978064Sume { HDA_CODEC_ALC260, "Realtek ALC260" }, 60078064Sume { HDA_CODEC_ALC262, "Realtek ALC262" }, 60162590Sitojun { HDA_CODEC_ALC268, "Realtek ALC268" }, 60278064Sume { HDA_CODEC_ALC660, "Realtek ALC660" }, 60355505Sshin { HDA_CODEC_ALC861, "Realtek ALC861" }, 60455505Sshin { HDA_CODEC_ALC861VD, "Realtek ALC861-VD" }, 60566865Ssumikawa { HDA_CODEC_ALC880, "Realtek ALC880" }, 606122615Sume { HDA_CODEC_ALC882, "Realtek ALC882" }, 60778064Sume { HDA_CODEC_ALC883, "Realtek ALC883" }, 608122615Sume { HDA_CODEC_ALC885, "Realtek ALC885" }, 60955505Sshin { HDA_CODEC_ALC888, "Realtek ALC888" }, 61055505Sshin { HDA_CODEC_AD1981HD, "Analog Devices AD1981HD" }, 61155505Sshin { HDA_CODEC_AD1983, "Analog Devices AD1983" }, 61255505Sshin { HDA_CODEC_AD1984, "Analog Devices AD1984" }, 61355505Sshin { HDA_CODEC_AD1986A, "Analog Devices AD1986A" }, 61455505Sshin { HDA_CODEC_AD1988, "Analog Devices AD1988" }, 61555505Sshin { HDA_CODEC_AD1988B, "Analog Devices AD1988B" }, 616186119Sqingli { HDA_CODEC_CMI9880, "CMedia CMI9880" }, 61755505Sshin { HDA_CODEC_STAC9221, "Sigmatel STAC9221" }, 618186119Sqingli { HDA_CODEC_STAC9221D, "Sigmatel STAC9221D" }, 619186119Sqingli { HDA_CODEC_STAC9220, "Sigmatel STAC9220" }, 620186119Sqingli { HDA_CODEC_STAC922XD, "Sigmatel STAC9220D/9223D" }, 62155505Sshin { HDA_CODEC_STAC9227, "Sigmatel STAC9227" }, 62255505Sshin { HDA_CODEC_STAC9271D, "Sigmatel STAC9271D" }, 62355505Sshin { HDA_CODEC_STAC9205, "Sigmatel STAC9205" }, 62455505Sshin { HDA_CODEC_STAC9872AK,"Sigmatel STAC9872AK" }, 625121156Sume { HDA_CODEC_CXVENICE, "Conexant Venice" }, 62655505Sshin { HDA_CODEC_CXWAIKIKI, "Conexant Waikiki" }, 62755505Sshin { HDA_CODEC_VT1708_8, "VIA VT1708_8" }, 62855505Sshin { HDA_CODEC_VT1708_9, "VIA VT1708_9" }, 62955505Sshin { HDA_CODEC_VT1708_A, "VIA VT1708_A" }, 63055505Sshin { HDA_CODEC_VT1708_B, "VIA VT1708_B" }, 63155505Sshin { HDA_CODEC_VT1709_0, "VIA VT1709_0" }, 63255505Sshin { HDA_CODEC_VT1709_1, "VIA VT1709_1" }, 63355505Sshin { HDA_CODEC_VT1709_2, "VIA VT1709_2" }, 63455505Sshin { HDA_CODEC_VT1709_3, "VIA VT1709_3" }, 63555505Sshin { HDA_CODEC_VT1709_4, "VIA VT1709_4" }, 63655505Sshin { HDA_CODEC_VT1709_5, "VIA VT1709_5" }, 63755505Sshin { HDA_CODEC_VT1709_6, "VIA VT1709_6" }, 63878064Sume { HDA_CODEC_VT1709_7, "VIA VT1709_7" }, 63978064Sume /* Unknown codec */ 64078064Sume { HDA_CODEC_ALCXXXX, "Realtek (Unknown)" }, 64178064Sume { HDA_CODEC_ADXXXX, "Analog Devices (Unknown)" }, 64278064Sume { HDA_CODEC_CMIXXXX, "CMedia (Unknown)" }, 64378064Sume { HDA_CODEC_STACXXXX, "Sigmatel (Unknown)" }, 64478064Sume { HDA_CODEC_CXXXXX, "Conexant (Unknown)" }, 64578064Sume { HDA_CODEC_VTXXXX, "VIA (Unknown)" }, 646121156Sume}; 64778064Sume#define HDAC_CODECS_LEN (sizeof(hdac_codecs) / sizeof(hdac_codecs[0])) 64878064Sume 64978064Sumeenum { 65078064Sume HDAC_HP_SWITCH_CTL, 65178064Sume HDAC_HP_SWITCH_CTRL, 65278064Sume HDAC_HP_SWITCH_DEBUG 65378064Sume}; 65478064Sume 655122615Sumestatic const struct { 656122615Sume uint32_t model; 657122615Sume uint32_t id; 65855505Sshin int type; 65955505Sshin int inverted; 66055505Sshin int polling; 66155505Sshin int execsense; 66255505Sshin nid_t hpnid; 66355505Sshin nid_t spkrnid[8]; 66455505Sshin nid_t eapdnid; 66555505Sshin} hdac_hp_switch[] = { 66655505Sshin /* Specific OEM models */ 66755505Sshin { HP_V3000_SUBVENDOR, HDA_CODEC_CXVENICE, HDAC_HP_SWITCH_CTL, 66855505Sshin 0, 0, -1, 17, { 16, -1 }, 16 }, 66966865Ssumikawa /* { HP_XW4300_SUBVENDOR, HDA_CODEC_ALC260, HDAC_HP_SWITCH_CTL, 67066865Ssumikawa 0, 0, -1, 21, { 16, 17, -1 }, -1 } */ 67155505Sshin /* { HP_3010_SUBVENDOR, HDA_CODEC_ALC260, HDAC_HP_SWITCH_DEBUG, 67266865Ssumikawa 0, 1, 0, 16, { 15, 18, 19, 20, 21, -1 }, -1 }, */ 67355505Sshin { HP_NX7400_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL, 67455505Sshin 0, 0, -1, 6, { 5, -1 }, 5 }, 675121156Sume { HP_NX6310_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL, 676122615Sume 0, 0, -1, 6, { 5, -1 }, 5 }, 67781366Ssumikawa { HP_NX6325_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL, 67881366Ssumikawa 0, 0, -1, 6, { 5, -1 }, 5 }, 67981366Ssumikawa /* { HP_DC7700_SUBVENDOR, HDA_CODEC_ALC262, HDAC_HP_SWITCH_CTL, 680122615Sume 0, 0, -1, 21, { 22, 27, -1 }, -1 }, */ 681122615Sume { TOSHIBA_U200_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL, 682122615Sume 0, 0, -1, 6, { 5, -1 }, -1 }, 68381366Ssumikawa { TOSHIBA_A135_SUBVENDOR, HDA_CODEC_ALC861VD, HDAC_HP_SWITCH_CTL, 68466865Ssumikawa 0, 0, -1, 27, { 20, -1 }, -1 }, 68581366Ssumikawa { DELL_D820_SUBVENDOR, HDA_CODEC_STAC9220, HDAC_HP_SWITCH_CTRL, 68666865Ssumikawa 0, 0, -1, 13, { 14, -1 }, -1 }, 68766865Ssumikawa { DELL_I1300_SUBVENDOR, HDA_CODEC_STAC9220, HDAC_HP_SWITCH_CTRL, 68855505Sshin 0, 0, -1, 13, { 14, -1 }, -1 }, 68955505Sshin { DELL_OPLX745_SUBVENDOR, HDA_CODEC_AD1983, HDAC_HP_SWITCH_CTL, 69055505Sshin 0, 0, -1, 6, { 5, 7, -1 }, -1 }, 69155505Sshin { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205, HDAC_HP_SWITCH_CTRL, 69278064Sume 0, 0, -1, 10, { 13, -1 }, -1 }, 69378064Sume { APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, HDAC_HP_SWITCH_CTL, 69478064Sume 0, 0, -1, 21, { 20, 22, -1 }, -1 }, 69578064Sume { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, HDAC_HP_SWITCH_CTRL, 69678064Sume 0, 0, -1, 10, { 13, -1 }, -1 }, 69778064Sume { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, HDAC_HP_SWITCH_CTL, 69878064Sume 1, 0, -1, 26, { 27, -1 }, -1 }, 69978064Sume /* { LENOVO_TCA55_SUBVENDOR, HDA_CODEC_AD1986A, HDAC_HP_SWITCH_CTL, 70078064Sume 0, 0, -1, 26, { 27, 28, 29, 30, -1 }, -1 }, */ 70178064Sume { LG_LW20_SUBVENDOR, HDA_CODEC_ALC880, HDAC_HP_SWITCH_CTL, 70278064Sume 0, 0, -1, 27, { 20, -1 }, -1 }, 70378064Sume { ACER_A5050_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 70455505Sshin 0, 0, -1, 20, { 21, -1 }, -1 }, 70578064Sume { ACER_3681WXM_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 70678064Sume 0, 0, -1, 20, { 21, -1 }, -1 }, 70755505Sshin { ACER_A4520_SUBVENDOR, HDA_CODEC_ALC268, HDAC_HP_SWITCH_CTL, 70855505Sshin 0, 0, -1, 20, { 21, -1 }, -1 }, 70962590Sitojun { ACER_A4710_SUBVENDOR, HDA_CODEC_ALC268, HDAC_HP_SWITCH_CTL, 71055505Sshin 0, 0, -1, 20, { 21, -1 }, -1 }, 71155505Sshin { UNIWILL_9080_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 71255505Sshin 0, 0, -1, 20, { 21, -1 }, -1 }, 713121156Sume { MSI_MS1034_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 71478064Sume 0, 0, -1, 20, { 27, -1 }, -1 }, 71555505Sshin { MSI_MS034A_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 71655505Sshin 0, 0, -1, 20, { 27, -1 }, -1 }, 71755505Sshin { FS_SI1848_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 71855505Sshin 0, 0, -1, 20, { 21, -1 }, -1 }, 719121156Sume { FL_S7020D_SUBVENDOR, HDA_CODEC_ALC260, HDAC_HP_SWITCH_CTL, 720121156Sume 0, 0, -1, 20, { 16, -1 }, -1 }, 72155505Sshin /* 72255505Sshin * All models that at least come from the same vendor with 72378064Sume * simmilar codec. 724121156Sume */ 72555505Sshin { HP_ALL_SUBVENDOR, HDA_CODEC_CXVENICE, HDAC_HP_SWITCH_CTL, 72655505Sshin 0, 0, -1, 17, { 16, -1 }, 16 }, 72778064Sume { HP_ALL_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL, 728121156Sume 0, 0, -1, 6, { 5, -1 }, 5 }, 72955505Sshin { TOSHIBA_ALL_SUBVENDOR, HDA_CODEC_AD1981HD, HDAC_HP_SWITCH_CTL, 73055505Sshin 0, 0, -1, 6, { 5, -1 }, -1 }, 731121156Sume { DELL_ALL_SUBVENDOR, HDA_CODEC_STAC9220, HDAC_HP_SWITCH_CTRL, 73255505Sshin 0, 0, -1, 13, { 14, -1 }, -1 }, 73355505Sshin#if 0 734121156Sume { LENOVO_ALL_SUBVENDOR, HDA_CODEC_AD1986A, HDAC_HP_SWITCH_CTL, 73555505Sshin 1, 0, -1, 26, { 27, -1 }, -1 }, 73655505Sshin { ACER_ALL_SUBVENDOR, HDA_CODEC_ALC883, HDAC_HP_SWITCH_CTL, 737121156Sume 0, 0, -1, 20, { 21, -1 }, -1 }, 73855505Sshin#endif 73955505Sshin}; 740121156Sume#define HDAC_HP_SWITCH_LEN \ 74155505Sshin (sizeof(hdac_hp_switch) / sizeof(hdac_hp_switch[0])) 74255505Sshin 743121156Sumestatic const struct { 74455505Sshin uint32_t model; 74555505Sshin uint32_t id; 74655505Sshin nid_t eapdnid; 74755505Sshin int hp_switch; 74855505Sshin} hdac_eapd_switch[] = { 74955505Sshin { HP_V3000_SUBVENDOR, HDA_CODEC_CXVENICE, 16, 1 }, 75078064Sume { HP_NX7400_SUBVENDOR, HDA_CODEC_AD1981HD, 5, 1 }, 75155505Sshin { HP_NX6310_SUBVENDOR, HDA_CODEC_AD1981HD, 5, 1 }, 75255505Sshin}; 75355505Sshin#define HDAC_EAPD_SWITCH_LEN \ 75455505Sshin (sizeof(hdac_eapd_switch) / sizeof(hdac_eapd_switch[0])) 75562590Sitojun 75662590Sitojun/**************************************************************************** 75762590Sitojun * Function prototypes 75862590Sitojun ****************************************************************************/ 75962590Sitojunstatic void hdac_intr_handler(void *); 760121156Sumestatic int hdac_reset(struct hdac_softc *); 761121156Sumestatic int hdac_get_capabilities(struct hdac_softc *); 76262590Sitojunstatic void hdac_dma_cb(void *, bus_dma_segment_t *, int, int); 76362590Sitojunstatic int hdac_dma_alloc(struct hdac_softc *, 764121156Sume struct hdac_dma *, bus_size_t); 765122615Sumestatic void hdac_dma_free(struct hdac_softc *, struct hdac_dma *); 76662590Sitojunstatic int hdac_mem_alloc(struct hdac_softc *); 767121156Sumestatic void hdac_mem_free(struct hdac_softc *); 768121156Sumestatic int hdac_irq_alloc(struct hdac_softc *); 769121156Sumestatic void hdac_irq_free(struct hdac_softc *); 770121156Sumestatic void hdac_corb_init(struct hdac_softc *); 771122615Sumestatic void hdac_rirb_init(struct hdac_softc *); 772122615Sumestatic void hdac_corb_start(struct hdac_softc *); 773122615Sumestatic void hdac_rirb_start(struct hdac_softc *); 774122615Sumestatic void hdac_scan_codecs(struct hdac_softc *, int); 775122615Sumestatic int hdac_probe_codec(struct hdac_codec *); 77655505Sshinstatic struct hdac_devinfo *hdac_probe_function(struct hdac_codec *, nid_t); 777122615Sumestatic void hdac_add_child(struct hdac_softc *, struct hdac_devinfo *); 77855505Sshin 77955505Sshinstatic void hdac_attach2(void *); 780122615Sume 78155505Sshinstatic uint32_t hdac_command_sendone_internal(struct hdac_softc *, 78255505Sshin uint32_t, int); 78355505Sshinstatic void hdac_command_send_internal(struct hdac_softc *, 78478064Sume struct hdac_command_list *, int); 78578064Sume 78655505Sshinstatic int hdac_probe(device_t); 78755505Sshinstatic int hdac_attach(device_t); 78855505Sshinstatic int hdac_detach(device_t); 789125675Ssumikawastatic void hdac_widget_connection_select(struct hdac_widget *, uint8_t); 79055505Sshinstatic void hdac_audio_ctl_amp_set(struct hdac_audio_ctl *, 79155505Sshin uint32_t, int, int); 79255505Sshinstatic struct hdac_audio_ctl *hdac_audio_ctl_amp_get(struct hdac_devinfo *, 79355505Sshin nid_t, int, int); 79455505Sshinstatic void hdac_audio_ctl_amp_set_internal(struct hdac_softc *, 79555505Sshin nid_t, nid_t, int, int, int, int, int, int); 79662590Sitojunstatic int hdac_audio_ctl_ossmixer_getnextdev(struct hdac_devinfo *); 79755505Sshinstatic struct hdac_widget *hdac_widget_get(struct hdac_devinfo *, nid_t); 79855505Sshin 79962590Sitojunstatic int hdac_rirb_flush(struct hdac_softc *sc); 80055505Sshinstatic int hdac_unsolq_flush(struct hdac_softc *sc); 80155505Sshin 80255505Sshin#define hdac_command(a1, a2, a3) \ 80355505Sshin hdac_command_sendone_internal(a1, a2, a3) 80455505Sshin 80555505Sshin#define hdac_codec_id(d) \ 80655505Sshin ((uint32_t)((d == NULL) ? 0x00000000 : \ 80755505Sshin ((((uint32_t)(d)->vendor_id & 0x0000ffff) << 16) | \ 80855505Sshin ((uint32_t)(d)->device_id & 0x0000ffff)))) 80955505Sshin 81055505Sshinstatic char * 81162590Sitojunhdac_codec_name(struct hdac_devinfo *devinfo) 81262590Sitojun{ 81355505Sshin uint32_t id; 81455505Sshin int i; 81555505Sshin 81655505Sshin id = hdac_codec_id(devinfo); 81755505Sshin 81855505Sshin for (i = 0; i < HDAC_CODECS_LEN; i++) { 81955505Sshin if (HDA_DEV_MATCH(hdac_codecs[i].id, id)) 82055505Sshin return (hdac_codecs[i].name); 82155505Sshin } 82255505Sshin 82355505Sshin return ((id == 0x00000000) ? "NULL Codec" : "Unknown Codec"); 82455505Sshin} 825121156Sume 82655505Sshinstatic char * 82755505Sshinhdac_audio_ctl_ossmixer_mask2name(uint32_t devmask) 82855505Sshin{ 82955505Sshin static char *ossname[] = SOUND_DEVICE_NAMES; 830121156Sume static char *unknown = "???"; 831121156Sume int i; 832121156Sume 833121156Sume for (i = SOUND_MIXER_NRDEVICES - 1; i >= 0; i--) { 83455505Sshin if (devmask & (1 << i)) 835121156Sume return (ossname[i]); 83655505Sshin } 83755505Sshin return (unknown); 83855505Sshin} 83955505Sshin 84055505Sshinstatic void 84155505Sshinhdac_audio_ctl_ossmixer_mask2allname(uint32_t mask, char *buf, size_t len) 84255505Sshin{ 84355505Sshin static char *ossname[] = SOUND_DEVICE_NAMES; 84455505Sshin int i, first = 1; 84555505Sshin 846121156Sume bzero(buf, len); 84755505Sshin for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { 84855505Sshin if (mask & (1 << i)) { 84955505Sshin if (first == 0) 85055505Sshin strlcat(buf, ", ", len); 851121156Sume strlcat(buf, ossname[i], len); 85255505Sshin first = 0; 85355505Sshin } 85455505Sshin } 85555505Sshin} 85655505Sshin 85755505Sshinstatic struct hdac_audio_ctl * 85855505Sshinhdac_audio_ctl_each(struct hdac_devinfo *devinfo, int *index) 859122615Sume{ 860122615Sume if (devinfo == NULL || 86178064Sume devinfo->node_type != HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO || 862122615Sume index == NULL || devinfo->function.audio.ctl == NULL || 863122615Sume devinfo->function.audio.ctlcnt < 1 || 864122615Sume *index < 0 || *index >= devinfo->function.audio.ctlcnt) 86562590Sitojun return (NULL); 866122615Sume return (&devinfo->function.audio.ctl[(*index)++]); 86762590Sitojun} 868122615Sume 86955505Sshinstatic struct hdac_audio_ctl * 87055505Sshinhdac_audio_ctl_amp_get(struct hdac_devinfo *devinfo, nid_t nid, 87155505Sshin int index, int cnt) 87255505Sshin{ 87355505Sshin struct hdac_audio_ctl *ctl, *retctl = NULL; 87455505Sshin int i, at, atindex, found = 0; 87555505Sshin 87655505Sshin if (devinfo == NULL || devinfo->function.audio.ctl == NULL) 87755505Sshin return (NULL); 87855505Sshin 87955505Sshin at = cnt; 88055505Sshin if (at == 0) 88155505Sshin at = 1; 88255505Sshin else if (at < 0) 88355505Sshin at = -1; 88455505Sshin atindex = index; 88555505Sshin if (atindex < 0) 88655505Sshin atindex = -1; 88755505Sshin 88855505Sshin i = 0; 88955505Sshin while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 89055505Sshin if (ctl->enable == 0 || ctl->widget == NULL) 89155505Sshin continue; 89255505Sshin if (!(ctl->widget->nid == nid && (atindex == -1 || 89355505Sshin ctl->index == atindex))) 89455505Sshin continue; 895122615Sume found++; 896122615Sume if (found == cnt) 897122615Sume return (ctl); 898122615Sume retctl = ctl; 899186500Sqingli } 900151473Ssuz 90162590Sitojun return ((at == -1) ? retctl : NULL); 90262590Sitojun} 903124241Ssuz 90462590Sitojunstatic void 905151473Ssuzhdac_hp_switch_handler(struct hdac_devinfo *devinfo) 90655505Sshin{ 90755505Sshin struct hdac_softc *sc; 90855505Sshin struct hdac_widget *w; 90955505Sshin struct hdac_audio_ctl *ctl; 91055505Sshin uint32_t val, id, res; 91155505Sshin int i = 0, j, timeout, forcemute; 91255505Sshin nid_t cad; 913151473Ssuz 91462590Sitojun if (devinfo == NULL || devinfo->codec == NULL || 91555505Sshin devinfo->codec->sc == NULL) 916151473Ssuz return; 91755505Sshin 91855505Sshin sc = devinfo->codec->sc; 91955505Sshin cad = devinfo->codec->cad; 92055505Sshin id = hdac_codec_id(devinfo); 92155505Sshin for (i = 0; i < HDAC_HP_SWITCH_LEN; i++) { 92255505Sshin if (HDA_DEV_MATCH(hdac_hp_switch[i].model, 92355505Sshin sc->pci_subvendor) && 92455505Sshin hdac_hp_switch[i].id == id) 925121156Sume break; 926121156Sume } 92755505Sshin 92855505Sshin if (i >= HDAC_HP_SWITCH_LEN) 92955505Sshin return; 93055505Sshin 93155505Sshin forcemute = 0; 93255505Sshin if (hdac_hp_switch[i].eapdnid != -1) { 93355505Sshin w = hdac_widget_get(devinfo, hdac_hp_switch[i].eapdnid); 93455505Sshin if (w != NULL && w->param.eapdbtl != HDAC_INVALID) 93555505Sshin forcemute = (w->param.eapdbtl & 93655505Sshin HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD) ? 0 : 1; 93755505Sshin } 93855505Sshin 939122615Sume if (hdac_hp_switch[i].execsense != -1) 940122615Sume hdac_command(sc, 94162590Sitojun HDA_CMD_SET_PIN_SENSE(cad, hdac_hp_switch[i].hpnid, 94262590Sitojun hdac_hp_switch[i].execsense), cad); 94355505Sshin 94455505Sshin timeout = 10000; 94562590Sitojun do { 94662590Sitojun res = hdac_command(sc, 94778064Sume HDA_CMD_GET_PIN_SENSE(cad, hdac_hp_switch[i].hpnid), 94878064Sume cad); 94978064Sume if (hdac_hp_switch[i].execsense == -1 || res != 0x7fffffff) 95055505Sshin break; 95155505Sshin DELAY(10); 952121156Sume } while (--timeout != 0); 953121156Sume 95455505Sshin HDA_BOOTVERBOSE( 95555505Sshin device_printf(sc->dev, 956121156Sume "HDA_DEBUG: Pin sense: nid=%d timeout=%d res=0x%08x\n", 95755505Sshin hdac_hp_switch[i].hpnid, timeout, res); 958121156Sume ); 959121156Sume 960122615Sume res = HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT(res); 96162590Sitojun res ^= hdac_hp_switch[i].inverted; 96262590Sitojun 963122615Sume switch (hdac_hp_switch[i].type) { 96462590Sitojun case HDAC_HP_SWITCH_CTL: 96562590Sitojun ctl = hdac_audio_ctl_amp_get(devinfo, 96662590Sitojun hdac_hp_switch[i].hpnid, 0, 1); 96762590Sitojun if (ctl != NULL) { 96862590Sitojun val = (res != 0 && forcemute == 0) ? 96962590Sitojun HDA_AMP_MUTE_NONE : HDA_AMP_MUTE_ALL; 97062590Sitojun if (val != ctl->muted) { 97162590Sitojun ctl->muted = val; 97262590Sitojun hdac_audio_ctl_amp_set(ctl, 97362590Sitojun HDA_AMP_MUTE_DEFAULT, ctl->left, 97462590Sitojun ctl->right); 97562590Sitojun } 97662590Sitojun } 97762590Sitojun for (j = 0; hdac_hp_switch[i].spkrnid[j] != -1; j++) { 97862590Sitojun ctl = hdac_audio_ctl_amp_get(devinfo, 97962590Sitojun hdac_hp_switch[i].spkrnid[j], 0, 1); 98062590Sitojun if (ctl == NULL) 981151468Ssuz continue; 982151468Ssuz val = (res != 0 || forcemute == 1) ? 983151468Ssuz HDA_AMP_MUTE_ALL : HDA_AMP_MUTE_NONE; 984151468Ssuz if (val == ctl->muted) 985151468Ssuz continue; 986151468Ssuz ctl->muted = val; 987151468Ssuz hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_DEFAULT, 988151468Ssuz ctl->left, ctl->right); 989151468Ssuz } 990151468Ssuz break; 991151468Ssuz case HDAC_HP_SWITCH_CTRL: 992151468Ssuz if (res != 0) { 993151468Ssuz /* HP in */ 994151468Ssuz w = hdac_widget_get(devinfo, hdac_hp_switch[i].hpnid); 995151468Ssuz if (w != NULL && w->type == 996151468Ssuz HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) { 997151468Ssuz if (forcemute == 0) 998151468Ssuz val = w->wclass.pin.ctrl | 999151468Ssuz HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 1000151468Ssuz else 1001151468Ssuz val = w->wclass.pin.ctrl & 1002151474Ssuz ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 100362590Sitojun if (val != w->wclass.pin.ctrl) { 1004118498Sume w->wclass.pin.ctrl = val; 1005118498Sume hdac_command(sc, 1006118498Sume HDA_CMD_SET_PIN_WIDGET_CTRL(cad, 1007197138Shrs w->nid, w->wclass.pin.ctrl), cad); 1008197138Shrs } 1009197138Shrs } 1010122615Sume for (j = 0; hdac_hp_switch[i].spkrnid[j] != -1; j++) { 1011122615Sume w = hdac_widget_get(devinfo, 1012122615Sume hdac_hp_switch[i].spkrnid[j]); 1013151468Ssuz if (w == NULL || w->type != 1014151468Ssuz HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 1015151468Ssuz continue; 101662590Sitojun val = w->wclass.pin.ctrl & 101762590Sitojun ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 1018151468Ssuz if (val == w->wclass.pin.ctrl) 1019151468Ssuz continue; 1020121156Sume w->wclass.pin.ctrl = val; 102162590Sitojun hdac_command(sc, HDA_CMD_SET_PIN_WIDGET_CTRL( 102262590Sitojun cad, w->nid, w->wclass.pin.ctrl), cad); 1023151468Ssuz } 102462590Sitojun } else { 102562590Sitojun /* HP out */ 1026121162Sume w = hdac_widget_get(devinfo, hdac_hp_switch[i].hpnid); 1027121162Sume if (w != NULL && w->type == 1028121162Sume HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) { 1029121162Sume val = w->wclass.pin.ctrl & 1030121162Sume ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 1031151468Ssuz if (val != w->wclass.pin.ctrl) { 1032151468Ssuz w->wclass.pin.ctrl = val; 1033151468Ssuz hdac_command(sc, 1034151468Ssuz HDA_CMD_SET_PIN_WIDGET_CTRL(cad, 103555505Sshin w->nid, w->wclass.pin.ctrl), cad); 1036121471Sume } 103755505Sshin } 103855505Sshin for (j = 0; hdac_hp_switch[i].spkrnid[j] != -1; j++) { 1039121156Sume w = hdac_widget_get(devinfo, 104055505Sshin hdac_hp_switch[i].spkrnid[j]); 104162590Sitojun if (w == NULL || w->type != 104278064Sume HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 104378064Sume continue; 104478064Sume if (forcemute == 0) 104578064Sume val = w->wclass.pin.ctrl | 104678064Sume HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 104778064Sume else 104878064Sume val = w->wclass.pin.ctrl & 1049121156Sume ~HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 105078064Sume if (val == w->wclass.pin.ctrl) 105178064Sume continue; 105278064Sume w->wclass.pin.ctrl = val; 105378064Sume hdac_command(sc, HDA_CMD_SET_PIN_WIDGET_CTRL( 105478064Sume cad, w->nid, w->wclass.pin.ctrl), cad); 105578064Sume } 105678064Sume } 105778064Sume break; 105878064Sume case HDAC_HP_SWITCH_DEBUG: 105978064Sume if (hdac_hp_switch[i].execsense != -1) 106078064Sume hdac_command(sc, 106178064Sume HDA_CMD_SET_PIN_SENSE(cad, hdac_hp_switch[i].hpnid, 1062151472Ssuz hdac_hp_switch[i].execsense), cad); 1063151472Ssuz res = hdac_command(sc, 106478064Sume HDA_CMD_GET_PIN_SENSE(cad, hdac_hp_switch[i].hpnid), cad); 106578064Sume device_printf(sc->dev, 106678064Sume "[ 0] HDA_DEBUG: Pin sense: nid=%d res=0x%08x\n", 106778064Sume hdac_hp_switch[i].hpnid, res); 106878064Sume for (j = 0; hdac_hp_switch[i].spkrnid[j] != -1; j++) { 106978064Sume w = hdac_widget_get(devinfo, 107062590Sitojun hdac_hp_switch[i].spkrnid[j]); 107162590Sitojun if (w == NULL || w->type != 1072151474Ssuz HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 1073151474Ssuz continue; 1074151474Ssuz if (hdac_hp_switch[i].execsense != -1) 1075151474Ssuz hdac_command(sc, 1076118498Sume HDA_CMD_SET_PIN_SENSE(cad, w->nid, 1077118498Sume hdac_hp_switch[i].execsense), cad); 1078118498Sume res = hdac_command(sc, 1079118498Sume HDA_CMD_GET_PIN_SENSE(cad, w->nid), cad); 1080118498Sume device_printf(sc->dev, 1081118498Sume "[%2d] HDA_DEBUG: Pin sense: nid=%d res=0x%08x\n", 1082197138Shrs j + 1, w->nid, res); 1083197138Shrs } 1084197138Shrs break; 1085197138Shrs default: 1086122615Sume break; 1087122615Sume } 1088122615Sume} 1089122615Sume 1090122615Sumestatic void 109162590Sitojunhdac_unsolicited_handler(struct hdac_codec *codec, uint32_t tag) 109255505Sshin{ 1093121156Sume struct hdac_softc *sc; 109455505Sshin struct hdac_devinfo *devinfo = NULL; 109555505Sshin device_t *devlist = NULL; 109655505Sshin int devcount, i; 109778064Sume 109878064Sume if (codec == NULL || codec->sc == NULL) 109978064Sume return; 110078064Sume 110155505Sshin sc = codec->sc; 110255505Sshin 110355505Sshin HDA_BOOTVERBOSE( 110478064Sume device_printf(sc->dev, "HDA_DEBUG: Unsol Tag: 0x%08x\n", tag); 110578064Sume ); 110678064Sume 110778064Sume device_get_children(sc->dev, &devlist, &devcount); 110878064Sume for (i = 0; devlist != NULL && i < devcount; i++) { 110978064Sume devinfo = (struct hdac_devinfo *)device_get_ivars(devlist[i]); 111078064Sume if (devinfo != NULL && devinfo->node_type == 111178064Sume HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO && 111278064Sume devinfo->codec != NULL && 111378064Sume devinfo->codec->cad == codec->cad) { 111478064Sume break; 1115151472Ssuz } else 1116151472Ssuz devinfo = NULL; 111778064Sume } 111878064Sume if (devlist != NULL) 1119121156Sume free(devlist, M_TEMP); 112078064Sume 112178064Sume if (devinfo == NULL) 112278064Sume return; 112378064Sume 112478064Sume switch (tag) { 112578064Sume case HDAC_UNSOLTAG_EVENT_HP: 112678064Sume hdac_hp_switch_handler(devinfo); 112778064Sume break; 112878064Sume case HDAC_UNSOLTAG_EVENT_TEST: 112978064Sume device_printf(sc->dev, "Unsol Test!\n"); 113078064Sume break; 113178064Sume default: 113278064Sume break; 1133121156Sume } 113478064Sume} 1135121156Sume 113678064Sumestatic int 1137121156Sumehdac_stream_intr(struct hdac_softc *sc, struct hdac_chan *ch) 113878064Sume{ 1139121156Sume /* XXX to be removed */ 1140121156Sume#ifdef HDAC_INTR_EXTRA 114178064Sume uint32_t res; 114278064Sume#endif 1143121156Sume 114478064Sume if (!(ch->flags & HDAC_CHN_RUNNING)) 114578064Sume return (0); 114678064Sume 114778064Sume /* XXX to be removed */ 114878064Sume#ifdef HDAC_INTR_EXTRA 1149121156Sume res = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDSTS); 115078064Sume#endif 115178064Sume 115278064Sume /* XXX to be removed */ 115355505Sshin#ifdef HDAC_INTR_EXTRA 115455505Sshin HDA_BOOTVERBOSE( 115555505Sshin if (res & (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE)) 115655505Sshin device_printf(sc->dev, 115755505Sshin "PCMDIR_%s intr triggered beyond stream boundary:" 1158121156Sume "%08x\n", 1159121156Sume (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", res); 116055505Sshin ); 116155505Sshin#endif 1162121156Sume 116355505Sshin HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDSTS, 1164121156Sume HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS ); 1165121156Sume 1166121156Sume /* XXX to be removed */ 116762590Sitojun#ifdef HDAC_INTR_EXTRA 116878064Sume if (res & HDAC_SDSTS_BCIS) { 116955505Sshin#endif 117055505Sshin return (1); 117155505Sshin /* XXX to be removed */ 117255505Sshin#ifdef HDAC_INTR_EXTRA 117355505Sshin } 117455505Sshin#endif 117555505Sshin 1176121156Sume return (0); 1177121156Sume} 1178121156Sume 117955505Sshin/**************************************************************************** 1180121156Sume * void hdac_intr_handler(void *) 118155505Sshin * 1182121156Sume * Interrupt handler. Processes interrupts received from the hdac. 1183121156Sume ****************************************************************************/ 118455505Sshinstatic void 118555505Sshinhdac_intr_handler(void *context) 118655505Sshin{ 118755505Sshin struct hdac_softc *sc; 118855505Sshin uint32_t intsts; 1189121156Sume uint8_t rirbsts; 119055505Sshin struct hdac_rirb *rirb_base; 119155505Sshin uint32_t trigger; 119255505Sshin 119378064Sume sc = (struct hdac_softc *)context; 119455505Sshin 119555505Sshin hdac_lock(sc); 119655505Sshin if (sc->polling != 0) { 119755505Sshin hdac_unlock(sc); 119855505Sshin return; 119978064Sume } 120078064Sume 120178064Sume /* Do we have anything to do? */ 120278064Sume intsts = HDAC_READ_4(&sc->mem, HDAC_INTSTS); 120378064Sume if (!HDA_FLAG_MATCH(intsts, HDAC_INTSTS_GIS)) { 120478064Sume hdac_unlock(sc); 120578064Sume return; 120678064Sume } 120778064Sume 120878064Sume trigger = 0; 120978064Sume 121078064Sume /* Was this a controller interrupt? */ 121178064Sume if (HDA_FLAG_MATCH(intsts, HDAC_INTSTS_CIS)) { 121278064Sume rirb_base = (struct hdac_rirb *)sc->rirb_dma.dma_vaddr; 121378064Sume rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS); 121478064Sume /* Get as many responses that we can */ 121578064Sume while (HDA_FLAG_MATCH(rirbsts, HDAC_RIRBSTS_RINTFL)) { 1216121156Sume HDAC_WRITE_1(&sc->mem, 121778064Sume HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL); 121878064Sume if (hdac_rirb_flush(sc) != 0) 121978064Sume trigger |= HDAC_TRIGGER_UNSOL; 122078064Sume rirbsts = HDAC_READ_1(&sc->mem, HDAC_RIRBSTS); 122178064Sume } 122278064Sume /* XXX to be removed */ 122378064Sume /* Clear interrupt and exit */ 122478064Sume#ifdef HDAC_INTR_EXTRA 122578064Sume HDAC_WRITE_4(&sc->mem, HDAC_INTSTS, HDAC_INTSTS_CIS); 122678064Sume#endif 122778064Sume } 122878064Sume 122978064Sume if (intsts & HDAC_INTSTS_SIS_MASK) { 123078064Sume if ((intsts & (1 << sc->num_iss)) && 123178064Sume hdac_stream_intr(sc, &sc->play) != 0) 123278064Sume trigger |= HDAC_TRIGGER_PLAY; 123378064Sume if ((intsts & (1 << 0)) && 1234121156Sume hdac_stream_intr(sc, &sc->rec) != 0) 123578064Sume trigger |= HDAC_TRIGGER_REC; 123678064Sume /* XXX to be removed */ 123778064Sume#ifdef HDAC_INTR_EXTRA 123878064Sume HDAC_WRITE_4(&sc->mem, HDAC_INTSTS, intsts & 123978064Sume HDAC_INTSTS_SIS_MASK); 124078064Sume#endif 124178064Sume } 1242121156Sume 1243121156Sume hdac_unlock(sc); 1244121156Sume 1245121156Sume if (trigger & HDAC_TRIGGER_PLAY) 124678064Sume chn_intr(sc->play.c); 1247121156Sume if (trigger & HDAC_TRIGGER_REC) 124878064Sume chn_intr(sc->rec.c); 1249121156Sume if (trigger & HDAC_TRIGGER_UNSOL) 125078064Sume taskqueue_enqueue(taskqueue_thread, &sc->unsolq_task); 1251121156Sume} 125278064Sume 125378064Sume/**************************************************************************** 125478064Sume * int hdac_reset(hdac_softc *) 1255122615Sume * 125678064Sume * Reset the hdac to a quiescent and known state. 125778064Sume ****************************************************************************/ 125878064Sumestatic int 1259122615Sumehdac_reset(struct hdac_softc *sc) 126078064Sume{ 126178064Sume uint32_t gctl; 126278064Sume int count, i; 126378064Sume 1264121156Sume /* 126578064Sume * Stop all Streams DMA engine 126678064Sume */ 126778064Sume for (i = 0; i < sc->num_iss; i++) 126878064Sume HDAC_WRITE_4(&sc->mem, HDAC_ISDCTL(sc, i), 0x0); 126978064Sume for (i = 0; i < sc->num_oss; i++) 127078064Sume HDAC_WRITE_4(&sc->mem, HDAC_OSDCTL(sc, i), 0x0); 127178064Sume for (i = 0; i < sc->num_bss; i++) 127278064Sume HDAC_WRITE_4(&sc->mem, HDAC_BSDCTL(sc, i), 0x0); 127378064Sume 127478064Sume /* 127578064Sume * Stop Control DMA engines. 127678064Sume */ 1277122615Sume HDAC_WRITE_1(&sc->mem, HDAC_CORBCTL, 0x0); 127878064Sume HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, 0x0); 127978064Sume 128078064Sume /* 128178064Sume * Reset DMA position buffer. 128278064Sume */ 128378064Sume HDAC_WRITE_4(&sc->mem, HDAC_DPIBLBASE, 0x0); 128478064Sume HDAC_WRITE_4(&sc->mem, HDAC_DPIBUBASE, 0x0); 128578064Sume 128678064Sume /* 128778064Sume * Reset the controller. The reset must remain asserted for 1288121156Sume * a minimum of 100us. 1289121156Sume */ 129078064Sume gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); 1291121156Sume HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl & ~HDAC_GCTL_CRST); 129278064Sume count = 10000; 129378064Sume do { 129478064Sume gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); 129578064Sume if (!(gctl & HDAC_GCTL_CRST)) 129678064Sume break; 129778064Sume DELAY(10); 129878064Sume } while (--count); 129978064Sume if (gctl & HDAC_GCTL_CRST) { 130078064Sume device_printf(sc->dev, "Unable to put hdac in reset\n"); 130178064Sume return (ENXIO); 130278064Sume } 130378064Sume DELAY(100); 130478064Sume gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); 130578064Sume HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl | HDAC_GCTL_CRST); 130678064Sume count = 10000; 130778064Sume do { 130878064Sume gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL); 130978064Sume if (gctl & HDAC_GCTL_CRST) 131055505Sshin break; 131155505Sshin DELAY(10); 131255505Sshin } while (--count); 131355505Sshin if (!(gctl & HDAC_GCTL_CRST)) { 131455505Sshin device_printf(sc->dev, "Device stuck in reset\n"); 131555505Sshin return (ENXIO); 131655505Sshin } 1317121156Sume 1318121156Sume /* 131955505Sshin * Wait for codecs to finish their own reset sequence. The delay here 132055505Sshin * should be of 250us but for some reasons, on it's not enough on my 1321121156Sume * computer. Let's use twice as much as necessary to make sure that 132255505Sshin * it's reset properly. 1323121156Sume */ 1324121156Sume DELAY(1000); 1325121156Sume 132662590Sitojun return (0); 132755505Sshin} 132878064Sume 132978064Sume 133078064Sume/**************************************************************************** 133178064Sume * int hdac_get_capabilities(struct hdac_softc *); 133278064Sume * 133378064Sume * Retreive the general capabilities of the hdac; 133478064Sume * Number of Input Streams 133578064Sume * Number of Output Streams 133678064Sume * Number of bidirectional Streams 133778064Sume * 64bit ready 133878064Sume * CORB and RIRB sizes 133978064Sume ****************************************************************************/ 134078064Sumestatic int 134178064Sumehdac_get_capabilities(struct hdac_softc *sc) 134278064Sume{ 134378064Sume uint16_t gcap; 134478064Sume uint8_t corbsize, rirbsize; 134578064Sume 134678064Sume gcap = HDAC_READ_2(&sc->mem, HDAC_GCAP); 134778064Sume sc->num_iss = HDAC_GCAP_ISS(gcap); 134878064Sume sc->num_oss = HDAC_GCAP_OSS(gcap); 1349121156Sume sc->num_bss = HDAC_GCAP_BSS(gcap); 135078064Sume 135178064Sume sc->support_64bit = HDA_FLAG_MATCH(gcap, HDAC_GCAP_64OK); 135278064Sume 135378064Sume corbsize = HDAC_READ_1(&sc->mem, HDAC_CORBSIZE); 135478064Sume if ((corbsize & HDAC_CORBSIZE_CORBSZCAP_256) == 135578064Sume HDAC_CORBSIZE_CORBSZCAP_256) 135678064Sume sc->corb_size = 256; 135778064Sume else if ((corbsize & HDAC_CORBSIZE_CORBSZCAP_16) == 1358121156Sume HDAC_CORBSIZE_CORBSZCAP_16) 1359121156Sume sc->corb_size = 16; 136078064Sume else if ((corbsize & HDAC_CORBSIZE_CORBSZCAP_2) == 136178064Sume HDAC_CORBSIZE_CORBSZCAP_2) 136278064Sume sc->corb_size = 2; 136378064Sume else { 1364121156Sume device_printf(sc->dev, "%s: Invalid corb size (%x)\n", 136578064Sume __func__, corbsize); 136655505Sshin return (ENXIO); 136762590Sitojun } 136862590Sitojun 136962590Sitojun rirbsize = HDAC_READ_1(&sc->mem, HDAC_RIRBSIZE); 137062590Sitojun if ((rirbsize & HDAC_RIRBSIZE_RIRBSZCAP_256) == 137178064Sume HDAC_RIRBSIZE_RIRBSZCAP_256) 137278064Sume sc->rirb_size = 256; 1373121156Sume else if ((rirbsize & HDAC_RIRBSIZE_RIRBSZCAP_16) == 137478064Sume HDAC_RIRBSIZE_RIRBSZCAP_16) 137578064Sume sc->rirb_size = 16; 137678064Sume else if ((rirbsize & HDAC_RIRBSIZE_RIRBSZCAP_2) == 1377121156Sume HDAC_RIRBSIZE_RIRBSZCAP_2) 1378121156Sume sc->rirb_size = 2; 1379121156Sume else { 1380121156Sume device_printf(sc->dev, "%s: Invalid rirb size (%x)\n", 138178064Sume __func__, rirbsize); 1382121156Sume return (ENXIO); 138378064Sume } 1384121156Sume 138578064Sume return (0); 1386121156Sume} 138778064Sume 138862590Sitojun 1389121156Sume/**************************************************************************** 1390121156Sume * void hdac_dma_cb 139178064Sume * 139255505Sshin * This function is called by bus_dmamap_load when the mapping has been 139355505Sshin * established. We just record the physical address of the mapping into 139455505Sshin * the struct hdac_dma passed in. 1395122615Sume ****************************************************************************/ 139655505Sshinstatic void 139755505Sshinhdac_dma_cb(void *callback_arg, bus_dma_segment_t *segs, int nseg, int error) 139855505Sshin{ 1399122615Sume struct hdac_dma *dma; 140055505Sshin 140162590Sitojun if (error == 0) { 140255505Sshin dma = (struct hdac_dma *)callback_arg; 140362590Sitojun dma->dma_paddr = segs[0].ds_addr; 1404121156Sume } 140555505Sshin} 140662590Sitojun 140778064Sume 140878064Sume/**************************************************************************** 140978064Sume * int hdac_dma_alloc 141078064Sume * 141162590Sitojun * This function allocate and setup a dma region (struct hdac_dma). 141262590Sitojun * It must be freed by a corresponding hdac_dma_free. 141362590Sitojun ****************************************************************************/ 141462590Sitojunstatic int 141562590Sitojunhdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size) 141662590Sitojun{ 141762590Sitojun bus_size_t roundsz; 141862590Sitojun int result; 141962590Sitojun int lowaddr; 142062590Sitojun 142162590Sitojun roundsz = roundup2(size, HDAC_DMA_ALIGNMENT); 142262590Sitojun lowaddr = (sc->support_64bit) ? BUS_SPACE_MAXADDR : 142362590Sitojun BUS_SPACE_MAXADDR_32BIT; 142462590Sitojun bzero(dma, sizeof(*dma)); 142562590Sitojun 142662590Sitojun /* 142762590Sitojun * Create a DMA tag 142878064Sume */ 142962590Sitojun result = bus_dma_tag_create(NULL, /* parent */ 143062590Sitojun HDAC_DMA_ALIGNMENT, /* alignment */ 143162590Sitojun 0, /* boundary */ 143262590Sitojun lowaddr, /* lowaddr */ 143362590Sitojun BUS_SPACE_MAXADDR, /* highaddr */ 143478064Sume NULL, /* filtfunc */ 143578064Sume NULL, /* fistfuncarg */ 143662590Sitojun roundsz, /* maxsize */ 143762590Sitojun 1, /* nsegments */ 143855505Sshin roundsz, /* maxsegsz */ 143955505Sshin 0, /* flags */ 144055505Sshin NULL, /* lockfunc */ 144155505Sshin NULL, /* lockfuncarg */ 144262590Sitojun &dma->dma_tag); /* dmat */ 144355505Sshin if (result != 0) { 144455505Sshin device_printf(sc->dev, "%s: bus_dma_tag_create failed (%x)\n", 144555505Sshin __func__, result); 144655505Sshin goto hdac_dma_alloc_fail; 144755505Sshin } 144862590Sitojun 144955505Sshin /* 1450121156Sume * Allocate DMA memory 1451121156Sume */ 1452121156Sume result = bus_dmamem_alloc(dma->dma_tag, (void **)&dma->dma_vaddr, 145362590Sitojun BUS_DMA_NOWAIT | BUS_DMA_ZERO | 145455505Sshin ((sc->flags & HDAC_F_DMA_NOCACHE) ? BUS_DMA_NOCACHE : 0), 1455121156Sume &dma->dma_map); 1456121156Sume if (result != 0) { 145762590Sitojun device_printf(sc->dev, "%s: bus_dmamem_alloc failed (%x)\n", 1458121156Sume __func__, result); 1459121156Sume goto hdac_dma_alloc_fail; 1460121156Sume } 1461121156Sume 1462121156Sume dma->dma_size = roundsz; 146362590Sitojun 146462590Sitojun /* 1465121156Sume * Map the memory 146662590Sitojun */ 146762590Sitojun result = bus_dmamap_load(dma->dma_tag, dma->dma_map, 146878064Sume (void *)dma->dma_vaddr, roundsz, hdac_dma_cb, (void *)dma, 0); 146962590Sitojun if (result != 0 || dma->dma_paddr == 0) { 147055505Sshin if (result == 0) 147155505Sshin result = ENOMEM; 147255505Sshin device_printf(sc->dev, "%s: bus_dmamem_load failed (%x)\n", 1473121156Sume __func__, result); 147462590Sitojun goto hdac_dma_alloc_fail; 147555505Sshin } 147655505Sshin 147755505Sshin HDA_BOOTVERBOSE( 147855505Sshin device_printf(sc->dev, "%s: size=%ju -> roundsz=%ju\n", 147978064Sume __func__, (uintmax_t)size, (uintmax_t)roundsz); 148055505Sshin ); 148155505Sshin 148255505Sshin return (0); 148355505Sshin 148455505Sshinhdac_dma_alloc_fail: 148555505Sshin hdac_dma_free(sc, dma); 148655505Sshin 148755505Sshin return (result); 148855505Sshin} 148955505Sshin 1490121156Sume 149155505Sshin/**************************************************************************** 1492121156Sume * void hdac_dma_free(struct hdac_softc *, struct hdac_dma *) 149355505Sshin * 149455505Sshin * Free a struct dhac_dma that has been previously allocated via the 149555505Sshin * hdac_dma_alloc function. 149655505Sshin ****************************************************************************/ 149755505Sshinstatic void 149855505Sshinhdac_dma_free(struct hdac_softc *sc, struct hdac_dma *dma) 149955505Sshin{ 150055505Sshin if (dma->dma_map != NULL) { 150155505Sshin#if 0 150255505Sshin /* Flush caches */ 1503121156Sume bus_dmamap_sync(dma->dma_tag, dma->dma_map, 150455505Sshin BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1505121156Sume#endif 150662590Sitojun bus_dmamap_unload(dma->dma_tag, dma->dma_map); 150762590Sitojun } 150855505Sshin if (dma->dma_vaddr != NULL) { 150955505Sshin bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map); 151055505Sshin dma->dma_vaddr = NULL; 151155505Sshin } 151255505Sshin dma->dma_map = NULL; 151355505Sshin if (dma->dma_tag != NULL) { 151455505Sshin bus_dma_tag_destroy(dma->dma_tag); 151555505Sshin dma->dma_tag = NULL; 151662590Sitojun } 151762590Sitojun dma->dma_size = 0; 1518121156Sume} 151962590Sitojun 1520121156Sume/**************************************************************************** 152162590Sitojun * int hdac_mem_alloc(struct hdac_softc *) 152262590Sitojun * 152355505Sshin * Allocate all the bus resources necessary to speak with the physical 152455505Sshin * controller. 152562590Sitojun ****************************************************************************/ 152662590Sitojunstatic int 152762590Sitojunhdac_mem_alloc(struct hdac_softc *sc) 152862590Sitojun{ 152962590Sitojun struct hdac_mem *mem; 153062590Sitojun 153162590Sitojun mem = &sc->mem; 153262590Sitojun mem->mem_rid = PCIR_BAR(0); 153362590Sitojun mem->mem_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, 153462590Sitojun &mem->mem_rid, RF_ACTIVE); 153562590Sitojun if (mem->mem_res == NULL) { 153662590Sitojun device_printf(sc->dev, 153762590Sitojun "%s: Unable to allocate memory resource\n", __func__); 153862590Sitojun return (ENOMEM); 153962590Sitojun } 154062590Sitojun mem->mem_tag = rman_get_bustag(mem->mem_res); 154162590Sitojun mem->mem_handle = rman_get_bushandle(mem->mem_res); 154262590Sitojun 1543121156Sume return (0); 154462590Sitojun} 154562590Sitojun 154662590Sitojun/**************************************************************************** 1547121156Sume * void hdac_mem_free(struct hdac_softc *) 154862590Sitojun * 154962590Sitojun * Free up resources previously allocated by hdac_mem_alloc. 155062590Sitojun ****************************************************************************/ 155162590Sitojunstatic void 155262590Sitojunhdac_mem_free(struct hdac_softc *sc) 155362590Sitojun{ 155462590Sitojun struct hdac_mem *mem; 155562590Sitojun 155662590Sitojun mem = &sc->mem; 155762590Sitojun if (mem->mem_res != NULL) 155862590Sitojun bus_release_resource(sc->dev, SYS_RES_MEMORY, mem->mem_rid, 155962590Sitojun mem->mem_res); 156062590Sitojun mem->mem_res = NULL; 156162590Sitojun} 1562121156Sume 156362590Sitojun/**************************************************************************** 156462590Sitojun * int hdac_irq_alloc(struct hdac_softc *) 1565121156Sume * 156662590Sitojun * Allocate and setup the resources necessary for interrupt handling. 156762590Sitojun ****************************************************************************/ 156862590Sitojunstatic int 156962590Sitojunhdac_irq_alloc(struct hdac_softc *sc) 157062590Sitojun{ 157162590Sitojun struct hdac_irq *irq; 157262590Sitojun int result; 157362590Sitojun 157462590Sitojun irq = &sc->irq; 157562590Sitojun irq->irq_rid = 0x0; 157662590Sitojun 157762590Sitojun#ifdef HDAC_MSI_ENABLED 157862590Sitojun if ((sc->flags & HDAC_F_MSI) && 157962590Sitojun (result = pci_msi_count(sc->dev)) == 1 && 158055505Sshin pci_alloc_msi(sc->dev, &result) == 0) 158155505Sshin irq->irq_rid = 0x1; 158255505Sshin else 158355505Sshin#endif 158455505Sshin sc->flags &= ~HDAC_F_MSI; 158555505Sshin 158655505Sshin irq->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, 158755505Sshin &irq->irq_rid, RF_SHAREABLE | RF_ACTIVE); 1588121156Sume if (irq->irq_res == NULL) { 1589121156Sume device_printf(sc->dev, "%s: Unable to allocate irq\n", 159055505Sshin __func__); 159155505Sshin goto hdac_irq_alloc_fail; 159255505Sshin } 159355505Sshin result = snd_setup_intr(sc->dev, irq->irq_res, INTR_MPSAFE, 159455505Sshin hdac_intr_handler, sc, &irq->irq_handle); 159555505Sshin if (result != 0) { 159655505Sshin device_printf(sc->dev, 159755505Sshin "%s: Unable to setup interrupt handler (%x)\n", 1598121156Sume __func__, result); 1599121156Sume goto hdac_irq_alloc_fail; 1600121156Sume } 1601121156Sume 160255505Sshin return (0); 160355505Sshin 160455505Sshinhdac_irq_alloc_fail: 1605121156Sume hdac_irq_free(sc); 1606121156Sume 1607121156Sume return (ENXIO); 1608121156Sume} 160955505Sshin 161055505Sshin/**************************************************************************** 161155505Sshin * void hdac_irq_free(struct hdac_softc *) 1612121156Sume * 1613121156Sume * Free up resources previously allocated by hdac_irq_alloc. 1614121156Sume ****************************************************************************/ 1615121156Sumestatic void 161655505Sshinhdac_irq_free(struct hdac_softc *sc) 1617121156Sume{ 161855505Sshin struct hdac_irq *irq; 161955505Sshin 162055505Sshin irq = &sc->irq; 162155505Sshin if (irq->irq_res != NULL && irq->irq_handle != NULL) 162255505Sshin bus_teardown_intr(sc->dev, irq->irq_res, irq->irq_handle); 162355505Sshin if (irq->irq_res != NULL) 162455505Sshin bus_release_resource(sc->dev, SYS_RES_IRQ, irq->irq_rid, 162555505Sshin irq->irq_res); 162655505Sshin#ifdef HDAC_MSI_ENABLED 162755505Sshin if ((sc->flags & HDAC_F_MSI) && irq->irq_rid == 0x1) 162855505Sshin pci_release_msi(sc->dev); 162955505Sshin#endif 163055505Sshin irq->irq_handle = NULL; 163155505Sshin irq->irq_res = NULL; 163255505Sshin irq->irq_rid = 0x0; 163355505Sshin} 163455505Sshin 163555505Sshin/**************************************************************************** 163655505Sshin * void hdac_corb_init(struct hdac_softc *) 1637186119Sqingli * 1638186119Sqingli * Initialize the corb registers for operations but do not start it up yet. 1639 * The CORB engine must not be running when this function is called. 1640 ****************************************************************************/ 1641static void 1642hdac_corb_init(struct hdac_softc *sc) 1643{ 1644 uint8_t corbsize; 1645 uint64_t corbpaddr; 1646 1647 /* Setup the CORB size. */ 1648 switch (sc->corb_size) { 1649 case 256: 1650 corbsize = HDAC_CORBSIZE_CORBSIZE(HDAC_CORBSIZE_CORBSIZE_256); 1651 break; 1652 case 16: 1653 corbsize = HDAC_CORBSIZE_CORBSIZE(HDAC_CORBSIZE_CORBSIZE_16); 1654 break; 1655 case 2: 1656 corbsize = HDAC_CORBSIZE_CORBSIZE(HDAC_CORBSIZE_CORBSIZE_2); 1657 break; 1658 default: 1659 panic("%s: Invalid CORB size (%x)\n", __func__, sc->corb_size); 1660 } 1661 HDAC_WRITE_1(&sc->mem, HDAC_CORBSIZE, corbsize); 1662 1663 /* Setup the CORB Address in the hdac */ 1664 corbpaddr = (uint64_t)sc->corb_dma.dma_paddr; 1665 HDAC_WRITE_4(&sc->mem, HDAC_CORBLBASE, (uint32_t)corbpaddr); 1666 HDAC_WRITE_4(&sc->mem, HDAC_CORBUBASE, (uint32_t)(corbpaddr >> 32)); 1667 1668 /* Set the WP and RP */ 1669 sc->corb_wp = 0; 1670 HDAC_WRITE_2(&sc->mem, HDAC_CORBWP, sc->corb_wp); 1671 HDAC_WRITE_2(&sc->mem, HDAC_CORBRP, HDAC_CORBRP_CORBRPRST); 1672 /* 1673 * The HDA specification indicates that the CORBRPRST bit will always 1674 * read as zero. Unfortunately, it seems that at least the 82801G 1675 * doesn't reset the bit to zero, which stalls the corb engine. 1676 * manually reset the bit to zero before continuing. 1677 */ 1678 HDAC_WRITE_2(&sc->mem, HDAC_CORBRP, 0x0); 1679 1680 /* Enable CORB error reporting */ 1681#if 0 1682 HDAC_WRITE_1(&sc->mem, HDAC_CORBCTL, HDAC_CORBCTL_CMEIE); 1683#endif 1684} 1685 1686/**************************************************************************** 1687 * void hdac_rirb_init(struct hdac_softc *) 1688 * 1689 * Initialize the rirb registers for operations but do not start it up yet. 1690 * The RIRB engine must not be running when this function is called. 1691 ****************************************************************************/ 1692static void 1693hdac_rirb_init(struct hdac_softc *sc) 1694{ 1695 uint8_t rirbsize; 1696 uint64_t rirbpaddr; 1697 1698 /* Setup the RIRB size. */ 1699 switch (sc->rirb_size) { 1700 case 256: 1701 rirbsize = HDAC_RIRBSIZE_RIRBSIZE(HDAC_RIRBSIZE_RIRBSIZE_256); 1702 break; 1703 case 16: 1704 rirbsize = HDAC_RIRBSIZE_RIRBSIZE(HDAC_RIRBSIZE_RIRBSIZE_16); 1705 break; 1706 case 2: 1707 rirbsize = HDAC_RIRBSIZE_RIRBSIZE(HDAC_RIRBSIZE_RIRBSIZE_2); 1708 break; 1709 default: 1710 panic("%s: Invalid RIRB size (%x)\n", __func__, sc->rirb_size); 1711 } 1712 HDAC_WRITE_1(&sc->mem, HDAC_RIRBSIZE, rirbsize); 1713 1714 /* Setup the RIRB Address in the hdac */ 1715 rirbpaddr = (uint64_t)sc->rirb_dma.dma_paddr; 1716 HDAC_WRITE_4(&sc->mem, HDAC_RIRBLBASE, (uint32_t)rirbpaddr); 1717 HDAC_WRITE_4(&sc->mem, HDAC_RIRBUBASE, (uint32_t)(rirbpaddr >> 32)); 1718 1719 /* Setup the WP and RP */ 1720 sc->rirb_rp = 0; 1721 HDAC_WRITE_2(&sc->mem, HDAC_RIRBWP, HDAC_RIRBWP_RIRBWPRST); 1722 1723 if (sc->polling == 0) { 1724 /* Setup the interrupt threshold */ 1725 HDAC_WRITE_2(&sc->mem, HDAC_RINTCNT, sc->rirb_size / 2); 1726 1727 /* Enable Overrun and response received reporting */ 1728#if 0 1729 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, 1730 HDAC_RIRBCTL_RIRBOIC | HDAC_RIRBCTL_RINTCTL); 1731#else 1732 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, HDAC_RIRBCTL_RINTCTL); 1733#endif 1734 } 1735 1736#if 0 1737 /* 1738 * Make sure that the Host CPU cache doesn't contain any dirty 1739 * cache lines that falls in the rirb. If I understood correctly, it 1740 * should be sufficient to do this only once as the rirb is purely 1741 * read-only from now on. 1742 */ 1743 bus_dmamap_sync(sc->rirb_dma.dma_tag, sc->rirb_dma.dma_map, 1744 BUS_DMASYNC_PREREAD); 1745#endif 1746} 1747 1748/**************************************************************************** 1749 * void hdac_corb_start(hdac_softc *) 1750 * 1751 * Startup the corb DMA engine 1752 ****************************************************************************/ 1753static void 1754hdac_corb_start(struct hdac_softc *sc) 1755{ 1756 uint32_t corbctl; 1757 1758 corbctl = HDAC_READ_1(&sc->mem, HDAC_CORBCTL); 1759 corbctl |= HDAC_CORBCTL_CORBRUN; 1760 HDAC_WRITE_1(&sc->mem, HDAC_CORBCTL, corbctl); 1761} 1762 1763/**************************************************************************** 1764 * void hdac_rirb_start(hdac_softc *) 1765 * 1766 * Startup the rirb DMA engine 1767 ****************************************************************************/ 1768static void 1769hdac_rirb_start(struct hdac_softc *sc) 1770{ 1771 uint32_t rirbctl; 1772 1773 rirbctl = HDAC_READ_1(&sc->mem, HDAC_RIRBCTL); 1774 rirbctl |= HDAC_RIRBCTL_RIRBDMAEN; 1775 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, rirbctl); 1776} 1777 1778 1779/**************************************************************************** 1780 * void hdac_scan_codecs(struct hdac_softc *, int) 1781 * 1782 * Scan the bus for available codecs, starting with num. 1783 ****************************************************************************/ 1784static void 1785hdac_scan_codecs(struct hdac_softc *sc, int num) 1786{ 1787 struct hdac_codec *codec; 1788 int i; 1789 uint16_t statests; 1790 1791 if (num < 0) 1792 num = 0; 1793 if (num >= HDAC_CODEC_MAX) 1794 num = HDAC_CODEC_MAX - 1; 1795 1796 statests = HDAC_READ_2(&sc->mem, HDAC_STATESTS); 1797 for (i = num; i < HDAC_CODEC_MAX; i++) { 1798 if (HDAC_STATESTS_SDIWAKE(statests, i)) { 1799 /* We have found a codec. */ 1800 codec = (struct hdac_codec *)malloc(sizeof(*codec), 1801 M_HDAC, M_ZERO | M_NOWAIT); 1802 if (codec == NULL) { 1803 device_printf(sc->dev, 1804 "Unable to allocate memory for codec\n"); 1805 continue; 1806 } 1807 codec->commands = NULL; 1808 codec->responses_received = 0; 1809 codec->verbs_sent = 0; 1810 codec->sc = sc; 1811 codec->cad = i; 1812 sc->codecs[i] = codec; 1813 if (hdac_probe_codec(codec) != 0) 1814 break; 1815 } 1816 } 1817 /* All codecs have been probed, now try to attach drivers to them */ 1818 /* bus_generic_attach(sc->dev); */ 1819} 1820 1821/**************************************************************************** 1822 * void hdac_probe_codec(struct hdac_softc *, int) 1823 * 1824 * Probe a the given codec_id for available function groups. 1825 ****************************************************************************/ 1826static int 1827hdac_probe_codec(struct hdac_codec *codec) 1828{ 1829 struct hdac_softc *sc = codec->sc; 1830 struct hdac_devinfo *devinfo; 1831 uint32_t vendorid, revisionid, subnode; 1832 int startnode; 1833 int endnode; 1834 int i; 1835 nid_t cad = codec->cad; 1836 1837 HDA_BOOTVERBOSE( 1838 device_printf(sc->dev, "HDA_DEBUG: Probing codec: %d\n", cad); 1839 ); 1840 vendorid = hdac_command(sc, 1841 HDA_CMD_GET_PARAMETER(cad, 0x0, HDA_PARAM_VENDOR_ID), 1842 cad); 1843 revisionid = hdac_command(sc, 1844 HDA_CMD_GET_PARAMETER(cad, 0x0, HDA_PARAM_REVISION_ID), 1845 cad); 1846 subnode = hdac_command(sc, 1847 HDA_CMD_GET_PARAMETER(cad, 0x0, HDA_PARAM_SUB_NODE_COUNT), 1848 cad); 1849 startnode = HDA_PARAM_SUB_NODE_COUNT_START(subnode); 1850 endnode = startnode + HDA_PARAM_SUB_NODE_COUNT_TOTAL(subnode); 1851 1852 HDA_BOOTVERBOSE( 1853 device_printf(sc->dev, "HDA_DEBUG: \tstartnode=%d endnode=%d\n", 1854 startnode, endnode); 1855 ); 1856 for (i = startnode; i < endnode; i++) { 1857 devinfo = hdac_probe_function(codec, i); 1858 if (devinfo != NULL) { 1859 /* XXX Ignore other FG. */ 1860 devinfo->vendor_id = 1861 HDA_PARAM_VENDOR_ID_VENDOR_ID(vendorid); 1862 devinfo->device_id = 1863 HDA_PARAM_VENDOR_ID_DEVICE_ID(vendorid); 1864 devinfo->revision_id = 1865 HDA_PARAM_REVISION_ID_REVISION_ID(revisionid); 1866 devinfo->stepping_id = 1867 HDA_PARAM_REVISION_ID_STEPPING_ID(revisionid); 1868 HDA_BOOTVERBOSE( 1869 device_printf(sc->dev, 1870 "HDA_DEBUG: \tFound AFG nid=%d " 1871 "[startnode=%d endnode=%d]\n", 1872 devinfo->nid, startnode, endnode); 1873 ); 1874 return (1); 1875 } 1876 } 1877 1878 HDA_BOOTVERBOSE( 1879 device_printf(sc->dev, "HDA_DEBUG: \tAFG not found\n"); 1880 ); 1881 return (0); 1882} 1883 1884static struct hdac_devinfo * 1885hdac_probe_function(struct hdac_codec *codec, nid_t nid) 1886{ 1887 struct hdac_softc *sc = codec->sc; 1888 struct hdac_devinfo *devinfo; 1889 uint32_t fctgrptype; 1890 nid_t cad = codec->cad; 1891 1892 fctgrptype = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE(hdac_command(sc, 1893 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_FCT_GRP_TYPE), cad)); 1894 1895 /* XXX For now, ignore other FG. */ 1896 if (fctgrptype != HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) 1897 return (NULL); 1898 1899 devinfo = (struct hdac_devinfo *)malloc(sizeof(*devinfo), M_HDAC, 1900 M_NOWAIT | M_ZERO); 1901 if (devinfo == NULL) { 1902 device_printf(sc->dev, "%s: Unable to allocate ivar\n", 1903 __func__); 1904 return (NULL); 1905 } 1906 1907 devinfo->nid = nid; 1908 devinfo->node_type = fctgrptype; 1909 devinfo->codec = codec; 1910 1911 hdac_add_child(sc, devinfo); 1912 1913 return (devinfo); 1914} 1915 1916static void 1917hdac_add_child(struct hdac_softc *sc, struct hdac_devinfo *devinfo) 1918{ 1919 devinfo->dev = device_add_child(sc->dev, NULL, -1); 1920 device_set_ivars(devinfo->dev, (void *)devinfo); 1921 /* XXX - Print more information when booting verbose??? */ 1922} 1923 1924static void 1925hdac_widget_connection_parse(struct hdac_widget *w) 1926{ 1927 struct hdac_softc *sc = w->devinfo->codec->sc; 1928 uint32_t res; 1929 int i, j, max, ents, entnum; 1930 nid_t cad = w->devinfo->codec->cad; 1931 nid_t nid = w->nid; 1932 nid_t cnid, addcnid, prevcnid; 1933 1934 w->nconns = 0; 1935 1936 res = hdac_command(sc, 1937 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_CONN_LIST_LENGTH), cad); 1938 1939 ents = HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH(res); 1940 1941 if (ents < 1) 1942 return; 1943 1944 entnum = HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM(res) ? 2 : 4; 1945 max = (sizeof(w->conns) / sizeof(w->conns[0])) - 1; 1946 prevcnid = 0; 1947 1948#define CONN_RMASK(e) (1 << ((32 / (e)) - 1)) 1949#define CONN_NMASK(e) (CONN_RMASK(e) - 1) 1950#define CONN_RESVAL(r, e, n) ((r) >> ((32 / (e)) * (n))) 1951#define CONN_RANGE(r, e, n) (CONN_RESVAL(r, e, n) & CONN_RMASK(e)) 1952#define CONN_CNID(r, e, n) (CONN_RESVAL(r, e, n) & CONN_NMASK(e)) 1953 1954 for (i = 0; i < ents; i += entnum) { 1955 res = hdac_command(sc, 1956 HDA_CMD_GET_CONN_LIST_ENTRY(cad, nid, i), cad); 1957 for (j = 0; j < entnum; j++) { 1958 cnid = CONN_CNID(res, entnum, j); 1959 if (cnid == 0) { 1960 if (w->nconns < ents) 1961 device_printf(sc->dev, 1962 "%s: nid=%d WARNING: zero cnid " 1963 "entnum=%d j=%d index=%d " 1964 "entries=%d found=%d res=0x%08x\n", 1965 __func__, nid, entnum, j, i, 1966 ents, w->nconns, res); 1967 else 1968 goto getconns_out; 1969 } 1970 if (cnid < w->devinfo->startnode || 1971 cnid >= w->devinfo->endnode) { 1972 HDA_BOOTVERBOSE( 1973 device_printf(sc->dev, 1974 "%s: GHOST: nid=%d j=%d " 1975 "entnum=%d index=%d res=0x%08x\n", 1976 __func__, nid, j, entnum, i, res); 1977 ); 1978 } 1979 if (CONN_RANGE(res, entnum, j) == 0) 1980 addcnid = cnid; 1981 else if (prevcnid == 0 || prevcnid >= cnid) { 1982 device_printf(sc->dev, 1983 "%s: WARNING: Invalid child range " 1984 "nid=%d index=%d j=%d entnum=%d " 1985 "prevcnid=%d cnid=%d res=0x%08x\n", 1986 __func__, nid, i, j, entnum, prevcnid, 1987 cnid, res); 1988 addcnid = cnid; 1989 } else 1990 addcnid = prevcnid + 1; 1991 while (addcnid <= cnid) { 1992 if (w->nconns > max) { 1993 device_printf(sc->dev, 1994 "%s: nid=%d: Adding %d: " 1995 "Max connection reached! max=%d\n", 1996 __func__, nid, addcnid, max + 1); 1997 goto getconns_out; 1998 } 1999 w->conns[w->nconns++] = addcnid++; 2000 } 2001 prevcnid = cnid; 2002 } 2003 } 2004 2005getconns_out: 2006 HDA_BOOTVERBOSE( 2007 device_printf(sc->dev, 2008 "HDA_DEBUG: %s: nid=%d entries=%d found=%d\n", 2009 __func__, nid, ents, w->nconns); 2010 ); 2011 return; 2012} 2013 2014static uint32_t 2015hdac_widget_pin_getconfig(struct hdac_widget *w) 2016{ 2017 struct hdac_softc *sc; 2018 uint32_t config, orig, id; 2019 nid_t cad, nid; 2020 2021 sc = w->devinfo->codec->sc; 2022 cad = w->devinfo->codec->cad; 2023 nid = w->nid; 2024 id = hdac_codec_id(w->devinfo); 2025 2026 config = hdac_command(sc, 2027 HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid), 2028 cad); 2029 orig = config; 2030 2031 /* 2032 * XXX REWRITE!!!! Don't argue! 2033 */ 2034 if (id == HDA_CODEC_ALC880 && sc->pci_subvendor == LG_LW20_SUBVENDOR) { 2035 switch (nid) { 2036 case 26: 2037 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2038 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 2039 break; 2040 case 27: 2041 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2042 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT; 2043 break; 2044 default: 2045 break; 2046 } 2047 } else if (id == HDA_CODEC_ALC880 && 2048 (sc->pci_subvendor == CLEVO_D900T_SUBVENDOR || 2049 sc->pci_subvendor == ASUS_M5200_SUBVENDOR)) { 2050 /* 2051 * Super broken BIOS 2052 */ 2053 switch (nid) { 2054 case 20: 2055 break; 2056 case 21: 2057 break; 2058 case 22: 2059 break; 2060 case 23: 2061 break; 2062 case 24: /* MIC1 */ 2063 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2064 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 2065 break; 2066 case 25: /* XXX MIC2 */ 2067 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2068 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 2069 break; 2070 case 26: /* LINE1 */ 2071 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2072 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 2073 break; 2074 case 27: /* XXX LINE2 */ 2075 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2076 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 2077 break; 2078 case 28: /* CD */ 2079 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2080 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_CD; 2081 break; 2082 case 30: 2083 break; 2084 case 31: 2085 break; 2086 default: 2087 break; 2088 } 2089 } else if (id == HDA_CODEC_ALC883 && 2090 (sc->pci_subvendor == MSI_MS034A_SUBVENDOR || 2091 HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, sc->pci_subvendor))) { 2092 switch (nid) { 2093 case 25: 2094 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2095 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2096 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 2097 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2098 break; 2099 case 28: 2100 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2101 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2102 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 2103 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2104 break; 2105 default: 2106 break; 2107 } 2108 } else if (id == HDA_CODEC_CXVENICE && sc->pci_subvendor == 2109 HP_V3000_SUBVENDOR) { 2110 switch (nid) { 2111 case 18: 2112 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 2113 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 2114 break; 2115 case 20: 2116 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2117 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2118 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 2119 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2120 break; 2121 case 21: 2122 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2123 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2124 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 2125 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2126 break; 2127 default: 2128 break; 2129 } 2130 } else if (id == HDA_CODEC_CXWAIKIKI && sc->pci_subvendor == 2131 HP_DV5000_SUBVENDOR) { 2132 switch (nid) { 2133 case 20: 2134 case 21: 2135 config &= ~HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK; 2136 config |= HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE; 2137 break; 2138 default: 2139 break; 2140 } 2141 } else if (id == HDA_CODEC_ALC861 && sc->pci_subvendor == 2142 ASUS_W6F_SUBVENDOR) { 2143 switch (nid) { 2144 case 11: 2145 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2146 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2147 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT | 2148 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2149 break; 2150 case 12: 2151 case 14: 2152 case 16: 2153 case 31: 2154 case 32: 2155 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2156 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2157 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN | 2158 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2159 break; 2160 case 15: 2161 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2162 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2163 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT | 2164 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK); 2165 break; 2166 default: 2167 break; 2168 } 2169 } else if (id == HDA_CODEC_ALC861 && sc->pci_subvendor == 2170 UNIWILL_9075_SUBVENDOR) { 2171 switch (nid) { 2172 case 15: 2173 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2174 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2175 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT | 2176 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK); 2177 break; 2178 default: 2179 break; 2180 } 2181 } else if (id == HDA_CODEC_AD1986A && 2182 (sc->pci_subvendor == ASUS_M2NPVMX_SUBVENDOR || 2183 sc->pci_subvendor == ASUS_A8NVMCSM_SUBVENDOR)) { 2184 switch (nid) { 2185 case 28: /* LINE */ 2186 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2187 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN; 2188 break; 2189 case 29: /* MIC */ 2190 config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 2191 config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN; 2192 break; 2193 default: 2194 break; 2195 } 2196 } else if (id == HDA_CODEC_ALC268 && 2197 HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, sc->pci_subvendor)) { 2198 switch (nid) { 2199 case 28: 2200 config &= ~(HDA_CONFIG_DEFAULTCONF_DEVICE_MASK | 2201 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK); 2202 config |= (HDA_CONFIG_DEFAULTCONF_DEVICE_CD | 2203 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED); 2204 break; 2205 default: 2206 break; 2207 } 2208 } 2209 2210 HDA_BOOTVERBOSE( 2211 if (config != orig) 2212 device_printf(sc->dev, 2213 "HDA_DEBUG: Pin config nid=%u 0x%08x -> 0x%08x\n", 2214 nid, orig, config); 2215 ); 2216 2217 return (config); 2218} 2219 2220static uint32_t 2221hdac_widget_pin_getcaps(struct hdac_widget *w) 2222{ 2223 struct hdac_softc *sc; 2224 uint32_t caps, orig, id; 2225 nid_t cad, nid; 2226 2227 sc = w->devinfo->codec->sc; 2228 cad = w->devinfo->codec->cad; 2229 nid = w->nid; 2230 id = hdac_codec_id(w->devinfo); 2231 2232 caps = hdac_command(sc, 2233 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_PIN_CAP), cad); 2234 orig = caps; 2235 2236 HDA_BOOTVERBOSE( 2237 if (caps != orig) 2238 device_printf(sc->dev, 2239 "HDA_DEBUG: Pin caps nid=%u 0x%08x -> 0x%08x\n", 2240 nid, orig, caps); 2241 ); 2242 2243 return (caps); 2244} 2245 2246static void 2247hdac_widget_pin_parse(struct hdac_widget *w) 2248{ 2249 struct hdac_softc *sc = w->devinfo->codec->sc; 2250 uint32_t config, pincap; 2251 char *devstr, *connstr; 2252 nid_t cad = w->devinfo->codec->cad; 2253 nid_t nid = w->nid; 2254 2255 config = hdac_widget_pin_getconfig(w); 2256 w->wclass.pin.config = config; 2257 2258 pincap = hdac_widget_pin_getcaps(w); 2259 w->wclass.pin.cap = pincap; 2260 2261 w->wclass.pin.ctrl = hdac_command(sc, 2262 HDA_CMD_GET_PIN_WIDGET_CTRL(cad, nid), cad) & 2263 ~(HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE | 2264 HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE | 2265 HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE | 2266 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK); 2267 2268 if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap)) 2269 w->wclass.pin.ctrl |= HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE; 2270 if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap)) 2271 w->wclass.pin.ctrl |= HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE; 2272 if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap)) 2273 w->wclass.pin.ctrl |= HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE; 2274 if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)) { 2275 w->param.eapdbtl = hdac_command(sc, 2276 HDA_CMD_GET_EAPD_BTL_ENABLE(cad, nid), cad); 2277 w->param.eapdbtl &= 0x7; 2278 w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD; 2279 } else 2280 w->param.eapdbtl = HDAC_INVALID; 2281 2282 switch (config & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) { 2283 case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT: 2284 devstr = "line out"; 2285 break; 2286 case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER: 2287 devstr = "speaker"; 2288 break; 2289 case HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT: 2290 devstr = "headphones out"; 2291 break; 2292 case HDA_CONFIG_DEFAULTCONF_DEVICE_CD: 2293 devstr = "CD"; 2294 break; 2295 case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT: 2296 devstr = "SPDIF out"; 2297 break; 2298 case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT: 2299 devstr = "digital (other) out"; 2300 break; 2301 case HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_LINE: 2302 devstr = "modem, line side"; 2303 break; 2304 case HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_HANDSET: 2305 devstr = "modem, handset side"; 2306 break; 2307 case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN: 2308 devstr = "line in"; 2309 break; 2310 case HDA_CONFIG_DEFAULTCONF_DEVICE_AUX: 2311 devstr = "AUX"; 2312 break; 2313 case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN: 2314 devstr = "Mic in"; 2315 break; 2316 case HDA_CONFIG_DEFAULTCONF_DEVICE_TELEPHONY: 2317 devstr = "telephony"; 2318 break; 2319 case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN: 2320 devstr = "SPDIF in"; 2321 break; 2322 case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN: 2323 devstr = "digital (other) in"; 2324 break; 2325 case HDA_CONFIG_DEFAULTCONF_DEVICE_OTHER: 2326 devstr = "other"; 2327 break; 2328 default: 2329 devstr = "unknown"; 2330 break; 2331 } 2332 2333 switch (config & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) { 2334 case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK: 2335 connstr = "jack"; 2336 break; 2337 case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE: 2338 connstr = "none"; 2339 break; 2340 case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED: 2341 connstr = "fixed"; 2342 break; 2343 case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_BOTH: 2344 connstr = "jack / fixed"; 2345 break; 2346 default: 2347 connstr = "unknown"; 2348 break; 2349 } 2350 2351 strlcat(w->name, ": ", sizeof(w->name)); 2352 strlcat(w->name, devstr, sizeof(w->name)); 2353 strlcat(w->name, " (", sizeof(w->name)); 2354 strlcat(w->name, connstr, sizeof(w->name)); 2355 strlcat(w->name, ")", sizeof(w->name)); 2356} 2357 2358static void 2359hdac_widget_parse(struct hdac_widget *w) 2360{ 2361 struct hdac_softc *sc = w->devinfo->codec->sc; 2362 uint32_t wcap, cap; 2363 char *typestr; 2364 nid_t cad = w->devinfo->codec->cad; 2365 nid_t nid = w->nid; 2366 2367 wcap = hdac_command(sc, 2368 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_AUDIO_WIDGET_CAP), 2369 cad); 2370 w->param.widget_cap = wcap; 2371 w->type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(wcap); 2372 2373 switch (w->type) { 2374 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT: 2375 typestr = "audio output"; 2376 break; 2377 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT: 2378 typestr = "audio input"; 2379 break; 2380 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER: 2381 typestr = "audio mixer"; 2382 break; 2383 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR: 2384 typestr = "audio selector"; 2385 break; 2386 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX: 2387 typestr = "pin"; 2388 break; 2389 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET: 2390 typestr = "power widget"; 2391 break; 2392 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET: 2393 typestr = "volume widget"; 2394 break; 2395 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET: 2396 typestr = "beep widget"; 2397 break; 2398 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET: 2399 typestr = "vendor widget"; 2400 break; 2401 default: 2402 typestr = "unknown type"; 2403 break; 2404 } 2405 2406 strlcpy(w->name, typestr, sizeof(w->name)); 2407 2408 if (HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(wcap)) { 2409 hdac_command(sc, 2410 HDA_CMD_SET_POWER_STATE(cad, nid, HDA_CMD_POWER_STATE_D0), 2411 cad); 2412 DELAY(1000); 2413 } 2414 2415 hdac_widget_connection_parse(w); 2416 2417 if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(wcap)) { 2418 if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap)) 2419 w->param.outamp_cap = 2420 hdac_command(sc, 2421 HDA_CMD_GET_PARAMETER(cad, nid, 2422 HDA_PARAM_OUTPUT_AMP_CAP), cad); 2423 else 2424 w->param.outamp_cap = 2425 w->devinfo->function.audio.outamp_cap; 2426 } else 2427 w->param.outamp_cap = 0; 2428 2429 if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(wcap)) { 2430 if (HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(wcap)) 2431 w->param.inamp_cap = 2432 hdac_command(sc, 2433 HDA_CMD_GET_PARAMETER(cad, nid, 2434 HDA_PARAM_INPUT_AMP_CAP), cad); 2435 else 2436 w->param.inamp_cap = 2437 w->devinfo->function.audio.inamp_cap; 2438 } else 2439 w->param.inamp_cap = 0; 2440 2441 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT || 2442 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) { 2443 if (HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR(wcap)) { 2444 cap = hdac_command(sc, 2445 HDA_CMD_GET_PARAMETER(cad, nid, 2446 HDA_PARAM_SUPP_STREAM_FORMATS), cad); 2447 w->param.supp_stream_formats = (cap != 0) ? cap : 2448 w->devinfo->function.audio.supp_stream_formats; 2449 cap = hdac_command(sc, 2450 HDA_CMD_GET_PARAMETER(cad, nid, 2451 HDA_PARAM_SUPP_PCM_SIZE_RATE), cad); 2452 w->param.supp_pcm_size_rate = (cap != 0) ? cap : 2453 w->devinfo->function.audio.supp_pcm_size_rate; 2454 } else { 2455 w->param.supp_stream_formats = 2456 w->devinfo->function.audio.supp_stream_formats; 2457 w->param.supp_pcm_size_rate = 2458 w->devinfo->function.audio.supp_pcm_size_rate; 2459 } 2460 } else { 2461 w->param.supp_stream_formats = 0; 2462 w->param.supp_pcm_size_rate = 0; 2463 } 2464 2465 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 2466 hdac_widget_pin_parse(w); 2467} 2468 2469static struct hdac_widget * 2470hdac_widget_get(struct hdac_devinfo *devinfo, nid_t nid) 2471{ 2472 if (devinfo == NULL || devinfo->widget == NULL || 2473 nid < devinfo->startnode || nid >= devinfo->endnode) 2474 return (NULL); 2475 return (&devinfo->widget[nid - devinfo->startnode]); 2476} 2477 2478static __inline int 2479hda_poll_channel(struct hdac_chan *ch) 2480{ 2481 uint32_t sz, delta; 2482 volatile uint32_t ptr; 2483 2484 if (!(ch->flags & HDAC_CHN_RUNNING)) 2485 return (0); 2486 2487 sz = ch->blksz * ch->blkcnt; 2488 if (ch->dmapos != NULL) 2489 ptr = *(ch->dmapos); 2490 else 2491 ptr = HDAC_READ_4(&ch->devinfo->codec->sc->mem, 2492 ch->off + HDAC_SDLPIB); 2493 ch->ptr = ptr; 2494 ptr %= sz; 2495 ptr &= ~(ch->blksz - 1); 2496 delta = (sz + ptr - ch->prevptr) % sz; 2497 2498 if (delta < ch->blksz) 2499 return (0); 2500 2501 ch->prevptr = ptr; 2502 2503 return (1); 2504} 2505 2506#define hda_chan_active(sc) (((sc)->play.flags | (sc)->rec.flags) & \ 2507 HDAC_CHN_RUNNING) 2508 2509static void 2510hda_poll_callback(void *arg) 2511{ 2512 struct hdac_softc *sc = arg; 2513 uint32_t trigger; 2514 2515 if (sc == NULL) 2516 return; 2517 2518 hdac_lock(sc); 2519 if (sc->polling == 0 || hda_chan_active(sc) == 0) { 2520 hdac_unlock(sc); 2521 return; 2522 } 2523 2524 trigger = 0; 2525 trigger |= (hda_poll_channel(&sc->play) != 0) ? HDAC_TRIGGER_PLAY : 0; 2526 trigger |= (hda_poll_channel(&sc->rec)) != 0 ? HDAC_TRIGGER_REC : 0; 2527 2528 /* XXX */ 2529 callout_reset(&sc->poll_hda, 1/*sc->poll_ticks*/, 2530 hda_poll_callback, sc); 2531 2532 hdac_unlock(sc); 2533 2534 if (trigger & HDAC_TRIGGER_PLAY) 2535 chn_intr(sc->play.c); 2536 if (trigger & HDAC_TRIGGER_REC) 2537 chn_intr(sc->rec.c); 2538} 2539 2540static int 2541hdac_rirb_flush(struct hdac_softc *sc) 2542{ 2543 struct hdac_rirb *rirb_base, *rirb; 2544 struct hdac_codec *codec; 2545 struct hdac_command_list *commands; 2546 nid_t cad; 2547 uint32_t resp; 2548 uint8_t rirbwp; 2549 int ret; 2550 2551 rirb_base = (struct hdac_rirb *)sc->rirb_dma.dma_vaddr; 2552 rirbwp = HDAC_READ_1(&sc->mem, HDAC_RIRBWP); 2553#if 0 2554 bus_dmamap_sync(sc->rirb_dma.dma_tag, sc->rirb_dma.dma_map, 2555 BUS_DMASYNC_POSTREAD); 2556#endif 2557 2558 ret = 0; 2559 2560 while (sc->rirb_rp != rirbwp) { 2561 sc->rirb_rp++; 2562 sc->rirb_rp %= sc->rirb_size; 2563 rirb = &rirb_base[sc->rirb_rp]; 2564 cad = HDAC_RIRB_RESPONSE_EX_SDATA_IN(rirb->response_ex); 2565 if (cad < 0 || cad >= HDAC_CODEC_MAX || 2566 sc->codecs[cad] == NULL) 2567 continue; 2568 resp = rirb->response; 2569 codec = sc->codecs[cad]; 2570 commands = codec->commands; 2571 if (rirb->response_ex & HDAC_RIRB_RESPONSE_EX_UNSOLICITED) { 2572 sc->unsolq[sc->unsolq_wp++] = (cad << 16) | 2573 ((resp >> 26) & 0xffff); 2574 sc->unsolq_wp %= HDAC_UNSOLQ_MAX; 2575 } else if (commands != NULL && commands->num_commands > 0 && 2576 codec->responses_received < commands->num_commands) 2577 commands->responses[codec->responses_received++] = 2578 resp; 2579 ret++; 2580 } 2581 2582 return (ret); 2583} 2584 2585static int 2586hdac_unsolq_flush(struct hdac_softc *sc) 2587{ 2588 nid_t cad; 2589 uint32_t tag; 2590 int ret = 0; 2591 2592 if (sc->unsolq_st == HDAC_UNSOLQ_READY) { 2593 sc->unsolq_st = HDAC_UNSOLQ_BUSY; 2594 while (sc->unsolq_rp != sc->unsolq_wp) { 2595 cad = sc->unsolq[sc->unsolq_rp] >> 16; 2596 tag = sc->unsolq[sc->unsolq_rp++] & 0xffff; 2597 sc->unsolq_rp %= HDAC_UNSOLQ_MAX; 2598 hdac_unsolicited_handler(sc->codecs[cad], tag); 2599 ret++; 2600 } 2601 sc->unsolq_st = HDAC_UNSOLQ_READY; 2602 } 2603 2604 return (ret); 2605} 2606 2607static void 2608hdac_poll_callback(void *arg) 2609{ 2610 struct hdac_softc *sc = arg; 2611 if (sc == NULL) 2612 return; 2613 2614 hdac_lock(sc); 2615 if (sc->polling == 0 || sc->poll_ival == 0) { 2616 hdac_unlock(sc); 2617 return; 2618 } 2619 if (hdac_rirb_flush(sc) != 0) 2620 hdac_unsolq_flush(sc); 2621 callout_reset(&sc->poll_hdac, sc->poll_ival, hdac_poll_callback, sc); 2622 hdac_unlock(sc); 2623} 2624 2625static void 2626hdac_stream_stop(struct hdac_chan *ch) 2627{ 2628 struct hdac_softc *sc = ch->devinfo->codec->sc; 2629 uint32_t ctl; 2630 2631 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0); 2632 ctl &= ~(HDAC_SDCTL_IOCE | HDAC_SDCTL_FEIE | HDAC_SDCTL_DEIE | 2633 HDAC_SDCTL_RUN); 2634 HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl); 2635 2636 ch->flags &= ~HDAC_CHN_RUNNING; 2637 2638 if (sc->polling != 0) { 2639 int pollticks; 2640 2641 if (hda_chan_active(sc) == 0) { 2642 callout_stop(&sc->poll_hda); 2643 sc->poll_ticks = 1; 2644 } else { 2645 if (sc->play.flags & HDAC_CHN_RUNNING) 2646 ch = &sc->play; 2647 else 2648 ch = &sc->rec; 2649 pollticks = ((uint64_t)hz * ch->blksz) / 2650 ((uint64_t)sndbuf_getbps(ch->b) * 2651 sndbuf_getspd(ch->b)); 2652 pollticks >>= 2; 2653 if (pollticks > hz) 2654 pollticks = hz; 2655 if (pollticks < 1) { 2656 HDA_BOOTVERBOSE( 2657 device_printf(sc->dev, 2658 "%s: pollticks=%d < 1 !\n", 2659 __func__, pollticks); 2660 ); 2661 pollticks = 1; 2662 } 2663 if (pollticks > sc->poll_ticks) { 2664 HDA_BOOTVERBOSE( 2665 device_printf(sc->dev, 2666 "%s: pollticks %d -> %d\n", 2667 __func__, sc->poll_ticks, 2668 pollticks); 2669 ); 2670 sc->poll_ticks = pollticks; 2671 callout_reset(&sc->poll_hda, 1, 2672 hda_poll_callback, sc); 2673 } 2674 } 2675 } else { 2676 ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL); 2677 ctl &= ~(1 << (ch->off >> 5)); 2678 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl); 2679 } 2680} 2681 2682static void 2683hdac_stream_start(struct hdac_chan *ch) 2684{ 2685 struct hdac_softc *sc = ch->devinfo->codec->sc; 2686 uint32_t ctl; 2687 2688 if (sc->polling != 0) { 2689 int pollticks; 2690 2691 pollticks = ((uint64_t)hz * ch->blksz) / 2692 ((uint64_t)sndbuf_getbps(ch->b) * sndbuf_getspd(ch->b)); 2693 pollticks >>= 2; 2694 if (pollticks > hz) 2695 pollticks = hz; 2696 if (pollticks < 1) { 2697 HDA_BOOTVERBOSE( 2698 device_printf(sc->dev, 2699 "%s: pollticks=%d < 1 !\n", 2700 __func__, pollticks); 2701 ); 2702 pollticks = 1; 2703 } 2704 if (hda_chan_active(sc) == 0 || pollticks < sc->poll_ticks) { 2705 HDA_BOOTVERBOSE( 2706 if (hda_chan_active(sc) == 0) { 2707 device_printf(sc->dev, 2708 "%s: pollticks=%d\n", 2709 __func__, pollticks); 2710 } else { 2711 device_printf(sc->dev, 2712 "%s: pollticks %d -> %d\n", 2713 __func__, sc->poll_ticks, 2714 pollticks); 2715 } 2716 ); 2717 sc->poll_ticks = pollticks; 2718 callout_reset(&sc->poll_hda, 1, hda_poll_callback, 2719 sc); 2720 } 2721 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0); 2722 ctl |= HDAC_SDCTL_RUN; 2723 } else { 2724 ctl = HDAC_READ_4(&sc->mem, HDAC_INTCTL); 2725 ctl |= 1 << (ch->off >> 5); 2726 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, ctl); 2727 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0); 2728 ctl |= HDAC_SDCTL_IOCE | HDAC_SDCTL_FEIE | HDAC_SDCTL_DEIE | 2729 HDAC_SDCTL_RUN; 2730 } 2731 HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl); 2732 2733 ch->flags |= HDAC_CHN_RUNNING; 2734} 2735 2736static void 2737hdac_stream_reset(struct hdac_chan *ch) 2738{ 2739 struct hdac_softc *sc = ch->devinfo->codec->sc; 2740 int timeout = 1000; 2741 int to = timeout; 2742 uint32_t ctl; 2743 2744 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0); 2745 ctl |= HDAC_SDCTL_SRST; 2746 HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl); 2747 do { 2748 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0); 2749 if (ctl & HDAC_SDCTL_SRST) 2750 break; 2751 DELAY(10); 2752 } while (--to); 2753 if (!(ctl & HDAC_SDCTL_SRST)) { 2754 device_printf(sc->dev, "timeout in reset\n"); 2755 } 2756 ctl &= ~HDAC_SDCTL_SRST; 2757 HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL0, ctl); 2758 to = timeout; 2759 do { 2760 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL0); 2761 if (!(ctl & HDAC_SDCTL_SRST)) 2762 break; 2763 DELAY(10); 2764 } while (--to); 2765 if (ctl & HDAC_SDCTL_SRST) 2766 device_printf(sc->dev, "can't reset!\n"); 2767} 2768 2769static void 2770hdac_stream_setid(struct hdac_chan *ch) 2771{ 2772 struct hdac_softc *sc = ch->devinfo->codec->sc; 2773 uint32_t ctl; 2774 2775 ctl = HDAC_READ_1(&sc->mem, ch->off + HDAC_SDCTL2); 2776 ctl &= ~HDAC_SDCTL2_STRM_MASK; 2777 ctl |= ch->sid << HDAC_SDCTL2_STRM_SHIFT; 2778 HDAC_WRITE_1(&sc->mem, ch->off + HDAC_SDCTL2, ctl); 2779} 2780 2781static void 2782hdac_bdl_setup(struct hdac_chan *ch) 2783{ 2784 struct hdac_softc *sc = ch->devinfo->codec->sc; 2785 struct hdac_bdle *bdle; 2786 uint64_t addr; 2787 uint32_t blksz, blkcnt; 2788 int i; 2789 2790 addr = (uint64_t)sndbuf_getbufaddr(ch->b); 2791 bdle = (struct hdac_bdle *)ch->bdl_dma.dma_vaddr; 2792 2793 if (sc->polling != 0) { 2794 blksz = ch->blksz * ch->blkcnt; 2795 blkcnt = 1; 2796 } else { 2797 blksz = ch->blksz; 2798 blkcnt = ch->blkcnt; 2799 } 2800 2801 for (i = 0; i < blkcnt; i++, bdle++) { 2802 bdle->addrl = (uint32_t)addr; 2803 bdle->addrh = (uint32_t)(addr >> 32); 2804 bdle->len = blksz; 2805 bdle->ioc = 1 ^ sc->polling; 2806 addr += blksz; 2807 } 2808 2809 HDAC_WRITE_4(&sc->mem, ch->off + HDAC_SDCBL, blksz * blkcnt); 2810 HDAC_WRITE_2(&sc->mem, ch->off + HDAC_SDLVI, blkcnt - 1); 2811 addr = ch->bdl_dma.dma_paddr; 2812 HDAC_WRITE_4(&sc->mem, ch->off + HDAC_SDBDPL, (uint32_t)addr); 2813 HDAC_WRITE_4(&sc->mem, ch->off + HDAC_SDBDPU, (uint32_t)(addr >> 32)); 2814 if (ch->dmapos != NULL && 2815 !(HDAC_READ_4(&sc->mem, HDAC_DPIBLBASE) & 0x00000001)) { 2816 addr = sc->pos_dma.dma_paddr; 2817 HDAC_WRITE_4(&sc->mem, HDAC_DPIBLBASE, 2818 ((uint32_t)addr & HDAC_DPLBASE_DPLBASE_MASK) | 0x00000001); 2819 HDAC_WRITE_4(&sc->mem, HDAC_DPIBUBASE, (uint32_t)(addr >> 32)); 2820 } 2821} 2822 2823static int 2824hdac_bdl_alloc(struct hdac_chan *ch) 2825{ 2826 struct hdac_softc *sc = ch->devinfo->codec->sc; 2827 int rc; 2828 2829 rc = hdac_dma_alloc(sc, &ch->bdl_dma, 2830 sizeof(struct hdac_bdle) * HDA_BDL_MAX); 2831 if (rc) { 2832 device_printf(sc->dev, "can't alloc bdl\n"); 2833 return (rc); 2834 } 2835 2836 return (0); 2837} 2838 2839static void 2840hdac_audio_ctl_amp_set_internal(struct hdac_softc *sc, nid_t cad, nid_t nid, 2841 int index, int lmute, int rmute, 2842 int left, int right, int dir) 2843{ 2844 uint16_t v = 0; 2845 2846 if (sc == NULL) 2847 return; 2848 2849 if (left != right || lmute != rmute) { 2850 v = (1 << (15 - dir)) | (1 << 13) | (index << 8) | 2851 (lmute << 7) | left; 2852 hdac_command(sc, 2853 HDA_CMD_SET_AMP_GAIN_MUTE(cad, nid, v), cad); 2854 v = (1 << (15 - dir)) | (1 << 12) | (index << 8) | 2855 (rmute << 7) | right; 2856 } else 2857 v = (1 << (15 - dir)) | (3 << 12) | (index << 8) | 2858 (lmute << 7) | left; 2859 2860 hdac_command(sc, 2861 HDA_CMD_SET_AMP_GAIN_MUTE(cad, nid, v), cad); 2862} 2863 2864static void 2865hdac_audio_ctl_amp_set(struct hdac_audio_ctl *ctl, uint32_t mute, 2866 int left, int right) 2867{ 2868 struct hdac_softc *sc; 2869 nid_t nid, cad; 2870 int lmute, rmute; 2871 2872 if (ctl == NULL || ctl->widget == NULL || 2873 ctl->widget->devinfo == NULL || 2874 ctl->widget->devinfo->codec == NULL || 2875 ctl->widget->devinfo->codec->sc == NULL) 2876 return; 2877 2878 sc = ctl->widget->devinfo->codec->sc; 2879 cad = ctl->widget->devinfo->codec->cad; 2880 nid = ctl->widget->nid; 2881 2882 if (mute == HDA_AMP_MUTE_DEFAULT) { 2883 lmute = HDA_AMP_LEFT_MUTED(ctl->muted); 2884 rmute = HDA_AMP_RIGHT_MUTED(ctl->muted); 2885 } else { 2886 lmute = HDA_AMP_LEFT_MUTED(mute); 2887 rmute = HDA_AMP_RIGHT_MUTED(mute); 2888 } 2889 2890 if (ctl->dir & HDA_CTL_OUT) 2891 hdac_audio_ctl_amp_set_internal(sc, cad, nid, ctl->index, 2892 lmute, rmute, left, right, 0); 2893 if (ctl->dir & HDA_CTL_IN) 2894 hdac_audio_ctl_amp_set_internal(sc, cad, nid, ctl->index, 2895 lmute, rmute, left, right, 1); 2896 ctl->left = left; 2897 ctl->right = right; 2898} 2899 2900static void 2901hdac_widget_connection_select(struct hdac_widget *w, uint8_t index) 2902{ 2903 if (w == NULL || w->nconns < 1 || index > (w->nconns - 1)) 2904 return; 2905 hdac_command(w->devinfo->codec->sc, 2906 HDA_CMD_SET_CONNECTION_SELECT_CONTROL(w->devinfo->codec->cad, 2907 w->nid, index), w->devinfo->codec->cad); 2908 w->selconn = index; 2909} 2910 2911 2912/**************************************************************************** 2913 * uint32_t hdac_command_sendone_internal 2914 * 2915 * Wrapper function that sends only one command to a given codec 2916 ****************************************************************************/ 2917static uint32_t 2918hdac_command_sendone_internal(struct hdac_softc *sc, uint32_t verb, nid_t cad) 2919{ 2920 struct hdac_command_list cl; 2921 uint32_t response = HDAC_INVALID; 2922 2923 if (!hdac_lockowned(sc)) 2924 device_printf(sc->dev, "WARNING!!!! mtx not owned!!!!\n"); 2925 cl.num_commands = 1; 2926 cl.verbs = &verb; 2927 cl.responses = &response; 2928 2929 hdac_command_send_internal(sc, &cl, cad); 2930 2931 return (response); 2932} 2933 2934/**************************************************************************** 2935 * hdac_command_send_internal 2936 * 2937 * Send a command list to the codec via the corb. We queue as much verbs as 2938 * we can and msleep on the codec. When the interrupt get the responses 2939 * back from the rirb, it will wake us up so we can queue the remaining verbs 2940 * if any. 2941 ****************************************************************************/ 2942static void 2943hdac_command_send_internal(struct hdac_softc *sc, 2944 struct hdac_command_list *commands, nid_t cad) 2945{ 2946 struct hdac_codec *codec; 2947 int corbrp; 2948 uint32_t *corb; 2949 int timeout; 2950 int retry = 10; 2951 struct hdac_rirb *rirb_base; 2952 2953 if (sc == NULL || sc->codecs[cad] == NULL || commands == NULL || 2954 commands->num_commands < 1) 2955 return; 2956 2957 codec = sc->codecs[cad]; 2958 codec->commands = commands; 2959 codec->responses_received = 0; 2960 codec->verbs_sent = 0; 2961 corb = (uint32_t *)sc->corb_dma.dma_vaddr; 2962 rirb_base = (struct hdac_rirb *)sc->rirb_dma.dma_vaddr; 2963 2964 do { 2965 if (codec->verbs_sent != commands->num_commands) { 2966 /* Queue as many verbs as possible */ 2967 corbrp = HDAC_READ_2(&sc->mem, HDAC_CORBRP); 2968#if 0 2969 bus_dmamap_sync(sc->corb_dma.dma_tag, 2970 sc->corb_dma.dma_map, BUS_DMASYNC_PREWRITE); 2971#endif 2972 while (codec->verbs_sent != commands->num_commands && 2973 ((sc->corb_wp + 1) % sc->corb_size) != corbrp) { 2974 sc->corb_wp++; 2975 sc->corb_wp %= sc->corb_size; 2976 corb[sc->corb_wp] = 2977 commands->verbs[codec->verbs_sent++]; 2978 } 2979 2980 /* Send the verbs to the codecs */ 2981#if 0 2982 bus_dmamap_sync(sc->corb_dma.dma_tag, 2983 sc->corb_dma.dma_map, BUS_DMASYNC_POSTWRITE); 2984#endif 2985 HDAC_WRITE_2(&sc->mem, HDAC_CORBWP, sc->corb_wp); 2986 } 2987 2988 timeout = 1000; 2989 while (hdac_rirb_flush(sc) == 0 && --timeout) 2990 DELAY(10); 2991 } while ((codec->verbs_sent != commands->num_commands || 2992 codec->responses_received != commands->num_commands) && --retry); 2993 2994 if (retry == 0) 2995 device_printf(sc->dev, 2996 "%s: TIMEOUT numcmd=%d, sent=%d, received=%d\n", 2997 __func__, commands->num_commands, codec->verbs_sent, 2998 codec->responses_received); 2999 3000 codec->commands = NULL; 3001 codec->responses_received = 0; 3002 codec->verbs_sent = 0; 3003 3004 hdac_unsolq_flush(sc); 3005} 3006 3007 3008/**************************************************************************** 3009 * Device Methods 3010 ****************************************************************************/ 3011 3012/**************************************************************************** 3013 * int hdac_probe(device_t) 3014 * 3015 * Probe for the presence of an hdac. If none is found, check for a generic 3016 * match using the subclass of the device. 3017 ****************************************************************************/ 3018static int 3019hdac_probe(device_t dev) 3020{ 3021 int i, result; 3022 uint32_t model; 3023 uint16_t class, subclass; 3024 char desc[64]; 3025 3026 model = (uint32_t)pci_get_device(dev) << 16; 3027 model |= (uint32_t)pci_get_vendor(dev) & 0x0000ffff; 3028 class = pci_get_class(dev); 3029 subclass = pci_get_subclass(dev); 3030 3031 bzero(desc, sizeof(desc)); 3032 result = ENXIO; 3033 for (i = 0; i < HDAC_DEVICES_LEN; i++) { 3034 if (hdac_devices[i].model == model) { 3035 strlcpy(desc, hdac_devices[i].desc, sizeof(desc)); 3036 result = BUS_PROBE_DEFAULT; 3037 break; 3038 } 3039 if (HDA_DEV_MATCH(hdac_devices[i].model, model) && 3040 class == PCIC_MULTIMEDIA && 3041 subclass == PCIS_MULTIMEDIA_HDA) { 3042 strlcpy(desc, hdac_devices[i].desc, sizeof(desc)); 3043 result = BUS_PROBE_GENERIC; 3044 break; 3045 } 3046 } 3047 if (result == ENXIO && class == PCIC_MULTIMEDIA && 3048 subclass == PCIS_MULTIMEDIA_HDA) { 3049 strlcpy(desc, "Generic", sizeof(desc)); 3050 result = BUS_PROBE_GENERIC; 3051 } 3052 if (result != ENXIO) { 3053 strlcat(desc, " High Definition Audio Controller", 3054 sizeof(desc)); 3055 device_set_desc_copy(dev, desc); 3056 } 3057 3058 return (result); 3059} 3060 3061static void * 3062hdac_channel_init(kobj_t obj, void *data, struct snd_dbuf *b, 3063 struct pcm_channel *c, int dir) 3064{ 3065 struct hdac_devinfo *devinfo = data; 3066 struct hdac_softc *sc = devinfo->codec->sc; 3067 struct hdac_chan *ch; 3068 3069 hdac_lock(sc); 3070 if (dir == PCMDIR_PLAY) { 3071 ch = &sc->play; 3072 ch->off = (sc->num_iss + devinfo->function.audio.playcnt) << 5; 3073 devinfo->function.audio.playcnt++; 3074 } else { 3075 ch = &sc->rec; 3076 ch->off = devinfo->function.audio.reccnt << 5; 3077 devinfo->function.audio.reccnt++; 3078 } 3079 if (devinfo->function.audio.quirks & HDA_QUIRK_FIXEDRATE) { 3080 ch->caps.minspeed = ch->caps.maxspeed = 48000; 3081 ch->pcmrates[0] = 48000; 3082 ch->pcmrates[1] = 0; 3083 } 3084 if (sc->pos_dma.dma_vaddr != NULL) 3085 ch->dmapos = (uint32_t *)(sc->pos_dma.dma_vaddr + 3086 (sc->streamcnt * 8)); 3087 else 3088 ch->dmapos = NULL; 3089 ch->sid = ++sc->streamcnt; 3090 ch->dir = dir; 3091 ch->b = b; 3092 ch->c = c; 3093 ch->devinfo = devinfo; 3094 ch->blksz = sc->chan_size / sc->chan_blkcnt; 3095 ch->blkcnt = sc->chan_blkcnt; 3096 hdac_unlock(sc); 3097 3098 if (hdac_bdl_alloc(ch) != 0) { 3099 ch->blkcnt = 0; 3100 return (NULL); 3101 } 3102 3103 if (sndbuf_alloc(ch->b, sc->chan_dmat, 3104 (sc->flags & HDAC_F_DMA_NOCACHE) ? BUS_DMA_NOCACHE : 0, 3105 sc->chan_size) != 0) 3106 return (NULL); 3107 3108 return (ch); 3109} 3110 3111static int 3112hdac_channel_setformat(kobj_t obj, void *data, uint32_t format) 3113{ 3114 struct hdac_chan *ch = data; 3115 int i; 3116 3117 for (i = 0; ch->caps.fmtlist[i] != 0; i++) { 3118 if (format == ch->caps.fmtlist[i]) { 3119 ch->fmt = format; 3120 return (0); 3121 } 3122 } 3123 3124 return (EINVAL); 3125} 3126 3127static int 3128hdac_channel_setspeed(kobj_t obj, void *data, uint32_t speed) 3129{ 3130 struct hdac_chan *ch = data; 3131 uint32_t spd = 0, threshold; 3132 int i; 3133 3134 for (i = 0; ch->pcmrates[i] != 0; i++) { 3135 spd = ch->pcmrates[i]; 3136 threshold = spd + ((ch->pcmrates[i + 1] != 0) ? 3137 ((ch->pcmrates[i + 1] - spd) >> 1) : 0); 3138 if (speed < threshold) 3139 break; 3140 } 3141 3142 if (spd == 0) /* impossible */ 3143 ch->spd = 48000; 3144 else 3145 ch->spd = spd; 3146 3147 return (ch->spd); 3148} 3149 3150static void 3151hdac_stream_setup(struct hdac_chan *ch) 3152{ 3153 struct hdac_softc *sc = ch->devinfo->codec->sc; 3154 struct hdac_widget *w; 3155 int i, chn, totalchn; 3156 nid_t cad = ch->devinfo->codec->cad; 3157 uint16_t fmt; 3158 3159 fmt = 0; 3160 if (ch->fmt & AFMT_S16_LE) 3161 fmt |= ch->bit16 << 4; 3162 else if (ch->fmt & AFMT_S32_LE) 3163 fmt |= ch->bit32 << 4; 3164 else 3165 fmt |= 1 << 4; 3166 3167 for (i = 0; i < HDA_RATE_TAB_LEN; i++) { 3168 if (hda_rate_tab[i].valid && ch->spd == hda_rate_tab[i].rate) { 3169 fmt |= hda_rate_tab[i].base; 3170 fmt |= hda_rate_tab[i].mul; 3171 fmt |= hda_rate_tab[i].div; 3172 break; 3173 } 3174 } 3175 3176 if (ch->fmt & AFMT_STEREO) { 3177 fmt |= 1; 3178 totalchn = 2; 3179 } else 3180 totalchn = 1; 3181 3182 HDAC_WRITE_2(&sc->mem, ch->off + HDAC_SDFMT, fmt); 3183 3184 chn = 0; 3185 for (i = 0; ch->io[i] != -1; i++) { 3186 w = hdac_widget_get(ch->devinfo, ch->io[i]); 3187 if (w == NULL) 3188 continue; 3189 HDA_BOOTVERBOSE( 3190 device_printf(sc->dev, 3191 "HDA_DEBUG: PCMDIR_%s: Stream setup nid=%d " 3192 "fmt=0x%08x\n", 3193 (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", 3194 ch->io[i], fmt); 3195 ); 3196 hdac_command(sc, 3197 HDA_CMD_SET_CONV_FMT(cad, ch->io[i], fmt), cad); 3198 if (ch->dir == PCMDIR_REC) 3199 hdac_command(sc, 3200 HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], 3201 (chn < totalchn) ? ((ch->sid << 4) | chn) : 0), 3202 cad); 3203 else 3204 hdac_command(sc, 3205 HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], 3206 ch->sid << 4), cad); 3207 chn += 3208 HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap) ? 3209 2 : 1; 3210 } 3211} 3212 3213static int 3214hdac_channel_setfragments(kobj_t obj, void *data, 3215 uint32_t blksz, uint32_t blkcnt) 3216{ 3217 struct hdac_chan *ch = data; 3218 struct hdac_softc *sc = ch->devinfo->codec->sc; 3219 3220 blksz &= HDA_BLK_ALIGN; 3221 3222 if (blksz > (sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN)) 3223 blksz = sndbuf_getmaxsize(ch->b) / HDA_BDL_MIN; 3224 if (blksz < HDA_BLK_MIN) 3225 blksz = HDA_BLK_MIN; 3226 if (blkcnt > HDA_BDL_MAX) 3227 blkcnt = HDA_BDL_MAX; 3228 if (blkcnt < HDA_BDL_MIN) 3229 blkcnt = HDA_BDL_MIN; 3230 3231 while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->b)) { 3232 if ((blkcnt >> 1) >= HDA_BDL_MIN) 3233 blkcnt >>= 1; 3234 else if ((blksz >> 1) >= HDA_BLK_MIN) 3235 blksz >>= 1; 3236 else 3237 break; 3238 } 3239 3240 if ((sndbuf_getblksz(ch->b) != blksz || 3241 sndbuf_getblkcnt(ch->b) != blkcnt) && 3242 sndbuf_resize(ch->b, blkcnt, blksz) != 0) 3243 device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n", 3244 __func__, blksz, blkcnt); 3245 3246 ch->blksz = sndbuf_getblksz(ch->b); 3247 ch->blkcnt = sndbuf_getblkcnt(ch->b); 3248 3249 return (1); 3250} 3251 3252static int 3253hdac_channel_setblocksize(kobj_t obj, void *data, uint32_t blksz) 3254{ 3255 struct hdac_chan *ch = data; 3256 struct hdac_softc *sc = ch->devinfo->codec->sc; 3257 3258 hdac_channel_setfragments(obj, data, blksz, sc->chan_blkcnt); 3259 3260 return (ch->blksz); 3261} 3262 3263static void 3264hdac_channel_stop(struct hdac_softc *sc, struct hdac_chan *ch) 3265{ 3266 struct hdac_devinfo *devinfo = ch->devinfo; 3267 nid_t cad = devinfo->codec->cad; 3268 int i; 3269 3270 hdac_stream_stop(ch); 3271 3272 for (i = 0; ch->io[i] != -1; i++) { 3273 hdac_command(sc, 3274 HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], 3275 0), cad); 3276 } 3277} 3278 3279static void 3280hdac_channel_start(struct hdac_softc *sc, struct hdac_chan *ch) 3281{ 3282 ch->ptr = 0; 3283 ch->prevptr = 0; 3284 hdac_stream_stop(ch); 3285 hdac_stream_reset(ch); 3286 hdac_bdl_setup(ch); 3287 hdac_stream_setid(ch); 3288 hdac_stream_setup(ch); 3289 hdac_stream_start(ch); 3290} 3291 3292static int 3293hdac_channel_trigger(kobj_t obj, void *data, int go) 3294{ 3295 struct hdac_chan *ch = data; 3296 struct hdac_softc *sc = ch->devinfo->codec->sc; 3297 3298 if (!PCMTRIG_COMMON(go)) 3299 return (0); 3300 3301 hdac_lock(sc); 3302 switch (go) { 3303 case PCMTRIG_START: 3304 hdac_channel_start(sc, ch); 3305 break; 3306 case PCMTRIG_STOP: 3307 case PCMTRIG_ABORT: 3308 hdac_channel_stop(sc, ch); 3309 break; 3310 default: 3311 break; 3312 } 3313 hdac_unlock(sc); 3314 3315 return (0); 3316} 3317 3318static int 3319hdac_channel_getptr(kobj_t obj, void *data) 3320{ 3321 struct hdac_chan *ch = data; 3322 struct hdac_softc *sc = ch->devinfo->codec->sc; 3323 uint32_t ptr; 3324 3325 hdac_lock(sc); 3326 if (sc->polling != 0) 3327 ptr = ch->ptr; 3328 else if (ch->dmapos != NULL) 3329 ptr = *(ch->dmapos); 3330 else 3331 ptr = HDAC_READ_4(&sc->mem, ch->off + HDAC_SDLPIB); 3332 hdac_unlock(sc); 3333 3334 /* 3335 * Round to available space and force 128 bytes aligment. 3336 */ 3337 ptr %= ch->blksz * ch->blkcnt; 3338 ptr &= HDA_BLK_ALIGN; 3339 3340 return (ptr); 3341} 3342 3343static struct pcmchan_caps * 3344hdac_channel_getcaps(kobj_t obj, void *data) 3345{ 3346 return (&((struct hdac_chan *)data)->caps); 3347} 3348 3349static kobj_method_t hdac_channel_methods[] = { 3350 KOBJMETHOD(channel_init, hdac_channel_init), 3351 KOBJMETHOD(channel_setformat, hdac_channel_setformat), 3352 KOBJMETHOD(channel_setspeed, hdac_channel_setspeed), 3353 KOBJMETHOD(channel_setblocksize, hdac_channel_setblocksize), 3354 KOBJMETHOD(channel_setfragments, hdac_channel_setfragments), 3355 KOBJMETHOD(channel_trigger, hdac_channel_trigger), 3356 KOBJMETHOD(channel_getptr, hdac_channel_getptr), 3357 KOBJMETHOD(channel_getcaps, hdac_channel_getcaps), 3358 { 0, 0 } 3359}; 3360CHANNEL_DECLARE(hdac_channel); 3361 3362static void 3363hdac_jack_poll_callback(void *arg) 3364{ 3365 struct hdac_devinfo *devinfo = arg; 3366 struct hdac_softc *sc; 3367 3368 if (devinfo == NULL || devinfo->codec == NULL || 3369 devinfo->codec->sc == NULL) 3370 return; 3371 sc = devinfo->codec->sc; 3372 hdac_lock(sc); 3373 if (sc->poll_ival == 0) { 3374 hdac_unlock(sc); 3375 return; 3376 } 3377 hdac_hp_switch_handler(devinfo); 3378 callout_reset(&sc->poll_jack, sc->poll_ival, 3379 hdac_jack_poll_callback, devinfo); 3380 hdac_unlock(sc); 3381} 3382 3383static int 3384hdac_audio_ctl_ossmixer_init(struct snd_mixer *m) 3385{ 3386 struct hdac_devinfo *devinfo = mix_getdevinfo(m); 3387 struct hdac_softc *sc = devinfo->codec->sc; 3388 struct hdac_widget *w, *cw; 3389 struct hdac_audio_ctl *ctl; 3390 uint32_t mask, recmask, id; 3391 int i, j, softpcmvol; 3392 nid_t cad; 3393 3394 hdac_lock(sc); 3395 3396 mask = 0; 3397 recmask = 0; 3398 3399 id = hdac_codec_id(devinfo); 3400 cad = devinfo->codec->cad; 3401 for (i = 0; i < HDAC_HP_SWITCH_LEN; i++) { 3402 if (!(HDA_DEV_MATCH(hdac_hp_switch[i].model, 3403 sc->pci_subvendor) && hdac_hp_switch[i].id == id)) 3404 continue; 3405 w = hdac_widget_get(devinfo, hdac_hp_switch[i].hpnid); 3406 if (w == NULL || w->enable == 0 || w->type != 3407 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 3408 continue; 3409 if (hdac_hp_switch[i].polling != 0) 3410 callout_reset(&sc->poll_jack, 1, 3411 hdac_jack_poll_callback, devinfo); 3412 else if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(w->param.widget_cap)) 3413 hdac_command(sc, 3414 HDA_CMD_SET_UNSOLICITED_RESPONSE(cad, w->nid, 3415 HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE | 3416 HDAC_UNSOLTAG_EVENT_HP), cad); 3417 else 3418 continue; 3419 hdac_hp_switch_handler(devinfo); 3420 HDA_BOOTVERBOSE( 3421 device_printf(sc->dev, 3422 "HDA_DEBUG: Enabling headphone/speaker " 3423 "audio routing switching:\n"); 3424 device_printf(sc->dev, 3425 "HDA_DEBUG: \tindex=%d nid=%d " 3426 "pci_subvendor=0x%08x " 3427 "codec=0x%08x [%s]\n", 3428 i, w->nid, sc->pci_subvendor, id, 3429 (hdac_hp_switch[i].polling != 0) ? "POLL" : 3430 "UNSOL"); 3431 ); 3432 break; 3433 } 3434 for (i = 0; i < HDAC_EAPD_SWITCH_LEN; i++) { 3435 if (!(HDA_DEV_MATCH(hdac_eapd_switch[i].model, 3436 sc->pci_subvendor) && 3437 hdac_eapd_switch[i].id == id)) 3438 continue; 3439 w = hdac_widget_get(devinfo, hdac_eapd_switch[i].eapdnid); 3440 if (w == NULL || w->enable == 0) 3441 break; 3442 if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX || 3443 w->param.eapdbtl == HDAC_INVALID) 3444 break; 3445 mask |= SOUND_MASK_OGAIN; 3446 break; 3447 } 3448 3449 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 3450 w = hdac_widget_get(devinfo, i); 3451 if (w == NULL || w->enable == 0) 3452 continue; 3453 mask |= w->ctlflags; 3454 if (!(w->pflags & HDA_ADC_RECSEL)) 3455 continue; 3456 for (j = 0; j < w->nconns; j++) { 3457 cw = hdac_widget_get(devinfo, w->conns[j]); 3458 if (cw == NULL || cw->enable == 0) 3459 continue; 3460 recmask |= cw->ctlflags; 3461 } 3462 } 3463 3464 if (!(mask & SOUND_MASK_PCM)) { 3465 softpcmvol = 1; 3466 mask |= SOUND_MASK_PCM; 3467 } else 3468 softpcmvol = (devinfo->function.audio.quirks & 3469 HDA_QUIRK_SOFTPCMVOL) ? 1 : 0; 3470 3471 i = 0; 3472 ctl = NULL; 3473 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 3474 if (ctl->widget == NULL || ctl->enable == 0) 3475 continue; 3476 if (!(ctl->ossmask & SOUND_MASK_PCM)) 3477 continue; 3478 if (ctl->step > 0) 3479 break; 3480 } 3481 3482 if (softpcmvol == 1 || ctl == NULL) { 3483 pcm_setflags(sc->dev, pcm_getflags(sc->dev) | SD_F_SOFTPCMVOL); 3484 HDA_BOOTVERBOSE( 3485 device_printf(sc->dev, 3486 "HDA_DEBUG: %s Soft PCM volume\n", 3487 (softpcmvol == 1) ? 3488 "Forcing" : "Enabling"); 3489 ); 3490 i = 0; 3491 /* 3492 * XXX Temporary quirk for STAC9220, until the parser 3493 * become smarter. 3494 */ 3495 if (id == HDA_CODEC_STAC9220) { 3496 mask |= SOUND_MASK_VOLUME; 3497 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != 3498 NULL) { 3499 if (ctl->widget == NULL || ctl->enable == 0) 3500 continue; 3501 if (ctl->widget->nid == 11 && ctl->index == 0) { 3502 ctl->ossmask = SOUND_MASK_VOLUME; 3503 ctl->ossval = 100 | (100 << 8); 3504 } else 3505 ctl->ossmask &= ~SOUND_MASK_VOLUME; 3506 } 3507 } else if (id == HDA_CODEC_STAC9221) { 3508 mask |= SOUND_MASK_VOLUME; 3509 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != 3510 NULL) { 3511 if (ctl->widget == NULL) 3512 continue; 3513 if (ctl->widget->type == 3514 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT && 3515 ctl->index == 0 && (ctl->widget->nid == 2 || 3516 ctl->widget->enable != 0)) { 3517 ctl->enable = 1; 3518 ctl->ossmask = SOUND_MASK_VOLUME; 3519 ctl->ossval = 100 | (100 << 8); 3520 } else if (ctl->enable == 0) 3521 continue; 3522 else 3523 ctl->ossmask &= ~SOUND_MASK_VOLUME; 3524 } 3525 } else { 3526 mix_setparentchild(m, SOUND_MIXER_VOLUME, 3527 SOUND_MASK_PCM); 3528 if (!(mask & SOUND_MASK_VOLUME)) 3529 mix_setrealdev(m, SOUND_MIXER_VOLUME, 3530 SOUND_MIXER_NONE); 3531 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != 3532 NULL) { 3533 if (ctl->widget == NULL || ctl->enable == 0) 3534 continue; 3535 if (!HDA_FLAG_MATCH(ctl->ossmask, 3536 SOUND_MASK_VOLUME | SOUND_MASK_PCM)) 3537 continue; 3538 if (!(ctl->mute == 1 && ctl->step == 0)) 3539 ctl->enable = 0; 3540 } 3541 } 3542 } 3543 3544 recmask &= ~(SOUND_MASK_PCM | SOUND_MASK_RECLEV | SOUND_MASK_SPEAKER | 3545 SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_IGAIN | 3546 SOUND_MASK_OGAIN); 3547 recmask &= (1 << SOUND_MIXER_NRDEVICES) - 1; 3548 mask &= (1 << SOUND_MIXER_NRDEVICES) - 1; 3549 3550 mix_setrecdevs(m, recmask); 3551 mix_setdevs(m, mask); 3552 3553 hdac_unlock(sc); 3554 3555 return (0); 3556} 3557 3558static int 3559hdac_audio_ctl_ossmixer_set(struct snd_mixer *m, unsigned dev, 3560 unsigned left, unsigned right) 3561{ 3562 struct hdac_devinfo *devinfo = mix_getdevinfo(m); 3563 struct hdac_softc *sc = devinfo->codec->sc; 3564 struct hdac_widget *w; 3565 struct hdac_audio_ctl *ctl; 3566 uint32_t id, mute; 3567 int lvol, rvol, mlvol, mrvol; 3568 int i = 0; 3569 3570 hdac_lock(sc); 3571 if (dev == SOUND_MIXER_OGAIN) { 3572 uint32_t orig; 3573 /*if (left != right || !(left == 0 || left == 1)) { 3574 hdac_unlock(sc); 3575 return (-1); 3576 }*/ 3577 id = hdac_codec_id(devinfo); 3578 for (i = 0; i < HDAC_EAPD_SWITCH_LEN; i++) { 3579 if (HDA_DEV_MATCH(hdac_eapd_switch[i].model, 3580 sc->pci_subvendor) && 3581 hdac_eapd_switch[i].id == id) 3582 break; 3583 } 3584 if (i >= HDAC_EAPD_SWITCH_LEN) { 3585 hdac_unlock(sc); 3586 return (-1); 3587 } 3588 w = hdac_widget_get(devinfo, hdac_eapd_switch[i].eapdnid); 3589 if (w == NULL || 3590 w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX || 3591 w->param.eapdbtl == HDAC_INVALID) { 3592 hdac_unlock(sc); 3593 return (-1); 3594 } 3595 orig = w->param.eapdbtl; 3596 if (left == 0) 3597 w->param.eapdbtl &= ~HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD; 3598 else 3599 w->param.eapdbtl |= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD; 3600 if (orig != w->param.eapdbtl) { 3601 uint32_t val; 3602 3603 if (hdac_eapd_switch[i].hp_switch != 0) 3604 hdac_hp_switch_handler(devinfo); 3605 val = w->param.eapdbtl; 3606 if (devinfo->function.audio.quirks & HDA_QUIRK_EAPDINV) 3607 val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD; 3608 hdac_command(sc, 3609 HDA_CMD_SET_EAPD_BTL_ENABLE(devinfo->codec->cad, 3610 w->nid, val), devinfo->codec->cad); 3611 } 3612 hdac_unlock(sc); 3613 return (left | (left << 8)); 3614 } 3615 if (dev == SOUND_MIXER_VOLUME) 3616 devinfo->function.audio.mvol = left | (right << 8); 3617 3618 mlvol = devinfo->function.audio.mvol & 0x7f; 3619 mrvol = (devinfo->function.audio.mvol >> 8) & 0x7f; 3620 lvol = 0; 3621 rvol = 0; 3622 3623 i = 0; 3624 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 3625 if (ctl->widget == NULL || ctl->enable == 0 || 3626 !(ctl->ossmask & (1 << dev))) 3627 continue; 3628 switch (dev) { 3629 case SOUND_MIXER_VOLUME: 3630 lvol = ((ctl->ossval & 0x7f) * left) / 100; 3631 lvol = (lvol * ctl->step) / 100; 3632 rvol = (((ctl->ossval >> 8) & 0x7f) * right) / 100; 3633 rvol = (rvol * ctl->step) / 100; 3634 break; 3635 default: 3636 if (ctl->ossmask & SOUND_MASK_VOLUME) { 3637 lvol = (left * mlvol) / 100; 3638 lvol = (lvol * ctl->step) / 100; 3639 rvol = (right * mrvol) / 100; 3640 rvol = (rvol * ctl->step) / 100; 3641 } else { 3642 lvol = (left * ctl->step) / 100; 3643 rvol = (right * ctl->step) / 100; 3644 } 3645 ctl->ossval = left | (right << 8); 3646 break; 3647 } 3648 mute = 0; 3649 if (ctl->step < 1) { 3650 mute |= (left == 0) ? HDA_AMP_MUTE_LEFT : 3651 (ctl->muted & HDA_AMP_MUTE_LEFT); 3652 mute |= (right == 0) ? HDA_AMP_MUTE_RIGHT : 3653 (ctl->muted & HDA_AMP_MUTE_RIGHT); 3654 } else { 3655 mute |= (lvol == 0) ? HDA_AMP_MUTE_LEFT : 3656 (ctl->muted & HDA_AMP_MUTE_LEFT); 3657 mute |= (rvol == 0) ? HDA_AMP_MUTE_RIGHT : 3658 (ctl->muted & HDA_AMP_MUTE_RIGHT); 3659 } 3660 hdac_audio_ctl_amp_set(ctl, mute, lvol, rvol); 3661 } 3662 hdac_unlock(sc); 3663 3664 return (left | (right << 8)); 3665} 3666 3667static int 3668hdac_audio_ctl_ossmixer_setrecsrc(struct snd_mixer *m, uint32_t src) 3669{ 3670 struct hdac_devinfo *devinfo = mix_getdevinfo(m); 3671 struct hdac_widget *w, *cw; 3672 struct hdac_softc *sc = devinfo->codec->sc; 3673 uint32_t ret = src, target; 3674 int i, j; 3675 3676 target = 0; 3677 for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { 3678 if (src & (1 << i)) { 3679 target = 1 << i; 3680 break; 3681 } 3682 } 3683 3684 hdac_lock(sc); 3685 3686 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 3687 w = hdac_widget_get(devinfo, i); 3688 if (w == NULL || w->enable == 0) 3689 continue; 3690 if (!(w->pflags & HDA_ADC_RECSEL)) 3691 continue; 3692 for (j = 0; j < w->nconns; j++) { 3693 cw = hdac_widget_get(devinfo, w->conns[j]); 3694 if (cw == NULL || cw->enable == 0) 3695 continue; 3696 if ((target == SOUND_MASK_VOLUME && 3697 cw->type != 3698 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) || 3699 (target != SOUND_MASK_VOLUME && 3700 cw->type == 3701 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER)) 3702 continue; 3703 if (cw->ctlflags & target) { 3704 if (!(w->pflags & HDA_ADC_LOCKED)) 3705 hdac_widget_connection_select(w, j); 3706 ret = target; 3707 j += w->nconns; 3708 } 3709 } 3710 } 3711 3712 hdac_unlock(sc); 3713 3714 return (ret); 3715} 3716 3717static kobj_method_t hdac_audio_ctl_ossmixer_methods[] = { 3718 KOBJMETHOD(mixer_init, hdac_audio_ctl_ossmixer_init), 3719 KOBJMETHOD(mixer_set, hdac_audio_ctl_ossmixer_set), 3720 KOBJMETHOD(mixer_setrecsrc, hdac_audio_ctl_ossmixer_setrecsrc), 3721 { 0, 0 } 3722}; 3723MIXER_DECLARE(hdac_audio_ctl_ossmixer); 3724 3725static void 3726hdac_unsolq_task(void *context, int pending) 3727{ 3728 struct hdac_softc *sc; 3729 3730 sc = (struct hdac_softc *)context; 3731 3732 hdac_lock(sc); 3733 hdac_unsolq_flush(sc); 3734 hdac_unlock(sc); 3735} 3736 3737/**************************************************************************** 3738 * int hdac_attach(device_t) 3739 * 3740 * Attach the device into the kernel. Interrupts usually won't be enabled 3741 * when this function is called. Setup everything that doesn't require 3742 * interrupts and defer probing of codecs until interrupts are enabled. 3743 ****************************************************************************/ 3744static int 3745hdac_attach(device_t dev) 3746{ 3747 struct hdac_softc *sc; 3748 int result; 3749 int i; 3750 uint16_t vendor; 3751 uint8_t v; 3752 3753 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 3754 sc->lock = snd_mtxcreate(device_get_nameunit(dev), HDAC_MTX_NAME); 3755 sc->dev = dev; 3756 sc->pci_subvendor = (uint32_t)pci_get_subdevice(sc->dev) << 16; 3757 sc->pci_subvendor |= (uint32_t)pci_get_subvendor(sc->dev) & 0x0000ffff; 3758 vendor = pci_get_vendor(dev); 3759 3760 if (sc->pci_subvendor == HP_NX6325_SUBVENDORX) { 3761 /* Screw nx6325 - subdevice/subvendor swapped */ 3762 sc->pci_subvendor = HP_NX6325_SUBVENDOR; 3763 } 3764 3765 callout_init(&sc->poll_hda, CALLOUT_MPSAFE); 3766 callout_init(&sc->poll_hdac, CALLOUT_MPSAFE); 3767 callout_init(&sc->poll_jack, CALLOUT_MPSAFE); 3768 3769 TASK_INIT(&sc->unsolq_task, 0, hdac_unsolq_task, sc); 3770 3771 sc->poll_ticks = 1; 3772 sc->poll_ival = HDAC_POLL_INTERVAL; 3773 if (resource_int_value(device_get_name(dev), 3774 device_get_unit(dev), "polling", &i) == 0 && i != 0) 3775 sc->polling = 1; 3776 else 3777 sc->polling = 0; 3778 3779 sc->chan_size = pcm_getbuffersize(dev, 3780 HDA_BUFSZ_MIN, HDA_BUFSZ_DEFAULT, HDA_BUFSZ_MAX); 3781 3782 if (resource_int_value(device_get_name(dev), 3783 device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { 3784 i &= HDA_BLK_ALIGN; 3785 if (i < HDA_BLK_MIN) 3786 i = HDA_BLK_MIN; 3787 sc->chan_blkcnt = sc->chan_size / i; 3788 i = 0; 3789 while (sc->chan_blkcnt >> i) 3790 i++; 3791 sc->chan_blkcnt = 1 << (i - 1); 3792 if (sc->chan_blkcnt < HDA_BDL_MIN) 3793 sc->chan_blkcnt = HDA_BDL_MIN; 3794 else if (sc->chan_blkcnt > HDA_BDL_MAX) 3795 sc->chan_blkcnt = HDA_BDL_MAX; 3796 } else 3797 sc->chan_blkcnt = HDA_BDL_DEFAULT; 3798 3799 result = bus_dma_tag_create(NULL, /* parent */ 3800 HDAC_DMA_ALIGNMENT, /* alignment */ 3801 0, /* boundary */ 3802 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 3803 BUS_SPACE_MAXADDR, /* highaddr */ 3804 NULL, /* filtfunc */ 3805 NULL, /* fistfuncarg */ 3806 sc->chan_size, /* maxsize */ 3807 1, /* nsegments */ 3808 sc->chan_size, /* maxsegsz */ 3809 0, /* flags */ 3810 NULL, /* lockfunc */ 3811 NULL, /* lockfuncarg */ 3812 &sc->chan_dmat); /* dmat */ 3813 if (result != 0) { 3814 device_printf(dev, "%s: bus_dma_tag_create failed (%x)\n", 3815 __func__, result); 3816 snd_mtxfree(sc->lock); 3817 free(sc, M_DEVBUF); 3818 return (ENXIO); 3819 } 3820 3821 3822 sc->hdabus = NULL; 3823 for (i = 0; i < HDAC_CODEC_MAX; i++) 3824 sc->codecs[i] = NULL; 3825 3826 pci_enable_busmaster(dev); 3827 3828 if (vendor == INTEL_VENDORID) { 3829 /* TCSEL -> TC0 */ 3830 v = pci_read_config(dev, 0x44, 1); 3831 pci_write_config(dev, 0x44, v & 0xf8, 1); 3832 HDA_BOOTVERBOSE( 3833 device_printf(dev, "TCSEL: 0x%02d -> 0x%02d\n", v, 3834 pci_read_config(dev, 0x44, 1)); 3835 ); 3836 } 3837 3838#ifdef HDAC_MSI_ENABLED 3839 if (resource_int_value(device_get_name(dev), 3840 device_get_unit(dev), "msi", &i) == 0 && i != 0 && 3841 pci_msi_count(dev) == 1) 3842 sc->flags |= HDAC_F_MSI; 3843 else 3844#endif 3845 sc->flags &= ~HDAC_F_MSI; 3846 3847#if defined(__i386__) || defined(__amd64__) 3848 sc->flags |= HDAC_F_DMA_NOCACHE; 3849 3850 if (resource_int_value(device_get_name(dev), 3851 device_get_unit(dev), "snoop", &i) == 0 && i != 0) { 3852#else 3853 sc->flags &= ~HDAC_F_DMA_NOCACHE; 3854#endif 3855 /* 3856 * Try to enable PCIe snoop to avoid messing around with 3857 * uncacheable DMA attribute. Since PCIe snoop register 3858 * config is pretty much vendor specific, there are no 3859 * general solutions on how to enable it, forcing us (even 3860 * Microsoft) to enable uncacheable or write combined DMA 3861 * by default. 3862 * 3863 * http://msdn2.microsoft.com/en-us/library/ms790324.aspx 3864 */ 3865 for (i = 0; i < HDAC_PCIESNOOP_LEN; i++) { 3866 if (hdac_pcie_snoop[i].vendor != vendor) 3867 continue; 3868 sc->flags &= ~HDAC_F_DMA_NOCACHE; 3869 if (hdac_pcie_snoop[i].reg == 0x00) 3870 break; 3871 v = pci_read_config(dev, hdac_pcie_snoop[i].reg, 1); 3872 if ((v & hdac_pcie_snoop[i].enable) == 3873 hdac_pcie_snoop[i].enable) 3874 break; 3875 v &= hdac_pcie_snoop[i].mask; 3876 v |= hdac_pcie_snoop[i].enable; 3877 pci_write_config(dev, hdac_pcie_snoop[i].reg, v, 1); 3878 v = pci_read_config(dev, hdac_pcie_snoop[i].reg, 1); 3879 if ((v & hdac_pcie_snoop[i].enable) != 3880 hdac_pcie_snoop[i].enable) { 3881 HDA_BOOTVERBOSE( 3882 device_printf(dev, 3883 "WARNING: Failed to enable PCIe " 3884 "snoop!\n"); 3885 ); 3886#if defined(__i386__) || defined(__amd64__) 3887 sc->flags |= HDAC_F_DMA_NOCACHE; 3888#endif 3889 } 3890 break; 3891 } 3892#if defined(__i386__) || defined(__amd64__) 3893 } 3894#endif 3895 3896 HDA_BOOTVERBOSE( 3897 device_printf(dev, "DMA Coherency: %s / vendor=0x%04x\n", 3898 (sc->flags & HDAC_F_DMA_NOCACHE) ? 3899 "Uncacheable" : "PCIe snoop", vendor); 3900 ); 3901 3902 /* Allocate resources */ 3903 result = hdac_mem_alloc(sc); 3904 if (result != 0) 3905 goto hdac_attach_fail; 3906 result = hdac_irq_alloc(sc); 3907 if (result != 0) 3908 goto hdac_attach_fail; 3909 3910 /* Get Capabilities */ 3911 result = hdac_get_capabilities(sc); 3912 if (result != 0) 3913 goto hdac_attach_fail; 3914 3915 /* Allocate CORB and RIRB dma memory */ 3916 result = hdac_dma_alloc(sc, &sc->corb_dma, 3917 sc->corb_size * sizeof(uint32_t)); 3918 if (result != 0) 3919 goto hdac_attach_fail; 3920 result = hdac_dma_alloc(sc, &sc->rirb_dma, 3921 sc->rirb_size * sizeof(struct hdac_rirb)); 3922 if (result != 0) 3923 goto hdac_attach_fail; 3924 3925 /* Quiesce everything */ 3926 hdac_reset(sc); 3927 3928 /* Initialize the CORB and RIRB */ 3929 hdac_corb_init(sc); 3930 hdac_rirb_init(sc); 3931 3932 /* Defer remaining of initialization until interrupts are enabled */ 3933 sc->intrhook.ich_func = hdac_attach2; 3934 sc->intrhook.ich_arg = (void *)sc; 3935 if (cold == 0 || config_intrhook_establish(&sc->intrhook) != 0) { 3936 sc->intrhook.ich_func = NULL; 3937 hdac_attach2((void *)sc); 3938 } 3939 3940 return (0); 3941 3942hdac_attach_fail: 3943 hdac_irq_free(sc); 3944 hdac_dma_free(sc, &sc->rirb_dma); 3945 hdac_dma_free(sc, &sc->corb_dma); 3946 hdac_mem_free(sc); 3947 snd_mtxfree(sc->lock); 3948 free(sc, M_DEVBUF); 3949 3950 return (ENXIO); 3951} 3952 3953static void 3954hdac_audio_parse(struct hdac_devinfo *devinfo) 3955{ 3956 struct hdac_softc *sc = devinfo->codec->sc; 3957 struct hdac_widget *w; 3958 uint32_t res; 3959 int i; 3960 nid_t cad, nid; 3961 3962 cad = devinfo->codec->cad; 3963 nid = devinfo->nid; 3964 3965 hdac_command(sc, 3966 HDA_CMD_SET_POWER_STATE(cad, nid, HDA_CMD_POWER_STATE_D0), cad); 3967 3968 DELAY(100); 3969 3970 res = hdac_command(sc, 3971 HDA_CMD_GET_PARAMETER(cad , nid, HDA_PARAM_SUB_NODE_COUNT), cad); 3972 3973 devinfo->nodecnt = HDA_PARAM_SUB_NODE_COUNT_TOTAL(res); 3974 devinfo->startnode = HDA_PARAM_SUB_NODE_COUNT_START(res); 3975 devinfo->endnode = devinfo->startnode + devinfo->nodecnt; 3976 3977 res = hdac_command(sc, 3978 HDA_CMD_GET_PARAMETER(cad , nid, HDA_PARAM_GPIO_COUNT), cad); 3979 devinfo->function.audio.gpio = res; 3980 3981 HDA_BOOTVERBOSE( 3982 device_printf(sc->dev, " Vendor: 0x%08x\n", 3983 devinfo->vendor_id); 3984 device_printf(sc->dev, " Device: 0x%08x\n", 3985 devinfo->device_id); 3986 device_printf(sc->dev, " Revision: 0x%08x\n", 3987 devinfo->revision_id); 3988 device_printf(sc->dev, " Stepping: 0x%08x\n", 3989 devinfo->stepping_id); 3990 device_printf(sc->dev, "PCI Subvendor: 0x%08x\n", 3991 sc->pci_subvendor); 3992 device_printf(sc->dev, " Nodes: start=%d " 3993 "endnode=%d total=%d\n", 3994 devinfo->startnode, devinfo->endnode, devinfo->nodecnt); 3995 device_printf(sc->dev, " CORB size: %d\n", sc->corb_size); 3996 device_printf(sc->dev, " RIRB size: %d\n", sc->rirb_size); 3997 device_printf(sc->dev, " Streams: ISS=%d OSS=%d BSS=%d\n", 3998 sc->num_iss, sc->num_oss, sc->num_bss); 3999 device_printf(sc->dev, " GPIO: 0x%08x\n", 4000 devinfo->function.audio.gpio); 4001 device_printf(sc->dev, " NumGPIO=%d NumGPO=%d " 4002 "NumGPI=%d GPIWake=%d GPIUnsol=%d\n", 4003 HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->function.audio.gpio), 4004 HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->function.audio.gpio), 4005 HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->function.audio.gpio), 4006 HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->function.audio.gpio), 4007 HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->function.audio.gpio)); 4008 ); 4009 4010 res = hdac_command(sc, 4011 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_SUPP_STREAM_FORMATS), 4012 cad); 4013 devinfo->function.audio.supp_stream_formats = res; 4014 4015 res = hdac_command(sc, 4016 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_SUPP_PCM_SIZE_RATE), 4017 cad); 4018 devinfo->function.audio.supp_pcm_size_rate = res; 4019 4020 res = hdac_command(sc, 4021 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_OUTPUT_AMP_CAP), 4022 cad); 4023 devinfo->function.audio.outamp_cap = res; 4024 4025 res = hdac_command(sc, 4026 HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_INPUT_AMP_CAP), 4027 cad); 4028 devinfo->function.audio.inamp_cap = res; 4029 4030 if (devinfo->nodecnt > 0) 4031 devinfo->widget = (struct hdac_widget *)malloc( 4032 sizeof(*(devinfo->widget)) * devinfo->nodecnt, M_HDAC, 4033 M_NOWAIT | M_ZERO); 4034 else 4035 devinfo->widget = NULL; 4036 4037 if (devinfo->widget == NULL) { 4038 device_printf(sc->dev, "unable to allocate widgets!\n"); 4039 devinfo->endnode = devinfo->startnode; 4040 devinfo->nodecnt = 0; 4041 return; 4042 } 4043 4044 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4045 w = hdac_widget_get(devinfo, i); 4046 if (w == NULL) 4047 device_printf(sc->dev, "Ghost widget! nid=%d!\n", i); 4048 else { 4049 w->devinfo = devinfo; 4050 w->nid = i; 4051 w->enable = 1; 4052 w->selconn = -1; 4053 w->pflags = 0; 4054 w->ctlflags = 0; 4055 w->param.eapdbtl = HDAC_INVALID; 4056 hdac_widget_parse(w); 4057 } 4058 } 4059} 4060 4061static void 4062hdac_audio_ctl_parse(struct hdac_devinfo *devinfo) 4063{ 4064 struct hdac_softc *sc = devinfo->codec->sc; 4065 struct hdac_audio_ctl *ctls; 4066 struct hdac_widget *w, *cw; 4067 int i, j, cnt, max, ocap, icap; 4068 int mute, offset, step, size; 4069 4070 /* XXX This is redundant */ 4071 max = 0; 4072 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4073 w = hdac_widget_get(devinfo, i); 4074 if (w == NULL || w->enable == 0) 4075 continue; 4076 if (w->param.outamp_cap != 0) 4077 max++; 4078 if (w->param.inamp_cap != 0) { 4079 switch (w->type) { 4080 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR: 4081 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER: 4082 for (j = 0; j < w->nconns; j++) { 4083 cw = hdac_widget_get(devinfo, 4084 w->conns[j]); 4085 if (cw == NULL || cw->enable == 0) 4086 continue; 4087 max++; 4088 } 4089 break; 4090 default: 4091 max++; 4092 break; 4093 } 4094 } 4095 } 4096 4097 devinfo->function.audio.ctlcnt = max; 4098 4099 if (max < 1) 4100 return; 4101 4102 ctls = (struct hdac_audio_ctl *)malloc( 4103 sizeof(*ctls) * max, M_HDAC, M_ZERO | M_NOWAIT); 4104 4105 if (ctls == NULL) { 4106 /* Blekh! */ 4107 device_printf(sc->dev, "unable to allocate ctls!\n"); 4108 devinfo->function.audio.ctlcnt = 0; 4109 return; 4110 } 4111 4112 cnt = 0; 4113 for (i = devinfo->startnode; cnt < max && i < devinfo->endnode; i++) { 4114 if (cnt >= max) { 4115 device_printf(sc->dev, "%s: Ctl overflow!\n", 4116 __func__); 4117 break; 4118 } 4119 w = hdac_widget_get(devinfo, i); 4120 if (w == NULL || w->enable == 0) 4121 continue; 4122 ocap = w->param.outamp_cap; 4123 icap = w->param.inamp_cap; 4124 if (ocap != 0) { 4125 mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(ocap); 4126 step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(ocap); 4127 size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(ocap); 4128 offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(ocap); 4129 /*if (offset > step) { 4130 HDA_BOOTVERBOSE( 4131 device_printf(sc->dev, 4132 "HDA_DEBUG: BUGGY outamp: nid=%d " 4133 "[offset=%d > step=%d]\n", 4134 w->nid, offset, step); 4135 ); 4136 offset = step; 4137 }*/ 4138 ctls[cnt].enable = 1; 4139 ctls[cnt].widget = w; 4140 ctls[cnt].mute = mute; 4141 ctls[cnt].step = step; 4142 ctls[cnt].size = size; 4143 ctls[cnt].offset = offset; 4144 ctls[cnt].left = offset; 4145 ctls[cnt].right = offset; 4146 ctls[cnt++].dir = HDA_CTL_OUT; 4147 } 4148 4149 if (icap != 0) { 4150 mute = HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(icap); 4151 step = HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(icap); 4152 size = HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(icap); 4153 offset = HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(icap); 4154 /*if (offset > step) { 4155 HDA_BOOTVERBOSE( 4156 device_printf(sc->dev, 4157 "HDA_DEBUG: BUGGY inamp: nid=%d " 4158 "[offset=%d > step=%d]\n", 4159 w->nid, offset, step); 4160 ); 4161 offset = step; 4162 }*/ 4163 switch (w->type) { 4164 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR: 4165 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER: 4166 for (j = 0; j < w->nconns; j++) { 4167 if (cnt >= max) { 4168 device_printf(sc->dev, 4169 "%s: Ctl overflow!\n", 4170 __func__); 4171 break; 4172 } 4173 cw = hdac_widget_get(devinfo, 4174 w->conns[j]); 4175 if (cw == NULL || cw->enable == 0) 4176 continue; 4177 ctls[cnt].enable = 1; 4178 ctls[cnt].widget = w; 4179 ctls[cnt].childwidget = cw; 4180 ctls[cnt].index = j; 4181 ctls[cnt].mute = mute; 4182 ctls[cnt].step = step; 4183 ctls[cnt].size = size; 4184 ctls[cnt].offset = offset; 4185 ctls[cnt].left = offset; 4186 ctls[cnt].right = offset; 4187 ctls[cnt++].dir = HDA_CTL_IN; 4188 } 4189 break; 4190 default: 4191 if (cnt >= max) { 4192 device_printf(sc->dev, 4193 "%s: Ctl overflow!\n", 4194 __func__); 4195 break; 4196 } 4197 ctls[cnt].enable = 1; 4198 ctls[cnt].widget = w; 4199 ctls[cnt].mute = mute; 4200 ctls[cnt].step = step; 4201 ctls[cnt].size = size; 4202 ctls[cnt].offset = offset; 4203 ctls[cnt].left = offset; 4204 ctls[cnt].right = offset; 4205 ctls[cnt++].dir = HDA_CTL_IN; 4206 break; 4207 } 4208 } 4209 } 4210 4211 devinfo->function.audio.ctl = ctls; 4212} 4213 4214static const struct { 4215 uint32_t model; 4216 uint32_t id; 4217 uint32_t set, unset; 4218} hdac_quirks[] = { 4219 /* 4220 * XXX Force stereo quirk. Monoural recording / playback 4221 * on few codecs (especially ALC880) seems broken or 4222 * perhaps unsupported. 4223 */ 4224 { HDA_MATCH_ALL, HDA_MATCH_ALL, 4225 HDA_QUIRK_FORCESTEREO | HDA_QUIRK_IVREF, 0 }, 4226 { ACER_ALL_SUBVENDOR, HDA_MATCH_ALL, 4227 HDA_QUIRK_GPIO0, 0 }, 4228 { ASUS_G2K_SUBVENDOR, HDA_CODEC_ALC660, 4229 HDA_QUIRK_GPIO0, 0 }, 4230 { ASUS_M5200_SUBVENDOR, HDA_CODEC_ALC880, 4231 HDA_QUIRK_GPIO0, 0 }, 4232 { ASUS_A7M_SUBVENDOR, HDA_CODEC_ALC880, 4233 HDA_QUIRK_GPIO0, 0 }, 4234 { ASUS_A7T_SUBVENDOR, HDA_CODEC_ALC882, 4235 HDA_QUIRK_GPIO0, 0 }, 4236 { ASUS_W2J_SUBVENDOR, HDA_CODEC_ALC882, 4237 HDA_QUIRK_GPIO0, 0 }, 4238 { ASUS_U5F_SUBVENDOR, HDA_CODEC_AD1986A, 4239 HDA_QUIRK_EAPDINV, 0 }, 4240 { ASUS_A8X_SUBVENDOR, HDA_CODEC_AD1986A, 4241 HDA_QUIRK_EAPDINV, 0 }, 4242 { ASUS_F3JC_SUBVENDOR, HDA_CODEC_ALC861, 4243 HDA_QUIRK_OVREF, 0 }, 4244 { UNIWILL_9075_SUBVENDOR, HDA_CODEC_ALC861, 4245 HDA_QUIRK_OVREF, 0 }, 4246 /*{ ASUS_M2N_SUBVENDOR, HDA_CODEC_AD1988, 4247 HDA_QUIRK_IVREF80, HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF100 },*/ 4248 { MEDION_MD95257_SUBVENDOR, HDA_CODEC_ALC880, 4249 HDA_QUIRK_GPIO1, 0 }, 4250 { LENOVO_3KN100_SUBVENDOR, HDA_CODEC_AD1986A, 4251 HDA_QUIRK_EAPDINV, 0 }, 4252 { SAMSUNG_Q1_SUBVENDOR, HDA_CODEC_AD1986A, 4253 HDA_QUIRK_EAPDINV, 0 }, 4254 { APPLE_MB3_SUBVENDOR, HDA_CODEC_ALC885, 4255 HDA_QUIRK_GPIO0 | HDA_QUIRK_OVREF50, 0}, 4256 { APPLE_INTEL_MAC, HDA_CODEC_STAC9221, 4257 HDA_QUIRK_GPIO0 | HDA_QUIRK_GPIO1, 0 }, 4258 { DELL_V1500_SUBVENDOR, HDA_CODEC_STAC9205, 4259 HDA_QUIRK_GPIO0, 0 }, 4260 { HDA_MATCH_ALL, HDA_CODEC_AD1988, 4261 HDA_QUIRK_IVREF80, HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF100 }, 4262 { HDA_MATCH_ALL, HDA_CODEC_AD1988B, 4263 HDA_QUIRK_IVREF80, HDA_QUIRK_IVREF50 | HDA_QUIRK_IVREF100 }, 4264 { HDA_MATCH_ALL, HDA_CODEC_CXVENICE, 4265 0, HDA_QUIRK_FORCESTEREO }, 4266 { HDA_MATCH_ALL, HDA_CODEC_STACXXXX, 4267 HDA_QUIRK_SOFTPCMVOL, 0 } 4268}; 4269#define HDAC_QUIRKS_LEN (sizeof(hdac_quirks) / sizeof(hdac_quirks[0])) 4270 4271static void 4272hdac_vendor_patch_parse(struct hdac_devinfo *devinfo) 4273{ 4274 struct hdac_widget *w; 4275 struct hdac_audio_ctl *ctl; 4276 uint32_t id, subvendor; 4277 int i; 4278 4279 id = hdac_codec_id(devinfo); 4280 subvendor = devinfo->codec->sc->pci_subvendor; 4281 4282 /* 4283 * Quirks 4284 */ 4285 for (i = 0; i < HDAC_QUIRKS_LEN; i++) { 4286 if (!(HDA_DEV_MATCH(hdac_quirks[i].model, subvendor) && 4287 HDA_DEV_MATCH(hdac_quirks[i].id, id))) 4288 continue; 4289 if (hdac_quirks[i].set != 0) 4290 devinfo->function.audio.quirks |= 4291 hdac_quirks[i].set; 4292 if (hdac_quirks[i].unset != 0) 4293 devinfo->function.audio.quirks &= 4294 ~(hdac_quirks[i].unset); 4295 } 4296 4297 switch (id) { 4298 case HDA_CODEC_ALC260: 4299 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4300 w = hdac_widget_get(devinfo, i); 4301 if (w == NULL || w->enable == 0) 4302 continue; 4303 if (w->type != 4304 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) 4305 continue; 4306 if (w->nid != 5) 4307 w->enable = 0; 4308 } 4309 if (subvendor == HP_XW4300_SUBVENDOR) { 4310 ctl = hdac_audio_ctl_amp_get(devinfo, 16, 0, 1); 4311 if (ctl != NULL && ctl->widget != NULL) { 4312 ctl->ossmask = SOUND_MASK_SPEAKER; 4313 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4314 } 4315 ctl = hdac_audio_ctl_amp_get(devinfo, 17, 0, 1); 4316 if (ctl != NULL && ctl->widget != NULL) { 4317 ctl->ossmask = SOUND_MASK_SPEAKER; 4318 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4319 } 4320 } else if (subvendor == HP_3010_SUBVENDOR) { 4321 ctl = hdac_audio_ctl_amp_get(devinfo, 17, 0, 1); 4322 if (ctl != NULL && ctl->widget != NULL) { 4323 ctl->ossmask = SOUND_MASK_SPEAKER; 4324 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4325 } 4326 ctl = hdac_audio_ctl_amp_get(devinfo, 21, 0, 1); 4327 if (ctl != NULL && ctl->widget != NULL) { 4328 ctl->ossmask = SOUND_MASK_SPEAKER; 4329 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4330 } 4331 } 4332 break; 4333 case HDA_CODEC_ALC262: 4334 if (subvendor == HP_DC7700S_SUBVENDOR) { 4335 ctl = hdac_audio_ctl_amp_get(devinfo, 21, 0, 1); 4336 if (ctl != NULL && ctl->widget != NULL) { 4337 ctl->ossmask = SOUND_MASK_PHONEOUT; 4338 ctl->widget->ctlflags |= SOUND_MASK_PHONEOUT; 4339 } 4340 ctl = hdac_audio_ctl_amp_get(devinfo, 22, 0, 1); 4341 if (ctl != NULL && ctl->widget != NULL) { 4342 ctl->ossmask = SOUND_MASK_SPEAKER; 4343 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4344 } 4345 } else if (subvendor == HP_DC7700_SUBVENDOR) { 4346 ctl = hdac_audio_ctl_amp_get(devinfo, 22, 0, 1); 4347 if (ctl != NULL && ctl->widget != NULL) { 4348 ctl->ossmask = SOUND_MASK_SPEAKER; 4349 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4350 } 4351 ctl = hdac_audio_ctl_amp_get(devinfo, 27, 0, 1); 4352 if (ctl != NULL && ctl->widget != NULL) { 4353 ctl->ossmask = SOUND_MASK_SPEAKER; 4354 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4355 } 4356 } 4357 break; 4358 case HDA_CODEC_ALC268: 4359 if (HDA_DEV_MATCH(ACER_ALL_SUBVENDOR, subvendor)) { 4360 w = hdac_widget_get(devinfo, 29); 4361 if (w != NULL) { 4362 w->enable = 1; 4363 w->type = 4364 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET; 4365 w->param.widget_cap &= 4366 ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK; 4367 w->param.widget_cap |= 4368 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET << 4369 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT; 4370 strlcpy(w->name, "beep widget", sizeof(w->name)); 4371 } 4372 } 4373 break; 4374 case HDA_CODEC_ALC861: 4375 ctl = hdac_audio_ctl_amp_get(devinfo, 21, 2, 1); 4376 if (ctl != NULL) 4377 ctl->muted = HDA_AMP_MUTE_ALL; 4378 break; 4379 case HDA_CODEC_ALC880: 4380 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4381 w = hdac_widget_get(devinfo, i); 4382 if (w == NULL || w->enable == 0) 4383 continue; 4384 if (w->type == 4385 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT && 4386 w->nid != 9 && w->nid != 29) { 4387 w->enable = 0; 4388 } else if (w->type != 4389 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET && 4390 w->nid == 29) { 4391 w->type = 4392 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET; 4393 w->param.widget_cap &= 4394 ~HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK; 4395 w->param.widget_cap |= 4396 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET << 4397 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT; 4398 strlcpy(w->name, "beep widget", sizeof(w->name)); 4399 } 4400 } 4401 break; 4402 case HDA_CODEC_ALC883: 4403 /* 4404 * nid: 24/25 = External (jack) or Internal (fixed) Mic. 4405 * Clear vref cap for jack connectivity. 4406 */ 4407 w = hdac_widget_get(devinfo, 24); 4408 if (w != NULL && w->enable != 0 && w->type == 4409 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 4410 (w->wclass.pin.config & 4411 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) == 4412 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK) 4413 w->wclass.pin.cap &= ~( 4414 HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK | 4415 HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK | 4416 HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK); 4417 w = hdac_widget_get(devinfo, 25); 4418 if (w != NULL && w->enable != 0 && w->type == 4419 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 4420 (w->wclass.pin.config & 4421 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) == 4422 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK) 4423 w->wclass.pin.cap &= ~( 4424 HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK | 4425 HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK | 4426 HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK); 4427 /* 4428 * nid: 26 = Line-in, leave it alone. 4429 */ 4430 break; 4431 case HDA_CODEC_AD1981HD: 4432 w = hdac_widget_get(devinfo, 11); 4433 if (w != NULL && w->enable != 0 && w->nconns > 3) 4434 w->selconn = 3; 4435 if (subvendor == IBM_M52_SUBVENDOR) { 4436 ctl = hdac_audio_ctl_amp_get(devinfo, 7, 0, 1); 4437 if (ctl != NULL) 4438 ctl->ossmask = SOUND_MASK_SPEAKER; 4439 } 4440 break; 4441 case HDA_CODEC_AD1986A: 4442 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4443 w = hdac_widget_get(devinfo, i); 4444 if (w == NULL || w->enable == 0) 4445 continue; 4446 if (w->type != 4447 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) 4448 continue; 4449 if (w->nid != 3) 4450 w->enable = 0; 4451 } 4452 if (subvendor == ASUS_M2NPVMX_SUBVENDOR || 4453 subvendor == ASUS_A8NVMCSM_SUBVENDOR) { 4454 /* nid 28 is mic, nid 29 is line-in */ 4455 w = hdac_widget_get(devinfo, 15); 4456 if (w != NULL) 4457 w->selconn = 2; 4458 w = hdac_widget_get(devinfo, 16); 4459 if (w != NULL) 4460 w->selconn = 1; 4461 } else if (subvendor == ASUS_A8X_SUBVENDOR) { 4462 /* 4463 * This is just plain ridiculous.. There 4464 * are several A8 series that share the same 4465 * pci id but works differently (EAPD). 4466 */ 4467 w = hdac_widget_get(devinfo, 26); 4468 if (w != NULL && w->type == 4469 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 4470 (w->wclass.pin.config & 4471 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) != 4472 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) 4473 devinfo->function.audio.quirks &= 4474 ~HDA_QUIRK_EAPDINV; 4475 } 4476 break; 4477 case HDA_CODEC_AD1988: 4478 case HDA_CODEC_AD1988B: 4479 /*w = hdac_widget_get(devinfo, 12); 4480 if (w != NULL) { 4481 w->selconn = 1; 4482 w->pflags |= HDA_ADC_LOCKED; 4483 } 4484 w = hdac_widget_get(devinfo, 13); 4485 if (w != NULL) { 4486 w->selconn = 4; 4487 w->pflags |= HDA_ADC_LOCKED; 4488 } 4489 w = hdac_widget_get(devinfo, 14); 4490 if (w != NULL) { 4491 w->selconn = 2; 4492 w->pflags |= HDA_ADC_LOCKED; 4493 }*/ 4494 ctl = hdac_audio_ctl_amp_get(devinfo, 57, 0, 1); 4495 if (ctl != NULL) { 4496 ctl->ossmask = SOUND_MASK_IGAIN; 4497 ctl->widget->ctlflags |= SOUND_MASK_IGAIN; 4498 } 4499 ctl = hdac_audio_ctl_amp_get(devinfo, 58, 0, 1); 4500 if (ctl != NULL) { 4501 ctl->ossmask = SOUND_MASK_IGAIN; 4502 ctl->widget->ctlflags |= SOUND_MASK_IGAIN; 4503 } 4504 ctl = hdac_audio_ctl_amp_get(devinfo, 60, 0, 1); 4505 if (ctl != NULL) { 4506 ctl->ossmask = SOUND_MASK_IGAIN; 4507 ctl->widget->ctlflags |= SOUND_MASK_IGAIN; 4508 } 4509 ctl = hdac_audio_ctl_amp_get(devinfo, 32, 0, 1); 4510 if (ctl != NULL) { 4511 ctl->ossmask = SOUND_MASK_MIC | SOUND_MASK_VOLUME; 4512 ctl->widget->ctlflags |= SOUND_MASK_MIC; 4513 } 4514 ctl = hdac_audio_ctl_amp_get(devinfo, 32, 4, 1); 4515 if (ctl != NULL) { 4516 ctl->ossmask = SOUND_MASK_MIC | SOUND_MASK_VOLUME; 4517 ctl->widget->ctlflags |= SOUND_MASK_MIC; 4518 } 4519 ctl = hdac_audio_ctl_amp_get(devinfo, 32, 1, 1); 4520 if (ctl != NULL) { 4521 ctl->ossmask = SOUND_MASK_LINE | SOUND_MASK_VOLUME; 4522 ctl->widget->ctlflags |= SOUND_MASK_LINE; 4523 } 4524 ctl = hdac_audio_ctl_amp_get(devinfo, 32, 7, 1); 4525 if (ctl != NULL) { 4526 ctl->ossmask = SOUND_MASK_SPEAKER | SOUND_MASK_VOLUME; 4527 ctl->widget->ctlflags |= SOUND_MASK_SPEAKER; 4528 } 4529 break; 4530 case HDA_CODEC_STAC9205: 4531 if (subvendor == DELL_V1500_SUBVENDOR) { 4532 w = hdac_widget_get(devinfo, 29); 4533 if (w != NULL) 4534 w->selconn = 1; 4535 w = hdac_widget_get(devinfo, 30); 4536 if (w != NULL) 4537 w->selconn = 1; 4538 } 4539 break; 4540 case HDA_CODEC_STAC9221: 4541 /* 4542 * Dell XPS M1210 need all DACs for each output jacks 4543 */ 4544 if (subvendor == DELL_XPSM1210_SUBVENDOR) 4545 break; 4546 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4547 w = hdac_widget_get(devinfo, i); 4548 if (w == NULL || w->enable == 0) 4549 continue; 4550 if (w->type != 4551 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) 4552 continue; 4553 if (w->nid != 2) 4554 w->enable = 0; 4555 } 4556 break; 4557 case HDA_CODEC_STAC9221D: 4558 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4559 w = hdac_widget_get(devinfo, i); 4560 if (w == NULL || w->enable == 0) 4561 continue; 4562 if (w->type == 4563 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT && 4564 w->nid != 6) 4565 w->enable = 0; 4566 4567 } 4568 break; 4569 case HDA_CODEC_STAC9227: 4570 w = hdac_widget_get(devinfo, 8); 4571 if (w != NULL) 4572 w->enable = 0; 4573 w = hdac_widget_get(devinfo, 9); 4574 if (w != NULL) 4575 w->enable = 0; 4576 break; 4577 case HDA_CODEC_CXWAIKIKI: 4578 if (subvendor == HP_DV5000_SUBVENDOR) { 4579 w = hdac_widget_get(devinfo, 27); 4580 if (w != NULL) 4581 w->enable = 0; 4582 } 4583 ctl = hdac_audio_ctl_amp_get(devinfo, 16, 0, 1); 4584 if (ctl != NULL) 4585 ctl->ossmask = SOUND_MASK_SKIP; 4586 ctl = hdac_audio_ctl_amp_get(devinfo, 25, 0, 1); 4587 if (ctl != NULL && ctl->childwidget != NULL && 4588 ctl->childwidget->enable != 0) { 4589 ctl->ossmask = SOUND_MASK_PCM | SOUND_MASK_VOLUME; 4590 ctl->childwidget->ctlflags |= SOUND_MASK_PCM; 4591 } 4592 ctl = hdac_audio_ctl_amp_get(devinfo, 25, 1, 1); 4593 if (ctl != NULL && ctl->childwidget != NULL && 4594 ctl->childwidget->enable != 0) { 4595 ctl->ossmask = SOUND_MASK_LINE | SOUND_MASK_VOLUME; 4596 ctl->childwidget->ctlflags |= SOUND_MASK_LINE; 4597 } 4598 ctl = hdac_audio_ctl_amp_get(devinfo, 25, 2, 1); 4599 if (ctl != NULL && ctl->childwidget != NULL && 4600 ctl->childwidget->enable != 0) { 4601 ctl->ossmask = SOUND_MASK_MIC | SOUND_MASK_VOLUME; 4602 ctl->childwidget->ctlflags |= SOUND_MASK_MIC; 4603 } 4604 ctl = hdac_audio_ctl_amp_get(devinfo, 26, 0, 1); 4605 if (ctl != NULL) { 4606 ctl->ossmask = SOUND_MASK_SKIP; 4607 /* XXX mixer \=rec mic broken.. why?!? */ 4608 /* ctl->widget->ctlflags |= SOUND_MASK_MIC; */ 4609 } 4610 break; 4611 default: 4612 break; 4613 } 4614} 4615 4616static int 4617hdac_audio_ctl_ossmixer_getnextdev(struct hdac_devinfo *devinfo) 4618{ 4619 int *dev = &devinfo->function.audio.ossidx; 4620 4621 while (*dev < SOUND_MIXER_NRDEVICES) { 4622 switch (*dev) { 4623 case SOUND_MIXER_VOLUME: 4624 case SOUND_MIXER_BASS: 4625 case SOUND_MIXER_TREBLE: 4626 case SOUND_MIXER_PCM: 4627 case SOUND_MIXER_SPEAKER: 4628 case SOUND_MIXER_LINE: 4629 case SOUND_MIXER_MIC: 4630 case SOUND_MIXER_CD: 4631 case SOUND_MIXER_RECLEV: 4632 case SOUND_MIXER_IGAIN: 4633 case SOUND_MIXER_OGAIN: /* reserved for EAPD switch */ 4634 (*dev)++; 4635 break; 4636 default: 4637 return (*dev)++; 4638 break; 4639 } 4640 } 4641 4642 return (-1); 4643} 4644 4645static int 4646hdac_widget_find_dac_path(struct hdac_devinfo *devinfo, nid_t nid, int depth) 4647{ 4648 struct hdac_widget *w; 4649 int i, ret = 0; 4650 4651 if (depth > HDA_PARSE_MAXDEPTH) 4652 return (0); 4653 w = hdac_widget_get(devinfo, nid); 4654 if (w == NULL || w->enable == 0) 4655 return (0); 4656 switch (w->type) { 4657 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT: 4658 w->pflags |= HDA_DAC_PATH; 4659 ret = 1; 4660 break; 4661 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER: 4662 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR: 4663 for (i = 0; i < w->nconns; i++) { 4664 if (hdac_widget_find_dac_path(devinfo, 4665 w->conns[i], depth + 1) != 0) { 4666 if (w->selconn == -1) 4667 w->selconn = i; 4668 ret = 1; 4669 w->pflags |= HDA_DAC_PATH; 4670 } 4671 } 4672 break; 4673 default: 4674 break; 4675 } 4676 return (ret); 4677} 4678 4679static int 4680hdac_widget_find_adc_path(struct hdac_devinfo *devinfo, nid_t nid, int depth) 4681{ 4682 struct hdac_widget *w; 4683 int i, conndev, ret = 0; 4684 4685 if (depth > HDA_PARSE_MAXDEPTH) 4686 return (0); 4687 w = hdac_widget_get(devinfo, nid); 4688 if (w == NULL || w->enable == 0) 4689 return (0); 4690 switch (w->type) { 4691 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT: 4692 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR: 4693 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER: 4694 for (i = 0; i < w->nconns; i++) { 4695 if (hdac_widget_find_adc_path(devinfo, w->conns[i], 4696 depth + 1) != 0) { 4697 if (w->selconn == -1) 4698 w->selconn = i; 4699 w->pflags |= HDA_ADC_PATH; 4700 ret = 1; 4701 } 4702 } 4703 break; 4704 case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX: 4705 conndev = w->wclass.pin.config & 4706 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 4707 if (HDA_PARAM_PIN_CAP_INPUT_CAP(w->wclass.pin.cap) && 4708 (conndev == HDA_CONFIG_DEFAULTCONF_DEVICE_CD || 4709 conndev == HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN || 4710 conndev == HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN)) { 4711 w->pflags |= HDA_ADC_PATH; 4712 ret = 1; 4713 } 4714 break; 4715 /*case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER: 4716 if (w->pflags & HDA_DAC_PATH) { 4717 w->pflags |= HDA_ADC_PATH; 4718 ret = 1; 4719 } 4720 break;*/ 4721 default: 4722 break; 4723 } 4724 return (ret); 4725} 4726 4727static uint32_t 4728hdac_audio_ctl_outamp_build(struct hdac_devinfo *devinfo, 4729 nid_t nid, nid_t pnid, int index, int depth) 4730{ 4731 struct hdac_widget *w, *pw; 4732 struct hdac_audio_ctl *ctl; 4733 uint32_t fl = 0; 4734 int i, ossdev, conndev, strategy; 4735 4736 if (depth > HDA_PARSE_MAXDEPTH) 4737 return (0); 4738 4739 w = hdac_widget_get(devinfo, nid); 4740 if (w == NULL || w->enable == 0) 4741 return (0); 4742 4743 pw = hdac_widget_get(devinfo, pnid); 4744 strategy = devinfo->function.audio.parsing_strategy; 4745 4746 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER 4747 || w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR) { 4748 for (i = 0; i < w->nconns; i++) { 4749 fl |= hdac_audio_ctl_outamp_build(devinfo, w->conns[i], 4750 w->nid, i, depth + 1); 4751 } 4752 w->ctlflags |= fl; 4753 return (fl); 4754 } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT && 4755 (w->pflags & HDA_DAC_PATH)) { 4756 i = 0; 4757 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 4758 if (ctl->enable == 0 || ctl->widget == NULL) 4759 continue; 4760 /* XXX This should be compressed! */ 4761 if (((ctl->widget->nid == w->nid) || 4762 (ctl->widget->nid == pnid && ctl->index == index && 4763 (ctl->dir & HDA_CTL_IN)) || 4764 (ctl->widget->nid == pnid && pw != NULL && 4765 pw->type == 4766 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR && 4767 (pw->nconns < 2 || pw->selconn == index || 4768 pw->selconn == -1) && 4769 (ctl->dir & HDA_CTL_OUT)) || 4770 (strategy == HDA_PARSE_DIRECT && 4771 ctl->widget->nid == w->nid)) && 4772 !(ctl->ossmask & ~SOUND_MASK_VOLUME)) { 4773 /*if (pw != NULL && pw->selconn == -1) 4774 pw->selconn = index; 4775 fl |= SOUND_MASK_VOLUME; 4776 fl |= SOUND_MASK_PCM; 4777 ctl->ossmask |= SOUND_MASK_VOLUME; 4778 ctl->ossmask |= SOUND_MASK_PCM; 4779 ctl->ossdev = SOUND_MIXER_PCM;*/ 4780 if (!(w->ctlflags & SOUND_MASK_PCM) || 4781 (pw != NULL && 4782 !(pw->ctlflags & SOUND_MASK_PCM))) { 4783 fl |= SOUND_MASK_VOLUME; 4784 fl |= SOUND_MASK_PCM; 4785 ctl->ossmask |= SOUND_MASK_VOLUME; 4786 ctl->ossmask |= SOUND_MASK_PCM; 4787 ctl->ossdev = SOUND_MIXER_PCM; 4788 w->ctlflags |= SOUND_MASK_VOLUME; 4789 w->ctlflags |= SOUND_MASK_PCM; 4790 if (pw != NULL) { 4791 if (pw->selconn == -1) 4792 pw->selconn = index; 4793 pw->ctlflags |= 4794 SOUND_MASK_VOLUME; 4795 pw->ctlflags |= 4796 SOUND_MASK_PCM; 4797 } 4798 } 4799 } 4800 } 4801 w->ctlflags |= fl; 4802 return (fl); 4803 } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 4804 HDA_PARAM_PIN_CAP_INPUT_CAP(w->wclass.pin.cap) && 4805 (w->pflags & HDA_ADC_PATH)) { 4806 conndev = w->wclass.pin.config & 4807 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 4808 i = 0; 4809 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 4810 if (ctl->enable == 0 || ctl->widget == NULL) 4811 continue; 4812 /* XXX This should be compressed! */ 4813 if (((ctl->widget->nid == pnid && ctl->index == index && 4814 (ctl->dir & HDA_CTL_IN)) || 4815 (ctl->widget->nid == pnid && pw != NULL && 4816 pw->type == 4817 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR && 4818 (pw->nconns < 2 || pw->selconn == index || 4819 pw->selconn == -1) && 4820 (ctl->dir & HDA_CTL_OUT)) || 4821 (strategy == HDA_PARSE_DIRECT && 4822 ctl->widget->nid == w->nid)) && 4823 !(ctl->ossmask & ~SOUND_MASK_VOLUME)) { 4824 if (pw != NULL && pw->selconn == -1) 4825 pw->selconn = index; 4826 ossdev = 0; 4827 switch (conndev) { 4828 case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN: 4829 ossdev = SOUND_MIXER_MIC; 4830 break; 4831 case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN: 4832 ossdev = SOUND_MIXER_LINE; 4833 break; 4834 case HDA_CONFIG_DEFAULTCONF_DEVICE_CD: 4835 ossdev = SOUND_MIXER_CD; 4836 break; 4837 default: 4838 ossdev = 4839 hdac_audio_ctl_ossmixer_getnextdev( 4840 devinfo); 4841 if (ossdev < 0) 4842 ossdev = 0; 4843 break; 4844 } 4845 if (strategy == HDA_PARSE_MIXER) { 4846 fl |= SOUND_MASK_VOLUME; 4847 ctl->ossmask |= SOUND_MASK_VOLUME; 4848 } 4849 fl |= 1 << ossdev; 4850 ctl->ossmask |= 1 << ossdev; 4851 ctl->ossdev = ossdev; 4852 } 4853 } 4854 w->ctlflags |= fl; 4855 return (fl); 4856 } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET) { 4857 i = 0; 4858 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 4859 if (ctl->enable == 0 || ctl->widget == NULL) 4860 continue; 4861 /* XXX This should be compressed! */ 4862 if (((ctl->widget->nid == pnid && ctl->index == index && 4863 (ctl->dir & HDA_CTL_IN)) || 4864 (ctl->widget->nid == pnid && pw != NULL && 4865 pw->type == 4866 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR && 4867 (pw->nconns < 2 || pw->selconn == index || 4868 pw->selconn == -1) && 4869 (ctl->dir & HDA_CTL_OUT)) || 4870 (strategy == HDA_PARSE_DIRECT && 4871 ctl->widget->nid == w->nid)) && 4872 !(ctl->ossmask & ~SOUND_MASK_VOLUME)) { 4873 if (pw != NULL && pw->selconn == -1) 4874 pw->selconn = index; 4875 fl |= SOUND_MASK_VOLUME; 4876 fl |= SOUND_MASK_SPEAKER; 4877 ctl->ossmask |= SOUND_MASK_VOLUME; 4878 ctl->ossmask |= SOUND_MASK_SPEAKER; 4879 ctl->ossdev = SOUND_MIXER_SPEAKER; 4880 } 4881 } 4882 w->ctlflags |= fl; 4883 return (fl); 4884 } 4885 return (0); 4886} 4887 4888static uint32_t 4889hdac_audio_ctl_inamp_build(struct hdac_devinfo *devinfo, nid_t nid, int depth) 4890{ 4891 struct hdac_widget *w, *cw; 4892 struct hdac_audio_ctl *ctl; 4893 uint32_t fl; 4894 int i; 4895 4896 if (depth > HDA_PARSE_MAXDEPTH) 4897 return (0); 4898 4899 w = hdac_widget_get(devinfo, nid); 4900 if (w == NULL || w->enable == 0) 4901 return (0); 4902 /*if (!(w->pflags & HDA_ADC_PATH)) 4903 return (0); 4904 if (!(w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT || 4905 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR)) 4906 return (0);*/ 4907 i = 0; 4908 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 4909 if (ctl->enable == 0 || ctl->widget == NULL) 4910 continue; 4911 if (ctl->widget->nid == nid) { 4912 ctl->ossmask |= SOUND_MASK_RECLEV; 4913 w->ctlflags |= SOUND_MASK_RECLEV; 4914 return (SOUND_MASK_RECLEV); 4915 } 4916 } 4917 for (i = 0; i < w->nconns; i++) { 4918 cw = hdac_widget_get(devinfo, w->conns[i]); 4919 if (cw == NULL || cw->enable == 0) 4920 continue; 4921 if (cw->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR) 4922 continue; 4923 fl = hdac_audio_ctl_inamp_build(devinfo, cw->nid, depth + 1); 4924 if (fl != 0) { 4925 cw->ctlflags |= fl; 4926 w->ctlflags |= fl; 4927 return (fl); 4928 } 4929 } 4930 return (0); 4931} 4932 4933static int 4934hdac_audio_ctl_recsel_build(struct hdac_devinfo *devinfo, nid_t nid, int depth) 4935{ 4936 struct hdac_widget *w, *cw; 4937 int i, child = 0; 4938 4939 if (depth > HDA_PARSE_MAXDEPTH) 4940 return (0); 4941 4942 w = hdac_widget_get(devinfo, nid); 4943 if (w == NULL || w->enable == 0) 4944 return (0); 4945 /*if (!(w->pflags & HDA_ADC_PATH)) 4946 return (0); 4947 if (!(w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT || 4948 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR)) 4949 return (0);*/ 4950 /* XXX weak! */ 4951 for (i = 0; i < w->nconns; i++) { 4952 cw = hdac_widget_get(devinfo, w->conns[i]); 4953 if (cw == NULL) 4954 continue; 4955 if (++child > 1) { 4956 w->pflags |= HDA_ADC_RECSEL; 4957 return (1); 4958 } 4959 } 4960 for (i = 0; i < w->nconns; i++) { 4961 if (hdac_audio_ctl_recsel_build(devinfo, 4962 w->conns[i], depth + 1) != 0) 4963 return (1); 4964 } 4965 return (0); 4966} 4967 4968static int 4969hdac_audio_build_tree_strategy(struct hdac_devinfo *devinfo) 4970{ 4971 struct hdac_widget *w, *cw; 4972 int i, j, conndev, found_dac = 0; 4973 int strategy; 4974 4975 strategy = devinfo->function.audio.parsing_strategy; 4976 4977 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 4978 w = hdac_widget_get(devinfo, i); 4979 if (w == NULL || w->enable == 0) 4980 continue; 4981 if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 4982 continue; 4983 if (!HDA_PARAM_PIN_CAP_OUTPUT_CAP(w->wclass.pin.cap)) 4984 continue; 4985 conndev = w->wclass.pin.config & 4986 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK; 4987 if (!(conndev == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT || 4988 conndev == HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER || 4989 conndev == HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT)) 4990 continue; 4991 for (j = 0; j < w->nconns; j++) { 4992 cw = hdac_widget_get(devinfo, w->conns[j]); 4993 if (cw == NULL || cw->enable == 0) 4994 continue; 4995 if (strategy == HDA_PARSE_MIXER && !(cw->type == 4996 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER || 4997 cw->type == 4998 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR)) 4999 continue; 5000 if (hdac_widget_find_dac_path(devinfo, cw->nid, 0) 5001 != 0) { 5002 if (w->selconn == -1) 5003 w->selconn = j; 5004 w->pflags |= HDA_DAC_PATH; 5005 found_dac++; 5006 } 5007 } 5008 } 5009 5010 return (found_dac); 5011} 5012 5013static void 5014hdac_audio_build_tree(struct hdac_devinfo *devinfo) 5015{ 5016 struct hdac_widget *w; 5017 struct hdac_audio_ctl *ctl; 5018 int i, j, dacs, strategy; 5019 5020 /* Construct DAC path */ 5021 strategy = HDA_PARSE_MIXER; 5022 devinfo->function.audio.parsing_strategy = strategy; 5023 HDA_BOOTVERBOSE( 5024 device_printf(devinfo->codec->sc->dev, 5025 "HDA_DEBUG: HWiP: HDA Widget Parser - Revision %d\n", 5026 HDA_WIDGET_PARSER_REV); 5027 ); 5028 dacs = hdac_audio_build_tree_strategy(devinfo); 5029 if (dacs == 0) { 5030 HDA_BOOTVERBOSE( 5031 device_printf(devinfo->codec->sc->dev, 5032 "HDA_DEBUG: HWiP: 0 DAC path found! " 5033 "Retrying parser " 5034 "using HDA_PARSE_DIRECT strategy.\n"); 5035 ); 5036 strategy = HDA_PARSE_DIRECT; 5037 devinfo->function.audio.parsing_strategy = strategy; 5038 dacs = hdac_audio_build_tree_strategy(devinfo); 5039 } 5040 5041 HDA_BOOTVERBOSE( 5042 device_printf(devinfo->codec->sc->dev, 5043 "HDA_DEBUG: HWiP: Found %d DAC path using HDA_PARSE_%s " 5044 "strategy.\n", 5045 dacs, (strategy == HDA_PARSE_MIXER) ? "MIXER" : "DIRECT"); 5046 ); 5047 5048 /* Construct ADC path */ 5049 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 5050 w = hdac_widget_get(devinfo, i); 5051 if (w == NULL || w->enable == 0) 5052 continue; 5053 if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) 5054 continue; 5055 (void)hdac_widget_find_adc_path(devinfo, w->nid, 0); 5056 } 5057 5058 /* Output mixers */ 5059 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 5060 w = hdac_widget_get(devinfo, i); 5061 if (w == NULL || w->enable == 0) 5062 continue; 5063 if ((strategy == HDA_PARSE_MIXER && 5064 (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER || 5065 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR) 5066 && (w->pflags & HDA_DAC_PATH)) || 5067 (strategy == HDA_PARSE_DIRECT && (w->pflags & 5068 (HDA_DAC_PATH | HDA_ADC_PATH)))) { 5069 w->ctlflags |= hdac_audio_ctl_outamp_build(devinfo, 5070 w->nid, devinfo->startnode - 1, 0, 0); 5071 } else if (w->type == 5072 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET) { 5073 j = 0; 5074 while ((ctl = hdac_audio_ctl_each(devinfo, &j)) != 5075 NULL) { 5076 if (ctl->enable == 0 || ctl->widget == NULL) 5077 continue; 5078 if (ctl->widget->nid != w->nid) 5079 continue; 5080 ctl->ossmask |= SOUND_MASK_VOLUME; 5081 ctl->ossmask |= SOUND_MASK_SPEAKER; 5082 ctl->ossdev = SOUND_MIXER_SPEAKER; 5083 w->ctlflags |= SOUND_MASK_VOLUME; 5084 w->ctlflags |= SOUND_MASK_SPEAKER; 5085 } 5086 } 5087 } 5088 5089 /* Input mixers (rec) */ 5090 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 5091 w = hdac_widget_get(devinfo, i); 5092 if (w == NULL || w->enable == 0) 5093 continue; 5094 if (!(w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT && 5095 w->pflags & HDA_ADC_PATH)) 5096 continue; 5097 hdac_audio_ctl_inamp_build(devinfo, w->nid, 0); 5098 hdac_audio_ctl_recsel_build(devinfo, w->nid, 0); 5099 } 5100} 5101 5102#define HDA_COMMIT_CONN (1 << 0) 5103#define HDA_COMMIT_CTRL (1 << 1) 5104#define HDA_COMMIT_EAPD (1 << 2) 5105#define HDA_COMMIT_GPIO (1 << 3) 5106#define HDA_COMMIT_MISC (1 << 4) 5107#define HDA_COMMIT_ALL (HDA_COMMIT_CONN | HDA_COMMIT_CTRL | \ 5108 HDA_COMMIT_EAPD | HDA_COMMIT_GPIO | HDA_COMMIT_MISC) 5109 5110static void 5111hdac_audio_commit(struct hdac_devinfo *devinfo, uint32_t cfl) 5112{ 5113 struct hdac_softc *sc = devinfo->codec->sc; 5114 struct hdac_widget *w; 5115 nid_t cad; 5116 int i; 5117 5118 if (!(cfl & HDA_COMMIT_ALL)) 5119 return; 5120 5121 cad = devinfo->codec->cad; 5122 5123 if ((cfl & HDA_COMMIT_MISC)) { 5124 if (sc->pci_subvendor == APPLE_INTEL_MAC) 5125 hdac_command(sc, HDA_CMD_12BIT(cad, devinfo->nid, 5126 0x7e7, 0), cad); 5127 } 5128 5129 if (cfl & HDA_COMMIT_GPIO) { 5130 uint32_t gdata, gmask, gdir; 5131 int commitgpio, numgpio; 5132 5133 gdata = 0; 5134 gmask = 0; 5135 gdir = 0; 5136 commitgpio = 0; 5137 5138 numgpio = HDA_PARAM_GPIO_COUNT_NUM_GPIO( 5139 devinfo->function.audio.gpio); 5140 5141 if (devinfo->function.audio.quirks & HDA_QUIRK_GPIOFLUSH) 5142 commitgpio = (numgpio > 0) ? 1 : 0; 5143 else { 5144 for (i = 0; i < numgpio && i < HDA_GPIO_MAX; i++) { 5145 if (!(devinfo->function.audio.quirks & 5146 (1 << i))) 5147 continue; 5148 if (commitgpio == 0) { 5149 commitgpio = 1; 5150 HDA_BOOTVERBOSE( 5151 gdata = hdac_command(sc, 5152 HDA_CMD_GET_GPIO_DATA(cad, 5153 devinfo->nid), cad); 5154 gmask = hdac_command(sc, 5155 HDA_CMD_GET_GPIO_ENABLE_MASK(cad, 5156 devinfo->nid), cad); 5157 gdir = hdac_command(sc, 5158 HDA_CMD_GET_GPIO_DIRECTION(cad, 5159 devinfo->nid), cad); 5160 device_printf(sc->dev, 5161 "GPIO init: data=0x%08x " 5162 "mask=0x%08x dir=0x%08x\n", 5163 gdata, gmask, gdir); 5164 gdata = 0; 5165 gmask = 0; 5166 gdir = 0; 5167 ); 5168 } 5169 gdata |= 1 << i; 5170 gmask |= 1 << i; 5171 gdir |= 1 << i; 5172 } 5173 } 5174 5175 if (commitgpio != 0) { 5176 HDA_BOOTVERBOSE( 5177 device_printf(sc->dev, 5178 "GPIO commit: data=0x%08x mask=0x%08x " 5179 "dir=0x%08x\n", 5180 gdata, gmask, gdir); 5181 ); 5182 hdac_command(sc, 5183 HDA_CMD_SET_GPIO_ENABLE_MASK(cad, devinfo->nid, 5184 gmask), cad); 5185 hdac_command(sc, 5186 HDA_CMD_SET_GPIO_DIRECTION(cad, devinfo->nid, 5187 gdir), cad); 5188 hdac_command(sc, 5189 HDA_CMD_SET_GPIO_DATA(cad, devinfo->nid, 5190 gdata), cad); 5191 } 5192 } 5193 5194 for (i = 0; i < devinfo->nodecnt; i++) { 5195 w = &devinfo->widget[i]; 5196 if (w == NULL || w->enable == 0) 5197 continue; 5198 if (cfl & HDA_COMMIT_CONN) { 5199 if (w->selconn == -1) 5200 w->selconn = 0; 5201 if (w->nconns > 0) 5202 hdac_widget_connection_select(w, w->selconn); 5203 } 5204 if ((cfl & HDA_COMMIT_CTRL) && 5205 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) { 5206 uint32_t pincap; 5207 5208 pincap = w->wclass.pin.cap; 5209 5210 if ((w->pflags & (HDA_DAC_PATH | HDA_ADC_PATH)) == 5211 (HDA_DAC_PATH | HDA_ADC_PATH)) 5212 device_printf(sc->dev, "WARNING: node %d " 5213 "participate both for DAC/ADC!\n", w->nid); 5214 if (w->pflags & HDA_DAC_PATH) { 5215 w->wclass.pin.ctrl &= 5216 ~HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE; 5217 if ((w->wclass.pin.config & 5218 HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) != 5219 HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT) 5220 w->wclass.pin.ctrl &= 5221 ~HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE; 5222 if ((devinfo->function.audio.quirks & HDA_QUIRK_OVREF100) && 5223 HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap)) 5224 w->wclass.pin.ctrl |= 5225 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE( 5226 HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100); 5227 else if ((devinfo->function.audio.quirks & HDA_QUIRK_OVREF80) && 5228 HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap)) 5229 w->wclass.pin.ctrl |= 5230 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE( 5231 HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80); 5232 else if ((devinfo->function.audio.quirks & HDA_QUIRK_OVREF50) && 5233 HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap)) 5234 w->wclass.pin.ctrl |= 5235 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE( 5236 HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50); 5237 } else if (w->pflags & HDA_ADC_PATH) { 5238 w->wclass.pin.ctrl &= 5239 ~(HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE | 5240 HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE); 5241 if ((devinfo->function.audio.quirks & HDA_QUIRK_IVREF100) && 5242 HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap)) 5243 w->wclass.pin.ctrl |= 5244 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE( 5245 HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100); 5246 else if ((devinfo->function.audio.quirks & HDA_QUIRK_IVREF80) && 5247 HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap)) 5248 w->wclass.pin.ctrl |= 5249 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE( 5250 HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80); 5251 else if ((devinfo->function.audio.quirks & HDA_QUIRK_IVREF50) && 5252 HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap)) 5253 w->wclass.pin.ctrl |= 5254 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE( 5255 HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50); 5256 } else 5257 w->wclass.pin.ctrl &= ~( 5258 HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE | 5259 HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE | 5260 HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE | 5261 HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK); 5262 hdac_command(sc, 5263 HDA_CMD_SET_PIN_WIDGET_CTRL(cad, w->nid, 5264 w->wclass.pin.ctrl), cad); 5265 } 5266 if ((cfl & HDA_COMMIT_EAPD) && 5267 w->param.eapdbtl != HDAC_INVALID) { 5268 uint32_t val; 5269 5270 val = w->param.eapdbtl; 5271 if (devinfo->function.audio.quirks & 5272 HDA_QUIRK_EAPDINV) 5273 val ^= HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD; 5274 hdac_command(sc, 5275 HDA_CMD_SET_EAPD_BTL_ENABLE(cad, w->nid, 5276 val), cad); 5277 5278 } 5279 DELAY(1000); 5280 } 5281} 5282 5283static void 5284hdac_audio_ctl_commit(struct hdac_devinfo *devinfo) 5285{ 5286 struct hdac_softc *sc = devinfo->codec->sc; 5287 struct hdac_audio_ctl *ctl; 5288 int i; 5289 5290 devinfo->function.audio.mvol = 100 | (100 << 8); 5291 i = 0; 5292 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 5293 if (ctl->enable == 0 || ctl->widget == NULL) { 5294 HDA_BOOTVERBOSE( 5295 device_printf(sc->dev, "[%2d] Ctl nid=%d", 5296 i, (ctl->widget != NULL) ? 5297 ctl->widget->nid : -1); 5298 if (ctl->childwidget != NULL) 5299 printf(" childnid=%d", 5300 ctl->childwidget->nid); 5301 if (ctl->widget == NULL) 5302 printf(" NULL WIDGET!"); 5303 printf(" DISABLED\n"); 5304 ); 5305 continue; 5306 } 5307 HDA_BOOTVERBOSE( 5308 if (ctl->ossmask == 0) { 5309 device_printf(sc->dev, "[%2d] Ctl nid=%d", 5310 i, ctl->widget->nid); 5311 if (ctl->childwidget != NULL) 5312 printf(" childnid=%d", 5313 ctl->childwidget->nid); 5314 printf(" Bind to NONE\n"); 5315 } 5316 ); 5317 if (ctl->step > 0) { 5318 ctl->ossval = (ctl->left * 100) / ctl->step; 5319 ctl->ossval |= ((ctl->right * 100) / ctl->step) << 8; 5320 } else 5321 ctl->ossval = 0; 5322 hdac_audio_ctl_amp_set(ctl, HDA_AMP_MUTE_DEFAULT, 5323 ctl->left, ctl->right); 5324 } 5325} 5326 5327static int 5328hdac_pcmchannel_setup(struct hdac_devinfo *devinfo, int dir) 5329{ 5330 struct hdac_chan *ch; 5331 struct hdac_widget *w; 5332 uint32_t cap, fmtcap, pcmcap, path; 5333 int i, type, ret, max; 5334 5335 if (dir == PCMDIR_PLAY) { 5336 type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT; 5337 ch = &devinfo->codec->sc->play; 5338 path = HDA_DAC_PATH; 5339 } else { 5340 type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT; 5341 ch = &devinfo->codec->sc->rec; 5342 path = HDA_ADC_PATH; 5343 } 5344 5345 ch->caps = hdac_caps; 5346 ch->caps.fmtlist = ch->fmtlist; 5347 ch->bit16 = 1; 5348 ch->bit32 = 0; 5349 ch->pcmrates[0] = 48000; 5350 ch->pcmrates[1] = 0; 5351 5352 ret = 0; 5353 fmtcap = devinfo->function.audio.supp_stream_formats; 5354 pcmcap = devinfo->function.audio.supp_pcm_size_rate; 5355 max = (sizeof(ch->io) / sizeof(ch->io[0])) - 1; 5356 5357 for (i = devinfo->startnode; i < devinfo->endnode && ret < max; i++) { 5358 w = hdac_widget_get(devinfo, i); 5359 if (w == NULL || w->enable == 0 || w->type != type || 5360 !(w->pflags & path)) 5361 continue; 5362 cap = w->param.widget_cap; 5363 /*if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(cap)) 5364 continue;*/ 5365 if (!HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(cap)) 5366 continue; 5367 cap = w->param.supp_stream_formats; 5368 /*if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap)) { 5369 } 5370 if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap)) { 5371 }*/ 5372 if (!HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap)) 5373 continue; 5374 if (ret == 0) { 5375 fmtcap = w->param.supp_stream_formats; 5376 pcmcap = w->param.supp_pcm_size_rate; 5377 } else { 5378 fmtcap &= w->param.supp_stream_formats; 5379 pcmcap &= w->param.supp_pcm_size_rate; 5380 } 5381 ch->io[ret++] = i; 5382 } 5383 ch->io[ret] = -1; 5384 5385 ch->supp_stream_formats = fmtcap; 5386 ch->supp_pcm_size_rate = pcmcap; 5387 5388 /* 5389 * 8bit = 0 5390 * 16bit = 1 5391 * 20bit = 2 5392 * 24bit = 3 5393 * 32bit = 4 5394 */ 5395 if (ret > 0) { 5396 cap = pcmcap; 5397 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(cap)) 5398 ch->bit16 = 1; 5399 else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(cap)) 5400 ch->bit16 = 0; 5401 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(cap)) 5402 ch->bit32 = 4; 5403 else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(cap)) 5404 ch->bit32 = 3; 5405 else if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(cap)) 5406 ch->bit32 = 2; 5407 i = 0; 5408 if (!(devinfo->function.audio.quirks & HDA_QUIRK_FORCESTEREO)) 5409 ch->fmtlist[i++] = AFMT_S16_LE; 5410 ch->fmtlist[i++] = AFMT_S16_LE | AFMT_STEREO; 5411 if (ch->bit32 > 0) { 5412 if (!(devinfo->function.audio.quirks & 5413 HDA_QUIRK_FORCESTEREO)) 5414 ch->fmtlist[i++] = AFMT_S32_LE; 5415 ch->fmtlist[i++] = AFMT_S32_LE | AFMT_STEREO; 5416 } 5417 ch->fmtlist[i] = 0; 5418 i = 0; 5419 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(cap)) 5420 ch->pcmrates[i++] = 8000; 5421 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(cap)) 5422 ch->pcmrates[i++] = 11025; 5423 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(cap)) 5424 ch->pcmrates[i++] = 16000; 5425 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(cap)) 5426 ch->pcmrates[i++] = 22050; 5427 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(cap)) 5428 ch->pcmrates[i++] = 32000; 5429 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(cap)) 5430 ch->pcmrates[i++] = 44100; 5431 /* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ(cap)) */ 5432 ch->pcmrates[i++] = 48000; 5433 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(cap)) 5434 ch->pcmrates[i++] = 88200; 5435 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(cap)) 5436 ch->pcmrates[i++] = 96000; 5437 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(cap)) 5438 ch->pcmrates[i++] = 176400; 5439 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(cap)) 5440 ch->pcmrates[i++] = 192000; 5441 /* if (HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ(cap)) */ 5442 ch->pcmrates[i] = 0; 5443 if (i > 0) { 5444 ch->caps.minspeed = ch->pcmrates[0]; 5445 ch->caps.maxspeed = ch->pcmrates[i - 1]; 5446 } 5447 } 5448 5449 return (ret); 5450} 5451 5452static void 5453hdac_dump_ctls(struct hdac_devinfo *devinfo, const char *banner, uint32_t flag) 5454{ 5455 struct hdac_audio_ctl *ctl; 5456 struct hdac_softc *sc = devinfo->codec->sc; 5457 int i; 5458 uint32_t fl = 0; 5459 5460 5461 if (flag == 0) { 5462 fl = SOUND_MASK_VOLUME | SOUND_MASK_PCM | 5463 SOUND_MASK_CD | SOUND_MASK_LINE | SOUND_MASK_RECLEV | 5464 SOUND_MASK_MIC | SOUND_MASK_SPEAKER | SOUND_MASK_OGAIN; 5465 } 5466 5467 i = 0; 5468 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 5469 if (ctl->enable == 0 || ctl->widget == NULL || 5470 ctl->widget->enable == 0 || (ctl->ossmask & 5471 (SOUND_MASK_SKIP | SOUND_MASK_DISABLE))) 5472 continue; 5473 if ((flag == 0 && (ctl->ossmask & ~fl)) || 5474 (flag != 0 && (ctl->ossmask & flag))) { 5475 if (banner != NULL) { 5476 device_printf(sc->dev, "\n"); 5477 device_printf(sc->dev, "%s\n", banner); 5478 } 5479 goto hdac_ctl_dump_it_all; 5480 } 5481 } 5482 5483 return; 5484 5485hdac_ctl_dump_it_all: 5486 i = 0; 5487 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 5488 if (ctl->enable == 0 || ctl->widget == NULL || 5489 ctl->widget->enable == 0) 5490 continue; 5491 if (!((flag == 0 && (ctl->ossmask & ~fl)) || 5492 (flag != 0 && (ctl->ossmask & flag)))) 5493 continue; 5494 if (flag == 0) { 5495 device_printf(sc->dev, "\n"); 5496 device_printf(sc->dev, "Unknown Ctl (OSS: %s)\n", 5497 hdac_audio_ctl_ossmixer_mask2name(ctl->ossmask)); 5498 } 5499 device_printf(sc->dev, " |\n"); 5500 device_printf(sc->dev, " +- nid: %2d index: %2d ", 5501 ctl->widget->nid, ctl->index); 5502 if (ctl->childwidget != NULL) 5503 printf("(nid: %2d) ", ctl->childwidget->nid); 5504 else 5505 printf(" "); 5506 printf("mute: %d step: %3d size: %3d off: %3d dir=0x%x ossmask=0x%08x\n", 5507 ctl->mute, ctl->step, ctl->size, ctl->offset, ctl->dir, 5508 ctl->ossmask); 5509 } 5510} 5511 5512static void 5513hdac_dump_audio_formats(struct hdac_softc *sc, uint32_t fcap, uint32_t pcmcap) 5514{ 5515 uint32_t cap; 5516 5517 cap = fcap; 5518 if (cap != 0) { 5519 device_printf(sc->dev, " Stream cap: 0x%08x\n", cap); 5520 device_printf(sc->dev, " Format:"); 5521 if (HDA_PARAM_SUPP_STREAM_FORMATS_AC3(cap)) 5522 printf(" AC3"); 5523 if (HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(cap)) 5524 printf(" FLOAT32"); 5525 if (HDA_PARAM_SUPP_STREAM_FORMATS_PCM(cap)) 5526 printf(" PCM"); 5527 printf("\n"); 5528 } 5529 cap = pcmcap; 5530 if (cap != 0) { 5531 device_printf(sc->dev, " PCM cap: 0x%08x\n", cap); 5532 device_printf(sc->dev, " PCM size:"); 5533 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(cap)) 5534 printf(" 8"); 5535 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(cap)) 5536 printf(" 16"); 5537 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(cap)) 5538 printf(" 20"); 5539 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(cap)) 5540 printf(" 24"); 5541 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(cap)) 5542 printf(" 32"); 5543 printf("\n"); 5544 device_printf(sc->dev, " PCM rate:"); 5545 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(cap)) 5546 printf(" 8"); 5547 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(cap)) 5548 printf(" 11"); 5549 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(cap)) 5550 printf(" 16"); 5551 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(cap)) 5552 printf(" 22"); 5553 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(cap)) 5554 printf(" 32"); 5555 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(cap)) 5556 printf(" 44"); 5557 printf(" 48"); 5558 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(cap)) 5559 printf(" 88"); 5560 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(cap)) 5561 printf(" 96"); 5562 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(cap)) 5563 printf(" 176"); 5564 if (HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(cap)) 5565 printf(" 192"); 5566 printf("\n"); 5567 } 5568} 5569 5570static void 5571hdac_dump_pin(struct hdac_softc *sc, struct hdac_widget *w) 5572{ 5573 uint32_t pincap, wcap; 5574 5575 pincap = w->wclass.pin.cap; 5576 wcap = w->param.widget_cap; 5577 5578 device_printf(sc->dev, " Pin cap: 0x%08x\n", pincap); 5579 device_printf(sc->dev, " "); 5580 if (HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap)) 5581 printf(" ISC"); 5582 if (HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap)) 5583 printf(" TRQD"); 5584 if (HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap)) 5585 printf(" PDC"); 5586 if (HDA_PARAM_PIN_CAP_HEADPHONE_CAP(pincap)) 5587 printf(" HP"); 5588 if (HDA_PARAM_PIN_CAP_OUTPUT_CAP(pincap)) 5589 printf(" OUT"); 5590 if (HDA_PARAM_PIN_CAP_INPUT_CAP(pincap)) 5591 printf(" IN"); 5592 if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap)) 5593 printf(" BAL"); 5594 if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) { 5595 printf(" VREF["); 5596 if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap)) 5597 printf(" 50"); 5598 if (HDA_PARAM_PIN_CAP_VREF_CTRL_80(pincap)) 5599 printf(" 80"); 5600 if (HDA_PARAM_PIN_CAP_VREF_CTRL_100(pincap)) 5601 printf(" 100"); 5602 if (HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND(pincap)) 5603 printf(" GROUND"); 5604 if (HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(pincap)) 5605 printf(" HIZ"); 5606 printf(" ]"); 5607 } 5608 if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap)) 5609 printf(" EAPD"); 5610 if (HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(wcap)) 5611 printf(" : UNSOL"); 5612 printf("\n"); 5613 device_printf(sc->dev, " Pin config: 0x%08x\n", 5614 w->wclass.pin.config); 5615 device_printf(sc->dev, " Pin control: 0x%08x", w->wclass.pin.ctrl); 5616 if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE) 5617 printf(" HP"); 5618 if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE) 5619 printf(" IN"); 5620 if (w->wclass.pin.ctrl & HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE) 5621 printf(" OUT"); 5622 printf("\n"); 5623} 5624 5625static void 5626hdac_dump_amp(struct hdac_softc *sc, uint32_t cap, char *banner) 5627{ 5628 device_printf(sc->dev, " %s amp: 0x%08x\n", banner, cap); 5629 device_printf(sc->dev, " " 5630 "mute=%d step=%d size=%d offset=%d\n", 5631 HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(cap), 5632 HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(cap), 5633 HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(cap), 5634 HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(cap)); 5635} 5636 5637static void 5638hdac_dump_nodes(struct hdac_devinfo *devinfo) 5639{ 5640 struct hdac_softc *sc = devinfo->codec->sc; 5641 struct hdac_widget *w, *cw; 5642 int i, j; 5643 5644 device_printf(sc->dev, "\n"); 5645 device_printf(sc->dev, "Default Parameter\n"); 5646 device_printf(sc->dev, "-----------------\n"); 5647 hdac_dump_audio_formats(sc, 5648 devinfo->function.audio.supp_stream_formats, 5649 devinfo->function.audio.supp_pcm_size_rate); 5650 device_printf(sc->dev, " IN amp: 0x%08x\n", 5651 devinfo->function.audio.inamp_cap); 5652 device_printf(sc->dev, " OUT amp: 0x%08x\n", 5653 devinfo->function.audio.outamp_cap); 5654 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 5655 w = hdac_widget_get(devinfo, i); 5656 if (w == NULL) { 5657 device_printf(sc->dev, "Ghost widget nid=%d\n", i); 5658 continue; 5659 } 5660 device_printf(sc->dev, "\n"); 5661 device_printf(sc->dev, " nid: %d [%s]%s\n", w->nid, 5662 HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap) ? 5663 "DIGITAL" : "ANALOG", 5664 (w->enable == 0) ? " [DISABLED]" : ""); 5665 device_printf(sc->dev, " name: %s\n", w->name); 5666 device_printf(sc->dev, " widget_cap: 0x%08x\n", 5667 w->param.widget_cap); 5668 device_printf(sc->dev, " Parse flags: 0x%08x\n", 5669 w->pflags); 5670 device_printf(sc->dev, " Ctl flags: 0x%08x\n", 5671 w->ctlflags); 5672 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT || 5673 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT) { 5674 hdac_dump_audio_formats(sc, 5675 w->param.supp_stream_formats, 5676 w->param.supp_pcm_size_rate); 5677 } else if (w->type == 5678 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 5679 hdac_dump_pin(sc, w); 5680 if (w->param.eapdbtl != HDAC_INVALID) 5681 device_printf(sc->dev, " EAPD: 0x%08x\n", 5682 w->param.eapdbtl); 5683 if (HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(w->param.widget_cap) && 5684 w->param.outamp_cap != 0) 5685 hdac_dump_amp(sc, w->param.outamp_cap, "Output"); 5686 if (HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(w->param.widget_cap) && 5687 w->param.inamp_cap != 0) 5688 hdac_dump_amp(sc, w->param.inamp_cap, " Input"); 5689 device_printf(sc->dev, " connections: %d\n", w->nconns); 5690 for (j = 0; j < w->nconns; j++) { 5691 cw = hdac_widget_get(devinfo, w->conns[j]); 5692 device_printf(sc->dev, " |\n"); 5693 device_printf(sc->dev, " + <- nid=%d [%s]", 5694 w->conns[j], (cw == NULL) ? "GHOST!" : cw->name); 5695 if (cw == NULL) 5696 printf(" [UNKNOWN]"); 5697 else if (cw->enable == 0) 5698 printf(" [DISABLED]"); 5699 if (w->nconns > 1 && w->selconn == j && w->type != 5700 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) 5701 printf(" (selected)"); 5702 printf("\n"); 5703 } 5704 } 5705 5706} 5707 5708static int 5709hdac_dump_dac_internal(struct hdac_devinfo *devinfo, nid_t nid, int depth) 5710{ 5711 struct hdac_widget *w, *cw; 5712 struct hdac_softc *sc = devinfo->codec->sc; 5713 int i; 5714 5715 if (depth > HDA_PARSE_MAXDEPTH) 5716 return (0); 5717 5718 w = hdac_widget_get(devinfo, nid); 5719 if (w == NULL || w->enable == 0 || !(w->pflags & HDA_DAC_PATH)) 5720 return (0); 5721 5722 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) { 5723 device_printf(sc->dev, "\n"); 5724 device_printf(sc->dev, " nid=%d [%s]\n", w->nid, w->name); 5725 device_printf(sc->dev, " ^\n"); 5726 device_printf(sc->dev, " |\n"); 5727 device_printf(sc->dev, " +-----<------+\n"); 5728 } else { 5729 device_printf(sc->dev, " ^\n"); 5730 device_printf(sc->dev, " |\n"); 5731 device_printf(sc->dev, " "); 5732 printf(" nid=%d [%s]\n", w->nid, w->name); 5733 } 5734 5735 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) { 5736 return (1); 5737 } else if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER) { 5738 for (i = 0; i < w->nconns; i++) { 5739 cw = hdac_widget_get(devinfo, w->conns[i]); 5740 if (cw == NULL || cw->enable == 0 || cw->type == 5741 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 5742 continue; 5743 if (hdac_dump_dac_internal(devinfo, cw->nid, 5744 depth + 1) != 0) 5745 return (1); 5746 } 5747 } else if ((w->type == 5748 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR || 5749 w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) && 5750 w->selconn > -1 && w->selconn < w->nconns) { 5751 if (hdac_dump_dac_internal(devinfo, w->conns[w->selconn], 5752 depth + 1) != 0) 5753 return (1); 5754 } 5755 5756 return (0); 5757} 5758 5759static void 5760hdac_dump_dac(struct hdac_devinfo *devinfo) 5761{ 5762 struct hdac_widget *w; 5763 struct hdac_softc *sc = devinfo->codec->sc; 5764 int i, printed = 0; 5765 5766 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 5767 w = hdac_widget_get(devinfo, i); 5768 if (w == NULL || w->enable == 0) 5769 continue; 5770 if (w->type != HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX || 5771 !(w->pflags & HDA_DAC_PATH)) 5772 continue; 5773 if (printed == 0) { 5774 printed = 1; 5775 device_printf(sc->dev, "\n"); 5776 device_printf(sc->dev, "Playback path:\n"); 5777 } 5778 hdac_dump_dac_internal(devinfo, w->nid, 0); 5779 } 5780} 5781 5782static void 5783hdac_dump_adc(struct hdac_devinfo *devinfo) 5784{ 5785 struct hdac_widget *w, *cw; 5786 struct hdac_softc *sc = devinfo->codec->sc; 5787 int i, j; 5788 int printed = 0; 5789 char ossdevs[256]; 5790 5791 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 5792 w = hdac_widget_get(devinfo, i); 5793 if (w == NULL || w->enable == 0) 5794 continue; 5795 if (!(w->pflags & HDA_ADC_RECSEL)) 5796 continue; 5797 if (printed == 0) { 5798 printed = 1; 5799 device_printf(sc->dev, "\n"); 5800 device_printf(sc->dev, "Recording sources:\n"); 5801 } 5802 device_printf(sc->dev, "\n"); 5803 device_printf(sc->dev, " nid=%d [%s]\n", w->nid, w->name); 5804 for (j = 0; j < w->nconns; j++) { 5805 cw = hdac_widget_get(devinfo, w->conns[j]); 5806 if (cw == NULL || cw->enable == 0) 5807 continue; 5808 hdac_audio_ctl_ossmixer_mask2allname(cw->ctlflags, 5809 ossdevs, sizeof(ossdevs)); 5810 device_printf(sc->dev, " |\n"); 5811 device_printf(sc->dev, " + <- nid=%d [%s]", 5812 cw->nid, cw->name); 5813 if (strlen(ossdevs) > 0) { 5814 printf(" [recsrc: %s]", ossdevs); 5815 } 5816 printf("\n"); 5817 } 5818 } 5819} 5820 5821static void 5822hdac_dump_pcmchannels(struct hdac_softc *sc, int pcnt, int rcnt) 5823{ 5824 nid_t *nids; 5825 5826 if (pcnt > 0) { 5827 device_printf(sc->dev, "\n"); 5828 device_printf(sc->dev, " PCM Playback: %d\n", pcnt); 5829 hdac_dump_audio_formats(sc, sc->play.supp_stream_formats, 5830 sc->play.supp_pcm_size_rate); 5831 device_printf(sc->dev, " DAC:"); 5832 for (nids = sc->play.io; *nids != -1; nids++) 5833 printf(" %d", *nids); 5834 printf("\n"); 5835 } 5836 5837 if (rcnt > 0) { 5838 device_printf(sc->dev, "\n"); 5839 device_printf(sc->dev, " PCM Record: %d\n", rcnt); 5840 hdac_dump_audio_formats(sc, sc->play.supp_stream_formats, 5841 sc->rec.supp_pcm_size_rate); 5842 device_printf(sc->dev, " ADC:"); 5843 for (nids = sc->rec.io; *nids != -1; nids++) 5844 printf(" %d", *nids); 5845 printf("\n"); 5846 } 5847} 5848 5849static void 5850hdac_release_resources(struct hdac_softc *sc) 5851{ 5852 struct hdac_devinfo *devinfo = NULL; 5853 device_t *devlist = NULL; 5854 int i, devcount; 5855 5856 if (sc == NULL) 5857 return; 5858 5859 hdac_lock(sc); 5860 sc->polling = 0; 5861 sc->poll_ival = 0; 5862 callout_stop(&sc->poll_hda); 5863 callout_stop(&sc->poll_hdac); 5864 callout_stop(&sc->poll_jack); 5865 hdac_reset(sc); 5866 hdac_unlock(sc); 5867 taskqueue_drain(taskqueue_thread, &sc->unsolq_task); 5868 callout_drain(&sc->poll_hda); 5869 callout_drain(&sc->poll_hdac); 5870 callout_drain(&sc->poll_jack); 5871 5872 hdac_irq_free(sc); 5873 5874 device_get_children(sc->dev, &devlist, &devcount); 5875 for (i = 0; devlist != NULL && i < devcount; i++) { 5876 devinfo = (struct hdac_devinfo *)device_get_ivars(devlist[i]); 5877 if (devinfo == NULL) 5878 continue; 5879 if (devinfo->widget != NULL) 5880 free(devinfo->widget, M_HDAC); 5881 if (devinfo->node_type == 5882 HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO && 5883 devinfo->function.audio.ctl != NULL) 5884 free(devinfo->function.audio.ctl, M_HDAC); 5885 free(devinfo, M_HDAC); 5886 device_delete_child(sc->dev, devlist[i]); 5887 } 5888 if (devlist != NULL) 5889 free(devlist, M_TEMP); 5890 5891 for (i = 0; i < HDAC_CODEC_MAX; i++) { 5892 if (sc->codecs[i] != NULL) 5893 free(sc->codecs[i], M_HDAC); 5894 sc->codecs[i] = NULL; 5895 } 5896 5897 hdac_dma_free(sc, &sc->pos_dma); 5898 hdac_dma_free(sc, &sc->rirb_dma); 5899 hdac_dma_free(sc, &sc->corb_dma); 5900 if (sc->play.blkcnt > 0) 5901 hdac_dma_free(sc, &sc->play.bdl_dma); 5902 if (sc->rec.blkcnt > 0) 5903 hdac_dma_free(sc, &sc->rec.bdl_dma); 5904 if (sc->chan_dmat != NULL) { 5905 bus_dma_tag_destroy(sc->chan_dmat); 5906 sc->chan_dmat = NULL; 5907 } 5908 hdac_mem_free(sc); 5909 snd_mtxfree(sc->lock); 5910 free(sc, M_DEVBUF); 5911} 5912 5913/* This function surely going to make its way into upper level someday. */ 5914static void 5915hdac_config_fetch(struct hdac_softc *sc, uint32_t *on, uint32_t *off) 5916{ 5917 const char *res = NULL; 5918 int i = 0, j, k, len, inv; 5919 5920 if (on != NULL) 5921 *on = 0; 5922 if (off != NULL) 5923 *off = 0; 5924 if (sc == NULL) 5925 return; 5926 if (resource_string_value(device_get_name(sc->dev), 5927 device_get_unit(sc->dev), "config", &res) != 0) 5928 return; 5929 if (!(res != NULL && strlen(res) > 0)) 5930 return; 5931 HDA_BOOTVERBOSE( 5932 device_printf(sc->dev, "HDA_DEBUG: HDA Config:"); 5933 ); 5934 for (;;) { 5935 while (res[i] != '\0' && 5936 (res[i] == ',' || isspace(res[i]) != 0)) 5937 i++; 5938 if (res[i] == '\0') { 5939 HDA_BOOTVERBOSE( 5940 printf("\n"); 5941 ); 5942 return; 5943 } 5944 j = i; 5945 while (res[j] != '\0' && 5946 !(res[j] == ',' || isspace(res[j]) != 0)) 5947 j++; 5948 len = j - i; 5949 if (len > 2 && strncmp(res + i, "no", 2) == 0) 5950 inv = 2; 5951 else 5952 inv = 0; 5953 for (k = 0; len > inv && k < HDAC_QUIRKS_TAB_LEN; k++) { 5954 if (strncmp(res + i + inv, 5955 hdac_quirks_tab[k].key, len - inv) != 0) 5956 continue; 5957 if (len - inv != strlen(hdac_quirks_tab[k].key)) 5958 break; 5959 HDA_BOOTVERBOSE( 5960 printf(" %s%s", (inv != 0) ? "no" : "", 5961 hdac_quirks_tab[k].key); 5962 ); 5963 if (inv == 0 && on != NULL) 5964 *on |= hdac_quirks_tab[k].value; 5965 else if (inv != 0 && off != NULL) 5966 *off |= hdac_quirks_tab[k].value; 5967 break; 5968 } 5969 i = j; 5970 } 5971} 5972 5973#ifdef SND_DYNSYSCTL 5974static int 5975sysctl_hdac_polling(SYSCTL_HANDLER_ARGS) 5976{ 5977 struct hdac_softc *sc; 5978 struct hdac_devinfo *devinfo; 5979 device_t dev; 5980 uint32_t ctl; 5981 int err, val; 5982 5983 dev = oidp->oid_arg1; 5984 devinfo = pcm_getdevinfo(dev); 5985 if (devinfo == NULL || devinfo->codec == NULL || 5986 devinfo->codec->sc == NULL) 5987 return (EINVAL); 5988 sc = devinfo->codec->sc; 5989 hdac_lock(sc); 5990 val = sc->polling; 5991 hdac_unlock(sc); 5992 err = sysctl_handle_int(oidp, &val, 0, req); 5993 5994 if (err != 0 || req->newptr == NULL) 5995 return (err); 5996 if (val < 0 || val > 1) 5997 return (EINVAL); 5998 5999 hdac_lock(sc); 6000 if (val != sc->polling) { 6001 if (hda_chan_active(sc) != 0) 6002 err = EBUSY; 6003 else if (val == 0) { 6004 callout_stop(&sc->poll_hdac); 6005 hdac_unlock(sc); 6006 callout_drain(&sc->poll_hdac); 6007 hdac_lock(sc); 6008 HDAC_WRITE_2(&sc->mem, HDAC_RINTCNT, 6009 sc->rirb_size / 2); 6010 ctl = HDAC_READ_1(&sc->mem, HDAC_RIRBCTL); 6011 ctl |= HDAC_RIRBCTL_RINTCTL; 6012 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, ctl); 6013 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, 6014 HDAC_INTCTL_CIE | HDAC_INTCTL_GIE); 6015 sc->polling = 0; 6016 DELAY(1000); 6017 } else { 6018 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, 0); 6019 HDAC_WRITE_2(&sc->mem, HDAC_RINTCNT, 0); 6020 ctl = HDAC_READ_1(&sc->mem, HDAC_RIRBCTL); 6021 ctl &= ~HDAC_RIRBCTL_RINTCTL; 6022 HDAC_WRITE_1(&sc->mem, HDAC_RIRBCTL, ctl); 6023 hdac_unlock(sc); 6024 taskqueue_drain(taskqueue_thread, &sc->unsolq_task); 6025 hdac_lock(sc); 6026 callout_reset(&sc->poll_hdac, 1, hdac_poll_callback, 6027 sc); 6028 sc->polling = 1; 6029 DELAY(1000); 6030 } 6031 } 6032 hdac_unlock(sc); 6033 6034 return (err); 6035} 6036 6037static int 6038sysctl_hdac_polling_interval(SYSCTL_HANDLER_ARGS) 6039{ 6040 struct hdac_softc *sc; 6041 struct hdac_devinfo *devinfo; 6042 device_t dev; 6043 int err, val; 6044 6045 dev = oidp->oid_arg1; 6046 devinfo = pcm_getdevinfo(dev); 6047 if (devinfo == NULL || devinfo->codec == NULL || 6048 devinfo->codec->sc == NULL) 6049 return (EINVAL); 6050 sc = devinfo->codec->sc; 6051 hdac_lock(sc); 6052 val = ((uint64_t)sc->poll_ival * 1000) / hz; 6053 hdac_unlock(sc); 6054 err = sysctl_handle_int(oidp, &val, 0, req); 6055 6056 if (err != 0 || req->newptr == NULL) 6057 return (err); 6058 6059 if (val < 1) 6060 val = 1; 6061 if (val > 5000) 6062 val = 5000; 6063 val = ((uint64_t)val * hz) / 1000; 6064 if (val < 1) 6065 val = 1; 6066 if (val > (hz * 5)) 6067 val = hz * 5; 6068 6069 hdac_lock(sc); 6070 sc->poll_ival = val; 6071 hdac_unlock(sc); 6072 6073 return (err); 6074} 6075 6076#ifdef SND_DEBUG 6077static int 6078sysctl_hdac_pindump(SYSCTL_HANDLER_ARGS) 6079{ 6080 struct hdac_softc *sc; 6081 struct hdac_devinfo *devinfo; 6082 struct hdac_widget *w; 6083 device_t dev; 6084 uint32_t res, pincap, timeout; 6085 int i, err, val; 6086 nid_t cad; 6087 6088 dev = oidp->oid_arg1; 6089 devinfo = pcm_getdevinfo(dev); 6090 if (devinfo == NULL || devinfo->codec == NULL || 6091 devinfo->codec->sc == NULL) 6092 return (EINVAL); 6093 val = 0; 6094 err = sysctl_handle_int(oidp, &val, 0, req); 6095 if (err != 0 || req->newptr == NULL || val == 0) 6096 return (err); 6097 sc = devinfo->codec->sc; 6098 cad = devinfo->codec->cad; 6099 hdac_lock(sc); 6100 device_printf(dev, "HDAC Dump AFG [nid=%d]:\n", devinfo->nid); 6101 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 6102 w = hdac_widget_get(devinfo, i); 6103 if (w == NULL || w->type != 6104 HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) 6105 continue; 6106 pincap = w->wclass.pin.cap; 6107 if ((HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(pincap) || 6108 HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(pincap)) && 6109 HDA_PARAM_PIN_CAP_TRIGGER_REQD(pincap)) { 6110 timeout = 10000; 6111 hdac_command(sc, 6112 HDA_CMD_SET_PIN_SENSE(cad, w->nid, 0), cad); 6113 do { 6114 res = hdac_command(sc, 6115 HDA_CMD_GET_PIN_SENSE(cad, w->nid), cad); 6116 if (res != 0x7fffffff) 6117 break; 6118 DELAY(10); 6119 } while (--timeout != 0); 6120 } else { 6121 timeout = -1; 6122 res = hdac_command(sc, HDA_CMD_GET_PIN_SENSE(cad, 6123 w->nid), cad); 6124 } 6125 device_printf(dev, 6126 "PIN_SENSE: nid=%-3d timeout=%d res=0x%08x [%s]\n", 6127 w->nid, timeout, res, 6128 (w->enable == 0) ? "DISABLED" : "ENABLED"); 6129 } 6130 device_printf(dev, 6131 "NumGPIO=%d NumGPO=%d NumGPI=%d GPIWake=%d GPIUnsol=%d\n", 6132 HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->function.audio.gpio), 6133 HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->function.audio.gpio), 6134 HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->function.audio.gpio), 6135 HDA_PARAM_GPIO_COUNT_GPI_WAKE(devinfo->function.audio.gpio), 6136 HDA_PARAM_GPIO_COUNT_GPI_UNSOL(devinfo->function.audio.gpio)); 6137 if (HDA_PARAM_GPIO_COUNT_NUM_GPI(devinfo->function.audio.gpio) > 0) { 6138 device_printf(dev, " GPI:"); 6139 res = hdac_command(sc, 6140 HDA_CMD_GET_GPI_DATA(cad, devinfo->nid), cad); 6141 printf(" data=0x%08x", res); 6142 res = hdac_command(sc, 6143 HDA_CMD_GET_GPI_WAKE_ENABLE_MASK(cad, devinfo->nid), 6144 cad); 6145 printf(" wake=0x%08x", res); 6146 res = hdac_command(sc, 6147 HDA_CMD_GET_GPI_UNSOLICITED_ENABLE_MASK(cad, devinfo->nid), 6148 cad); 6149 printf(" unsol=0x%08x", res); 6150 res = hdac_command(sc, 6151 HDA_CMD_GET_GPI_STICKY_MASK(cad, devinfo->nid), cad); 6152 printf(" sticky=0x%08x\n", res); 6153 } 6154 if (HDA_PARAM_GPIO_COUNT_NUM_GPO(devinfo->function.audio.gpio) > 0) { 6155 device_printf(dev, " GPO:"); 6156 res = hdac_command(sc, 6157 HDA_CMD_GET_GPO_DATA(cad, devinfo->nid), cad); 6158 printf(" data=0x%08x\n", res); 6159 } 6160 if (HDA_PARAM_GPIO_COUNT_NUM_GPIO(devinfo->function.audio.gpio) > 0) { 6161 device_printf(dev, "GPI0:"); 6162 res = hdac_command(sc, 6163 HDA_CMD_GET_GPIO_DATA(cad, devinfo->nid), cad); 6164 printf(" data=0x%08x", res); 6165 res = hdac_command(sc, 6166 HDA_CMD_GET_GPIO_ENABLE_MASK(cad, devinfo->nid), cad); 6167 printf(" enable=0x%08x", res); 6168 res = hdac_command(sc, 6169 HDA_CMD_GET_GPIO_DIRECTION(cad, devinfo->nid), cad); 6170 printf(" direction=0x%08x\n", res); 6171 res = hdac_command(sc, 6172 HDA_CMD_GET_GPIO_WAKE_ENABLE_MASK(cad, devinfo->nid), cad); 6173 device_printf(dev, " wake=0x%08x", res); 6174 res = hdac_command(sc, 6175 HDA_CMD_GET_GPIO_UNSOLICITED_ENABLE_MASK(cad, devinfo->nid), 6176 cad); 6177 printf(" unsol=0x%08x", res); 6178 res = hdac_command(sc, 6179 HDA_CMD_GET_GPIO_STICKY_MASK(cad, devinfo->nid), cad); 6180 printf(" sticky=0x%08x\n", res); 6181 } 6182 hdac_unlock(sc); 6183 return (0); 6184} 6185#endif 6186#endif 6187 6188static void 6189hdac_attach2(void *arg) 6190{ 6191 struct hdac_softc *sc; 6192 struct hdac_widget *w; 6193 struct hdac_audio_ctl *ctl; 6194 uint32_t quirks_on, quirks_off; 6195 int pcnt, rcnt, codec_index; 6196 int i; 6197 char status[SND_STATUSLEN]; 6198 device_t *devlist = NULL; 6199 int devcount; 6200 struct hdac_devinfo *devinfo = NULL; 6201 6202 sc = (struct hdac_softc *)arg; 6203 6204 hdac_config_fetch(sc, &quirks_on, &quirks_off); 6205 6206 HDA_BOOTVERBOSE( 6207 device_printf(sc->dev, "HDA_DEBUG: HDA Config: on=0x%08x off=0x%08x\n", 6208 quirks_on, quirks_off); 6209 ); 6210 6211 if (resource_int_value(device_get_name(sc->dev), 6212 device_get_unit(sc->dev), "codec_index", &codec_index) != 0) { 6213 switch (sc->pci_subvendor) { 6214 case GB_G33S2H_SUBVENDOR: 6215 codec_index = 2; 6216 break; 6217 default: 6218 codec_index = 0; 6219 break; 6220 } 6221 } 6222 6223 hdac_lock(sc); 6224 6225 /* Remove ourselves from the config hooks */ 6226 if (sc->intrhook.ich_func != NULL) { 6227 config_intrhook_disestablish(&sc->intrhook); 6228 sc->intrhook.ich_func = NULL; 6229 } 6230 6231 /* Start the corb and rirb engines */ 6232 HDA_BOOTVERBOSE( 6233 device_printf(sc->dev, "HDA_DEBUG: Starting CORB Engine...\n"); 6234 ); 6235 hdac_corb_start(sc); 6236 HDA_BOOTVERBOSE( 6237 device_printf(sc->dev, "HDA_DEBUG: Starting RIRB Engine...\n"); 6238 ); 6239 hdac_rirb_start(sc); 6240 6241 HDA_BOOTVERBOSE( 6242 device_printf(sc->dev, 6243 "HDA_DEBUG: Enabling controller interrupt...\n"); 6244 ); 6245 if (sc->polling == 0) 6246 HDAC_WRITE_4(&sc->mem, HDAC_INTCTL, 6247 HDAC_INTCTL_CIE | HDAC_INTCTL_GIE); 6248 HDAC_WRITE_4(&sc->mem, HDAC_GCTL, HDAC_READ_4(&sc->mem, HDAC_GCTL) | 6249 HDAC_GCTL_UNSOL); 6250 6251 DELAY(1000); 6252 6253 HDA_BOOTVERBOSE( 6254 device_printf(sc->dev, 6255 "HDA_DEBUG: Scanning HDA codecs [start index=%d] ...\n", 6256 codec_index); 6257 ); 6258 hdac_scan_codecs(sc, codec_index); 6259 6260 device_get_children(sc->dev, &devlist, &devcount); 6261 for (i = 0; devlist != NULL && i < devcount; i++) { 6262 devinfo = (struct hdac_devinfo *)device_get_ivars(devlist[i]); 6263 if (devinfo != NULL && devinfo->node_type == 6264 HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO) { 6265 break; 6266 } else 6267 devinfo = NULL; 6268 } 6269 if (devlist != NULL) 6270 free(devlist, M_TEMP); 6271 6272 if (devinfo == NULL) { 6273 hdac_unlock(sc); 6274 device_printf(sc->dev, "Audio Function Group not found!\n"); 6275 hdac_release_resources(sc); 6276 return; 6277 } 6278 6279 HDA_BOOTVERBOSE( 6280 device_printf(sc->dev, 6281 "HDA_DEBUG: Parsing AFG nid=%d cad=%d\n", 6282 devinfo->nid, devinfo->codec->cad); 6283 ); 6284 hdac_audio_parse(devinfo); 6285 HDA_BOOTVERBOSE( 6286 device_printf(sc->dev, "HDA_DEBUG: Parsing Ctls...\n"); 6287 ); 6288 hdac_audio_ctl_parse(devinfo); 6289 HDA_BOOTVERBOSE( 6290 device_printf(sc->dev, "HDA_DEBUG: Parsing vendor patch...\n"); 6291 ); 6292 hdac_vendor_patch_parse(devinfo); 6293 if (quirks_on != 0) 6294 devinfo->function.audio.quirks |= quirks_on; 6295 if (quirks_off != 0) 6296 devinfo->function.audio.quirks &= ~quirks_off; 6297 6298 /* XXX Disable all DIGITAL path. */ 6299 for (i = devinfo->startnode; i < devinfo->endnode; i++) { 6300 w = hdac_widget_get(devinfo, i); 6301 if (w == NULL) 6302 continue; 6303 if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) { 6304 w->enable = 0; 6305 continue; 6306 } 6307 /* XXX Disable useless pin ? */ 6308 if (w->type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX && 6309 (w->wclass.pin.config & 6310 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) == 6311 HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE) 6312 w->enable = 0; 6313 } 6314 i = 0; 6315 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 6316 if (ctl->widget == NULL) 6317 continue; 6318 if (ctl->ossmask & SOUND_MASK_DISABLE) 6319 ctl->enable = 0; 6320 w = ctl->widget; 6321 if (w->enable == 0 || 6322 HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) 6323 ctl->enable = 0; 6324 w = ctl->childwidget; 6325 if (w == NULL) 6326 continue; 6327 if (w->enable == 0 || 6328 HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) 6329 ctl->enable = 0; 6330 } 6331 6332 HDA_BOOTVERBOSE( 6333 device_printf(sc->dev, "HDA_DEBUG: Building AFG tree...\n"); 6334 ); 6335 hdac_audio_build_tree(devinfo); 6336 6337 i = 0; 6338 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 6339 if (ctl->ossmask & (SOUND_MASK_SKIP | SOUND_MASK_DISABLE)) 6340 ctl->ossmask = 0; 6341 } 6342 HDA_BOOTVERBOSE( 6343 device_printf(sc->dev, "HDA_DEBUG: AFG commit...\n"); 6344 ); 6345 hdac_audio_commit(devinfo, HDA_COMMIT_ALL); 6346 HDA_BOOTVERBOSE( 6347 device_printf(sc->dev, "HDA_DEBUG: Ctls commit...\n"); 6348 ); 6349 hdac_audio_ctl_commit(devinfo); 6350 6351 HDA_BOOTVERBOSE( 6352 device_printf(sc->dev, "HDA_DEBUG: PCMDIR_PLAY setup...\n"); 6353 ); 6354 pcnt = hdac_pcmchannel_setup(devinfo, PCMDIR_PLAY); 6355 HDA_BOOTVERBOSE( 6356 device_printf(sc->dev, "HDA_DEBUG: PCMDIR_REC setup...\n"); 6357 ); 6358 rcnt = hdac_pcmchannel_setup(devinfo, PCMDIR_REC); 6359 6360 hdac_unlock(sc); 6361 HDA_BOOTVERBOSE( 6362 device_printf(sc->dev, 6363 "HDA_DEBUG: OSS mixer initialization...\n"); 6364 ); 6365 6366 /* 6367 * There is no point of return after this. If the driver failed, 6368 * so be it. Let the detach procedure do all the cleanup. 6369 */ 6370 if (mixer_init(sc->dev, &hdac_audio_ctl_ossmixer_class, devinfo) != 0) 6371 device_printf(sc->dev, "Can't register mixer\n"); 6372 6373 if (pcnt > 0) 6374 pcnt = 1; 6375 if (rcnt > 0) 6376 rcnt = 1; 6377 6378 HDA_BOOTVERBOSE( 6379 device_printf(sc->dev, 6380 "HDA_DEBUG: Registering PCM channels...\n"); 6381 ); 6382 if (pcm_register(sc->dev, devinfo, pcnt, rcnt) != 0) 6383 device_printf(sc->dev, "Can't register PCM\n"); 6384 6385 sc->registered++; 6386 6387 if ((devinfo->function.audio.quirks & HDA_QUIRK_DMAPOS) && 6388 hdac_dma_alloc(sc, &sc->pos_dma, 6389 (sc->num_iss + sc->num_oss + sc->num_bss) * 8) != 0) { 6390 HDA_BOOTVERBOSE( 6391 device_printf(sc->dev, 6392 "Failed to allocate DMA pos buffer (non-fatal)\n"); 6393 ); 6394 } 6395 6396 for (i = 0; i < pcnt; i++) 6397 pcm_addchan(sc->dev, PCMDIR_PLAY, &hdac_channel_class, devinfo); 6398 for (i = 0; i < rcnt; i++) 6399 pcm_addchan(sc->dev, PCMDIR_REC, &hdac_channel_class, devinfo); 6400 6401#ifdef SND_DYNSYSCTL 6402 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev), 6403 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, 6404 "polling", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev), 6405 sysctl_hdac_polling, "I", "Enable polling mode"); 6406 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev), 6407 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, 6408 "polling_interval", CTLTYPE_INT | CTLFLAG_RW, sc->dev, 6409 sizeof(sc->dev), sysctl_hdac_polling_interval, "I", 6410 "Controller/Jack Sense polling interval (1-1000 ms)"); 6411#ifdef SND_DEBUG 6412 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev), 6413 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO, 6414 "pindump", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev), 6415 sysctl_hdac_pindump, "I", "Dump pin states/data"); 6416#endif 6417#endif 6418 6419 snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s [%s]", 6420 rman_get_start(sc->mem.mem_res), rman_get_start(sc->irq.irq_res), 6421 PCM_KLDSTRING(snd_hda), HDA_DRV_TEST_REV); 6422 pcm_setstatus(sc->dev, status); 6423 device_printf(sc->dev, "<HDA Codec: %s>\n", hdac_codec_name(devinfo)); 6424 HDA_BOOTVERBOSE( 6425 device_printf(sc->dev, "<HDA Codec ID: 0x%08x>\n", 6426 hdac_codec_id(devinfo)); 6427 ); 6428 device_printf(sc->dev, "<HDA Driver Revision: %s>\n", 6429 HDA_DRV_TEST_REV); 6430 6431 HDA_BOOTVERBOSE( 6432 if (devinfo->function.audio.quirks != 0) { 6433 device_printf(sc->dev, "\n"); 6434 device_printf(sc->dev, "HDA config/quirks:"); 6435 for (i = 0; i < HDAC_QUIRKS_TAB_LEN; i++) { 6436 if ((devinfo->function.audio.quirks & 6437 hdac_quirks_tab[i].value) == 6438 hdac_quirks_tab[i].value) 6439 printf(" %s", hdac_quirks_tab[i].key); 6440 } 6441 printf("\n"); 6442 } 6443 device_printf(sc->dev, "\n"); 6444 device_printf(sc->dev, "+-------------------+\n"); 6445 device_printf(sc->dev, "| DUMPING HDA NODES |\n"); 6446 device_printf(sc->dev, "+-------------------+\n"); 6447 hdac_dump_nodes(devinfo); 6448 device_printf(sc->dev, "\n"); 6449 device_printf(sc->dev, "+------------------------+\n"); 6450 device_printf(sc->dev, "| DUMPING HDA AMPLIFIERS |\n"); 6451 device_printf(sc->dev, "+------------------------+\n"); 6452 device_printf(sc->dev, "\n"); 6453 i = 0; 6454 while ((ctl = hdac_audio_ctl_each(devinfo, &i)) != NULL) { 6455 device_printf(sc->dev, "%3d: nid=%d", i, 6456 (ctl->widget != NULL) ? ctl->widget->nid : -1); 6457 if (ctl->childwidget != NULL) 6458 printf(" cnid=%d", ctl->childwidget->nid); 6459 printf(" dir=0x%x index=%d " 6460 "ossmask=0x%08x ossdev=%d%s\n", 6461 ctl->dir, ctl->index, 6462 ctl->ossmask, ctl->ossdev, 6463 (ctl->enable == 0) ? " [DISABLED]" : ""); 6464 } 6465 device_printf(sc->dev, "\n"); 6466 device_printf(sc->dev, "+-----------------------------------+\n"); 6467 device_printf(sc->dev, "| DUMPING HDA AUDIO/VOLUME CONTROLS |\n"); 6468 device_printf(sc->dev, "+-----------------------------------+\n"); 6469 hdac_dump_ctls(devinfo, "Master Volume (OSS: vol)", SOUND_MASK_VOLUME); 6470 hdac_dump_ctls(devinfo, "PCM Volume (OSS: pcm)", SOUND_MASK_PCM); 6471 hdac_dump_ctls(devinfo, "CD Volume (OSS: cd)", SOUND_MASK_CD); 6472 hdac_dump_ctls(devinfo, "Microphone Volume (OSS: mic)", SOUND_MASK_MIC); 6473 hdac_dump_ctls(devinfo, "Line-in Volume (OSS: line)", SOUND_MASK_LINE); 6474 hdac_dump_ctls(devinfo, "Recording Level (OSS: rec)", SOUND_MASK_RECLEV); 6475 hdac_dump_ctls(devinfo, "Speaker/Beep (OSS: speaker)", SOUND_MASK_SPEAKER); 6476 hdac_dump_ctls(devinfo, NULL, 0); 6477 hdac_dump_dac(devinfo); 6478 hdac_dump_adc(devinfo); 6479 device_printf(sc->dev, "\n"); 6480 device_printf(sc->dev, "+--------------------------------------+\n"); 6481 device_printf(sc->dev, "| DUMPING PCM Playback/Record Channels |\n"); 6482 device_printf(sc->dev, "+--------------------------------------+\n"); 6483 hdac_dump_pcmchannels(sc, pcnt, rcnt); 6484 ); 6485 6486 if (sc->polling != 0) { 6487 hdac_lock(sc); 6488 callout_reset(&sc->poll_hdac, 1, hdac_poll_callback, sc); 6489 hdac_unlock(sc); 6490 } 6491} 6492 6493/**************************************************************************** 6494 * int hdac_detach(device_t) 6495 * 6496 * Detach and free up resources utilized by the hdac device. 6497 ****************************************************************************/ 6498static int 6499hdac_detach(device_t dev) 6500{ 6501 struct hdac_softc *sc = NULL; 6502 struct hdac_devinfo *devinfo = NULL; 6503 int err; 6504 6505 devinfo = (struct hdac_devinfo *)pcm_getdevinfo(dev); 6506 if (devinfo != NULL && devinfo->codec != NULL) 6507 sc = devinfo->codec->sc; 6508 if (sc == NULL) 6509 return (0); 6510 6511 if (sc->registered > 0) { 6512 err = pcm_unregister(dev); 6513 if (err != 0) 6514 return (err); 6515 } 6516 6517 hdac_release_resources(sc); 6518 6519 return (0); 6520} 6521 6522static device_method_t hdac_methods[] = { 6523 /* device interface */ 6524 DEVMETHOD(device_probe, hdac_probe), 6525 DEVMETHOD(device_attach, hdac_attach), 6526 DEVMETHOD(device_detach, hdac_detach), 6527 { 0, 0 } 6528}; 6529 6530static driver_t hdac_driver = { 6531 "pcm", 6532 hdac_methods, 6533 PCM_SOFTC_SIZE, 6534}; 6535 6536DRIVER_MODULE(snd_hda, pci, hdac_driver, pcm_devclass, 0, 0); 6537MODULE_DEPEND(snd_hda, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 6538MODULE_VERSION(snd_hda, 1); 6539