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