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