xref: /openbsd-src/sys/dev/pci/cs4281.c (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
1 /*	$OpenBSD: cs4281.c,v 1.13 2003/04/27 11:22:53 ho 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 #include <sys/types.h>
51 #include <sys/systm.h>
52 
53 #include <dev/pci/pcidevs.h>
54 #include <dev/pci/pcivar.h>
55 #include <dev/pci/cs4281reg.h>
56 
57 #include <sys/audioio.h>
58 #include <dev/audio_if.h>
59 #include <dev/midi_if.h>
60 #include <dev/mulaw.h>
61 #include <dev/auconv.h>
62 
63 #include <dev/ic/ac97.h>
64 
65 #include <machine/bus.h>
66 
67 #define CSCC_PCI_BA0 0x10
68 #define CSCC_PCI_BA1 0x14
69 
70 struct cs4281_dma {
71 	bus_dmamap_t map;
72 	caddr_t addr;		/* real dma buffer */
73 	caddr_t dum;		/* dummy buffer for audio driver */
74 	bus_dma_segment_t segs[1];
75 	int nsegs;
76 	size_t size;
77 	struct cs4281_dma *next;
78 };
79 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
80 #define BUFADDR(p)  ((void *)((p)->dum))
81 #define KERNADDR(p) ((void *)((p)->addr))
82 
83 /*
84  * Software state
85  */
86 struct cs4281_softc {
87 	struct device		sc_dev;
88 
89 	pci_intr_handle_t	*sc_ih;
90 
91         /* I/O (BA0) */
92 	bus_space_tag_t		ba0t;
93 	bus_space_handle_t	ba0h;
94 
95 	/* BA1 */
96 	bus_space_tag_t		ba1t;
97 	bus_space_handle_t	ba1h;
98 
99 	/* DMA */
100 	bus_dma_tag_t		sc_dmatag;
101 	struct cs4281_dma	*sc_dmas;
102 	size_t dma_size;
103 	size_t dma_align;
104 
105 	int	hw_blocksize;
106 
107         /* playback */
108 	void	(*sc_pintr)(void *);	/* dma completion intr handler */
109 	void	*sc_parg;		/* arg for sc_intr() */
110 	char	*sc_ps, *sc_pe, *sc_pn;
111 	int	sc_pcount;
112 	int	sc_pi;
113 	struct cs4281_dma *sc_pdma;
114 	char	*sc_pbuf;
115 	int	(*halt_output)(void *);
116 #ifdef DIAGNOSTIC
117         char	sc_prun;
118 #endif
119 
120 	/* capturing */
121 	void	(*sc_rintr)(void *);	/* dma completion intr handler */
122 	void	*sc_rarg;		/* arg for sc_intr() */
123 	char	*sc_rs, *sc_re, *sc_rn;
124 	int	sc_rcount;
125 	int	sc_ri;
126 	struct	cs4281_dma *sc_rdma;
127 	char	*sc_rbuf;
128 	int	sc_rparam;		/* record format */
129 	int	(*halt_input)(void *);
130 #ifdef DIAGNOSTIC
131         char	sc_rrun;
132 #endif
133 
134 #if NMIDI > 0
135         void	(*sc_iintr)(void *, int);	/* midi input ready handler */
136         void	(*sc_ointr)(void *);		/* midi output ready handler */
137         void	*sc_arg;
138 #endif
139 
140 	/* AC97 CODEC */
141 	struct ac97_codec_if *codec_if;
142 	struct ac97_host_if host_if;
143 
144         /* Power Management */
145         char	sc_suspend;
146         void	*sc_powerhook;		/* Power hook */
147 	u_int16_t ac97_reg[CS4281_SAVE_REG_MAX + 1];   /* Save ac97 registers */
148 };
149 
150 #define BA0READ4(sc, r) bus_space_read_4((sc)->ba0t, (sc)->ba0h, (r))
151 #define BA0WRITE4(sc, r, x) bus_space_write_4((sc)->ba0t, (sc)->ba0h, (r), (x))
152 
153 #if defined(ENABLE_SECONDARY_CODEC)
154 #define MAX_CHANNELS  (4)
155 #define MAX_FIFO_SIZE 32 /* 128/4 channels */
156 #else
157 #define MAX_CHANNELS  (2)
158 #define MAX_FIFO_SIZE 64 /* 128/2 channels */
159 #endif
160 
161 int cs4281_match(struct device *, void *, void *);
162 void cs4281_attach(struct device *, struct device *, void *);
163 int cs4281_intr(void *);
164 int cs4281_query_encoding(void *, struct audio_encoding *);
165 int cs4281_set_params(void *, int, int, struct audio_params *,
166 				     struct audio_params *);
167 int cs4281_halt_output(void *);
168 int cs4281_halt_input(void *);
169 int cs4281_getdev(void *, struct audio_device *);
170 int cs4281_trigger_output(void *, void *, void *, int, void (*)(void *),
171 			  void *, struct audio_params *);
172 int cs4281_trigger_input(void *, void *, void *, int, void (*)(void *),
173 			 void *, struct audio_params *);
174 u_int8_t cs4281_sr2regval(int);
175 void cs4281_set_dac_rate(struct cs4281_softc *, int);
176 void cs4281_set_adc_rate(struct cs4281_softc *, int);
177 int cs4281_init(struct cs4281_softc *);
178 
179 int cs4281_open(void *, int);
180 void cs4281_close(void *);
181 int cs4281_round_blocksize(void *, int);
182 int cs4281_get_props(void *);
183 int cs4281_attach_codec(void *, struct ac97_codec_if *);
184 int cs4281_read_codec(void *, u_int8_t , u_int16_t *);
185 int cs4281_write_codec(void *, u_int8_t, u_int16_t);
186 void cs4281_reset_codec(void *);
187 
188 void cs4281_power(int, void *);
189 
190 int cs4281_mixer_set_port(void *, mixer_ctrl_t *);
191 int cs4281_mixer_get_port(void *, mixer_ctrl_t *);
192 int cs4281_query_devinfo(void *, mixer_devinfo_t *);
193 void *cs4281_malloc(void *, int, size_t, int, int);
194 size_t cs4281_round_buffersize(void *, int, size_t);
195 void cs4281_free(void *, void *, int);
196 paddr_t cs4281_mappage(void *, void *, off_t, int);
197 
198 int cs4281_allocmem(struct cs4281_softc *, size_t, int, int,
199 				     struct cs4281_dma *);
200 int cs4281_src_wait(struct cs4281_softc *);
201 
202 #if defined(CS4281_DEBUG)
203 #undef DPRINTF
204 #undef DPRINTFN
205 #define DPRINTF(x)	    if (cs4281_debug) printf x
206 #define DPRINTFN(n,x)	    if (cs4281_debug>(n)) printf x
207 int cs4281_debug = 5;
208 #else
209 #define DPRINTF(x)
210 #define DPRINTFN(n,x)
211 #endif
212 
213 struct audio_hw_if cs4281_hw_if = {
214 	cs4281_open,
215 	cs4281_close,
216 	NULL,
217 	cs4281_query_encoding,
218 	cs4281_set_params,
219 	cs4281_round_blocksize,
220 	NULL,
221 	NULL,
222 	NULL,
223 	NULL,
224 	NULL,
225 	cs4281_halt_output,
226 	cs4281_halt_input,
227 	NULL,
228 	cs4281_getdev,
229 	NULL,
230 	cs4281_mixer_set_port,
231 	cs4281_mixer_get_port,
232 	cs4281_query_devinfo,
233 	cs4281_malloc,
234 	cs4281_free,
235 	cs4281_round_buffersize,
236 	NULL, /* cs4281_mappage, */
237 	cs4281_get_props,
238 	cs4281_trigger_output,
239 	cs4281_trigger_input,
240 };
241 
242 #if NMIDI > 0
243 /* Midi Interface */
244 void cs4281_midi_close(void *);
245 void cs4281_midi_getinfo(void *, struct midi_info *);
246 int cs4281_midi_open(void *, int, void (*)(void *, int),
247 		     void (*)(void *), void *);
248 int cs4281_midi_output(void *, int);
249 
250 struct midi_hw_if cs4281_midi_hw_if = {
251 	cs4281_midi_open,
252 	cs4281_midi_close,
253 	cs4281_midi_output,
254 	cs4281_midi_getinfo,
255 	0,
256 };
257 #endif
258 
259 struct cfattach clct_ca = {
260 	sizeof(struct cs4281_softc), cs4281_match, cs4281_attach
261 };
262 
263 struct cfdriver clct_cd = {
264 	NULL, "clct", DV_DULL
265 };
266 
267 struct audio_device cs4281_device = {
268 	"CS4281",
269 	"",
270 	"cs4281"
271 };
272 
273 
274 int
275 cs4281_match(parent, match, aux)
276 	struct device *parent;
277 	void *match;
278 	void *aux;
279 {
280 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
281 
282 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CIRRUS ||
283 	    PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_CIRRUS_CS4281)
284 		return (0);
285 
286 	return (1);
287 }
288 
289 void
290 cs4281_attach(parent, self, aux)
291 	struct device *parent;
292 	struct device *self;
293 	void *aux;
294 {
295 	struct cs4281_softc *sc = (struct cs4281_softc *)self;
296 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
297 	pci_chipset_tag_t pc = pa->pa_pc;
298 	char const *intrstr;
299 	pci_intr_handle_t ih;
300 	pcireg_t csr;
301 	int pci_pwrmgmt_cap_reg, pci_pwrmgmt_csr_reg;
302 
303 	/* Map I/O register */
304 	if (pci_mapreg_map(pa, CSCC_PCI_BA0,
305 	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ba0t,
306 	    &sc->ba0h, NULL, NULL, 0)) {
307 		printf("%s: can't map BA0 space\n", sc->sc_dev.dv_xname);
308 		return;
309 	}
310 	if (pci_mapreg_map(pa, CSCC_PCI_BA1,
311 	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->ba1t,
312 	    &sc->ba1h, NULL, NULL, 0)) {
313 		printf("%s: can't map BA1 space\n", sc->sc_dev.dv_xname);
314 		return;
315 	}
316 
317 	sc->sc_dmatag = pa->pa_dmat;
318 
319 	/*
320 	 * Set Power State D0.
321 	 * Without doing this, 0xffffffff is read from all registers after
322 	 * using Windows and rebooting into OpenBSD.
323 	 * On my IBM ThinkPad X20, it is set to D3 after using Windows2000.
324 	 */
325 	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
326 	    &pci_pwrmgmt_cap_reg, 0)) {
327 		pcireg_t reg;
328 
329 		pci_pwrmgmt_csr_reg = pci_pwrmgmt_cap_reg + 4;
330 		reg = pci_conf_read(pa->pa_pc, pa->pa_tag, pci_pwrmgmt_csr_reg);
331 		if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0) {
332 			pci_conf_write(pc, pa->pa_tag, pci_pwrmgmt_csr_reg,
333 			    (reg & ~PCI_PMCSR_STATE_MASK) |
334 			    PCI_PMCSR_STATE_D0);
335 		}
336 	}
337 
338 	/* Enable the device (set bus master flag) */
339 	csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
340 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
341 	    csr | PCI_COMMAND_MASTER_ENABLE);
342 
343 	/* Map and establish the interrupt. */
344 	if (pci_intr_map(pa, &ih)) {
345 		printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
346 		return;
347 	}
348 	intrstr = pci_intr_string(pc, ih);
349 
350 	sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, cs4281_intr, sc,
351 	    sc->sc_dev.dv_xname);
352 	if (sc->sc_ih == NULL) {
353 		printf("%s: couldn't establish interrupt",sc->sc_dev.dv_xname);
354 		if (intrstr != NULL)
355 			printf(" at %s", intrstr);
356 		printf("\n");
357 		return;
358 	}
359 	printf(" %s\n", intrstr);
360 
361 	/*
362 	 * Sound System start-up
363 	 */
364 	if (cs4281_init(sc) != 0)
365 		return;
366 
367 	sc->halt_input  = cs4281_halt_input;
368 	sc->halt_output = cs4281_halt_output;
369 
370 	sc->dma_size     = CS4281_BUFFER_SIZE / MAX_CHANNELS;
371 	sc->dma_align    = 0x10;
372 	sc->hw_blocksize = sc->dma_size / 2;
373 
374 	/* AC 97 attachment */
375 	sc->host_if.arg = sc;
376 	sc->host_if.attach = cs4281_attach_codec;
377 	sc->host_if.read   = cs4281_read_codec;
378 	sc->host_if.write  = cs4281_write_codec;
379 	sc->host_if.reset  = cs4281_reset_codec;
380 	if (ac97_attach(&sc->host_if) != 0) {
381 		printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname);
382 		return;
383 	}
384 	audio_attach_mi(&cs4281_hw_if, sc, &sc->sc_dev);
385 
386 #if NMIDI > 0
387 	midi_attach_mi(&cs4281_midi_hw_if, sc, &sc->sc_dev);
388 #endif
389 
390 	sc->sc_suspend = PWR_RESUME;
391 	sc->sc_powerhook = powerhook_establish(cs4281_power, sc);
392 }
393 
394 
395 int
396 cs4281_intr(p)
397 	void *p;
398 {
399 	struct cs4281_softc *sc = p;
400 	u_int32_t intr, val;
401 	char *empty_dma;
402 
403 	intr = BA0READ4(sc, CS4281_HISR);
404 	if (!(intr & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {
405 		BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
406 		return (0);
407 	}
408 	DPRINTF(("cs4281_intr:"));
409 
410 	if (intr & HISR_DMA0)
411 		val = BA0READ4(sc, CS4281_HDSR0); /* clear intr condition */
412 	if (intr & HISR_DMA1)
413 		val = BA0READ4(sc, CS4281_HDSR1); /* clear intr condition */
414 	BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
415 
416 	/* Playback Interrupt */
417 	if (intr & HISR_DMA0) {
418 		DPRINTF((" PB DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA0),
419 			 (int)BA0READ4(sc, CS4281_DCC0)));
420 		if (sc->sc_pintr) {
421 			if ((sc->sc_pi%sc->sc_pcount) == 0)
422 				sc->sc_pintr(sc->sc_parg);
423 		} else {
424 			printf("unexpected play intr\n");
425 		}
426 		/* copy buffer */
427 		++sc->sc_pi;
428 		empty_dma = sc->sc_pdma->addr;
429 		if (sc->sc_pi&1)
430 			empty_dma += sc->hw_blocksize;
431 		memcpy(empty_dma, sc->sc_pn, sc->hw_blocksize);
432 		sc->sc_pn += sc->hw_blocksize;
433 		if (sc->sc_pn >= sc->sc_pe)
434 			sc->sc_pn = sc->sc_ps;
435 	}
436 	if (intr & HISR_DMA1) {
437 		val = BA0READ4(sc, CS4281_HDSR1);
438 		/* copy from dma */
439 		DPRINTF((" CP DMA 0x%x(%d)", (int)BA0READ4(sc, CS4281_DCA1),
440 			 (int)BA0READ4(sc, CS4281_DCC1)));
441 		++sc->sc_ri;
442 		empty_dma = sc->sc_rdma->addr;
443 		if ((sc->sc_ri & 1) == 0)
444 			empty_dma += sc->hw_blocksize;
445 		memcpy(sc->sc_rn, empty_dma, sc->hw_blocksize);
446 		if (sc->sc_rn >= sc->sc_re)
447 			sc->sc_rn = sc->sc_rs;
448 		if (sc->sc_rintr) {
449 			if ((sc->sc_ri % sc->sc_rcount) == 0)
450 				sc->sc_rintr(sc->sc_rarg);
451 		} else {
452 			printf("unexpected record intr\n");
453 		}
454 	}
455 	DPRINTF(("\n"));
456 	return (1);
457 }
458 
459 int
460 cs4281_query_encoding(addr, fp)
461 	void *addr;
462 	struct audio_encoding *fp;
463 {
464 	switch (fp->index) {
465 	case 0:
466 		strlcpy(fp->name, AudioEulinear, sizeof fp->name);
467 		fp->encoding = AUDIO_ENCODING_ULINEAR;
468 		fp->precision = 8;
469 		fp->flags = 0;
470 		break;
471 	case 1:
472 		strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
473 		fp->encoding = AUDIO_ENCODING_ULAW;
474 		fp->precision = 8;
475 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
476 		break;
477 	case 2:
478 		strlcpy(fp->name, AudioEalaw, sizeof fp->name);
479 		fp->encoding = AUDIO_ENCODING_ALAW;
480 		fp->precision = 8;
481 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
482 		break;
483 	case 3:
484 		strlcpy(fp->name, AudioEslinear, sizeof fp->name);
485 		fp->encoding = AUDIO_ENCODING_SLINEAR;
486 		fp->precision = 8;
487 		fp->flags = 0;
488 		break;
489 	case 4:
490 		strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
491 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
492 		fp->precision = 16;
493 		fp->flags = 0;
494 		break;
495 	case 5:
496 		strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
497 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
498 		fp->precision = 16;
499 		fp->flags = 0;
500 		break;
501 	case 6:
502 		strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
503 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
504 		fp->precision = 16;
505 		fp->flags = 0;
506 		break;
507 	case 7:
508 		strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
509 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
510 		fp->precision = 16;
511 		fp->flags = 0;
512 		break;
513 	default:
514 		return EINVAL;
515 	}
516 	return (0);
517 }
518 
519 int
520 cs4281_set_params(addr, setmode, usemode, play, rec)
521 	void *addr;
522 	int setmode, usemode;
523 	struct audio_params *play, *rec;
524 {
525 	struct cs4281_softc *sc = addr;
526 	struct audio_params *p;
527 	int mode;
528 
529 	for (mode = AUMODE_RECORD; mode != -1;
530 	    mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
531 		if ((setmode & mode) == 0)
532 			continue;
533 
534 		p = mode == AUMODE_PLAY ? play : rec;
535 
536 		if (p == play) {
537 			DPRINTFN(5,("play: samp=%ld precision=%d channels=%d\n",
538 				p->sample_rate, p->precision, p->channels));
539 			if (p->sample_rate < 6023 || p->sample_rate > 48000 ||
540 			    (p->precision != 8 && p->precision != 16) ||
541 			    (p->channels != 1  && p->channels != 2)) {
542 				return (EINVAL);
543 			}
544 		} else {
545 			DPRINTFN(5,("rec: samp=%ld precision=%d channels=%d\n",
546 				p->sample_rate, p->precision, p->channels));
547 			if (p->sample_rate < 6023 || p->sample_rate > 48000 ||
548 			    (p->precision != 8 && p->precision != 16) ||
549 			    (p->channels != 1 && p->channels != 2)) {
550 				return (EINVAL);
551 			}
552 		}
553 		p->factor = 1;
554 		p->sw_code = 0;
555 
556 		switch (p->encoding) {
557 		case AUDIO_ENCODING_SLINEAR_BE:
558 			break;
559 		case AUDIO_ENCODING_SLINEAR_LE:
560 			break;
561 		case AUDIO_ENCODING_ULINEAR_BE:
562 			break;
563 		case AUDIO_ENCODING_ULINEAR_LE:
564 			break;
565 		case AUDIO_ENCODING_ULAW:
566 			if (mode == AUMODE_PLAY) {
567 				p->sw_code = mulaw_to_slinear8;
568 			} else {
569 				p->sw_code = slinear8_to_mulaw;
570 			}
571 			break;
572 		case AUDIO_ENCODING_ALAW:
573 			if (mode == AUMODE_PLAY) {
574 				p->sw_code = alaw_to_slinear8;
575 			} else {
576 				p->sw_code = slinear8_to_alaw;
577 			}
578 			break;
579 		default:
580 			return (EINVAL);
581 		}
582 	}
583 
584 	/* set sample rate */
585 	cs4281_set_dac_rate(sc, play->sample_rate);
586 	cs4281_set_adc_rate(sc, rec->sample_rate);
587 	return (0);
588 }
589 
590 int
591 cs4281_halt_output(addr)
592 	void *addr;
593 {
594 	struct cs4281_softc *sc = addr;
595 
596 	BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
597 #ifdef DIAGNOSTIC
598 	sc->sc_prun = 0;
599 #endif
600 	return (0);
601 }
602 
603 int
604 cs4281_halt_input(addr)
605 	void *addr;
606 {
607 	struct cs4281_softc *sc = addr;
608 
609 	BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
610 #ifdef DIAGNOSTIC
611 	sc->sc_rrun = 0;
612 #endif
613 	return (0);
614 }
615 
616 /* trivial */
617 int
618 cs4281_getdev(addr, retp)
619      void *addr;
620      struct audio_device *retp;
621 {
622 	*retp = cs4281_device;
623 	return (0);
624 }
625 
626 
627 int
628 cs4281_trigger_output(addr, start, end, blksize, intr, arg, param)
629 	void *addr;
630 	void *start, *end;
631 	int blksize;
632 	void (*intr)(void *);
633 	void *arg;
634 	struct audio_params *param;
635 {
636 	struct cs4281_softc *sc = addr;
637 	u_int32_t fmt=0;
638 	struct cs4281_dma *p;
639 	int dma_count;
640 
641 #ifdef DIAGNOSTIC
642 	if (sc->sc_prun)
643 		printf("cs4281_trigger_output: already running\n");
644 	sc->sc_prun = 1;
645 #endif
646 
647 	DPRINTF(("cs4281_trigger_output: sc=%p start=%p end=%p "
648 		 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
649 	sc->sc_pintr = intr;
650 	sc->sc_parg  = arg;
651 
652 	/* stop playback DMA */
653 	BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) | DCRn_MSK);
654 
655 	DPRINTF(("param: precision=%d  factor=%d channels=%d encoding=%d\n",
656 	       param->precision, param->factor, param->channels,
657 	       param->encoding));
658 	for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next)
659 		;
660 	if (p == NULL) {
661 		printf("cs4281_trigger_output: bad addr %p\n", start);
662 		return (EINVAL);
663 	}
664 
665 	sc->sc_pcount = blksize / sc->hw_blocksize;
666 	sc->sc_ps = (char *)start;
667 	sc->sc_pe = (char *)end;
668 	sc->sc_pdma = p;
669 	sc->sc_pbuf = KERNADDR(p);
670 	sc->sc_pi = 0;
671 	sc->sc_pn = sc->sc_ps;
672 	if (blksize >= sc->dma_size) {
673 		sc->sc_pn = sc->sc_ps + sc->dma_size;
674 		memcpy(sc->sc_pbuf, start, sc->dma_size);
675 		++sc->sc_pi;
676 	} else {
677 		sc->sc_pn = sc->sc_ps + sc->hw_blocksize;
678 		memcpy(sc->sc_pbuf, start, sc->hw_blocksize);
679 	}
680 
681 	dma_count = sc->dma_size;
682 	if (param->precision * param->factor != 8)
683 		dma_count /= 2;   /* 16 bit */
684 	if (param->channels > 1)
685 		dma_count /= 2;   /* Stereo */
686 
687 	DPRINTF(("cs4281_trigger_output: DMAADDR(p)=0x%x count=%d\n",
688 		 (int)DMAADDR(p), dma_count));
689 	BA0WRITE4(sc, CS4281_DBA0, DMAADDR(p));
690 	BA0WRITE4(sc, CS4281_DBC0, dma_count-1);
691 
692 	/* set playback format */
693 	fmt = BA0READ4(sc, CS4281_DMR0) & ~DMRn_FMTMSK;
694 	if (param->precision * param->factor == 8)
695 		fmt |= DMRn_SIZE8;
696 	if (param->channels == 1)
697 		fmt |= DMRn_MONO;
698 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
699 	    param->encoding == AUDIO_ENCODING_SLINEAR_BE)
700 		fmt |= DMRn_BEND;
701 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
702 	    param->encoding == AUDIO_ENCODING_ULINEAR_LE)
703 		fmt |= DMRn_USIGN;
704 	BA0WRITE4(sc, CS4281_DMR0, fmt);
705 
706 	/* set sample rate */
707 	cs4281_set_dac_rate(sc, param->sample_rate);
708 
709 	/* start DMA */
710 	BA0WRITE4(sc, CS4281_DCR0, BA0READ4(sc, CS4281_DCR0) & ~DCRn_MSK);
711 	/* Enable interrupts */
712 	BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
713 
714 	BA0WRITE4(sc, CS4281_PPRVC, 7);
715 	BA0WRITE4(sc, CS4281_PPLVC, 7);
716 
717 	DPRINTF(("HICR =0x%08x(expected 0x00000001)\n", BA0READ4(sc, CS4281_HICR)));
718 	DPRINTF(("HIMR =0x%08x(expected 0x00f0fc3f)\n", BA0READ4(sc, CS4281_HIMR)));
719 	DPRINTF(("DMR0 =0x%08x(expected 0x2???0018)\n", BA0READ4(sc, CS4281_DMR0)));
720 	DPRINTF(("DCR0 =0x%08x(expected 0x00030000)\n", BA0READ4(sc, CS4281_DCR0)));
721 	DPRINTF(("FCR0 =0x%08x(expected 0x81000f00)\n", BA0READ4(sc, CS4281_FCR0)));
722 	DPRINTF(("DACSR=0x%08x(expected 1 for 44kHz 5 for 8kHz)\n",
723 		 BA0READ4(sc, CS4281_DACSR)));
724 	DPRINTF(("SRCSA=0x%08x(expected 0x0b0a0100)\n", BA0READ4(sc, CS4281_SRCSA)));
725 	DPRINTF(("SSPM&SSPM_PSRCEN =0x%08x(expected 0x00000010)\n",
726 		 BA0READ4(sc, CS4281_SSPM) & SSPM_PSRCEN));
727 
728 	return (0);
729 }
730 
731 int
732 cs4281_trigger_input(addr, start, end, blksize, intr, arg, param)
733 	void *addr;
734 	void *start, *end;
735 	int blksize;
736 	void (*intr)(void *);
737 	void *arg;
738 	struct audio_params *param;
739 {
740 	struct cs4281_softc *sc = addr;
741 	struct cs4281_dma *p;
742 	u_int32_t fmt=0;
743 	int dma_count;
744 
745 	printf("cs4281_trigger_input: not implemented yet\n");
746 #ifdef DIAGNOSTIC
747 	if (sc->sc_rrun)
748 		printf("cs4281_trigger_input: already running\n");
749 	sc->sc_rrun = 1;
750 #endif
751 	DPRINTF(("cs4281_trigger_input: sc=%p start=%p end=%p "
752 	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
753 	sc->sc_rintr = intr;
754 	sc->sc_rarg  = arg;
755 
756 	/* stop recording DMA */
757 	BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) | DCRn_MSK);
758 
759 	for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next)
760 		;
761 	if (!p) {
762 		printf("cs4281_trigger_input: bad addr %p\n", start);
763 		return (EINVAL);
764 	}
765 
766 	sc->sc_rcount = blksize / sc->hw_blocksize;
767 	sc->sc_rs = (char *)start;
768 	sc->sc_re = (char *)end;
769 	sc->sc_rdma = p;
770 	sc->sc_rbuf = KERNADDR(p);
771 	sc->sc_ri = 0;
772 	sc->sc_rn = sc->sc_rs;
773 
774 	dma_count = sc->dma_size;
775 	if (param->precision * param->factor == 8)
776 		dma_count /= 2;
777 	if (param->channels > 1)
778 		dma_count /= 2;
779 
780 	DPRINTF(("cs4281_trigger_input: DMAADDR(p)=0x%x count=%d\n",
781 		 (int)DMAADDR(p), dma_count));
782 	BA0WRITE4(sc, CS4281_DBA1, DMAADDR(p));
783 	BA0WRITE4(sc, CS4281_DBC1, dma_count-1);
784 
785 	/* set recording format */
786 	fmt = BA0READ4(sc, CS4281_DMR1) & ~DMRn_FMTMSK;
787 	if (param->precision * param->factor == 8)
788 		fmt |= DMRn_SIZE8;
789 	if (param->channels == 1)
790 		fmt |= DMRn_MONO;
791 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
792 	    param->encoding == AUDIO_ENCODING_SLINEAR_BE)
793 		fmt |= DMRn_BEND;
794 	if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
795 	    param->encoding == AUDIO_ENCODING_ULINEAR_LE)
796 		fmt |= DMRn_USIGN;
797 	BA0WRITE4(sc, CS4281_DMR1, fmt);
798 
799 	/* set sample rate */
800 	cs4281_set_adc_rate(sc, param->sample_rate);
801 
802 	/* Start DMA */
803 	BA0WRITE4(sc, CS4281_DCR1, BA0READ4(sc, CS4281_DCR1) & ~DCRn_MSK);
804 	/* Enable interrupts */
805 	BA0WRITE4(sc, CS4281_HICR, HICR_IEV | HICR_CHGM);
806 
807 	DPRINTF(("HICR=0x%08x\n", BA0READ4(sc, CS4281_HICR)));
808 	DPRINTF(("HIMR=0x%08x\n", BA0READ4(sc, CS4281_HIMR)));
809 	DPRINTF(("DMR1=0x%08x\n", BA0READ4(sc, CS4281_DMR1)));
810 	DPRINTF(("DCR1=0x%08x\n", BA0READ4(sc, CS4281_DCR1)));
811 
812 	return (0);
813 }
814 
815 /* convert sample rate to register value */
816 u_int8_t
817 cs4281_sr2regval(rate)
818      int rate;
819 {
820 	u_int8_t retval;
821 
822 	/* We don't have to change here. but anyway ... */
823 	if (rate > 48000)
824 		rate = 48000;
825 	if (rate < 6023)
826 		rate = 6023;
827 
828 	switch (rate) {
829 	case 8000:
830 		retval = 5;
831 		break;
832 	case 11025:
833 		retval = 4;
834 		break;
835 	case 16000:
836 		retval = 3;
837 		break;
838 	case 22050:
839 		retval = 2;
840 		break;
841 	case 44100:
842 		retval = 1;
843 		break;
844 	case 48000:
845 		retval = 0;
846 		break;
847 	default:
848 		retval = 1536000/rate; /* == 24576000/(rate*16) */
849 	}
850 	return (retval);
851 }
852 
853 
854 void
855 cs4281_set_dac_rate(sc, rate)
856 	struct cs4281_softc *sc;
857 	int rate;
858 {
859 	BA0WRITE4(sc, CS4281_DACSR, cs4281_sr2regval(rate));
860 }
861 
862 void
863 cs4281_set_adc_rate(sc, rate)
864 	struct cs4281_softc *sc;
865 	int rate;
866 {
867 	BA0WRITE4(sc, CS4281_ADCSR, cs4281_sr2regval(rate));
868 }
869 
870 int
871 cs4281_init(sc)
872      struct cs4281_softc *sc;
873 {
874 	int n;
875 	u_int16_t data;
876 	u_int32_t dat32;
877 
878 	/* set "Configuration Write Protect" register to
879 	 * 0x4281 to allow to write */
880 	BA0WRITE4(sc, CS4281_CWPR, 0x4281);
881 
882 	/*
883 	 * Unset "Full Power-Down bit of Extended PCI Power Management
884 	 * Control" register to release the reset state.
885 	 */
886 	dat32 = BA0READ4(sc, CS4281_EPPMC);
887 	if (dat32 & EPPMC_FPDN)
888 		BA0WRITE4(sc, CS4281_EPPMC, dat32 & ~EPPMC_FPDN);
889 
890 	/* Start PLL out in known state */
891 	BA0WRITE4(sc, CS4281_CLKCR1, 0);
892 	/* Start serial ports out in known state */
893 	BA0WRITE4(sc, CS4281_SERMC, 0);
894 
895 	/* Reset codec */
896 	BA0WRITE4(sc, CS4281_ACCTL, 0);
897 	delay(50);	/* delay 50us */
898 
899 	BA0WRITE4(sc, CS4281_SPMC, 0);
900 	delay(100);	/* delay 100us */
901 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN);
902 #if defined(ENABLE_SECONDARY_CODEC)
903 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E);
904 	BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID);
905 #endif
906 	delay(50000);   /* XXX: delay 50ms */
907 
908 	/* Turn on Sound System clocks based on ABITCLK */
909 	BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_DLLP);
910 	delay(50000);   /* XXX: delay 50ms */
911 	BA0WRITE4(sc, CS4281_CLKCR1, CLKCR1_SWCE | CLKCR1_DLLP);
912 
913 	/* Set enables for sections that are needed in the SSPM registers */
914 	BA0WRITE4(sc, CS4281_SSPM,
915 		  SSPM_MIXEN |		/* Mixer */
916 		  SSPM_CSRCEN |		/* Capture SRC */
917 		  SSPM_PSRCEN |		/* Playback SRC */
918 		  SSPM_JSEN |		/* Joystick */
919 		  SSPM_ACLEN |		/* AC LINK */
920 		  SSPM_FMEN		/* FM */
921 		  );
922 
923 	/* Wait for clock stabilization */
924 	n = 0;
925 	while ((BA0READ4(sc, CS4281_CLKCR1)& (CLKCR1_DLLRDY | CLKCR1_CLKON))
926 	    != (CLKCR1_DLLRDY | CLKCR1_CLKON)) {
927 		delay(100);
928 		if (++n > 1000)
929 			return (-1);
930 	}
931 
932 	/* Enable ASYNC generation */
933 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN);
934 
935 	/* Wait for Codec ready. Linux driver wait 50ms here */
936 	n = 0;
937 	while((BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY) == 0) {
938 		delay(100);
939 		if (++n > 1000)
940 			return (-1);
941 	}
942 
943 #if defined(ENABLE_SECONDARY_CODEC)
944 	/* secondary codec ready*/
945 	n = 0;
946 	while((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) {
947 		delay(100);
948 		if (++n > 1000)
949 			return (-1);
950 	}
951 #endif
952 
953 	/* Set the serial timing configuration */
954 	/* XXX: undocumented but the Linux driver do this */
955 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
956 
957 	/* Wait for Codec ready signal */
958 	n = 0;
959 	do {
960 		delay(1000);
961 		if (++n > 1000) {
962 			printf("%s: Timeout waiting for Codec ready\n",
963 			       sc->sc_dev.dv_xname);
964 			return -1;
965 		}
966 		dat32 = BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY;
967 	} while (dat32 == 0);
968 
969 	/* Enable Valid Frame output on ASDOUT */
970 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN | ACCTL_VFRM);
971 
972 	/* Wait until Codec Calibration is finished. Codec register 26h */
973 	n = 0;
974 	do {
975 		delay(1);
976 		if (++n > 1000) {
977 			printf("%s: Timeout waiting for Codec calibration\n",
978 			       sc->sc_dev.dv_xname);
979 			return -1;
980 		}
981 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
982 	} while ((data & 0x0f) != 0x0f);
983 
984 	/* Set the serial timing configuration again */
985 	/* XXX: undocumented but the Linux driver do this */
986 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
987 
988 	/* Wait until we've sampled input slots 3 & 4 as valid */
989 	n = 0;
990 	do {
991 		delay(1000);
992 		if (++n > 1000) {
993 			printf("%s: Timeout waiting for sampled input slots as valid\n",
994 			       sc->sc_dev.dv_xname);
995 			return -1;
996 		}
997 		dat32 = BA0READ4(sc, CS4281_ACISV) & (ACISV_ISV3 | ACISV_ISV4);
998 	} while (dat32 != (ACISV_ISV3 | ACISV_ISV4));
999 
1000 	/* Start digital data transfer of audio data to the codec */
1001 	BA0WRITE4(sc, CS4281_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4));
1002 
1003 	cs4281_write_codec(sc, AC97_REG_HEADPHONE_VOLUME, 0);
1004 	cs4281_write_codec(sc, AC97_REG_MASTER_VOLUME, 0);
1005 
1006 	/* Power on the DAC */
1007 	cs4281_read_codec(sc, AC97_REG_POWER, &data);
1008 	cs4281_write_codec(sc, AC97_REG_POWER, data &= 0xfdff);
1009 
1010 	/* Wait until we sample a DAC ready state.
1011 	 * Not documented, but Linux driver does.
1012 	 */
1013 	for (n = 0; n < 32; ++n) {
1014 		delay(1000);
1015 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
1016 		if (data & 0x02)
1017 			break;
1018 	}
1019 
1020 	/* Power on the ADC */
1021 	cs4281_read_codec(sc, AC97_REG_POWER, &data);
1022 	cs4281_write_codec(sc, AC97_REG_POWER, data &= 0xfeff);
1023 
1024 	/* Wait until we sample ADC ready state.
1025 	 * Not documented, but Linux driver does.
1026 	 */
1027 	for (n = 0; n < 32; ++n) {
1028 		delay(1000);
1029 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
1030 		if (data & 0x01)
1031 			break;
1032 	}
1033 
1034 #if 0
1035 	/* Initialize SSCR register features */
1036 	/* XXX: hardware volume setting */
1037 	BA0WRITE4(sc, CS4281_SSCR, ~SSCR_HVC); /* disable HW volume setting */
1038 #endif
1039 
1040 	/* disable Sound Blaster Pro emulation */
1041 	/* XXX:
1042 	 * Cannot set since the documents does not describe which bit is
1043 	 * correspond to SSCR_SB. Since the reset value of SSCR is 0,
1044 	 * we can ignore it.*/
1045 #if 0
1046 	BA0WRITE4(sc, CS4281_SSCR, SSCR_SB);
1047 #endif
1048 
1049 	/* map AC97 PCM playback to DMA Channel 0 */
1050 	/* Reset FEN bit to setup first */
1051 	BA0WRITE4(sc, CS4281_FCR0, (BA0READ4(sc,CS4281_FCR0) & ~FCRn_FEN));
1052 	/*
1053 	 *| RS[4:0]/|        |
1054 	 *| LS[4:0] |  AC97  | Slot Function
1055 	 *|---------+--------+--------------------
1056 	 *|     0   |    3   | Left PCM Playback
1057 	 *|     1   |    4   | Right PCM Playback
1058 	 *|     2   |    5   | Phone Line 1 DAC
1059 	 *|     3   |    6   | Center PCM Playback
1060 	 *....
1061 	 *  quoted from Table 29(p109)
1062 	 */
1063 	dat32 = 0x01 << 24 |   /* RS[4:0] =  1 see above */
1064 		0x00 << 16 |   /* LS[4:0] =  0 see above */
1065 		0x0f <<  8 |   /* SZ[6:0] = 15 size of buffer */
1066 		0x00 <<  0 ;   /* OF[6:0] =  0 offset */
1067 	BA0WRITE4(sc, CS4281_FCR0, dat32);
1068 	BA0WRITE4(sc, CS4281_FCR0, dat32 | FCRn_FEN);
1069 
1070 	/* map AC97 PCM record to DMA Channel 1 */
1071 	/* Reset FEN bit to setup first */
1072 	BA0WRITE4(sc, CS4281_FCR1, (BA0READ4(sc,CS4281_FCR1) & ~FCRn_FEN));
1073 	/*
1074 	 *| RS[4:0]/|
1075 	 *| LS[4:0] | AC97 | Slot Function
1076 	 *|---------+------+-------------------
1077 	 *|   10    |   3  | Left PCM Record
1078 	 *|   11    |   4  | Right PCM Record
1079 	 *|   12    |   5  | Phone Line 1 ADC
1080 	 *|   13    |   6  | Mic ADC
1081 	 *....
1082 	 * quoted from Table 30(p109)
1083 	 */
1084 	dat32 = 0x0b << 24 |    /* RS[4:0] = 11 See above */
1085 		0x0a << 16 |    /* LS[4:0] = 10 See above */
1086 		0x0f <<  8 |    /* SZ[6:0] = 15 Size of buffer */
1087 		0x10 <<  0 ;    /* OF[6:0] = 16 offset */
1088 
1089 	/* XXX: I cannot understand why FCRn_PSH is needed here. */
1090 	BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_PSH);
1091 	BA0WRITE4(sc, CS4281_FCR1, dat32 | FCRn_FEN);
1092 
1093 #if 0
1094 	/* Disable DMA Channel 2, 3 */
1095 	BA0WRITE4(sc, CS4281_FCR2, (BA0READ4(sc,CS4281_FCR2) & ~FCRn_FEN));
1096 	BA0WRITE4(sc, CS4281_FCR3, (BA0READ4(sc,CS4281_FCR3) & ~FCRn_FEN));
1097 #endif
1098 
1099 	/* Set the SRC Slot Assignment accordingly */
1100 	/*| PLSS[4:0]/
1101 	 *| PRSS[4:0] | AC97 | Slot Function
1102 	 *|-----------+------+----------------
1103 	 *|     0     |  3   | Left PCM Playback
1104 	 *|     1     |  4   | Right PCM Playback
1105 	 *|     2     |  5   | phone line 1 DAC
1106 	 *|     3     |  6   | Center PCM Playback
1107 	 *|     4     |  7   | Left Surround PCM Playback
1108 	 *|     5     |  8   | Right Surround PCM Playback
1109 	 *......
1110 	 *
1111 	 *| CLSS[4:0]/
1112 	 *| CRSS[4:0] | AC97 | Codec |Slot Function
1113 	 *|-----------+------+-------+-----------------
1114 	 *|    10     |   3  |Primary| Left PCM Record
1115 	 *|    11     |   4  |Primary| Right PCM Record
1116 	 *|    12     |   5  |Primary| Phone Line 1 ADC
1117 	 *|    13     |   6  |Primary| Mic ADC
1118 	 *|.....
1119 	 *|    20     |   3  |  Sec. | Left PCM Record
1120 	 *|    21     |   4  |  Sec. | Right PCM Record
1121 	 *|    22     |   5  |  Sec. | Phone Line 1 ADC
1122 	 *|    23     |   6  |  Sec. | Mic ADC
1123 	 */
1124 	dat32 = 0x0b << 24 |   /* CRSS[4:0] Right PCM Record(primary) */
1125 		0x0a << 16 |   /* CLSS[4:0] Left  PCM Record(primary) */
1126 		0x01 <<  8 |   /* PRSS[4:0] Right PCM Playback */
1127 		0x00 <<  0;    /* PLSS[4:0] Left  PCM Playback */
1128 	BA0WRITE4(sc, CS4281_SRCSA, dat32);
1129 
1130 	/* Set interrupt to occurred at Half and Full terminal
1131 	 * count interrupt enable for DMA channel 0 and 1.
1132 	 * To keep DMA stop, set MSK.
1133 	 */
1134 	dat32 = DCRn_HTCIE | DCRn_TCIE | DCRn_MSK;
1135 	BA0WRITE4(sc, CS4281_DCR0, dat32);
1136 	BA0WRITE4(sc, CS4281_DCR1, dat32);
1137 
1138 	/* Set Auto-Initialize Contorl enable */
1139 	BA0WRITE4(sc, CS4281_DMR0,
1140 		  DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);
1141 	BA0WRITE4(sc, CS4281_DMR1,
1142 		  DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);
1143 
1144 	/* Clear DMA Mask in HIMR */
1145 	dat32 = BA0READ4(sc, CS4281_HIMR) & 0xfffbfcff;
1146 	BA0WRITE4(sc, CS4281_HIMR, dat32);
1147 	return (0);
1148 }
1149 
1150 void
1151 cs4281_power(why, v)
1152 	int why;
1153 	void *v;
1154 {
1155 	struct cs4281_softc *sc = (struct cs4281_softc *)v;
1156 	int i;
1157 
1158 	DPRINTF(("%s: cs4281_power why=%d\n", sc->sc_dev.dv_xname, why));
1159 	if (why != PWR_RESUME) {
1160 		sc->sc_suspend = why;
1161 
1162 		cs4281_halt_output(sc);
1163 		cs4281_halt_input(sc);
1164 		/* Save AC97 registers */
1165 		for (i = 1; i <= CS4281_SAVE_REG_MAX; i++) {
1166 			if (i == 0x04)	/* AC97_REG_MASTER_TONE */
1167 				continue;
1168 			cs4281_read_codec(sc, 2*i, &sc->ac97_reg[i>>1]);
1169 		}
1170 		/* should I powerdown here ? */
1171 		cs4281_write_codec(sc, AC97_REG_POWER, CS4281_POWER_DOWN_ALL);
1172 	} else {
1173 		if (sc->sc_suspend == PWR_RESUME) {
1174 			printf("cs4281_power: odd, resume without suspend.\n");
1175 			sc->sc_suspend = why;
1176 			return;
1177 		}
1178 		sc->sc_suspend = why;
1179 		cs4281_init(sc);
1180 		cs4281_reset_codec(sc);
1181 
1182 		/* restore ac97 registers */
1183 		for (i = 1; i <= CS4281_SAVE_REG_MAX; i++) {
1184 			if (i == 0x04)	/* AC97_REG_MASTER_TONE */
1185 				continue;
1186 			cs4281_write_codec(sc, 2*i, sc->ac97_reg[i>>1]);
1187 		}
1188 	}
1189 }
1190 
1191 void
1192 cs4281_reset_codec(void *addr)
1193 {
1194 	struct cs4281_softc *sc;
1195 	u_int16_t data;
1196 	u_int32_t dat32;
1197 	int n;
1198 
1199 	sc = addr;
1200 
1201 	DPRINTFN(3,("cs4281_reset_codec\n"));
1202 
1203 	/* Reset codec */
1204 	BA0WRITE4(sc, CS4281_ACCTL, 0);
1205 	delay(50);    /* delay 50us */
1206 
1207 	BA0WRITE4(sc, CS4281_SPMC, 0);
1208 	delay(100);	/* delay 100us */
1209 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN);
1210 #if defined(ENABLE_SECONDARY_CODEC)
1211 	BA0WRITE4(sc, CS4281_SPMC, SPMC_RSTN | SPCM_ASDIN2E);
1212 	BA0WRITE4(sc, CS4281_SERMC, SERMC_TCID);
1213 #endif
1214 	delay(50000);   /* XXX: delay 50ms */
1215 
1216 	/* Enable ASYNC generation */
1217 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN);
1218 
1219 	/* Wait for Codec ready. Linux driver wait 50ms here */
1220 	n = 0;
1221 	while((BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY) == 0) {
1222 		delay(100);
1223 		if (++n > 1000) {
1224 			printf("reset_codec: AC97 codec ready timeout\n");
1225 			return;
1226 		}
1227 	}
1228 #if defined(ENABLE_SECONDARY_CODEC)
1229 	/* secondary codec ready*/
1230 	n = 0;
1231 	while((BA0READ4(sc, CS4281_ACSTS2) & ACSTS2_CRDY2) == 0) {
1232 		delay(100);
1233 		if (++n > 1000)
1234 			return;
1235 	}
1236 #endif
1237 	/* Set the serial timing configuration */
1238 	/* XXX: undocumented but the Linux driver do this */
1239 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
1240 
1241 	/* Wait for Codec ready signal */
1242 	n = 0;
1243 	do {
1244 		delay(1000);
1245 		if (++n > 1000) {
1246 			printf("%s: Timeout waiting for Codec ready\n",
1247 			       sc->sc_dev.dv_xname);
1248 			return;
1249 		}
1250 		dat32 = BA0READ4(sc, CS4281_ACSTS) & ACSTS_CRDY;
1251 	} while (dat32 == 0);
1252 
1253 	/* Enable Valid Frame output on ASDOUT */
1254 	BA0WRITE4(sc, CS4281_ACCTL, ACCTL_ESYN | ACCTL_VFRM);
1255 
1256 	/* Wait until Codec Calibration is finished. Codec register 26h */
1257 	n = 0;
1258 	do {
1259 		delay(1);
1260 		if (++n > 1000) {
1261 			printf("%s: Timeout waiting for Codec calibration\n",
1262 			       sc->sc_dev.dv_xname);
1263 			return ;
1264 		}
1265 		cs4281_read_codec(sc, AC97_REG_POWER, &data);
1266 	} while ((data & 0x0f) != 0x0f);
1267 
1268 	/* Set the serial timing configuration again */
1269 	/* XXX: undocumented but the Linux driver do this */
1270 	BA0WRITE4(sc, CS4281_SERMC, SERMC_PTCAC97);
1271 
1272 	/* Wait until we've sampled input slots 3 & 4 as valid */
1273 	n = 0;
1274 	do {
1275 		delay(1000);
1276 		if (++n > 1000) {
1277 			printf("%s: Timeout waiting for sampled input slots as valid\n",
1278 			       sc->sc_dev.dv_xname);
1279 			return;
1280 		}
1281 		dat32 = BA0READ4(sc, CS4281_ACISV) & (ACISV_ISV3 | ACISV_ISV4) ;
1282 	} while (dat32 != (ACISV_ISV3 | ACISV_ISV4));
1283 
1284 	/* Start digital data transfer of audio data to the codec */
1285 	BA0WRITE4(sc, CS4281_ACOSV, (ACOSV_SLV3 | ACOSV_SLV4));
1286 }
1287 
1288 int
1289 cs4281_open(void *addr, int flags)
1290 {
1291 	return (0);
1292 }
1293 
1294 void
1295 cs4281_close(void *addr)
1296 {
1297 	struct cs4281_softc *sc;
1298 
1299 	sc = addr;
1300 
1301 	(*sc->halt_output)(sc);
1302 	(*sc->halt_input)(sc);
1303 
1304 	sc->sc_pintr = 0;
1305 	sc->sc_rintr = 0;
1306 }
1307 
1308 int
1309 cs4281_round_blocksize(void *addr, int blk)
1310 {
1311 	struct cs4281_softc *sc;
1312 	int retval;
1313 
1314 	DPRINTFN(5,("cs4281_round_blocksize blk=%d -> ", blk));
1315 
1316 	sc=addr;
1317 	if (blk < sc->hw_blocksize)
1318 		retval = sc->hw_blocksize;
1319 	else
1320 		retval = blk & -(sc->hw_blocksize);
1321 
1322 	DPRINTFN(5,("%d\n", retval));
1323 
1324 	return (retval);
1325 }
1326 
1327 int
1328 cs4281_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1329 {
1330 	struct cs4281_softc *sc;
1331 	int val;
1332 
1333 	sc = addr;
1334 	val = sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
1335 	DPRINTFN(3,("mixer_set_port: val=%d\n", val));
1336 	return (val);
1337 }
1338 
1339 int
1340 cs4281_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1341 {
1342 	struct cs4281_softc *sc;
1343 
1344 	sc = addr;
1345 	return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
1346 }
1347 
1348 
1349 int
1350 cs4281_query_devinfo(void *addr, mixer_devinfo_t *dip)
1351 {
1352 	struct cs4281_softc *sc;
1353 
1354 	sc = addr;
1355 	return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
1356 }
1357 
1358 void *
1359 cs4281_malloc(void *addr, int direction, size_t size, int pool, int flags)
1360 {
1361 	struct cs4281_softc *sc;
1362 	struct cs4281_dma   *p;
1363 	int error;
1364 
1365 	sc = addr;
1366 
1367 	p = malloc(sizeof(*p), pool, flags);
1368 	if (!p)
1369 		return (0);
1370 
1371 	error = cs4281_allocmem(sc, size, pool, flags, p);
1372 
1373 	if (error) {
1374 		free(p, pool);
1375 		return (0);
1376 	}
1377 
1378 	p->next = sc->sc_dmas;
1379 	sc->sc_dmas = p;
1380 	return (BUFADDR(p));
1381 }
1382 
1383 
1384 
1385 void
1386 cs4281_free(void *addr, void *ptr, int pool)
1387 {
1388 	struct cs4281_softc *sc;
1389 	struct cs4281_dma **pp, *p;
1390 
1391 	sc = addr;
1392 	for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
1393 		if (BUFADDR(p) == ptr) {
1394 			bus_dmamap_unload(sc->sc_dmatag, p->map);
1395 			bus_dmamap_destroy(sc->sc_dmatag, p->map);
1396 			bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1397 			bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1398 			free(p->dum, pool);
1399 			*pp = p->next;
1400 			free(p, pool);
1401 			return;
1402 		}
1403 	}
1404 }
1405 
1406 size_t
1407 cs4281_round_buffersize(void *addr, int direction, size_t size)
1408 {
1409 	/* The real dma buffersize are 4KB for CS4280
1410 	 * and 64kB/MAX_CHANNELS for CS4281.
1411 	 * But they are too small for high quality audio,
1412 	 * let the upper layer(audio) use a larger buffer.
1413 	 * (originally suggested by Lennart Augustsson.)
1414 	 */
1415 	return (size);
1416 }
1417 
1418 paddr_t
1419 cs4281_mappage(void *addr, void *mem, off_t off, int prot)
1420 {
1421 	struct cs4281_softc *sc;
1422 	struct cs4281_dma *p;
1423 
1424 	sc = addr;
1425 	if (off < 0)
1426 		return -1;
1427 
1428 	for (p = sc->sc_dmas; p && BUFADDR(p) != mem; p = p->next)
1429 		;
1430 
1431 	if (!p) {
1432 		DPRINTF(("cs4281_mappage: bad buffer address\n"));
1433 		return (-1);
1434 	}
1435 
1436 	return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, off, prot,
1437 	    BUS_DMA_WAITOK));
1438 }
1439 
1440 
1441 int
1442 cs4281_get_props(void *addr)
1443 {
1444 	int retval;
1445 
1446 	retval = AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
1447 #ifdef MMAP_READY
1448 	retval |= AUDIO_PROP_MMAP;
1449 #endif
1450 	return (retval);
1451 }
1452 
1453 /* AC97 */
1454 int
1455 cs4281_attach_codec(void *addr, struct ac97_codec_if *codec_if)
1456 {
1457 	struct cs4281_softc *sc;
1458 
1459 	DPRINTF(("cs4281_attach_codec:\n"));
1460 	sc = addr;
1461 	sc->codec_if = codec_if;
1462 	return (0);
1463 }
1464 
1465 
1466 int
1467 cs4281_read_codec(void *addr, u_int8_t ac97_addr, u_int16_t *ac97_data)
1468 {
1469 	struct cs4281_softc *sc;
1470 	u_int32_t acctl;
1471 	int n;
1472 
1473 	sc = addr;
1474 
1475 	DPRINTFN(5,("read_codec: add=0x%02x ", ac97_addr));
1476 	/*
1477 	 * Make sure that there is not data sitting around from a preivous
1478 	 * uncompleted access.
1479 	 */
1480 	BA0READ4(sc, CS4281_ACSDA);
1481 
1482 	/* Set up AC97 control registers. */
1483 	BA0WRITE4(sc, CS4281_ACCAD, ac97_addr);
1484 	BA0WRITE4(sc, CS4281_ACCDA, 0);
1485 
1486 	acctl = ACCTL_ESYN | ACCTL_VFRM | ACCTL_CRW  | ACCTL_DCV;
1487 	BA0WRITE4(sc, CS4281_ACCTL, acctl);
1488 
1489 	if (cs4281_src_wait(sc) < 0) {
1490 		printf("%s: AC97 read prob. (DCV!=0) for add=0x%0x\n",
1491 		       sc->sc_dev.dv_xname, ac97_addr);
1492 		return 1;
1493 	}
1494 
1495 	/* wait for valid status bit is active */
1496 	n = 0;
1497 	while ((BA0READ4(sc, CS4281_ACSTS) & ACSTS_VSTS) == 0) {
1498 		delay(1);
1499 		while (++n > 1000) {
1500 			printf("%s: AC97 read fail (VSTS==0) for add=0x%0x\n",
1501 			       sc->sc_dev.dv_xname, ac97_addr);
1502 			return 1;
1503 		}
1504 	}
1505 	*ac97_data = BA0READ4(sc, CS4281_ACSDA);
1506 	DPRINTFN(5,("data=0x%04x\n", *ac97_data));
1507 	return (0);
1508 }
1509 
1510 int
1511 cs4281_write_codec(void *addr, u_int8_t ac97_addr, u_int16_t ac97_data)
1512 {
1513 	struct cs4281_softc *sc;
1514 	u_int32_t acctl;
1515 
1516 	sc = addr;
1517 
1518 	DPRINTFN(5,("write_codec: add=0x%02x  data=0x%04x\n", ac97_addr, ac97_data));
1519 	BA0WRITE4(sc, CS4281_ACCAD, ac97_addr);
1520 	BA0WRITE4(sc, CS4281_ACCDA, ac97_data);
1521 
1522 	acctl = ACCTL_ESYN | ACCTL_VFRM | ACCTL_DCV;
1523 	BA0WRITE4(sc, CS4281_ACCTL, acctl);
1524 
1525 	if (cs4281_src_wait(sc) < 0) {
1526 		printf("%s: AC97 write fail (DCV!=0) for add=0x%02x data="
1527 		       "0x%04x\n", sc->sc_dev.dv_xname, ac97_addr, ac97_data);
1528 		return (1);
1529 	}
1530 	return (0);
1531 }
1532 
1533 int
1534 cs4281_allocmem(struct cs4281_softc *sc, size_t size, int pool, int flags,
1535 		struct cs4281_dma *p)
1536 {
1537 	int error;
1538 	size_t align;
1539 
1540 	align   = sc->dma_align;
1541 	p->size = sc->dma_size;
1542 	/* allocate memory for upper audio driver */
1543 	p->dum  = malloc(size, pool, flags);
1544 	if (!p->dum)
1545 		return (1);
1546 	error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
1547 				 p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
1548 				 &p->nsegs, BUS_DMA_NOWAIT);
1549 	if (error) {
1550 		printf("%s: unable to allocate dma. error=%d\n",
1551 		       sc->sc_dev.dv_xname, error);
1552 		return (error);
1553 	}
1554 
1555 	error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,
1556 			       &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
1557 	if (error) {
1558 		printf("%s: unable to map dma, error=%d\n",
1559 		       sc->sc_dev.dv_xname, error);
1560 		goto free;
1561 	}
1562 
1563 	error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
1564 				  0, BUS_DMA_NOWAIT, &p->map);
1565 	if (error) {
1566 		printf("%s: unable to create dma map, error=%d\n",
1567 		       sc->sc_dev.dv_xname, error);
1568 		goto unmap;
1569 	}
1570 
1571 	error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL,
1572 				BUS_DMA_NOWAIT);
1573 	if (error) {
1574 		printf("%s: unable to load dma map, error=%d\n",
1575 		       sc->sc_dev.dv_xname, error);
1576 		goto destroy;
1577 	}
1578 	return (0);
1579 
1580 destroy:
1581 	bus_dmamap_destroy(sc->sc_dmatag, p->map);
1582 unmap:
1583 	bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
1584 free:
1585 	bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
1586 	return (error);
1587 }
1588 
1589 
1590 int
1591 cs4281_src_wait(sc)
1592 	struct cs4281_softc *sc;
1593 {
1594 	int n;
1595 
1596 	n = 0;
1597 	while ((BA0READ4(sc, CS4281_ACCTL) & ACCTL_DCV)) {
1598 		delay(1000);
1599 		while (++n > 1000)
1600 			return (-1);
1601 	}
1602 	return (0);
1603 }
1604