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