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