1 /* $NetBSD: azalia.c,v 1.70 2009/11/12 19:40:19 dyoung Exp $ */
4 * Copyright (c) 2005 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * High Definition Audio Specification
34 * ftp://download.intel.com/standards/hdaudio/pdf/HDAudio_03.pdf
39 * - multiple codecs (needed?)
40 * - multiple streams (needed?)
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: azalia.c,v 1.70 2009/11/12 19:40:19 dyoung Exp $");
46 #include <sys/param.h>
47 #include <sys/device.h>
48 #include <sys/fcntl.h>
49 #include <sys/malloc.h>
50 #include <sys/systm.h>
51 #include <sys/module.h>
52 #include <dev/audio_if.h>
53 #include <dev/auconv.h>
54 #include <dev/pci/pcidevs.h>
55 #include <dev/pci/pcivar.h>
57 #include <dev/pci/azalia.h>
59 /* ----------------------------------------------------------------
60 * ICH6/ICH7 constant values
61 * ---------------------------------------------------------------- */
64 #define ICH_PCI_HDBARL 0x10
65 #define ICH_PCI_HDBARU 0x14
66 #define ICH_PCI_HDCTL 0x40
67 #define ICH_PCI_HDCTL_CLKDETCLR 0x08
68 #define ICH_PCI_HDCTL_CLKDETEN 0x04
69 #define ICH_PCI_HDCTL_CLKDETINV 0x02
70 #define ICH_PCI_HDCTL_SIGNALMODE 0x01
76 void *addr
; /* kernel virtual address */
77 bus_dma_segment_t segments
[1];
81 #define AZALIA_DMA_DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
87 int dir
; /* AUMODE_PLAY or AUMODE_RECORD */
93 bus_addr_t dmaend
, dmanext
; /* XXX needed? */
96 /* XXXfreza use bus_space_subregion() instead of adding 'regbase' offset */
97 #define STR_READ_1(s, r) \
98 bus_space_read_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
99 #define STR_READ_2(s, r) \
100 bus_space_read_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
101 #define STR_READ_4(s, r) \
102 bus_space_read_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
103 #define STR_WRITE_1(s, r, v) \
104 bus_space_write_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
105 #define STR_WRITE_2(s, r, v) \
106 bus_space_write_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
107 #define STR_WRITE_4(s, r, v) \
108 bus_space_write_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
110 typedef struct azalia_t
{
114 pci_chipset_tag_t pc
;
118 bus_space_handle_t ioh
;
125 int ncodecs
; /* number of codecs */
126 int codecno
; /* index of the using codec */
128 azalia_dma_t corb_dma
;
130 azalia_dma_t rirb_dma
;
133 #define UNSOLQ_SIZE 256
134 rirb_entry_t
*unsolq
;
140 int nistreams
, nostreams
, nbstreams
;
147 #define AZ_READ_1(z, r) bus_space_read_1((z)->iot, (z)->ioh, HDA_##r)
148 #define AZ_READ_2(z, r) bus_space_read_2((z)->iot, (z)->ioh, HDA_##r)
149 #define AZ_READ_4(z, r) bus_space_read_4((z)->iot, (z)->ioh, HDA_##r)
150 #define AZ_WRITE_1(z, r, v) bus_space_write_1((z)->iot, (z)->ioh, HDA_##r, v)
151 #define AZ_WRITE_2(z, r, v) bus_space_write_2((z)->iot, (z)->ioh, HDA_##r, v)
152 #define AZ_WRITE_4(z, r, v) bus_space_write_4((z)->iot, (z)->ioh, HDA_##r, v)
156 static int azalia_pci_match(device_t
, cfdata_t
, void *);
157 static void azalia_pci_attach(device_t
, device_t
, void *);
158 static int azalia_pci_detach(device_t
, int);
159 static bool azalia_pci_resume(device_t
, pmf_qual_t
);
160 static void azalia_childdet(device_t
, device_t
);
161 static int azalia_intr(void *);
162 static int azalia_attach(azalia_t
*);
163 static void azalia_attach_intr(device_t
);
164 static int azalia_init_corb(azalia_t
*, int);
165 static int azalia_delete_corb(azalia_t
*);
166 static int azalia_init_rirb(azalia_t
*, int);
167 static int azalia_delete_rirb(azalia_t
*);
168 static int azalia_set_command(const azalia_t
*, nid_t
, int, uint32_t,
170 static int azalia_get_response(azalia_t
*, uint32_t *);
171 static void azalia_rirb_kick_unsol_events(azalia_t
*);
172 static void azalia_rirb_intr(azalia_t
*);
173 static int azalia_alloc_dmamem(azalia_t
*, size_t, size_t, azalia_dma_t
*);
174 static int azalia_free_dmamem(const azalia_t
*, azalia_dma_t
*);
176 static int azalia_codec_init(codec_t
*, int, uint32_t);
177 static int azalia_codec_delete(codec_t
*);
178 static void azalia_codec_add_bits(codec_t
*, int, uint32_t, int);
179 static void azalia_codec_add_format(codec_t
*, int, int, int, uint32_t,
181 static int azalia_codec_comresp(const codec_t
*, nid_t
, uint32_t,
182 uint32_t, uint32_t *);
183 static int azalia_codec_connect_stream(codec_t
*, int, uint16_t, int);
184 static int azalia_codec_disconnect_stream(codec_t
*, int);
186 static int azalia_widget_init(widget_t
*, const codec_t
*, int, const char *);
187 static int azalia_widget_init_audio(widget_t
*, const codec_t
*, const char *);
189 static int azalia_widget_print_audio(const widget_t
*, const char *, int);
191 static int azalia_widget_init_pin(widget_t
*, const codec_t
*);
192 static int azalia_widget_print_pin(const widget_t
*, const char *);
193 static int azalia_widget_init_connection(widget_t
*, const codec_t
*, const char *);
195 static int azalia_stream_init(stream_t
*, azalia_t
*, int, int, int);
196 static int azalia_stream_delete(stream_t
*, azalia_t
*);
197 static int azalia_stream_reset(stream_t
*);
198 static int azalia_stream_start(stream_t
*, void *, void *, int,
199 void (*)(void *), void *, uint16_t);
200 static int azalia_stream_halt(stream_t
*);
201 static int azalia_stream_intr(stream_t
*, uint32_t);
203 static int azalia_open(void *, int);
204 static void azalia_close(void *);
205 static int azalia_query_encoding(void *, audio_encoding_t
*);
206 static int azalia_set_params(void *, int, int, audio_params_t
*,
207 audio_params_t
*, stream_filter_list_t
*, stream_filter_list_t
*);
208 static int azalia_round_blocksize(void *, int, int, const audio_params_t
*);
209 static int azalia_halt_output(void *);
210 static int azalia_halt_input(void *);
211 static int azalia_getdev(void *, struct audio_device
*);
212 static int azalia_set_port(void *, mixer_ctrl_t
*);
213 static int azalia_get_port(void *, mixer_ctrl_t
*);
214 static int azalia_query_devinfo(void *, mixer_devinfo_t
*);
215 static void *azalia_allocm(void *, int, size_t, struct malloc_type
*, int);
216 static void azalia_freem(void *, void *, struct malloc_type
*);
217 static size_t azalia_round_buffersize(void *, int, size_t);
218 static int azalia_get_props(void *);
219 static int azalia_trigger_output(void *, void *, void *, int,
220 void (*)(void *), void *, const audio_params_t
*);
221 static int azalia_trigger_input(void *, void *, void *, int,
222 void (*)(void *), void *, const audio_params_t
*);
224 static int azalia_params2fmt(const audio_params_t
*, uint16_t *);
227 CFATTACH_DECL2_NEW(azalia
, sizeof(azalia_t
),
228 azalia_pci_match
, azalia_pci_attach
, azalia_pci_detach
, NULL
,
229 NULL
, azalia_childdet
);
231 static const struct audio_hw_if azalia_hw_if
= {
235 azalia_query_encoding
,
237 azalia_round_blocksize
,
238 NULL
, /* commit_settings */
239 NULL
, /* init_output */
240 NULL
, /* init_input */
241 NULL
, /* start_output */
242 NULL
, /* satart_inpu */
245 NULL
, /* speaker_ctl */
250 azalia_query_devinfo
,
253 azalia_round_buffersize
,
256 azalia_trigger_output
,
257 azalia_trigger_input
,
258 NULL
, /* dev_ioctl */
259 NULL
, /* powerstate */
262 static const char *pin_colors
[16] = {
263 "unknown", "black", "gray", "blue",
264 "green", "red", "orange", "yellow",
265 "purple", "pink", "col0a", "col0b",
266 "col0c", "col0d", "white", "other"
270 static const char *pin_devices
[16] = {
271 "line-out", AudioNspeaker
, AudioNheadphone
, AudioNcd
,
272 "SPDIF-out", "digital-out", "modem-line", "modem-handset",
273 "line-in", AudioNaux
, AudioNmicrophone
, "telephony",
274 "SPDIF-in", "digital-in", "dev0e", "other"
278 /* ================================================================
280 * ================================================================ */
283 azalia_pci_match(device_t parent
, cfdata_t match
, void *aux
)
285 struct pci_attach_args
*pa
;
288 if (PCI_CLASS(pa
->pa_class
) == PCI_CLASS_MULTIMEDIA
289 && PCI_SUBCLASS(pa
->pa_class
) == PCI_SUBCLASS_MULTIMEDIA_HDAUDIO
)
295 azalia_pci_attach(device_t parent
, device_t self
, void *aux
)
297 azalia_t
*sc
= device_private(self
);
298 struct pci_attach_args
*pa
= aux
;
300 pci_intr_handle_t ih
;
301 const char *intrrupt_str
;
306 sc
->dmat
= pa
->pa_dmat
;
308 aprint_normal(": Generic High Definition Audio Controller\n");
310 v
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, ICH_PCI_HDBARL
);
311 v
&= PCI_MAPREG_TYPE_MASK
| PCI_MAPREG_MEM_TYPE_MASK
;
312 if (pci_mapreg_map(pa
, ICH_PCI_HDBARL
, v
, 0,
313 &sc
->iot
, &sc
->ioh
, NULL
, &sc
->map_size
)) {
314 aprint_error_dev(self
, "can't map device i/o space\n");
318 /* enable bus mastering */
319 v
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
320 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
,
321 v
| PCI_COMMAND_MASTER_ENABLE
| PCI_COMMAND_BACKTOBACK_ENABLE
);
324 if (pci_intr_map(pa
, &ih
)) {
325 aprint_error_dev(self
, "can't map interrupt\n");
329 sc
->tag
= pa
->pa_tag
;
330 intrrupt_str
= pci_intr_string(pa
->pa_pc
, ih
);
331 sc
->ih
= pci_intr_establish(pa
->pa_pc
, ih
, IPL_AUDIO
, azalia_intr
, sc
);
332 if (sc
->ih
== NULL
) {
333 aprint_error_dev(self
, "can't establish interrupt");
334 if (intrrupt_str
!= NULL
)
335 aprint_error(" at %s", intrrupt_str
);
339 aprint_normal_dev(self
, "interrupting at %s\n", intrrupt_str
);
341 if (!pmf_device_register(self
, NULL
, azalia_pci_resume
))
342 aprint_error_dev(self
, "couldn't establish power handler\n");
344 sc
->pciid
= pa
->pa_id
;
345 vendor
= pci_findvendor(pa
->pa_id
);
346 name
= pci_findproduct(pa
->pa_id
);
347 if (vendor
!= NULL
&& name
!= NULL
) {
348 aprint_normal_dev(self
, "host: %s %s (rev. %d)",
349 vendor
, name
, PCI_REVISION(pa
->pa_class
));
351 aprint_normal_dev(self
, "host: 0x%4.4x/0x%4.4x (rev. %d)",
352 PCI_VENDOR(pa
->pa_id
), PCI_PRODUCT(pa
->pa_id
),
353 PCI_REVISION(pa
->pa_class
));
356 if (azalia_attach(sc
)) {
357 aprint_error_dev(self
, "initialization failure\n");
358 azalia_pci_detach(self
, 0);
361 sc
->subid
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_SUBSYS_ID_REG
);
363 config_interrupts(self
, azalia_attach_intr
);
367 azalia_childdet(device_t self
, device_t child
)
369 azalia_t
*az
= device_private(self
);
371 KASSERT(az
->audiodev
== child
);
376 azalia_pci_detach(device_t self
, int flags
)
381 DPRINTF(("%s\n", __func__
));
382 az
= device_private(self
);
383 if (az
->audiodev
!= NULL
)
384 config_detach(az
->audiodev
, flags
);
387 DPRINTF(("%s: halt streams\n", __func__
));
388 azalia_stream_halt(&az
->rstream
);
389 azalia_stream_halt(&az
->pstream
);
392 DPRINTF(("%s: delete streams\n", __func__
));
393 azalia_stream_delete(&az
->rstream
, az
);
394 azalia_stream_delete(&az
->pstream
, az
);
396 DPRINTF(("%s: delete codecs\n", __func__
));
397 for (i
= 0; i
< az
->ncodecs
; i
++) {
398 azalia_codec_delete(&az
->codecs
[i
]);
402 DPRINTF(("%s: delete CORB and RIRB\n", __func__
));
403 azalia_delete_corb(az
);
404 azalia_delete_rirb(az
);
406 DPRINTF(("%s: delete PCI resources\n", __func__
));
407 if (az
->ih
!= NULL
) {
408 pci_intr_disestablish(az
->pc
, az
->ih
);
411 if (az
->map_size
!= 0) {
412 bus_space_unmap(az
->iot
, az
->ioh
, az
->map_size
);
419 azalia_pci_resume(device_t dv
, pmf_qual_t qual
)
421 azalia_t
*az
= device_private(dv
);
428 azalia_attach_intr(az
->dev
);
443 if (!device_has_power(az
->dev
))
446 if ((intsts
= AZ_READ_4(az
, INTSTS
)) == 0)
449 ret
= azalia_stream_intr(&az
->pstream
, intsts
) +
450 azalia_stream_intr(&az
->rstream
, intsts
);
452 rirbsts
= AZ_READ_1(az
, RIRBSTS
);
453 if (rirbsts
& (HDA_RIRBSTS_RIRBOIS
| HDA_RIRBSTS_RINTFL
)) {
454 if (rirbsts
& HDA_RIRBSTS_RINTFL
) {
455 azalia_rirb_intr(az
);
457 /*printf("[Overflow!]");*/
459 AZ_WRITE_1(az
, RIRBSTS
,
460 rirbsts
| HDA_RIRBSTS_RIRBOIS
| HDA_RIRBSTS_RINTFL
);
467 /* ================================================================
468 * HDA controller functions
469 * ================================================================ */
472 azalia_attach(azalia_t
*az
)
479 if (az
->audiodev
== NULL
)
480 aprint_normal(", HDA rev. %d.%d\n",
481 AZ_READ_1(az
, VMAJ
), AZ_READ_1(az
, VMIN
));
483 gcap
= AZ_READ_2(az
, GCAP
);
484 az
->nistreams
= HDA_GCAP_ISS(gcap
);
485 az
->nostreams
= HDA_GCAP_OSS(gcap
);
486 az
->nbstreams
= HDA_GCAP_BSS(gcap
);
487 az
->ok64
= (gcap
& HDA_GCAP_64OK
) != 0;
488 DPRINTF(("%s: host: %d output, %d input, and %d bidi streams\n",
489 device_xname(az
->dev
), az
->nostreams
, az
->nistreams
, az
->nbstreams
));
490 if (az
->nistreams
> 0)
491 az
->mode_cap
|= AUMODE_RECORD
;
492 if (az
->nostreams
> 0)
493 az
->mode_cap
|= AUMODE_PLAY
;
495 /* 4.2.2 Starting the High Definition Audio Controller */
496 DPRINTF(("%s: resetting\n", __func__
));
497 gctl
= AZ_READ_4(az
, GCTL
);
498 AZ_WRITE_4(az
, GCTL
, gctl
& ~HDA_GCTL_CRST
);
499 for (i
= 5000; i
>= 0; i
--) {
501 if ((AZ_READ_4(az
, GCTL
) & HDA_GCTL_CRST
) == 0)
504 DPRINTF(("%s: reset counter = %d\n", __func__
, i
));
506 aprint_error_dev(az
->dev
, "reset failure\n");
510 gctl
= AZ_READ_4(az
, GCTL
);
511 AZ_WRITE_4(az
, GCTL
, gctl
| HDA_GCTL_CRST
);
512 for (i
= 5000; i
>= 0; i
--) {
514 if (AZ_READ_4(az
, GCTL
) & HDA_GCTL_CRST
)
517 DPRINTF(("%s: reset counter = %d\n", __func__
, i
));
519 aprint_error_dev(az
->dev
, "reset-exit failure\n");
523 /* enable unsolicited response */
524 gctl
= AZ_READ_4(az
, GCTL
);
525 AZ_WRITE_4(az
, GCTL
, gctl
| HDA_GCTL_UNSOL
);
527 /* 4.3 Codec discovery */
529 statests
= AZ_READ_2(az
, STATESTS
);
530 for (i
= 0, n
= 0; i
< 15; i
++) {
531 if ((statests
>> i
) & 1) {
532 DPRINTF(("%s: found a codec at #%d\n",
533 device_xname(az
->dev
), i
));
534 az
->codecs
[n
].address
= i
;
535 az
->codecs
[n
++].dev
= az
->dev
;
539 if (az
->ncodecs
< 1) {
540 aprint_error_dev(az
->dev
, "No HD-Audio codecs\n");
547 azalia_attach_intr(device_t self
)
550 int err
, i
, c
, reinit
;
552 az
= device_private(self
);
553 reinit
= az
->audiodev
== NULL
? 0 : 1;
555 AZ_WRITE_2(az
, STATESTS
, HDA_STATESTS_SDIWAKE
);
556 AZ_WRITE_1(az
, RIRBSTS
, HDA_RIRBSTS_RINTFL
| HDA_RIRBSTS_RIRBOIS
);
557 AZ_WRITE_4(az
, INTSTS
, HDA_INTSTS_CIS
| HDA_INTSTS_GIS
);
558 AZ_WRITE_4(az
, DPLBASE
, 0);
559 AZ_WRITE_4(az
, DPUBASE
, 0);
561 /* 4.4.1 Command Outbound Ring Buffer */
562 if (azalia_init_corb(az
, reinit
))
564 /* 4.4.2 Response Inbound Ring Buffer */
565 if (azalia_init_rirb(az
, reinit
))
568 AZ_WRITE_4(az
, INTCTL
,
569 AZ_READ_4(az
, INTCTL
) | HDA_INTCTL_CIE
| HDA_INTCTL_GIE
);
572 for (i
= 0; i
< az
->ncodecs
; i
++) {
573 err
= azalia_codec_init(&az
->codecs
[i
], reinit
, az
->subid
);
579 /* Use the first audio codec */
581 DPRINTF(("%s: using the #%d codec\n",
582 device_xname(az
->dev
), az
->codecno
));
583 if (az
->codecs
[c
].dacs
.ngroups
<= 0)
584 az
->mode_cap
&= ~AUMODE_PLAY
;
585 if (az
->codecs
[c
].adcs
.ngroups
<= 0)
586 az
->mode_cap
&= ~AUMODE_RECORD
;
588 /* Use stream#1 and #2. Don't use stream#0. */
590 if (azalia_stream_init(&az
->pstream
, az
, az
->nistreams
+ 0,
593 if (azalia_stream_init(&az
->rstream
, az
, 0, 2, AUMODE_RECORD
))
596 az
->audiodev
= audio_attach_mi(&azalia_hw_if
, az
, az
->dev
);
600 azalia_pci_detach(self
, 0);
605 azalia_init_corb(azalia_t
*az
, int reinit
)
608 uint16_t corbrp
, corbwp
;
609 uint8_t corbsize
, cap
, corbctl
;
612 corbctl
= AZ_READ_1(az
, CORBCTL
);
613 if (corbctl
& HDA_CORBCTL_CORBRUN
) { /* running? */
614 AZ_WRITE_1(az
, CORBCTL
, corbctl
& ~HDA_CORBCTL_CORBRUN
);
615 for (i
= 5000; i
>= 0; i
--) {
617 corbctl
= AZ_READ_1(az
, CORBCTL
);
618 if ((corbctl
& HDA_CORBCTL_CORBRUN
) == 0)
622 aprint_error_dev(az
->dev
, "CORB is running\n");
627 /* determine CORB size */
628 corbsize
= AZ_READ_1(az
, CORBSIZE
);
629 cap
= corbsize
& HDA_CORBSIZE_CORBSZCAP_MASK
;
630 corbsize
&= ~HDA_CORBSIZE_CORBSIZE_MASK
;
631 if (cap
& HDA_CORBSIZE_CORBSZCAP_256
) {
633 corbsize
|= HDA_CORBSIZE_CORBSIZE_256
;
634 } else if (cap
& HDA_CORBSIZE_CORBSZCAP_16
) {
636 corbsize
|= HDA_CORBSIZE_CORBSIZE_16
;
637 } else if (cap
& HDA_CORBSIZE_CORBSZCAP_2
) {
639 corbsize
|= HDA_CORBSIZE_CORBSIZE_2
;
641 aprint_error_dev(az
->dev
, "Invalid CORBSZCAP: 0x%2x\n", cap
);
646 err
= azalia_alloc_dmamem(az
, entries
* sizeof(corb_entry_t
),
649 aprint_error_dev(az
->dev
, "can't allocate CORB buffer\n");
653 AZ_WRITE_4(az
, CORBLBASE
, (uint32_t)AZALIA_DMA_DMAADDR(&az
->corb_dma
));
654 AZ_WRITE_4(az
, CORBUBASE
, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az
->corb_dma
)));
655 AZ_WRITE_1(az
, CORBSIZE
, corbsize
);
656 az
->corb_size
= entries
;
658 DPRINTF(("%s: CORB allocation succeeded.\n", __func__
));
661 corbrp
= AZ_READ_2(az
, CORBRP
);
662 AZ_WRITE_2(az
, CORBRP
, corbrp
| HDA_CORBRP_CORBRPRST
);
663 AZ_WRITE_2(az
, CORBRP
, corbrp
& ~HDA_CORBRP_CORBRPRST
);
664 for (i
= 5000; i
>= 0; i
--) {
666 corbrp
= AZ_READ_2(az
, CORBRP
);
667 if ((corbrp
& HDA_CORBRP_CORBRPRST
) == 0)
671 aprint_error_dev(az
->dev
, "CORBRP reset failure\n");
674 DPRINTF(("%s: CORBWP=%d; size=%d\n", __func__
,
675 AZ_READ_2(az
, CORBRP
) & HDA_CORBRP_CORBRP
, az
->corb_size
));
678 corbwp
= AZ_READ_2(az
, CORBWP
);
679 AZ_WRITE_2(az
, CORBWP
, corbwp
& ~HDA_CORBWP_CORBWP
);
682 corbctl
= AZ_READ_1(az
, CORBCTL
);
683 AZ_WRITE_1(az
, CORBCTL
, corbctl
| HDA_CORBCTL_CORBRUN
);
688 azalia_delete_corb(azalia_t
*az
)
693 if (az
->corb_dma
.addr
== NULL
)
696 corbctl
= AZ_READ_1(az
, CORBCTL
);
697 AZ_WRITE_1(az
, CORBCTL
, corbctl
& ~HDA_CORBCTL_CORBRUN
);
698 for (i
= 5000; i
>= 0; i
--) {
700 corbctl
= AZ_READ_1(az
, CORBCTL
);
701 if ((corbctl
& HDA_CORBCTL_CORBRUN
) == 0)
704 azalia_free_dmamem(az
, &az
->corb_dma
);
709 azalia_init_rirb(azalia_t
*az
, int reinit
)
713 uint8_t rirbsize
, cap
, rirbctl
;
716 rirbctl
= AZ_READ_1(az
, RIRBCTL
);
717 if (rirbctl
& HDA_RIRBCTL_RIRBDMAEN
) { /* running? */
718 AZ_WRITE_1(az
, RIRBCTL
, rirbctl
& ~HDA_RIRBCTL_RIRBDMAEN
);
719 for (i
= 5000; i
>= 0; i
--) {
721 rirbctl
= AZ_READ_1(az
, RIRBCTL
);
722 if ((rirbctl
& HDA_RIRBCTL_RIRBDMAEN
) == 0)
726 aprint_error_dev(az
->dev
, "RIRB is running\n");
731 /* determine RIRB size */
732 rirbsize
= AZ_READ_1(az
, RIRBSIZE
);
733 cap
= rirbsize
& HDA_RIRBSIZE_RIRBSZCAP_MASK
;
734 rirbsize
&= ~HDA_RIRBSIZE_RIRBSIZE_MASK
;
735 if (cap
& HDA_RIRBSIZE_RIRBSZCAP_256
) {
737 rirbsize
|= HDA_RIRBSIZE_RIRBSIZE_256
;
738 } else if (cap
& HDA_RIRBSIZE_RIRBSZCAP_16
) {
740 rirbsize
|= HDA_RIRBSIZE_RIRBSIZE_16
;
741 } else if (cap
& HDA_RIRBSIZE_RIRBSZCAP_2
) {
743 rirbsize
|= HDA_RIRBSIZE_RIRBSIZE_2
;
745 aprint_error_dev(az
->dev
, "Invalid RIRBSZCAP: 0x%2x\n", cap
);
750 err
= azalia_alloc_dmamem(az
, entries
* sizeof(rirb_entry_t
),
753 aprint_error_dev(az
->dev
, "can't allocate RIRB buffer\n");
757 AZ_WRITE_4(az
, RIRBLBASE
, (uint32_t)AZALIA_DMA_DMAADDR(&az
->rirb_dma
));
758 AZ_WRITE_4(az
, RIRBUBASE
, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az
->rirb_dma
)));
759 AZ_WRITE_1(az
, RIRBSIZE
, rirbsize
);
760 az
->rirb_size
= entries
;
762 DPRINTF(("%s: RIRB allocation succeeded.\n", __func__
));
764 /* setup the unsolicited response queue */
767 az
->unsolq_kick
= FALSE
;
769 az
->unsolq
= malloc(sizeof(rirb_entry_t
) * UNSOLQ_SIZE
,
770 M_DEVBUF
, M_ZERO
| M_NOWAIT
);
772 memset(az
->unsolq
, 0, sizeof(rirb_entry_t
) * UNSOLQ_SIZE
);
774 if (az
->unsolq
== NULL
) {
775 aprint_error_dev(az
->dev
, "can't allocate unsolicited response queue.\n");
776 azalia_free_dmamem(az
, &az
->rirb_dma
);
781 rirbctl
= AZ_READ_1(az
, RIRBCTL
);
782 AZ_WRITE_1(az
, RIRBCTL
, rirbctl
& ~HDA_RIRBCTL_RINTCTL
);
785 /* reset the write pointer */
786 rirbwp
= AZ_READ_2(az
, RIRBWP
);
787 AZ_WRITE_2(az
, RIRBWP
, rirbwp
| HDA_RIRBWP_RIRBWPRST
);
789 /* clear the read pointer */
790 az
->rirb_rp
= AZ_READ_2(az
, RIRBWP
) & HDA_RIRBWP_RIRBWP
;
791 DPRINTF(("%s: RIRBRP=%d, size=%d\n", __func__
, az
->rirb_rp
, az
->rirb_size
));
793 AZ_WRITE_2(az
, RINTCNT
, 1);
796 rirbctl
= AZ_READ_1(az
, RIRBCTL
);
797 AZ_WRITE_1(az
, RIRBCTL
, rirbctl
| HDA_RIRBCTL_RIRBDMAEN
| HDA_RIRBCTL_RINTCTL
);
802 azalia_delete_rirb(azalia_t
*az
)
807 if (az
->unsolq
!= NULL
) {
808 free(az
->unsolq
, M_DEVBUF
);
811 if (az
->rirb_dma
.addr
== NULL
)
814 rirbctl
= AZ_READ_1(az
, RIRBCTL
);
815 AZ_WRITE_1(az
, RIRBCTL
, rirbctl
& ~HDA_RIRBCTL_RIRBDMAEN
);
816 for (i
= 5000; i
>= 0; i
--) {
818 rirbctl
= AZ_READ_1(az
, RIRBCTL
);
819 if ((rirbctl
& HDA_RIRBCTL_RIRBDMAEN
) == 0)
822 azalia_free_dmamem(az
, &az
->rirb_dma
);
827 azalia_set_command(const azalia_t
*az
, int caddr
, nid_t nid
, uint32_t control
,
836 if ((AZ_READ_1(az
, CORBCTL
) & HDA_CORBCTL_CORBRUN
) == 0) {
837 aprint_error_dev(az
->dev
, "CORB is not running.\n");
841 verb
= (caddr
<< 28) | (nid
<< 20) | (control
<< 8) | param
;
842 corbwp
= AZ_READ_2(az
, CORBWP
);
843 wp
= corbwp
& HDA_CORBWP_CORBWP
;
844 corb
= (corb_entry_t
*)az
->corb_dma
.addr
;
845 if (++wp
>= az
->corb_size
)
848 AZ_WRITE_2(az
, CORBWP
, (corbwp
& ~HDA_CORBWP_CORBWP
) | wp
);
850 DPRINTF(("%s: caddr=%d nid=%d control=0x%x param=0x%x verb=0x%8.8x wp=%d\n",
851 __func__
, caddr
, nid
, control
, param
, verb
, wp
));
857 azalia_get_response(azalia_t
*az
, uint32_t *result
)
859 const rirb_entry_t
*rirb
;
864 if ((AZ_READ_1(az
, RIRBCTL
) & HDA_RIRBCTL_RIRBDMAEN
) == 0) {
865 aprint_error_dev(az
->dev
, "RIRB is not running.\n");
869 for (i
= 5000; i
>= 0; i
--) {
870 wp
= AZ_READ_2(az
, RIRBWP
) & HDA_RIRBWP_RIRBWP
;
871 if (az
->rirb_rp
!= wp
)
876 aprint_error_dev(az
->dev
, "RIRB time out\n");
879 rirb
= (rirb_entry_t
*)az
->rirb_dma
.addr
;
881 if (++az
->rirb_rp
>= az
->rirb_size
)
883 if (rirb
[az
->rirb_rp
].resp_ex
& RIRB_RESP_UNSOL
) {
884 az
->unsolq
[az
->unsolq_wp
].resp
= rirb
[az
->rirb_rp
].resp
;
885 az
->unsolq
[az
->unsolq_wp
++].resp_ex
= rirb
[az
->rirb_rp
].resp_ex
;
886 az
->unsolq_wp
%= UNSOLQ_SIZE
;
891 *result
= rirb
[az
->rirb_rp
].resp
;
892 azalia_rirb_kick_unsol_events(az
);
894 DPRINTF(("%s: rirbwp=%d rp=%d resp1=0x%8.8x resp2=0x%8.8x\n",
895 __func__
, wp
, az
->rirb_rp
, rirb
[az
->rirb_rp
].resp
,
896 rirb
[az
->rirb_rp
].resp_ex
));
897 for (i
= 0; i
< 16 /*az->rirb_size*/; i
++) {
898 DPRINTF(("rirb[%d] 0x%8.8x:0x%8.8x ", i
, rirb
[i
].resp
, rirb
[i
].resp_ex
));
907 azalia_rirb_kick_unsol_events(azalia_t
*az
)
911 az
->unsolq_kick
= TRUE
;
912 while (az
->unsolq_rp
!= az
->unsolq_wp
) {
916 i
= RIRB_RESP_CODEC(az
->unsolq
[az
->unsolq_rp
].resp_ex
);
917 tag
= RIRB_UNSOL_TAG(az
->unsolq
[az
->unsolq_rp
].resp
);
918 codec
= &az
->codecs
[i
];
919 DPRINTF(("%s: codec#=%d tag=%d\n", __func__
, i
, tag
));
921 az
->unsolq_rp
%= UNSOLQ_SIZE
;
922 if (codec
->unsol_event
!= NULL
)
923 codec
->unsol_event(codec
, tag
);
925 az
->unsolq_kick
= FALSE
;
929 azalia_rirb_intr(azalia_t
*az
)
931 const rirb_entry_t
*rirb
;
934 wp
= AZ_READ_2(az
, RIRBWP
) & HDA_RIRBWP_RIRBWP
;
935 if (az
->rirb_rp
== wp
)
936 return; /* interrupted but no data in RIRB */
937 /* Copy the first sequence of unsolicited reponses in the RIRB to
938 * unsolq. Don't consume non-unsolicited responses. */
939 rirb
= (rirb_entry_t
*)az
->rirb_dma
.addr
;
940 while (az
->rirb_rp
!= wp
) {
941 newrp
= az
->rirb_rp
+ 1;
942 if (newrp
>= az
->rirb_size
)
944 if (rirb
[newrp
].resp_ex
& RIRB_RESP_UNSOL
) {
945 az
->unsolq
[az
->unsolq_wp
].resp
= rirb
[newrp
].resp
;
946 az
->unsolq
[az
->unsolq_wp
++].resp_ex
= rirb
[newrp
].resp_ex
;
947 az
->unsolq_wp
%= UNSOLQ_SIZE
;
953 azalia_rirb_kick_unsol_events(az
);
957 azalia_alloc_dmamem(azalia_t
*az
, size_t size
, size_t align
, azalia_dma_t
*d
)
963 err
= bus_dmamem_alloc(az
->dmat
, size
, align
, 0, d
->segments
, 1,
964 &nsegs
, BUS_DMA_NOWAIT
);
969 err
= bus_dmamem_map(az
->dmat
, d
->segments
, 1, size
,
970 &d
->addr
, BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
| BUS_DMA_NOCACHE
);
973 err
= bus_dmamap_create(az
->dmat
, size
, 1, size
, 0,
974 BUS_DMA_NOWAIT
, &d
->map
);
977 err
= bus_dmamap_load(az
->dmat
, d
->map
, d
->addr
, size
,
978 NULL
, BUS_DMA_NOWAIT
);
982 if (!az
->ok64
&& PTR_UPPER32(AZALIA_DMA_DMAADDR(d
)) != 0) {
983 azalia_free_dmamem(az
, d
);
989 bus_dmamap_destroy(az
->dmat
, d
->map
);
991 bus_dmamem_unmap(az
->dmat
, d
->addr
, size
);
993 bus_dmamem_free(az
->dmat
, d
->segments
, 1);
999 azalia_free_dmamem(const azalia_t
*az
, azalia_dma_t
* d
)
1001 if (d
->addr
== NULL
)
1003 bus_dmamap_unload(az
->dmat
, d
->map
);
1004 bus_dmamap_destroy(az
->dmat
, d
->map
);
1005 bus_dmamem_unmap(az
->dmat
, d
->addr
, d
->size
);
1006 bus_dmamem_free(az
->dmat
, d
->segments
, 1);
1011 /* ================================================================
1012 * HDA coodec functions
1013 * ================================================================ */
1016 azalia_codec_init(codec_t
*this, int reinit
, uint32_t subid
)
1018 #define LEAD_LEN 100
1019 char lead
[LEAD_LEN
];
1020 uint32_t rev
, id
, result
;
1021 int err
, addr
, n
, i
;
1023 this->comresp
= azalia_codec_comresp
;
1024 addr
= this->address
;
1025 DPRINTF(("%s: information of codec[%d] follows:\n",
1026 device_xname(this->dev
), addr
));
1027 /* codec vendor/device/revision */
1028 err
= this->comresp(this, CORB_NID_ROOT
, CORB_GET_PARAMETER
,
1029 COP_REVISION_ID
, &rev
);
1032 err
= this->comresp(this, CORB_NID_ROOT
, CORB_GET_PARAMETER
,
1033 COP_VENDOR_ID
, &id
);
1037 this->subid
= subid
;
1040 err
= azalia_codec_init_vtbl(this);
1046 aprint_normal("%s: codec[%d]: ", device_xname(this->dev
), addr
);
1047 if (this->name
== NULL
) {
1048 aprint_normal("0x%4.4x/0x%4.4x (rev. %u.%u)",
1049 id
>> 16, id
& 0xffff,
1050 COP_RID_REVISION(rev
), COP_RID_STEPPING(rev
));
1052 aprint_normal("%s (rev. %u.%u)", this->name
,
1053 COP_RID_REVISION(rev
), COP_RID_STEPPING(rev
));
1055 aprint_normal(", HDA rev. %u.%u\n",
1056 COP_RID_MAJ(rev
), COP_RID_MIN(rev
));
1059 /* identify function nodes */
1060 err
= this->comresp(this, CORB_NID_ROOT
, CORB_GET_PARAMETER
,
1061 COP_SUBORDINATE_NODE_COUNT
, &result
);
1064 this->nfunctions
= COP_NSUBNODES(result
);
1065 if (COP_NSUBNODES(result
) <= 0) {
1066 aprint_error("%s: No function groups\n",
1067 device_xname(this->dev
));
1070 /* iterate function nodes and find an audio function */
1071 n
= COP_START_NID(result
);
1072 DPRINTF(("%s: nidstart=%d #functions=%d\n",
1073 __func__
, n
, this->nfunctions
));
1074 this->audiofunc
= -1;
1075 for (i
= 0; i
< this->nfunctions
; i
++) {
1076 err
= this->comresp(this, n
+ i
, CORB_GET_PARAMETER
,
1077 COP_FUNCTION_GROUP_TYPE
, &result
);
1080 DPRINTF(("%s: FTYPE result = 0x%8.8x\n", __func__
, result
));
1081 if (COP_FTYPE(result
) == COP_FTYPE_AUDIO
) {
1082 this->audiofunc
= n
+ i
;
1083 break; /* XXX multiple audio functions? */
1084 } else if (COP_FTYPE(result
) == COP_FTYPE_MODEM
&& !reinit
) {
1085 aprint_normal("%s: codec[%d]: No support for modem "
1086 "function groups\n",
1087 device_xname(this->dev
), addr
);
1090 if (this->audiofunc
< 0 && !reinit
) {
1091 aprint_verbose("%s: codec[%d] has no audio function groups\n",
1092 device_xname(this->dev
), addr
);
1096 /* power the audio function */
1097 this->comresp(this, this->audiofunc
, CORB_SET_POWER_STATE
, CORB_PS_D0
, &result
);
1100 /* check widgets in the audio function */
1101 err
= this->comresp(this, this->audiofunc
,
1102 CORB_GET_PARAMETER
, COP_SUBORDINATE_NODE_COUNT
, &result
);
1105 DPRINTF(("%s: There are %d widgets in the audio function.\n",
1106 __func__
, COP_NSUBNODES(result
)));
1107 this->wstart
= COP_START_NID(result
);
1108 if (this->wstart
< 2) {
1110 aprint_error("%s: invalid node structure\n",
1111 device_xname(this->dev
));
1114 this->wend
= this->wstart
+ COP_NSUBNODES(result
);
1116 this->w
= malloc(sizeof(widget_t
) * this->wend
, M_DEVBUF
,
1118 if (this->w
== NULL
) {
1119 aprint_error("%s: out of memory\n",
1120 device_xname(this->dev
));
1124 memset(this->w
, 0, sizeof(widget_t
) * this->wend
);
1126 /* query the base parameters */
1127 this->comresp(this, this->audiofunc
, CORB_GET_PARAMETER
,
1128 COP_STREAM_FORMATS
, &result
);
1129 this->w
[this->audiofunc
].d
.audio
.encodings
= result
;
1130 this->comresp(this, this->audiofunc
, CORB_GET_PARAMETER
,
1132 this->w
[this->audiofunc
].d
.audio
.bits_rates
= result
;
1133 this->comresp(this, this->audiofunc
, CORB_GET_PARAMETER
,
1134 COP_INPUT_AMPCAP
, &result
);
1135 this->w
[this->audiofunc
].inamp_cap
= result
;
1136 this->comresp(this, this->audiofunc
, CORB_GET_PARAMETER
,
1137 COP_OUTPUT_AMPCAP
, &result
);
1138 this->w
[this->audiofunc
].outamp_cap
= result
;
1141 snprintf(lead
, LEAD_LEN
, "%s: ", device_xname(this->dev
));
1142 azalia_widget_print_audio(&this->w
[this->audiofunc
], lead
, -1);
1143 result
= this->w
[this->audiofunc
].inamp_cap
;
1144 DPRINTF(("%sinamp: mute=%u size=%u steps=%u offset=%u\n", lead
,
1145 (result
& COP_AMPCAP_MUTE
) != 0, COP_AMPCAP_STEPSIZE(result
),
1146 COP_AMPCAP_NUMSTEPS(result
), COP_AMPCAP_OFFSET(result
)));
1147 result
= this->w
[this->audiofunc
].outamp_cap
;
1148 DPRINTF(("%soutamp: mute=%u size=%u steps=%u offset=%u\n", lead
,
1149 (result
& COP_AMPCAP_MUTE
) != 0, COP_AMPCAP_STEPSIZE(result
),
1150 COP_AMPCAP_NUMSTEPS(result
), COP_AMPCAP_OFFSET(result
)));
1153 strlcpy(this->w
[CORB_NID_ROOT
].name
, "root",
1154 sizeof(this->w
[CORB_NID_ROOT
].name
));
1155 strlcpy(this->w
[this->audiofunc
].name
, "hdaudio",
1156 sizeof(this->w
[this->audiofunc
].name
));
1157 FOR_EACH_WIDGET(this, i
) {
1158 err
= azalia_widget_init(&this->w
[i
], this, i
, lead
);
1162 #if defined(AZALIA_DEBUG) && defined(AZALIA_DEBUG_DOT)
1163 DPRINTF(("-------- Graphviz DOT starts\n"));
1164 if (this->name
== NULL
) {
1165 DPRINTF(("digraph \"0x%4.4x/0x%4.4x (rev. %u.%u)\" {\n",
1166 id
>> 16, id
& 0xffff,
1167 COP_RID_REVISION(rev
), COP_RID_STEPPING(rev
)));
1169 DPRINTF(("digraph \"%s (rev. %u.%u)\" {\n", this->name
,
1170 COP_RID_REVISION(rev
), COP_RID_STEPPING(rev
)));
1172 FOR_EACH_WIDGET(this, i
) {
1177 case COP_AWTYPE_AUDIO_OUTPUT
:
1178 DPRINTF((" %s [shape=box,style=filled,fillcolor=\""
1179 "#88ff88\"];\n", w
->name
));
1181 case COP_AWTYPE_AUDIO_INPUT
:
1182 DPRINTF((" %s [shape=box,style=filled,fillcolor=\""
1183 "#ff8888\"];\n", w
->name
));
1185 case COP_AWTYPE_AUDIO_MIXER
:
1186 DPRINTF((" %s [shape=invhouse];\n", w
->name
));
1188 case COP_AWTYPE_AUDIO_SELECTOR
:
1189 DPRINTF((" %s [shape=invtrapezium];\n", w
->name
));
1191 case COP_AWTYPE_PIN_COMPLEX
:
1192 DPRINTF((" %s [label=\"%s\\ndevice=%s\",style=filled",
1193 w
->name
, w
->name
, pin_devices
[w
->d
.pin
.device
]));
1194 if (w
->d
.pin
.cap
& COP_PINCAP_OUTPUT
&&
1195 w
->d
.pin
.cap
& COP_PINCAP_INPUT
)
1196 DPRINTF((",shape=doublecircle,fillcolor=\""
1198 else if (w
->d
.pin
.cap
& COP_PINCAP_OUTPUT
)
1199 DPRINTF((",shape=circle,fillcolor=\"#88ff88\"];\n"));
1201 DPRINTF((",shape=circle,fillcolor=\"#ff8888\"];\n"));
1204 if ((w
->widgetcap
& COP_AWCAP_CONNLIST
) == 0)
1206 for (j
= 0; j
< w
->nconnections
; j
++) {
1207 int src
= w
->connections
[j
];
1208 if (!VALID_WIDGET_NID(src
, this))
1210 DPRINTF((" %s -> %s [sametail=%s];\n",
1211 this->w
[src
].name
, w
->name
, this->w
[src
].name
));
1215 DPRINTF((" {rank=min;"));
1216 FOR_EACH_WIDGET(this, i
) {
1220 case COP_AWTYPE_AUDIO_OUTPUT
:
1221 case COP_AWTYPE_AUDIO_INPUT
:
1222 DPRINTF((" %s;", w
->name
));
1228 DPRINTF((" {rank=max;"));
1229 FOR_EACH_WIDGET(this, i
) {
1233 case COP_AWTYPE_PIN_COMPLEX
:
1234 DPRINTF((" %s;", w
->name
));
1241 DPRINTF(("-------- Graphviz DOT ends\n"));
1242 #endif /* AZALIA_DEBUG && AZALIA_DEBUG_DOT */
1244 err
= this->init_dacgroup(this);
1248 for (i
= 0; i
< this->dacs
.ngroups
; i
++) {
1249 DPRINTF(("%s: dacgroup[%d]:", __func__
, i
));
1250 for (n
= 0; n
< this->dacs
.groups
[i
].nconv
; n
++) {
1251 DPRINTF((" %2.2x", this->dacs
.groups
[i
].conv
[n
]));
1257 /* set invalid values for azalia_codec_construct_format() to work */
1258 this->dacs
.cur
= -1;
1259 this->adcs
.cur
= -1;
1260 err
= azalia_codec_construct_format(this,
1261 this->dacs
.ngroups
> 0 ? 0 : -1,
1262 this->adcs
.ngroups
> 0 ? 0 : -1);
1266 return this->mixer_init(this);
1270 azalia_codec_delete(codec_t
*this)
1272 if (this->mixer_delete
!= NULL
)
1273 this->mixer_delete(this);
1274 if (this->formats
!= NULL
) {
1275 free(this->formats
, M_DEVBUF
);
1276 this->formats
= NULL
;
1278 auconv_delete_encodings(this->encodings
);
1279 this->encodings
= NULL
;
1280 if (this->extra
!= NULL
) {
1281 free(this->extra
, M_DEVBUF
);
1288 azalia_codec_construct_format(codec_t
*this, int newdac
, int newadc
)
1291 char flagbuf
[FLAGBUFLEN
];
1293 const convgroup_t
*group
;
1294 uint32_t bits_rates
;
1295 int prev_dac
, prev_adc
;
1297 int nbits
, c
, chan
, i
, err
;
1303 prev_dac
= this->dacs
.cur
;
1304 if (newdac
>= 0 && newdac
< this->dacs
.ngroups
) {
1305 this->dacs
.cur
= newdac
;
1306 group
= &this->dacs
.groups
[this->dacs
.cur
];
1307 bits_rates
= this->w
[group
->conv
[0]].d
.audio
.bits_rates
;
1309 if (bits_rates
& COP_PCM_B8
)
1311 if (bits_rates
& COP_PCM_B16
)
1313 if (bits_rates
& COP_PCM_B20
)
1315 if (bits_rates
& COP_PCM_B24
)
1317 if (bits_rates
& COP_PCM_B32
)
1320 aprint_error("%s: invalid PCM format: 0x%8.8x\n",
1321 device_xname(this->dev
), bits_rates
);
1324 variation
= group
->nconv
* nbits
;
1327 prev_adc
= this->adcs
.cur
;
1328 if (newadc
>= 0 && newadc
< this->adcs
.ngroups
) {
1329 this->adcs
.cur
= newadc
;
1330 group
= &this->adcs
.groups
[this->adcs
.cur
];
1331 bits_rates
= this->w
[group
->conv
[0]].d
.audio
.bits_rates
;
1333 if (bits_rates
& COP_PCM_B8
)
1335 if (bits_rates
& COP_PCM_B16
)
1337 if (bits_rates
& COP_PCM_B20
)
1339 if (bits_rates
& COP_PCM_B24
)
1341 if (bits_rates
& COP_PCM_B32
)
1344 aprint_error("%s: invalid PCM format: 0x%8.8x\n",
1345 device_xname(this->dev
), bits_rates
);
1348 variation
+= group
->nconv
* nbits
;
1351 if (this->formats
!= NULL
)
1352 free(this->formats
, M_DEVBUF
);
1354 this->formats
= malloc(sizeof(struct audio_format
) * variation
,
1355 M_DEVBUF
, M_ZERO
| M_NOWAIT
);
1356 if (this->formats
== NULL
) {
1357 aprint_error("%s: out of memory in %s\n",
1358 device_xname(this->dev
), __func__
);
1362 /* register formats for playback */
1363 if (this->dacs
.cur
>= 0 && this->dacs
.cur
< this->dacs
.ngroups
) {
1364 group
= &this->dacs
.groups
[this->dacs
.cur
];
1365 for (c
= 0; c
< group
->nconv
; c
++) {
1368 for (i
= 0; i
<= c
; i
++) {
1369 nid
= group
->conv
[i
];
1370 chan
+= WIDGET_CHANNELS(&this->w
[nid
]);
1371 bits_rates
&= this->w
[nid
].d
.audio
.bits_rates
;
1373 azalia_codec_add_bits(this, chan
,
1374 bits_rates
, AUMODE_PLAY
);
1377 /* print playback capability */
1378 if (prev_dac
!= this->dacs
.cur
) {
1379 snprintf(flagbuf
, FLAGBUFLEN
, "%s: playback: ",
1380 device_xname(this->dev
));
1381 azalia_widget_print_audio(&this->w
[group
->conv
[0]],
1387 /* register formats for recording */
1388 if (this->adcs
.cur
>= 0 && this->adcs
.cur
< this->adcs
.ngroups
) {
1389 group
= &this->adcs
.groups
[this->adcs
.cur
];
1390 for (c
= 0; c
< group
->nconv
; c
++) {
1393 for (i
= 0; i
<= c
; i
++) {
1394 nid
= group
->conv
[i
];
1395 chan
+= WIDGET_CHANNELS(&this->w
[nid
]);
1396 bits_rates
&= this->w
[nid
].d
.audio
.bits_rates
;
1398 azalia_codec_add_bits(this, chan
,
1399 bits_rates
, AUMODE_RECORD
);
1402 /* print recording capability */
1403 if (prev_adc
!= this->adcs
.cur
) {
1404 snprintf(flagbuf
, FLAGBUFLEN
, "%s: recording: ",
1405 device_xname(this->dev
));
1406 azalia_widget_print_audio(&this->w
[group
->conv
[0]],
1413 if (this->nformats
> variation
) {
1414 aprint_error("%s: Internal error: the format buffer is too small: "
1415 "nformats=%d variation=%d\n", device_xname(this->dev
),
1416 this->nformats
, variation
);
1421 err
= auconv_create_encodings(this->formats
, this->nformats
,
1429 azalia_codec_add_bits(codec_t
*this, int chan
, uint32_t bits_rates
, int mode
)
1431 if (bits_rates
& COP_PCM_B8
)
1432 azalia_codec_add_format(this, chan
, 8, 16, bits_rates
, mode
);
1433 if (bits_rates
& COP_PCM_B16
)
1434 azalia_codec_add_format(this, chan
, 16, 16, bits_rates
, mode
);
1435 if (bits_rates
& COP_PCM_B20
)
1436 azalia_codec_add_format(this, chan
, 20, 32, bits_rates
, mode
);
1437 if (bits_rates
& COP_PCM_B24
)
1438 azalia_codec_add_format(this, chan
, 24, 32, bits_rates
, mode
);
1439 if (bits_rates
& COP_PCM_B32
)
1440 azalia_codec_add_format(this, chan
, 32, 32, bits_rates
, mode
);
1444 azalia_codec_add_format(codec_t
*this, int chan
, int valid
, int prec
,
1445 uint32_t rates
, int32_t mode
)
1447 struct audio_format
*f
;
1449 f
= &this->formats
[this->nformats
++];
1451 f
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
1452 if (valid
== 8 && prec
== 8)
1453 f
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
1454 f
->validbits
= valid
;
1455 f
->precision
= prec
;
1459 f
->channel_mask
= AUFMT_MONAURAL
;
1462 f
->channel_mask
= AUFMT_STEREO
;
1465 f
->channel_mask
= AUFMT_SURROUND4
;
1468 f
->channel_mask
= AUFMT_DOLBY_5_1
;
1471 f
->channel_mask
= AUFMT_DOLBY_5_1
1472 | AUFMT_SIDE_LEFT
| AUFMT_SIDE_RIGHT
;
1475 f
->channel_mask
= 0;
1477 f
->frequency_type
= 0;
1478 if (rates
& COP_PCM_R80
)
1479 f
->frequency
[f
->frequency_type
++] = 8000;
1480 if (rates
& COP_PCM_R110
)
1481 f
->frequency
[f
->frequency_type
++] = 11025;
1482 if (rates
& COP_PCM_R160
)
1483 f
->frequency
[f
->frequency_type
++] = 16000;
1484 if (rates
& COP_PCM_R220
)
1485 f
->frequency
[f
->frequency_type
++] = 22050;
1486 if (rates
& COP_PCM_R320
)
1487 f
->frequency
[f
->frequency_type
++] = 32000;
1488 if (rates
& COP_PCM_R441
)
1489 f
->frequency
[f
->frequency_type
++] = 44100;
1490 if (rates
& COP_PCM_R480
)
1491 f
->frequency
[f
->frequency_type
++] = 48000;
1492 if (rates
& COP_PCM_R882
)
1493 f
->frequency
[f
->frequency_type
++] = 88200;
1494 if (rates
& COP_PCM_R960
)
1495 f
->frequency
[f
->frequency_type
++] = 96000;
1496 if (rates
& COP_PCM_R1764
)
1497 f
->frequency
[f
->frequency_type
++] = 176400;
1498 if (rates
& COP_PCM_R1920
)
1499 f
->frequency
[f
->frequency_type
++] = 192000;
1500 if (rates
& COP_PCM_R3840
)
1501 f
->frequency
[f
->frequency_type
++] = 384000;
1505 azalia_codec_comresp(const codec_t
*codec
, nid_t nid
, uint32_t control
,
1506 uint32_t param
, uint32_t* result
)
1508 azalia_t
*az
= device_private(codec
->dev
);
1512 err
= azalia_set_command(az
, codec
->address
, nid
, control
, param
);
1515 err
= azalia_get_response(az
, result
);
1522 azalia_codec_connect_stream(codec_t
*this, int dir
, uint16_t fmt
, int number
)
1524 const convgroup_t
*group
;
1526 int i
, err
, startchan
, nchan
;
1530 DPRINTF(("%s: fmt=0x%4.4x number=%d\n", __func__
, fmt
, number
));
1532 if (dir
== AUMODE_RECORD
)
1533 group
= &this->adcs
.groups
[this->adcs
.cur
];
1535 group
= &this->dacs
.groups
[this->dacs
.cur
];
1536 flag222
= group
->nconv
>= 3 &&
1537 (WIDGET_CHANNELS(&this->w
[group
->conv
[0]]) == 2) &&
1538 (WIDGET_CHANNELS(&this->w
[group
->conv
[1]]) == 2) &&
1539 (WIDGET_CHANNELS(&this->w
[group
->conv
[2]]) == 2);
1540 nchan
= (fmt
& HDA_SD_FMT_CHAN
) + 1;
1542 for (i
= 0; i
< group
->nconv
; i
++) {
1543 uint32_t stream_chan
;
1544 nid
= group
->conv
[i
];
1546 /* surround and c/lfe handling */
1547 if (nchan
>= 6 && flag222
&& i
== 1) {
1548 nid
= group
->conv
[2];
1549 } else if (nchan
>= 6 && flag222
&& i
== 2) {
1550 nid
= group
->conv
[1];
1553 err
= this->comresp(this, nid
, CORB_SET_CONVERTER_FORMAT
, fmt
, NULL
);
1556 stream_chan
= (number
<< 4) | startchan
;
1557 if (startchan
>= nchan
)
1558 stream_chan
= 0; /* stream#0 */
1559 err
= this->comresp(this, nid
, CORB_SET_CONVERTER_STREAM_CHANNEL
,
1563 if (this->w
[nid
].widgetcap
& COP_AWCAP_DIGITAL
) {
1565 this->comresp(this, nid
, CORB_GET_DIGITAL_CONTROL
,
1567 v
= (v
& 0xff) | CORB_DCC_DIGEN
;
1568 this->comresp(this, nid
, CORB_SET_DIGITAL_CONTROL_L
,
1571 startchan
+= WIDGET_CHANNELS(&this->w
[nid
]);
1575 DPRINTF(("%s: leave with %d\n", __func__
, err
));
1580 azalia_codec_disconnect_stream(codec_t
*this, int dir
)
1582 const convgroup_t
*group
;
1587 if (dir
== AUMODE_RECORD
)
1588 group
= &this->adcs
.groups
[this->adcs
.cur
];
1590 group
= &this->dacs
.groups
[this->dacs
.cur
];
1591 for (i
= 0; i
< group
->nconv
; i
++) {
1592 nid
= group
->conv
[i
];
1593 this->comresp(this, nid
, CORB_SET_CONVERTER_STREAM_CHANNEL
,
1594 0, NULL
); /* stream#0 */
1595 if (this->w
[nid
].widgetcap
& COP_AWCAP_DIGITAL
) {
1596 /* disable S/PDIF */
1597 this->comresp(this, nid
, CORB_GET_DIGITAL_CONTROL
, 0, &v
);
1598 v
= (v
& ~CORB_DCC_DIGEN
) & 0xff;
1599 this->comresp(this, nid
, CORB_SET_DIGITAL_CONTROL_L
, v
, NULL
);
1605 /* ================================================================
1606 * HDA widget functions
1607 * ================================================================ */
1610 azalia_widget_init(widget_t
*this, const codec_t
*codec
,
1611 nid_t nid
, const char *lead
)
1613 char flagbuf
[FLAGBUFLEN
];
1617 err
= codec
->comresp(codec
, nid
, CORB_GET_PARAMETER
,
1618 COP_AUDIO_WIDGET_CAP
, &result
);
1622 this->widgetcap
= result
;
1623 this->type
= COP_AWCAP_TYPE(result
);
1624 snprintb(flagbuf
, sizeof(flagbuf
),
1625 "\20\014LRSWAP\013POWER\012DIGITAL"
1626 "\011CONNLIST\010UNSOL\07PROC\06STRIPE\05FORMATOV\04AMPOV\03OUTAMP"
1627 "\02INAMP\01STEREO", this->widgetcap
);
1628 DPRINTF(("%s: ", device_xname(codec
->dev
)));
1629 if (this->widgetcap
& COP_AWCAP_POWER
) {
1630 codec
->comresp(codec
, nid
, CORB_SET_POWER_STATE
, CORB_PS_D0
, &result
);
1633 switch (this->type
) {
1634 case COP_AWTYPE_AUDIO_OUTPUT
:
1635 snprintf(this->name
, sizeof(this->name
), "dac%2.2x", nid
);
1636 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1637 azalia_widget_init_audio(this, codec
, lead
);
1639 case COP_AWTYPE_AUDIO_INPUT
:
1640 snprintf(this->name
, sizeof(this->name
), "adc%2.2x", nid
);
1641 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1642 azalia_widget_init_audio(this, codec
, lead
);
1644 case COP_AWTYPE_AUDIO_MIXER
:
1645 snprintf(this->name
, sizeof(this->name
), "mix%2.2x", nid
);
1646 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1648 case COP_AWTYPE_AUDIO_SELECTOR
:
1649 snprintf(this->name
, sizeof(this->name
), "sel%2.2x", nid
);
1650 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1652 case COP_AWTYPE_PIN_COMPLEX
:
1653 azalia_widget_init_pin(this, codec
);
1654 snprintf(this->name
, sizeof(this->name
), "%s%2.2x",
1655 pin_colors
[this->d
.pin
.color
], nid
);
1656 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1657 azalia_widget_print_pin(this, lead
);
1659 case COP_AWTYPE_POWER
:
1660 snprintf(this->name
, sizeof(this->name
), "pow%2.2x", nid
);
1661 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1663 case COP_AWTYPE_VOLUME_KNOB
:
1664 snprintf(this->name
, sizeof(this->name
), "volume%2.2x", nid
);
1665 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1666 err
= codec
->comresp(codec
, nid
, CORB_GET_PARAMETER
,
1667 COP_VOLUME_KNOB_CAPABILITIES
, &result
);
1669 this->d
.volume
.cap
= result
;
1670 DPRINTF(("%sdelta=%d steps=%d\n", lead
,
1671 !!(result
& COP_VKCAP_DELTA
),
1672 COP_VKCAP_NUMSTEPS(result
)));
1675 case COP_AWTYPE_BEEP_GENERATOR
:
1676 snprintf(this->name
, sizeof(this->name
), "beep%2.2x", nid
);
1677 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1680 snprintf(this->name
, sizeof(this->name
), "widget%2.2x", nid
);
1681 DPRINTF(("%s wcap=%s\n", this->name
, flagbuf
));
1684 azalia_widget_init_connection(this, codec
, lead
);
1686 /* amplifier information */
1687 if (this->widgetcap
& COP_AWCAP_INAMP
) {
1688 if (this->widgetcap
& COP_AWCAP_AMPOV
)
1689 codec
->comresp(codec
, nid
, CORB_GET_PARAMETER
,
1690 COP_INPUT_AMPCAP
, &this->inamp_cap
);
1692 this->inamp_cap
= codec
->w
[codec
->audiofunc
].inamp_cap
;
1693 DPRINTF(("%sinamp: mute=%u size=%u steps=%u offset=%u\n",
1694 lead
, (this->inamp_cap
& COP_AMPCAP_MUTE
) != 0,
1695 COP_AMPCAP_STEPSIZE(this->inamp_cap
),
1696 COP_AMPCAP_NUMSTEPS(this->inamp_cap
),
1697 COP_AMPCAP_OFFSET(this->inamp_cap
)));
1699 if (this->widgetcap
& COP_AWCAP_OUTAMP
) {
1700 if (this->widgetcap
& COP_AWCAP_AMPOV
)
1701 codec
->comresp(codec
, nid
, CORB_GET_PARAMETER
,
1702 COP_OUTPUT_AMPCAP
, &this->outamp_cap
);
1704 this->outamp_cap
= codec
->w
[codec
->audiofunc
].outamp_cap
;
1705 DPRINTF(("%soutamp: mute=%u size=%u steps=%u offset=%u\n",
1706 lead
, (this->outamp_cap
& COP_AMPCAP_MUTE
) != 0,
1707 COP_AMPCAP_STEPSIZE(this->outamp_cap
),
1708 COP_AMPCAP_NUMSTEPS(this->outamp_cap
),
1709 COP_AMPCAP_OFFSET(this->outamp_cap
)));
1711 if (codec
->init_widget
!= NULL
)
1712 codec
->init_widget(codec
, this, nid
);
1717 azalia_widget_init_audio(widget_t
*this, const codec_t
*codec
, const char *lead
)
1722 /* check audio format */
1723 if (this->widgetcap
& COP_AWCAP_FORMATOV
) {
1724 err
= codec
->comresp(codec
, this->nid
,
1725 CORB_GET_PARAMETER
, COP_STREAM_FORMATS
, &result
);
1728 this->d
.audio
.encodings
= result
;
1729 if (result
== 0) { /* quirk for CMI9880.
1730 * This must not occuur usually... */
1731 this->d
.audio
.encodings
=
1732 codec
->w
[codec
->audiofunc
].d
.audio
.encodings
;
1733 this->d
.audio
.bits_rates
=
1734 codec
->w
[codec
->audiofunc
].d
.audio
.bits_rates
;
1736 if ((result
& COP_STREAM_FORMAT_PCM
) == 0) {
1737 aprint_error("%s: %s: No PCM support: %x\n",
1738 device_xname(codec
->dev
), this->name
, result
);
1741 err
= codec
->comresp(codec
, this->nid
, CORB_GET_PARAMETER
,
1745 this->d
.audio
.bits_rates
= result
;
1748 this->d
.audio
.encodings
=
1749 codec
->w
[codec
->audiofunc
].d
.audio
.encodings
;
1750 this->d
.audio
.bits_rates
=
1751 codec
->w
[codec
->audiofunc
].d
.audio
.bits_rates
;
1754 azalia_widget_print_audio(this, lead
, -1);
1761 azalia_widget_print_audio(const widget_t
*this, const char *lead
, int channels
)
1763 char flagbuf
[FLAGBUFLEN
];
1765 snprintb(flagbuf
, sizeof(flagbuf
),
1766 "\20\3AC3\2FLOAT32\1PCM", this->d
.audio
.encodings
);
1768 aprint_normal("%sencodings=%s\n", lead
, flagbuf
);
1769 } else if (this->widgetcap
& COP_AWCAP_DIGITAL
) {
1770 aprint_normal("%smax channels=%d, DIGITAL, encodings=%s\n",
1771 lead
, channels
, flagbuf
);
1773 aprint_normal("%smax channels=%d, encodings=%s\n",
1774 lead
, channels
, flagbuf
);
1776 snprintb(flagbuf
, sizeof(flagbuf
),
1777 "\20\x15""32bit\x14""24bit\x13""20bit"
1778 "\x12""16bit\x11""8bit""\x0c""384kHz\x0b""192kHz\x0a""176.4kHz"
1779 "\x09""96kHz\x08""88.2kHz\x07""48kHz\x06""44.1kHz\x05""32kHz\x04"
1780 "22.05kHz\x03""16kHz\x02""11.025kHz\x01""8kHz",
1781 this->d
.audio
.bits_rates
);
1782 aprint_normal("%sPCM formats=%s\n", lead
, flagbuf
);
1788 azalia_widget_init_pin(widget_t
*this, const codec_t
*codec
)
1793 err
= codec
->comresp(codec
, this->nid
, CORB_GET_CONFIGURATION_DEFAULT
,
1797 this->d
.pin
.config
= result
;
1798 this->d
.pin
.sequence
= CORB_CD_SEQUENCE(result
);
1799 this->d
.pin
.association
= CORB_CD_ASSOCIATION(result
);
1800 this->d
.pin
.color
= CORB_CD_COLOR(result
);
1801 this->d
.pin
.device
= CORB_CD_DEVICE(result
);
1803 err
= codec
->comresp(codec
, this->nid
, CORB_GET_PARAMETER
,
1804 COP_PINCAP
, &result
);
1807 this->d
.pin
.cap
= result
;
1810 if ((this->d
.pin
.cap
& COP_PINCAP_INPUT
) &&
1811 (this->d
.pin
.cap
& COP_PINCAP_OUTPUT
) == 0) {
1812 err
= codec
->comresp(codec
, this->nid
,
1813 CORB_GET_PIN_WIDGET_CONTROL
, 0, &result
);
1815 result
&= ~CORB_PWC_OUTPUT
;
1816 result
|= CORB_PWC_INPUT
;
1817 codec
->comresp(codec
, this->nid
,
1818 CORB_SET_PIN_WIDGET_CONTROL
, result
, NULL
);
1821 /* output pin, or bidirectional pin */
1822 if (this->d
.pin
.cap
& COP_PINCAP_OUTPUT
) {
1823 err
= codec
->comresp(codec
, this->nid
,
1824 CORB_GET_PIN_WIDGET_CONTROL
, 0, &result
);
1826 result
&= ~CORB_PWC_INPUT
;
1827 result
|= CORB_PWC_OUTPUT
;
1828 codec
->comresp(codec
, this->nid
,
1829 CORB_SET_PIN_WIDGET_CONTROL
, result
, NULL
);
1836 azalia_widget_print_pin(const widget_t
*this, const char *lead
)
1838 char flagbuf
[FLAGBUFLEN
];
1840 DPRINTF(("%spin config; device=%s color=%s assoc=%d seq=%d", lead
,
1841 pin_devices
[this->d
.pin
.device
], pin_colors
[this->d
.pin
.color
],
1842 this->d
.pin
.association
, this->d
.pin
.sequence
));
1843 snprintb(flagbuf
, sizeof(flagbuf
),
1844 "\20\021EAPD\07BALANCE\06INPUT"
1845 "\05OUTPUT\04HEADPHONE\03PRESENCE\02TRIGGER\01IMPEDANCE",
1847 DPRINTF((" cap=%s\n", flagbuf
));
1852 azalia_widget_init_connection(widget_t
*this, const codec_t
*codec
,
1860 this->selected
= -1;
1861 if ((this->widgetcap
& COP_AWCAP_CONNLIST
) == 0)
1864 err
= codec
->comresp(codec
, this->nid
, CORB_GET_PARAMETER
,
1865 COP_CONNECTION_LIST_LENGTH
, &result
);
1868 longform
= (result
& COP_CLL_LONG
) != 0;
1869 length
= COP_CLL_LENGTH(result
);
1872 this->nconnections
= length
;
1873 this->connections
= malloc(sizeof(nid_t
) * (length
+ 3),
1874 M_DEVBUF
, M_NOWAIT
);
1875 if (this->connections
== NULL
) {
1876 aprint_error("%s: out of memory\n", device_xname(codec
->dev
));
1880 for (i
= 0; i
< length
;) {
1881 err
= codec
->comresp(codec
, this->nid
,
1882 CORB_GET_CONNECTION_LIST_ENTRY
, i
, &result
);
1885 this->connections
[i
++] = CORB_CLE_LONG_0(result
);
1886 this->connections
[i
++] = CORB_CLE_LONG_1(result
);
1889 for (i
= 0; i
< length
;) {
1890 err
= codec
->comresp(codec
, this->nid
,
1891 CORB_GET_CONNECTION_LIST_ENTRY
, i
, &result
);
1894 this->connections
[i
++] = CORB_CLE_SHORT_0(result
);
1895 this->connections
[i
++] = CORB_CLE_SHORT_1(result
);
1896 this->connections
[i
++] = CORB_CLE_SHORT_2(result
);
1897 this->connections
[i
++] = CORB_CLE_SHORT_3(result
);
1901 DPRINTF(("%sconnections=0x%x", lead
, this->connections
[0]));
1902 for (i
= 1; i
< length
; i
++) {
1903 DPRINTF((",0x%x", this->connections
[i
]));
1906 err
= codec
->comresp(codec
, this->nid
,
1907 CORB_GET_CONNECTION_SELECT_CONTROL
, 0, &result
);
1910 this->selected
= CORB_CSC_INDEX(result
);
1911 DPRINTF(("; selected=0x%x\n", this->connections
[result
]));
1916 /* ================================================================
1918 * ================================================================ */
1921 azalia_stream_init(stream_t
*this, azalia_t
*az
, int regindex
, int strnum
, int dir
)
1926 this->regbase
= HDA_SD_BASE
+ regindex
* HDA_SD_SIZE
;
1927 this->intr_bit
= 1 << regindex
;
1928 this->number
= strnum
;
1931 /* setup BDL buffers */
1932 err
= azalia_alloc_dmamem(az
, sizeof(bdlist_entry_t
) * HDA_BDL_MAX
,
1933 128, &this->bdlist
);
1935 aprint_error_dev(az
->dev
, "can't allocate a BDL buffer\n");
1942 azalia_stream_delete(stream_t
*this, azalia_t
*az
)
1944 if (this->bdlist
.addr
== NULL
)
1946 azalia_free_dmamem(az
, &this->bdlist
);
1951 azalia_stream_reset(stream_t
*this)
1956 if (this->bdlist
.addr
== NULL
)
1958 ctl
= STR_READ_2(this, CTL
);
1959 STR_WRITE_2(this, CTL
, ctl
| HDA_SD_CTL_SRST
);
1960 for (i
= 5000; i
>= 0; i
--) {
1962 ctl
= STR_READ_2(this, CTL
);
1963 if (ctl
& HDA_SD_CTL_SRST
)
1967 aprint_error_dev(this->az
->dev
, "stream reset failure 1\n");
1970 STR_WRITE_2(this, CTL
, ctl
& ~HDA_SD_CTL_SRST
);
1971 for (i
= 5000; i
>= 0; i
--) {
1973 ctl
= STR_READ_2(this, CTL
);
1974 if ((ctl
& HDA_SD_CTL_SRST
) == 0)
1978 aprint_error_dev(this->az
->dev
, "stream reset failure 2\n");
1985 azalia_stream_start(stream_t
*this, void *start
, void *end
, int blk
,
1986 void (*intr
)(void *), void *arg
, uint16_t fmt
)
1988 bdlist_entry_t
*bdlist
;
1994 DPRINTF(("%s: start=%p end=%p\n", __func__
, start
, end
));
1995 if (this->bdlist
.addr
== NULL
)
1998 this->intr_arg
= arg
;
2000 err
= azalia_stream_reset(this);
2005 dmaaddr
= AZALIA_DMA_DMAADDR(&this->buffer
);
2006 this->dmaend
= dmaaddr
+ ((char *)end
- (char *)start
);
2007 bdlist
= (bdlist_entry_t
*)this->bdlist
.addr
;
2008 for (index
= 0; index
< HDA_BDL_MAX
; index
++) {
2009 bdlist
[index
].low
= dmaaddr
;
2010 bdlist
[index
].high
= PTR_UPPER32(dmaaddr
);
2011 bdlist
[index
].length
= blk
;
2012 bdlist
[index
].flags
= BDLIST_ENTRY_IOC
;
2014 if (dmaaddr
>= this->dmaend
) {
2019 /* The BDL covers the whole of the buffer. */
2020 this->dmanext
= AZALIA_DMA_DMAADDR(&this->buffer
);
2022 dmaaddr
= AZALIA_DMA_DMAADDR(&this->bdlist
);
2023 STR_WRITE_4(this, BDPL
, dmaaddr
);
2024 STR_WRITE_4(this, BDPU
, PTR_UPPER32(dmaaddr
));
2025 STR_WRITE_2(this, LVI
, (index
- 1) & HDA_SD_LVI_LVI
);
2026 ctl2
= STR_READ_1(this, CTL2
);
2027 STR_WRITE_1(this, CTL2
,
2028 (ctl2
& ~HDA_SD_CTL2_STRM
) | (this->number
<< HDA_SD_CTL2_STRM_SHIFT
));
2029 STR_WRITE_4(this, CBL
, ((char *)end
- (char *)start
));
2031 STR_WRITE_2(this, FMT
, fmt
);
2033 err
= azalia_codec_connect_stream(&this->az
->codecs
[this->az
->codecno
],
2034 this->dir
, fmt
, this->number
);
2038 intctl
= AZ_READ_4(this->az
, INTCTL
);
2039 intctl
|= this->intr_bit
;
2040 AZ_WRITE_4(this->az
, INTCTL
, intctl
);
2042 ctl
= STR_READ_1(this, CTL
);
2043 ctl
|= ctl
| HDA_SD_CTL_DEIE
| HDA_SD_CTL_FEIE
| HDA_SD_CTL_IOCE
| HDA_SD_CTL_RUN
;
2044 STR_WRITE_1(this, CTL
, ctl
);
2049 azalia_stream_halt(stream_t
*this)
2053 if (this->bdlist
.addr
== NULL
)
2055 this->intr
= this->intr_arg
= NULL
;
2056 ctl
= STR_READ_2(this, CTL
);
2057 ctl
&= ~(HDA_SD_CTL_DEIE
| HDA_SD_CTL_FEIE
| HDA_SD_CTL_IOCE
| HDA_SD_CTL_RUN
);
2058 STR_WRITE_2(this, CTL
, ctl
);
2059 AZ_WRITE_4(this->az
, INTCTL
, AZ_READ_4(this->az
, INTCTL
) & ~this->intr_bit
);
2060 azalia_codec_disconnect_stream
2061 (&this->az
->codecs
[this->az
->codecno
], this->dir
);
2066 azalia_stream_intr(stream_t
*this, uint32_t intsts
)
2068 if (this->bdlist
.addr
== NULL
)
2070 if ((intsts
& this->intr_bit
) == 0)
2072 STR_WRITE_1(this, STS
, HDA_SD_STS_DESE
2073 | HDA_SD_STS_FIFOE
| HDA_SD_STS_BCIS
);
2075 if (this->intr
!= NULL
)
2076 this->intr(this->intr_arg
);
2080 /* ================================================================
2082 * ================================================================ */
2085 azalia_open(void *v
, int flags
)
2090 DPRINTF(("%s: flags=0x%x\n", __func__
, flags
));
2092 codec
= &az
->codecs
[az
->codecno
];
2093 if (flags
& FWRITE
&& (az
->mode_cap
& AUMODE_PLAY
) == 0)
2095 if (flags
& FREAD
&& (az
->mode_cap
& AUMODE_RECORD
) == 0)
2102 azalia_close(void *v
)
2107 DPRINTF(("%s\n", __func__
));
2109 codec
= &az
->codecs
[az
->codecno
];
2114 azalia_query_encoding(void *v
, audio_encoding_t
*enc
)
2120 codec
= &az
->codecs
[az
->codecno
];
2121 return auconv_query_encoding(codec
->encodings
, enc
);
2125 azalia_set_params(void *v
, int smode
, int umode
, audio_params_t
*p
,
2126 audio_params_t
*r
, stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
2133 codec
= &az
->codecs
[az
->codecno
];
2134 smode
&= az
->mode_cap
;
2135 if (smode
& AUMODE_RECORD
&& r
!= NULL
) {
2136 index
= auconv_set_converter(codec
->formats
, codec
->nformats
,
2137 AUMODE_RECORD
, r
, TRUE
, rfil
);
2141 if (smode
& AUMODE_PLAY
&& p
!= NULL
) {
2142 index
= auconv_set_converter(codec
->formats
, codec
->nformats
,
2143 AUMODE_PLAY
, p
, TRUE
, pfil
);
2151 azalia_round_blocksize(void *v
, int blk
, int mode
,
2152 const audio_params_t
*param
)
2157 blk
&= ~0x7f; /* must be multiple of 128 */
2160 /* number of blocks must be <= HDA_BDL_MAX */
2162 size
= mode
== AUMODE_PLAY
? az
->pstream
.buffer
.size
: az
->rstream
.buffer
.size
;
2165 aprint_error("%s: size is 0", __func__
);
2169 if (size
> HDA_BDL_MAX
* blk
) {
2170 blk
= size
/ HDA_BDL_MAX
;
2172 blk
= (blk
+ 0x7f) & ~0x7f;
2174 DPRINTF(("%s: resultant block size = %d\n", __func__
, blk
));
2179 azalia_halt_output(void *v
)
2183 DPRINTF(("%s\n", __func__
));
2185 return azalia_stream_halt(&az
->pstream
);
2189 azalia_halt_input(void *v
)
2193 DPRINTF(("%s\n", __func__
));
2195 return azalia_stream_halt(&az
->rstream
);
2199 azalia_getdev(void *v
, struct audio_device
*dev
)
2204 strlcpy(dev
->name
, "HD-Audio", MAX_AUDIO_DEV_LEN
);
2205 snprintf(dev
->version
, MAX_AUDIO_DEV_LEN
,
2206 "%d.%d", AZ_READ_1(az
, VMAJ
), AZ_READ_1(az
, VMIN
));
2207 strlcpy(dev
->config
, device_xname(az
->dev
), MAX_AUDIO_DEV_LEN
);
2212 azalia_set_port(void *v
, mixer_ctrl_t
*mc
)
2218 co
= &az
->codecs
[az
->codecno
];
2219 return co
->set_port(co
, mc
);
2223 azalia_get_port(void *v
, mixer_ctrl_t
*mc
)
2229 co
= &az
->codecs
[az
->codecno
];
2230 return co
->get_port(co
, mc
);
2234 azalia_query_devinfo(void *v
, mixer_devinfo_t
*mdev
)
2240 co
= &az
->codecs
[az
->codecno
];
2241 if (mdev
->index
>= co
->nmixers
)
2243 *mdev
= co
->mixers
[mdev
->index
].devinfo
;
2248 azalia_allocm(void *v
, int dir
, size_t size
, struct malloc_type
*pool
,
2256 stream
= dir
== AUMODE_PLAY
? &az
->pstream
: &az
->rstream
;
2257 err
= azalia_alloc_dmamem(az
, size
, 128, &stream
->buffer
);
2260 return stream
->buffer
.addr
;
2264 azalia_freem(void *v
, void *addr
, struct malloc_type
*pool
)
2270 if (addr
== az
->pstream
.buffer
.addr
) {
2271 stream
= &az
->pstream
;
2272 } else if (addr
== az
->rstream
.buffer
.addr
) {
2273 stream
= &az
->rstream
;
2277 azalia_free_dmamem(az
, &stream
->buffer
);
2281 azalia_round_buffersize(void *v
, int dir
, size_t size
)
2283 size
&= ~0x7f; /* must be multiple of 128 */
2290 azalia_get_props(void *v
)
2292 return AUDIO_PROP_INDEPENDENT
| AUDIO_PROP_FULLDUPLEX
;
2296 azalia_trigger_output(void *v
, void *start
, void *end
, int blk
,
2297 void (*intr
)(void *), void *arg
, const audio_params_t
*param
)
2303 DPRINTF(("%s: this=%p start=%p end=%p blk=%d {enc=%u %uch %u/%ubit %uHz}\n",
2304 __func__
, v
, start
, end
, blk
, param
->encoding
, param
->channels
,
2305 param
->validbits
, param
->precision
, param
->sample_rate
));
2307 err
= azalia_params2fmt(param
, &fmt
);
2312 return azalia_stream_start(&az
->pstream
, start
, end
, blk
, intr
, arg
, fmt
);
2316 azalia_trigger_input(void *v
, void *start
, void *end
, int blk
,
2317 void (*intr
)(void *), void *arg
, const audio_params_t
*param
)
2323 DPRINTF(("%s: this=%p start=%p end=%p blk=%d {enc=%u %uch %u/%ubit %uHz}\n",
2324 __func__
, v
, start
, end
, blk
, param
->encoding
, param
->channels
,
2325 param
->validbits
, param
->precision
, param
->sample_rate
));
2327 err
= azalia_params2fmt(param
, &fmt
);
2332 return azalia_stream_start(&az
->rstream
, start
, end
, blk
, intr
, arg
, fmt
);
2335 /* --------------------------------
2336 * helpers for MI audio functions
2337 * -------------------------------- */
2339 azalia_params2fmt(const audio_params_t
*param
, uint16_t *fmt
)
2345 if (param
->channels
> HDA_MAX_CHANNELS
) {
2346 aprint_error("%s: too many channels: %u\n", __func__
,
2351 ret
|= param
->channels
- 1;
2353 switch (param
->validbits
) {
2355 ret
|= HDA_SD_FMT_BITS_8_16
;
2358 ret
|= HDA_SD_FMT_BITS_16_16
;
2361 ret
|= HDA_SD_FMT_BITS_20_32
;
2364 ret
|= HDA_SD_FMT_BITS_24_32
;
2367 ret
|= HDA_SD_FMT_BITS_32_32
;
2370 aprint_error("%s: invalid validbits: %u\n", __func__
,
2374 if (param
->sample_rate
== 384000) {
2375 aprint_error("%s: invalid sample_rate: %u\n", __func__
,
2376 param
->sample_rate
);
2378 } else if (param
->sample_rate
== 192000) {
2379 ret
|= HDA_SD_FMT_BASE_48
| HDA_SD_FMT_MULT_X4
| HDA_SD_FMT_DIV_BY1
;
2380 } else if (param
->sample_rate
== 176400) {
2381 ret
|= HDA_SD_FMT_BASE_44
| HDA_SD_FMT_MULT_X4
| HDA_SD_FMT_DIV_BY1
;
2382 } else if (param
->sample_rate
== 96000) {
2383 ret
|= HDA_SD_FMT_BASE_48
| HDA_SD_FMT_MULT_X2
| HDA_SD_FMT_DIV_BY1
;
2384 } else if (param
->sample_rate
== 88200) {
2385 ret
|= HDA_SD_FMT_BASE_44
| HDA_SD_FMT_MULT_X2
| HDA_SD_FMT_DIV_BY1
;
2386 } else if (param
->sample_rate
== 48000) {
2387 ret
|= HDA_SD_FMT_BASE_48
| HDA_SD_FMT_MULT_X1
| HDA_SD_FMT_DIV_BY1
;
2388 } else if (param
->sample_rate
== 44100) {
2389 ret
|= HDA_SD_FMT_BASE_44
| HDA_SD_FMT_MULT_X1
| HDA_SD_FMT_DIV_BY1
;
2390 } else if (param
->sample_rate
== 32000) {
2391 ret
|= HDA_SD_FMT_BASE_48
| HDA_SD_FMT_MULT_X2
| HDA_SD_FMT_DIV_BY3
;
2392 } else if (param
->sample_rate
== 22050) {
2393 ret
|= HDA_SD_FMT_BASE_44
| HDA_SD_FMT_MULT_X1
| HDA_SD_FMT_DIV_BY2
;
2394 } else if (param
->sample_rate
== 16000) {
2395 ret
|= HDA_SD_FMT_BASE_48
| HDA_SD_FMT_MULT_X1
| HDA_SD_FMT_DIV_BY3
;
2396 } else if (param
->sample_rate
== 11025) {
2397 ret
|= HDA_SD_FMT_BASE_44
| HDA_SD_FMT_MULT_X1
| HDA_SD_FMT_DIV_BY4
;
2398 } else if (param
->sample_rate
== 8000) {
2399 ret
|= HDA_SD_FMT_BASE_48
| HDA_SD_FMT_MULT_X1
| HDA_SD_FMT_DIV_BY6
;
2401 aprint_error("%s: invalid sample_rate: %u\n", __func__
,
2402 param
->sample_rate
);
2411 MODULE(MODULE_CLASS_DRIVER
, azalia
, NULL
);
2413 static const struct cfiattrdata audiobuscf_iattrdata
= {
2414 "audiobus", 0, { { NULL
, NULL
, 0 }, }
2416 static const struct cfiattrdata
* const azalia_attrs
[] = {
2417 &audiobuscf_iattrdata
, NULL
2419 CFDRIVER_DECL(azalia
, DV_DULL
, azalia_attrs
);
2420 extern struct cfattach azalia_ca
;
2421 static int azalialoc
[] = { -1, -1 };
2422 static struct cfparent pciparent
= {
2423 "pci", "pci", DVUNIT_ANY
2425 static struct cfdata azalia_cfdata
[] = {
2427 .cf_name
= "azalia",
2428 .cf_atname
= "azalia",
2430 .cf_fstate
= FSTATE_STAR
,
2431 .cf_loc
= azalialoc
,
2433 .cf_pspec
= &pciparent
,
2439 azalia_modcmd(modcmd_t cmd
, void *arg
)
2444 case MODULE_CMD_INIT
:
2445 err
= config_cfdriver_attach(&azalia_cd
);
2448 err
= config_cfattach_attach("azalia", &azalia_ca
);
2450 config_cfdriver_detach(&azalia_cd
);
2454 err
= config_cfdata_attach(azalia_cfdata
, 1);
2457 config_cfattach_detach("azalia", &azalia_ca
);
2458 config_cfdriver_detach(&azalia_cd
);
2462 case MODULE_CMD_FINI
:
2463 err
= config_cfdata_detach(azalia_cfdata
);
2466 config_cfattach_detach("azalia", &azalia_ca
);
2467 config_cfdriver_detach(&azalia_cd
);