neo.c revision 1.1 1 /* $NetBSD: neo.c,v 1.1 2000/11/05 06:43:46 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1999 Cameron Grant <gandalf (at) vilnya.demon.co.uk>
5 * All rights reserved.
6 *
7 * Derived from the public domain Linux driver
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * FreeBSD: src/sys/dev/sound/pci/neomagic.c,v 1.8 2000/03/20 15:30:50 cg Exp
31 * OpenBSD: neo.c,v 1.4 2000/07/19 09:04:37 csapuntz Exp
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38 #include <sys/device.h>
39
40 #include <machine/bus.h>
41
42 #include <dev/pci/pcidevs.h>
43 #include <dev/pci/pcivar.h>
44
45 #include <dev/pci/neoreg.h>
46 #include <dev/pci/neo-coeff.h>
47
48 #include <sys/audioio.h>
49 #include <dev/audio_if.h>
50 #include <dev/mulaw.h>
51 #include <dev/auconv.h>
52
53 #include <dev/ic/ac97var.h>
54
55
56 /* -------------------------------------------------------------------- */
57 /*
58 * As of 04/13/00, public documentation on the Neomagic 256 is not available.
59 * These comments were gleaned by looking at the driver carefully.
60 *
61 * The Neomagic 256 AV/ZX chips provide both video and audio capabilities
62 * on one chip. About 2-6 megabytes of memory are associated with
63 * the chip. Most of this goes to video frame buffers, but some is used for
64 * audio buffering
65 *
66 * Unlike most PCI audio chips, the Neomagic chip does not rely on DMA.
67 * Instead, the chip allows you to carve out two ring buffers out of its
68 * memory. However you carve this and how much you can carve seems to be
69 * voodoo. The algorithm is in nm_init.
70 *
71 * Most Neomagic audio chips use the AC-97 codec interface. However, there
72 * seem to be a select few chips 256AV chips that do not support AC-97.
73 * This driver does not support them but there are rumors that it
74 * mgiht work with wss isa drivers. This might require some playing around
75 * with your BIOS.
76 *
77 * The Neomagic 256 AV/ZX have 2 PCI I/O region descriptors. Both of
78 * them describe a memory region. The frame buffer is the first region
79 * and the register set is the secodn region.
80 *
81 * The register manipulation logic is taken from the Linux driver,
82 * which is in the public domain.
83 *
84 * The Neomagic is even nice enough to map the AC-97 codec registers into
85 * the register space to allow direct manipulation. Watch out, accessing
86 * AC-97 registers on the Neomagic requires great delicateness, otherwise
87 * the thing will hang the PCI bus, rendering your system frozen.
88 *
89 * For one, it seems the Neomagic status register that reports AC-97
90 * readiness should NOT be polled more often than once each 1ms.
91 *
92 * Also, writes to the AC-97 register space may take order 40us to
93 * complete.
94 *
95 * Unlike many sound engines, the Neomagic does not support (as fas as
96 * we know :) the notion of interrupting every n bytes transferred,
97 * unlike many DMA engines. Instead, it allows you to specify one
98 * location in each ring buffer (called the watermark). When the chip
99 * passes that location while playing, it signals an interrupt.
100 *
101 * The ring buffer size is currently 16k. That is about 100ms of audio
102 * at 44.1khz/stero/16 bit. However, to keep the buffer full, interrupts
103 * are generated more often than that, so 20-40 interrupts per second
104 * should not be unexpected. Increasing BUFFSIZE should help minimize
105 * of glitches due to drivers that spend to much time looping at high
106 * privelege levels as well as the impact of badly written audio
107 * interface clients.
108 *
109 * TO-DO list:
110 * Add mmap support.
111 *
112 * Figure out interaction with video stuff (look at Xfree86 driver?)
113 *
114 * Power management (neoactivate)
115 *
116 * Fix detect of Neo devices that don't work this driver (see neo_attach)
117 *
118 * Figure out how to shrink that huge table neo-coeff.h
119 */
120
121 #define NM_BUFFSIZE 16384
122
123 /* device private data */
124 struct neo_softc {
125 struct device dev;
126
127 bus_space_tag_t bufiot;
128 bus_space_handle_t bufioh;
129
130 bus_space_tag_t regiot;
131 bus_space_handle_t regioh;
132
133 u_int32_t type;
134 void *ih;
135
136 void (*pintr)(void *); /* dma completion intr handler */
137 void *parg; /* arg for intr() */
138
139 void (*rintr)(void *); /* dma completion intr handler */
140 void *rarg; /* arg for intr() */
141
142 vaddr_t buf_vaddr;
143 vaddr_t rbuf_vaddr;
144 vaddr_t pbuf_vaddr;
145 int pbuf_allocated;
146 int rbuf_allocated;
147
148 u_int32_t ac97_base, ac97_status, ac97_busy;
149 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf;
150 u_int32_t playint, recint, misc1int, misc2int;
151 u_int32_t irsz, badintr;
152
153 u_int32_t pbufsize;
154 u_int32_t rbufsize;
155
156 u_int32_t pblksize;
157 u_int32_t rblksize;
158
159 u_int32_t pwmark;
160 u_int32_t rwmark;
161
162 struct ac97_codec_if *codec_if;
163 struct ac97_host_if host_if;
164 };
165
166 /* -------------------------------------------------------------------- */
167
168 /*
169 * prototypes
170 */
171
172 static int nm_waitcd(struct neo_softc *sc);
173 static int nm_loadcoeff(struct neo_softc *sc, int dir, int num);
174 static int nm_init(struct neo_softc *);
175
176 int neo_match(struct device *, struct cfdata *, void *);
177 void neo_attach(struct device *, struct device *, void *);
178 int neo_intr(void *);
179
180 int neo_open(void *, int);
181 void neo_close(void *);
182 int neo_query_encoding(void *, struct audio_encoding *);
183 int neo_set_params(void *, int, int, struct audio_params *,
184 struct audio_params *);
185 int neo_round_blocksize(void *, int);
186 int neo_trigger_output(void *, void *, void *, int, void (*)(void *),
187 void *, struct audio_params *);
188 int neo_trigger_input(void *, void *, void *, int, void (*)(void *),
189 void *, struct audio_params *);
190 int neo_halt_output(void *);
191 int neo_halt_input(void *);
192 int neo_getdev(void *, struct audio_device *);
193 int neo_mixer_set_port(void *, mixer_ctrl_t *);
194 int neo_mixer_get_port(void *, mixer_ctrl_t *);
195 int neo_attach_codec(void *sc, struct ac97_codec_if *);
196 int neo_read_codec(void *sc, u_int8_t a, u_int16_t *d);
197 int neo_write_codec(void *sc, u_int8_t a, u_int16_t d);
198 void neo_reset_codec(void *sc);
199 enum ac97_host_flags neo_flags_codec(void *sc);
200 int neo_query_devinfo(void *, mixer_devinfo_t *);
201 void *neo_malloc(void *, int, size_t, int, int);
202 void neo_free(void *, void *, int);
203 size_t neo_round_buffersize(void *, int, size_t);
204 int neo_get_props(void *);
205 void neo_set_mixer(struct neo_softc *sc, int a, int d);
206
207 struct cfattach neo_ca = {
208 sizeof(struct neo_softc), neo_match, neo_attach
209 };
210
211 struct audio_device neo_device = {
212 "NeoMagic 256",
213 "",
214 "neo"
215 };
216
217 #if 0
218 static u_int32_t badcards[] = {
219 0x0007103c,
220 0x008f1028,
221 };
222
223 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t))
224 #endif
225
226 /* The actual rates supported by the card. */
227 static const int samplerates[9] = {
228 8000,
229 11025,
230 16000,
231 22050,
232 24000,
233 32000,
234 44100,
235 48000,
236 99999999
237 };
238
239 /* -------------------------------------------------------------------- */
240
241 struct audio_hw_if neo_hw_if = {
242 neo_open,
243 neo_close,
244 NULL, /* drain */
245 neo_query_encoding,
246 neo_set_params,
247 neo_round_blocksize,
248 NULL, /* commit_setting */
249 NULL, /* init_output */
250 NULL, /* init_input */
251 NULL, /* start_output */
252 NULL, /* start_input */
253 neo_halt_output,
254 neo_halt_input,
255 NULL, /* speaker_ctl */
256 neo_getdev,
257 NULL, /* getfd */
258 neo_mixer_set_port,
259 neo_mixer_get_port,
260 neo_query_devinfo,
261 neo_malloc,
262 neo_free,
263 neo_round_buffersize,
264 0, /* mappage */
265 neo_get_props,
266 neo_trigger_output,
267 neo_trigger_input,
268 };
269
270 /* -------------------------------------------------------------------- */
271
272 #define nm_rd_1(sc, regno) \
273 bus_space_read_1((sc)->regiot, (sc)->regioh, (regno))
274
275 #define nm_rd_2(sc, regno) \
276 bus_space_read_2((sc)->regiot, (sc)->regioh, (regno))
277
278 #define nm_rd_4(sc, regno) \
279 bus_space_read_4((sc)->regiot, (sc)->regioh, (regno))
280
281 #define nm_wr_1(sc, regno, val) \
282 bus_space_write_1((sc)->regiot, (sc)->regioh, (regno), (val))
283
284 #define nm_wr_2(sc, regno, val) \
285 bus_space_write_2((sc)->regiot, (sc)->regioh, (regno), (val))
286
287 #define nm_wr_4(sc, regno, val) \
288 bus_space_write_4((sc)->regiot, (sc)->regioh, (regno), (val))
289
290 #define nm_rdbuf_4(sc, regno) \
291 bus_space_read_4((sc)->bufiot, (sc)->bufioh, (regno))
292
293 #define nm_wrbuf_1(sc, regno, val) \
294 bus_space_write_1((sc)->bufiot, (sc)->bufioh, (regno), (val))
295
296 /* ac97 codec */
297 static int
298 nm_waitcd(struct neo_softc *sc)
299 {
300 int cnt = 10;
301 int fail = 1;
302
303 while (cnt-- > 0) {
304 if (nm_rd_2(sc, sc->ac97_status) & sc->ac97_busy)
305 DELAY(100);
306 else {
307 fail = 0;
308 break;
309 }
310 }
311 return (fail);
312 }
313
314
315 static void
316 nm_ackint(struct neo_softc *sc, u_int32_t num)
317 {
318
319 switch (sc->type) {
320 case PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU:
321 nm_wr_2(sc, NM_INT_REG, num << 1);
322 break;
323
324 case PCI_PRODUCT_NEOMAGIC_NMMM256ZX_AU:
325 nm_wr_4(sc, NM_INT_REG, num);
326 break;
327 }
328 }
329
330 static int
331 nm_loadcoeff(struct neo_softc *sc, int dir, int num)
332 {
333 int ofs, sz, i;
334 u_int32_t addr;
335
336 addr = (dir == AUMODE_PLAY)? 0x01c : 0x21c;
337 if (dir == AUMODE_RECORD)
338 num += 8;
339 sz = coefficientSizes[num];
340 ofs = 0;
341 while (num-- > 0)
342 ofs+= coefficientSizes[num];
343 for (i = 0; i < sz; i++)
344 nm_wrbuf_1(sc, sc->cbuf + i, coefficients[ofs + i]);
345 nm_wr_4(sc, addr, sc->cbuf);
346 if (dir == AUMODE_PLAY)
347 sz--;
348 nm_wr_4(sc, addr + 4, sc->cbuf + sz);
349 return 0;
350 }
351
352 /* The interrupt handler */
353 int
354 neo_intr(void *p)
355 {
356 struct neo_softc *sc = (struct neo_softc *)p;
357 int status, x, active;
358 int rv = 0;
359
360 active = (sc->pintr || sc->rintr);
361 status = (sc->irsz == 2) ?
362 nm_rd_2(sc, NM_INT_REG) :
363 nm_rd_4(sc, NM_INT_REG);
364
365 if (status & sc->playint) {
366 status &= ~sc->playint;
367
368 sc->pwmark += sc->pblksize;
369 sc->pwmark %= sc->pbufsize;
370
371 nm_wr_4(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark);
372
373 nm_ackint(sc, sc->playint);
374
375 if (sc->pintr)
376 (*sc->pintr)(sc->parg);
377
378 rv = 1;
379 }
380 if (status & sc->recint) {
381 status &= ~sc->recint;
382
383 sc->rwmark += sc->rblksize;
384 sc->rwmark %= sc->rbufsize;
385
386 nm_ackint(sc, sc->recint);
387 if (sc->rintr)
388 (*sc->rintr)(sc->rarg);
389
390 rv = 1;
391 }
392 if (status & sc->misc1int) {
393 status &= ~sc->misc1int;
394 nm_ackint(sc, sc->misc1int);
395 x = nm_rd_1(sc, 0x400);
396 nm_wr_1(sc, 0x400, x | 2);
397 printf("%s: misc int 1\n", sc->dev.dv_xname);
398 rv = 1;
399 }
400 if (status & sc->misc2int) {
401 status &= ~sc->misc2int;
402 nm_ackint(sc, sc->misc2int);
403 x = nm_rd_1(sc, 0x400);
404 nm_wr_1(sc, 0x400, x & ~2);
405 printf("%s: misc int 2\n", sc->dev.dv_xname);
406 rv = 1;
407 }
408 if (status) {
409 status &= ~sc->misc2int;
410 nm_ackint(sc, sc->misc2int);
411 printf("%s: unknown int\n", sc->dev.dv_xname);
412 rv = 1;
413 }
414
415 return (rv);
416 }
417
418 /* -------------------------------------------------------------------- */
419
420 /*
421 * Probe and attach the card
422 */
423
424 static int
425 nm_init(struct neo_softc *sc)
426 {
427 u_int32_t ofs, i;
428
429 switch (sc->type) {
430 case PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU:
431 sc->ac97_base = NM_MIXER_OFFSET;
432 sc->ac97_status = NM_MIXER_STATUS_OFFSET;
433 sc->ac97_busy = NM_MIXER_READY_MASK;
434
435 sc->buftop = 2560 * 1024;
436
437 sc->irsz = 2;
438 sc->playint = NM_PLAYBACK_INT;
439 sc->recint = NM_RECORD_INT;
440 sc->misc1int = NM_MISC_INT_1;
441 sc->misc2int = NM_MISC_INT_2;
442 break;
443
444 case PCI_PRODUCT_NEOMAGIC_NMMM256ZX_AU:
445 sc->ac97_base = NM_MIXER_OFFSET;
446 sc->ac97_status = NM2_MIXER_STATUS_OFFSET;
447 sc->ac97_busy = NM2_MIXER_READY_MASK;
448
449 sc->buftop = (nm_rd_2(sc, 0xa0b) ? 6144 : 4096) * 1024;
450
451 sc->irsz = 4;
452 sc->playint = NM2_PLAYBACK_INT;
453 sc->recint = NM2_RECORD_INT;
454 sc->misc1int = NM2_MISC_INT_1;
455 sc->misc2int = NM2_MISC_INT_2;
456 break;
457 #ifdef DIAGNOSTIC
458 default:
459 panic("nm_init: impossible");
460 #endif
461 }
462
463 sc->badintr = 0;
464 ofs = sc->buftop - 0x0400;
465 sc->buftop -= 0x1400;
466
467 if ((nm_rdbuf_4(sc, ofs) & NM_SIG_MASK) == NM_SIGNATURE) {
468 i = nm_rdbuf_4(sc, ofs + 4);
469 if (i != 0 && i != 0xffffffff)
470 sc->buftop = i;
471 }
472
473 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT;
474 sc->rbuf = sc->cbuf - NM_BUFFSIZE;
475 sc->pbuf = sc->rbuf - NM_BUFFSIZE;
476 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4);
477
478 sc->buf_vaddr = (vaddr_t) bus_space_vaddr(sc->bufiot, sc->bufioh);
479 sc->rbuf_vaddr = sc->buf_vaddr + sc->rbuf;
480 sc->pbuf_vaddr = sc->buf_vaddr + sc->pbuf;
481
482 nm_wr_1(sc, 0, 0x11);
483 nm_wr_1(sc, NM_RECORD_ENABLE_REG, 0);
484 nm_wr_2(sc, 0x214, 0);
485
486 return 0;
487 }
488
489 void
490 neo_attach(struct device *parent, struct device *self, void *aux)
491 {
492 struct neo_softc *sc = (struct neo_softc *)self;
493 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
494 pci_chipset_tag_t pc = pa->pa_pc;
495 char const *intrstr;
496 pci_intr_handle_t ih;
497 pcireg_t csr;
498 int error;
499
500 sc->type = PCI_PRODUCT(pa->pa_id);
501
502 printf(": NeoMagic 256%s audio\n",
503 sc->type == PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU ? "AV" : "ZX");
504
505 /* Map I/O register */
506 if (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_MEM, 0,
507 &sc->bufiot, &sc->bufioh, NULL, NULL)) {
508 printf("%s: can't map buffer\n", sc->dev.dv_xname);
509 return;
510 }
511
512 if (pci_mapreg_map(pa, PCI_MAPREG_START + 4, PCI_MAPREG_TYPE_MEM, 0,
513 &sc->regiot, &sc->regioh, NULL, NULL)) {
514 printf("%s: can't map registers\n", sc->dev.dv_xname);
515 return;
516 }
517
518 /* Map and establish the interrupt. */
519 if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
520 pa->pa_intrline, &ih)) {
521 printf("%s: couldn't map interrupt\n", sc->dev.dv_xname);
522 return;
523 }
524
525 intrstr = pci_intr_string(pc, ih);
526 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc);
527
528 if (sc->ih == NULL) {
529 printf("%s: couldn't establish interrupt",
530 sc->dev.dv_xname);
531 if (intrstr != NULL)
532 printf(" at %s", intrstr);
533 printf("\n");
534 return;
535 }
536 printf("%s: interruping at %s\n", sc->dev.dv_xname, intrstr);
537
538 if ((error = nm_init(sc)) != 0)
539 return;
540
541 /* Enable the device. */
542 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
543 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
544 csr | PCI_COMMAND_MASTER_ENABLE);
545
546 sc->host_if.arg = sc;
547
548 sc->host_if.attach = neo_attach_codec;
549 sc->host_if.read = neo_read_codec;
550 sc->host_if.write = neo_write_codec;
551 sc->host_if.reset = neo_reset_codec;
552 sc->host_if.flags = neo_flags_codec;
553
554 if ((error = ac97_attach(&sc->host_if)) != 0)
555 return;
556
557 audio_attach_mi(&neo_hw_if, sc, &sc->dev);
558 }
559
560 int
561 neo_match(struct device *parent, struct cfdata *match, void *aux)
562 {
563 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
564 #if 0
565 u_int32_t subdev, badcard;
566 #endif
567
568 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC)
569 return (0);
570
571 #if 0
572 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
573 #endif
574 switch (PCI_PRODUCT(pa->pa_id)) {
575 case PCI_PRODUCT_NEOMAGIC_NMMM256AV_AU:
576 #if 0
577 i = 0;
578 while ((i < NUM_BADCARDS) && (badcards[i] != subdev))
579 i++;
580 if (i == NUM_BADCARDS)
581 s = "NeoMagic 256AV";
582 DEB(else)
583 DEB(device_printf(dev,
584 "this is a non-ac97 NM256AV, not attaching\n"));
585 return (1);
586 #endif
587 case PCI_PRODUCT_NEOMAGIC_NMMM256ZX_AU:
588 return (1);
589 }
590
591 return (0);
592 }
593
594 int
595 neo_read_codec(void *v, u_int8_t a, u_int16_t *d)
596 {
597 struct neo_softc *sc = v;
598
599 if (!nm_waitcd(sc)) {
600 *d = nm_rd_2(sc, sc->ac97_base + a);
601 DELAY(1000);
602 return 0;
603 }
604
605 return (ENXIO);
606 }
607
608
609 int
610 neo_write_codec(void *v, u_int8_t a, u_int16_t d)
611 {
612 struct neo_softc *sc = v;
613 int cnt = 3;
614
615 if (!nm_waitcd(sc)) {
616 while (cnt-- > 0) {
617 nm_wr_2(sc, sc->ac97_base + a, d);
618 if (!nm_waitcd(sc)) {
619 DELAY(1000);
620 return (0);
621 }
622 }
623 }
624
625 return (ENXIO);
626 }
627
628 int
629 neo_attach_codec(void *v, struct ac97_codec_if *codec_if)
630 {
631 struct neo_softc *sc = v;
632
633 sc->codec_if = codec_if;
634 return (0);
635 }
636
637 void
638 neo_reset_codec(void *v)
639 {
640 struct neo_softc *sc = v;
641
642 nm_wr_1(sc, 0x6c0, 0x01);
643 nm_wr_1(sc, 0x6cc, 0x87);
644 nm_wr_1(sc, 0x6cc, 0x80);
645 nm_wr_1(sc, 0x6cc, 0x00);
646 }
647
648 enum ac97_host_flags
649 neo_flags_codec(void *v)
650 {
651
652 return (AC97_HOST_DONT_READ);
653 }
654
655 int
656 neo_open(void *addr, int flags)
657 {
658
659 return (0);
660 }
661
662 /*
663 * Close function is called at splaudio().
664 */
665 void
666 neo_close(void *addr)
667 {
668 struct neo_softc *sc = addr;
669
670 neo_halt_output(sc);
671 neo_halt_input(sc);
672
673 sc->pintr = 0;
674 sc->rintr = 0;
675 }
676
677 int
678 neo_query_encoding(void *addr, struct audio_encoding *fp)
679 {
680
681 switch (fp->index) {
682 case 0:
683 strcpy(fp->name, AudioEulinear);
684 fp->encoding = AUDIO_ENCODING_ULINEAR;
685 fp->precision = 8;
686 fp->flags = 0;
687 return (0);
688 case 1:
689 strcpy(fp->name, AudioEmulaw);
690 fp->encoding = AUDIO_ENCODING_ULAW;
691 fp->precision = 8;
692 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
693 return (0);
694 case 2:
695 strcpy(fp->name, AudioEalaw);
696 fp->encoding = AUDIO_ENCODING_ALAW;
697 fp->precision = 8;
698 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
699 return (0);
700 case 3:
701 strcpy(fp->name, AudioEslinear);
702 fp->encoding = AUDIO_ENCODING_SLINEAR;
703 fp->precision = 8;
704 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
705 return (0);
706 case 4:
707 strcpy(fp->name, AudioEslinear_le);
708 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
709 fp->precision = 16;
710 fp->flags = 0;
711 return (0);
712 case 5:
713 strcpy(fp->name, AudioEulinear_le);
714 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
715 fp->precision = 16;
716 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
717 return (0);
718 case 6:
719 strcpy(fp->name, AudioEslinear_be);
720 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
721 fp->precision = 16;
722 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
723 return (0);
724 case 7:
725 strcpy(fp->name, AudioEulinear_be);
726 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
727 fp->precision = 16;
728 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
729 return (0);
730 default:
731 return (EINVAL);
732 }
733 }
734
735 /* Todo: don't commit settings to card until we've verified all parameters */
736 int
737 neo_set_params(void *addr, int setmode, int usemode, struct audio_params *play,
738 struct audio_params *rec)
739 {
740 struct neo_softc *sc = addr;
741 u_int32_t base;
742 u_int8_t x;
743 int mode;
744 struct audio_params *p;
745
746 for (mode = AUMODE_RECORD; mode != -1;
747 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
748 if ((setmode & mode) == 0)
749 continue;
750
751 p = mode == AUMODE_PLAY ? play : rec;
752
753 if (p == NULL) continue;
754
755 for (x = 0; x < 8; x++) {
756 if (p->sample_rate <
757 (samplerates[x] + samplerates[x + 1]) / 2)
758 break;
759 }
760 if (x == 8)
761 return (EINVAL);
762
763 p->sample_rate = samplerates[x];
764 nm_loadcoeff(sc, mode, x);
765
766 x <<= 4;
767 x &= NM_RATE_MASK;
768 if (p->precision == 16)
769 x |= NM_RATE_BITS_16;
770 if (p->channels == 2)
771 x |= NM_RATE_STEREO;
772
773 base = (mode == AUMODE_PLAY)?
774 NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET;
775 nm_wr_1(sc, base + NM_RATE_REG_OFFSET, x);
776
777 p->factor = 1;
778 p->sw_code = 0;
779 switch (p->encoding) {
780 case AUDIO_ENCODING_SLINEAR_BE:
781 if (p->precision == 16)
782 p->sw_code = swap_bytes;
783 else
784 p->sw_code = change_sign8;
785 break;
786 case AUDIO_ENCODING_SLINEAR_LE:
787 if (p->precision != 16)
788 p->sw_code = change_sign8;
789 break;
790 case AUDIO_ENCODING_ULINEAR_BE:
791 if (p->precision == 16) {
792 if (mode == AUMODE_PLAY)
793 p->sw_code =
794 swap_bytes_change_sign16_le;
795 else
796 p->sw_code =
797 change_sign16_swap_bytes_le;
798 }
799 break;
800 case AUDIO_ENCODING_ULINEAR_LE:
801 if (p->precision == 16)
802 p->sw_code = change_sign16_le;
803 break;
804 case AUDIO_ENCODING_ULAW:
805 if (mode == AUMODE_PLAY) {
806 p->factor = 2;
807 p->sw_code = mulaw_to_slinear16_le;
808 } else
809 p->sw_code = ulinear8_to_mulaw;
810 break;
811 case AUDIO_ENCODING_ALAW:
812 if (mode == AUMODE_PLAY) {
813 p->factor = 2;
814 p->sw_code = alaw_to_slinear16_le;
815 } else
816 p->sw_code = ulinear8_to_alaw;
817 break;
818 default:
819 return (EINVAL);
820 }
821 }
822
823
824 return (0);
825 }
826
827 int
828 neo_round_blocksize(void *addr, int blk)
829 {
830
831 return (NM_BUFFSIZE / 2);
832 }
833
834 int
835 neo_trigger_output(void *addr, void *start, void *end, int blksize,
836 void (*intr)(void *), void *arg, struct audio_params *param)
837 {
838 struct neo_softc *sc = addr;
839 int ssz;
840
841 sc->pintr = intr;
842 sc->parg = arg;
843
844 ssz = (param->precision * param->factor == 16) ? 2 : 1;
845 if (param->channels == 2)
846 ssz <<= 1;
847
848 sc->pbufsize = ((char*)end - (char *)start);
849 sc->pblksize = blksize;
850 sc->pwmark = blksize;
851
852 nm_wr_4(sc, NM_PBUFFER_START, sc->pbuf);
853 nm_wr_4(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz);
854 nm_wr_4(sc, NM_PBUFFER_CURRP, sc->pbuf);
855 nm_wr_4(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark);
856 nm_wr_1(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
857 NM_PLAYBACK_ENABLE_FLAG);
858 nm_wr_2(sc, NM_AUDIO_MUTE_REG, 0);
859
860 return (0);
861 }
862
863 int
864 neo_trigger_input(void *addr, void *start, void *end, int blksize,
865 void (*intr)(void *), void *arg, struct audio_params *param)
866 {
867 struct neo_softc *sc = addr;
868 int ssz;
869
870 sc->rintr = intr;
871 sc->rarg = arg;
872
873 ssz = (param->precision * param->factor == 16) ? 2 : 1;
874 if (param->channels == 2)
875 ssz <<= 1;
876
877 sc->rbufsize = ((char*)end - (char *)start);
878 sc->rblksize = blksize;
879 sc->rwmark = blksize;
880
881 nm_wr_4(sc, NM_RBUFFER_START, sc->rbuf);
882 nm_wr_4(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize);
883 nm_wr_4(sc, NM_RBUFFER_CURRP, sc->rbuf);
884 nm_wr_4(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark);
885 nm_wr_1(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
886 NM_RECORD_ENABLE_FLAG);
887
888 return (0);
889 }
890
891 int
892 neo_halt_output(void *addr)
893 {
894 struct neo_softc *sc = (struct neo_softc *)addr;
895
896 nm_wr_1(sc, NM_PLAYBACK_ENABLE_REG, 0);
897 nm_wr_2(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH);
898
899 return (0);
900 }
901
902 int
903 neo_halt_input(void *addr)
904 {
905 struct neo_softc *sc = (struct neo_softc *)addr;
906
907 nm_wr_1(sc, NM_RECORD_ENABLE_REG, 0);
908
909 return (0);
910 }
911
912 int
913 neo_getdev(void *addr, struct audio_device *retp)
914 {
915
916 *retp = neo_device;
917 return (0);
918 }
919
920 int
921 neo_mixer_set_port(void *addr, mixer_ctrl_t *cp)
922 {
923 struct neo_softc *sc = addr;
924
925 return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if, cp));
926 }
927
928 int
929 neo_mixer_get_port(void *addr, mixer_ctrl_t *cp)
930 {
931 struct neo_softc *sc = addr;
932
933 return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if, cp));
934 }
935
936 int
937 neo_query_devinfo(void *addr, mixer_devinfo_t *dip)
938 {
939 struct neo_softc *sc = addr;
940
941 return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip));
942 }
943
944 void *
945 neo_malloc(void *addr, int direction, size_t size, int pool, int flags)
946 {
947 struct neo_softc *sc = addr;
948 void *rv = NULL;
949
950 switch (direction) {
951 case AUMODE_PLAY:
952 if (sc->pbuf_allocated == 0) {
953 rv = (void *) sc->pbuf_vaddr;
954 sc->pbuf_allocated = 1;
955 }
956 break;
957
958 case AUMODE_RECORD:
959 if (sc->rbuf_allocated == 0) {
960 rv = (void *) sc->rbuf_vaddr;
961 sc->rbuf_allocated = 1;
962 }
963 break;
964 }
965
966 return (rv);
967 }
968
969 void
970 neo_free(void *addr, void *ptr, int pool)
971 {
972 struct neo_softc *sc = addr;
973 vaddr_t v = (vaddr_t) ptr;
974
975 if (v == sc->pbuf_vaddr)
976 sc->pbuf_allocated = 0;
977 else if (v == sc->rbuf_vaddr)
978 sc->rbuf_allocated = 0;
979 else
980 printf("neo_free: bad address %p\n", ptr);
981 }
982
983 size_t
984 neo_round_buffersize(void *addr, int direction, size_t size)
985 {
986
987 return (NM_BUFFSIZE);
988 }
989
990
991 int
992 neo_get_props(void *addr)
993 {
994
995 return (AUDIO_PROP_INDEPENDENT |
996 AUDIO_PROP_FULLDUPLEX);
997 }
998