xref: /openbsd/sys/dev/pci/cs4281.c (revision 097a140d)
1 /*	$OpenBSD: cs4281.c,v 1.38 2021/03/05 12:40:13 jsg Exp $ */
2 /*	$Tera: cs4281.c,v 1.18 2000/12/27 14:24:45 tacha Exp $	*/
3 
4 /*
5  * Copyright (c) 2000 Tatoku Ogaito.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Tatoku Ogaito
18  *	for the NetBSD Project.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Cirrus Logic CS4281 driver.
36  * Data sheets can be found
37  * http://www.cirrus.com/pubs/4281.pdf?DocumentID=30
38  * ftp://ftp.alsa-project.org/pub/manuals/cirrus/cs4281tm.pdf
39  *
40  * TODO:
41  *   1: midi and FM support
42  */
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/fcntl.h>
49 #include <sys/device.h>
50 
51 #include <dev/pci/pcidevs.h>
52 #include <dev/pci/pcivar.h>
53 #include <dev/pci/cs4281reg.h>
54 
55 #include <sys/audioio.h>
56 #include <dev/audio_if.h>
57 #include <dev/midi_if.h>
58 
59 #include <dev/ic/ac97.h>
60 
61 #include <machine/bus.h>
62 
63 #define CSCC_PCI_BA0 0x10
64 #define CSCC_PCI_BA1 0x14
65 
66 struct cs4281_dma {
67 	bus_dmamap_t map;
68 	caddr_t addr;		/* real dma buffer */
69 	bus_dma_segment_t segs[1];
70 	int nsegs;
71 	size_t size;
72 	struct cs4281_dma *next;
73 };
74 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
75 #define KERNADDR(p) ((void *)((p)->addr))
76 
77 /*
78  * Software state
79  */
80 struct cs4281_softc {
81 	struct device		sc_dev;
82 
83 	pci_intr_handle_t	*sc_ih;
84 
85         /* I/O (BA0) */
86 	bus_space_tag_t		ba0t;
87 	bus_space_handle_t	ba0h;
88 
89 	/* BA1 */
90 	bus_space_tag_t		ba1t;
91 	bus_space_handle_t	ba1h;
92 
93 	/* DMA */
94 	bus_dma_tag_t		sc_dmatag;
95 	struct cs4281_dma	*sc_dmas;
96 
97         /* playback */
98 	void	(*sc_pintr)(void *);	/* dma completion intr handler */
99 	void	*sc_parg;		/* arg for sc_intr() */
100 	int	(*halt_output)(void *);
101 #ifdef DIAGNOSTIC
102         char	sc_prun;
103 #endif
104 
105 	/* capturing */
106 	void	(*sc_rintr)(void *);	/* dma completion intr handler */
107 	void	*sc_rarg;		/* arg for sc_intr() */
108 	int	sc_rparam;		/* record format */
109 	int	(*halt_input)(void *);
110 #ifdef DIAGNOSTIC
111         char	sc_rrun;
112 #endif
113 
114 #if NMIDI > 0
115         void	(*sc_iintr)(void *, int);	/* midi input ready handler */
116         void	(*sc_ointr)(void *);		/* midi output ready handler */
117         void	*sc_arg;
118 #endif
119 
120 	/* AC97 CODEC */
121 	struct ac97_codec_if *codec_if;
122 	struct ac97_host_if host_if;
123 
124         /* Power Management */
125 	u_int16_t ac97_reg[CS4281_SAVE_REG_MAX + 1];   /* Save ac97 registers */
126 };
127 
128 #define BA0READ4(sc, r) bus_space_read_4((sc)->ba0t, (sc)->ba0h, (r))
129 #define BA0WRITE4(sc, r, x) bus_space_write_4((sc)->ba0t, (sc)->ba0h, (r), (x))
130 
131 #if defined(ENABLE_SECONDARY_CODEC)
132 #define MAX_CHANNELS  (4)
133 #define MAX_FIFO_SIZE 32 /* 128/4 channels */
134 #else
135 #define MAX_CHANNELS  (2)
136 #define MAX_FIFO_SIZE 64 /* 128/2 channels */
137 #endif
138 
139 /*
140  * Hardware imposes the buffer size to be twice the block size, this
141  * is OK, except that round_blocksize() is the only mean to expose
142  * this hardware constraint but it doesn't know the buffer size.
143  *
144  * So we've no other choice than hardcoding a buffer size
145  */
146 #define DMA_SIZE	(1024 * 4 * 2)
147 #define DMA_ALIGN	0x10
148 
149 int cs4281_match(struct device *, void *, void *);
150 void cs4281_attach(struct device *, struct device *, void *);
151 int cs4281_activate(struct device *, int);
152 int cs4281_intr(void *);
153 int cs4281_set_params(void *, int, int, struct audio_params *,
154 				     struct audio_params *);
155 int cs4281_halt_output(void *);
156 int cs4281_halt_input(void *);
157 int cs4281_trigger_output(void *, void *, void *, int, void (*)(void *),
158 			  void *, struct audio_params *);
159 int cs4281_trigger_input(void *, void *, void *, int, void (*)(void *),
160 			 void *, struct audio_params *);
161 u_int8_t cs4281_sr2regval(int);
162 void cs4281_set_dac_rate(struct cs4281_softc *, int);
163 void cs4281_set_adc_rate(struct cs4281_softc *, int);
164 int cs4281_init(struct cs4281_softc *);
165 
166 int cs4281_open(void *, int);
167 void cs4281_close(void *);
168 int cs4281_round_blocksize(void *, int);
169 int cs4281_get_props(void *);
170 int cs4281_attach_codec(void *, struct ac97_codec_if *);
171 int cs4281_read_codec(void *, u_int8_t , u_int16_t *);
172 int cs4281_write_codec(void *, u_int8_t, u_int16_t);
173 void cs4281_reset_codec(void *);
174 
175 int cs4281_mixer_set_port(void *, mixer_ctrl_t *);
176 int cs4281_mixer_get_port(void *, mixer_ctrl_t *);
177 int cs4281_query_devinfo(void *, mixer_devinfo_t *);
178 void *cs4281_malloc(void *, int, size_t, int, int);
179 size_t cs4281_round_buffersize(void *, int, size_t);
180 void cs4281_free(void *, void *, int);
181 
182 int cs4281_allocmem(struct cs4281_softc *, size_t, int, int,
183 				     struct cs4281_dma *);
184 int cs4281_src_wait(struct cs4281_softc *);
185 
186 #if defined(CS4281_DEBUG)
187 #undef DPRINTF
188 #undef DPRINTFN
189 #define DPRINTF(x)	    if (cs4281_debug) printf x
190 #define DPRINTFN(n,x)	    if (cs4281_debug>(n)) printf x
191 int cs4281_debug = 5;
192 #else
193 #define DPRINTF(x)
194 #define DPRINTFN(n,x)
195 #endif
196 
197 struct audio_hw_if cs4281_hw_if = {
198 	cs4281_open,
199 	cs4281_close,
200 	cs4281_set_params,
201 	cs4281_round_blocksize,
202 	NULL,
203 	NULL,
204 	NULL,
205 	NULL,
206 	NULL,
207 	cs4281_halt_output,
208 	cs4281_halt_input,
209 	NULL,
210 	NULL,
211 	cs4281_mixer_set_port,
212 	cs4281_mixer_get_port,
213 	cs4281_query_devinfo,
214 	cs4281_malloc,
215 	cs4281_free,
216 	cs4281_round_buffersize,
217 	cs4281_get_props,
218 	cs4281_trigger_output,
219 	cs4281_trigger_input
220 };
221 
222 #if NMIDI > 0
223 /* Midi Interface */
224 void cs4281_midi_close(void *);
225 void cs4281_midi_getinfo(void *, struct midi_info *);
226 int cs4281_midi_open(void *, int, void (*)(void *, int),
227 		     void (*)(void *), void *);
228 int cs4281_midi_output(void *, int);
229 
230 struct midi_hw_if cs4281_midi_hw_if = {
231 	cs4281_midi_open,
232 	cs4281_midi_close,
233 	cs4281_midi_output,
234 	cs4281_midi_getinfo,
235 	0,
236 };
237 #endif
238 
239 struct cfattach clct_ca = {
240 	sizeof(struct cs4281_softc), cs4281_match, cs4281_attach, NULL,
241 	cs4281_activate
242 };
243 
244 struct cfdriver clct_cd = {
245 	NULL, "clct", DV_DULL
246 };
247 
248 int
249 cs4281_match(struct device *parent, void *match, void *aux)
250 {
251 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
252 
253 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CIRRUS ||
254 	    PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_CIRRUS_CS4281)
255 		return (0);
256 
257 	return (1);
258 }
259 
260 void
261 cs4281_attach(struct device *parent, struct device *self, void *aux)
262 {
263 	struct cs4281_softc *sc = (struct cs4281_softc *)self;
264 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
265 	pci_chipset_tag_t pc = pa->pa_pc;
266 	char const *intrstr;
267 	pci_intr_handle_t ih;
268 
269 	/* Map I/O register */
270 	if (pci_mapreg_map(pa, CSCC_PCI_BA0,
271 	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ba0t,
272 	    &sc->ba0h, NULL, NULL, 0)) {
273 		printf("%s: can't map BA0 space\n", sc->sc_dev.dv_xname);
274 		return;
275 	}
276 	if (pci_mapreg_map(pa, CSCC_PCI_BA1,
277 	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ba1t,
278 	    &sc->ba1h, NULL, NULL, 0)) {
279 		printf("%s: can't map BA1 space\n", sc->sc_dev.dv_xname);
280 		return;
281 	}
282 
283 	sc->sc_dmatag = pa->pa_dmat;
284 
285 	/*
286 	 * Set Power State D0.
287 	 * Without doing this, 0xffffffff is read from all registers after
288 	 * using Windows and rebooting into OpenBSD.
289 	 * On my IBM ThinkPad X20, it is set to D3 after using Windows2000.
290 	 */
291 	pci_set_powerstate(pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
292 
293 	/* Map and establish the interrupt. */
294 	if (pci_intr_map(pa, &ih)) {
295 		printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
296 		return;
297 	}
298 	intrstr = pci_intr_string(pc, ih);
299 
300 	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO | IPL_MPSAFE,
301 	    cs4281_intr, sc, sc->sc_dev.dv_xname);
302 	if (sc->sc_ih == NULL) {
303 		printf("%s: couldn't establish interrupt",sc->sc_dev.dv_xname);
304 		if (intrstr != NULL)
305 			printf(" at %s", intrstr);
306 		printf("\n");
307 		return;
308 	}
309 	printf(": %s\n", intrstr);
310 
311 	/*
312 	 * Sound System start-up
313 	 */
314 	if (cs4281_init(sc) != 0)
315 		return;
316 
317 	sc->halt_input  = cs4281_halt_input;
318 	sc->halt_output = cs4281_halt_output;
319 
320 	/* AC 97 attachment */
321 	sc->host_if.arg = sc;
322 	sc->host_if.attach = cs4281_attach_codec;
323 	sc->host_if.read   = cs4281_read_codec;
324 	sc->host_if.write  = cs4281_write_codec;
325 	sc->host_if.reset  = cs4281_reset_codec;
326 	if (ac97_attach(&sc->host_if) != 0) {
327 		printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname);
328 		return;
329 	}
330 	audio_attach_mi(&cs4281_hw_if, sc, &sc->sc_dev);
331 
332 #if NMIDI > 0
333 	midi_attach_mi(&cs4281_midi_hw_if, sc, &sc->sc_dev);
334 #endif
335 }
336 
337 int
338 cs4281_intr(void *p)
339 {
340 	struct cs4281_softc *sc = p;
341 	u_int32_t intr, val;
342 
343 	mtx_enter(&audio_lock);
344 	intr = BA0READ4(sc, CS4281_HISR);
345 	if (!(intr & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {
346 		BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
347 		mtx_leave(&audio_lock);
348 		return (-1);
349 	}
350 	DPRINTF(("cs4281_intr:"));
351 
352 	if (intr & HISR_DMA0)
353 		val = BA0READ4(sc, CS4281_HDSR0); /* clear intr condition */
354 	if (intr & HISR_DMA1)
355 		val = BA0READ4(sc, CS4281_HDSR1); /* clear intr condition */
356 	BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
357 
358 	/* Playback Interrupt */
359 	if (intr & HISR_DMA0) {
360 		DPRINTF((" PB DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA0),
361 			 (int)BA0READ4(sc, CS4281_DCC0)));
362 		if (sc->sc_pintr) {
363 			sc->sc_pintr(sc->sc_parg);
364 		} else {
365 #ifdef DIAGNOSTIC
366 			printf("%s: unexpected play intr\n",
367 			    sc->sc_dev.dv_xname);
368 #endif
369 		}
370 	}
371 	if (intr & HISR_DMA1) {
372 		val = BA0READ4(sc, CS4281_HDSR1);
373 		/* copy from dma */
374 		DPRINTF((" CP DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA1),
375 			 (int)BA0READ4(sc, CS4281_DCC1)));
376 		if (sc->sc_rintr) {
377 			sc->sc_rintr(sc->sc_rarg);
378 		} else {
379 #ifdef DIAGNOSTIC
380 			printf("%s: unexpected record intr\n",
381 			    sc->sc_dev.dv_xname);
382 #endif
383 		}
384 	}
385 	DPRINTF(("\n"));
386 	mtx_leave(&audio_lock);
387 	return (1);
388 }
389 
390 int
391 cs4281_set_params(void *addr, int setmode, int usemode,
392     struct audio_params *play, struct audio_params *rec)
393 {
394 	struct cs4281_softc *sc = addr;
395 	struct audio_params *p;
396 	int mode;
397 
398 	for (mode = AUMODE_RECORD; mode != -1;
399 	    mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
400 		if ((setmode & mode) == 0)
401 			continue;
402 
403 		p = mode == AUMODE_PLAY ? play : rec;
404 
405 		if (p == play) {
406 			DPRINTFN(5,("play: samp=%ld precision=%d channels=%d\n",
407 				p->sample_rate, p->precision, p->channels));
408 		} else {
409 			DPRINTFN(5,("rec: samp=%ld precision=%d channels=%d\n",
410 				p->sample_rate, p->precision, p->channels));
411 		}
412 		if (p->sample_rate < 6023)
413 			p->sample_rate = 6023;
414 		if (p->sample_rate > 48000)
415 			p->sample_rate = 48000;
416 		if (p->precision > 16)
417 			p->precision = 16;
418 		if (p->channels > 2)
419 			p->channels = 2;
420 
421 		switch (p->encoding) {
422 		case AUDIO_ENCODING_SLINEAR_BE:
423 			break;
424 		case AUDIO_ENCODING_SLINEAR_LE:
425 			break;
426 		case AUDIO_ENCODING_ULINEAR_BE:
427 			break;
428 		case AUDIO_ENCODING_ULINEAR_LE:
429 			break;
430 		default:
431 			return (EINVAL);
432 		}
433 		p->bps = AUDIO_BPS(p->precision);
434 		p->msb = 1;
435 	}
436 
437 	/* set sample rate */
438 	cs4281_set_dac_rate(sc, play->sample_rate);
439 	cs4281_set_adc_rate(sc, rec->sample_rate);
440 	return (0);
441 }
442 
443 int
444 cs4281_halt_output(void *addr)
445 {
446 	struct cs4281_softc *sc = addr;
447 
448 	BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
449 #ifdef DIAGNOSTIC
450 	sc->sc_prun = 0;
451 #endif
452 	return (0);
453 }
454 
455 int
456 cs4281_halt_input(void *addr)
457 {
458 	struct cs4281_softc *sc = addr;
459 
460 	BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
461 #ifdef DIAGNOSTIC
462 	sc->sc_rrun = 0;
463 #endif
464 	return (0);
465 }
466 
467 int
468 cs4281_trigger_output(void *addr, void *start, void *end, int blksize,
469     void (*intr)(void *), void *arg, struct audio_params *param)
470 {
471 	struct cs4281_softc *sc = addr;
472 	u_int32_t fmt = 0;
473 	struct cs4281_dma *p;
474 	int dma_count;
475 
476 #ifdef DIAGNOSTIC
477 	if (sc->sc_prun)
478 		printf("cs4281_trigger_output: already running\n");
479 	sc->sc_prun = 1;
480 #endif
481 
482 	if ((char *)end - (char *)start != 2 * blksize) {
483 #ifdef DIAGNOSTIC
484 		printf("%s: play block size must be half the buffer size\n",
485 		    sc->sc_dev.dv_xname);
486 #endif
487 		return EIO;
488 	}
489 
490 	DPRINTF(("cs4281_trigger_output: sc=%p start=%p end=%p "
491 		 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
492 	sc->sc_pintr = intr;
493 	sc->sc_parg  = arg;
494 
495 	/* stop playback DMA */
496 	BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
497 
498 	DPRINTF(("param: precision=%d channels=%d encoding=%d\n",
499 	       param->precision, param->channels,
500 	       param->encoding));
501 	for (p = sc->sc_dmas; p != NULL && KERNADDR(p) != start; p = p->next)
502 		;
503 	if (p == NULL) {
504 		printf("cs4281_trigger_output: bad addr %p\n", start);
505 		mtx_leave(&audio_lock);
506 		return (EINVAL);
507 	}
508 
509 	dma_count = (char *)end - (char *)start;
510 	if (param->precision != 8)
511 		dma_count /= 2;   /* 16 bit */
512 	if (param->channels > 1)
513 		dma_count /= 2;   /* Stereo */
514 
515 	DPRINTF(("cs4281_trigger_output: DMAADDR(p)=0x%x count=%d\n",
516 		 (int)DMAADDR(p), dma_count));
517 	BA0WRITE4(sc, CS4281_DBA0, DMAADDR(p));
518 	BA0WRITE4(sc, CS4281_DBC0, dma_count - 1);
519 
520 	/* set playback format */
521 	fmt = BA0READ4(sc, CS4281_DMR0) & ~DMRn_FMTMSK;
522 	if (param->precision == 8)
523 		fmt |= DMRn_SIZE8;
524 	if (param->channels == 1)
525 		fmt |= DMRn_MONO;
526 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
527 	    param->encoding == AUDIO_ENCODING_SLINEAR_BE)
528 		fmt |= DMRn_BEND;
529 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
530 	    param->encoding == AUDIO_ENCODING_ULINEAR_LE)
531 		fmt |= DMRn_USIGN;
532 	BA0WRITE4(sc, CS4281_DMR0, fmt);
533 
534 	/* set sample rate */
535 	cs4281_set_dac_rate(sc, param->sample_rate);
536 
537 	/* start DMA */
538 	mtx_enter(&audio_lock);
539 	BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) & ~DCRn_MSK);
540 	/* Enable interrupts */
541 	BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
542 
543 	BA0WRITE4(sc, CS4281_PPRVC, 7);
544 	BA0WRITE4(sc, CS4281_PPLVC, 7);
545 
546 	DPRINTF(("HICR =0x%08x(expected 0x00000001)\n", BA0READ4(sc, CS4281_HICR)));
547 	DPRINTF(("HIMR =0x%08x(expected 0x00f0fc3f)\n", BA0READ4(sc, CS4281_HIMR)));
548 	DPRINTF(("DMR0 =0x%08x(expected 0x2???0018)\n", BA0READ4(sc, CS4281_DMR0)));
549 	DPRINTF(("DCR0 =0x%08x(expected 0x00030000)\n", BA0READ4(sc, CS4281_DCR0)));
550 	DPRINTF(("FCR0 =0x%08x(expected 0x81000f00)\n", BA0READ4(sc, CS4281_FCR0)));
551 	DPRINTF(("DACSR=0x%08x(expected 1 for 44kHz 5 for 8kHz)\n",
552 		 BA0READ4(sc, CS4281_DACSR)));
553 	DPRINTF(("SRCSA=0x%08x(expected 0x0b0a0100)\n", BA0READ4(sc, CS4281_SRCSA)));
554 	DPRINTF(("SSPM&SSPM_PSRCEN =0x%08x(expected 0x00000010)\n",
555 		 BA0READ4(sc, CS4281_SSPM) & SSPM_PSRCEN));
556 	mtx_leave(&audio_lock);
557 	return (0);
558 }
559 
560 int
561 cs4281_trigger_input(void *addr, void *start, void *end, int blksize,
562     void (*intr)(void *), void *arg, struct audio_params *param)
563 {
564 	struct cs4281_softc *sc = addr;
565 	struct cs4281_dma *p;
566 	u_int32_t fmt = 0;
567 	int dma_count;
568 
569 	if ((char *)end - (char *)start != 2 * blksize) {
570 #ifdef DIAGNOSTIC
571 		printf("%s: rec block size must be half the buffer size\n",
572 		    sc->sc_dev.dv_xname);
573 #endif
574 		return EIO;
575 	}
576 
577 #ifdef DIAGNOSTIC
578 	if (sc->sc_rrun)
579 		printf("cs4281_trigger_input: already running\n");
580 	sc->sc_rrun = 1;
581 #endif
582 	DPRINTF(("cs4281_trigger_input: sc=%p start=%p end=%p "
583 	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
584 	sc->sc_rintr = intr;
585 	sc->sc_rarg  = arg;
586 
587 	/* stop recording DMA */
588 	BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
589 
590 	for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next)
591 		;
592 	if (!p) {
593 		printf("cs4281_trigger_input: bad addr %p\n", start);
594 		return (EINVAL);
595 	}
596 
597 	dma_count = (char *)end - (char *)start;
598 	if (param->precision != 8)
599 		dma_count /= 2;
600 	if (param->channels > 1)
601 		dma_count /= 2;
602 
603 	DPRINTF(("cs4281_trigger_input: DMAADDR(p)=0x%x count=%d\n",
604 		 (int)DMAADDR(p), dma_count));
605 	BA0WRITE4(sc, CS4281_DBA1, DMAADDR(p));
606 	BA0WRITE4(sc, CS4281_DBC1, dma_count-1);
607 
608 	/* set recording format */
609 	fmt = BA0READ4(sc, CS4281_DMR1) & ~DMRn_FMTMSK;
610 	if (param->precision == 8)
611 		fmt |= DMRn_SIZE8;
612 	if (param->channels == 1)
613 		fmt |= DMRn_MONO;
614 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
615 	    param->encoding == AUDIO_ENCODING_SLINEAR_BE)
616 		fmt |= DMRn_BEND;
617 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
618 	    param->encoding == AUDIO_ENCODING_ULINEAR_LE)
619 		fmt |= DMRn_USIGN;
620 	BA0WRITE4(sc, CS4281_DMR1, fmt);
621 
622 	/* set sample rate */
623 	cs4281_set_adc_rate(sc, param->sample_rate);
624 
625 	/* Start DMA */
626 	mtx_enter(&audio_lock);
627 	BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) & ~DCRn_MSK);
628 	/* Enable interrupts */
629 	BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
630 
631 	DPRINTF(("HICR=0x%08x\n", BA0READ4(sc, CS4281_HICR)));
632 	DPRINTF(("HIMR=0x%08x\n", BA0READ4(sc, CS4281_HIMR)));
633 	DPRINTF(("DMR1=0x%08x\n", BA0READ4(sc, CS4281_DMR1)));
634 	DPRINTF(("DCR1=0x%08x\n", BA0READ4(sc, CS4281_DCR1)));
635 	mtx_leave(&audio_lock);
636 	return (0);
637 }
638 
639 /* convert sample rate to register value */
640 u_int8_t
641 cs4281_sr2regval(int rate)
642 {
643 	u_int8_t retval;
644 
645 	/* We don't have to change here. but anyway ... */
646 	if (rate > 48000)
647 		rate = 48000;
648 	if (rate < 6023)
649 		rate = 6023;
650 
651 	switch (rate) {
652 	case 8000:
653 		retval = 5;
654 		break;
655 	case 11025:
656 		retval = 4;
657 		break;
658 	case 16000:
659 		retval = 3;
660 		break;
661 	case 22050:
662 		retval = 2;
663 		break;
664 	case 44100:
665 		retval = 1;
666 		break;
667 	case 48000:
668 		retval = 0;
669 		break;
670 	default:
671 		retval = 1536000/rate; /* == 24576000/(rate*16) */
672 	}
673 	return (retval);
674 }
675 
676 void
677 cs4281_set_dac_rate(struct cs4281_softc *sc, int rate)
678 {
679 	BA0WRITE4(sc, CS4281_DACSR, cs4281_sr2regval(rate));
680 }
681 
682 void
683 cs4281_set_adc_rate(struct cs4281_softc *sc, int rate)
684 {
685 	BA0WRITE4(sc, CS4281_ADCSR, cs4281_sr2regval(rate));
686 }
687 
688 int
689 cs4281_init(struct cs4281_softc *sc)
690 {
691 	int n;
692 	u_int16_t data;
693 	u_int32_t dat32;
694 
695 	/* set "Configuration Write Protect" register to
696 	 * 0x4281 to allow to write */
697 	BA0WRITE4(sc, CS4281_CWPR, 0x4281);
698 
699 	/*
700 	 * Unset "Full Power-Down bit of Extended PCI Power Management
701 	 * Control" register to release the reset state.
702 	 */
703 	dat32 = BA0READ4(sc, CS4281_EPPMC);
704 	if (dat32 & EPPMC_FPDN)
705 		BA0WRITE4(sc, CS4281_EPPMC, dat32 & ~EPPMC_FPDN);
706 
707 	/* Start PLL out in known state */
708 	BA0WRITE4(sc, CS4281_CLKCR1, 0);
709 	/* Start serial ports out in known state */
710 	BA0WRITE4(sc, CS4281_SERMC, 0);
711 
712 	/* Reset codec */
713 	BA0WRITE4(sc, CS4281_ACCTL, 0);
714 	delay(50);	/* delay 50us */
715 
716 	BA0WRITE4(sc, CS4281_SPMC, 0);
717 	delay(100);	/* delay 100us */
718 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN);
719 #if defined(ENABLE_SECONDARY_CODEC)
720 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E);
721 	BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID);
722 #endif
723 	delay(50000);   /* XXX: delay 50ms */
724 
725 	/* Turn on Sound System clocks based on ABITCLK */
726 	BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_DLLP);
727 	delay(50000);   /* XXX: delay 50ms */
728 	BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_SWCE | CLKCR1_DLLP);
729 
730 	/* Set enables for sections that are needed in the SSPM registers */
731 	BA0WRITE4(sc, CS4281_SSPM,
732 		  SSPM_MIXEN |		/* Mixer */
733 		  SSPM_CSRCEN |		/* Capture SRC */
734 		  SSPM_PSRCEN |		/* Playback SRC */
735 		  SSPM_JSEN |		/* Joystick */
736 		  SSPM_ACLEN |		/* AC LINK */
737 		  SSPM_FMEN		/* FM */
738 		  );
739 
740 	/* Wait for clock stabilization */
741 	n = 0;
742 	while ((BA0READ4(sc, CS4281_CLKCR1)& (CLKCR1_DLLRDY | CLKCR1_CLKON))
743 	    != (CLKCR1_DLLRDY | CLKCR1_CLKON)) {
744 		delay(100);
745 		if (++n > 1000)
746 			return (-1);
747 	}
748 
749 	/* Enable ASYNC generation */
750 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN);
751 
752 	/* Wait for Codec ready. Linux driver wait 50ms here */
753 	n = 0;
754 	while((BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY) == 0) {
755 		delay(100);
756 		if (++n > 1000)
757 			return (-1);
758 	}
759 
760 #if defined(ENABLE_SECONDARY_CODEC)
761 	/* secondary codec ready*/
762 	n = 0;
763 	while((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) {
764 		delay(100);
765 		if (++n > 1000)
766 			return (-1);
767 	}
768 #endif
769 
770 	/* Set the serial timing configuration */
771 	/* XXX: undocumented but the Linux driver do this */
772 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
773 
774 	/* Wait for Codec ready signal */
775 	n = 0;
776 	do {
777 		delay(1000);
778 		if (++n > 1000) {
779 			printf("%s: Timeout waiting for Codec ready\n",
780 			       sc->sc_dev.dv_xname);
781 			return -1;
782 		}
783 		dat32 = BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY;
784 	} while (dat32 == 0);
785 
786 	/* Enable Valid Frame output on ASDOUT */
787 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN | ACCTL_VFRM);
788 
789 	/* Wait until Codec Calibration is finished. Codec register 26h */
790 	n = 0;
791 	do {
792 		delay(1);
793 		if (++n > 1000) {
794 			printf("%s: Timeout waiting for Codec calibration\n",
795 			       sc->sc_dev.dv_xname);
796 			return -1;
797 		}
798 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
799 	} while ((data & 0x0f) != 0x0f);
800 
801 	/* Set the serial timing configuration again */
802 	/* XXX: undocumented but the Linux driver do this */
803 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
804 
805 	/* Wait until we've sampled input slots 3 & 4 as valid */
806 	n = 0;
807 	do {
808 		delay(1000);
809 		if (++n > 1000) {
810 			printf("%s: Timeout waiting for sampled input slots as valid\n",
811 			       sc->sc_dev.dv_xname);
812 			return -1;
813 		}
814 		dat32 = BA0READ4(sc, CS4281_ACISV) & (ACISV_ISV3 | ACISV_ISV4);
815 	} while (dat32 != (ACISV_ISV3 | ACISV_ISV4));
816 
817 	/* Start digital data transfer of audio data to the codec */
818 	BA0WRITE4(sc, CS4281_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4));
819 
820 	cs4281_write_codec(sc, AC97_REG_HEADPHONE_VOLUME, 0);
821 	cs4281_write_codec(sc, AC97_REG_MASTER_VOLUME, 0);
822 
823 	/* Power on the DAC */
824 	cs4281_read_codec(sc, AC97_REG_POWER, &data);
825 	cs4281_write_codec(sc, AC97_REG_POWER, data &= 0xfdff);
826 
827 	/* Wait until we sample a DAC ready state.
828 	 * Not documented, but Linux driver does.
829 	 */
830 	for (n = 0; n < 32; ++n) {
831 		delay(1000);
832 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
833 		if (data & 0x02)
834 			break;
835 	}
836 
837 	/* Power on the ADC */
838 	cs4281_read_codec(sc, AC97_REG_POWER, &data);
839 	cs4281_write_codec(sc, AC97_REG_POWER, data &= 0xfeff);
840 
841 	/* Wait until we sample ADC ready state.
842 	 * Not documented, but Linux driver does.
843 	 */
844 	for (n = 0; n < 32; ++n) {
845 		delay(1000);
846 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
847 		if (data & 0x01)
848 			break;
849 	}
850 
851 #if 0
852 	/* Initialize SSCR register features */
853 	/* XXX: hardware volume setting */
854 	BA0WRITE4(sc, CS4281_SSCR, ~SSCR_HVC); /* disable HW volume setting */
855 #endif
856 
857 	/* disable Sound Blaster Pro emulation */
858 	/* XXX:
859 	 * Cannot set since the documents does not describe which bit is
860 	 * correspond to SSCR_SB. Since the reset value of SSCR is 0,
861 	 * we can ignore it.*/
862 #if 0
863 	BA0WRITE4(sc, CS4281_SSCR, SSCR_SB);
864 #endif
865 
866 	/* map AC97 PCM playback to DMA Channel 0 */
867 	/* Reset FEN bit to setup first */
868 	BA0WRITE4(sc, CS4281_FCR0, (BA0READ4(sc,CS4281_FCR0) & ~FCRn_FEN));
869 	/*
870 	 *| RS[4:0]/|        |
871 	 *| LS[4:0] |  AC97  | Slot Function
872 	 *|---------+--------+--------------------
873 	 *|     0   |    3   | Left PCM Playback
874 	 *|     1   |    4   | Right PCM Playback
875 	 *|     2   |    5   | Phone Line 1 DAC
876 	 *|     3   |    6   | Center PCM Playback
877 	 *....
878 	 *  quoted from Table 29(p109)
879 	 */
880 	dat32 = 0x01 << 24 |   /* RS[4:0] =  1 see above */
881 		0x00 << 16 |   /* LS[4:0] =  0 see above */
882 		0x0f <<  8 |   /* SZ[6:0] = 15 size of buffer */
883 		0x00 <<  0 ;   /* OF[6:0] =  0 offset */
884 	BA0WRITE4(sc, CS4281_FCR0, dat32);
885 	BA0WRITE4(sc, CS4281_FCR0, dat32 | FCRn_FEN);
886 
887 	/* map AC97 PCM record to DMA Channel 1 */
888 	/* Reset FEN bit to setup first */
889 	BA0WRITE4(sc, CS4281_FCR1, (BA0READ4(sc,CS4281_FCR1) & ~FCRn_FEN));
890 	/*
891 	 *| RS[4:0]/|
892 	 *| LS[4:0] | AC97 | Slot Function
893 	 *|---------+------+-------------------
894 	 *|   10    |   3  | Left PCM Record
895 	 *|   11    |   4  | Right PCM Record
896 	 *|   12    |   5  | Phone Line 1 ADC
897 	 *|   13    |   6  | Mic ADC
898 	 *....
899 	 * quoted from Table 30(p109)
900 	 */
901 	dat32 = 0x0b << 24 |    /* RS[4:0] = 11 See above */
902 		0x0a << 16 |    /* LS[4:0] = 10 See above */
903 		0x0f <<  8 |    /* SZ[6:0] = 15 Size of buffer */
904 		0x10 <<  0 ;    /* OF[6:0] = 16 offset */
905 
906 	/* XXX: I cannot understand why FCRn_PSH is needed here. */
907 	BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_PSH);
908 	BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_FEN);
909 
910 #if 0
911 	/* Disable DMA Channel 2, 3 */
912 	BA0WRITE4(sc, CS4281_FCR2, (BA0READ4(sc,CS4281_FCR2) & ~FCRn_FEN));
913 	BA0WRITE4(sc, CS4281_FCR3, (BA0READ4(sc,CS4281_FCR3) & ~FCRn_FEN));
914 #endif
915 
916 	/* Set the SRC Slot Assignment accordingly */
917 	/*| PLSS[4:0]/
918 	 *| PRSS[4:0] | AC97 | Slot Function
919 	 *|-----------+------+----------------
920 	 *|     0     |  3   | Left PCM Playback
921 	 *|     1     |  4   | Right PCM Playback
922 	 *|     2     |  5   | phone line 1 DAC
923 	 *|     3     |  6   | Center PCM Playback
924 	 *|     4     |  7   | Left Surround PCM Playback
925 	 *|     5     |  8   | Right Surround PCM Playback
926 	 *......
927 	 *
928 	 *| CLSS[4:0]/
929 	 *| CRSS[4:0] | AC97 | Codec |Slot Function
930 	 *|-----------+------+-------+-----------------
931 	 *|    10     |   3  |Primary| Left PCM Record
932 	 *|    11     |   4  |Primary| Right PCM Record
933 	 *|    12     |   5  |Primary| Phone Line 1 ADC
934 	 *|    13     |   6  |Primary| Mic ADC
935 	 *|.....
936 	 *|    20     |   3  |  Sec. | Left PCM Record
937 	 *|    21     |   4  |  Sec. | Right PCM Record
938 	 *|    22     |   5  |  Sec. | Phone Line 1 ADC
939 	 *|    23     |   6  |  Sec. | Mic ADC
940 	 */
941 	dat32 = 0x0b << 24 |   /* CRSS[4:0] Right PCM Record(primary) */
942 		0x0a << 16 |   /* CLSS[4:0] Left  PCM Record(primary) */
943 		0x01 <<  8 |   /* PRSS[4:0] Right PCM Playback */
944 		0x00 <<  0;    /* PLSS[4:0] Left  PCM Playback */
945 	BA0WRITE4(sc, CS4281_SRCSA, dat32);
946 
947 	/* Set interrupt to occurred at Half and Full terminal
948 	 * count interrupt enable for DMA channel 0 and 1.
949 	 * To keep DMA stop, set MSK.
950 	 */
951 	dat32 = DCRn_HTCIE | DCRn_TCIE | DCRn_MSK;
952 	BA0WRITE4(sc, CS4281_DCR0, dat32);
953 	BA0WRITE4(sc, CS4281_DCR1, dat32);
954 
955 	/* Set Auto-Initialize Control enable */
956 	BA0WRITE4(sc, CS4281_DMR0,
957 		  DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);
958 	BA0WRITE4(sc, CS4281_DMR1,
959 		  DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);
960 
961 	/* Clear DMA Mask in HIMR */
962 	dat32 = BA0READ4(sc, CS4281_HIMR) & 0xfffbfcff;
963 	BA0WRITE4(sc, CS4281_HIMR, dat32);
964 	return (0);
965 }
966 
967 int
968 cs4281_activate(struct device *self, int act)
969 {
970 	struct cs4281_softc *sc = (struct cs4281_softc *)self;
971 	int rv = 0;
972 
973 	switch (act) {
974 	case DVACT_SUSPEND:
975 		/* should I powerdown here ? */
976 		cs4281_write_codec(sc, AC97_REG_POWER, CS4281_POWER_DOWN_ALL);
977 		break;
978 	case DVACT_RESUME:
979 		cs4281_init(sc);
980 		ac97_resume(&sc->host_if, sc->codec_if);
981 		rv = config_activate_children(self, act);
982 		break;
983 	default:
984 		rv = config_activate_children(self, act);
985 		break;
986 	}
987 	return (rv);
988 }
989 
990 void
991 cs4281_reset_codec(void *addr)
992 {
993 	struct cs4281_softc *sc;
994 	u_int16_t data;
995 	u_int32_t dat32;
996 	int n;
997 
998 	sc = addr;
999 
1000 	DPRINTFN(3,("cs4281_reset_codec\n"));
1001 
1002 	/* Reset codec */
1003 	BA0WRITE4(sc, CS4281_ACCTL, 0);
1004 	delay(50);    /* delay 50us */
1005 
1006 	BA0WRITE4(sc, CS4281_SPMC, 0);
1007 	delay(100);	/* delay 100us */
1008 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN);
1009 #if defined(ENABLE_SECONDARY_CODEC)
1010 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E);
1011 	BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID);
1012 #endif
1013 	delay(50000);   /* XXX: delay 50ms */
1014 
1015 	/* Enable ASYNC generation */
1016 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN);
1017 
1018 	/* Wait for Codec ready. Linux driver wait 50ms here */
1019 	n = 0;
1020 	while((BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY) == 0) {
1021 		delay(100);
1022 		if (++n > 1000) {
1023 			printf("%s: AC97 codec ready timeout\n",
1024 			    sc->sc_dev.dv_xname);
1025 			return;
1026 		}
1027 	}
1028 #if defined(ENABLE_SECONDARY_CODEC)
1029 	/* secondary codec ready*/
1030 	n = 0;
1031 	while((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) {
1032 		delay(100);
1033 		if (++n > 1000)
1034 			return;
1035 	}
1036 #endif
1037 	/* Set the serial timing configuration */
1038 	/* XXX: undocumented but the Linux driver do this */
1039 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
1040 
1041 	/* Wait for Codec ready signal */
1042 	n = 0;
1043 	do {
1044 		delay(1000);
1045 		if (++n > 1000) {
1046 			printf("%s: Timeout waiting for Codec ready\n",
1047 			       sc->sc_dev.dv_xname);
1048 			return;
1049 		}
1050 		dat32 = BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY;
1051 	} while (dat32 == 0);
1052 
1053 	/* Enable Valid Frame output on ASDOUT */
1054 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN | ACCTL_VFRM);
1055 
1056 	/* Wait until Codec Calibration is finished. Codec register 26h */
1057 	n = 0;
1058 	do {
1059 		delay(1);
1060 		if (++n > 1000) {
1061 			printf("%s: Timeout waiting for Codec calibration\n",
1062 			       sc->sc_dev.dv_xname);
1063 			return ;
1064 		}
1065 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
1066 	} while ((data & 0x0f) != 0x0f);
1067 
1068 	/* Set the serial timing configuration again */
1069 	/* XXX: undocumented but the Linux driver do this */
1070 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
1071 
1072 	/* Wait until we've sampled input slots 3 & 4 as valid */
1073 	n = 0;
1074 	do {
1075 		delay(1000);
1076 		if (++n > 1000) {
1077 			printf("%s: Timeout waiting for sampled input slots as valid\n",
1078 			       sc->sc_dev.dv_xname);
1079 			return;
1080 		}
1081 		dat32 = BA0READ4(sc, CS4281_ACISV) & (ACISV_ISV3 | ACISV_ISV4) ;
1082 	} while (dat32 != (ACISV_ISV3 | ACISV_ISV4));
1083 
1084 	/* Start digital data transfer of audio data to the codec */
1085 	BA0WRITE4(sc, CS4281_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4));
1086 }
1087 
1088 int
1089 cs4281_open(void *addr, int flags)
1090 {
1091 	return (0);
1092 }
1093 
1094 void
1095 cs4281_close(void *addr)
1096 {
1097 	struct cs4281_softc *sc;
1098 
1099 	sc = addr;
1100 
1101 	(*sc->halt_output)(sc);
1102 	(*sc->halt_input)(sc);
1103 
1104 	sc->sc_pintr = 0;
1105 	sc->sc_rintr = 0;
1106 }
1107 
1108 int
1109 cs4281_round_blocksize(void *addr, int blk)
1110 {
1111 	return DMA_SIZE / 2;
1112 }
1113 
1114 int
1115 cs4281_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1116 {
1117 	struct cs4281_softc *sc;
1118 	int val;
1119 
1120 	sc = addr;
1121 	val = sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
1122 	DPRINTFN(3,("mixer_set_port: val=%d\n", val));
1123 	return (val);
1124 }
1125 
1126 int
1127 cs4281_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1128 {
1129 	struct cs4281_softc *sc;
1130 
1131 	sc = addr;
1132 	return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
1133 }
1134 
1135 int
1136 cs4281_query_devinfo(void *addr, mixer_devinfo_t *dip)
1137 {
1138 	struct cs4281_softc *sc;
1139 
1140 	sc = addr;
1141 	return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
1142 }
1143 
1144 void *
1145 cs4281_malloc(void *addr, int direction, size_t size, int pool, int flags)
1146 {
1147 	struct cs4281_softc *sc;
1148 	struct cs4281_dma   *p;
1149 	int error;
1150 
1151 	sc = addr;
1152 
1153 	p = malloc(sizeof(*p), pool, flags);
1154 	if (!p)
1155 		return (0);
1156 
1157 	error = cs4281_allocmem(sc, size, pool, flags, p);
1158 
1159 	if (error) {
1160 		free(p, pool, sizeof(*p));
1161 		return (0);
1162 	}
1163 
1164 	p->next = sc->sc_dmas;
1165 	sc->sc_dmas = p;
1166 	return (KERNADDR(p));
1167 }
1168 
1169 void
1170 cs4281_free(void *addr, void *ptr, int pool)
1171 {
1172 	struct cs4281_softc *sc;
1173 	struct cs4281_dma **pp, *p;
1174 
1175 	sc = addr;
1176 	for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
1177 		if (KERNADDR(p) == ptr) {
1178 			bus_dmamap_unload(sc->sc_dmatag, p->map);
1179 			bus_dmamap_destroy(sc->sc_dmatag, p->map);
1180 			bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1181 			bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1182 			*pp = p->next;
1183 			free(p, pool, sizeof(*p));
1184 			return;
1185 		}
1186 	}
1187 }
1188 
1189 size_t
1190 cs4281_round_buffersize(void *addr, int direction, size_t size)
1191 {
1192 	return (DMA_SIZE);
1193 }
1194 
1195 int
1196 cs4281_get_props(void *addr)
1197 {
1198 	int retval;
1199 
1200 	retval = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
1201 #ifdef MMAP_READY
1202 	retval |= AUDIO_PROP_MMAP;
1203 #endif
1204 	return (retval);
1205 }
1206 
1207 /* AC97 */
1208 int
1209 cs4281_attach_codec(void *addr, struct ac97_codec_if *codec_if)
1210 {
1211 	struct cs4281_softc *sc;
1212 
1213 	DPRINTF(("cs4281_attach_codec:\n"));
1214 	sc = addr;
1215 	sc->codec_if = codec_if;
1216 	return (0);
1217 }
1218 
1219 int
1220 cs4281_read_codec(void *addr, u_int8_t ac97_addr, u_int16_t *ac97_data)
1221 {
1222 	struct cs4281_softc *sc;
1223 	u_int32_t acctl;
1224 	int n;
1225 
1226 	sc = addr;
1227 
1228 	DPRINTFN(5,("read_codec: add=0x%02x ", ac97_addr));
1229 	/*
1230 	 * Make sure that there is not data sitting around from a preivous
1231 	 * uncompleted access.
1232 	 */
1233 	BA0READ4(sc, CS4281_ACSDA);
1234 
1235 	/* Set up AC97 control registers. */
1236 	BA0WRITE4(sc, CS4281_ACCAD, ac97_addr);
1237 	BA0WRITE4(sc, CS4281_ACCDA, 0);
1238 
1239 	acctl = ACCTL_ESYN | ACCTL_VFRM | ACCTL_CRW  | ACCTL_DCV;
1240 	BA0WRITE4(sc, CS4281_ACCTL, acctl);
1241 
1242 	if (cs4281_src_wait(sc) < 0) {
1243 		printf("%s: AC97 read prob. (DCV!=0) for add=0x%0x\n",
1244 		       sc->sc_dev.dv_xname, ac97_addr);
1245 		return 1;
1246 	}
1247 
1248 	/* wait for valid status bit is active */
1249 	n = 0;
1250 	while ((BA0READ4(sc, CS4281_ACSTS) & ACSTS_VSTS) == 0) {
1251 		delay(1);
1252 		while (++n > 1000) {
1253 			printf("%s: AC97 read fail (VSTS==0) for add=0x%0x\n",
1254 			       sc->sc_dev.dv_xname, ac97_addr);
1255 			return 1;
1256 		}
1257 	}
1258 	*ac97_data = BA0READ4(sc, CS4281_ACSDA);
1259 	DPRINTFN(5,("data=0x%04x\n", *ac97_data));
1260 	return (0);
1261 }
1262 
1263 int
1264 cs4281_write_codec(void *addr, u_int8_t ac97_addr, u_int16_t ac97_data)
1265 {
1266 	struct cs4281_softc *sc;
1267 	u_int32_t acctl;
1268 
1269 	sc = addr;
1270 
1271 	DPRINTFN(5,("write_codec: add=0x%02x  data=0x%04x\n", ac97_addr, ac97_data));
1272 	BA0WRITE4(sc, CS4281_ACCAD, ac97_addr);
1273 	BA0WRITE4(sc, CS4281_ACCDA, ac97_data);
1274 
1275 	acctl = ACCTL_ESYN | ACCTL_VFRM | ACCTL_DCV;
1276 	BA0WRITE4(sc, CS4281_ACCTL, acctl);
1277 
1278 	if (cs4281_src_wait(sc) < 0) {
1279 		printf("%s: AC97 write fail (DCV!=0) for add=0x%02x data="
1280 		       "0x%04x\n", sc->sc_dev.dv_xname, ac97_addr, ac97_data);
1281 		return (1);
1282 	}
1283 	return (0);
1284 }
1285 
1286 int
1287 cs4281_allocmem(struct cs4281_softc *sc, size_t size, int pool, int flags,
1288 		struct cs4281_dma *p)
1289 {
1290 	int error;
1291 
1292 	if (size != DMA_SIZE) {
1293 		printf("%s: dma size is %zd should be %d\n",
1294 		    sc->sc_dev.dv_xname, size, DMA_SIZE);
1295 		return ENOMEM;
1296 
1297 	}
1298 	p->size = size;
1299 
1300 	/* allocate memory for upper audio driver */
1301 	error = bus_dmamem_alloc(sc->sc_dmatag, p->size, DMA_ALIGN, 0,
1302 				 p->segs, nitems(p->segs),
1303 				 &p->nsegs, BUS_DMA_NOWAIT);
1304 	if (error) {
1305 		printf("%s: unable to allocate dma. error=%d\n",
1306 		       sc->sc_dev.dv_xname, error);
1307 		return (error);
1308 	}
1309 
1310 	error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,
1311 			       &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
1312 	if (error) {
1313 		printf("%s: unable to map dma, error=%d\n",
1314 		       sc->sc_dev.dv_xname, error);
1315 		goto free;
1316 	}
1317 
1318 	error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
1319 				  0, BUS_DMA_NOWAIT, &p->map);
1320 	if (error) {
1321 		printf("%s: unable to create dma map, error=%d\n",
1322 		       sc->sc_dev.dv_xname, error);
1323 		goto unmap;
1324 	}
1325 
1326 	error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL,
1327 				BUS_DMA_NOWAIT);
1328 	if (error) {
1329 		printf("%s: unable to load dma map, error=%d\n",
1330 		       sc->sc_dev.dv_xname, error);
1331 		goto destroy;
1332 	}
1333 	return (0);
1334 
1335 destroy:
1336 	bus_dmamap_destroy(sc->sc_dmatag, p->map);
1337 unmap:
1338 	bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1339 free:
1340 	bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1341 	return (error);
1342 }
1343 
1344 int
1345 cs4281_src_wait(struct cs4281_softc *sc)
1346 {
1347 	int n;
1348 
1349 	n = 0;
1350 	while ((BA0READ4(sc, CS4281_ACCTL) & ACCTL_DCV)) {
1351 		delay(1000);
1352 		if (++n > 1000)
1353 			return (-1);
1354 	}
1355 	return (0);
1356 }
1357