This source file includes following definitions.
- cs4280_match
- cs4280_read_codec
- cs4280_write_codec
- cs4280_src_wait
- cs4280_set_adc_rate
- cs4280_set_dac_rate
- cs4280_attachhook
- cs4280_attach
- cs4280_intr
- cs4280_download
- cs4280_download_image
- cs4280_checkimage
- cs4280_check_images
- cs4280_attach_codec
- cs4280_reset_codec
- cs4280_reset
- cs4280_open
- cs4280_close
- cs4280_query_encoding
- cs4280_set_params
- cs4280_round_blocksize
- cs4280_round_buffersize
- cs4280_get_props
- cs4280_mixer_get_port
- cs4280_mappage
- cs4280_query_devinfo
- cs4280_get_portnum_by_name
- cs4280_halt_output
- cs4280_halt_input
- cs4280_getdev
- cs4280_mixer_set_port
- cs4280_freemem
- cs4280_allocmem
- cs4280_malloc
- cs4280_free
- cs4280_trigger_output
- cs4280_trigger_input
- cs4280_init
- cs4280_init2
- cs4280_power
- cs4280_clear_fifos
- cs4280_midi_open
- cs4280_midi_close
- cs4280_midi_output
- cs4280_midi_getinfo
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 #ifdef CS4280_DEBUG
50 #ifndef MIDI_READY
51 #define MIDI_READY
52 #endif
53 #endif
54
55 #ifdef MIDI_READY
56 #include "midi.h"
57 #endif
58
59 #if defined(CS4280_DEBUG)
60 #define DPRINTF(x) if (cs4280debug) printf x
61 #define DPRINTFN(n,x) if (cs4280debug>(n)) printf x
62 int cs4280debug = 0;
63 #else
64 #define DPRINTF(x)
65 #define DPRINTFN(n,x)
66 #endif
67
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/fcntl.h>
72 #include <sys/malloc.h>
73 #include <sys/device.h>
74
75 #include <dev/pci/pcidevs.h>
76 #include <dev/pci/pcivar.h>
77 #include <dev/pci/cs4280reg.h>
78
79 #include <sys/audioio.h>
80 #include <dev/audio_if.h>
81 #include <dev/midi_if.h>
82 #include <dev/mulaw.h>
83 #include <dev/auconv.h>
84
85 #include <dev/ic/ac97.h>
86
87 #include <machine/bus.h>
88
89 #define CSCC_PCI_BA0 0x10
90 #define CSCC_PCI_BA1 0x14
91
92 struct cs4280_dma {
93 bus_dmamap_t map;
94 caddr_t addr;
95 caddr_t dum;
96 bus_dma_segment_t segs[1];
97 int nsegs;
98 size_t size;
99 struct cs4280_dma *next;
100 };
101 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
102 #define BUFADDR(p) ((void *)((p)->dum))
103 #define KERNADDR(p) ((void *)((p)->addr))
104
105
106
107
108 struct cs4280_softc {
109 struct device sc_dev;
110
111 pci_intr_handle_t * sc_ih;
112
113
114 bus_space_tag_t ba0t;
115 bus_space_handle_t ba0h;
116
117
118 bus_space_tag_t ba1t;
119 bus_space_handle_t ba1h;
120
121
122 bus_dma_tag_t sc_dmatag;
123 struct cs4280_dma *sc_dmas;
124
125 void (*sc_pintr)(void *);
126 void *sc_parg;
127 char *sc_ps, *sc_pe, *sc_pn;
128 int sc_pcount;
129 int sc_pi;
130 struct cs4280_dma *sc_pdma;
131 char *sc_pbuf;
132 #ifdef DIAGNOSTIC
133 char sc_prun;
134 #endif
135
136 void (*sc_rintr)(void *);
137 void *sc_rarg;
138 char *sc_rs, *sc_re, *sc_rn;
139 int sc_rcount;
140 int sc_ri;
141 struct cs4280_dma *sc_rdma;
142 char *sc_rbuf;
143 int sc_rparam;
144 #ifdef DIAGNOSTIC
145 char sc_rrun;
146 #endif
147
148 #if NMIDI > 0
149 void (*sc_iintr)(void *, int);
150 void (*sc_ointr)(void *);
151 void *sc_arg;
152 #endif
153
154 u_int32_t pctl;
155 u_int32_t cctl;
156
157 struct ac97_codec_if *codec_if;
158 struct ac97_host_if host_if;
159
160 char sc_suspend;
161 void *sc_powerhook;
162 u_int16_t ac97_reg[CS4280_SAVE_REG_MAX + 1];
163 };
164
165 #define BA0READ4(sc, r) bus_space_read_4((sc)->ba0t, (sc)->ba0h, (r))
166 #define BA0WRITE4(sc, r, x) bus_space_write_4((sc)->ba0t, (sc)->ba0h, (r), (x))
167 #define BA1READ4(sc, r) bus_space_read_4((sc)->ba1t, (sc)->ba1h, (r))
168 #define BA1WRITE4(sc, r, x) bus_space_write_4((sc)->ba1t, (sc)->ba1h, (r), (x))
169
170 int cs4280_match(struct device *, void *, void *);
171 void cs4280_attach(struct device *, struct device *, void *);
172 void cs4280_attachhook(void *xsc);
173 int cs4280_intr(void *);
174 void cs4280_reset(void *);
175 int cs4280_download_image(struct cs4280_softc *);
176
177 int cs4280_download(struct cs4280_softc *, const u_int32_t *, u_int32_t, u_int32_t);
178 int cs4280_allocmem(struct cs4280_softc *, size_t, size_t,
179 struct cs4280_dma *);
180 int cs4280_freemem(struct cs4280_softc *, struct cs4280_dma *);
181
182 #ifdef CS4280_DEBUG
183 int cs4280_check_images(struct cs4280_softc *);
184 int cs4280_checkimage(struct cs4280_softc *, u_int32_t *, u_int32_t,
185 u_int32_t);
186 #endif
187
188 struct cfdriver clcs_cd = {
189 NULL, "clcs", DV_DULL
190 };
191
192 struct cfattach clcs_ca = {
193 sizeof(struct cs4280_softc), cs4280_match, cs4280_attach
194 };
195
196 int cs4280_init(struct cs4280_softc *, int);
197 int cs4280_init2(struct cs4280_softc *, int);
198 int cs4280_open(void *, int);
199 void cs4280_close(void *);
200
201 int cs4280_query_encoding(void *, struct audio_encoding *);
202 int cs4280_set_params(void *, int, int, struct audio_params *, struct audio_params *);
203 int cs4280_round_blocksize(void *, int);
204
205 int cs4280_halt_output(void *);
206 int cs4280_halt_input(void *);
207
208 int cs4280_getdev(void *, struct audio_device *);
209
210 int cs4280_mixer_set_port(void *, mixer_ctrl_t *);
211 int cs4280_mixer_get_port(void *, mixer_ctrl_t *);
212 int cs4280_query_devinfo(void *addr, mixer_devinfo_t *dip);
213 void *cs4280_malloc(void *, int, size_t, int, int);
214 void cs4280_free(void *, void *, int);
215 size_t cs4280_round_buffersize(void *, int, size_t);
216 paddr_t cs4280_mappage(void *, void *, off_t, int);
217 int cs4280_get_props(void *);
218 int cs4280_trigger_output(void *, void *, void *, int, void (*)(void *),
219 void *, struct audio_params *);
220 int cs4280_trigger_input(void *, void *, void *, int, void (*)(void *),
221 void *, struct audio_params *);
222
223
224 void cs4280_set_dac_rate(struct cs4280_softc *, int );
225 void cs4280_set_adc_rate(struct cs4280_softc *, int );
226 int cs4280_get_portnum_by_name(struct cs4280_softc *, char *, char *,
227 char *);
228 int cs4280_src_wait(struct cs4280_softc *);
229 int cs4280_attach_codec(void *sc, struct ac97_codec_if *);
230 int cs4280_read_codec(void *sc, u_int8_t a, u_int16_t *d);
231 int cs4280_write_codec(void *sc, u_int8_t a, u_int16_t d);
232 void cs4280_reset_codec(void *sc);
233
234 void cs4280_power(int, void *);
235
236 void cs4280_clear_fifos(struct cs4280_softc *);
237
238 #if NMIDI > 0
239 void cs4280_midi_close(void *);
240 void cs4280_midi_getinfo(void *, struct midi_info *);
241 int cs4280_midi_open(void *, int, void (*)(void *, int),
242 void (*)(void *), void *);
243 int cs4280_midi_output(void *, int);
244 #endif
245
246 struct audio_hw_if cs4280_hw_if = {
247 cs4280_open,
248 cs4280_close,
249 NULL,
250 cs4280_query_encoding,
251 cs4280_set_params,
252 cs4280_round_blocksize,
253 NULL,
254 NULL,
255 NULL,
256 NULL,
257 NULL,
258 cs4280_halt_output,
259 cs4280_halt_input,
260 NULL,
261 cs4280_getdev,
262 NULL,
263 cs4280_mixer_set_port,
264 cs4280_mixer_get_port,
265 cs4280_query_devinfo,
266 cs4280_malloc,
267 cs4280_free,
268 cs4280_round_buffersize,
269 0,
270 cs4280_get_props,
271 cs4280_trigger_output,
272 cs4280_trigger_input,
273 };
274
275 #if NMIDI > 0
276 struct midi_hw_if cs4280_midi_hw_if = {
277 cs4280_midi_open,
278 cs4280_midi_close,
279 cs4280_midi_output,
280 0,
281 cs4280_midi_getinfo,
282 0,
283 };
284 #endif
285
286
287
288 struct audio_device cs4280_device = {
289 "CS4280",
290 "",
291 "cs4280"
292 };
293
294 const struct pci_matchid cs4280_devices[] = {
295 { PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CS4280 },
296 { PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CS4610 },
297 { PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CS4615 },
298 };
299
300 int
301 cs4280_match(parent, ma, aux)
302 struct device *parent;
303 void *ma;
304 void *aux;
305 {
306 return (pci_matchbyid((struct pci_attach_args *)aux, cs4280_devices,
307 sizeof(cs4280_devices)/sizeof(cs4280_devices[0])));
308 }
309
310 int
311 cs4280_read_codec(sc_, add, data)
312 void *sc_;
313 u_int8_t add;
314 u_int16_t *data;
315 {
316 struct cs4280_softc *sc = sc_;
317 int n;
318
319 DPRINTFN(5,("read_codec: add=0x%02x ", add));
320
321
322
323
324 BA0READ4(sc, CS4280_ACSDA);
325
326
327 BA0WRITE4(sc, CS4280_ACCAD, add);
328 BA0WRITE4(sc, CS4280_ACCDA, 0);
329 BA0WRITE4(sc, CS4280_ACCTL,
330 ACCTL_RSTN | ACCTL_ESYN | ACCTL_VFRM | ACCTL_CRW | ACCTL_DCV );
331
332 if (cs4280_src_wait(sc) < 0) {
333 printf("%s: AC97 read prob. (DCV!=0) for add=0x%02x\n",
334 sc->sc_dev.dv_xname, add);
335 return (1);
336 }
337
338
339 n = 0;
340 while (!(BA0READ4(sc, CS4280_ACSTS) & ACSTS_VSTS)) {
341 delay(1);
342 while (++n > 1000) {
343 printf("%s: AC97 read fail (VSTS==0) for add=0x%02x\n",
344 sc->sc_dev.dv_xname, add);
345 return (1);
346 }
347 }
348 *data = BA0READ4(sc, CS4280_ACSDA);
349 DPRINTFN(5,("data=0x%04x\n", *data));
350 return (0);
351 }
352
353 int
354 cs4280_write_codec(sc_, add, data)
355 void *sc_;
356 u_int8_t add;
357 u_int16_t data;
358 {
359 struct cs4280_softc *sc = sc_;
360
361 DPRINTFN(5,("write_codec: add=0x%02x data=0x%04x\n", add, data));
362 BA0WRITE4(sc, CS4280_ACCAD, add);
363 BA0WRITE4(sc, CS4280_ACCDA, data);
364 BA0WRITE4(sc, CS4280_ACCTL,
365 ACCTL_RSTN | ACCTL_ESYN | ACCTL_VFRM | ACCTL_DCV );
366
367 if (cs4280_src_wait(sc) < 0) {
368 printf("%s: AC97 write fail (DCV!=0) for add=0x%02x data="
369 "0x%04x\n", sc->sc_dev.dv_xname, add, data);
370 return (1);
371 }
372 return (0);
373 }
374
375 int
376 cs4280_src_wait(sc)
377 struct cs4280_softc *sc;
378 {
379 int n;
380
381 n = 0;
382 while ((BA0READ4(sc, CS4280_ACCTL) & ACCTL_DCV)) {
383 delay(1000);
384 if (++n > 1000)
385 return (-1);
386 }
387 return (0);
388 }
389
390
391 void
392 cs4280_set_adc_rate(sc, rate)
393 struct cs4280_softc *sc;
394 int rate;
395 {
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414 u_int32_t cci,cpi,cnt,cx,cy, tmp1;
415 u_int16_t csrc, cgl, cdlay;
416
417
418
419
420
421
422
423
424
425
426
427 if (rate < 8000)
428 rate = 8000;
429 if (rate > 48000)
430 rate = 48000;
431
432 cx = rate << 16;
433 cci = cx / 48000;
434 cx -= cci * 48000;
435 cx <<= 7;
436 cci <<= 7;
437 cci += cx / 48000;
438 cci = - cci;
439
440 cx = 48000 << 16;
441 cpi = cx / rate;
442 cx -= cpi * rate;
443 cx <<= 10;
444 cpi <<= 10;
445 cy = cx / rate;
446 cpi += cy;
447 cx -= cy * rate;
448
449 cy = cx / 200;
450 csrc = cx - 200*cy;
451
452 cdlay = ((48000 * 24) + rate - 1) / rate;
453 #if 0
454 cdlay &= 0x3fff;
455 #endif
456
457 cnt = rate << 16;
458 cnt /= 24000;
459
460 cgl = 1;
461 for (tmp1 = 2; tmp1 <= 64; tmp1 *= 2) {
462 if (((rate / tmp1) * tmp1) != rate)
463 cgl *= 2;
464 }
465 if (((rate / 3) * 3) != rate)
466 cgl *= 3;
467 for (tmp1 = 5; tmp1 <= 125; tmp1 *= 5) {
468 if (((rate / tmp1) * tmp1) != rate)
469 cgl *= 5;
470 }
471 #if 0
472
473 tmp1 = BA1READ4(sc, CS4280_CSRC) & ~CSRC_MASK;
474 tmp1 |= csrc<<16;
475 BA1WRITE4(sc, CS4280_CSRC, tmp1);
476 #else
477
478 BA1WRITE4(sc, CS4280_CSRC, CS4280_MK_CSRC(csrc, cy));
479 #endif
480
481 #if 0
482
483
484
485
486
487 tmp1 = BA1READ4(sc, CS4280_CCI) & ~CCI_MASK;
488 tmp1 |= cci<<16;
489 BA1WRITE4(sc, CS4280_CCI, tmp1);
490 #else
491 BA1WRITE4(sc, CS4280_CCI, cci);
492 #endif
493
494 tmp1 = BA1READ4(sc, CS4280_CD) & ~CD_MASK;
495 tmp1 |= cdlay <<18;
496 BA1WRITE4(sc, CS4280_CD, tmp1);
497
498 BA1WRITE4(sc, CS4280_CPI, cpi);
499
500 tmp1 = BA1READ4(sc, CS4280_CGL) & ~CGL_MASK;
501 tmp1 |= cgl;
502 BA1WRITE4(sc, CS4280_CGL, tmp1);
503
504 BA1WRITE4(sc, CS4280_CNT, cnt);
505
506 tmp1 = BA1READ4(sc, CS4280_CGC) & ~CGC_MASK;
507 tmp1 |= cgl;
508 BA1WRITE4(sc, CS4280_CGC, tmp1);
509 }
510
511 void
512 cs4280_set_dac_rate(sc, rate)
513 struct cs4280_softc *sc;
514 int rate;
515 {
516
517
518
519
520
521
522
523
524
525
526
527 int32_t ppi;
528 int16_t psrc;
529 u_int32_t px, py;
530
531 if (rate < 8000)
532 rate = 8000;
533 if (rate > 48000)
534 rate = 48000;
535 px = rate << 16;
536 ppi = px/48000;
537 px -= ppi*48000;
538 ppi <<= 10;
539 px <<= 10;
540 py = px / 48000;
541 ppi += py;
542 px -= py*48000;
543 py = px/200;
544 px -= py*200;
545 psrc = px;
546 #if 0
547
548 px = BA1READ4(sc, CS4280_PSRC) & ~PSRC_MASK;
549 BA1WRITE4(sc, CS4280_PSRC,
550 ( ((psrc<<16) & PSRC_MASK) | px ));
551 #else
552
553 BA1WRITE4(sc, CS4280_PSRC, CS4280_MK_PSRC(psrc,py));
554 #endif
555 BA1WRITE4(sc, CS4280_PPI, ppi);
556 }
557
558 void
559 cs4280_attachhook(void *xsc)
560 {
561 struct cs4280_softc *sc = xsc;
562 mixer_ctrl_t ctl;
563
564
565 if (cs4280_init2(sc, 1) != 0)
566 return;
567
568 printf("%s: firmware loaded\n", sc->sc_dev.dv_xname);
569
570
571 ctl.type = AUDIO_MIXER_ENUM;
572 ctl.un.ord = 0;
573
574 ctl.dev = cs4280_get_portnum_by_name(sc, AudioCoutputs,
575 AudioNmaster, AudioNmute);
576 cs4280_mixer_set_port(sc, &ctl);
577
578 ctl.dev = cs4280_get_portnum_by_name(sc, AudioCinputs,
579 AudioNdac, AudioNmute);
580 cs4280_mixer_set_port(sc, &ctl);
581
582 ctl.dev = cs4280_get_portnum_by_name(sc, AudioCinputs,
583 AudioNcd, AudioNmute);
584 cs4280_mixer_set_port(sc, &ctl);
585
586 audio_attach_mi(&cs4280_hw_if, sc, &sc->sc_dev);
587
588 #if NMIDI > 0
589 midi_attach_mi(&cs4280_midi_hw_if, sc, &sc->sc_dev);
590 #endif
591 sc->sc_suspend = PWR_RESUME;
592 sc->sc_powerhook = powerhook_establish(cs4280_power, sc);
593 }
594
595 void
596 cs4280_attach(parent, self, aux)
597 struct device *parent;
598 struct device *self;
599 void *aux;
600 {
601 struct cs4280_softc *sc = (struct cs4280_softc *) self;
602 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
603 pci_chipset_tag_t pc = pa->pa_pc;
604 char const *intrstr;
605 pci_intr_handle_t ih;
606 u_int32_t mem;
607
608
609 if (pci_mapreg_map(pa, CSCC_PCI_BA0,
610 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
611 &sc->ba0t, &sc->ba0h, NULL, NULL, 0)) {
612 printf(": can't map BA0 space\n");
613 return;
614 }
615 if (pci_mapreg_map(pa, CSCC_PCI_BA1,
616 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
617 &sc->ba1t, &sc->ba1h, NULL, NULL, 0)) {
618 printf(": can't map BA1 space\n");
619 return;
620 }
621
622 sc->sc_dmatag = pa->pa_dmat;
623
624
625 mem = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
626 if ( PCI_LATTIMER(mem) < 32 ) {
627 mem &= 0xffff00ff;
628 mem |= 0x00002000;
629 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, mem);
630 }
631
632
633 if (pci_intr_map(pa, &ih)) {
634 printf(": couldn't map interrupt\n");
635 return;
636 }
637 intrstr = pci_intr_string(pc, ih);
638
639 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, cs4280_intr, sc,
640 sc->sc_dev.dv_xname);
641 if (sc->sc_ih == NULL) {
642 printf(": couldn't establish interrupt");
643 if (intrstr != NULL)
644 printf(" at %s", intrstr);
645 printf("\n");
646 return;
647 }
648 printf(": %s\n", intrstr);
649
650
651 if (cs4280_init(sc, 1) != 0)
652 return;
653
654 mountroothook_establish(cs4280_attachhook, sc);
655
656
657 sc->host_if.arg = sc;
658 sc->host_if.attach = cs4280_attach_codec;
659 sc->host_if.read = cs4280_read_codec;
660 sc->host_if.write = cs4280_write_codec;
661 sc->host_if.reset = cs4280_reset_codec;
662
663 if (ac97_attach(&sc->host_if) != 0) {
664 printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname);
665 return;
666 }
667 }
668
669 int
670 cs4280_intr(p)
671 void *p;
672 {
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695 struct cs4280_softc *sc = p;
696 u_int32_t intr, mem;
697 char * empty_dma;
698 int handled = 0;
699
700
701 intr = BA0READ4(sc, CS4280_HISR);
702 BA0WRITE4(sc, CS4280_HICR, HICR_CHGM | HICR_IEV);
703
704
705 if (intr & HISR_PINT) {
706 handled = 1;
707 mem = BA1READ4(sc, CS4280_PFIE);
708 BA1WRITE4(sc, CS4280_PFIE, (mem & ~PFIE_PI_MASK) | PFIE_PI_DISABLE);
709 if (sc->sc_pintr) {
710 if ((sc->sc_pi%sc->sc_pcount) == 0)
711 sc->sc_pintr(sc->sc_parg);
712 } else {
713 printf("unexpected play intr\n");
714 }
715
716 ++sc->sc_pi;
717 empty_dma = sc->sc_pdma->addr;
718 if (sc->sc_pi&1)
719 empty_dma += CS4280_ICHUNK;
720 memcpy(empty_dma, sc->sc_pn, CS4280_ICHUNK);
721 sc->sc_pn += CS4280_ICHUNK;
722 if (sc->sc_pn >= sc->sc_pe)
723 sc->sc_pn = sc->sc_ps;
724 BA1WRITE4(sc, CS4280_PFIE, mem);
725 }
726
727 if (intr & HISR_CINT) {
728 int i;
729 int16_t rdata;
730
731 handled = 1;
732 mem = BA1READ4(sc, CS4280_CIE);
733 BA1WRITE4(sc, CS4280_CIE, (mem & ~CIE_CI_MASK) | CIE_CI_DISABLE);
734 ++sc->sc_ri;
735 empty_dma = sc->sc_rdma->addr;
736 if ((sc->sc_ri&1) == 0)
737 empty_dma += CS4280_ICHUNK;
738
739
740
741
742
743
744
745 switch(sc->sc_rparam) {
746 case CF_16BIT_STEREO:
747
748 memcpy(sc->sc_rn, empty_dma, CS4280_ICHUNK);
749 sc->sc_rn += CS4280_ICHUNK;
750 break;
751 case CF_16BIT_MONO:
752 for (i = 0; i < 512; i++) {
753 rdata = *((int16_t *)empty_dma)++>>1;
754 rdata += *((int16_t *)empty_dma)++>>1;
755 *((int16_t *)sc->sc_rn)++ = rdata;
756 }
757 break;
758 case CF_8BIT_STEREO:
759 for (i = 0; i < 512; i++) {
760 rdata = *((int16_t*)empty_dma)++;
761 *sc->sc_rn++ = rdata >> 8;
762 rdata = *((int16_t*)empty_dma)++;
763 *sc->sc_rn++ = rdata >> 8;
764 }
765 break;
766 case CF_8BIT_MONO:
767 for (i = 0; i < 512; i++) {
768 rdata = *((int16_t*)empty_dma)++ >>1;
769 rdata += *((int16_t*)empty_dma)++ >>1;
770 *sc->sc_rn++ = rdata >>8;
771 }
772 break;
773 default:
774
775 printf("unknown sc->sc_rparam: %d\n", sc->sc_rparam);
776 }
777 if (sc->sc_rn >= sc->sc_re)
778 sc->sc_rn = sc->sc_rs;
779 BA1WRITE4(sc, CS4280_CIE, mem);
780 if (sc->sc_rintr) {
781 if ((sc->sc_ri%(sc->sc_rcount)) == 0)
782 sc->sc_rintr(sc->sc_rarg);
783 } else {
784 printf("unexpected record intr\n");
785 }
786 }
787
788 #if NMIDI > 0
789
790 if (intr & HISR_MIDI) {
791 int data;
792
793 handled = 1;
794 DPRINTF(("i: %d: ",
795 BA0READ4(sc, CS4280_MIDSR)));
796
797 while ((sc->sc_iintr != NULL) &&
798 ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_RBE) == 0)) {
799 data = BA0READ4(sc, CS4280_MIDRP) & MIDRP_MASK;
800 DPRINTF(("r:%x\n",data));
801 sc->sc_iintr(sc->sc_arg, data);
802 }
803
804
805 #if 1
806
807
808
809
810 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) {
811 DPRINTF(("w: "));
812 if (sc->sc_ointr != NULL)
813 sc->sc_ointr(sc->sc_arg);
814 }
815 #else
816 while ((sc->sc_ointr != NULL) &&
817 ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0)) {
818 DPRINTF(("w: "));
819 sc->sc_ointr(sc->sc_arg);
820 }
821 #endif
822 DPRINTF(("\n"));
823 }
824 #endif
825
826 return handled;
827 }
828
829
830
831
832 int
833 cs4280_download(sc, src, offset, len)
834 struct cs4280_softc *sc;
835 const u_int32_t *src;
836 u_int32_t offset, len;
837 {
838 u_int32_t ctr;
839
840 #ifdef CS4280_DEBUG
841 u_int32_t con, data;
842 u_int8_t c0,c1,c2,c3;
843 #endif
844 if ((offset&3) || (len&3))
845 return (-1);
846
847 len /= sizeof(u_int32_t);
848 for (ctr = 0; ctr < len; ctr++) {
849
850
851
852
853 BA1WRITE4(sc, offset+ctr*4, htole32(*(src+ctr)));
854 #ifdef CS4280_DEBUG
855 data = htole32(*(src+ctr));
856 c0 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+0);
857 c1 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+1);
858 c2 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+2);
859 c3 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+3);
860 con = ( (c3<<24) | (c2<<16) | (c1<<8) | c0 );
861 if (data != con ) {
862 printf("0x%06x: write=0x%08x read=0x%08x\n",
863 offset+ctr*4, data, con);
864 return (-1);
865 }
866 #endif
867 }
868 return (0);
869 }
870
871 struct BA1struct *BA1Struct;
872
873 int
874 cs4280_download_image(sc)
875 struct cs4280_softc *sc;
876 {
877 int idx, err = 0;
878 u_int32_t offset = 0;
879 static u_char *cs4280_firmware;
880 static size_t cs4280_firmwarelen;
881
882 if (cs4280_firmware == NULL) {
883 err = loadfirmware("cs4280", &cs4280_firmware,
884 &cs4280_firmwarelen);
885 if (err)
886 return (err);
887 }
888
889 BA1Struct = (struct BA1struct *)cs4280_firmware;
890
891 for (idx = 0; idx < BA1_MEMORY_COUNT; ++idx) {
892 err = cs4280_download(sc, &BA1Struct->map[offset],
893 BA1Struct->memory[idx].offset, BA1Struct->memory[idx].size);
894 if (err != 0) {
895 printf("%s: load_image failed at %d\n",
896 sc->sc_dev.dv_xname, idx);
897 return (-1);
898 }
899 offset += BA1Struct->memory[idx].size / sizeof(u_int32_t);
900 }
901 return (err);
902 }
903
904 #ifdef CS4280_DEBUG
905 int
906 cs4280_checkimage(sc, src, offset, len)
907 struct cs4280_softc *sc;
908 u_int32_t *src;
909 u_int32_t offset, len;
910 {
911 u_int32_t ctr, data;
912 int err = 0;
913
914 if ((offset&3) || (len&3))
915 return -1;
916
917 len /= sizeof(u_int32_t);
918 for (ctr = 0; ctr < len; ctr++) {
919
920
921
922 data = BA1READ4(sc, offset+ctr*4);
923 if (data != htole32(*(src+ctr))) {
924 printf("0x%06x: 0x%08x(0x%08x)\n",
925 offset+ctr*4, data, *(src+ctr));
926 *(src+ctr) = data;
927 ++err;
928 }
929 }
930 return (err);
931 }
932
933 int
934 cs4280_check_images(sc)
935 struct cs4280_softc *sc;
936 {
937 int idx, err;
938 u_int32_t offset = 0;
939
940 err = 0;
941
942 for (idx = 0; idx < 1; ++idx) {
943 err = cs4280_checkimage(sc, &BA1Struct->map[offset],
944 BA1Struct->memory[idx].offset,
945 BA1Struct->memory[idx].size);
946 if (err != 0) {
947 printf("%s: check_image failed at %d\n",
948 sc->sc_dev.dv_xname, idx);
949 }
950 offset += BA1Struct->memory[idx].size / sizeof(u_int32_t);
951 }
952 return (err);
953 }
954
955 #endif
956
957 int
958 cs4280_attach_codec(sc_, codec_if)
959 void *sc_;
960 struct ac97_codec_if *codec_if;
961 {
962 struct cs4280_softc *sc = sc_;
963
964 sc->codec_if = codec_if;
965 return (0);
966 }
967
968 void
969 cs4280_reset_codec(sc_)
970 void *sc_;
971 {
972 struct cs4280_softc *sc = sc_;
973 int n;
974
975
976 BA0WRITE4(sc, CS4280_ACCTL, 0);
977 delay(100);
978 BA0WRITE4(sc, CS4280_ACCTL, ACCTL_RSTN);
979
980
981
982
983
984
985 BA0WRITE4(sc, CS4280_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
986 delay(50*1000);
987
988
989 BA0WRITE4(sc, CS4280_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
990
991
992 n = 0;
993 while (BA0READ4(sc, CS4280_ACISV) != (ACISV_ISV3 | ACISV_ISV4)) {
994 delay(1000);
995 if (++n > 1000) {
996 printf("reset_codec: AC97 inputs slot ready timeout\n");
997 return;
998 }
999 }
1000 }
1001
1002
1003
1004 void
1005 cs4280_reset(sc_)
1006 void *sc_;
1007 {
1008 struct cs4280_softc *sc = sc_;
1009
1010
1011 BA1WRITE4(sc, CS4280_SPCR, SPCR_RSTSP);
1012 delay(100);
1013
1014 BA1WRITE4(sc, CS4280_SPCR, 0);
1015
1016 BA1WRITE4(sc, CS4280_SPCR, SPCR_DRQEN);
1017 }
1018
1019 int
1020 cs4280_open(addr, flags)
1021 void *addr;
1022 int flags;
1023 {
1024 return (0);
1025 }
1026
1027 void
1028 cs4280_close(addr)
1029 void *addr;
1030 {
1031 struct cs4280_softc *sc = addr;
1032
1033 cs4280_halt_output(sc);
1034 cs4280_halt_input(sc);
1035
1036 sc->sc_pintr = 0;
1037 sc->sc_rintr = 0;
1038 }
1039
1040 int
1041 cs4280_query_encoding(addr, fp)
1042 void *addr;
1043 struct audio_encoding *fp;
1044 {
1045 switch (fp->index) {
1046 case 0:
1047 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
1048 fp->encoding = AUDIO_ENCODING_ULINEAR;
1049 fp->precision = 8;
1050 fp->flags = 0;
1051 break;
1052 case 1:
1053 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
1054 fp->encoding = AUDIO_ENCODING_ULAW;
1055 fp->precision = 8;
1056 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1057 break;
1058 case 2:
1059 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
1060 fp->encoding = AUDIO_ENCODING_ALAW;
1061 fp->precision = 8;
1062 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
1063 break;
1064 case 3:
1065 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
1066 fp->encoding = AUDIO_ENCODING_SLINEAR;
1067 fp->precision = 8;
1068 fp->flags = 0;
1069 break;
1070 case 4:
1071 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
1072 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
1073 fp->precision = 16;
1074 fp->flags = 0;
1075 break;
1076 case 5:
1077 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
1078 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
1079 fp->precision = 16;
1080 fp->flags = 0;
1081 break;
1082 case 6:
1083 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
1084 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
1085 fp->precision = 16;
1086 fp->flags = 0;
1087 break;
1088 case 7:
1089 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
1090 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
1091 fp->precision = 16;
1092 fp->flags = 0;
1093 break;
1094 default:
1095 return (EINVAL);
1096 }
1097 return (0);
1098 }
1099
1100 int
1101 cs4280_set_params(addr, setmode, usemode, play, rec)
1102 void *addr;
1103 int setmode, usemode;
1104 struct audio_params *play, *rec;
1105 {
1106 struct cs4280_softc *sc = addr;
1107 struct audio_params *p;
1108 int mode;
1109
1110 for (mode = AUMODE_RECORD; mode != -1;
1111 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1 ) {
1112 if ((setmode & mode) == 0)
1113 continue;
1114
1115 p = mode == AUMODE_PLAY ? play : rec;
1116
1117 if (p == play) {
1118 DPRINTFN(5,("play: sample=%ld precision=%d channels=%d\n",
1119 p->sample_rate, p->precision, p->channels));
1120
1121
1122
1123
1124 if (p->sample_rate < 8000 || p->sample_rate > 48000 ||
1125 (p->precision != 8 && p->precision != 16) ||
1126 (p->channels != 1 && p->channels != 2) ) {
1127 return (EINVAL);
1128 }
1129 } else {
1130 DPRINTFN(5,("rec: sample=%ld precision=%d channels=%d\n",
1131 p->sample_rate, p->precision, p->channels));
1132
1133
1134
1135
1136
1137
1138
1139
1140 if (p->sample_rate < 8000 || p->sample_rate > 48000 ||
1141 (p->precision != 8 && p->precision != 16) ||
1142 (p->channels != 1 && p->channels != 2) ) {
1143 return (EINVAL);
1144 }
1145 }
1146 p->factor = 1;
1147 p->sw_code = 0;
1148
1149
1150 switch (p->encoding) {
1151 case AUDIO_ENCODING_SLINEAR_BE:
1152 if (mode == AUMODE_RECORD) {
1153 if (p->precision == 16)
1154 p->sw_code = swap_bytes;
1155 }
1156 break;
1157 case AUDIO_ENCODING_SLINEAR_LE:
1158 break;
1159 case AUDIO_ENCODING_ULINEAR_BE:
1160 if (mode == AUMODE_RECORD) {
1161 if (p->precision == 16)
1162 p->sw_code = change_sign16_swap_bytes;
1163 else
1164 p->sw_code = change_sign8;
1165 }
1166 break;
1167 case AUDIO_ENCODING_ULINEAR_LE:
1168 if (mode == AUMODE_RECORD) {
1169 if (p->precision == 16)
1170 p->sw_code = change_sign16;
1171 else
1172 p->sw_code = change_sign8;
1173 }
1174 break;
1175 case AUDIO_ENCODING_ULAW:
1176 if (mode == AUMODE_PLAY) {
1177 p->factor = 2;
1178 p->sw_code = mulaw_to_slinear16;
1179 } else {
1180 p->sw_code = slinear8_to_mulaw;
1181 }
1182 break;
1183 case AUDIO_ENCODING_ALAW:
1184 if (mode == AUMODE_PLAY) {
1185 p->factor = 2;
1186 p->sw_code = alaw_to_slinear16;
1187 } else {
1188 p->sw_code = slinear8_to_alaw;
1189 }
1190 break;
1191 default:
1192 return (EINVAL);
1193 }
1194 }
1195
1196
1197 cs4280_set_dac_rate(sc, play->sample_rate);
1198 cs4280_set_adc_rate(sc, rec->sample_rate);
1199 return (0);
1200 }
1201
1202 int
1203 cs4280_round_blocksize(hdl, blk)
1204 void *hdl;
1205 int blk;
1206 {
1207 return (blk < CS4280_ICHUNK ? CS4280_ICHUNK : blk & -CS4280_ICHUNK);
1208 }
1209
1210 size_t
1211 cs4280_round_buffersize(addr, direction, size)
1212 void *addr;
1213 int direction;
1214 size_t size;
1215 {
1216
1217
1218
1219
1220 return (size);
1221 }
1222
1223 int
1224 cs4280_get_props(hdl)
1225 void *hdl;
1226 {
1227 return (AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
1228 #ifdef notyet
1229
1230
1231
1232 AUDIO_PROP_MMAP
1233 #endif
1234
1235 }
1236
1237 int
1238 cs4280_mixer_get_port(addr, cp)
1239 void *addr;
1240 mixer_ctrl_t *cp;
1241 {
1242 struct cs4280_softc *sc = addr;
1243
1244 return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
1245 }
1246
1247 paddr_t
1248 cs4280_mappage(addr, mem, off, prot)
1249 void *addr;
1250 void *mem;
1251 off_t off;
1252 int prot;
1253 {
1254 struct cs4280_softc *sc = addr;
1255 struct cs4280_dma *p;
1256
1257 if (off < 0)
1258 return (-1);
1259 for (p = sc->sc_dmas; p && BUFADDR(p) != mem; p = p->next)
1260 ;
1261 if (!p) {
1262 DPRINTF(("cs4280_mappage: bad buffer address\n"));
1263 return (-1);
1264 }
1265 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs,
1266 off, prot, BUS_DMA_WAITOK));
1267 }
1268
1269
1270 int
1271 cs4280_query_devinfo(addr, dip)
1272 void *addr;
1273 mixer_devinfo_t *dip;
1274 {
1275 struct cs4280_softc *sc = addr;
1276
1277 return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
1278 }
1279
1280 int
1281 cs4280_get_portnum_by_name(sc, class, device, qualifier)
1282 struct cs4280_softc *sc;
1283 char *class, *device, *qualifier;
1284 {
1285 return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class,
1286 device, qualifier));
1287 }
1288
1289 int
1290 cs4280_halt_output(addr)
1291 void *addr;
1292 {
1293 struct cs4280_softc *sc = addr;
1294 u_int32_t mem;
1295
1296 mem = BA1READ4(sc, CS4280_PCTL);
1297 BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK);
1298 #ifdef DIAGNOSTIC
1299 sc->sc_prun = 0;
1300 #endif
1301 return (0);
1302 }
1303
1304 int
1305 cs4280_halt_input(addr)
1306 void *addr;
1307 {
1308 struct cs4280_softc *sc = addr;
1309 u_int32_t mem;
1310
1311 mem = BA1READ4(sc, CS4280_CCTL);
1312 BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK);
1313 #ifdef DIAGNOSTIC
1314 sc->sc_rrun = 0;
1315 #endif
1316 return (0);
1317 }
1318
1319 int
1320 cs4280_getdev(addr, retp)
1321 void *addr;
1322 struct audio_device *retp;
1323 {
1324 *retp = cs4280_device;
1325 return (0);
1326 }
1327
1328 int
1329 cs4280_mixer_set_port(addr, cp)
1330 void *addr;
1331 mixer_ctrl_t *cp;
1332 {
1333 struct cs4280_softc *sc = addr;
1334 int val;
1335
1336 val = sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
1337 DPRINTFN(3,("mixer_set_port: val=%d\n", val));
1338 return (val);
1339 }
1340
1341
1342 int
1343 cs4280_freemem(sc, p)
1344 struct cs4280_softc *sc;
1345 struct cs4280_dma *p;
1346 {
1347 bus_dmamap_unload(sc->sc_dmatag, p->map);
1348 bus_dmamap_destroy(sc->sc_dmatag, p->map);
1349 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1350 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1351 return (0);
1352 }
1353
1354 int
1355 cs4280_allocmem(sc, size, align, p)
1356 struct cs4280_softc *sc;
1357 size_t size;
1358 size_t align;
1359 struct cs4280_dma *p;
1360 {
1361 int error;
1362
1363
1364 p->size = size;
1365 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
1366 p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
1367 &p->nsegs, BUS_DMA_NOWAIT);
1368 if (error) {
1369 printf("%s: unable to allocate dma, error=%d\n",
1370 sc->sc_dev.dv_xname, error);
1371 return (error);
1372 }
1373
1374 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,
1375 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
1376 if (error) {
1377 printf("%s: unable to map dma, error=%d\n",
1378 sc->sc_dev.dv_xname, error);
1379 goto free;
1380 }
1381
1382 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
1383 0, BUS_DMA_NOWAIT, &p->map);
1384 if (error) {
1385 printf("%s: unable to create dma map, error=%d\n",
1386 sc->sc_dev.dv_xname, error);
1387 goto unmap;
1388 }
1389
1390 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL,
1391 BUS_DMA_NOWAIT);
1392 if (error) {
1393 printf("%s: unable to load dma map, error=%d\n",
1394 sc->sc_dev.dv_xname, error);
1395 goto destroy;
1396 }
1397 return (0);
1398
1399 destroy:
1400 bus_dmamap_destroy(sc->sc_dmatag, p->map);
1401 unmap:
1402 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1403 free:
1404 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1405 return (error);
1406 }
1407
1408
1409 void *
1410 cs4280_malloc(addr, direction, size, pool, flags)
1411 void *addr;
1412 int direction;
1413 size_t size;
1414 int pool, flags;
1415 {
1416 struct cs4280_softc *sc = addr;
1417 struct cs4280_dma *p;
1418 caddr_t q;
1419 int error;
1420
1421 DPRINTFN(5,("cs4280_malloc: size=%d pool=%d flags=%d\n", size, pool, flags));
1422 q = malloc(size, pool, flags);
1423 if (!q)
1424 return (0);
1425 p = malloc(sizeof(*p), pool, flags);
1426 if (!p) {
1427 free(q,pool);
1428 return (0);
1429 }
1430
1431
1432
1433 error = cs4280_allocmem(sc, CS4280_DCHUNK, CS4280_DALIGN, p);
1434
1435 if (error) {
1436 free(q, pool);
1437 free(p, pool);
1438 return (0);
1439 }
1440
1441 p->next = sc->sc_dmas;
1442 sc->sc_dmas = p;
1443 p->dum = q;
1444
1445 return (p->dum);
1446 }
1447
1448 void
1449 cs4280_free(addr, ptr, pool)
1450 void *addr;
1451 void *ptr;
1452 int pool;
1453 {
1454 struct cs4280_softc *sc = addr;
1455 struct cs4280_dma **pp, *p;
1456
1457 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
1458 if (BUFADDR(p) == ptr) {
1459 cs4280_freemem(sc, p);
1460 *pp = p->next;
1461 free(p->dum, pool);
1462 free(p, pool);
1463 return;
1464 }
1465 }
1466 }
1467
1468 int
1469 cs4280_trigger_output(addr, start, end, blksize, intr, arg, param)
1470 void *addr;
1471 void *start, *end;
1472 int blksize;
1473 void (*intr)(void *);
1474 void *arg;
1475 struct audio_params *param;
1476 {
1477 struct cs4280_softc *sc = addr;
1478 u_int32_t pfie, pctl, mem, pdtc;
1479 struct cs4280_dma *p;
1480
1481 #ifdef DIAGNOSTIC
1482 if (sc->sc_prun)
1483 printf("cs4280_trigger_output: already running\n");
1484 sc->sc_prun = 1;
1485 #endif
1486
1487 DPRINTF(("cs4280_trigger_output: sc=%p start=%p end=%p "
1488 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1489 sc->sc_pintr = intr;
1490 sc->sc_parg = arg;
1491
1492
1493 mem = BA1READ4(sc, CS4280_PCTL);
1494 BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK);
1495
1496
1497 pdtc = BA1READ4(sc, CS4280_PDTC);
1498 pdtc &= ~PDTC_MASK;
1499 pdtc |= CS4280_MK_PDTC(param->precision * param->channels);
1500 BA1WRITE4(sc, CS4280_PDTC, pdtc);
1501
1502 DPRINTF(("param: precision=%d factor=%d channels=%d encoding=%d\n",
1503 param->precision, param->factor, param->channels,
1504 param->encoding));
1505 for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next)
1506 ;
1507 if (p == NULL) {
1508 printf("cs4280_trigger_output: bad addr %p\n", start);
1509 return (EINVAL);
1510 }
1511 if (DMAADDR(p) % CS4280_DALIGN != 0 ) {
1512 printf("cs4280_trigger_output: DMAADDR(p)=0x%lx does not start"
1513 "4kB align\n", DMAADDR(p));
1514 return (EINVAL);
1515 }
1516
1517 sc->sc_pcount = blksize / CS4280_ICHUNK;
1518 sc->sc_ps = (char *)start;
1519 sc->sc_pe = (char *)end;
1520 sc->sc_pdma = p;
1521 sc->sc_pbuf = KERNADDR(p);
1522 sc->sc_pi = 0;
1523 sc->sc_pn = sc->sc_ps;
1524 if (blksize >= CS4280_DCHUNK) {
1525 sc->sc_pn = sc->sc_ps + CS4280_DCHUNK;
1526 memcpy(sc->sc_pbuf, start, CS4280_DCHUNK);
1527 ++sc->sc_pi;
1528 } else {
1529 sc->sc_pn = sc->sc_ps + CS4280_ICHUNK;
1530 memcpy(sc->sc_pbuf, start, CS4280_ICHUNK);
1531 }
1532
1533
1534 BA1WRITE4(sc, CS4280_PBA, DMAADDR(p));
1535
1536
1537 pfie = BA1READ4(sc, CS4280_PFIE) & ~PFIE_MASK;
1538
1539 if (param->precision * param->factor == 8)
1540 pfie |= PFIE_8BIT;
1541 if (param->channels == 1)
1542 pfie |= PFIE_MONO;
1543
1544 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
1545 param->encoding == AUDIO_ENCODING_SLINEAR_BE)
1546 pfie |= PFIE_SWAPPED;
1547 if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
1548 param->encoding == AUDIO_ENCODING_ULINEAR_LE)
1549 pfie |= PFIE_UNSIGNED;
1550
1551 BA1WRITE4(sc, CS4280_PFIE, pfie | PFIE_PI_ENABLE);
1552
1553 cs4280_set_dac_rate(sc, param->sample_rate);
1554
1555 pctl = BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK;
1556 pctl |= sc->pctl;
1557 BA1WRITE4(sc, CS4280_PCTL, pctl);
1558 return (0);
1559 }
1560
1561 int
1562 cs4280_trigger_input(addr, start, end, blksize, intr, arg, param)
1563 void *addr;
1564 void *start, *end;
1565 int blksize;
1566 void (*intr)(void *);
1567 void *arg;
1568 struct audio_params *param;
1569 {
1570 struct cs4280_softc *sc = addr;
1571 u_int32_t cctl, cie;
1572 struct cs4280_dma *p;
1573
1574 #ifdef DIAGNOSTIC
1575 if (sc->sc_rrun)
1576 printf("cs4280_trigger_input: already running\n");
1577 sc->sc_rrun = 1;
1578 #endif
1579 DPRINTF(("cs4280_trigger_input: sc=%p start=%p end=%p "
1580 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1581 sc->sc_rintr = intr;
1582 sc->sc_rarg = arg;
1583
1584 sc->sc_ri = 0;
1585 sc->sc_rcount = blksize / CS4280_ICHUNK;
1586 sc->sc_rs = (char *)start;
1587 sc->sc_re = (char *)end;
1588 sc->sc_rn = sc->sc_rs;
1589
1590
1591 sc->sc_rparam = 0;
1592 if (param->precision == 8) {
1593 sc->sc_rparam += CF_8BIT;
1594 sc->sc_rcount <<= 1;
1595 }
1596 if (param->channels == 1) {
1597 sc->sc_rparam += CF_MONO;
1598 sc->sc_rcount <<= 1;
1599 }
1600
1601
1602 cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK;
1603 BA1WRITE4(sc, CS4280_CCTL, cctl);
1604
1605 for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next)
1606 ;
1607 if (!p) {
1608 printf("cs4280_trigger_input: bad addr %p\n", start);
1609 return (EINVAL);
1610 }
1611 if (DMAADDR(p) % CS4280_DALIGN != 0) {
1612 printf("cs4280_trigger_input: DMAADDR(p)=0x%lx does not start"
1613 "4kB align\n", DMAADDR(p));
1614 return (EINVAL);
1615 }
1616 sc->sc_rdma = p;
1617 sc->sc_rbuf = KERNADDR(p);
1618
1619
1620 BA1WRITE4(sc, CS4280_CBA, DMAADDR(p));
1621
1622
1623 cie = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK;
1624 BA1WRITE4(sc, CS4280_CIE, cie | CIE_CI_ENABLE);
1625
1626 cs4280_set_adc_rate(sc, param->sample_rate);
1627
1628 cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK;
1629 cctl |= sc->cctl;
1630 BA1WRITE4(sc, CS4280_CCTL, cctl);
1631 return (0);
1632 }
1633
1634
1635 int
1636 cs4280_init(sc, init)
1637 struct cs4280_softc *sc;
1638 int init;
1639 {
1640 int n;
1641 u_int32_t mem;
1642
1643
1644 BA0WRITE4(sc, CS4280_CLKCR1, 0);
1645
1646 BA0WRITE4(sc, CS4280_SERMC1, 0);
1647
1648
1649
1650 #define SERACC_CODEC_TYPE_1_03
1651 #ifdef SERACC_CODEC_TYPE_1_03
1652 BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_1_03);
1653 #else
1654 BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_2_0);
1655 #endif
1656
1657
1658 BA0WRITE4(sc, CS4280_ACCTL, 0);
1659 delay(100);
1660 BA0WRITE4(sc, CS4280_ACCTL, ACCTL_RSTN);
1661
1662
1663 BA0WRITE4(sc, CS4280_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
1664 delay(50*1000);
1665
1666
1667 BA0WRITE4(sc, CS4280_SERMC1, SERMC1_PTC_AC97);
1668
1669
1670 BA0WRITE4(sc, CS4280_PLLCC, PLLCC_CDR_STATE|PLLCC_LPF_STATE);
1671 BA0WRITE4(sc, CS4280_PLLM, PLLM_STATE);
1672 BA0WRITE4(sc, CS4280_CLKCR2, CLKCR2_PDIVS_8);
1673
1674
1675 BA0WRITE4(sc, CS4280_CLKCR1, CLKCR1_PLLP);
1676 delay(50*1000);
1677
1678
1679 mem = BA0READ4(sc, CS4280_CLKCR1) | CLKCR1_SWCE;
1680 BA0WRITE4(sc, CS4280_CLKCR1, mem);
1681
1682
1683
1684 cs4280_clear_fifos(sc);
1685
1686 #if 0
1687
1688 BA0WRITE4(sc, CS4280_SERBSP, 0);
1689 #endif
1690
1691
1692 BA0WRITE4(sc, CS4280_SERC1, SERC1_SO1EN | SERC1_SO1F_AC97);
1693 BA0WRITE4(sc, CS4280_SERC2, SERC2_SI1EN | SERC2_SI1F_AC97);
1694 BA0WRITE4(sc, CS4280_SERMC1, SERMC1_MSPE | SERMC1_PTC_AC97);
1695
1696
1697 n = 0;
1698 while ((BA0READ4(sc, CS4280_ACSTS) & ACSTS_CRDY) == 0) {
1699 delay(125);
1700 if (++n > 1000) {
1701 printf("%s: codec ready timeout\n",
1702 sc->sc_dev.dv_xname);
1703 return(1);
1704 }
1705 }
1706
1707
1708 BA0WRITE4(sc, CS4280_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
1709
1710
1711 n = 0;
1712 while ((BA0READ4(sc, CS4280_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) !=
1713 (ACISV_ISV3 | ACISV_ISV4)) {
1714 delay(1000);
1715 if (++n > 1000) {
1716 printf("AC97 inputs slot ready timeout\n");
1717 return(1);
1718 }
1719 }
1720
1721
1722 BA0WRITE4(sc, CS4280_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
1723
1724
1725 cs4280_reset(sc);
1726 return (0);
1727 }
1728
1729 int
1730 cs4280_init2(sc, init)
1731 struct cs4280_softc *sc;
1732 int init;
1733 {
1734 int n;
1735 u_int32_t mem;
1736
1737
1738 if (cs4280_download_image(sc) != 0) {
1739 printf("%s: image download error\n", sc->sc_dev.dv_xname);
1740 return(1);
1741 }
1742
1743
1744
1745
1746
1747 mem = BA1READ4(sc, CS4280_PCTL);
1748 sc->pctl = mem & PCTL_MASK;
1749 cs4280_halt_output(sc);
1750
1751
1752
1753
1754
1755 mem = BA1READ4(sc, CS4280_CCTL);
1756 sc->cctl = mem & CCTL_MASK;
1757 cs4280_halt_input(sc);
1758
1759
1760
1761
1762 BA1WRITE4(sc, CS4280_FRMT, FRMT_FTV);
1763 BA1WRITE4(sc, CS4280_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
1764
1765
1766 n = 0;
1767 while (BA1READ4(sc, CS4280_SPCR) & SPCR_RUNFR) {
1768 delay(10);
1769 if (++n > 1000) {
1770 printf("SPCR 1->0 transition timeout\n");
1771 return(1);
1772 }
1773 }
1774
1775 n = 0;
1776 while (!(BA1READ4(sc, CS4280_SPCS) & SPCS_SPRUN)) {
1777 delay(10);
1778 if (++n > 1000) {
1779 printf("SPCS 0->1 transition timeout\n");
1780 return(1);
1781 }
1782 }
1783
1784
1785
1786 BA1WRITE4(sc, CS4280_PVOL, 0x80008000);
1787 BA1WRITE4(sc, CS4280_CVOL, 0x80008000);
1788
1789
1790 BA0WRITE4(sc, CS4280_HICR, HICR_IEV|HICR_CHGM);
1791
1792
1793 mem = BA1READ4(sc, CS4280_PFIE) & ~PFIE_PI_MASK;
1794 mem |= PFIE_PI_ENABLE;
1795 BA1WRITE4(sc, CS4280_PFIE, mem);
1796
1797 mem = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK;
1798 mem |= CIE_CI_ENABLE;
1799 BA1WRITE4(sc, CS4280_CIE, mem);
1800
1801 #if NMIDI > 0
1802
1803 mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK;
1804 BA0WRITE4(sc, CS4280_MIDCR, mem | MIDCR_MRST);
1805 DPRINTF(("midi reset: 0x%x\n", BA0READ4(sc, CS4280_MIDCR)));
1806
1807 mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE;
1808 BA0WRITE4(sc, CS4280_MIDCR, mem);
1809 #endif
1810 return(0);
1811 }
1812
1813 void
1814 cs4280_power(why, v)
1815 int why;
1816 void *v;
1817 {
1818 struct cs4280_softc *sc = (struct cs4280_softc *)v;
1819 int i;
1820
1821 DPRINTF(("%s: cs4280_power why=%d\n",
1822 sc->sc_dev.dv_xname, why));
1823 if (why != PWR_RESUME) {
1824 sc->sc_suspend = why;
1825
1826 cs4280_halt_output(sc);
1827 cs4280_halt_input(sc);
1828
1829 for(i = 1; i <= CS4280_SAVE_REG_MAX; i++) {
1830 if(i == 0x04)
1831 continue;
1832 cs4280_read_codec(sc, 2*i, &sc->ac97_reg[i]);
1833 }
1834
1835 cs4280_write_codec(sc, AC97_REG_POWER, CS4280_POWER_DOWN_ALL);
1836 } else {
1837 if (sc->sc_suspend == PWR_RESUME) {
1838 printf("cs4280_power: odd, resume without suspend.\n");
1839 sc->sc_suspend = why;
1840 return;
1841 }
1842 sc->sc_suspend = why;
1843 cs4280_init(sc, 0);
1844 cs4280_init2(sc, 0);
1845 cs4280_reset_codec(sc);
1846
1847
1848 for(i = 1; i <= CS4280_SAVE_REG_MAX; i++) {
1849 if(i == 0x04)
1850 continue;
1851 cs4280_write_codec(sc, 2*i, sc->ac97_reg[i]);
1852 }
1853 }
1854 }
1855
1856 void
1857 cs4280_clear_fifos(sc)
1858 struct cs4280_softc *sc;
1859 {
1860 int pd = 0, cnt, n;
1861 u_int32_t mem;
1862
1863
1864
1865
1866
1867 mem = BA0READ4(sc, CS4280_CLKCR1);
1868 if (!(mem & CLKCR1_SWCE)) {
1869 printf("cs4280_clear_fifo: power down found.\n");
1870 BA0WRITE4(sc, CS4280_CLKCR1, mem | CLKCR1_SWCE);
1871 pd = 1;
1872 }
1873 BA0WRITE4(sc, CS4280_SERBWP, 0);
1874 for (cnt = 0; cnt < 256; cnt++) {
1875 n = 0;
1876 while (BA0READ4(sc, CS4280_SERBST) & SERBST_WBSY) {
1877 delay(1000);
1878 if (++n > 1000) {
1879 printf("clear_fifo: fist timeout cnt=%d\n", cnt);
1880 break;
1881 }
1882 }
1883 BA0WRITE4(sc, CS4280_SERBAD, cnt);
1884 BA0WRITE4(sc, CS4280_SERBCM, SERBCM_WRC);
1885 }
1886 if (pd)
1887 BA0WRITE4(sc, CS4280_CLKCR1, mem);
1888 }
1889
1890 #if NMIDI > 0
1891 int
1892 cs4280_midi_open(addr, flags, iintr, ointr, arg)
1893 void *addr;
1894 int flags;
1895 void (*iintr)(void *, int);
1896 void (*ointr)(void *);
1897 void *arg;
1898 {
1899 struct cs4280_softc *sc = addr;
1900 u_int32_t mem;
1901
1902 DPRINTF(("midi_open\n"));
1903 sc->sc_iintr = iintr;
1904 sc->sc_ointr = ointr;
1905 sc->sc_arg = arg;
1906
1907
1908 mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK;
1909 mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE | MIDCR_MLB;
1910 BA0WRITE4(sc, CS4280_MIDCR, mem);
1911 #ifdef CS4280_DEBUG
1912 if (mem != BA0READ4(sc, CS4280_MIDCR)) {
1913 DPRINTF(("midi_open: MIDCR=%d\n", BA0READ4(sc, CS4280_MIDCR)));
1914 return(EINVAL);
1915 }
1916 DPRINTF(("MIDCR=0x%x\n", BA0READ4(sc, CS4280_MIDCR)));
1917 #endif
1918 return (0);
1919 }
1920
1921 void
1922 cs4280_midi_close(addr)
1923 void *addr;
1924 {
1925 struct cs4280_softc *sc = addr;
1926 u_int32_t mem;
1927
1928 DPRINTF(("midi_close\n"));
1929 mem = BA0READ4(sc, CS4280_MIDCR);
1930 mem &= ~MIDCR_MASK;
1931 BA0WRITE4(sc, CS4280_MIDCR, mem);
1932
1933 sc->sc_iintr = 0;
1934 sc->sc_ointr = 0;
1935 }
1936
1937 int
1938 cs4280_midi_output(addr, d)
1939 void *addr;
1940 int d;
1941 {
1942 struct cs4280_softc *sc = addr;
1943 u_int32_t mem;
1944 int x;
1945
1946 for (x = 0; x != MIDI_BUSY_WAIT; x++) {
1947 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) {
1948 mem = BA0READ4(sc, CS4280_MIDWP) & ~MIDWP_MASK;
1949 mem |= d & MIDWP_MASK;
1950 DPRINTFN(5,("midi_output d=0x%08x",d));
1951 BA0WRITE4(sc, CS4280_MIDWP, mem);
1952 if (mem != BA0READ4(sc, CS4280_MIDWP)) {
1953 DPRINTF(("Bad write data: %d %d",
1954 mem, BA0READ4(sc, CS4280_MIDWP)));
1955 return(EIO);
1956 }
1957 return (0);
1958 }
1959 delay(MIDI_BUSY_DELAY);
1960 }
1961 return (EIO);
1962 }
1963
1964 void
1965 cs4280_midi_getinfo(addr, mi)
1966 void *addr;
1967 struct midi_info *mi;
1968 {
1969 mi->name = "CS4280 MIDI UART";
1970 mi->props = MIDI_PROP_CAN_INPUT | MIDI_PROP_OUT_INTR;
1971 }
1972
1973 #endif