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