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