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