This source file includes following definitions.
- nm_rd
- nm_wr
- nm_rdbuf
- nm_wrbuf
- nm_waitcd
- nm_ackint
- nm_loadcoeff
- nmchan_getptr
- neo_intr
- nm_init
- neo_attach
- neo_power
- neo_match
- neo_read_codec
- neo_write_codec
- neo_attach_codec
- neo_reset_codec
- neo_flags_codec
- neo_open
- neo_close
- neo_query_encoding
- neo_set_params
- neo_round_blocksize
- neo_trigger_output
- neo_trigger_input
- neo_halt_output
- neo_halt_input
- neo_getdev
- neo_mixer_set_port
- neo_mixer_get_port
- neo_query_devinfo
- neo_malloc
- neo_free
- neo_round_buffersize
- neo_get_props
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 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/device.h>
40
41 #include <dev/pci/pcidevs.h>
42 #include <dev/pci/pcivar.h>
43
44 #include <sys/audioio.h>
45 #include <dev/audio_if.h>
46 #include <dev/mulaw.h>
47 #include <dev/auconv.h>
48 #include <dev/ic/ac97.h>
49
50 #include <dev/pci/neoreg.h>
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 #define NM_BUFFSIZE 16384
118
119 #define NM256AV_PCI_ID 0x800510c8
120 #define NM256ZX_PCI_ID 0x800610c8
121
122
123 struct neo_softc {
124 struct device dev;
125
126 bus_space_tag_t bufiot;
127 bus_space_handle_t bufioh;
128
129 bus_space_tag_t regiot;
130 bus_space_handle_t regioh;
131
132 u_int32_t type;
133 void *ih;
134
135 void (*pintr)(void *);
136 void *parg;
137
138 void (*rintr)(void *);
139 void *rarg;
140
141 u_int32_t ac97_base, ac97_status, ac97_busy;
142 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf;
143 u_int32_t playint, recint, misc1int, misc2int;
144 u_int32_t irsz, badintr;
145
146 u_int32_t pbufsize;
147 u_int32_t rbufsize;
148
149 u_int32_t pblksize;
150 u_int32_t rblksize;
151
152 u_int32_t pwmark;
153 u_int32_t rwmark;
154
155 struct ac97_codec_if *codec_if;
156 struct ac97_host_if host_if;
157
158 void *powerhook;
159 };
160
161 static struct neo_firmware *nf;
162
163
164
165
166
167
168
169 static int nm_waitcd(struct neo_softc *sc);
170 static int nm_loadcoeff(struct neo_softc *sc, int dir, int num);
171 static int nm_init(struct neo_softc *);
172
173 int nmchan_getptr(struct neo_softc *, int);
174
175 static u_int32_t nm_rd(struct neo_softc *, int, int);
176 static void nm_wr(struct neo_softc *, int, u_int32_t, int);
177 static u_int32_t nm_rdbuf(struct neo_softc *, int, int);
178 static void nm_wrbuf(struct neo_softc *, int, u_int32_t, int);
179
180 int neo_match(struct device *, void *, void *);
181 void neo_attach(struct device *, struct device *, void *);
182 int neo_intr(void *);
183
184 int neo_open(void *, int);
185 void neo_close(void *);
186 int neo_query_encoding(void *, struct audio_encoding *);
187 int neo_set_params(void *, int, int, struct audio_params *, struct audio_params *);
188 int neo_round_blocksize(void *, int);
189 int neo_trigger_output(void *, void *, void *, int, void (*)(void *),
190 void *, struct audio_params *);
191 int neo_trigger_input(void *, void *, void *, int, void (*)(void *),
192 void *, struct audio_params *);
193 int neo_halt_output(void *);
194 int neo_halt_input(void *);
195 int neo_getdev(void *, struct audio_device *);
196 int neo_mixer_set_port(void *, mixer_ctrl_t *);
197 int neo_mixer_get_port(void *, mixer_ctrl_t *);
198 int neo_attach_codec(void *sc, struct ac97_codec_if *);
199 int neo_read_codec(void *sc, u_int8_t a, u_int16_t *d);
200 int neo_write_codec(void *sc, u_int8_t a, u_int16_t d);
201 void neo_reset_codec(void *sc);
202 enum ac97_host_flags neo_flags_codec(void *sc);
203 int neo_query_devinfo(void *, mixer_devinfo_t *);
204 void *neo_malloc(void *, int, size_t, int, int);
205 void neo_free(void *, void *, int);
206 size_t neo_round_buffersize(void *, int, size_t);
207 int neo_get_props(void *);
208 void neo_set_mixer(struct neo_softc *sc, int a, int d);
209 void neo_power(int why, void *arg);
210
211
212 struct cfdriver neo_cd = {
213 NULL, "neo", DV_DULL
214 };
215
216
217 struct cfattach neo_ca = {
218 sizeof(struct neo_softc), neo_match, neo_attach
219 };
220
221
222 struct audio_device neo_device = {
223 "NeoMagic 256",
224 "",
225 "neo"
226 };
227
228 #if 0
229 static u_int32_t badcards[] = {
230 0x0007103c,
231 0x008f1028,
232 };
233 #endif
234
235 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t))
236
237
238 static int samplerates[9] = {
239 8000,
240 11025,
241 16000,
242 22050,
243 24000,
244 32000,
245 44100,
246 48000,
247 99999999
248 };
249
250
251
252 struct audio_hw_if neo_hw_if = {
253 neo_open,
254 neo_close,
255 NULL,
256 neo_query_encoding,
257 neo_set_params,
258 #if 1
259 neo_round_blocksize,
260 #else
261 NULL,
262 #endif
263 NULL,
264 NULL,
265 NULL,
266 NULL,
267 NULL,
268 neo_halt_output,
269 neo_halt_input,
270 NULL,
271 neo_getdev,
272 NULL,
273 neo_mixer_set_port,
274 neo_mixer_get_port,
275 neo_query_devinfo,
276 neo_malloc,
277 neo_free,
278 neo_round_buffersize,
279 0,
280 neo_get_props,
281 neo_trigger_output,
282 neo_trigger_input,
283
284 };
285
286
287
288
289 static u_int32_t
290 nm_rd(struct neo_softc *sc, int regno, int size)
291 {
292 bus_space_tag_t st = sc->regiot;
293 bus_space_handle_t sh = sc->regioh;
294
295 switch (size) {
296 case 1:
297 return bus_space_read_1(st, sh, regno);
298 case 2:
299 return bus_space_read_2(st, sh, regno);
300 case 4:
301 return bus_space_read_4(st, sh, regno);
302 default:
303 return (0xffffffff);
304 }
305 }
306
307 static void
308 nm_wr(struct neo_softc *sc, int regno, u_int32_t data, int size)
309 {
310 bus_space_tag_t st = sc->regiot;
311 bus_space_handle_t sh = sc->regioh;
312
313 switch (size) {
314 case 1:
315 bus_space_write_1(st, sh, regno, data);
316 break;
317 case 2:
318 bus_space_write_2(st, sh, regno, data);
319 break;
320 case 4:
321 bus_space_write_4(st, sh, regno, data);
322 break;
323 }
324 }
325
326 static u_int32_t
327 nm_rdbuf(struct neo_softc *sc, int regno, int size)
328 {
329 bus_space_tag_t st = sc->bufiot;
330 bus_space_handle_t sh = sc->bufioh;
331
332 switch (size) {
333 case 1:
334 return bus_space_read_1(st, sh, regno);
335 case 2:
336 return bus_space_read_2(st, sh, regno);
337 case 4:
338 return bus_space_read_4(st, sh, regno);
339 default:
340 return (0xffffffff);
341 }
342 }
343
344 static void
345 nm_wrbuf(struct neo_softc *sc, int regno, u_int32_t data, int size)
346 {
347 bus_space_tag_t st = sc->bufiot;
348 bus_space_handle_t sh = sc->bufioh;
349
350 switch (size) {
351 case 1:
352 bus_space_write_1(st, sh, regno, data);
353 break;
354 case 2:
355 bus_space_write_2(st, sh, regno, data);
356 break;
357 case 4:
358 bus_space_write_4(st, sh, regno, data);
359 break;
360 }
361 }
362
363
364 static int
365 nm_waitcd(struct neo_softc *sc)
366 {
367 int cnt = 10;
368 int fail = 1;
369
370 while (cnt-- > 0) {
371 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy)
372 DELAY(100);
373 else {
374 fail = 0;
375 break;
376 }
377 }
378 return (fail);
379 }
380
381
382 static void
383 nm_ackint(struct neo_softc *sc, u_int32_t num)
384 {
385 if (sc->type == NM256AV_PCI_ID)
386 nm_wr(sc, NM_INT_REG, num << 1, 2);
387 else if (sc->type == NM256ZX_PCI_ID)
388 nm_wr(sc, NM_INT_REG, num, 4);
389 }
390
391 static int
392 nm_loadcoeff(struct neo_softc *sc, int dir, int num)
393 {
394 int ofs, sz, i;
395 u_int32_t addr;
396
397 if (nf == NULL) {
398 size_t buflen;
399 u_char *buf;
400 int error;
401
402 error = loadfirmware("neo-coefficients", &buf, &buflen);
403 if (error)
404 return (error);
405 nf = (struct neo_firmware *)buf;
406 }
407
408 addr = (dir == AUMODE_PLAY)? 0x01c : 0x21c;
409 if (dir == AUMODE_RECORD)
410 num += 8;
411 sz = nf->coefficientSizes[num];
412 ofs = 0;
413 while (num-- > 0)
414 ofs+= nf->coefficientSizes[num];
415 for (i = 0; i < sz; i++)
416 nm_wrbuf(sc, sc->cbuf + i, nf->coefficients[ofs + i], 1);
417 nm_wr(sc, addr, sc->cbuf, 4);
418 if (dir == AUMODE_PLAY)
419 sz--;
420 nm_wr(sc, addr + 4, sc->cbuf + sz, 4);
421 return (0);
422 }
423
424 int
425 nmchan_getptr(sc, mode)
426 struct neo_softc *sc;
427 int mode;
428 {
429 if (mode == AUMODE_PLAY)
430 return (nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf);
431 else
432 return (nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf);
433 }
434
435
436
437 int
438 neo_intr(void *p)
439 {
440 struct neo_softc *sc = (struct neo_softc *)p;
441 int status, x;
442 int rv = 0;
443
444 status = nm_rd(sc, NM_INT_REG, sc->irsz);
445
446 if (status & sc->playint) {
447 status &= ~sc->playint;
448
449 sc->pwmark += sc->pblksize;
450 sc->pwmark %= sc->pbufsize;
451
452 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
453
454 nm_ackint(sc, sc->playint);
455
456 if (sc->pintr)
457 (*sc->pintr)(sc->parg);
458
459 rv = 1;
460 }
461 if (status & sc->recint) {
462 status &= ~sc->recint;
463
464 sc->rwmark += sc->rblksize;
465 sc->rwmark %= sc->rbufsize;
466
467 nm_ackint(sc, sc->recint);
468 if (sc->rintr)
469 (*sc->rintr)(sc->rarg);
470
471 rv = 1;
472 }
473 if (status & sc->misc1int) {
474 status &= ~sc->misc1int;
475 nm_ackint(sc, sc->misc1int);
476 x = nm_rd(sc, 0x400, 1);
477 nm_wr(sc, 0x400, x | 2, 1);
478 printf("%s: misc int 1\n", sc->dev.dv_xname);
479 rv = 1;
480 }
481 if (status & sc->misc2int) {
482 status &= ~sc->misc2int;
483 nm_ackint(sc, sc->misc2int);
484 x = nm_rd(sc, 0x400, 1);
485 nm_wr(sc, 0x400, x & ~2, 1);
486 printf("%s: misc int 2\n", sc->dev.dv_xname);
487 rv = 1;
488 }
489 if (status) {
490 status &= ~sc->misc2int;
491 nm_ackint(sc, sc->misc2int);
492 printf("%s: unknown int\n", sc->dev.dv_xname);
493 rv = 1;
494 }
495
496 return (rv);
497 }
498
499
500
501
502
503
504
505 static int
506 nm_init(struct neo_softc *sc)
507 {
508 u_int32_t ofs, i;
509
510 if (sc->type == NM256AV_PCI_ID) {
511 sc->ac97_base = NM_MIXER_OFFSET;
512 sc->ac97_status = NM_MIXER_STATUS_OFFSET;
513 sc->ac97_busy = NM_MIXER_READY_MASK;
514
515 sc->buftop = 2560 * 1024;
516
517 sc->irsz = 2;
518 sc->playint = NM_PLAYBACK_INT;
519 sc->recint = NM_RECORD_INT;
520 sc->misc1int = NM_MISC_INT_1;
521 sc->misc2int = NM_MISC_INT_2;
522 } else if (sc->type == NM256ZX_PCI_ID) {
523 sc->ac97_base = NM_MIXER_OFFSET;
524 sc->ac97_status = NM2_MIXER_STATUS_OFFSET;
525 sc->ac97_busy = NM2_MIXER_READY_MASK;
526
527 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024;
528
529 sc->irsz = 4;
530 sc->playint = NM2_PLAYBACK_INT;
531 sc->recint = NM2_RECORD_INT;
532 sc->misc1int = NM2_MISC_INT_1;
533 sc->misc2int = NM2_MISC_INT_2;
534 } else return -1;
535 sc->badintr = 0;
536 ofs = sc->buftop - 0x0400;
537 sc->buftop -= 0x1400;
538
539 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) {
540 i = nm_rdbuf(sc, ofs + 4, 4);
541 if (i != 0 && i != 0xffffffff)
542 sc->buftop = i;
543 }
544
545 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT;
546 sc->rbuf = sc->cbuf - NM_BUFFSIZE;
547 sc->pbuf = sc->rbuf - NM_BUFFSIZE;
548 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4);
549
550 nm_wr(sc, 0, 0x11, 1);
551 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
552 nm_wr(sc, 0x214, 0, 2);
553
554 return 0;
555 }
556
557
558 void
559 neo_attach(parent, self, aux)
560 struct device *parent;
561 struct device *self;
562 void *aux;
563 {
564 struct neo_softc *sc = (struct neo_softc *)self;
565 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
566 pci_chipset_tag_t pc = pa->pa_pc;
567 char const *intrstr;
568 pci_intr_handle_t ih;
569 int error;
570
571 sc->type = pa->pa_id;
572
573
574 if (pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_MEM, 0,
575 &sc->bufiot, &sc->bufioh, NULL, NULL, 0)) {
576 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname);
577 return;
578 }
579
580
581 if (pci_mapreg_map(pa, PCI_MAPS + 4, PCI_MAPREG_TYPE_MEM, 0,
582 &sc->regiot, &sc->regioh, NULL, NULL, 0)) {
583 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname);
584 return;
585 }
586
587
588 if (pci_intr_map(pa, &ih)) {
589 printf("\n%s: couldn't map interrupt\n", sc->dev.dv_xname);
590 return;
591 }
592 intrstr = pci_intr_string(pc, ih);
593 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc,
594 sc->dev.dv_xname);
595
596 if (sc->ih == NULL) {
597 printf("\n%s: couldn't establish interrupt",
598 sc->dev.dv_xname);
599 if (intrstr != NULL)
600 printf(" at %s", intrstr);
601 printf("\n");
602 return;
603 }
604 printf(": %s\n", intrstr);
605
606 if ((error = nm_init(sc)) != 0)
607 return;
608
609 sc->host_if.arg = sc;
610
611 sc->host_if.attach = neo_attach_codec;
612 sc->host_if.read = neo_read_codec;
613 sc->host_if.write = neo_write_codec;
614 sc->host_if.reset = neo_reset_codec;
615 sc->host_if.flags = neo_flags_codec;
616
617 if ((error = ac97_attach(&sc->host_if)) != 0)
618 return;
619
620 sc->powerhook = powerhook_establish(neo_power, sc);
621
622 audio_attach_mi(&neo_hw_if, sc, &sc->dev);
623
624 return;
625 }
626
627 void
628 neo_power(int why, void *addr)
629 {
630 struct neo_softc *sc = (struct neo_softc *)addr;
631
632 if (why == PWR_RESUME) {
633 nm_init(sc);
634 (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
635 }
636 }
637
638
639
640 int
641 neo_match(parent, match, aux)
642 struct device *parent;
643 void *match;
644 void *aux;
645 {
646 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
647 #if 0
648 u_int32_t subdev, badcard;
649 #endif
650
651 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC)
652 return (0);
653
654 #if 0
655 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
656 #endif
657 switch (PCI_PRODUCT(pa->pa_id)) {
658 case PCI_PRODUCT_NEOMAGIC_NM256AV:
659 #if 0
660 i = 0;
661 while ((i < NUM_BADCARDS) && (badcards[i] != subdev))
662 i++;
663 if (i == NUM_BADCARDS)
664 s = "NeoMagic 256AV";
665 DEB(else)
666 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n"));
667 return (1);
668 #endif
669 case PCI_PRODUCT_NEOMAGIC_NM256ZX:
670 return (1);
671 }
672
673 return (0);
674 }
675
676 int
677 neo_read_codec(sc_, a, d)
678 void *sc_;
679 u_int8_t a;
680 u_int16_t *d;
681 {
682 struct neo_softc *sc = sc_;
683
684 if (!nm_waitcd(sc)) {
685 *d = nm_rd(sc, sc->ac97_base + a, 2);
686 DELAY(1000);
687 return 0;
688 }
689
690 return (ENXIO);
691 }
692
693
694 int
695 neo_write_codec(sc_, a, d)
696 void *sc_;
697 u_int8_t a;
698 u_int16_t d;
699 {
700 struct neo_softc *sc = sc_;
701 int cnt = 3;
702
703 if (!nm_waitcd(sc)) {
704 while (cnt-- > 0) {
705 nm_wr(sc, sc->ac97_base + a, d, 2);
706 if (!nm_waitcd(sc)) {
707 DELAY(1000);
708 return (0);
709 }
710 }
711 }
712
713 return (ENXIO);
714 }
715
716
717 int
718 neo_attach_codec(sc_, codec_if)
719 void *sc_;
720 struct ac97_codec_if *codec_if;
721 {
722 struct neo_softc *sc = sc_;
723
724 sc->codec_if = codec_if;
725 return (0);
726 }
727
728 void
729 neo_reset_codec(sc)
730 void *sc;
731 {
732 nm_wr(sc, 0x6c0, 0x01, 1);
733 nm_wr(sc, 0x6cc, 0x87, 1);
734 nm_wr(sc, 0x6cc, 0x80, 1);
735 nm_wr(sc, 0x6cc, 0x00, 1);
736
737 return;
738 }
739
740
741 enum ac97_host_flags
742 neo_flags_codec(sc)
743 void *sc;
744 {
745 return (AC97_HOST_DONT_READANY);
746 }
747
748 int
749 neo_open(addr, flags)
750 void *addr;
751 int flags;
752 {
753 return (0);
754 }
755
756
757
758
759 void
760 neo_close(addr)
761 void *addr;
762 {
763 struct neo_softc *sc = addr;
764
765 neo_halt_output(sc);
766 neo_halt_input(sc);
767
768 sc->pintr = 0;
769 sc->rintr = 0;
770 }
771
772 int
773 neo_query_encoding(addr, fp)
774 void *addr;
775 struct audio_encoding *fp;
776 {
777 switch (fp->index) {
778 case 0:
779 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
780 fp->encoding = AUDIO_ENCODING_ULINEAR;
781 fp->precision = 8;
782 fp->flags = 0;
783 return (0);
784 case 1:
785 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
786 fp->encoding = AUDIO_ENCODING_ULAW;
787 fp->precision = 8;
788 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
789 return (0);
790 case 2:
791 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
792 fp->encoding = AUDIO_ENCODING_ALAW;
793 fp->precision = 8;
794 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
795 return (0);
796 case 3:
797 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
798 fp->encoding = AUDIO_ENCODING_SLINEAR;
799 fp->precision = 8;
800 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
801 return (0);
802 case 4:
803 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
804 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
805 fp->precision = 16;
806 fp->flags = 0;
807 return (0);
808 case 5:
809 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
810 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
811 fp->precision = 16;
812 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
813 return (0);
814 case 6:
815 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
816 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
817 fp->precision = 16;
818 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
819 return (0);
820 case 7:
821 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
822 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
823 fp->precision = 16;
824 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
825 return (0);
826 default:
827 return (EINVAL);
828 }
829 }
830
831
832 int
833 neo_set_params(addr, setmode, usemode, play, rec)
834 void *addr;
835 int setmode, usemode;
836 struct audio_params *play, *rec;
837 {
838 struct neo_softc *sc = addr;
839 u_int32_t base;
840 u_int8_t x;
841 int mode;
842 struct audio_params *p;
843
844 for (mode = AUMODE_RECORD; mode != -1;
845 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
846 if ((setmode & mode) == 0)
847 continue;
848
849 p = mode == AUMODE_PLAY ? play : rec;
850
851 if (p == NULL) continue;
852
853 for (x = 0; x < 8; x++)
854 if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2)
855 break;
856
857 if (x == 8) return (EINVAL);
858
859 p->sample_rate = samplerates[x];
860 nm_loadcoeff(sc, mode, x);
861
862 x <<= 4;
863 x &= NM_RATE_MASK;
864 if (p->precision == 16) x |= NM_RATE_BITS_16;
865 if (p->channels == 2) x |= NM_RATE_STEREO;
866
867 base = (mode == AUMODE_PLAY) ?
868 NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET;
869 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1);
870
871 p->factor = 1;
872 p->sw_code = 0;
873 switch (p->encoding) {
874 case AUDIO_ENCODING_SLINEAR_BE:
875 if (p->precision == 16)
876 p->sw_code = swap_bytes;
877 else
878 p->sw_code = change_sign8;
879 break;
880 case AUDIO_ENCODING_SLINEAR_LE:
881 if (p->precision != 16)
882 p->sw_code = change_sign8;
883 break;
884 case AUDIO_ENCODING_ULINEAR_BE:
885 if (p->precision == 16) {
886 if (mode == AUMODE_PLAY)
887 p->sw_code = swap_bytes_change_sign16;
888 else
889 p->sw_code = change_sign16_swap_bytes;
890 }
891 break;
892 case AUDIO_ENCODING_ULINEAR_LE:
893 if (p->precision == 16)
894 p->sw_code = change_sign16;
895 break;
896 case AUDIO_ENCODING_ULAW:
897 if (mode == AUMODE_PLAY) {
898 p->factor = 2;
899 p->sw_code = mulaw_to_slinear16;
900 } else
901 p->sw_code = ulinear8_to_mulaw;
902 break;
903 case AUDIO_ENCODING_ALAW:
904 if (mode == AUMODE_PLAY) {
905 p->factor = 2;
906 p->sw_code = alaw_to_slinear16;
907 } else
908 p->sw_code = ulinear8_to_alaw;
909 break;
910 default:
911 return (EINVAL);
912 }
913 }
914
915
916 return (0);
917 }
918
919 int
920 neo_round_blocksize(addr, blk)
921 void *addr;
922 int blk;
923 {
924 return (NM_BUFFSIZE / 2);
925 }
926
927 int
928 neo_trigger_output(addr, start, end, blksize, intr, arg, param)
929 void *addr;
930 void *start, *end;
931 int blksize;
932 void (*intr)(void *);
933 void *arg;
934 struct audio_params *param;
935 {
936 struct neo_softc *sc = addr;
937 int ssz;
938
939 sc->pintr = intr;
940 sc->parg = arg;
941
942 ssz = (param->precision * param->factor == 16)? 2 : 1;
943 if (param->channels == 2)
944 ssz <<= 1;
945
946 sc->pbufsize = ((char *)end - (char *)start);
947 sc->pblksize = blksize;
948 sc->pwmark = blksize;
949
950 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4);
951 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4);
952 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4);
953 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
954 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
955 NM_PLAYBACK_ENABLE_FLAG, 1);
956 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2);
957
958 return (0);
959 }
960
961
962
963 int
964 neo_trigger_input(addr, start, end, blksize, intr, arg, param)
965 void *addr;
966 void *start, *end;
967 int blksize;
968 void (*intr)(void *);
969 void *arg;
970 struct audio_params *param;
971 {
972 struct neo_softc *sc = addr;
973 int ssz;
974
975 sc->rintr = intr;
976 sc->rarg = arg;
977
978 ssz = (param->precision * param->factor == 16)? 2 : 1;
979 if (param->channels == 2)
980 ssz <<= 1;
981
982 sc->rbufsize = ((char *)end - (char *)start);
983 sc->rblksize = blksize;
984 sc->rwmark = blksize;
985
986 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4);
987 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4);
988 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4);
989 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4);
990 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
991 NM_RECORD_ENABLE_FLAG, 1);
992
993 return (0);
994 }
995
996 int
997 neo_halt_output(addr)
998 void *addr;
999 {
1000 struct neo_softc *sc = (struct neo_softc *)addr;
1001
1002 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1);
1003 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2);
1004
1005 sc->pintr = 0;
1006
1007 return (0);
1008 }
1009
1010 int
1011 neo_halt_input(addr)
1012 void *addr;
1013 {
1014 struct neo_softc *sc = (struct neo_softc *)addr;
1015
1016 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
1017
1018 sc->rintr = 0;
1019
1020 return (0);
1021 }
1022
1023 int
1024 neo_getdev(addr, retp)
1025 void *addr;
1026 struct audio_device *retp;
1027 {
1028 *retp = neo_device;
1029 return (0);
1030 }
1031
1032 int
1033 neo_mixer_set_port(addr, cp)
1034 void *addr;
1035 mixer_ctrl_t *cp;
1036 {
1037 struct neo_softc *sc = addr;
1038
1039 return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if, cp));
1040 }
1041
1042 int
1043 neo_mixer_get_port(addr, cp)
1044 void *addr;
1045 mixer_ctrl_t *cp;
1046 {
1047 struct neo_softc *sc = addr;
1048
1049 return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if, cp));
1050 }
1051
1052 int
1053 neo_query_devinfo(addr, dip)
1054 void *addr;
1055 mixer_devinfo_t *dip;
1056 {
1057 struct neo_softc *sc = addr;
1058
1059 return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip));
1060 }
1061
1062 void *
1063 neo_malloc(addr, direction, size, pool, flags)
1064 void *addr;
1065 int direction;
1066 size_t size;
1067 int pool, flags;
1068 {
1069 struct neo_softc *sc = addr;
1070 void *rv = 0;
1071
1072 switch (direction) {
1073 case AUMODE_PLAY:
1074 rv = (char *)sc->bufioh + sc->pbuf;
1075 break;
1076 case AUMODE_RECORD:
1077 rv = (char *)sc->bufioh + sc->rbuf;
1078 break;
1079 default:
1080 break;
1081 }
1082
1083 return (rv);
1084 }
1085
1086 void
1087 neo_free(addr, ptr, pool)
1088 void *addr;
1089 void *ptr;
1090 int pool;
1091 {
1092 return;
1093 }
1094
1095 size_t
1096 neo_round_buffersize(addr, direction, size)
1097 void *addr;
1098 int direction;
1099 size_t size;
1100 {
1101 return (NM_BUFFSIZE);
1102 }
1103
1104
1105 int
1106 neo_get_props(addr)
1107 void *addr;
1108 {
1109
1110 return (AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
1111 }