xref: /freebsd/sys/dev/sound/pci/csapcm.c (revision a753ca9c3f0644611e7dfb453af61896fed6c897)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 1999 Seigo Tanimura
5  * All rights reserved.
6  *
7  * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in
8  * cwcealdr1.zip, the sample sources by Crystal Semiconductor.
9  * Copyright (c) 1996-1998 Crystal Semiconductor Corp.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #ifdef HAVE_KERNEL_OPTION_HEADERS
34 #include "opt_snd.h"
35 #endif
36 
37 #include <dev/sound/pcm/sound.h>
38 #include <dev/sound/pcm/ac97.h>
39 #include <dev/sound/pci/csareg.h>
40 #include <dev/sound/pci/csavar.h>
41 
42 #include <dev/pci/pcireg.h>
43 #include <dev/pci/pcivar.h>
44 
45 /* Buffer size on dma transfer. Fixed for CS416x. */
46 #define CS461x_BUFFSIZE   (4 * 1024)
47 
48 #define GOF_PER_SEC 200
49 
50 /* device private data */
51 struct csa_info;
52 
53 struct csa_chinfo {
54 	struct csa_info *parent;
55 	struct pcm_channel *channel;
56 	struct snd_dbuf *buffer;
57 	int dir;
58 	uint32_t fmt, spd;
59 	int dma;
60 };
61 
62 struct csa_info {
63 	csa_res		res; /* resource */
64 	void		*ih; /* Interrupt cookie */
65 	bus_dma_tag_t	parent_dmat; /* DMA tag */
66 	struct csa_bridgeinfo *binfo; /* The state of the parent. */
67 	struct csa_card *card;
68 
69 	int active;
70 	/* Contents of board's registers */
71 	unsigned long	pfie;
72 	unsigned long	pctl;
73 	unsigned long	cctl;
74 	struct csa_chinfo pch, rch;
75 	uint32_t	ac97[CS461x_AC97_NUMBER_RESTORE_REGS];
76 	uint32_t	ac97_powerdown;
77 	uint32_t	ac97_general_purpose;
78 };
79 
80 /* -------------------------------------------------------------------- */
81 
82 /* prototypes */
83 static int      csa_init(struct csa_info *);
84 static void     csa_intr(void *);
85 static void	csa_setplaysamplerate(csa_res *resp, unsigned long ulInRate);
86 static void	csa_setcapturesamplerate(csa_res *resp,
87 		    unsigned long ulOutRate);
88 static void	csa_startplaydma(struct csa_info *csa);
89 static void	csa_startcapturedma(struct csa_info *csa);
90 static void	csa_stopplaydma(struct csa_info *csa);
91 static void	csa_stopcapturedma(struct csa_info *csa);
92 static int	csa_startdsp(csa_res *resp);
93 static int	csa_stopdsp(csa_res *resp);
94 static int	csa_allocres(struct csa_info *scp, device_t dev);
95 static void	csa_releaseres(struct csa_info *scp, device_t dev);
96 static void	csa_ac97_suspend(struct csa_info *csa);
97 static void	csa_ac97_resume(struct csa_info *csa);
98 
99 static uint32_t csa_playfmt[] = {
100 	SND_FORMAT(AFMT_U8, 1, 0),
101 	SND_FORMAT(AFMT_U8, 2, 0),
102 	SND_FORMAT(AFMT_S8, 1, 0),
103 	SND_FORMAT(AFMT_S8, 2, 0),
104 	SND_FORMAT(AFMT_S16_LE, 1, 0),
105 	SND_FORMAT(AFMT_S16_LE, 2, 0),
106 	SND_FORMAT(AFMT_S16_BE, 1, 0),
107 	SND_FORMAT(AFMT_S16_BE, 2, 0),
108 	0
109 };
110 static struct pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0};
111 
112 static uint32_t csa_recfmt[] = {
113 	SND_FORMAT(AFMT_S16_LE, 1, 0),
114 	SND_FORMAT(AFMT_S16_LE, 2, 0),
115 	0
116 };
117 static struct pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
118 
119 /* -------------------------------------------------------------------- */
120 
121 static int
csa_active(struct csa_info * csa,int run)122 csa_active(struct csa_info *csa, int run)
123 {
124 	int old;
125 
126 	old = csa->active;
127 	csa->active += run;
128 
129 	if ((csa->active > 1) || (csa->active < -1))
130 		csa->active = 0;
131 	if (csa->card->active)
132 		return (csa->card->active(!(csa->active && old)));
133 
134 	return 0;
135 }
136 
137 /* -------------------------------------------------------------------- */
138 /* ac97 codec */
139 
140 static int
csa_rdcd(kobj_t obj,void * devinfo,int regno)141 csa_rdcd(kobj_t obj, void *devinfo, int regno)
142 {
143 	uint32_t data;
144 	struct csa_info *csa = (struct csa_info *)devinfo;
145 
146 	csa_active(csa, 1);
147 	if (csa_readcodec(&csa->res, regno + BA0_AC97_RESET, &data))
148 		data = 0;
149 	csa_active(csa, -1);
150 
151 	return data;
152 }
153 
154 static int
csa_wrcd(kobj_t obj,void * devinfo,int regno,uint32_t data)155 csa_wrcd(kobj_t obj, void *devinfo, int regno, uint32_t data)
156 {
157 	struct csa_info *csa = (struct csa_info *)devinfo;
158 
159 	csa_active(csa, 1);
160 	csa_writecodec(&csa->res, regno + BA0_AC97_RESET, data);
161 	csa_active(csa, -1);
162 
163 	return 0;
164 }
165 
166 static kobj_method_t csa_ac97_methods[] = {
167     	KOBJMETHOD(ac97_read,		csa_rdcd),
168     	KOBJMETHOD(ac97_write,		csa_wrcd),
169 	KOBJMETHOD_END
170 };
171 AC97_DECLARE(csa_ac97);
172 
173 static void
csa_setplaysamplerate(csa_res * resp,unsigned long ulInRate)174 csa_setplaysamplerate(csa_res *resp, unsigned long ulInRate)
175 {
176 	unsigned long ulTemp1, ulTemp2;
177 	unsigned long ulPhiIncr;
178 	unsigned long ulCorrectionPerGOF, ulCorrectionPerSec;
179 	unsigned long ulOutRate;
180 
181 	ulOutRate = 48000;
182 
183 	/*
184 	 * Compute the values used to drive the actual sample rate conversion.
185 	 * The following formulas are being computed, using inline assembly
186 	 * since we need to use 64 bit arithmetic to compute the values:
187 	 *
188 	 *     ulPhiIncr = floor((Fs,in * 2^26) / Fs,out)
189 	 *     ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) /
190 	 *                                GOF_PER_SEC)
191 	 *     ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
192 	 *                          GOF_PER_SEC * ulCorrectionPerGOF
193 	 *
194 	 * i.e.
195 	 *
196 	 *     ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
197 	 *     ulCorrectionPerGOF:ulCorrectionPerSec =
198 	 *         dividend:remainder(ulOther / GOF_PER_SEC)
199 	 */
200 	ulTemp1 = ulInRate << 16;
201 	ulPhiIncr = ulTemp1 / ulOutRate;
202 	ulTemp1 -= ulPhiIncr * ulOutRate;
203 	ulTemp1 <<= 10;
204 	ulPhiIncr <<= 10;
205 	ulTemp2 = ulTemp1 / ulOutRate;
206 	ulPhiIncr += ulTemp2;
207 	ulTemp1 -= ulTemp2 * ulOutRate;
208 	ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC;
209 	ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC;
210 	ulCorrectionPerSec = ulTemp1;
211 
212 	/*
213 	 * Fill in the SampleRateConverter control block.
214 	 */
215 	csa_writemem(resp, BA1_PSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF));
216 	csa_writemem(resp, BA1_PPI, ulPhiIncr);
217 }
218 
219 static void
csa_setcapturesamplerate(csa_res * resp,unsigned long ulOutRate)220 csa_setcapturesamplerate(csa_res *resp, unsigned long ulOutRate)
221 {
222 	unsigned long ulPhiIncr, ulCoeffIncr, ulTemp1, ulTemp2;
223 	unsigned long ulCorrectionPerGOF, ulCorrectionPerSec, ulInitialDelay;
224 	unsigned long dwFrameGroupLength, dwCnt;
225 	unsigned long ulInRate;
226 
227 	ulInRate = 48000;
228 
229 	/*
230 	 * We can only decimate by up to a factor of 1/9th the hardware rate.
231 	 * Return an error if an attempt is made to stray outside that limit.
232 	 */
233 	if((ulOutRate * 9) < ulInRate)
234 		return;
235 
236 	/*
237 	 * We can not capture at at rate greater than the Input Rate (48000).
238 	 * Return an error if an attempt is made to stray outside that limit.
239 	 */
240 	if(ulOutRate > ulInRate)
241 		return;
242 
243 	/*
244 	 * Compute the values used to drive the actual sample rate conversion.
245 	 * The following formulas are being computed, using inline assembly
246 	 * since we need to use 64 bit arithmetic to compute the values:
247 	 *
248 	 *     ulCoeffIncr = -floor((Fs,out * 2^23) / Fs,in)
249 	 *     ulPhiIncr = floor((Fs,in * 2^26) / Fs,out)
250 	 *     ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) /
251 	 *                                GOF_PER_SEC)
252 	 *     ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
253 	 *                          GOF_PER_SEC * ulCorrectionPerGOF
254 	 *     ulInitialDelay = ceil((24 * Fs,in) / Fs,out)
255 	 *
256 	 * i.e.
257 	 *
258 	 *     ulCoeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
259 	 *     ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
260 	 *     ulCorrectionPerGOF:ulCorrectionPerSec =
261 	 *         dividend:remainder(ulOther / GOF_PER_SEC)
262 	 *     ulInitialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
263 	 */
264 	ulTemp1 = ulOutRate << 16;
265 	ulCoeffIncr = ulTemp1 / ulInRate;
266 	ulTemp1 -= ulCoeffIncr * ulInRate;
267 	ulTemp1 <<= 7;
268 	ulCoeffIncr <<= 7;
269 	ulCoeffIncr += ulTemp1 / ulInRate;
270 	ulCoeffIncr ^= 0xFFFFFFFF;
271 	ulCoeffIncr++;
272 	ulTemp1 = ulInRate << 16;
273 	ulPhiIncr = ulTemp1 / ulOutRate;
274 	ulTemp1 -= ulPhiIncr * ulOutRate;
275 	ulTemp1 <<= 10;
276 	ulPhiIncr <<= 10;
277 	ulTemp2 = ulTemp1 / ulOutRate;
278 	ulPhiIncr += ulTemp2;
279 	ulTemp1 -= ulTemp2 * ulOutRate;
280 	ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC;
281 	ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC;
282 	ulCorrectionPerSec = ulTemp1;
283 	ulInitialDelay = ((ulInRate * 24) + ulOutRate - 1) / ulOutRate;
284 
285 	/*
286 	 * Fill in the VariDecimate control block.
287 	 */
288 	csa_writemem(resp, BA1_CSRC,
289 		     ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF));
290 	csa_writemem(resp, BA1_CCI, ulCoeffIncr);
291 	csa_writemem(resp, BA1_CD,
292 	     (((BA1_VARIDEC_BUF_1 + (ulInitialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
293 	csa_writemem(resp, BA1_CPI, ulPhiIncr);
294 
295 	/*
296 	 * Figure out the frame group length for the write back task.  Basically,
297 	 * this is just the factors of 24000 (2^6*3*5^3) that are not present in
298 	 * the output sample rate.
299 	 */
300 	dwFrameGroupLength = 1;
301 	for(dwCnt = 2; dwCnt <= 64; dwCnt *= 2)
302 	{
303 		if(((ulOutRate / dwCnt) * dwCnt) !=
304 		   ulOutRate)
305 		{
306 			dwFrameGroupLength *= 2;
307 		}
308 	}
309 	if(((ulOutRate / 3) * 3) !=
310 	   ulOutRate)
311 	{
312 		dwFrameGroupLength *= 3;
313 	}
314 	for(dwCnt = 5; dwCnt <= 125; dwCnt *= 5)
315 	{
316 		if(((ulOutRate / dwCnt) * dwCnt) !=
317 		   ulOutRate)
318 		{
319 			dwFrameGroupLength *= 5;
320 		}
321 	}
322 
323 	/*
324 	 * Fill in the WriteBack control block.
325 	 */
326 	csa_writemem(resp, BA1_CFG1, dwFrameGroupLength);
327 	csa_writemem(resp, BA1_CFG2, (0x00800000 | dwFrameGroupLength));
328 	csa_writemem(resp, BA1_CCST, 0x0000FFFF);
329 	csa_writemem(resp, BA1_CSPB, ((65536 * ulOutRate) / 24000));
330 	csa_writemem(resp, (BA1_CSPB + 4), 0x0000FFFF);
331 }
332 
333 static void
csa_startplaydma(struct csa_info * csa)334 csa_startplaydma(struct csa_info *csa)
335 {
336 	csa_res *resp;
337 	unsigned long ul;
338 
339 	if (!csa->pch.dma) {
340 		resp = &csa->res;
341 		ul = csa_readmem(resp, BA1_PCTL);
342 		ul &= 0x0000ffff;
343 		csa_writemem(resp, BA1_PCTL, ul | csa->pctl);
344 		csa_writemem(resp, BA1_PVOL, 0x80008000);
345 		csa->pch.dma = 1;
346 	}
347 }
348 
349 static void
csa_startcapturedma(struct csa_info * csa)350 csa_startcapturedma(struct csa_info *csa)
351 {
352 	csa_res *resp;
353 	unsigned long ul;
354 
355 	if (!csa->rch.dma) {
356 		resp = &csa->res;
357 		ul = csa_readmem(resp, BA1_CCTL);
358 		ul &= 0xffff0000;
359 		csa_writemem(resp, BA1_CCTL, ul | csa->cctl);
360 		csa_writemem(resp, BA1_CVOL, 0x80008000);
361 		csa->rch.dma = 1;
362 	}
363 }
364 
365 static void
csa_stopplaydma(struct csa_info * csa)366 csa_stopplaydma(struct csa_info *csa)
367 {
368 	csa_res *resp;
369 	unsigned long ul;
370 
371 	if (csa->pch.dma) {
372 		resp = &csa->res;
373 		ul = csa_readmem(resp, BA1_PCTL);
374 		csa->pctl = ul & 0xffff0000;
375 		csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff);
376 		csa_writemem(resp, BA1_PVOL, 0xffffffff);
377 		csa->pch.dma = 0;
378 
379 		/*
380 		 * The bitwise pointer of the serial FIFO in the DSP
381 		 * seems to make an error upon starting or stopping the
382 		 * DSP. Clear the FIFO and correct the pointer if we
383 		 * are not capturing.
384 		 */
385 		if (!csa->rch.dma) {
386 			csa_clearserialfifos(resp);
387 			csa_writeio(resp, BA0_SERBSP, 0);
388 		}
389 	}
390 }
391 
392 static void
csa_stopcapturedma(struct csa_info * csa)393 csa_stopcapturedma(struct csa_info *csa)
394 {
395 	csa_res *resp;
396 	unsigned long ul;
397 
398 	if (csa->rch.dma) {
399 		resp = &csa->res;
400 		ul = csa_readmem(resp, BA1_CCTL);
401 		csa->cctl = ul & 0x0000ffff;
402 		csa_writemem(resp, BA1_CCTL, ul & 0xffff0000);
403 		csa_writemem(resp, BA1_CVOL, 0xffffffff);
404 		csa->rch.dma = 0;
405 
406 		/*
407 		 * The bitwise pointer of the serial FIFO in the DSP
408 		 * seems to make an error upon starting or stopping the
409 		 * DSP. Clear the FIFO and correct the pointer if we
410 		 * are not playing.
411 		 */
412 		if (!csa->pch.dma) {
413 			csa_clearserialfifos(resp);
414 			csa_writeio(resp, BA0_SERBSP, 0);
415 		}
416 	}
417 }
418 
419 static int
csa_startdsp(csa_res * resp)420 csa_startdsp(csa_res *resp)
421 {
422 	int i;
423 	unsigned long ul;
424 
425 	/*
426 	 * Set the frame timer to reflect the number of cycles per frame.
427 	 */
428 	csa_writemem(resp, BA1_FRMT, 0xadf);
429 
430 	/*
431 	 * Turn on the run, run at frame, and DMA enable bits in the local copy of
432 	 * the SP control register.
433 	 */
434 	csa_writemem(resp, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
435 
436 	/*
437 	 * Wait until the run at frame bit resets itself in the SP control
438 	 * register.
439 	 */
440 	ul = 0;
441 	for (i = 0 ; i < 25 ; i++) {
442 		/*
443 		 * Wait a little bit, so we don't issue PCI reads too frequently.
444 		 */
445 		DELAY(50);
446 		/*
447 		 * Fetch the current value of the SP status register.
448 		 */
449 		ul = csa_readmem(resp, BA1_SPCR);
450 
451 		/*
452 		 * If the run at frame bit has reset, then stop waiting.
453 		 */
454 		if((ul & SPCR_RUNFR) == 0)
455 			break;
456 	}
457 	/*
458 	 * If the run at frame bit never reset, then return an error.
459 	 */
460 	if((ul & SPCR_RUNFR) != 0)
461 		return (EAGAIN);
462 
463 	return (0);
464 }
465 
466 static int
csa_stopdsp(csa_res * resp)467 csa_stopdsp(csa_res *resp)
468 {
469 	/*
470 	 * Turn off the run, run at frame, and DMA enable bits in
471 	 * the local copy of the SP control register.
472 	 */
473 	csa_writemem(resp, BA1_SPCR, 0);
474 
475 	return (0);
476 }
477 
478 static int
csa_setupchan(struct csa_chinfo * ch)479 csa_setupchan(struct csa_chinfo *ch)
480 {
481 	struct csa_info *csa = ch->parent;
482 	csa_res *resp = &csa->res;
483 	unsigned long pdtc, tmp;
484 
485 	if (ch->dir == PCMDIR_PLAY) {
486 		/* direction */
487 		csa_writemem(resp, BA1_PBA, ch->buffer->buf_addr);
488 
489 		/* format */
490 		csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f;
491 		if (!(ch->fmt & AFMT_SIGNED))
492 			csa->pfie |= 0x8000;
493 		if (ch->fmt & AFMT_BIGENDIAN)
494 			csa->pfie |= 0x4000;
495 		if (AFMT_CHANNEL(ch->fmt) < 2)
496 			csa->pfie |= 0x2000;
497 		if (ch->fmt & AFMT_8BIT)
498 			csa->pfie |= 0x1000;
499 		csa_writemem(resp, BA1_PFIE, csa->pfie);
500 
501 		tmp = 4;
502 		if (ch->fmt & AFMT_16BIT)
503 			tmp <<= 1;
504 		if (AFMT_CHANNEL(ch->fmt) > 1)
505 			tmp <<= 1;
506 		tmp--;
507 
508 		pdtc = csa_readmem(resp, BA1_PDTC) & ~0x000001ff;
509 		pdtc |= tmp;
510 		csa_writemem(resp, BA1_PDTC, pdtc);
511 
512 		/* rate */
513 		csa_setplaysamplerate(resp, ch->spd);
514 	} else if (ch->dir == PCMDIR_REC) {
515 		/* direction */
516 		csa_writemem(resp, BA1_CBA, ch->buffer->buf_addr);
517 
518 		/* format */
519 		csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
520 
521 		/* rate */
522 		csa_setcapturesamplerate(resp, ch->spd);
523 	}
524 	return 0;
525 }
526 
527 /* -------------------------------------------------------------------- */
528 /* channel interface */
529 
530 static void *
csachan_init(kobj_t obj,void * devinfo,struct snd_dbuf * b,struct pcm_channel * c,int dir)531 csachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
532 {
533 	struct csa_info *csa = devinfo;
534 	struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch;
535 
536 	ch->parent = csa;
537 	ch->channel = c;
538 	ch->buffer = b;
539 	ch->dir = dir;
540 	if (sndbuf_alloc(ch->buffer, csa->parent_dmat, 0, CS461x_BUFFSIZE) != 0)
541 		return NULL;
542 	return ch;
543 }
544 
545 static int
csachan_setformat(kobj_t obj,void * data,uint32_t format)546 csachan_setformat(kobj_t obj, void *data, uint32_t format)
547 {
548 	struct csa_chinfo *ch = data;
549 
550 	ch->fmt = format;
551 	return 0;
552 }
553 
554 static uint32_t
csachan_setspeed(kobj_t obj,void * data,uint32_t speed)555 csachan_setspeed(kobj_t obj, void *data, uint32_t speed)
556 {
557 	struct csa_chinfo *ch = data;
558 
559 	ch->spd = speed;
560 	return ch->spd; /* XXX calc real speed */
561 }
562 
563 static uint32_t
csachan_setblocksize(kobj_t obj,void * data,uint32_t blocksize)564 csachan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
565 {
566 	return CS461x_BUFFSIZE / 2;
567 }
568 
569 static int
csachan_trigger(kobj_t obj,void * data,int go)570 csachan_trigger(kobj_t obj, void *data, int go)
571 {
572 	struct csa_chinfo *ch = data;
573 	struct csa_info *csa = ch->parent;
574 
575 	if (!PCMTRIG_COMMON(go))
576 		return 0;
577 
578 	if (go == PCMTRIG_START) {
579 		csa_active(csa, 1);
580 		csa_setupchan(ch);
581 		if (ch->dir == PCMDIR_PLAY)
582 			csa_startplaydma(csa);
583 		else
584 			csa_startcapturedma(csa);
585 	} else {
586 		if (ch->dir == PCMDIR_PLAY)
587 			csa_stopplaydma(csa);
588 		else
589 			csa_stopcapturedma(csa);
590 		csa_active(csa, -1);
591 	}
592 	return 0;
593 }
594 
595 static uint32_t
csachan_getptr(kobj_t obj,void * data)596 csachan_getptr(kobj_t obj, void *data)
597 {
598 	struct csa_chinfo *ch = data;
599 	struct csa_info *csa = ch->parent;
600 	csa_res *resp;
601 	uint32_t ptr;
602 
603 	resp = &csa->res;
604 
605 	if (ch->dir == PCMDIR_PLAY) {
606 		ptr = csa_readmem(resp, BA1_PBA) - ch->buffer->buf_addr;
607 		if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
608 			ptr >>= 1;
609 	} else {
610 		ptr = csa_readmem(resp, BA1_CBA) - ch->buffer->buf_addr;
611 		if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0)
612 			ptr >>= 1;
613 	}
614 
615 	return (ptr);
616 }
617 
618 static struct pcmchan_caps *
csachan_getcaps(kobj_t obj,void * data)619 csachan_getcaps(kobj_t obj, void *data)
620 {
621 	struct csa_chinfo *ch = data;
622 	return (ch->dir == PCMDIR_PLAY)? &csa_playcaps : &csa_reccaps;
623 }
624 
625 static kobj_method_t csachan_methods[] = {
626     	KOBJMETHOD(channel_init,		csachan_init),
627     	KOBJMETHOD(channel_setformat,		csachan_setformat),
628     	KOBJMETHOD(channel_setspeed,		csachan_setspeed),
629     	KOBJMETHOD(channel_setblocksize,	csachan_setblocksize),
630     	KOBJMETHOD(channel_trigger,		csachan_trigger),
631     	KOBJMETHOD(channel_getptr,		csachan_getptr),
632     	KOBJMETHOD(channel_getcaps,		csachan_getcaps),
633 	KOBJMETHOD_END
634 };
635 CHANNEL_DECLARE(csachan);
636 
637 /* -------------------------------------------------------------------- */
638 /* The interrupt handler */
639 static void
csa_intr(void * p)640 csa_intr(void *p)
641 {
642 	struct csa_info *csa = p;
643 
644 	if ((csa->binfo->hisr & HISR_VC0) != 0)
645 		chn_intr(csa->pch.channel);
646 	if ((csa->binfo->hisr & HISR_VC1) != 0)
647 		chn_intr(csa->rch.channel);
648 }
649 
650 /* -------------------------------------------------------------------- */
651 
652 /*
653  * Probe and attach the card
654  */
655 
656 static int
csa_init(struct csa_info * csa)657 csa_init(struct csa_info *csa)
658 {
659 	csa_res *resp;
660 
661 	resp = &csa->res;
662 
663 	csa->pfie = 0;
664 	csa_stopplaydma(csa);
665 	csa_stopcapturedma(csa);
666 
667 	if (csa_startdsp(resp))
668 		return (1);
669 
670 	/* Crank up the power on the DAC and ADC. */
671 	csa_setplaysamplerate(resp, 8000);
672 	csa_setcapturesamplerate(resp, 8000);
673 	/* Set defaults */
674 	csa_writeio(resp, BA0_EGPIODR, EGPIODR_GPOE0);
675 	csa_writeio(resp, BA0_EGPIOPTR, EGPIOPTR_GPPT0);
676 	/* Power up amplifier */
677 	csa_writeio(resp, BA0_EGPIODR, csa_readio(resp, BA0_EGPIODR) |
678 		EGPIODR_GPOE2);
679 	csa_writeio(resp, BA0_EGPIOPTR, csa_readio(resp, BA0_EGPIOPTR) |
680 		EGPIOPTR_GPPT2);
681 
682 	return 0;
683 }
684 
685 /* Allocates resources. */
686 static int
csa_allocres(struct csa_info * csa,device_t dev)687 csa_allocres(struct csa_info *csa, device_t dev)
688 {
689 	csa_res *resp;
690 
691 	resp = &csa->res;
692 	if (resp->io == NULL) {
693 		resp->io = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
694 			&resp->io_rid, RF_ACTIVE);
695 		if (resp->io == NULL)
696 			return (1);
697 	}
698 	if (resp->mem == NULL) {
699 		resp->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
700 			&resp->mem_rid, RF_ACTIVE);
701 		if (resp->mem == NULL)
702 			return (1);
703 	}
704 	if (resp->irq == NULL) {
705 		resp->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
706 			&resp->irq_rid, RF_ACTIVE | RF_SHAREABLE);
707 		if (resp->irq == NULL)
708 			return (1);
709 	}
710 	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev),
711 			       /*alignment*/CS461x_BUFFSIZE,
712 			       /*boundary*/CS461x_BUFFSIZE,
713 			       /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
714 			       /*highaddr*/BUS_SPACE_MAXADDR,
715 			       /*filter*/NULL, /*filterarg*/NULL,
716 			       /*maxsize*/CS461x_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff,
717 			       /*flags*/0, /*lockfunc*/NULL, /*lockarg*/NULL,
718 			       &csa->parent_dmat) != 0)
719 		return (1);
720 
721 	return (0);
722 }
723 
724 /* Releases resources. */
725 static void
csa_releaseres(struct csa_info * csa,device_t dev)726 csa_releaseres(struct csa_info *csa, device_t dev)
727 {
728 	csa_res *resp;
729 
730 	KASSERT(csa != NULL, ("called with bogus resource structure"));
731 
732 	resp = &csa->res;
733 	if (resp->irq != NULL) {
734 		if (csa->ih)
735 			bus_teardown_intr(dev, resp->irq, csa->ih);
736 		bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq);
737 		resp->irq = NULL;
738 	}
739 	if (resp->io != NULL) {
740 		bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io);
741 		resp->io = NULL;
742 	}
743 	if (resp->mem != NULL) {
744 		bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem);
745 		resp->mem = NULL;
746 	}
747 	if (csa->parent_dmat != NULL) {
748 		bus_dma_tag_destroy(csa->parent_dmat);
749 		csa->parent_dmat = NULL;
750 	}
751 
752 	free(csa, M_DEVBUF);
753 }
754 
755 static int
pcmcsa_probe(device_t dev)756 pcmcsa_probe(device_t dev)
757 {
758 	char *s;
759 
760 	/* The parent device has already been probed. */
761 
762 	if (device_get_ivars(dev) == NULL)
763 		return (ENXIO);
764 
765 	s = "CS461x PCM Audio";
766 
767 	device_set_desc(dev, s);
768 	return (0);
769 }
770 
771 static int
pcmcsa_attach(device_t dev)772 pcmcsa_attach(device_t dev)
773 {
774 	struct csa_info *csa;
775 	csa_res *resp;
776 	char status[SND_STATUSLEN];
777 	struct ac97_info *codec;
778 
779 	csa = malloc(sizeof(*csa), M_DEVBUF, M_WAITOK | M_ZERO);
780 	csa->binfo = device_get_ivars(dev);
781 	/*
782 	 * Fake the status of DMA so that the initial value of
783 	 * PCTL and CCTL can be stored into csa->pctl and csa->cctl,
784 	 * respectively.
785 	 */
786 	csa->pch.dma = csa->rch.dma = 1;
787 	csa->active = 0;
788 	csa->card = csa->binfo->card;
789 
790 	/* Allocate the resources. */
791 	resp = &csa->res;
792 	resp->io_rid = PCIR_BAR(0);
793 	resp->mem_rid = PCIR_BAR(1);
794 	resp->irq_rid = 0;
795 	if (csa_allocres(csa, dev)) {
796 		csa_releaseres(csa, dev);
797 		return (ENXIO);
798 	}
799 
800 	csa_active(csa, 1);
801 	if (csa_init(csa)) {
802 		csa_releaseres(csa, dev);
803 		return (ENXIO);
804 	}
805 	codec = AC97_CREATE(dev, csa, csa_ac97);
806 	if (codec == NULL) {
807 		csa_releaseres(csa, dev);
808 		return (ENXIO);
809 	}
810 	if (csa->card->inv_eapd)
811 		ac97_setflags(codec, AC97_F_EAPD_INV);
812 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) {
813 		ac97_destroy(codec);
814 		csa_releaseres(csa, dev);
815 		return (ENXIO);
816 	}
817 
818 	snprintf(status, SND_STATUSLEN, "irq %jd on %s",
819 			rman_get_start(resp->irq),
820 			device_get_nameunit(device_get_parent(dev)));
821 
822 	/* Enable interrupt. */
823 	if (snd_setup_intr(dev, resp->irq, 0, csa_intr, csa, &csa->ih)) {
824 		ac97_destroy(codec);
825 		csa_releaseres(csa, dev);
826 		return (ENXIO);
827 	}
828 	csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f);
829 	csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
830 	csa_active(csa, -1);
831 
832 	pcm_init(dev, csa);
833 	pcm_addchan(dev, PCMDIR_REC, &csachan_class, csa);
834 	pcm_addchan(dev, PCMDIR_PLAY, &csachan_class, csa);
835 	if (pcm_register(dev, status)) {
836 		ac97_destroy(codec);
837 		csa_releaseres(csa, dev);
838 		return (ENXIO);
839 	}
840 
841 	return (0);
842 }
843 
844 static int
pcmcsa_detach(device_t dev)845 pcmcsa_detach(device_t dev)
846 {
847 	int r;
848 	struct csa_info *csa;
849 
850 	r = pcm_unregister(dev);
851 	if (r)
852 		return r;
853 
854 	csa = pcm_getdevinfo(dev);
855 	csa_releaseres(csa, dev);
856 
857 	return 0;
858 }
859 
860 static void
csa_ac97_suspend(struct csa_info * csa)861 csa_ac97_suspend(struct csa_info *csa)
862 {
863 	int count, i;
864 	uint32_t tmp;
865 
866 	for (count = 0x2, i=0;
867 	    (count <= CS461x_AC97_HIGHESTREGTORESTORE) &&
868 	    (i < CS461x_AC97_NUMBER_RESTORE_REGS);
869 	    count += 2, i++)
870 		csa_readcodec(&csa->res, BA0_AC97_RESET + count, &csa->ac97[i]);
871 
872 	/* mute the outputs */
873 	csa_writecodec(&csa->res, BA0_AC97_MASTER_VOLUME, 0x8000);
874 	csa_writecodec(&csa->res, BA0_AC97_HEADPHONE_VOLUME, 0x8000);
875 	csa_writecodec(&csa->res, BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
876 	csa_writecodec(&csa->res, BA0_AC97_PCM_OUT_VOLUME, 0x8000);
877 	/* save the registers that cause pops */
878 	csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &csa->ac97_powerdown);
879 	csa_readcodec(&csa->res, BA0_AC97_GENERAL_PURPOSE,
880 	    &csa->ac97_general_purpose);
881 
882 	/*
883 	 * And power down everything on the AC97 codec. Well, for now,
884 	 * only power down the DAC/ADC and MIXER VREFON components.
885 	 * trouble with removing VREF.
886 	 */
887 
888 	/* MIXVON */
889 	csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &tmp);
890 	csa_writecodec(&csa->res, BA0_AC97_POWERDOWN,
891 	    tmp | CS_AC97_POWER_CONTROL_MIXVON);
892 	/* ADC */
893 	csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &tmp);
894 	csa_writecodec(&csa->res, BA0_AC97_POWERDOWN,
895 	    tmp | CS_AC97_POWER_CONTROL_ADC);
896 	/* DAC */
897 	csa_readcodec(&csa->res, BA0_AC97_POWERDOWN, &tmp);
898 	csa_writecodec(&csa->res, BA0_AC97_POWERDOWN,
899 	    tmp | CS_AC97_POWER_CONTROL_DAC);
900 }
901 
902 static void
csa_ac97_resume(struct csa_info * csa)903 csa_ac97_resume(struct csa_info *csa)
904 {
905 	int count, i;
906 
907 	/*
908 	 * First, we restore the state of the general purpose register.  This
909 	 * contains the mic select (mic1 or mic2) and if we restore this after
910 	 * we restore the mic volume/boost state and mic2 was selected at
911 	 * suspend time, we will end up with a brief period of time where mic1
912 	 * is selected with the volume/boost settings for mic2, causing
913 	 * acoustic feedback.  So we restore the general purpose register
914 	 * first, thereby getting the correct mic selected before we restore
915 	 * the mic volume/boost.
916 	 */
917 	csa_writecodec(&csa->res, BA0_AC97_GENERAL_PURPOSE,
918 	    csa->ac97_general_purpose);
919 	/*
920 	 * Now, while the outputs are still muted, restore the state of power
921 	 * on the AC97 part.
922 	 */
923 	csa_writecodec(&csa->res, BA0_AC97_POWERDOWN, csa->ac97_powerdown);
924 	/*
925 	 * Restore just the first set of registers, from register number
926 	 * 0x02 to the register number that ulHighestRegToRestore specifies.
927 	 */
928 	for (count = 0x2, i=0;
929 	    (count <= CS461x_AC97_HIGHESTREGTORESTORE) &&
930 	    (i < CS461x_AC97_NUMBER_RESTORE_REGS);
931 	    count += 2, i++)
932 		csa_writecodec(&csa->res, BA0_AC97_RESET + count, csa->ac97[i]);
933 }
934 
935 static int
pcmcsa_suspend(device_t dev)936 pcmcsa_suspend(device_t dev)
937 {
938 	struct csa_info *csa;
939 	csa_res *resp;
940 
941 	csa = pcm_getdevinfo(dev);
942 	resp = &csa->res;
943 
944 	csa_active(csa, 1);
945 
946 	/* playback interrupt disable */
947 	csa_writemem(resp, BA1_PFIE,
948 	    (csa_readmem(resp, BA1_PFIE) & ~0x0000f03f) | 0x00000010);
949 	/* capture interrupt disable */
950 	csa_writemem(resp, BA1_CIE,
951 	    (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000011);
952 	csa_stopplaydma(csa);
953 	csa_stopcapturedma(csa);
954 
955 	csa_ac97_suspend(csa);
956 
957 	csa_resetdsp(resp);
958 
959 	csa_stopdsp(resp);
960 	/*
961 	 *  Power down the DAC and ADC.  For now leave the other areas on.
962 	 */
963 	csa_writecodec(&csa->res, BA0_AC97_POWERDOWN, 0x300);
964 	/*
965 	 *  Power down the PLL.
966 	 */
967 	csa_writemem(resp, BA0_CLKCR1, 0);
968 	/*
969 	 * Turn off the Processor by turning off the software clock
970 	 * enable flag in the clock control register.
971 	 */
972 	csa_writemem(resp, BA0_CLKCR1,
973 	    csa_readmem(resp, BA0_CLKCR1) & ~CLKCR1_SWCE);
974 
975 	csa_active(csa, -1);
976 
977 	return 0;
978 }
979 
980 static int
pcmcsa_resume(device_t dev)981 pcmcsa_resume(device_t dev)
982 {
983 	struct csa_info *csa;
984 	csa_res *resp;
985 
986 	csa = pcm_getdevinfo(dev);
987 	resp = &csa->res;
988 
989 	csa_active(csa, 1);
990 
991 	/* cs_hardware_init */
992 	csa_stopplaydma(csa);
993 	csa_stopcapturedma(csa);
994 	csa_ac97_resume(csa);
995 	if (csa_startdsp(resp))
996 		return (ENXIO);
997 	/* Enable interrupts on the part. */
998 	if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0)
999 		csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM);
1000 	/* playback interrupt enable */
1001 	csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f);
1002 	/* capture interrupt enable */
1003 	csa_writemem(resp, BA1_CIE,
1004 	    (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
1005 	/* cs_restart_part */
1006 	csa_setupchan(&csa->pch);
1007 	csa_startplaydma(csa);
1008 	csa_setupchan(&csa->rch);
1009 	csa_startcapturedma(csa);
1010 
1011 	csa_active(csa, -1);
1012 
1013 	return 0;
1014 }
1015 
1016 static device_method_t pcmcsa_methods[] = {
1017 	/* Device interface */
1018 	DEVMETHOD(device_probe , pcmcsa_probe ),
1019 	DEVMETHOD(device_attach, pcmcsa_attach),
1020 	DEVMETHOD(device_detach, pcmcsa_detach),
1021 	DEVMETHOD(device_suspend, pcmcsa_suspend),
1022 	DEVMETHOD(device_resume, pcmcsa_resume),
1023 
1024 	DEVMETHOD_END
1025 };
1026 
1027 static driver_t pcmcsa_driver = {
1028 	"pcm",
1029 	pcmcsa_methods,
1030 	PCM_SOFTC_SIZE,
1031 };
1032 
1033 DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, 0, 0);
1034 MODULE_DEPEND(snd_csapcm, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1035 MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1);
1036 MODULE_VERSION(snd_csapcm, 1);
1037