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