This source file includes following definitions.
- azalia_dma_t
- stream_t
- azalia_t
- azalia_pci_match
- azalia_pci_attach
- azalia_pci_activate
- azalia_pci_detach
- azalia_intr
- azalia_attach
- azalia_attach_intr
- azalia_init_corb
- azalia_delete_corb
- azalia_init_rirb
- azalia_delete_rirb
- azalia_set_command
- azalia_get_response
- azalia_rirb_kick_unsol_events
- azalia_rirb_intr
- azalia_alloc_dmamem
- azalia_free_dmamem
- azalia_codec_init
- azalia_codec_delete
- azalia_codec_construct_format
- azalia_codec_add_bits
- azalia_codec_add_format
- azalia_codec_comresp
- azalia_codec_connect_stream
- azalia_widget_init
- azalia_widget_init_audio
- azalia_widget_print_audio
- azalia_widget_init_pin
- azalia_widget_print_pin
- azalia_widget_init_connection
- azalia_stream_init
- azalia_stream_delete
- azalia_stream_reset
- azalia_stream_start
- azalia_stream_halt
- azalia_stream_intr
- azalia_open
- azalia_close
- azalia_query_encoding
- azalia_set_params
- azalia_round_blocksize
- azalia_halt_output
- azalia_halt_input
- azalia_getdev
- azalia_set_port
- azalia_get_port
- azalia_query_devinfo
- azalia_allocm
- azalia_freem
- azalia_round_buffersize
- azalia_get_props
- azalia_trigger_output
- azalia_trigger_input
- azalia_params2fmt
- azalia_create_encodings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 #include <sys/cdefs.h>
53 #ifdef NETBSD_GOOP
54 __KERNEL_RCSID(0, "$NetBSD: azalia.c,v 1.15 2005/09/29 04:14:03 kent Exp $");
55 #endif
56
57 #include <sys/param.h>
58 #include <sys/device.h>
59 #include <sys/malloc.h>
60 #include <sys/systm.h>
61 #include <uvm/uvm_param.h>
62 #include <dev/audio_if.h>
63 #include <dev/auconv.h>
64 #include <dev/pci/pcidevs.h>
65 #include <dev/pci/pcivar.h>
66
67 #include <dev/pci/azalia.h>
68
69 typedef struct audio_params audio_params_t;
70 #ifndef BUS_DMA_NOCACHE
71 #define BUS_DMA_NOCACHE 0
72 #endif
73 #define auconv_delete_encodings(x...)
74 #define auconv_query_encoding(x...) (EINVAL)
75 #define auconv_create_encodings(x...) (0)
76
77 struct audio_format {
78 void *driver_data;
79 int32_t mode;
80 u_int encoding;
81 u_int validbits;
82 u_int precision;
83 u_int channels;
84 u_int channel_mask;
85 #define AUFMT_UNKNOWN_POSITION 0U
86 #define AUFMT_FRONT_LEFT 0x00001U
87 #define AUFMT_FRONT_RIGHT 0x00002U
88 #define AUFMT_FRONT_CENTER 0x00004U
89 #define AUFMT_LOW_FREQUENCY 0x00008U
90 #define AUFMT_BACK_LEFT 0x00010U
91 #define AUFMT_BACK_RIGHT 0x00020U
92 #define AUFMT_FRONT_LEFT_OF_CENTER 0x00040U
93 #define AUFMT_FRONT_RIGHT_OF_CENTER 0x00080U
94 #define AUFMT_BACK_CENTER 0x00100U
95 #define AUFMT_SIDE_LEFT 0x00200U
96 #define AUFMT_SIDE_RIGHT 0x00400U
97 #define AUFMT_TOP_CENTER 0x00800U
98 #define AUFMT_TOP_FRONT_LEFT 0x01000U
99 #define AUFMT_TOP_FRONT_CENTER 0x02000U
100 #define AUFMT_TOP_FRONT_RIGHT 0x04000U
101 #define AUFMT_TOP_BACK_LEFT 0x08000U
102 #define AUFMT_TOP_BACK_CENTER 0x10000U
103 #define AUFMT_TOP_BACK_RIGHT 0x20000U
104
105 #define AUFMT_MONAURAL AUFMT_FRONT_CENTER
106 #define AUFMT_STEREO (AUFMT_FRONT_LEFT | AUFMT_FRONT_RIGHT)
107 #define AUFMT_SURROUND4 (AUFMT_STEREO | AUFMT_BACK_LEFT \
108 | AUFMT_BACK_RIGHT)
109 #define AUFMT_DOLBY_5_1 (AUFMT_SURROUND4 | AUFMT_FRONT_CENTER \
110 | AUFMT_LOW_FREQUENCY)
111
112
113
114
115
116 u_int frequency_type;
117
118 #define AUFMT_MAX_FREQUENCIES 16
119
120
121
122 u_int frequency[AUFMT_MAX_FREQUENCIES];
123 };
124
125 #define AUFMT_INVALIDATE(fmt) (fmt)->mode |= 0x80000000
126 #define AUFMT_VALIDATE(fmt) (fmt)->mode &= 0x7fffffff
127 #define AUFMT_IS_VALID(fmt) (((fmt)->mode & 0x80000000) == 0)
128
129
130
131
132
133
134 #define ICH_PCI_HDBARL 0x10
135 #define ICH_PCI_HDBARU 0x14
136 #define ICH_PCI_HDCTL 0x40
137 #define ICH_PCI_HDCTL_CLKDETCLR 0x08
138 #define ICH_PCI_HDCTL_CLKDETEN 0x04
139 #define ICH_PCI_HDCTL_CLKDETINV 0x02
140 #define ICH_PCI_HDCTL_SIGNALMODE 0x01
141
142
143
144 typedef struct {
145 bus_dmamap_t map;
146 caddr_t addr;
147 bus_dma_segment_t segments[1];
148 size_t size;
149 } azalia_dma_t;
150 #define AZALIA_DMA_DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
151
152 typedef struct {
153 struct azalia_t *az;
154 int regbase;
155 int number;
156 int dir;
157 uint32_t intr_bit;
158 azalia_dma_t bdlist;
159 azalia_dma_t buffer;
160 void (*intr)(void*);
161 void *intr_arg;
162 } stream_t;
163 #define STR_READ_1(s, r) \
164 bus_space_read_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
165 #define STR_READ_2(s, r) \
166 bus_space_read_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
167 #define STR_READ_4(s, r) \
168 bus_space_read_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
169 #define STR_WRITE_1(s, r, v) \
170 bus_space_write_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
171 #define STR_WRITE_2(s, r, v) \
172 bus_space_write_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
173 #define STR_WRITE_4(s, r, v) \
174 bus_space_write_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
175
176 typedef struct azalia_t {
177 struct device dev;
178 struct device *audiodev;
179
180 pci_chipset_tag_t pc;
181 void *ih;
182 bus_space_tag_t iot;
183 bus_space_handle_t ioh;
184 bus_size_t map_size;
185 bus_dma_tag_t dmat;
186 pcireg_t pciid;
187 uint32_t subid;
188
189 codec_t codecs[15];
190 int ncodecs;
191 int codecno;
192
193 azalia_dma_t corb_dma;
194 int corb_size;
195 azalia_dma_t rirb_dma;
196 int rirb_size;
197 int rirb_rp;
198 #define UNSOLQ_SIZE 256
199 rirb_entry_t *unsolq;
200 int unsolq_wp;
201 int unsolq_rp;
202 boolean_t unsolq_kick;
203
204 boolean_t ok64;
205 int nistreams, nostreams, nbstreams;
206 stream_t pstream;
207 stream_t rstream;
208 } azalia_t;
209 #define XNAME(sc) ((sc)->dev.dv_xname)
210 #define AZ_READ_1(z, r) bus_space_read_1((z)->iot, (z)->ioh, HDA_##r)
211 #define AZ_READ_2(z, r) bus_space_read_2((z)->iot, (z)->ioh, HDA_##r)
212 #define AZ_READ_4(z, r) bus_space_read_4((z)->iot, (z)->ioh, HDA_##r)
213 #define AZ_WRITE_1(z, r, v) bus_space_write_1((z)->iot, (z)->ioh, HDA_##r, v)
214 #define AZ_WRITE_2(z, r, v) bus_space_write_2((z)->iot, (z)->ioh, HDA_##r, v)
215 #define AZ_WRITE_4(z, r, v) bus_space_write_4((z)->iot, (z)->ioh, HDA_##r, v)
216
217
218
219 int azalia_pci_match(struct device *, void *, void *);
220 void azalia_pci_attach(struct device *, struct device *, void *);
221 int azalia_pci_activate(struct device *, enum devact);
222 int azalia_pci_detach(struct device *, int);
223 int azalia_intr(void *);
224 int azalia_attach(azalia_t *);
225 void azalia_attach_intr(struct device *);
226 int azalia_init_corb(azalia_t *);
227 int azalia_delete_corb(azalia_t *);
228 int azalia_init_rirb(azalia_t *);
229 int azalia_delete_rirb(azalia_t *);
230 int azalia_set_command(azalia_t *, nid_t, int, uint32_t,
231 uint32_t);
232 int azalia_get_response(azalia_t *, uint32_t *);
233 void azalia_rirb_kick_unsol_events(azalia_t *);
234 void azalia_rirb_intr(azalia_t *);
235 int azalia_alloc_dmamem(azalia_t *, size_t, size_t, azalia_dma_t *);
236 int azalia_free_dmamem(const azalia_t *, azalia_dma_t*);
237
238 int azalia_codec_init(codec_t *);
239 int azalia_codec_delete(codec_t *);
240 void azalia_codec_add_bits(codec_t *, int, uint32_t, int);
241 void azalia_codec_add_format(codec_t *, int, int, int, uint32_t,
242 int32_t);
243 int azalia_codec_comresp(const codec_t *, nid_t, uint32_t,
244 uint32_t, uint32_t *);
245 int azalia_codec_connect_stream(codec_t *, int, uint16_t, int);
246
247 int azalia_widget_init(widget_t *, const codec_t *, int);
248 int azalia_widget_init_audio(widget_t *, const codec_t *);
249 int azalia_widget_print_audio(const widget_t *, const char *);
250 int azalia_widget_init_pin(widget_t *, const codec_t *);
251 int azalia_widget_print_pin(const widget_t *);
252 int azalia_widget_init_connection(widget_t *, const codec_t *);
253
254 int azalia_stream_init(stream_t *, azalia_t *, int, int, int);
255 int azalia_stream_delete(stream_t *, azalia_t *);
256 int azalia_stream_reset(stream_t *);
257 int azalia_stream_start(stream_t *, void *, void *, int,
258 void (*)(void *), void *, uint16_t);
259 int azalia_stream_halt(stream_t *);
260 int azalia_stream_intr(stream_t *, uint32_t);
261
262 int azalia_open(void *, int);
263 void azalia_close(void *);
264 int azalia_query_encoding(void *, audio_encoding_t *);
265 int azalia_set_params(void *, int, int, audio_params_t *,
266 audio_params_t *);
267 int azalia_round_blocksize(void *, int);
268 int azalia_halt_output(void *);
269 int azalia_halt_input(void *);
270 int azalia_getdev(void *, struct audio_device *);
271 int azalia_set_port(void *, mixer_ctrl_t *);
272 int azalia_get_port(void *, mixer_ctrl_t *);
273 int azalia_query_devinfo(void *, mixer_devinfo_t *);
274 void *azalia_allocm(void *, int, size_t, int, int);
275 void azalia_freem(void *, void *, int);
276 size_t azalia_round_buffersize(void *, int, size_t);
277 int azalia_get_props(void *);
278 int azalia_trigger_output(void *, void *, void *, int,
279 void (*)(void *), void *, audio_params_t *);
280 int azalia_trigger_input(void *, void *, void *, int,
281 void (*)(void *), void *, audio_params_t *);
282
283 int azalia_params2fmt(const audio_params_t *, uint16_t *);
284 int azalia_create_encodings(struct audio_format *, int,
285 struct audio_encoding_set **);
286
287
288 struct cfattach azalia_ca = {
289 sizeof(azalia_t), azalia_pci_match, azalia_pci_attach,
290 azalia_pci_detach, azalia_pci_activate
291 };
292
293 struct cfdriver azalia_cd = {
294 NULL, "azalia", DV_DULL
295 };
296
297 struct audio_hw_if azalia_hw_if = {
298 azalia_open,
299 azalia_close,
300 NULL,
301 azalia_query_encoding,
302 azalia_set_params,
303 azalia_round_blocksize,
304 NULL,
305 NULL,
306 NULL,
307 NULL,
308 NULL,
309 azalia_halt_output,
310 azalia_halt_input,
311 NULL,
312 azalia_getdev,
313 NULL,
314 azalia_set_port,
315 azalia_get_port,
316 azalia_query_devinfo,
317 azalia_allocm,
318 azalia_freem,
319 azalia_round_buffersize,
320 NULL,
321 azalia_get_props,
322 azalia_trigger_output,
323 azalia_trigger_input,
324 };
325
326 static const char *pin_colors[16] = {
327 "unknown", "black", "gray", "blue",
328 "green", "red", "orange", "yellow",
329 "purple", "pink", "col0a", "col0b",
330 "col0c", "col0d", "white", "other"};
331 #ifdef AZALIA_DEBUG
332 static const char *pin_devices[16] = {
333 "line-out", AudioNspeaker, AudioNheadphone, AudioNcd,
334 "SPDIF-out", "digital-out", "modem-line", "modem-handset",
335 "line-in", AudioNaux, AudioNmicrophone, "telephony",
336 "SPDIF-in", "digital-in", "dev0e", "other"};
337 #endif
338
339
340
341
342
343 #define PCI_ID_CODE0(v, p) PCI_ID_CODE(PCI_VENDOR_##v, PCI_PRODUCT_##v##_##p)
344 #define PCIID_NVIDIA_MCP51 PCI_ID_CODE0(NVIDIA, MCP51_HDA)
345 #define PCIID_NVIDIA_MCP55 PCI_ID_CODE0(NVIDIA, MCP55_HDA)
346 #define PCIID_ALI_M5461 PCI_ID_CODE0(ALI, M5461)
347 #define PCIID_VIATECH_HDA PCI_ID_CODE0(VIATECH, HDA)
348
349 int
350 azalia_pci_match(struct device *parent, void *match, void *aux)
351 {
352 struct pci_attach_args *pa;
353
354 pa = aux;
355 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MULTIMEDIA
356 && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MULTIMEDIA_HDAUDIO)
357 return 1;
358 return 0;
359 }
360
361 void
362 azalia_pci_attach(struct device *parent, struct device *self, void *aux)
363 {
364 azalia_t *sc;
365 struct pci_attach_args *pa;
366 pcireg_t v;
367 pci_intr_handle_t ih;
368 const char *intrrupt_str;
369
370 sc = (azalia_t*)self;
371 pa = aux;
372
373 sc->dmat = pa->pa_dmat;
374
375 v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_PCI_HDBARL);
376 v &= PCI_MAPREG_TYPE_MASK | PCI_MAPREG_MEM_TYPE_MASK;
377 if (pci_mapreg_map(pa, ICH_PCI_HDBARL, v, 0,
378 &sc->iot, &sc->ioh, NULL, &sc->map_size, 0)) {
379 printf(": can't map device i/o space\n");
380 return;
381 }
382
383
384 v = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
385 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
386 v | PCI_COMMAND_BACKTOBACK_ENABLE);
387
388 v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44);
389 pci_conf_write(pa->pa_pc, pa->pa_tag, 0x44, v & (~0x7));
390
391
392 if (pci_intr_map(pa, &ih)) {
393 printf(": can't map interrupt\n");
394 return;
395 }
396 sc->pc = pa->pa_pc;
397 intrrupt_str = pci_intr_string(pa->pa_pc, ih);
398 sc->ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, azalia_intr,
399 sc, sc->dev.dv_xname);
400 if (sc->ih == NULL) {
401 printf(": can't establish interrupt");
402 if (intrrupt_str != NULL)
403 printf(" at %s", intrrupt_str);
404 printf("\n");
405 return;
406 }
407 printf(": %s\n", intrrupt_str);
408
409 sc->pciid = pa->pa_id;
410
411 if (azalia_attach(sc)) {
412 printf("%s: initialization failure\n", XNAME(sc));
413 azalia_pci_detach(self, 0);
414 return;
415 }
416 sc->subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
417
418 azalia_attach_intr(self);
419 }
420
421 int
422 azalia_pci_activate(struct device *self, enum devact act)
423 {
424 azalia_t *sc;
425 int ret;
426
427 sc = (azalia_t*)self;
428 ret = 0;
429 switch (act) {
430 case DVACT_ACTIVATE:
431 return ret;
432 case DVACT_DEACTIVATE:
433 if (sc->audiodev != NULL)
434 ret = config_deactivate(sc->audiodev);
435 return ret;
436 }
437 return EOPNOTSUPP;
438 }
439
440 int
441 azalia_pci_detach(struct device *self, int flags)
442 {
443 azalia_t *az;
444 int i;
445
446 DPRINTF(("%s\n", __func__));
447 az = (azalia_t*)self;
448 if (az->audiodev != NULL) {
449 config_detach(az->audiodev, flags);
450 az->audiodev = NULL;
451 }
452
453 DPRINTF(("%s: delete streams\n", __func__));
454 azalia_stream_delete(&az->rstream, az);
455 azalia_stream_delete(&az->pstream, az);
456
457 DPRINTF(("%s: delete codecs\n", __func__));
458 for (i = 0; i < az->ncodecs; i++) {
459 azalia_codec_delete(&az->codecs[i]);
460 }
461 az->ncodecs = 0;
462
463 DPRINTF(("%s: delete CORB and RIRB\n", __func__));
464 azalia_delete_corb(az);
465 azalia_delete_rirb(az);
466
467 DPRINTF(("%s: delete PCI resources\n", __func__));
468 if (az->ih != NULL) {
469 pci_intr_disestablish(az->pc, az->ih);
470 az->ih = NULL;
471 }
472 if (az->map_size != 0) {
473 bus_space_unmap(az->iot, az->ioh, az->map_size);
474 az->map_size = 0;
475 }
476 return 0;
477 }
478
479 int
480 azalia_intr(void *v)
481 {
482 azalia_t *az = v;
483 int ret = 0;
484 uint32_t intsts;
485 uint8_t rirbsts, rirbctl;
486
487 intsts = AZ_READ_4(az, INTSTS);
488 if (intsts == 0)
489 return (0);
490
491 AZ_WRITE_4(az, INTSTS, intsts);
492
493 ret += azalia_stream_intr(&az->pstream, intsts);
494 ret += azalia_stream_intr(&az->rstream, intsts);
495
496 rirbctl = AZ_READ_1(az, RIRBCTL);
497 rirbsts = AZ_READ_1(az, RIRBSTS);
498
499 if (intsts & HDA_INTCTL_CIE) {
500 if (rirbctl & HDA_RIRBCTL_RINTCTL) {
501 if (rirbsts & HDA_RIRBSTS_RINTFL)
502 azalia_rirb_intr(az);
503 }
504 }
505
506 return (1);
507 }
508
509
510
511
512
513 int
514 azalia_attach(azalia_t *az)
515 {
516 int i, n;
517 uint32_t gctl;
518 uint16_t gcap;
519 uint16_t statests;
520
521 printf("%s: host: High Definition Audio rev. %d.%d\n",
522 XNAME(az), AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN));
523 gcap = AZ_READ_2(az, GCAP);
524 az->nistreams = HDA_GCAP_ISS(gcap);
525 az->nostreams = HDA_GCAP_OSS(gcap);
526 az->nbstreams = HDA_GCAP_BSS(gcap);
527 az->ok64 = (gcap & HDA_GCAP_64OK) != 0;
528 DPRINTF(("%s: host: %d output, %d input, and %d bidi streams\n",
529 XNAME(az), az->nostreams, az->nistreams, az->nbstreams));
530
531
532 DPRINTF(("%s: resetting\n", __func__));
533 gctl = AZ_READ_4(az, GCTL);
534 AZ_WRITE_4(az, GCTL, gctl & ~HDA_GCTL_CRST);
535 for (i = 5000; i >= 0; i--) {
536 DELAY(10);
537 if ((AZ_READ_4(az, GCTL) & HDA_GCTL_CRST) == 0)
538 break;
539 }
540 DPRINTF(("%s: reset counter = %d\n", __func__, i));
541 if (i <= 0) {
542 printf("%s: reset failure\n", XNAME(az));
543 return ETIMEDOUT;
544 }
545 DELAY(1000);
546 gctl = AZ_READ_4(az, GCTL);
547 AZ_WRITE_4(az, GCTL, gctl | HDA_GCTL_CRST);
548 for (i = 5000; i >= 0; i--) {
549 DELAY(10);
550 if (AZ_READ_4(az, GCTL) & HDA_GCTL_CRST)
551 break;
552 }
553 DPRINTF(("%s: reset counter = %d\n", __func__, i));
554 if (i <= 0) {
555 printf("%s: reset-exit failure\n", XNAME(az));
556 return ETIMEDOUT;
557 }
558
559
560 gctl = AZ_READ_4(az, GCTL);
561 AZ_WRITE_4(az, GCTL, gctl | HDA_GCTL_UNSOL);
562
563
564 DELAY(1000);
565 statests = AZ_READ_2(az, STATESTS);
566 for (i = 0, n = 0; i < 15; i++) {
567 if ((statests >> i) & 1) {
568 DPRINTF(("%s: found a codec at #%d\n", XNAME(az), i));
569 az->codecs[n].address = i;
570 az->codecs[n++].az = az;
571 }
572 }
573 az->ncodecs = n;
574 if (az->ncodecs < 1) {
575 printf("%s: No HD-Audio codecs\n", XNAME(az));
576 return -1;
577 }
578 return 0;
579 }
580
581 void
582 azalia_attach_intr(struct device *self)
583 {
584 azalia_t *az;
585 int err, i, c;
586
587 az = (azalia_t*)self;
588
589 AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE);
590 AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS);
591 AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS);
592 AZ_WRITE_4(az, DPLBASE, 0);
593 AZ_WRITE_4(az, DPUBASE, 0);
594
595
596 if (azalia_init_corb(az))
597 goto err_exit;
598
599 if (azalia_init_rirb(az))
600 goto err_exit;
601
602 AZ_WRITE_4(az, INTCTL,
603 AZ_READ_4(az, INTCTL) | HDA_INTCTL_CIE | HDA_INTCTL_GIE);
604
605 c = -1;
606 for (i = 0; i < az->ncodecs; i++) {
607 err = azalia_codec_init(&az->codecs[i]);
608 if (!err && c < 0)
609 c = i;
610 }
611 if (c < 0)
612 goto err_exit;
613
614 az->codecno = c;
615 DPRINTF(("%s: using the #%d codec\n", XNAME(az), az->codecno));
616
617 if (azalia_stream_init(&az->pstream, az, az->nistreams + 0,
618 1, AUMODE_PLAY))
619 goto err_exit;
620 if (azalia_stream_init(&az->rstream, az, 0, 2, AUMODE_RECORD))
621 goto err_exit;
622
623 az->audiodev = audio_attach_mi(&azalia_hw_if, az, &az->dev);
624 return;
625 err_exit:
626 azalia_pci_detach(self, 0);
627 return;
628 }
629
630 int
631 azalia_init_corb(azalia_t *az)
632 {
633 int entries, err, i;
634 uint16_t corbrp, corbwp;
635 uint8_t corbsize, cap, corbctl;
636
637
638 corbctl = AZ_READ_1(az, CORBCTL);
639 if (corbctl & HDA_CORBCTL_CORBRUN) {
640 AZ_WRITE_1(az, CORBCTL, corbctl & ~HDA_CORBCTL_CORBRUN);
641 for (i = 5000; i >= 0; i--) {
642 DELAY(10);
643 corbctl = AZ_READ_1(az, CORBCTL);
644 if ((corbctl & HDA_CORBCTL_CORBRUN) == 0)
645 break;
646 }
647 if (i <= 0) {
648 printf("%s: CORB is running\n", XNAME(az));
649 return EBUSY;
650 }
651 }
652
653
654 corbsize = AZ_READ_1(az, CORBSIZE);
655 cap = corbsize & HDA_CORBSIZE_CORBSZCAP_MASK;
656 corbsize &= ~HDA_CORBSIZE_CORBSIZE_MASK;
657 if (cap & HDA_CORBSIZE_CORBSZCAP_256) {
658 entries = 256;
659 corbsize |= HDA_CORBSIZE_CORBSIZE_256;
660 } else if (cap & HDA_CORBSIZE_CORBSZCAP_16) {
661 entries = 16;
662 corbsize |= HDA_CORBSIZE_CORBSIZE_16;
663 } else if (cap & HDA_CORBSIZE_CORBSZCAP_2) {
664 entries = 2;
665 corbsize |= HDA_CORBSIZE_CORBSIZE_2;
666 } else {
667 printf("%s: Invalid CORBSZCAP: 0x%2x\n", XNAME(az), cap);
668 return -1;
669 }
670
671 err = azalia_alloc_dmamem(az, entries * sizeof(corb_entry_t),
672 128, &az->corb_dma);
673 if (err) {
674 printf("%s: can't allocate CORB buffer\n", XNAME(az));
675 return err;
676 }
677 AZ_WRITE_4(az, CORBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->corb_dma));
678 AZ_WRITE_4(az, CORBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->corb_dma)));
679 AZ_WRITE_1(az, CORBSIZE, corbsize);
680 az->corb_size = entries;
681
682 DPRINTF(("%s: CORB allocation succeeded.\n", __func__));
683
684
685 corbrp = AZ_READ_2(az, CORBRP);
686 AZ_WRITE_2(az, CORBRP, corbrp | HDA_CORBRP_CORBRPRST);
687 AZ_WRITE_2(az, CORBRP, corbrp & ~HDA_CORBRP_CORBRPRST);
688 for (i = 5000; i >= 0; i--) {
689 DELAY(10);
690 corbrp = AZ_READ_2(az, CORBRP);
691 if ((corbrp & HDA_CORBRP_CORBRPRST) == 0)
692 break;
693 }
694 if (i <= 0) {
695 printf("%s: CORBRP reset failure\n", XNAME(az));
696 return -1;
697 }
698 DPRINTF(("%s: CORBWP=%d; size=%d\n", __func__,
699 AZ_READ_2(az, CORBRP) & HDA_CORBRP_CORBRP, az->corb_size));
700
701
702 corbwp = AZ_READ_2(az, CORBWP);
703 AZ_WRITE_2(az, CORBWP, corbwp & ~HDA_CORBWP_CORBWP);
704
705
706 corbctl = AZ_READ_1(az, CORBCTL);
707 AZ_WRITE_1(az, CORBCTL, corbctl | HDA_CORBCTL_CORBRUN);
708 return 0;
709 }
710
711 int
712 azalia_delete_corb(azalia_t *az)
713 {
714 int i;
715 uint8_t corbctl;
716
717 if (az->corb_dma.addr == NULL)
718 return 0;
719
720 corbctl = AZ_READ_1(az, CORBCTL);
721 AZ_WRITE_1(az, CORBCTL, corbctl & ~HDA_CORBCTL_CORBRUN);
722 for (i = 5000; i >= 0; i--) {
723 DELAY(10);
724 corbctl = AZ_READ_1(az, CORBCTL);
725 if ((corbctl & HDA_CORBCTL_CORBRUN) == 0)
726 break;
727 }
728 azalia_free_dmamem(az, &az->corb_dma);
729 return 0;
730 }
731
732 int
733 azalia_init_rirb(azalia_t *az)
734 {
735 int entries, err, i;
736 uint16_t rirbwp;
737 uint8_t rirbsize, cap, rirbctl;
738
739
740 rirbctl = AZ_READ_1(az, RIRBCTL);
741 if (rirbctl & HDA_RIRBCTL_RIRBDMAEN) {
742 AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RIRBDMAEN);
743 for (i = 5000; i >= 0; i--) {
744 DELAY(10);
745 rirbctl = AZ_READ_1(az, RIRBCTL);
746 if ((rirbctl & HDA_RIRBCTL_RIRBDMAEN) == 0)
747 break;
748 }
749 if (i <= 0) {
750 printf("%s: RIRB is running\n", XNAME(az));
751 return EBUSY;
752 }
753 }
754
755
756 rirbsize = AZ_READ_1(az, RIRBSIZE);
757 cap = rirbsize & HDA_RIRBSIZE_RIRBSZCAP_MASK;
758 rirbsize &= ~HDA_RIRBSIZE_RIRBSIZE_MASK;
759 if (cap & HDA_RIRBSIZE_RIRBSZCAP_256) {
760 entries = 256;
761 rirbsize |= HDA_RIRBSIZE_RIRBSIZE_256;
762 } else if (cap & HDA_RIRBSIZE_RIRBSZCAP_16) {
763 entries = 16;
764 rirbsize |= HDA_RIRBSIZE_RIRBSIZE_16;
765 } else if (cap & HDA_RIRBSIZE_RIRBSZCAP_2) {
766 entries = 2;
767 rirbsize |= HDA_RIRBSIZE_RIRBSIZE_2;
768 } else {
769 printf("%s: Invalid RIRBSZCAP: 0x%2x\n", XNAME(az), cap);
770 return -1;
771 }
772
773 err = azalia_alloc_dmamem(az, entries * sizeof(rirb_entry_t),
774 128, &az->rirb_dma);
775 if (err) {
776 printf("%s: can't allocate RIRB buffer\n", XNAME(az));
777 return err;
778 }
779 AZ_WRITE_4(az, RIRBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->rirb_dma));
780 AZ_WRITE_4(az, RIRBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->rirb_dma)));
781 AZ_WRITE_1(az, RIRBSIZE, rirbsize);
782 az->rirb_size = entries;
783
784 DPRINTF(("%s: RIRB allocation succeeded.\n", __func__));
785
786
787 az->unsolq_rp = 0;
788 az->unsolq_wp = 0;
789 az->unsolq_kick = FALSE;
790 az->unsolq = malloc(sizeof(rirb_entry_t) * UNSOLQ_SIZE,
791 M_DEVBUF, M_NOWAIT);
792 if (az->unsolq == NULL) {
793 DPRINTF(("%s: can't allocate unsolicited response queue.\n",
794 XNAME(az)));
795 azalia_free_dmamem(az, &az->rirb_dma);
796 return ENOMEM;
797 }
798 bzero(az->unsolq, sizeof(rirb_entry_t) * UNSOLQ_SIZE);
799
800
801 rirbwp = AZ_READ_2(az, RIRBWP);
802 AZ_WRITE_2(az, RIRBWP, rirbwp | HDA_RIRBWP_RIRBWPRST);
803
804
805 az->rirb_rp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP;
806 DPRINTF(("%s: RIRBRP=%d, size=%d\n", __func__, az->rirb_rp, az->rirb_size));
807
808 AZ_WRITE_2(az, RINTCNT, 1);
809
810
811 rirbctl = AZ_READ_1(az, RIRBCTL);
812 AZ_WRITE_1(az, RIRBCTL, rirbctl |
813 HDA_RIRBCTL_RIRBDMAEN | HDA_RIRBCTL_RINTCTL);
814
815 return (0);
816 }
817
818 int
819 azalia_delete_rirb(azalia_t *az)
820 {
821 int i;
822 uint8_t rirbctl;
823
824 if (az->unsolq != NULL) {
825 free(az->unsolq, M_DEVBUF);
826 az->unsolq = NULL;
827 }
828 if (az->rirb_dma.addr == NULL)
829 return 0;
830
831 rirbctl = AZ_READ_1(az, RIRBCTL);
832 AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RIRBDMAEN);
833 for (i = 5000; i >= 0; i--) {
834 DELAY(10);
835 rirbctl = AZ_READ_1(az, RIRBCTL);
836 if ((rirbctl & HDA_RIRBCTL_RIRBDMAEN) == 0)
837 break;
838 }
839 azalia_free_dmamem(az, &az->rirb_dma);
840 return 0;
841 }
842
843 int
844 azalia_set_command(azalia_t *az, int caddr, nid_t nid, uint32_t control,
845 uint32_t param)
846 {
847 corb_entry_t *corb;
848 int wp;
849 uint32_t verb;
850 uint16_t corbwp;
851 uint8_t rirbctl;
852
853 #ifdef DIAGNOSTIC
854 if ((AZ_READ_1(az, CORBCTL) & HDA_CORBCTL_CORBRUN) == 0) {
855 printf("%s: CORB is not running.\n", XNAME(az));
856 return -1;
857 }
858 #endif
859 verb = (caddr << 28) | (nid << 20) | (control << 8) | param;
860 corbwp = AZ_READ_2(az, CORBWP);
861 wp = corbwp & HDA_CORBWP_CORBWP;
862 corb = (corb_entry_t*)az->corb_dma.addr;
863 if (++wp >= az->corb_size)
864 wp = 0;
865 corb[wp] = verb;
866
867
868 rirbctl = AZ_READ_1(az, RIRBCTL);
869 if (rirbctl & HDA_RIRBCTL_RINTCTL) {
870 AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RINTCTL);
871 azalia_rirb_intr(az);
872 }
873
874 AZ_WRITE_2(az, CORBWP, (corbwp & ~HDA_CORBWP_CORBWP) | wp);
875 #if 0
876 DPRINTF(("%s: caddr=%d nid=%d control=0x%x param=0x%x verb=0x%8.8x wp=%d\n",
877 __func__, caddr, nid, control, param, verb, wp));
878 #endif
879 return 0;
880 }
881
882 int
883 azalia_get_response(azalia_t *az, uint32_t *result)
884 {
885 const rirb_entry_t *rirb;
886 int i;
887 uint16_t wp;
888 uint8_t rirbctl;
889
890 #ifdef DIAGNOSTIC
891 if ((AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RIRBDMAEN) == 0) {
892 printf("%s: RIRB is not running.\n", XNAME(az));
893 return -1;
894 }
895 #endif
896 for (i = 5000; i >= 0; i--) {
897 wp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP;
898 if (az->rirb_rp != wp)
899 break;
900 DELAY(10);
901 }
902 if (i <= 0) {
903 printf("%s: RIRB time out\n", XNAME(az));
904 return ETIMEDOUT;
905 }
906 rirb = (rirb_entry_t*)az->rirb_dma.addr;
907 for (;;) {
908 if (++az->rirb_rp >= az->rirb_size)
909 az->rirb_rp = 0;
910 if (rirb[az->rirb_rp].resp_ex & RIRB_RESP_UNSOL) {
911 az->unsolq[az->unsolq_wp].resp = rirb[az->rirb_rp].resp;
912 az->unsolq[az->unsolq_wp++].resp_ex = rirb[az->rirb_rp].resp_ex;
913 az->unsolq_wp %= UNSOLQ_SIZE;
914 } else
915 break;
916 }
917 if (result != NULL)
918 *result = rirb[az->rirb_rp].resp;
919
920 azalia_rirb_kick_unsol_events(az);
921 #if 0
922 for (i = 0; i < 16 ; i++) {
923 DPRINTF(("rirb[%d] 0x%8.8x:0x%8.8x ", i, rirb[i].resp, rirb[i].resp_ex));
924 if ((i % 2) == 1)
925 DPRINTF(("\n"));
926 }
927 #endif
928
929
930 rirbctl = AZ_READ_1(az, RIRBCTL);
931 AZ_WRITE_1(az, RIRBCTL, rirbctl | HDA_RIRBCTL_RINTCTL);
932
933 return 0;
934 }
935
936 void
937 azalia_rirb_kick_unsol_events(azalia_t *az)
938 {
939 if (az->unsolq_kick)
940 return;
941 az->unsolq_kick = TRUE;
942 while (az->unsolq_rp != az->unsolq_wp) {
943 int i;
944 int tag;
945 codec_t *codec;
946 i = RIRB_RESP_CODEC(az->unsolq[az->unsolq_rp].resp_ex);
947 tag = RIRB_UNSOL_TAG(az->unsolq[az->unsolq_rp].resp);
948 codec = &az->codecs[i];
949 DPRINTF(("%s: codec#=%d tag=%d\n", __func__, i, tag));
950 az->unsolq_rp++;
951 az->unsolq_rp %= UNSOLQ_SIZE;
952 if (codec->unsol_event != NULL)
953 codec->unsol_event(codec, tag);
954 }
955 az->unsolq_kick = FALSE;
956 }
957
958 void
959 azalia_rirb_intr(azalia_t *az)
960 {
961 const rirb_entry_t *rirb;
962 uint16_t wp, rp;
963 uint8_t rirbsts;
964
965 rirbsts = AZ_READ_1(az, RIRBSTS);
966
967 wp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP;
968 if (rp == wp)
969 return;
970 rirb = (rirb_entry_t*)az->rirb_dma.addr;
971 while (az->rirb_rp != wp) {
972 if (++az->rirb_rp >= az->rirb_size)
973 az->rirb_rp = 0;
974 if (rirb[az->rirb_rp].resp_ex & RIRB_RESP_UNSOL) {
975 az->unsolq[az->unsolq_wp].resp = rirb[az->rirb_rp].resp;
976 az->unsolq[az->unsolq_wp++].resp_ex = rirb[az->rirb_rp].resp_ex;
977 az->unsolq_wp %= UNSOLQ_SIZE;
978 } else {
979 break;
980 }
981 }
982
983 azalia_rirb_kick_unsol_events(az);
984
985 AZ_WRITE_1(az, RIRBSTS,
986 rirbsts | HDA_RIRBSTS_RIRBOIS | HDA_RIRBSTS_RINTFL);
987 }
988
989 int
990 azalia_alloc_dmamem(azalia_t *az, size_t size, size_t align, azalia_dma_t *d)
991 {
992 int err;
993 int nsegs;
994
995 d->size = size;
996 err = bus_dmamem_alloc(az->dmat, size, align, 0, d->segments, 1,
997 &nsegs, BUS_DMA_NOWAIT);
998 if (err)
999 return err;
1000 if (nsegs != 1)
1001 goto free;
1002 err = bus_dmamem_map(az->dmat, d->segments, 1, size,
1003 &d->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_NOCACHE);
1004 if (err)
1005 goto free;
1006 err = bus_dmamap_create(az->dmat, size, 1, size, 0,
1007 BUS_DMA_NOWAIT, &d->map);
1008 if (err)
1009 goto unmap;
1010 err = bus_dmamap_load(az->dmat, d->map, d->addr, size,
1011 NULL, BUS_DMA_NOWAIT);
1012 if (err)
1013 goto destroy;
1014
1015 if (!az->ok64 && PTR_UPPER32(AZALIA_DMA_DMAADDR(d)) != 0) {
1016 azalia_free_dmamem(az, d);
1017 return -1;
1018 }
1019 return 0;
1020
1021 destroy:
1022 bus_dmamap_destroy(az->dmat, d->map);
1023 unmap:
1024 bus_dmamem_unmap(az->dmat, d->addr, size);
1025 free:
1026 bus_dmamem_free(az->dmat, d->segments, 1);
1027 d->addr = NULL;
1028 return err;
1029 }
1030
1031 int
1032 azalia_free_dmamem(const azalia_t *az, azalia_dma_t* d)
1033 {
1034 if (d->addr == NULL)
1035 return 0;
1036 bus_dmamap_unload(az->dmat, d->map);
1037 bus_dmamap_destroy(az->dmat, d->map);
1038 bus_dmamem_unmap(az->dmat, d->addr, d->size);
1039 bus_dmamem_free(az->dmat, d->segments, 1);
1040 d->addr = NULL;
1041 return 0;
1042 }
1043
1044
1045
1046
1047
1048 int
1049 azalia_codec_init(codec_t *this)
1050 {
1051 uint32_t rev, id, result;
1052 int err, addr, n, i;
1053 const char *vendor;
1054
1055 this->comresp = azalia_codec_comresp;
1056 addr = this->address;
1057 DPRINTF(("%s: information of codec[%d] follows:\n",
1058 XNAME(this->az), addr));
1059
1060 err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
1061 COP_REVISION_ID, &rev);
1062 if (err)
1063 return err;
1064 err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
1065 COP_VENDOR_ID, &id);
1066 if (err)
1067 return err;
1068 this->vid = id;
1069 this->subid = this->az->subid;
1070 azalia_codec_init_vtbl(this);
1071
1072 printf("%s: codec:", XNAME(this->az));
1073 if (this->name == NULL) {
1074 vendor = pci_findvendor(id >> 16);
1075 if (vendor == NULL)
1076 printf(" 0x%04x/0x%04x", id >> 16, id & 0xffff);
1077 else
1078 printf(" %s/0x%04x", vendor, id & 0xffff);
1079 } else
1080 printf(" %s", this->name);
1081 printf(" (rev. %u.%u), HDA version %u.%u\n",
1082 COP_RID_REVISION(rev), COP_RID_STEPPING(rev),
1083 COP_RID_MAJ(rev), COP_RID_MIN(rev));
1084
1085
1086 err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
1087 COP_SUBORDINATE_NODE_COUNT, &result);
1088 if (err)
1089 return err;
1090 this->nfunctions = COP_NSUBNODES(result);
1091 if (COP_NSUBNODES(result) <= 0) {
1092 printf("%s: No function groups\n", XNAME(this->az));
1093 return -1;
1094 }
1095
1096 n = COP_START_NID(result);
1097 DPRINTF(("%s: nidstart=%d #functions=%d\n",
1098 __func__, n, this->nfunctions));
1099 this->audiofunc = -1;
1100 for (i = 0; i < this->nfunctions; i++) {
1101 err = this->comresp(this, n + i, CORB_GET_PARAMETER,
1102 COP_FUNCTION_GROUP_TYPE, &result);
1103 if (err)
1104 continue;
1105 DPRINTF(("%s: FTYPE result = 0x%8.8x\n", __func__, result));
1106 if (COP_FTYPE(result) == COP_FTYPE_AUDIO) {
1107 this->audiofunc = n + i;
1108 break;
1109 } else if (COP_FTYPE(result) == COP_FTYPE_MODEM) {
1110 printf("%s: codec[%d]: No support for modem function groups\n",
1111 XNAME(this->az), addr);
1112 }
1113 }
1114 if (this->audiofunc < 0) {
1115 printf("%s: codec[%d]: No audio function groups\n",
1116 XNAME(this->az), addr);
1117 return -1;
1118 }
1119
1120
1121 this->comresp(this, this->audiofunc, CORB_SET_POWER_STATE, CORB_PS_D0, &result);
1122 DELAY(100);
1123
1124
1125 err = this->comresp(this, this->audiofunc,
1126 CORB_GET_PARAMETER, COP_SUBORDINATE_NODE_COUNT, &result);
1127 if (err)
1128 return err;
1129 DPRINTF(("%s: There are %d widgets in the audio function.\n",
1130 __func__, COP_NSUBNODES(result)));
1131 this->wstart = COP_START_NID(result);
1132 if (this->wstart < 2) {
1133 printf("%s: invalid node structure\n", XNAME(this->az));
1134 return -1;
1135 }
1136 this->wend = this->wstart + COP_NSUBNODES(result);
1137 this->w = malloc(sizeof(widget_t) * this->wend, M_DEVBUF, M_NOWAIT);
1138 if (this->w == NULL) {
1139 printf("%s: out of memory\n", XNAME(this->az));
1140 return ENOMEM;
1141 }
1142 bzero(this->w, sizeof(widget_t) * this->wend);
1143
1144
1145 this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
1146 COP_STREAM_FORMATS, &result);
1147 this->w[this->audiofunc].d.audio.encodings = result;
1148 this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
1149 COP_PCM, &result);
1150 this->w[this->audiofunc].d.audio.bits_rates = result;
1151 this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
1152 COP_INPUT_AMPCAP, &result);
1153 this->w[this->audiofunc].inamp_cap = result;
1154 this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
1155 COP_OUTPUT_AMPCAP, &result);
1156 this->w[this->audiofunc].outamp_cap = result;
1157 #ifdef AZALIA_DEBUG
1158 azalia_widget_print_audio(&this->w[this->audiofunc], "\t");
1159 result = this->w[this->audiofunc].inamp_cap;
1160 DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n",
1161 (result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result),
1162 COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result)));
1163 result = this->w[this->audiofunc].outamp_cap;
1164 DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
1165 (result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result),
1166 COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result)));
1167 #endif
1168
1169 strlcpy(this->w[CORB_NID_ROOT].name, "root",
1170 sizeof(this->w[CORB_NID_ROOT].name));
1171 strlcpy(this->w[this->audiofunc].name, "hdaudio",
1172 sizeof(this->w[this->audiofunc].name));
1173 FOR_EACH_WIDGET(this, i) {
1174 err = azalia_widget_init(&this->w[i], this, i);
1175 if (err)
1176 return err;
1177 }
1178
1179 err = this->init_dacgroup(this);
1180 if (err)
1181 return err;
1182 #ifdef AZALIA_DEBUG
1183 for (i = 0; i < this->dacs.ngroups; i++) {
1184 DPRINTF(("%s: dacgroup[%d]:", __func__, i));
1185 for (n = 0; n < this->dacs.groups[i].nconv; n++) {
1186 DPRINTF((" %2.2x", this->dacs.groups[i].conv[n]));
1187 }
1188 DPRINTF(("\n"));
1189 }
1190 #endif
1191
1192
1193 this->dacs.cur = -1;
1194 this->adcs.cur = -1;
1195 err = azalia_codec_construct_format(this, 0, 0);
1196 if (err)
1197 return err;
1198
1199 return this->mixer_init(this);
1200 }
1201
1202 int
1203 azalia_codec_delete(codec_t *this)
1204 {
1205 if (this->mixer_delete != NULL)
1206 this->mixer_delete(this);
1207 if (this->formats != NULL) {
1208 free(this->formats, M_DEVBUF);
1209 this->formats = NULL;
1210 }
1211 printf("delete_encodings...\n");
1212 auconv_delete_encodings(this->encodings);
1213 this->encodings = NULL;
1214 return 0;
1215 }
1216
1217 int
1218 azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
1219 {
1220 const convgroup_t *group;
1221 uint32_t bits_rates;
1222 int prev_dac, prev_adc;
1223 int pvariation, rvariation;
1224 int nbits, c, chan, i, err;
1225 nid_t nid;
1226
1227 prev_dac = this->dacs.cur;
1228 this->dacs.cur = newdac;
1229 group = &this->dacs.groups[this->dacs.cur];
1230 bits_rates = this->w[group->conv[0]].d.audio.bits_rates;
1231 nbits = 0;
1232 if (bits_rates & COP_PCM_B8)
1233 nbits++;
1234 if (bits_rates & COP_PCM_B16)
1235 nbits++;
1236 if (bits_rates & COP_PCM_B20)
1237 nbits++;
1238 if (bits_rates & COP_PCM_B24)
1239 nbits++;
1240 if (bits_rates & COP_PCM_B32)
1241 nbits++;
1242 if (nbits == 0) {
1243 printf("%s: %s/%d invalid PCM format: 0x%8.8x\n",
1244 XNAME(this->az), __FILE__, __LINE__, bits_rates);
1245 return -1;
1246 }
1247 pvariation = group->nconv * nbits;
1248
1249 prev_adc = this->adcs.cur;
1250 this->adcs.cur = newadc;
1251 group = &this->adcs.groups[this->adcs.cur];
1252 bits_rates = this->w[group->conv[0]].d.audio.bits_rates;
1253 nbits = 0;
1254 if (bits_rates & COP_PCM_B8)
1255 nbits++;
1256 if (bits_rates & COP_PCM_B16)
1257 nbits++;
1258 if (bits_rates & COP_PCM_B20)
1259 nbits++;
1260 if (bits_rates & COP_PCM_B24)
1261 nbits++;
1262 if (bits_rates & COP_PCM_B32)
1263 nbits++;
1264 if (nbits == 0) {
1265 printf("%s: %s/%d invalid PCM format: 0x%8.8x\n",
1266 XNAME(this->az), __FILE__, __LINE__, bits_rates);
1267 return -1;
1268 }
1269 rvariation = group->nconv * nbits;
1270
1271 if (this->formats != NULL)
1272 free(this->formats, M_DEVBUF);
1273 this->nformats = 0;
1274 this->formats = malloc(sizeof(struct audio_format) *
1275 (pvariation + rvariation), M_DEVBUF, M_NOWAIT);
1276 if (this->formats == NULL) {
1277 printf("%s: out of memory in %s\n",
1278 XNAME(this->az), __func__);
1279 return ENOMEM;
1280 }
1281 bzero(this->formats, sizeof(struct audio_format) *
1282 (pvariation + rvariation));
1283
1284
1285 group = &this->dacs.groups[this->dacs.cur];
1286 nid = group->conv[0];
1287 chan = 0;
1288 bits_rates = this->w[nid].d.audio.bits_rates;
1289 for (c = 0; c < group->nconv; c++) {
1290 for (chan = 0, i = 0; i <= c; i++)
1291 chan += WIDGET_CHANNELS(&this->w[group->conv[c]]);
1292 azalia_codec_add_bits(this, chan, bits_rates, AUMODE_PLAY);
1293 }
1294
1295
1296 group = &this->adcs.groups[this->adcs.cur];
1297 nid = group->conv[0];
1298 chan = 0;
1299 bits_rates = this->w[nid].d.audio.bits_rates;
1300 for (c = 0; c < group->nconv; c++) {
1301 for (chan = 0, i = 0; i <= c; i++)
1302 chan += WIDGET_CHANNELS(&this->w[group->conv[c]]);
1303 azalia_codec_add_bits(this, chan, bits_rates, AUMODE_RECORD);
1304 }
1305
1306 err = azalia_create_encodings(this->formats, this->nformats,
1307 &this->encodings);
1308 if (err)
1309 return err;
1310 return 0;
1311 }
1312
1313 void
1314 azalia_codec_add_bits(codec_t *this, int chan, uint32_t bits_rates, int mode)
1315 {
1316 if (bits_rates & COP_PCM_B8)
1317 azalia_codec_add_format(this, chan, 8, 16, bits_rates, mode);
1318 if (bits_rates & COP_PCM_B16)
1319 azalia_codec_add_format(this, chan, 16, 16, bits_rates, mode);
1320 if (bits_rates & COP_PCM_B20)
1321 azalia_codec_add_format(this, chan, 20, 32, bits_rates, mode);
1322 if (bits_rates & COP_PCM_B24)
1323 azalia_codec_add_format(this, chan, 24, 32, bits_rates, mode);
1324 if (bits_rates & COP_PCM_B32)
1325 azalia_codec_add_format(this, chan, 32, 32, bits_rates, mode);
1326 }
1327
1328 void
1329 azalia_codec_add_format(codec_t *this, int chan, int valid, int prec,
1330 uint32_t rates, int32_t mode)
1331 {
1332 struct audio_format *f;
1333
1334 f = &this->formats[this->nformats++];
1335 f->mode = mode;
1336 f->encoding = AUDIO_ENCODING_SLINEAR_LE;
1337 if (valid == 8 && prec == 8)
1338 f->encoding = AUDIO_ENCODING_ULINEAR_LE;
1339 f->validbits = valid;
1340 f->precision = prec;
1341 f->channels = chan;
1342 switch (chan) {
1343 case 1:
1344 f->channel_mask = AUFMT_MONAURAL;
1345 break;
1346 case 2:
1347 f->channel_mask = AUFMT_STEREO;
1348 break;
1349 case 4:
1350 f->channel_mask = AUFMT_SURROUND4;
1351 break;
1352 case 6:
1353 f->channel_mask = AUFMT_DOLBY_5_1;
1354 break;
1355 case 8:
1356 f->channel_mask = AUFMT_DOLBY_5_1
1357 | AUFMT_SIDE_LEFT | AUFMT_SIDE_RIGHT;
1358 break;
1359 default:
1360 f->channel_mask = 0;
1361 }
1362 if (rates & COP_PCM_R80)
1363 f->frequency[f->frequency_type++] = 8000;
1364 if (rates & COP_PCM_R110)
1365 f->frequency[f->frequency_type++] = 11025;
1366 if (rates & COP_PCM_R160)
1367 f->frequency[f->frequency_type++] = 16000;
1368 if (rates & COP_PCM_R220)
1369 f->frequency[f->frequency_type++] = 22050;
1370 if (rates & COP_PCM_R320)
1371 f->frequency[f->frequency_type++] = 32000;
1372 if (rates & COP_PCM_R441)
1373 f->frequency[f->frequency_type++] = 44100;
1374 if (rates & COP_PCM_R480)
1375 f->frequency[f->frequency_type++] = 48000;
1376 if (rates & COP_PCM_R882)
1377 f->frequency[f->frequency_type++] = 88200;
1378 if (rates & COP_PCM_R960)
1379 f->frequency[f->frequency_type++] = 96000;
1380 if (rates & COP_PCM_R1764)
1381 f->frequency[f->frequency_type++] = 176400;
1382 if (rates & COP_PCM_R1920)
1383 f->frequency[f->frequency_type++] = 192000;
1384 if (rates & COP_PCM_R3840)
1385 f->frequency[f->frequency_type++] = 384000;
1386 }
1387
1388 int
1389 azalia_codec_comresp(const codec_t *codec, nid_t nid, uint32_t control,
1390 uint32_t param, uint32_t* result)
1391 {
1392 int err;
1393
1394 err = azalia_set_command(codec->az, codec->address, nid, control, param);
1395 if (err)
1396 return err;
1397 return azalia_get_response(codec->az, result);
1398 }
1399
1400 int
1401 azalia_codec_connect_stream(codec_t *this, int dir, uint16_t fmt, int number)
1402 {
1403 const convgroup_t *group;
1404 int i, err, startchan, nchan;
1405 nid_t nid;
1406 boolean_t flag222;
1407
1408 DPRINTF(("%s: fmt=0x%4.4x number=%d\n", __func__, fmt, number));
1409 err = 0;
1410 if (dir == AUMODE_RECORD)
1411 group = &this->adcs.groups[this->adcs.cur];
1412 else
1413 group = &this->dacs.groups[this->dacs.cur];
1414 flag222 = group->nconv >= 3 &&
1415 (WIDGET_CHANNELS(&this->w[group->conv[0]]) == 2) &&
1416 (WIDGET_CHANNELS(&this->w[group->conv[1]]) == 2) &&
1417 (WIDGET_CHANNELS(&this->w[group->conv[2]]) == 2);
1418 nchan = (fmt & HDA_SD_FMT_CHAN) + 1;
1419 startchan = 0;
1420 for (i = 0; i < group->nconv; i++) {
1421 nid = group->conv[i];
1422
1423
1424 if (nchan >= 6 && flag222 && i == 1) {
1425 nid = group->conv[2];
1426 } else if (nchan >= 6 && flag222 && i == 2) {
1427 nid = group->conv[1];
1428 }
1429
1430 err = this->comresp(this, nid, CORB_SET_CONVERTER_FORMAT, fmt, NULL);
1431 if (err)
1432 goto exit;
1433 err = this->comresp(this, nid, CORB_SET_CONVERTER_STREAM_CHANNEL,
1434 (number << 4) | startchan, NULL);
1435 if (err)
1436 goto exit;
1437 if (nchan > 2)
1438 startchan += WIDGET_CHANNELS(&this->w[nid]);
1439 }
1440
1441 exit:
1442 DPRINTF(("%s: leave with %d\n", __func__, err));
1443 return err;
1444 }
1445
1446
1447
1448
1449
1450 #define WIDGETCAP_BITS \
1451 "\20\014LRSWAP\013POWER\012DIGITAL" \
1452 "\011CONNLIST\010UNSOL\07PROC\06STRIPE\05FORMATOV\04AMPOV\03OUTAMP" \
1453 "\02INAMP\01STEREO"
1454
1455 int
1456 azalia_widget_init(widget_t *this, const codec_t *codec, nid_t nid)
1457 {
1458 uint32_t result;
1459 int err;
1460
1461 err = codec->comresp(codec, nid, CORB_GET_PARAMETER,
1462 COP_AUDIO_WIDGET_CAP, &result);
1463 if (err)
1464 return err;
1465 this->nid = nid;
1466 this->widgetcap = result;
1467 this->type = COP_AWCAP_TYPE(result);
1468 DPRINTF(("%s: ", XNAME(codec->az)));
1469 if (this->widgetcap & COP_AWCAP_POWER) {
1470 codec->comresp(codec, nid, CORB_SET_POWER_STATE, CORB_PS_D0, &result);
1471 DELAY(100);
1472 }
1473 switch (this->type) {
1474 case COP_AWTYPE_AUDIO_OUTPUT:
1475 snprintf(this->name, sizeof(this->name), "dac%2.2x", nid);
1476 DPRINTF(("%s wcap=%b\n", this->name,
1477 this->widgetcap, WIDGETCAP_BITS));
1478 azalia_widget_init_audio(this, codec);
1479 break;
1480 case COP_AWTYPE_AUDIO_INPUT:
1481 snprintf(this->name, sizeof(this->name), "adc%2.2x", nid);
1482 DPRINTF(("%s wcap=%b\n", this->name,
1483 this->widgetcap, WIDGETCAP_BITS));
1484 azalia_widget_init_audio(this, codec);
1485 break;
1486 case COP_AWTYPE_AUDIO_MIXER:
1487 snprintf(this->name, sizeof(this->name), "mix%2.2x", nid);
1488 DPRINTF(("%s wcap=%b\n", this->name,
1489 this->widgetcap, WIDGETCAP_BITS));
1490 break;
1491 case COP_AWTYPE_AUDIO_SELECTOR:
1492 snprintf(this->name, sizeof(this->name), "sel%2.2x", nid);
1493 DPRINTF(("%s wcap=%b\n", this->name,
1494 this->widgetcap, WIDGETCAP_BITS));
1495 break;
1496 case COP_AWTYPE_PIN_COMPLEX:
1497 azalia_widget_init_pin(this, codec);
1498 snprintf(this->name, sizeof(this->name), "%s%2.2x",
1499 pin_colors[this->d.pin.color], nid);
1500 DPRINTF(("%s wcap=%b\n", this->name,
1501 this->widgetcap, WIDGETCAP_BITS));
1502 azalia_widget_print_pin(this);
1503 break;
1504 case COP_AWTYPE_POWER:
1505 snprintf(this->name, sizeof(this->name), "pow%2.2x", nid);
1506 DPRINTF(("%s wcap=%b\n", this->name,
1507 this->widgetcap, WIDGETCAP_BITS));
1508 break;
1509 case COP_AWTYPE_VOLUME_KNOB:
1510 snprintf(this->name, sizeof(this->name), "volume%2.2x", nid);
1511 DPRINTF(("%s wcap=%b\n", this->name,
1512 this->widgetcap, WIDGETCAP_BITS));
1513 err = codec->comresp(codec, nid, CORB_GET_PARAMETER,
1514 COP_VOLUME_KNOB_CAPABILITIES, &result);
1515 if (!err) {
1516 this->d.volume.cap = result;
1517 DPRINTF(("\tdelta=%d steps=%d\n",
1518 !!(result & COP_VKCAP_DELTA),
1519 COP_VKCAP_NUMSTEPS(result)));
1520 }
1521 break;
1522 case COP_AWTYPE_BEEP_GENERATOR:
1523 snprintf(this->name, sizeof(this->name), "beep%2.2x", nid);
1524 DPRINTF(("%s wcap=%b\n", this->name,
1525 this->widgetcap, WIDGETCAP_BITS));
1526 break;
1527 default:
1528 snprintf(this->name, sizeof(this->name), "widget%2.2x", nid);
1529 DPRINTF(("%s wcap=%b\n", this->name,
1530 this->widgetcap, WIDGETCAP_BITS));
1531 break;
1532 }
1533 azalia_widget_init_connection(this, codec);
1534
1535
1536 if (this->widgetcap & COP_AWCAP_INAMP) {
1537 if (this->widgetcap & COP_AWCAP_AMPOV)
1538 codec->comresp(codec, nid, CORB_GET_PARAMETER,
1539 COP_INPUT_AMPCAP, &this->inamp_cap);
1540 else
1541 this->inamp_cap = codec->w[codec->audiofunc].inamp_cap;
1542 DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n",
1543 (this->inamp_cap & COP_AMPCAP_MUTE) != 0,
1544 COP_AMPCAP_STEPSIZE(this->inamp_cap),
1545 COP_AMPCAP_NUMSTEPS(this->inamp_cap),
1546 COP_AMPCAP_OFFSET(this->inamp_cap)));
1547 }
1548 if (this->widgetcap & COP_AWCAP_OUTAMP) {
1549 if (this->widgetcap & COP_AWCAP_AMPOV)
1550 codec->comresp(codec, nid, CORB_GET_PARAMETER,
1551 COP_OUTPUT_AMPCAP, &this->outamp_cap);
1552 else
1553 this->outamp_cap = codec->w[codec->audiofunc].outamp_cap;
1554 DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
1555 (this->outamp_cap & COP_AMPCAP_MUTE) != 0,
1556 COP_AMPCAP_STEPSIZE(this->outamp_cap),
1557 COP_AMPCAP_NUMSTEPS(this->outamp_cap),
1558 COP_AMPCAP_OFFSET(this->outamp_cap)));
1559 }
1560 if (codec->init_widget != NULL)
1561 codec->init_widget(codec, this, nid);
1562 return 0;
1563 }
1564
1565 int
1566 azalia_widget_init_audio(widget_t *this, const codec_t *codec)
1567 {
1568 uint32_t result;
1569 int err;
1570
1571
1572 if (this->widgetcap & COP_AWCAP_FORMATOV) {
1573 err = codec->comresp(codec, this->nid,
1574 CORB_GET_PARAMETER, COP_STREAM_FORMATS, &result);
1575 if (err)
1576 return err;
1577 this->d.audio.encodings = result;
1578 if (result == 0) {
1579
1580 this->d.audio.encodings =
1581 codec->w[codec->audiofunc].d.audio.encodings;
1582 this->d.audio.bits_rates =
1583 codec->w[codec->audiofunc].d.audio.bits_rates;
1584 } else {
1585 if ((result & COP_STREAM_FORMAT_PCM) == 0) {
1586 printf("%s: %s: No PCM support: %x\n",
1587 XNAME(codec->az), this->name, result);
1588 return -1;
1589 }
1590 err = codec->comresp(codec, this->nid, CORB_GET_PARAMETER,
1591 COP_PCM, &result);
1592 if (err)
1593 return err;
1594 this->d.audio.bits_rates = result;
1595 }
1596 this->d.audio.bits_rates = result;
1597 } else {
1598 this->d.audio.encodings =
1599 codec->w[codec->audiofunc].d.audio.encodings;
1600 this->d.audio.bits_rates =
1601 codec->w[codec->audiofunc].d.audio.bits_rates;
1602 }
1603 #ifdef AZALIA_DEBUG
1604 azalia_widget_print_audio(this, "\t");
1605 #endif
1606 return 0;
1607 }
1608
1609 #define ENCODING_BITS "\20\3AC3\2FLOAT32\1PCM"
1610 #define BITSRATES_BITS "\20\x15""32bit\x14""24bit\x13""20bit" \
1611 "\x12""16bit\x11""8bit""\x0c""384kHz\x0b""192kHz\x0a""176.4kHz" \
1612 "\x09""96kHz\x08""88.2kHz\x07""48kHz\x06""44.1kHz\x05""32kHz\x04" \
1613 "22.05kHz\x03""16kHz\x02""11.025kHz\x01""8kHz"
1614
1615 int
1616 azalia_widget_print_audio(const widget_t *this, const char *lead)
1617 {
1618 printf("%sencodings=%b\n", lead, this->d.audio.encodings,
1619 ENCODING_BITS);
1620 printf("%sPCM formats=%b\n", lead, this->d.audio.bits_rates,
1621 BITSRATES_BITS);
1622 return 0;
1623 }
1624
1625 int
1626 azalia_widget_init_pin(widget_t *this, const codec_t *codec)
1627 {
1628 uint32_t result;
1629 int err;
1630
1631 err = codec->comresp(codec, this->nid, CORB_GET_CONFIGURATION_DEFAULT,
1632 0, &result);
1633 if (err)
1634 return err;
1635 this->d.pin.config = result;
1636 this->d.pin.sequence = CORB_CD_SEQUENCE(result);
1637 this->d.pin.association = CORB_CD_ASSOCIATION(result);
1638 this->d.pin.color = CORB_CD_COLOR(result);
1639 this->d.pin.device = CORB_CD_DEVICE(result);
1640
1641 err = codec->comresp(codec, this->nid, CORB_GET_PARAMETER,
1642 COP_PINCAP, &result);
1643 if (err)
1644 return err;
1645 this->d.pin.cap = result;
1646 return 0;
1647 }
1648
1649 #define PINCAP_BITS "\20\021EAPD\07BALANCE\06INPUT" \
1650 "\05OUTPUT\04HEADPHONE\03PRESENCE\02TRIGGER\01IMPEDANCE"
1651
1652 int
1653 azalia_widget_print_pin(const widget_t *this)
1654 {
1655 DPRINTF(("\tpin config; device=%s color=%s assoc=%d seq=%d",
1656 pin_devices[this->d.pin.device], pin_colors[this->d.pin.color],
1657 this->d.pin.association, this->d.pin.sequence));
1658 DPRINTF((" cap=%b\n", this->d.pin.cap, PINCAP_BITS));
1659 return 0;
1660 }
1661
1662 int
1663 azalia_widget_init_connection(widget_t *this, const codec_t *codec)
1664 {
1665 uint32_t result;
1666 int err;
1667 boolean_t longform;
1668 int length, i;
1669
1670 this->selected = -1;
1671 if ((this->widgetcap & COP_AWCAP_CONNLIST) == 0)
1672 return 0;
1673
1674 err = codec->comresp(codec, this->nid, CORB_GET_PARAMETER,
1675 COP_CONNECTION_LIST_LENGTH, &result);
1676 if (err)
1677 return err;
1678 longform = (result & COP_CLL_LONG) != 0;
1679 length = COP_CLL_LENGTH(result);
1680 if (length == 0)
1681 return 0;
1682 this->nconnections = length;
1683 this->connections = malloc(sizeof(nid_t) * (length + 3),
1684 M_DEVBUF, M_NOWAIT);
1685 if (this->connections == NULL) {
1686 printf("%s: out of memory\n", XNAME(codec->az));
1687 return ENOMEM;
1688 }
1689 if (longform) {
1690 for (i = 0; i < length;) {
1691 err = codec->comresp(codec, this->nid,
1692 CORB_GET_CONNECTION_LIST_ENTRY, i, &result);
1693 if (err)
1694 return err;
1695 this->connections[i++] = CORB_CLE_LONG_0(result);
1696 this->connections[i++] = CORB_CLE_LONG_1(result);
1697 }
1698 } else {
1699 for (i = 0; i < length;) {
1700 err = codec->comresp(codec, this->nid,
1701 CORB_GET_CONNECTION_LIST_ENTRY, i, &result);
1702 if (err)
1703 return err;
1704 this->connections[i++] = CORB_CLE_SHORT_0(result);
1705 this->connections[i++] = CORB_CLE_SHORT_1(result);
1706 this->connections[i++] = CORB_CLE_SHORT_2(result);
1707 this->connections[i++] = CORB_CLE_SHORT_3(result);
1708 }
1709 }
1710 if (length > 0) {
1711 DPRINTF(("\tconnections=0x%x", this->connections[0]));
1712 for (i = 1; i < length; i++) {
1713 DPRINTF((",0x%x", this->connections[i]));
1714 }
1715
1716 err = codec->comresp(codec, this->nid,
1717 CORB_GET_CONNECTION_SELECT_CONTROL, 0, &result);
1718 if (err)
1719 return err;
1720 this->selected = CORB_CSC_INDEX(result);
1721 DPRINTF(("; selected=0x%x\n", this->connections[result]));
1722 }
1723 return 0;
1724 }
1725
1726
1727
1728
1729
1730 int
1731 azalia_stream_init(stream_t *this, azalia_t *az, int regindex, int strnum, int dir)
1732 {
1733 int err;
1734
1735 this->az = az;
1736 this->regbase = HDA_SD_BASE + regindex * HDA_SD_SIZE;
1737 this->intr_bit = 1 << regindex;
1738 this->number = strnum;
1739 this->dir = dir;
1740
1741
1742 err = azalia_alloc_dmamem(az, sizeof(bdlist_entry_t) * HDA_BDL_MAX,
1743 128, &this->bdlist);
1744 if (err) {
1745 printf("%s: can't allocate a BDL buffer\n", XNAME(az));
1746 return err;
1747 }
1748 return 0;
1749 }
1750
1751 int
1752 azalia_stream_delete(stream_t *this, azalia_t *az)
1753 {
1754 if (this->bdlist.addr == NULL)
1755 return 0;
1756 azalia_free_dmamem(az, &this->bdlist);
1757 return 0;
1758 }
1759
1760 int
1761 azalia_stream_reset(stream_t *this)
1762 {
1763 int i;
1764 uint16_t ctl;
1765 uint8_t sts;
1766
1767
1768 ctl = STR_READ_2(this, CTL);
1769 ctl &= ~HDA_SD_CTL_RUN;
1770 STR_WRITE_2(this, CTL, ctl);
1771
1772
1773 ctl = STR_READ_2(this, CTL);
1774 STR_WRITE_2(this, CTL, ctl | HDA_SD_CTL_SRST);
1775 for (i = 5000; i >= 0; i--) {
1776 DELAY(10);
1777 ctl = STR_READ_2(this, CTL);
1778 if (ctl & HDA_SD_CTL_SRST)
1779 break;
1780 }
1781 if (i <= 0) {
1782 printf("%s: stream reset failure 1\n", XNAME(this->az));
1783 return -1;
1784 }
1785
1786
1787 STR_WRITE_2(this, CTL, ctl & ~HDA_SD_CTL_SRST);
1788 for (i = 5000; i >= 0; i--) {
1789 DELAY(10);
1790 ctl = STR_READ_2(this, CTL);
1791 if ((ctl & HDA_SD_CTL_SRST) == 0)
1792 break;
1793 }
1794 if (i <= 0) {
1795 printf("%s: stream reset failure 2\n", XNAME(this->az));
1796 return -1;
1797 }
1798
1799 sts = STR_READ_1(this, STS);
1800 sts |= HDA_SD_STS_DESE | HDA_SD_STS_FIFOE | HDA_SD_STS_BCIS;
1801 STR_WRITE_1(this, STS, sts);
1802
1803 return (0);
1804 }
1805
1806 int
1807 azalia_stream_start(stream_t *this, void *start, void *end, int blk,
1808 void (*intr)(void *), void *arg, uint16_t fmt)
1809 {
1810 bdlist_entry_t *bdlist;
1811 bus_addr_t dmaaddr, dmaend;
1812 int err, index;
1813 uint32_t intctl;
1814 uint8_t ctl2;
1815
1816 this->intr = intr;
1817 this->intr_arg = arg;
1818
1819 err = azalia_stream_reset(this);
1820 if (err) {
1821 printf("%s: stream reset failed\n", "azalia");
1822 return err;
1823 }
1824
1825 STR_WRITE_4(this, BDPL, 0);
1826 STR_WRITE_4(this, BDPU, 0);
1827
1828
1829 dmaaddr = AZALIA_DMA_DMAADDR(&this->buffer);
1830 dmaend = dmaaddr + ((caddr_t)end - (caddr_t)start);
1831 bdlist = (bdlist_entry_t*)this->bdlist.addr;
1832 for (index = 0; index < HDA_BDL_MAX; index++) {
1833 bdlist[index].low = htole32(dmaaddr);
1834 bdlist[index].high = htole32(PTR_UPPER32(dmaaddr));
1835 bdlist[index].length = htole32(blk);
1836 bdlist[index].flags = htole32(BDLIST_ENTRY_IOC);
1837 dmaaddr += blk;
1838 if (dmaaddr >= dmaend) {
1839 index++;
1840 break;
1841 }
1842 }
1843
1844 dmaaddr = AZALIA_DMA_DMAADDR(&this->bdlist);
1845 STR_WRITE_4(this, BDPL, dmaaddr);
1846 STR_WRITE_4(this, BDPU, PTR_UPPER32(dmaaddr));
1847 STR_WRITE_2(this, LVI, (index - 1) & HDA_SD_LVI_LVI);
1848 ctl2 = STR_READ_1(this, CTL2);
1849 STR_WRITE_1(this, CTL2,
1850 (ctl2 & ~HDA_SD_CTL2_STRM) | (this->number << HDA_SD_CTL2_STRM_SHIFT));
1851 STR_WRITE_4(this, CBL, ((caddr_t)end - (caddr_t)start));
1852 STR_WRITE_2(this, FMT, fmt);
1853
1854 err = azalia_codec_connect_stream(&this->az->codecs[this->az->codecno],
1855 this->dir, fmt, this->number);
1856 if (err)
1857 return EINVAL;
1858
1859 intctl = AZ_READ_4(this->az, INTCTL);
1860 intctl |= this->intr_bit;
1861 AZ_WRITE_4(this->az, INTCTL, intctl);
1862
1863 STR_WRITE_1(this, CTL, STR_READ_1(this, CTL) |
1864 HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE |
1865 HDA_SD_CTL_RUN);
1866
1867 return (0);
1868 }
1869
1870 int
1871 azalia_stream_halt(stream_t *this)
1872 {
1873 uint16_t ctl;
1874
1875 ctl = STR_READ_2(this, CTL);
1876 ctl &= ~(HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | HDA_SD_CTL_RUN);
1877 STR_WRITE_2(this, CTL, ctl);
1878 AZ_WRITE_4(this->az, INTCTL,
1879 AZ_READ_4(this->az, INTCTL) & ~this->intr_bit);
1880 return (0);
1881 }
1882
1883 #define HDA_SD_STS_BITS "\20\3BCIS\4FIFOE\5DESE\6FIFORDY"
1884
1885 int
1886 azalia_stream_intr(stream_t *this, uint32_t intsts)
1887 {
1888 u_int8_t sts;
1889
1890 if ((intsts & this->intr_bit) == 0)
1891 return (0);
1892
1893 sts = STR_READ_1(this, STS);
1894 STR_WRITE_1(this, STS, sts |
1895 HDA_SD_STS_DESE | HDA_SD_STS_FIFOE | HDA_SD_STS_BCIS);
1896
1897 if (sts & (HDA_SD_STS_DESE | HDA_SD_STS_FIFOE))
1898 printf("%s: stream %d: sts=%b\n", XNAME(this->az),
1899 this->number, sts, HDA_SD_STS_BITS);
1900 if (sts & HDA_SD_STS_BCIS)
1901 this->intr(this->intr_arg);
1902 return (1);
1903 }
1904
1905
1906
1907
1908
1909 int
1910 azalia_open(void *v, int flags)
1911 {
1912 azalia_t *az;
1913 codec_t *codec;
1914
1915 DPRINTF(("%s: flags=0x%x\n", __func__, flags));
1916 az = v;
1917 codec = &az->codecs[az->codecno];
1918 codec->running++;
1919 return 0;
1920 }
1921
1922 void
1923 azalia_close(void *v)
1924 {
1925 azalia_t *az;
1926 codec_t *codec;
1927
1928 DPRINTF(("%s\n", __func__));
1929 az = v;
1930 codec = &az->codecs[az->codecno];
1931 codec->running--;
1932 }
1933
1934 int
1935 azalia_query_encoding(void *v, audio_encoding_t *enc)
1936 {
1937 azalia_t *az;
1938 codec_t *codec;
1939 int i, j;
1940
1941 az = v;
1942 codec = &az->codecs[az->codecno];
1943 for (j = 0, i = 0; j < codec->nformats; j++) {
1944 if (codec->formats[j].validbits !=
1945 codec->formats[j].precision)
1946 continue;
1947 if (i == enc->index) {
1948 enc->encoding = codec->formats[j].encoding;
1949 enc->precision = codec->formats[j].precision;
1950 switch (enc->encoding) {
1951 case AUDIO_ENCODING_SLINEAR_LE:
1952 strlcpy(enc->name, enc->precision == 8 ?
1953 AudioEslinear : AudioEslinear_le,
1954 sizeof enc->name);
1955 break;
1956 case AUDIO_ENCODING_ULINEAR_LE:
1957 strlcpy(enc->name, enc->precision == 8 ?
1958 AudioEulinear : AudioEulinear_le,
1959 sizeof enc->name);
1960 break;
1961 default:
1962 strlcpy(enc->name, "unknown", sizeof enc->name);
1963 break;
1964 }
1965 return (0);
1966 }
1967 i++;
1968 }
1969 return (EINVAL);
1970 }
1971
1972 int
1973 azalia_set_params(void *v, int smode, int umode, audio_params_t *p,
1974 audio_params_t *r)
1975 {
1976 azalia_t *az;
1977 codec_t *codec;
1978 void (*pswcode)(void *, u_char *, int) = NULL;
1979 void (*rswcode)(void *, u_char *, int) = NULL;
1980 int i, j;
1981
1982 az = v;
1983 codec = &az->codecs[az->codecno];
1984 if (smode & AUMODE_RECORD && r != NULL) {
1985 if (r->encoding == AUDIO_ENCODING_ULAW) {
1986 r->encoding = AUDIO_ENCODING_SLINEAR_LE;
1987 r->precision = 16;
1988 r->channels = 2;
1989 r->sample_rate = 44100;
1990 }
1991 for (i = 0; i < codec->nformats; i++) {
1992 if (r->encoding != codec->formats[i].encoding)
1993 continue;
1994 if (r->precision != codec->formats[i].precision)
1995 continue;
1996 if (r->channels != codec->formats[i].channels)
1997 continue;
1998 break;
1999 }
2000 if (i == codec->nformats) {
2001 printf("didn't find Record format %u/%u/%u\n",
2002 r->encoding, r->precision, r->channels);
2003 return (EINVAL);
2004 }
2005 for (j = 0; j < codec->formats[i].frequency_type; j++) {
2006 if (r->sample_rate != codec->formats[i].frequency[j])
2007 continue;
2008 break;
2009 }
2010 if (j == codec->formats[i].frequency_type) {
2011 printf("didn't find Record rate %u\n",
2012 r->sample_rate);
2013 return (EINVAL);
2014 }
2015 r->sw_code = rswcode;
2016 }
2017 if (smode & AUMODE_PLAY && p != NULL) {
2018 if (p->encoding == AUDIO_ENCODING_ULAW) {
2019 p->encoding = AUDIO_ENCODING_SLINEAR_LE;
2020 p->precision = 16;
2021 p->channels = 2;
2022 p->sample_rate = 44100;
2023 }
2024 for (i = 0; i < codec->nformats; i++) {
2025 if (p->encoding != codec->formats[i].encoding)
2026 continue;
2027 if (p->precision != codec->formats[i].precision)
2028 continue;
2029 if (p->channels != codec->formats[i].channels)
2030 continue;
2031 break;
2032 }
2033 if (i == codec->nformats) {
2034 printf("can't find playback format %u/%u/%u\n",
2035 r->encoding, r->precision, r->channels);
2036 return (EINVAL);
2037 }
2038 for (j = 0; j < codec->formats[i].frequency_type; j++) {
2039 if (p->sample_rate != codec->formats[i].frequency[j])
2040 continue;
2041 break;
2042 }
2043 if (j == codec->formats[i].frequency_type) {
2044 printf("can't find playback rate %u\n",
2045 p->sample_rate);
2046 return (EINVAL);
2047 }
2048 p->sw_code = pswcode;
2049 }
2050
2051 return (0);
2052 }
2053
2054 int
2055 azalia_round_blocksize(void *v, int blk)
2056 {
2057 azalia_t *az;
2058 size_t size;
2059
2060 blk &= ~0x7f;
2061 if (blk <= 0)
2062 blk = 128;
2063
2064 az = v;
2065 size = az->pstream.buffer.size;
2066 #ifdef DIAGNOSTIC
2067 if (size <= 0) {
2068 printf("%s: size is 0", __func__);
2069 return 256;
2070 }
2071 #endif
2072 if (size > HDA_BDL_MAX * blk) {
2073 blk = size / HDA_BDL_MAX;
2074 if (blk & 0x7f)
2075 blk = (blk + 0x7f) & ~0x7f;
2076 }
2077 DPRINTF(("%s: resultant block size = %d\n", __func__, blk));
2078 return blk;
2079 }
2080
2081 int
2082 azalia_halt_output(void *v)
2083 {
2084 azalia_t *az;
2085
2086 DPRINTF(("%s\n", __func__));
2087 az = v;
2088 return azalia_stream_halt(&az->pstream);
2089 }
2090
2091 int
2092 azalia_halt_input(void *v)
2093 {
2094 azalia_t *az;
2095
2096 DPRINTF(("%s\n", __func__));
2097 az = v;
2098 return azalia_stream_halt(&az->rstream);
2099 }
2100
2101 int
2102 azalia_getdev(void *v, struct audio_device *dev)
2103 {
2104 azalia_t *az;
2105
2106 az = v;
2107 strlcpy(dev->name, "HD-Audio", MAX_AUDIO_DEV_LEN);
2108 snprintf(dev->version, MAX_AUDIO_DEV_LEN,
2109 "%d.%d", AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN));
2110 strlcpy(dev->config, XNAME(az), MAX_AUDIO_DEV_LEN);
2111 return 0;
2112 }
2113
2114 int
2115 azalia_set_port(void *v, mixer_ctrl_t *mc)
2116 {
2117 azalia_t *az;
2118 codec_t *co;
2119
2120 az = v;
2121 co = &az->codecs[az->codecno];
2122 return co->set_port(co, mc);
2123 }
2124
2125 int
2126 azalia_get_port(void *v, mixer_ctrl_t *mc)
2127 {
2128 azalia_t *az;
2129 codec_t *co;
2130
2131 az = v;
2132 co = &az->codecs[az->codecno];
2133 return co->get_port(co, mc);
2134 }
2135
2136 int
2137 azalia_query_devinfo(void *v, mixer_devinfo_t *mdev)
2138 {
2139 azalia_t *az;
2140 const codec_t *co;
2141
2142 az = v;
2143 co = &az->codecs[az->codecno];
2144 if (mdev->index >= co->nmixers)
2145 return ENXIO;
2146 *mdev = co->mixers[mdev->index].devinfo;
2147 return 0;
2148 }
2149
2150 void *
2151 azalia_allocm(void *v, int dir, size_t size, int pool, int flags)
2152 {
2153 azalia_t *az;
2154 stream_t *stream;
2155 int err;
2156
2157 az = v;
2158 stream = dir == AUMODE_PLAY ? &az->pstream : &az->rstream;
2159 err = azalia_alloc_dmamem(az, size, 128, &stream->buffer);
2160 if (err) {
2161 printf("%s: allocm failed\n", az->dev.dv_xname);
2162 return NULL;
2163 }
2164 return stream->buffer.addr;
2165 }
2166
2167 void
2168 azalia_freem(void *v, void *addr, int pool)
2169 {
2170 azalia_t *az;
2171 stream_t *stream;
2172
2173 az = v;
2174 if (addr == az->pstream.buffer.addr) {
2175 stream = &az->pstream;
2176 } else if (addr == az->rstream.buffer.addr) {
2177 stream = &az->rstream;
2178 } else {
2179 return;
2180 }
2181 azalia_free_dmamem(az, &stream->buffer);
2182 }
2183
2184 size_t
2185 azalia_round_buffersize(void *v, int dir, size_t size)
2186 {
2187 size &= ~0x7f;
2188 if (size <= 0)
2189 size = 128;
2190 return size;
2191 }
2192
2193 int
2194 azalia_get_props(void *v)
2195 {
2196 return AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
2197 }
2198
2199 int
2200 azalia_trigger_output(void *v, void *start, void *end, int blk,
2201 void (*intr)(void *), void *arg, audio_params_t *param)
2202 {
2203 azalia_t *az;
2204 int err;
2205 uint16_t fmt;
2206
2207 err = azalia_params2fmt(param, &fmt);
2208 if (err)
2209 return EINVAL;
2210
2211 az = v;
2212 return azalia_stream_start(&az->pstream, start, end, blk, intr, arg, fmt);
2213 }
2214
2215 int
2216 azalia_trigger_input(void *v, void *start, void *end, int blk,
2217 void (*intr)(void *), void *arg, audio_params_t *param)
2218 {
2219 azalia_t *az;
2220 int err;
2221 uint16_t fmt;
2222
2223 DPRINTF(("%s: this=%p start=%p end=%p blk=%d {enc=%u %uch %u/%ubit %uHz}\n",
2224 __func__, v, start, end, blk, param->encoding, param->channels,
2225 param->precision, param->precision, param->sample_rate));
2226
2227 err = azalia_params2fmt(param, &fmt);
2228 if (err)
2229 return EINVAL;
2230
2231 az = v;
2232 return azalia_stream_start(&az->rstream, start, end, blk, intr, arg, fmt);
2233 }
2234
2235
2236
2237
2238 int
2239 azalia_params2fmt(const audio_params_t *param, uint16_t *fmt)
2240 {
2241 uint16_t ret;
2242
2243 ret = 0;
2244 #ifdef DIAGNOSTIC
2245 if (param->channels > HDA_MAX_CHANNELS) {
2246 printf("%s: too many channels: %u\n", __func__,
2247 param->channels);
2248 return EINVAL;
2249 }
2250 #endif
2251 ret |= param->channels - 1;
2252
2253 switch (param->precision) {
2254 case 8:
2255 ret |= HDA_SD_FMT_BITS_8_16;
2256 break;
2257 case 16:
2258 ret |= HDA_SD_FMT_BITS_16_16;
2259 break;
2260 case 32:
2261 ret |= HDA_SD_FMT_BITS_32_32;
2262 break;
2263 }
2264
2265 #if 0
2266 switch (param->validbits) {
2267 case 8:
2268 ret |= HDA_SD_FMT_BITS_8_16;
2269 break;
2270 case 16:
2271 ret |= HDA_SD_FMT_BITS_16_16;
2272 break;
2273 case 20:
2274 ret |= HDA_SD_FMT_BITS_20_32;
2275 break;
2276 case 24:
2277 ret |= HDA_SD_FMT_BITS_24_32;
2278 break;
2279 case 32:
2280 ret |= HDA_SD_FMT_BITS_32_32;
2281 break;
2282 default:
2283 printf("%s: invalid validbits: %u\n", __func__,
2284 param->validbits);
2285 }
2286 #endif
2287
2288 if (param->sample_rate == 384000) {
2289 printf("%s: invalid sample_rate: %u\n", __func__,
2290 param->sample_rate);
2291 return EINVAL;
2292 } else if (param->sample_rate == 192000) {
2293 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X4 | HDA_SD_FMT_DIV_BY1;
2294 } else if (param->sample_rate == 176400) {
2295 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X4 | HDA_SD_FMT_DIV_BY1;
2296 } else if (param->sample_rate == 96000) {
2297 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY1;
2298 } else if (param->sample_rate == 88200) {
2299 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY1;
2300 } else if (param->sample_rate == 48000) {
2301 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY1;
2302 } else if (param->sample_rate == 44100) {
2303 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY1;
2304 } else if (param->sample_rate == 32000) {
2305 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY3;
2306 } else if (param->sample_rate == 22050) {
2307 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY2;
2308 } else if (param->sample_rate == 16000) {
2309 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY3;
2310 } else if (param->sample_rate == 11025) {
2311 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY4;
2312 } else if (param->sample_rate == 8000) {
2313 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY6;
2314 } else {
2315 printf("%s: invalid sample_rate: %u\n", __func__,
2316 param->sample_rate);
2317 return EINVAL;
2318 }
2319 *fmt = ret;
2320 return 0;
2321 }
2322
2323 int
2324 azalia_create_encodings(struct audio_format *formats, int nformats,
2325 struct audio_encoding_set **encodings)
2326 {
2327 #if 0
2328 int i;
2329 u_int j;
2330
2331 for (i = 0; i < nformats; i++) {
2332 printf("format(%d): encoding %u vbits %u prec %u chans %u cmask 0x%x\n",
2333 i, formats[i].encoding, formats[i].validbits,
2334 formats[i].precision, formats[i].channels,
2335 formats[i].channel_mask);
2336 printf("format(%d) rates:", i);
2337 for (j = 0; j < formats[i].frequency_type; j++) {
2338 printf(" %u", formats[i].frequency[j]);
2339 }
2340 printf("\n");
2341 }
2342 #endif
2343 return (0);
2344 }