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