xref: /freebsd/sys/dev/sound/pci/csapcm.c (revision 77a0943ded95b9e6438f7db70c4a28e4d93946d4)
1 /*
2  * Copyright (c) 1999 Seigo Tanimura
3  * All rights reserved.
4  *
5  * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in
6  * cwcealdr1.zip, the sample sources by Crystal Semiconductor.
7  * Copyright (c) 1996-1998 Crystal Semiconductor Corp.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32 
33 #include <sys/soundcard.h>
34 #include <dev/sound/pcm/sound.h>
35 #include <dev/sound/pcm/ac97.h>
36 #include <dev/sound/chip.h>
37 #include <dev/sound/pci/csareg.h>
38 #include <dev/sound/pci/csavar.h>
39 
40 #include <pci/pcireg.h>
41 #include <pci/pcivar.h>
42 
43 /* device private data */
44 struct csa_info;
45 
46 struct csa_chinfo {
47 	struct csa_info *parent;
48 	pcm_channel *channel;
49 	snd_dbuf *buffer;
50 	int dir;
51 	u_int32_t fmt;
52 	int dma;
53 };
54 
55 struct csa_info {
56 	csa_res		res; /* resource */
57 	void		*ih; /* Interrupt cookie */
58 	bus_dma_tag_t	parent_dmat; /* DMA tag */
59 	struct csa_bridgeinfo *binfo; /* The state of the parent. */
60 
61 	/* Contents of board's registers */
62 	u_long		pfie;
63 	u_long		pctl;
64 	u_long		cctl;
65 	struct csa_chinfo pch, rch;
66 };
67 
68 /* -------------------------------------------------------------------- */
69 
70 /* prototypes */
71 static int      csa_init(struct csa_info *);
72 static void     csa_intr(void *);
73 static void	csa_setplaysamplerate(csa_res *resp, u_long ulInRate);
74 static void	csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate);
75 static void	csa_startplaydma(struct csa_info *csa);
76 static void	csa_startcapturedma(struct csa_info *csa);
77 static void	csa_stopplaydma(struct csa_info *csa);
78 static void	csa_stopcapturedma(struct csa_info *csa);
79 static void	csa_powerupadc(csa_res *resp);
80 static void	csa_powerupdac(csa_res *resp);
81 static int	csa_startdsp(csa_res *resp);
82 static int	csa_allocres(struct csa_info *scp, device_t dev);
83 static void	csa_releaseres(struct csa_info *scp, device_t dev);
84 
85 /* talk to the codec - called from ac97.c */
86 static u_int32_t csa_rdcd(void *, int);
87 static void  	 csa_wrcd(void *, int, u_int32_t);
88 
89 /* channel interface */
90 static void *csachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
91 static int csachan_setdir(void *data, int dir);
92 static int csachan_setformat(void *data, u_int32_t format);
93 static int csachan_setspeed(void *data, u_int32_t speed);
94 static int csachan_setblocksize(void *data, u_int32_t blocksize);
95 static int csachan_trigger(void *data, int go);
96 static int csachan_getptr(void *data);
97 static pcmchan_caps *csachan_getcaps(void *data);
98 
99 static u_int32_t csa_playfmt[] = {
100 	AFMT_U8,
101 	AFMT_STEREO | AFMT_U8,
102 	AFMT_S8,
103 	AFMT_STEREO | AFMT_S8,
104 	AFMT_S16_LE,
105 	AFMT_STEREO | AFMT_S16_LE,
106 	AFMT_S16_BE,
107 	AFMT_STEREO | AFMT_S16_BE,
108 	0
109 };
110 static pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0};
111 
112 static u_int32_t csa_recfmt[] = {
113 	AFMT_S16_LE,
114 	AFMT_STEREO | AFMT_S16_LE,
115 	0
116 };
117 static pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
118 
119 static pcm_channel csa_chantemplate = {
120 	csachan_init,
121 	csachan_setdir,
122 	csachan_setformat,
123 	csachan_setspeed,
124 	csachan_setblocksize,
125 	csachan_trigger,
126 	csachan_getptr,
127 	csachan_getcaps,
128 	NULL, 			/* free */
129 	NULL, 			/* nop1 */
130 	NULL, 			/* nop2 */
131 	NULL, 			/* nop3 */
132 	NULL, 			/* nop4 */
133 	NULL, 			/* nop5 */
134 	NULL, 			/* nop6 */
135 	NULL, 			/* nop7 */
136 };
137 
138 /* -------------------------------------------------------------------- */
139 
140 /* channel interface */
141 static void *
142 csachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
143 {
144 	struct csa_info *csa = devinfo;
145 	struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch;
146 
147 	ch->parent = csa;
148 	ch->channel = c;
149 	ch->buffer = b;
150 	ch->buffer->bufsize = CS461x_BUFFSIZE;
151 	if (chn_allocbuf(ch->buffer, csa->parent_dmat) == -1) return NULL;
152 	return ch;
153 }
154 
155 static int
156 csachan_setdir(void *data, int dir)
157 {
158 	struct csa_chinfo *ch = data;
159 	struct csa_info *csa = ch->parent;
160 	csa_res *resp;
161 
162 	resp = &csa->res;
163 
164 	if (dir == PCMDIR_PLAY)
165 		csa_writemem(resp, BA1_PBA, vtophys(ch->buffer->buf));
166 	else
167 		csa_writemem(resp, BA1_CBA, vtophys(ch->buffer->buf));
168 	ch->dir = dir;
169 	return 0;
170 }
171 
172 static int
173 csachan_setformat(void *data, u_int32_t format)
174 {
175 	struct csa_chinfo *ch = data;
176 	struct csa_info *csa = ch->parent;
177 	u_long pdtc;
178 	csa_res *resp;
179 
180 	resp = &csa->res;
181 
182 	if (ch->dir == PCMDIR_REC)
183 		csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
184 	else {
185 		csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f;
186 		if (format & AFMT_U8 || format & AFMT_U16_LE || format & AFMT_U16_BE)
187 			csa->pfie |= 0x8000;
188 		if (format & AFMT_S16_BE || format & AFMT_U16_BE)
189 			csa->pfie |= 0x4000;
190 		if (!(format & AFMT_STEREO))
191 			csa->pfie |= 0x2000;
192 		if (format & AFMT_U8 || format & AFMT_S8)
193 			csa->pfie |= 0x1000;
194 		csa_writemem(resp, BA1_PFIE, csa->pfie);
195 		pdtc = csa_readmem(resp, BA1_PDTC) & ~0x000003ff;
196 		if ((format & AFMT_S16_BE || format & AFMT_U16_BE || format & AFMT_S16_LE || format & AFMT_U16_LE) && (format & AFMT_STEREO))
197 			pdtc |= 0x00f;
198 		else if ((format & AFMT_S16_BE || format & AFMT_U16_BE || format & AFMT_S16_LE || format & AFMT_U16_LE) || (format & AFMT_STEREO))
199 			pdtc |= 0x007;
200 		else
201 			pdtc |= 0x003;
202 		csa_writemem(resp, BA1_PDTC, pdtc);
203 	}
204 	ch->fmt = format;
205 	return 0;
206 }
207 
208 static int
209 csachan_setspeed(void *data, u_int32_t speed)
210 {
211 	struct csa_chinfo *ch = data;
212 	struct csa_info *csa = ch->parent;
213 	csa_res *resp;
214 
215 	resp = &csa->res;
216 
217 	if (ch->dir == PCMDIR_PLAY)
218 		csa_setplaysamplerate(resp, speed);
219 	else if (ch->dir == PCMDIR_REC)
220 		csa_setcapturesamplerate(resp, speed);
221 
222 	/* rec/play speeds locked together - should indicate in flags */
223 #if 0
224 	if (ch->direction == PCMDIR_PLAY) d->rec[0].speed = speed;
225 	else d->play[0].speed = speed;
226 #endif
227 	return speed; /* XXX calc real speed */
228 }
229 
230 static void
231 csa_setplaysamplerate(csa_res *resp, u_long ulInRate)
232 {
233 	u_long ulTemp1, ulTemp2;
234 	u_long ulPhiIncr;
235 	u_long ulCorrectionPerGOF, ulCorrectionPerSec;
236 	u_long ulOutRate;
237 
238 	ulOutRate = 48000;
239 
240 	/*
241 	 * Compute the values used to drive the actual sample rate conversion.
242 	 * The following formulas are being computed, using inline assembly
243 	 * since we need to use 64 bit arithmetic to compute the values:
244 	 *
245 	 *     ulPhiIncr = floor((Fs,in * 2^26) / Fs,out)
246 	 *     ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) /
247 	 *                                GOF_PER_SEC)
248 	 *     ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
249 	 *                          GOF_PER_SEC * ulCorrectionPerGOF
250 	 *
251 	 * i.e.
252 	 *
253 	 *     ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
254 	 *     ulCorrectionPerGOF:ulCorrectionPerSec =
255 	 *         dividend:remainder(ulOther / GOF_PER_SEC)
256 	 */
257 	ulTemp1 = ulInRate << 16;
258 	ulPhiIncr = ulTemp1 / ulOutRate;
259 	ulTemp1 -= ulPhiIncr * ulOutRate;
260 	ulTemp1 <<= 10;
261 	ulPhiIncr <<= 10;
262 	ulTemp2 = ulTemp1 / ulOutRate;
263 	ulPhiIncr += ulTemp2;
264 	ulTemp1 -= ulTemp2 * ulOutRate;
265 	ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC;
266 	ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC;
267 	ulCorrectionPerSec = ulTemp1;
268 
269 	/*
270 	 * Fill in the SampleRateConverter control block.
271 	 */
272 	csa_writemem(resp, BA1_PSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF));
273 	csa_writemem(resp, BA1_PPI, ulPhiIncr);
274 }
275 
276 static void
277 csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate)
278 {
279 	u_long ulPhiIncr, ulCoeffIncr, ulTemp1, ulTemp2;
280 	u_long ulCorrectionPerGOF, ulCorrectionPerSec, ulInitialDelay;
281 	u_long dwFrameGroupLength, dwCnt;
282 	u_long ulInRate;
283 
284 	ulInRate = 48000;
285 
286 	/*
287 	 * We can only decimate by up to a factor of 1/9th the hardware rate.
288 	 * Return an error if an attempt is made to stray outside that limit.
289 	 */
290 	if((ulOutRate * 9) < ulInRate)
291 		return;
292 
293 	/*
294 	 * We can not capture at at rate greater than the Input Rate (48000).
295 	 * Return an error if an attempt is made to stray outside that limit.
296 	 */
297 	if(ulOutRate > ulInRate)
298 		return;
299 
300 	/*
301 	 * Compute the values used to drive the actual sample rate conversion.
302 	 * The following formulas are being computed, using inline assembly
303 	 * since we need to use 64 bit arithmetic to compute the values:
304 	 *
305 	 *     ulCoeffIncr = -floor((Fs,out * 2^23) / Fs,in)
306 	 *     ulPhiIncr = floor((Fs,in * 2^26) / Fs,out)
307 	 *     ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) /
308 	 *                                GOF_PER_SEC)
309 	 *     ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
310 	 *                          GOF_PER_SEC * ulCorrectionPerGOF
311 	 *     ulInitialDelay = ceil((24 * Fs,in) / Fs,out)
312 	 *
313 	 * i.e.
314 	 *
315 	 *     ulCoeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
316 	 *     ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
317 	 *     ulCorrectionPerGOF:ulCorrectionPerSec =
318 	 *         dividend:remainder(ulOther / GOF_PER_SEC)
319 	 *     ulInitialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
320 	 */
321 	ulTemp1 = ulOutRate << 16;
322 	ulCoeffIncr = ulTemp1 / ulInRate;
323 	ulTemp1 -= ulCoeffIncr * ulInRate;
324 	ulTemp1 <<= 7;
325 	ulCoeffIncr <<= 7;
326 	ulCoeffIncr += ulTemp1 / ulInRate;
327 	ulCoeffIncr ^= 0xFFFFFFFF;
328 	ulCoeffIncr++;
329 	ulTemp1 = ulInRate << 16;
330 	ulPhiIncr = ulTemp1 / ulOutRate;
331 	ulTemp1 -= ulPhiIncr * ulOutRate;
332 	ulTemp1 <<= 10;
333 	ulPhiIncr <<= 10;
334 	ulTemp2 = ulTemp1 / ulOutRate;
335 	ulPhiIncr += ulTemp2;
336 	ulTemp1 -= ulTemp2 * ulOutRate;
337 	ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC;
338 	ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC;
339 	ulCorrectionPerSec = ulTemp1;
340 	ulInitialDelay = ((ulInRate * 24) + ulOutRate - 1) / ulOutRate;
341 
342 	/*
343 	 * Fill in the VariDecimate control block.
344 	 */
345 	csa_writemem(resp, BA1_CSRC,
346 		     ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF));
347 	csa_writemem(resp, BA1_CCI, ulCoeffIncr);
348 	csa_writemem(resp, BA1_CD,
349 	     (((BA1_VARIDEC_BUF_1 + (ulInitialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
350 	csa_writemem(resp, BA1_CPI, ulPhiIncr);
351 
352 	/*
353 	 * Figure out the frame group length for the write back task.  Basically,
354 	 * this is just the factors of 24000 (2^6*3*5^3) that are not present in
355 	 * the output sample rate.
356 	 */
357 	dwFrameGroupLength = 1;
358 	for(dwCnt = 2; dwCnt <= 64; dwCnt *= 2)
359 	{
360 		if(((ulOutRate / dwCnt) * dwCnt) !=
361 		   ulOutRate)
362 		{
363 			dwFrameGroupLength *= 2;
364 		}
365 	}
366 	if(((ulOutRate / 3) * 3) !=
367 	   ulOutRate)
368 	{
369 		dwFrameGroupLength *= 3;
370 	}
371 	for(dwCnt = 5; dwCnt <= 125; dwCnt *= 5)
372 	{
373 		if(((ulOutRate / dwCnt) * dwCnt) !=
374 		   ulOutRate)
375 		{
376 			dwFrameGroupLength *= 5;
377 		}
378 	}
379 
380 	/*
381 	 * Fill in the WriteBack control block.
382 	 */
383 	csa_writemem(resp, BA1_CFG1, dwFrameGroupLength);
384 	csa_writemem(resp, BA1_CFG2, (0x00800000 | dwFrameGroupLength));
385 	csa_writemem(resp, BA1_CCST, 0x0000FFFF);
386 	csa_writemem(resp, BA1_CSPB, ((65536 * ulOutRate) / 24000));
387 	csa_writemem(resp, (BA1_CSPB + 4), 0x0000FFFF);
388 }
389 
390 static int
391 csachan_setblocksize(void *data, u_int32_t blocksize)
392 {
393 #if notdef
394 	return blocksize;
395 #else
396 	struct csa_chinfo *ch = data;
397 	return ch->buffer->bufsize / 2;
398 #endif /* notdef */
399 }
400 
401 static int
402 csachan_trigger(void *data, int go)
403 {
404 	struct csa_chinfo *ch = data;
405 	struct csa_info *csa = ch->parent;
406 
407 	if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
408 		return 0;
409 
410 	if (ch->dir == PCMDIR_PLAY) {
411 		if (go == PCMTRIG_START)
412 			csa_startplaydma(csa);
413 		else
414 			csa_stopplaydma(csa);
415 	} else {
416 		if (go == PCMTRIG_START)
417 			csa_startcapturedma(csa);
418 		else
419 			csa_stopcapturedma(csa);
420 	}
421 	return 0;
422 }
423 
424 static void
425 csa_startplaydma(struct csa_info *csa)
426 {
427 	csa_res *resp;
428 	u_long ul;
429 
430 	if (!csa->pch.dma) {
431 		resp = &csa->res;
432 		ul = csa_readmem(resp, BA1_PCTL);
433 		ul &= 0x0000ffff;
434 		csa_writemem(resp, BA1_PCTL, ul | csa->pctl);
435 		csa_writemem(resp, BA1_PVOL, 0x80008000);
436 		csa->pch.dma = 1;
437 	}
438 }
439 
440 static void
441 csa_startcapturedma(struct csa_info *csa)
442 {
443 	csa_res *resp;
444 	u_long ul;
445 
446 	if (!csa->rch.dma) {
447 		resp = &csa->res;
448 		ul = csa_readmem(resp, BA1_CCTL);
449 		ul &= 0xffff0000;
450 		csa_writemem(resp, BA1_CCTL, ul | csa->cctl);
451 		csa_writemem(resp, BA1_CVOL, 0x80008000);
452 		csa->rch.dma = 1;
453 	}
454 }
455 
456 static void
457 csa_stopplaydma(struct csa_info *csa)
458 {
459 	csa_res *resp;
460 	u_long ul;
461 
462 	if (csa->pch.dma) {
463 		resp = &csa->res;
464 		ul = csa_readmem(resp, BA1_PCTL);
465 		csa->pctl = ul & 0xffff0000;
466 		csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff);
467 		csa_writemem(resp, BA1_PVOL, 0xffffffff);
468 		csa->pch.dma = 0;
469 
470 		/*
471 		 * The bitwise pointer of the serial FIFO in the DSP
472 		 * seems to make an error upon starting or stopping the
473 		 * DSP. Clear the FIFO and correct the pointer if we
474 		 * are not capturing.
475 		 */
476 		if (!csa->rch.dma) {
477 			csa_clearserialfifos(resp);
478 			csa_writeio(resp, BA0_SERBSP, 0);
479 		}
480 	}
481 }
482 
483 static void
484 csa_stopcapturedma(struct csa_info *csa)
485 {
486 	csa_res *resp;
487 	u_long ul;
488 
489 	if (csa->rch.dma) {
490 		resp = &csa->res;
491 		ul = csa_readmem(resp, BA1_CCTL);
492 		csa->cctl = ul & 0x0000ffff;
493 		csa_writemem(resp, BA1_CCTL, ul & 0xffff0000);
494 		csa_writemem(resp, BA1_CVOL, 0xffffffff);
495 		csa->rch.dma = 0;
496 
497 		/*
498 		 * The bitwise pointer of the serial FIFO in the DSP
499 		 * seems to make an error upon starting or stopping the
500 		 * DSP. Clear the FIFO and correct the pointer if we
501 		 * are not playing.
502 		 */
503 		if (!csa->pch.dma) {
504 			csa_clearserialfifos(resp);
505 			csa_writeio(resp, BA0_SERBSP, 0);
506 		}
507 	}
508 }
509 
510 static void
511 csa_powerupdac(csa_res *resp)
512 {
513 	int i;
514 	u_long ul;
515 
516 	/*
517 	 * Power on the DACs on the AC97 codec.  We turn off the DAC
518 	 * powerdown bit and write the new value of the power control
519 	 * register.
520 	 */
521 	ul = csa_readio(resp, BA0_AC97_POWERDOWN);
522 	ul &= 0xfdff;
523 	csa_writeio(resp, BA0_AC97_POWERDOWN, ul);
524 
525 	/*
526 	 * Now, we wait until we sample a DAC ready state.
527 	 */
528 	for (i = 0 ; i < 32 ; i++) {
529 		/*
530 		 * First, lets wait a short while to let things settle out a
531 		 * bit, and to prevent retrying the read too quickly.
532 		 */
533 		DELAY(125);
534 
535 		/*
536 		 * Read the current state of the power control register.
537 		 */
538 		ul = csa_readio(resp, BA0_AC97_POWERDOWN);
539 
540 		/*
541 		 * If the DAC ready state bit is set, then stop waiting.
542 		 */
543 		if ((ul & 0x2) != 0)
544 			break;
545 	}
546 	/*
547 	 * The DACs are now calibrated, so we can unmute the DAC output.
548 	 */
549 	csa_writeio(resp, BA0_AC97_PCM_OUT_VOLUME, 0x0808);
550 }
551 
552 static void
553 csa_powerupadc(csa_res *resp)
554 {
555 	int i;
556 	u_long ul;
557 
558 	/*
559 	 * Power on the ADCs on the AC97 codec.  We turn off the ADC
560 	 * powerdown bit and write the new value of the power control
561 	 * register.
562 	 */
563 	ul = csa_readio(resp, BA0_AC97_POWERDOWN);
564 	ul &= 0xfeff;
565 	csa_writeio(resp, BA0_AC97_POWERDOWN, ul);
566 
567 	/*
568 	 * Now, we wait until we sample a ADC ready state.
569 	 */
570 	for (i = 0 ; i < 32 ; i++) {
571 		/*
572 		 * First, lets wait a short while to let things settle out a
573 		 * bit, and to prevent retrying the read too quickly.
574 		 */
575 		DELAY(125);
576 
577 		/*
578 		 * Read the current state of the power control register.
579 		 */
580 		ul = csa_readio(resp, BA0_AC97_POWERDOWN);
581 
582 		/*
583 		 * If the ADC ready state bit is set, then stop waiting.
584 		 */
585 		if ((ul & 0x1) != 0)
586 			break;
587 	}
588 }
589 
590 static int
591 csa_startdsp(csa_res *resp)
592 {
593 	int i;
594 	u_long ul;
595 
596 	/*
597 	 * Set the frame timer to reflect the number of cycles per frame.
598 	 */
599 	csa_writemem(resp, BA1_FRMT, 0xadf);
600 
601 	/*
602 	 * Turn on the run, run at frame, and DMA enable bits in the local copy of
603 	 * the SP control register.
604 	 */
605 	csa_writemem(resp, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
606 
607 	/*
608 	 * Wait until the run at frame bit resets itself in the SP control
609 	 * register.
610 	 */
611 	ul = 0;
612 	for (i = 0 ; i < 25 ; i++) {
613 		/*
614 		 * Wait a little bit, so we don't issue PCI reads too frequently.
615 		 */
616 #if notdef
617 		DELAY(1000);
618 #else
619 		DELAY(125);
620 #endif /* notdef */
621 		/*
622 		 * Fetch the current value of the SP status register.
623 		 */
624 		ul = csa_readmem(resp, BA1_SPCR);
625 
626 		/*
627 		 * If the run at frame bit has reset, then stop waiting.
628 		 */
629 		if((ul & SPCR_RUNFR) == 0)
630 			break;
631 	}
632 	/*
633 	 * If the run at frame bit never reset, then return an error.
634 	 */
635 	if((ul & SPCR_RUNFR) != 0)
636 		return (EAGAIN);
637 
638 	return (0);
639 }
640 
641 static int
642 csachan_getptr(void *data)
643 {
644 	struct csa_chinfo *ch = data;
645 	struct csa_info *csa = ch->parent;
646 	csa_res *resp;
647 	int ptr;
648 
649 	resp = &csa->res;
650 
651 	if (ch->dir == PCMDIR_PLAY) {
652 		ptr = csa_readmem(resp, BA1_PBA) - vtophys(ch->buffer->buf);
653 		if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
654 			ptr >>= 1;
655 	} else {
656 		ptr = csa_readmem(resp, BA1_CBA) - vtophys(ch->buffer->buf);
657 		if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
658 			ptr >>= 1;
659 	}
660 
661 	return (ptr);
662 }
663 
664 static pcmchan_caps *
665 csachan_getcaps(void *data)
666 {
667 	struct csa_chinfo *ch = data;
668 	return (ch->dir == PCMDIR_PLAY)? &csa_playcaps : &csa_reccaps;
669 }
670 
671 /* The interrupt handler */
672 static void
673 csa_intr (void *p)
674 {
675 	struct csa_info *csa = p;
676 
677 	if ((csa->binfo->hisr & HISR_VC0) != 0)
678 		chn_intr(csa->pch.channel);
679 	if ((csa->binfo->hisr & HISR_VC1) != 0)
680 		chn_intr(csa->rch.channel);
681 }
682 
683 /* -------------------------------------------------------------------- */
684 
685 /*
686  * Probe and attach the card
687  */
688 
689 static int
690 csa_init(struct csa_info *csa)
691 {
692 	csa_res *resp;
693 
694 	resp = &csa->res;
695 
696 	csa->pfie = 0;
697 	csa_stopplaydma(csa);
698 	csa_stopcapturedma(csa);
699 
700 	/* Crank up the power on the DAC and ADC. */
701 	csa_powerupadc(resp);
702 	csa_powerupdac(resp);
703 
704 	csa_setplaysamplerate(resp, 8000);
705 	csa_setcapturesamplerate(resp, 8000);
706 
707 	if (csa_startdsp(resp))
708 		return (1);
709 
710 	return 0;
711 }
712 
713 /* Allocates resources. */
714 static int
715 csa_allocres(struct csa_info *csa, device_t dev)
716 {
717 	csa_res *resp;
718 
719 	resp = &csa->res;
720 	if (resp->io == NULL) {
721 		resp->io = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->io_rid, 0, ~0, CS461x_IO_SIZE, RF_ACTIVE);
722 		if (resp->io == NULL)
723 			return (1);
724 	}
725 	if (resp->mem == NULL) {
726 		resp->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->mem_rid, 0, ~0, CS461x_MEM_SIZE, RF_ACTIVE);
727 		if (resp->mem == NULL)
728 			return (1);
729 	}
730 	if (resp->irq == NULL) {
731 		resp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &resp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
732 		if (resp->irq == NULL)
733 			return (1);
734 	}
735 	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/CS461x_BUFFSIZE, /*boundary*/CS461x_BUFFSIZE,
736 			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
737 			       /*highaddr*/BUS_SPACE_MAXADDR,
738 			       /*filter*/NULL, /*filterarg*/NULL,
739 			       /*maxsize*/CS461x_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff,
740 			       /*flags*/0, &csa->parent_dmat) != 0)
741 		return (1);
742 
743 	return (0);
744 }
745 
746 /* Releases resources. */
747 static void
748 csa_releaseres(struct csa_info *csa, device_t dev)
749 {
750 	csa_res *resp;
751 
752 	resp = &csa->res;
753 	if (resp->irq != NULL) {
754 		if (csa->ih)
755 			bus_teardown_intr(dev, resp->irq, csa->ih);
756 		bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq);
757 		resp->irq = NULL;
758 	}
759 	if (resp->io != NULL) {
760 		bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io);
761 		resp->io = NULL;
762 	}
763 	if (resp->mem != NULL) {
764 		bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem);
765 		resp->mem = NULL;
766 	}
767 	if (csa->parent_dmat != NULL) {
768 		bus_dma_tag_destroy(csa->parent_dmat);
769 		csa->parent_dmat = NULL;
770 	}
771 	if (csa != NULL) {
772 		free(csa, M_DEVBUF);
773 		csa = NULL;
774 	}
775 }
776 
777 static int pcmcsa_probe(device_t dev);
778 static int pcmcsa_attach(device_t dev);
779 
780 static int
781 pcmcsa_probe(device_t dev)
782 {
783 	char *s;
784 	struct sndcard_func *func;
785 
786 	/* The parent device has already been probed. */
787 
788 	func = device_get_ivars(dev);
789 	if (func == NULL || func->func != SCF_PCM)
790 		return (ENXIO);
791 
792 	s = "CS461x PCM Audio";
793 
794 	device_set_desc(dev, s);
795 	return (0);
796 }
797 
798 static int
799 pcmcsa_attach(device_t dev)
800 {
801 	struct csa_info *csa;
802 	csa_res *resp;
803 	int unit;
804 	char status[SND_STATUSLEN];
805 	struct ac97_info *codec;
806 	struct sndcard_func *func;
807 
808 	csa = malloc(sizeof(*csa), M_DEVBUF, M_NOWAIT);
809 	if (csa == NULL)
810 		return (ENOMEM);
811 	bzero(csa, sizeof(*csa));
812 	unit = device_get_unit(dev);
813 	func = device_get_ivars(dev);
814 	csa->binfo = func->varinfo;
815 	/*
816 	 * Fake the status of DMA so that the initial value of
817 	 * PCTL and CCTL can be stored into csa->pctl and csa->cctl,
818 	 * respectively.
819 	 */
820 	csa->pch.dma = csa->rch.dma = 1;
821 
822 	/* Allocate the resources. */
823 	resp = &csa->res;
824 	resp->io_rid = CS461x_IO_OFFSET;
825 	resp->mem_rid = CS461x_MEM_OFFSET;
826 	resp->irq_rid = 0;
827 	if (csa_allocres(csa, dev)) {
828 		csa_releaseres(csa, dev);
829 		return (ENXIO);
830 	}
831 
832 	if (csa_init(csa)) {
833 		csa_releaseres(csa, dev);
834 		return (ENXIO);
835 	}
836 	codec = ac97_create(dev, csa, NULL, csa_rdcd, csa_wrcd);
837 	if (codec == NULL) {
838 		csa_releaseres(csa, dev);
839 		return (ENXIO);
840 	}
841 	if (mixer_init(dev, &ac97_mixer, codec) == -1) {
842 		ac97_destroy(codec);
843 		csa_releaseres(csa, dev);
844 		return (ENXIO);
845 	}
846 
847 	snprintf(status, SND_STATUSLEN, "at irq %ld", rman_get_start(resp->irq));
848 
849 	/* Enable interrupt. */
850 	if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, csa, &csa->ih)) {
851 		ac97_destroy(codec);
852 		csa_releaseres(csa, dev);
853 		return (ENXIO);
854 	}
855 	csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f);
856 	csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
857 
858 	if (pcm_register(dev, csa, 1, 1)) {
859 		ac97_destroy(codec);
860 		csa_releaseres(csa, dev);
861 		return (ENXIO);
862 	}
863 	pcm_addchan(dev, PCMDIR_REC, &csa_chantemplate, csa);
864 	pcm_addchan(dev, PCMDIR_PLAY, &csa_chantemplate, csa);
865 	pcm_setstatus(dev, status);
866 
867 	return (0);
868 }
869 
870 static int
871 pcmcsa_detach(device_t dev)
872 {
873 	int r;
874 	struct csa_info *csa;
875 
876 	r = pcm_unregister(dev);
877 	if (r)
878 		return r;
879 
880 	csa = pcm_getdevinfo(dev);
881 	csa_releaseres(csa, dev);
882 
883 	return 0;
884 }
885 
886 /* ac97 codec */
887 
888 static u_int32_t
889 csa_rdcd(void *devinfo, int regno)
890 {
891 	u_int32_t data;
892 	struct csa_info *csa = (struct csa_info *)devinfo;
893 
894 	if (csa_readcodec(&csa->res, regno + BA0_AC97_RESET, &data))
895 		data = 0;
896 
897 	return data;
898 }
899 
900 static void
901 csa_wrcd(void *devinfo, int regno, u_int32_t data)
902 {
903 	struct csa_info *csa = (struct csa_info *)devinfo;
904 
905 	csa_writecodec(&csa->res, regno + BA0_AC97_RESET, data);
906 }
907 
908 static device_method_t pcmcsa_methods[] = {
909 	/* Device interface */
910 	DEVMETHOD(device_probe , pcmcsa_probe ),
911 	DEVMETHOD(device_attach, pcmcsa_attach),
912 	DEVMETHOD(device_detach, pcmcsa_detach),
913 
914 	{ 0, 0 },
915 };
916 
917 static driver_t pcmcsa_driver = {
918 	"pcm",
919 	pcmcsa_methods,
920 	sizeof(snddev_info),
921 };
922 
923 static devclass_t pcm_devclass;
924 
925 DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0);
926 MODULE_DEPEND(snd_csapcm, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
927 MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1);
928 MODULE_VERSION(snd_csapcm, 1);
929