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