xref: /openbsd-src/sys/dev/pci/neo.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*      $OpenBSD: neo.c,v 1.7 2001/06/18 19:27:18 deraadt 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, 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  */
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 out two ring buffers out of its
65  * memory. However 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  * mgiht 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 secodn 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 order 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  * of glitches due to drivers that spend to 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 detect 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 
160 /* -------------------------------------------------------------------- */
161 
162 /*
163  * prototypes
164  */
165 
166 static int 	 nm_waitcd(struct neo_softc *sc);
167 static int 	 nm_loadcoeff(struct neo_softc *sc, int dir, int num);
168 static int       nm_init(struct neo_softc *);
169 
170 int    nmchan_getptr(struct neo_softc *, int);
171 /* talk to the card */
172 static u_int32_t nm_rd(struct neo_softc *, int, int);
173 static void 	 nm_wr(struct neo_softc *, int, u_int32_t, int);
174 static u_int32_t nm_rdbuf(struct neo_softc *, int, int);
175 static void 	 nm_wrbuf(struct neo_softc *, int, u_int32_t, int);
176 
177 int	neo_match __P((struct device *, void *, void *));
178 void	neo_attach __P((struct device *, struct device *, void *));
179 int	neo_intr __P((void *));
180 
181 int	neo_open __P((void *, int));
182 void	neo_close __P((void *));
183 int	neo_query_encoding __P((void *, struct audio_encoding *));
184 int	neo_set_params __P((void *, int, int, struct audio_params *, struct audio_params *));
185 int	neo_round_blocksize __P((void *, int));
186 int	neo_trigger_output __P((void *, void *, void *, int, void (*)(void *),
187 	    void *, struct audio_params *));
188 int	neo_trigger_input __P((void *, void *, void *, int, void (*)(void *),
189 	    void *, struct audio_params *));
190 int	neo_halt_output __P((void *));
191 int	neo_halt_input __P((void *));
192 int	neo_getdev __P((void *, struct audio_device *));
193 int	neo_mixer_set_port __P((void *, mixer_ctrl_t *));
194 int	neo_mixer_get_port __P((void *, mixer_ctrl_t *));
195 int     neo_attach_codec __P((void *sc, struct ac97_codec_if *));
196 int	neo_read_codec __P((void *sc, u_int8_t a, u_int16_t *d));
197 int	neo_write_codec __P((void *sc, u_int8_t a, u_int16_t d));
198 void    neo_reset_codec __P((void *sc));
199 enum ac97_host_flags neo_flags_codec __P((void *sc));
200 int	neo_query_devinfo __P((void *, mixer_devinfo_t *));
201 void   *neo_malloc __P((void *, int, size_t, int, int));
202 void	neo_free __P((void *, void *, int));
203 size_t	neo_round_buffersize __P((void *, int, size_t));
204 int	neo_get_props __P((void *));
205 void	neo_set_mixer __P((struct neo_softc *sc, int a, int d));
206 
207 
208 
209 struct  cfdriver neo_cd = {
210 	NULL, "neo", DV_DULL
211 };
212 
213 
214 struct cfattach neo_ca = {
215 	sizeof(struct neo_softc), neo_match, neo_attach
216 };
217 
218 
219 struct audio_device neo_device = {
220 	"NeoMagic 256",
221 	"",
222 	"neo"
223 };
224 
225 #if 0
226 static u_int32_t badcards[] = {
227 	0x0007103c,
228 	0x008f1028,
229 };
230 #endif
231 
232 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t))
233 
234 /* The actual rates supported by the card. */
235 static int samplerates[9] = {
236 	8000,
237 	11025,
238 	16000,
239 	22050,
240 	24000,
241 	32000,
242 	44100,
243 	48000,
244 	99999999
245 };
246 
247 /* -------------------------------------------------------------------- */
248 
249 struct audio_hw_if neo_hw_if = {
250 	neo_open,
251 	neo_close,
252 	NULL,
253 	neo_query_encoding,
254 	neo_set_params,
255 #if 1
256 	neo_round_blocksize,
257 #else
258 	NULL,
259 #endif
260 	NULL,
261 	NULL,
262 	NULL,
263 	NULL,
264 	NULL,
265 	neo_halt_output,
266 	neo_halt_input,
267 	NULL,
268 	neo_getdev,
269 	NULL,
270 	neo_mixer_set_port,
271 	neo_mixer_get_port,
272 	neo_query_devinfo,
273 	NULL, /* neo_malloc_old, */
274 	neo_free,
275 	NULL, /* neo_round_buffersize_old, */
276 	0, /* neo_mappage, */
277 	neo_get_props,
278 	neo_trigger_output,
279 	neo_trigger_input,
280 	neo_malloc,
281 	neo_round_buffersize,
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 
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 	addr = (dir == AUMODE_PLAY)? 0x01c : 0x21c;
398 	if (dir == AUMODE_RECORD)
399 		num += 8;
400 	sz = coefficientSizes[num];
401 	ofs = 0;
402 	while (num-- > 0)
403 		ofs+= coefficientSizes[num];
404 	for (i = 0; i < sz; i++)
405 		nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1);
406 	nm_wr(sc, addr, sc->cbuf, 4);
407 	if (dir == AUMODE_PLAY)
408 		sz--;
409 	nm_wr(sc, addr + 4, sc->cbuf + sz, 4);
410 	return 0;
411 }
412 
413 int
414 nmchan_getptr(sc, mode)
415         struct neo_softc *sc;
416 	int mode;
417 {
418 	if (mode == AUMODE_PLAY)
419 		return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf;
420 	else
421 		return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf;
422 }
423 
424 
425 /* The interrupt handler */
426 int
427 neo_intr(void *p)
428 {
429 	struct neo_softc *sc = (struct neo_softc *)p;
430 	int status, x, active;
431 	int rv = 0;
432 
433 	active = (sc->pintr || sc->rintr);
434 	status = nm_rd(sc, NM_INT_REG, sc->irsz);
435 
436 	if (status & sc->playint) {
437 		status &= ~sc->playint;
438 
439 		sc->pwmark += sc->pblksize;
440 		sc->pwmark %= sc->pbufsize;
441 
442 		nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
443 
444 		nm_ackint(sc, sc->playint);
445 
446 		if (sc->pintr)
447 			(*sc->pintr)(sc->parg);
448 
449 		rv = 1;
450 	}
451 	if (status & sc->recint) {
452 		status &= ~sc->recint;
453 
454 		sc->rwmark += sc->rblksize;
455 		sc->rwmark %= sc->rbufsize;
456 
457 		nm_ackint(sc, sc->recint);
458 		if (sc->rintr)
459 			(*sc->rintr)(sc->rarg);
460 
461 		rv = 1;
462 	}
463 	if (status & sc->misc1int) {
464 		status &= ~sc->misc1int;
465 		nm_ackint(sc, sc->misc1int);
466 		x = nm_rd(sc, 0x400, 1);
467 		nm_wr(sc, 0x400, x | 2, 1);
468 		printf("%s: misc int 1\n", sc->dev.dv_xname);
469 		rv = 1;
470 	}
471 	if (status & sc->misc2int) {
472 		status &= ~sc->misc2int;
473 		nm_ackint(sc, sc->misc2int);
474 		x = nm_rd(sc, 0x400, 1);
475 		nm_wr(sc, 0x400, x & ~2, 1);
476 		printf("%s: misc int 2\n", sc->dev.dv_xname);
477 		rv = 1;
478 	}
479 	if (status) {
480 		status &= ~sc->misc2int;
481 		nm_ackint(sc, sc->misc2int);
482 		printf("%s: unknown int\n", sc->dev.dv_xname);
483 		rv = 1;
484 	}
485 
486 	return (rv);
487 }
488 
489 /* -------------------------------------------------------------------- */
490 
491 /*
492  * Probe and attach the card
493  */
494 
495 static int
496 nm_init(struct neo_softc *sc)
497 {
498 	u_int32_t ofs, i;
499 
500 	if (sc->type == NM256AV_PCI_ID) {
501 		sc->ac97_base = NM_MIXER_OFFSET;
502 		sc->ac97_status = NM_MIXER_STATUS_OFFSET;
503 		sc->ac97_busy = NM_MIXER_READY_MASK;
504 
505 		sc->buftop = 2560 * 1024;
506 
507 		sc->irsz = 2;
508 		sc->playint = NM_PLAYBACK_INT;
509 		sc->recint = NM_RECORD_INT;
510 		sc->misc1int = NM_MISC_INT_1;
511 		sc->misc2int = NM_MISC_INT_2;
512 	} else if (sc->type == NM256ZX_PCI_ID) {
513 		sc->ac97_base = NM_MIXER_OFFSET;
514 		sc->ac97_status = NM2_MIXER_STATUS_OFFSET;
515 		sc->ac97_busy = NM2_MIXER_READY_MASK;
516 
517 		sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024;
518 
519 		sc->irsz = 4;
520 		sc->playint = NM2_PLAYBACK_INT;
521 		sc->recint = NM2_RECORD_INT;
522 		sc->misc1int = NM2_MISC_INT_1;
523 		sc->misc2int = NM2_MISC_INT_2;
524 	} else return -1;
525 	sc->badintr = 0;
526 	ofs = sc->buftop - 0x0400;
527 	sc->buftop -= 0x1400;
528 
529  	if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) {
530 		i = nm_rdbuf(sc, ofs + 4, 4);
531 		if (i != 0 && i != 0xffffffff)
532 			sc->buftop = i;
533 	}
534 
535 	sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT;
536 	sc->rbuf = sc->cbuf - NM_BUFFSIZE;
537 	sc->pbuf = sc->rbuf - NM_BUFFSIZE;
538 	sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4);
539 
540 	nm_wr(sc, 0, 0x11, 1);
541 	nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
542 	nm_wr(sc, 0x214, 0, 2);
543 
544 	return 0;
545 }
546 
547 
548 void
549 neo_attach(parent, self, aux)
550 	struct device *parent;
551 	struct device *self;
552 	void *aux;
553 {
554 	struct neo_softc *sc = (struct neo_softc *)self;
555 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
556 	pci_chipset_tag_t pc = pa->pa_pc;
557 	char const *intrstr;
558 	pci_intr_handle_t ih;
559 	pcireg_t csr;
560 	int error;
561 
562 	sc->type = pa->pa_id;
563 
564 	/* Map I/O register */
565 	if (pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_MEM, 0,
566 			   &sc->bufiot, &sc->bufioh, NULL, NULL, 0)) {
567 		printf("\n%s: can't map i/o space\n", sc->dev.dv_xname);
568 		return;
569 	}
570 
571 
572 	if (pci_mapreg_map(pa, PCI_MAPS + 4, PCI_MAPREG_TYPE_MEM, 0,
573 			   &sc->regiot, &sc->regioh, NULL, NULL, 0)) {
574 		printf("\n%s: can't map i/o space\n", sc->dev.dv_xname);
575 		return;
576 	}
577 
578 	/* Map and establish the interrupt. */
579 	if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
580 			 pa->pa_intrline, &ih)) {
581 		printf("\n%s: couldn't map interrupt\n", sc->dev.dv_xname);
582 		return;
583 	}
584 	intrstr = pci_intr_string(pc, ih);
585 	sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc,
586 				       sc->dev.dv_xname);
587 
588 	if (sc->ih == NULL) {
589 		printf("\n%s: couldn't establish interrupt",
590 		       sc->dev.dv_xname);
591 		if (intrstr != NULL)
592 			printf(" at %s", intrstr);
593 		printf("\n");
594 		return;
595 	}
596 	printf(": %s\n", intrstr);
597 
598 	if ((error = nm_init(sc)) != 0)
599 		return;
600 
601 	/* Enable the device. */
602 	csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
603 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
604 		       csr | PCI_COMMAND_MASTER_ENABLE);
605 
606 	sc->host_if.arg = sc;
607 
608 	sc->host_if.attach = neo_attach_codec;
609 	sc->host_if.read   = neo_read_codec;
610 	sc->host_if.write  = neo_write_codec;
611 	sc->host_if.reset  = neo_reset_codec;
612 	sc->host_if.flags  = neo_flags_codec;
613 
614 	if ((error = ac97_attach(&sc->host_if)) != 0)
615 		return;
616 
617 	audio_attach_mi(&neo_hw_if, sc, &sc->dev);
618 
619 	return;
620 }
621 
622 int
623 neo_match(parent, match, aux)
624 	struct device *parent;
625 	void *match;
626 	void *aux;
627 {
628 	struct pci_attach_args *pa = (struct pci_attach_args *) aux;
629 #if 0
630 	u_int32_t subdev, badcard;
631 #endif
632 
633 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC)
634 		return (0);
635 
636 #if 0
637 	subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
638 #endif
639 	switch (PCI_PRODUCT(pa->pa_id)) {
640 	case PCI_PRODUCT_NEOMAGIC_NM256AV:
641 #if 0
642 		i = 0;
643 		while ((i < NUM_BADCARDS) && (badcards[i] != subdev))
644 			i++;
645 		if (i == NUM_BADCARDS)
646 			s = "NeoMagic 256AV";
647 		DEB(else)
648 			DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n"));
649 		return (1);
650 #endif
651 	case PCI_PRODUCT_NEOMAGIC_NM256ZX:
652 		return (1);
653 	}
654 
655 	return (0);
656 }
657 
658 int
659 neo_read_codec(sc_, a, d)
660         void *sc_;
661 	u_int8_t a;
662 	u_int16_t *d;
663 {
664 	struct neo_softc *sc = sc_;
665 
666 	if (!nm_waitcd(sc)) {
667 		*d = nm_rd(sc, sc->ac97_base + a, 2);
668 		DELAY(1000);
669 		return 0;
670 	}
671 
672 	return (ENXIO);
673 }
674 
675 
676 int
677 neo_write_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 	int cnt = 3;
684 
685 	if (!nm_waitcd(sc)) {
686 		while (cnt-- > 0) {
687 			nm_wr(sc, sc->ac97_base + a, d, 2);
688 			if (!nm_waitcd(sc)) {
689 				DELAY(1000);
690 				return (0);
691 			}
692 		}
693 	}
694 
695         return (ENXIO);
696 }
697 
698 
699 int
700 neo_attach_codec(sc_, codec_if)
701 	void *sc_;
702 	struct ac97_codec_if  *codec_if;
703 {
704 	struct neo_softc *sc = sc_;
705 
706 	sc->codec_if = codec_if;
707 	return (0);
708 }
709 
710 void
711 neo_reset_codec(sc)
712 	void *sc;
713 {
714 	nm_wr(sc, 0x6c0, 0x01, 1);
715 	nm_wr(sc, 0x6cc, 0x87, 1);
716 	nm_wr(sc, 0x6cc, 0x80, 1);
717 	nm_wr(sc, 0x6cc, 0x00, 1);
718 
719 	return;
720 }
721 
722 
723 enum ac97_host_flags
724 neo_flags_codec(sc)
725 	void *sc;
726 {
727 	return (AC97_HOST_DONT_READANY);
728 }
729 
730 int
731 neo_open(addr, flags)
732 	void *addr;
733 	int flags;
734 {
735 	return (0);
736 }
737 
738 /*
739  * Close function is called at splaudio().
740  */
741 void
742 neo_close(addr)
743 	void *addr;
744 {
745 	struct neo_softc *sc = addr;
746 
747 	neo_halt_output(sc);
748 	neo_halt_input(sc);
749 
750 	sc->pintr = 0;
751 	sc->rintr = 0;
752 }
753 
754 int
755 neo_query_encoding(addr, fp)
756 	void *addr;
757 	struct audio_encoding *fp;
758 {
759 	switch (fp->index) {
760 	case 0:
761 		strcpy(fp->name, AudioEulinear);
762 		fp->encoding = AUDIO_ENCODING_ULINEAR;
763 		fp->precision = 8;
764 		fp->flags = 0;
765 		return (0);
766 	case 1:
767 		strcpy(fp->name, AudioEmulaw);
768 		fp->encoding = AUDIO_ENCODING_ULAW;
769 		fp->precision = 8;
770 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
771 		return (0);
772 	case 2:
773 		strcpy(fp->name, AudioEalaw);
774 		fp->encoding = AUDIO_ENCODING_ALAW;
775 		fp->precision = 8;
776 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
777 		return (0);
778 	case 3:
779 		strcpy(fp->name, AudioEslinear);
780 		fp->encoding = AUDIO_ENCODING_SLINEAR;
781 		fp->precision = 8;
782 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
783 		return (0);
784 	case 4:
785 		strcpy(fp->name, AudioEslinear_le);
786 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
787 		fp->precision = 16;
788 		fp->flags = 0;
789 		return (0);
790 	case 5:
791 		strcpy(fp->name, AudioEulinear_le);
792 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
793 		fp->precision = 16;
794 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
795 		return (0);
796 	case 6:
797 		strcpy(fp->name, AudioEslinear_be);
798 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
799 		fp->precision = 16;
800 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
801 		return (0);
802 	case 7:
803 		strcpy(fp->name, AudioEulinear_be);
804 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
805 		fp->precision = 16;
806 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
807 		return (0);
808 	default:
809 		return (EINVAL);
810 	}
811 }
812 
813 /* Todo: don't commit settings to card until we've verified all parameters */
814 int
815 neo_set_params(addr, setmode, usemode, play, rec)
816 	void *addr;
817 	int setmode, usemode;
818 	struct audio_params *play, *rec;
819 {
820 	struct neo_softc *sc = addr;
821 	u_int32_t base;
822 	u_int8_t x;
823 	int mode;
824 	struct audio_params *p;
825 
826 	for (mode = AUMODE_RECORD; mode != -1;
827 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
828 		if ((setmode & mode) == 0)
829 			continue;
830 
831 		p = mode == AUMODE_PLAY ? play : rec;
832 
833 		if (p == NULL) continue;
834 
835 		for (x = 0; x < 8; x++)
836 			if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2)
837 				break;
838 
839 		if (x == 8) return (EINVAL);
840 
841 		p->sample_rate = samplerates[x];
842 		nm_loadcoeff(sc, mode, x);
843 
844 		x <<= 4;
845 		x &= NM_RATE_MASK;
846 		if (p->precision == 16) x |= NM_RATE_BITS_16;
847 		if (p->channels == 2) x |= NM_RATE_STEREO;
848 
849 		base = (mode == AUMODE_PLAY)?
850 		    NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET;
851 		nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1);
852 
853 		p->factor = 1;
854 		p->sw_code = 0;
855 		switch (p->encoding) {
856 		case AUDIO_ENCODING_SLINEAR_BE:
857 			if (p->precision == 16)
858 				p->sw_code = swap_bytes;
859 			else
860 				p->sw_code = change_sign8;
861 			break;
862 		case AUDIO_ENCODING_SLINEAR_LE:
863 			if (p->precision != 16)
864 				p->sw_code = change_sign8;
865 			break;
866 		case AUDIO_ENCODING_ULINEAR_BE:
867 			if (p->precision == 16) {
868 				if (mode == AUMODE_PLAY)
869 					p->sw_code = swap_bytes_change_sign16;
870 				else
871 					p->sw_code = change_sign16_swap_bytes;
872 			}
873 			break;
874 		case AUDIO_ENCODING_ULINEAR_LE:
875 			if (p->precision == 16)
876 				p->sw_code = change_sign16;
877 			break;
878 		case AUDIO_ENCODING_ULAW:
879 			if (mode == AUMODE_PLAY) {
880 				p->factor = 2;
881 				p->sw_code = mulaw_to_slinear16;
882 			} else
883 				p->sw_code = ulinear8_to_mulaw;
884 			break;
885 		case AUDIO_ENCODING_ALAW:
886 			if (mode == AUMODE_PLAY) {
887 				p->factor = 2;
888 				p->sw_code = alaw_to_slinear16;
889 			} else
890 				p->sw_code = ulinear8_to_alaw;
891 			break;
892 		default:
893 			return (EINVAL);
894 		}
895 	}
896 
897 
898 	return (0);
899 }
900 
901 int
902 neo_round_blocksize(addr, blk)
903 	void *addr;
904 	int blk;
905 {
906 	return (NM_BUFFSIZE / 2);
907 }
908 
909 int
910 neo_trigger_output(addr, start, end, blksize, intr, arg, param)
911 	void *addr;
912 	void *start, *end;
913 	int blksize;
914 	void (*intr) __P((void *));
915 	void *arg;
916 	struct audio_params *param;
917 {
918 	struct neo_softc *sc = addr;
919 	int ssz;
920 
921 	sc->pintr = intr;
922 	sc->parg = arg;
923 
924 	ssz = (param->precision * param->factor == 16)? 2 : 1;
925 	if (param->channels == 2)
926 		ssz <<= 1;
927 
928 	sc->pbufsize = ((char*)end - (char *)start);
929 	sc->pblksize = blksize;
930 	sc->pwmark = blksize;
931 
932 	nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4);
933 	nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4);
934 	nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4);
935 	nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
936 	nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
937 	    NM_PLAYBACK_ENABLE_FLAG, 1);
938 	nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2);
939 
940 	return (0);
941 }
942 
943 
944 
945 int
946 neo_trigger_input(addr, start, end, blksize, intr, arg, param)
947 	void *addr;
948 	void *start, *end;
949 	int blksize;
950 	void (*intr) __P((void *));
951 	void *arg;
952 	struct audio_params *param;
953 {
954 	struct neo_softc *sc = addr;
955 	int ssz;
956 
957 	sc->rintr = intr;
958 	sc->rarg = arg;
959 
960 	ssz = (param->precision * param->factor == 16)? 2 : 1;
961 	if (param->channels == 2)
962 		ssz <<= 1;
963 
964 	sc->rbufsize = ((char*)end - (char *)start);
965 	sc->rblksize = blksize;
966 	sc->rwmark = blksize;
967 
968 	nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4);
969 	nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4);
970 	nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4);
971 	nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4);
972 	nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
973 	    NM_RECORD_ENABLE_FLAG, 1);
974 
975 	return (0);
976 }
977 
978 int
979 neo_halt_output(addr)
980 	void *addr;
981 {
982 	struct neo_softc *sc = (struct neo_softc *)addr;
983 
984 	nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1);
985 	nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2);
986 
987 	sc->pintr = 0;
988 
989 	return (0);
990 }
991 
992 int
993 neo_halt_input(addr)
994 	void *addr;
995 {
996 	struct neo_softc *sc = (struct neo_softc *)addr;
997 
998 	nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
999 
1000 	sc->rintr = 0;
1001 
1002 	return (0);
1003 }
1004 
1005 int
1006 neo_getdev(addr, retp)
1007 	void *addr;
1008 	struct audio_device *retp;
1009 {
1010 	*retp = neo_device;
1011 	return (0);
1012 }
1013 
1014 int
1015 neo_mixer_set_port(addr, cp)
1016 	void *addr;
1017 	mixer_ctrl_t *cp;
1018 {
1019 	struct neo_softc *sc = addr;
1020 
1021 	return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if,
1022 						     cp));
1023 }
1024 
1025 int
1026 neo_mixer_get_port(addr, cp)
1027 	void *addr;
1028 	mixer_ctrl_t *cp;
1029 {
1030 	struct neo_softc *sc = addr;
1031 
1032 	return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if,
1033 						     cp));
1034 }
1035 
1036 int
1037 neo_query_devinfo(addr, dip)
1038 	void *addr;
1039 	mixer_devinfo_t *dip;
1040 {
1041 	struct neo_softc *sc = addr;
1042 
1043 	return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip));
1044 }
1045 
1046 void *
1047 neo_malloc(addr, direction, size, pool, flags)
1048 	void *addr;
1049 	int  direction;
1050 	size_t size;
1051 	int pool, flags;
1052 {
1053 	struct neo_softc *sc = addr;
1054 	void *rv = 0;
1055 
1056 	switch (direction) {
1057 	case AUMODE_PLAY:
1058 	  rv = (char *)sc->bufioh + sc->pbuf;
1059 	  break;
1060 	case AUMODE_RECORD:
1061 	  rv = (char *)sc->bufioh + sc->rbuf;
1062 	  break;
1063 	default:
1064 	  break;
1065 	}
1066 
1067 	return (rv);
1068 }
1069 
1070 void
1071 neo_free(addr, ptr, pool)
1072 	void *addr;
1073 	void *ptr;
1074 	int pool;
1075 {
1076 	return;
1077 }
1078 
1079 size_t
1080 neo_round_buffersize(addr, direction, size)
1081 	void *addr;
1082 	int direction;
1083 	size_t size;
1084 {
1085 	return (NM_BUFFSIZE);
1086 }
1087 
1088 
1089 int
1090 neo_get_props(addr)
1091 	void *addr;
1092 {
1093 
1094 	return (AUDIO_PROP_INDEPENDENT |
1095                 AUDIO_PROP_FULLDUPLEX);
1096 }
1097