1/*-
2 * Copyright (c) 2000 Cameron Grant <cg@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#ifdef HAVE_KERNEL_OPTION_HEADERS
28#include "opt_snd.h"
29#endif
30
31#include <dev/sound/pcm/sound.h>
32#include <dev/sound/pcm/ac97.h>
33
34#include <dev/pci/pcireg.h>
35#include <dev/pci/pcivar.h>
36
37#include <dev/sound/pci/ds1.h>
38#include <dev/sound/pci/ds1-fw.h>
39
40SND_DECLARE_FILE("$FreeBSD$");
41
42/* -------------------------------------------------------------------- */
43
44#define	DS1_CHANS 4
45#define DS1_RECPRIMARY 0
46#define DS1_IRQHZ ((48000 << 8) / 256)
47#define DS1_BUFFSIZE 4096
48
49struct pbank {
50	volatile u_int32_t	Format;
51	volatile u_int32_t	LoopDefault;
52	volatile u_int32_t	PgBase;
53	volatile u_int32_t	PgLoop;
54	volatile u_int32_t	PgLoopEnd;
55	volatile u_int32_t	PgLoopFrac;
56	volatile u_int32_t	PgDeltaEnd;
57	volatile u_int32_t	LpfKEnd;
58	volatile u_int32_t	EgGainEnd;
59	volatile u_int32_t	LchGainEnd;
60	volatile u_int32_t	RchGainEnd;
61	volatile u_int32_t	Effect1GainEnd;
62	volatile u_int32_t	Effect2GainEnd;
63	volatile u_int32_t	Effect3GainEnd;
64	volatile u_int32_t	LpfQ;
65	volatile u_int32_t	Status;
66	volatile u_int32_t	NumOfFrames;
67	volatile u_int32_t	LoopCount;
68	volatile u_int32_t	PgStart;
69	volatile u_int32_t	PgStartFrac;
70	volatile u_int32_t	PgDelta;
71	volatile u_int32_t	LpfK;
72	volatile u_int32_t	EgGain;
73	volatile u_int32_t	LchGain;
74	volatile u_int32_t	RchGain;
75	volatile u_int32_t	Effect1Gain;
76	volatile u_int32_t	Effect2Gain;
77	volatile u_int32_t	Effect3Gain;
78	volatile u_int32_t	LpfD1;
79	volatile u_int32_t	LpfD2;
80};
81
82struct rbank {
83	volatile u_int32_t	PgBase;
84	volatile u_int32_t	PgLoopEnd;
85	volatile u_int32_t	PgStart;
86	volatile u_int32_t	NumOfLoops;
87};
88
89struct sc_info;
90
91/* channel registers */
92struct sc_pchinfo {
93	int run, spd, dir, fmt;
94	struct snd_dbuf *buffer;
95	struct pcm_channel *channel;
96	volatile struct pbank *lslot, *rslot;
97	int lsnum, rsnum;
98	struct sc_info *parent;
99};
100
101struct sc_rchinfo {
102	int run, spd, dir, fmt, num;
103	struct snd_dbuf *buffer;
104	struct pcm_channel *channel;
105	volatile struct rbank *slot;
106	struct sc_info *parent;
107};
108
109/* device private data */
110struct sc_info {
111	device_t	dev;
112	u_int32_t 	type, rev;
113	u_int32_t	cd2id, ctrlbase;
114
115	bus_space_tag_t st;
116	bus_space_handle_t sh;
117	bus_dma_tag_t buffer_dmat, control_dmat;
118	bus_dmamap_t map;
119
120	struct resource *reg, *irq;
121	int		regid, irqid;
122	void		*ih;
123	struct mtx	*lock;
124
125	void *regbase;
126	u_int32_t *pbase, pbankbase, pbanksize;
127	volatile struct pbank *pbank[2 * 64];
128	volatile struct rbank *rbank;
129	int pslotfree, currbank, pchn, rchn;
130	unsigned int bufsz;
131
132	struct sc_pchinfo pch[DS1_CHANS];
133	struct sc_rchinfo rch[2];
134};
135
136struct {
137	u_int32_t dev, subdev;
138	char *name;
139	u_int32_t *mcode;
140} ds_devs[] = {
141	{0x00041073, 0, 		"Yamaha DS-1 (YMF724)", CntrlInst},
142	{0x000d1073, 0, 		"Yamaha DS-1E (YMF724F)", CntrlInst1E},
143	{0x00051073, 0, 		"Yamaha DS-1? (YMF734)", CntrlInst},
144	{0x00081073, 0, 		"Yamaha DS-1? (YMF737)", CntrlInst},
145	{0x00201073, 0, 		"Yamaha DS-1? (YMF738)", CntrlInst},
146	{0x00061073, 0, 		"Yamaha DS-1? (YMF738_TEG)", CntrlInst},
147	{0x000a1073, 0x00041073, 	"Yamaha DS-1 (YMF740)", CntrlInst},
148	{0x000a1073, 0x000a1073,  	"Yamaha DS-1 (YMF740B)", CntrlInst},
149	{0x000a1073, 0x53328086,	"Yamaha DS-1 (YMF740I)", CntrlInst},
150	{0x000a1073, 0, 		"Yamaha DS-1 (YMF740?)", CntrlInst},
151	{0x000c1073, 0, 		"Yamaha DS-1E (YMF740C)", CntrlInst1E},
152	{0x00101073, 0, 		"Yamaha DS-1E (YMF744)", CntrlInst1E},
153	{0x00121073, 0, 		"Yamaha DS-1E (YMF754)", CntrlInst1E},
154	{0, 0, NULL, NULL}
155};
156
157/* -------------------------------------------------------------------- */
158
159/*
160 * prototypes
161 */
162
163/* stuff */
164static int       ds_init(struct sc_info *);
165static void      ds_intr(void *);
166
167/* talk to the card */
168static u_int32_t ds_rd(struct sc_info *, int, int);
169static void 	 ds_wr(struct sc_info *, int, u_int32_t, int);
170
171/* -------------------------------------------------------------------- */
172
173static u_int32_t ds_recfmt[] = {
174	SND_FORMAT(AFMT_U8, 1, 0),
175	SND_FORMAT(AFMT_U8, 2, 0),
176	SND_FORMAT(AFMT_S8, 1, 0),
177	SND_FORMAT(AFMT_S8, 2, 0),
178	SND_FORMAT(AFMT_S16_LE, 1, 0),
179	SND_FORMAT(AFMT_S16_LE, 2, 0),
180	SND_FORMAT(AFMT_U16_LE, 1, 0),
181	SND_FORMAT(AFMT_U16_LE, 2, 0),
182	0
183};
184static struct pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0};
185
186static u_int32_t ds_playfmt[] = {
187	SND_FORMAT(AFMT_U8, 1, 0),
188	SND_FORMAT(AFMT_U8, 2, 0),
189	/* SND_FORMAT(AFMT_S16_LE, 1, 0), */
190	SND_FORMAT(AFMT_S16_LE, 2, 0),
191	0
192};
193static struct pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
194
195/* -------------------------------------------------------------------- */
196/* Hardware */
197static u_int32_t
198ds_rd(struct sc_info *sc, int regno, int size)
199{
200	switch (size) {
201	case 1:
202		return bus_space_read_1(sc->st, sc->sh, regno);
203	case 2:
204		return bus_space_read_2(sc->st, sc->sh, regno);
205	case 4:
206		return bus_space_read_4(sc->st, sc->sh, regno);
207	default:
208		return 0xffffffff;
209	}
210}
211
212static void
213ds_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
214{
215	switch (size) {
216	case 1:
217		bus_space_write_1(sc->st, sc->sh, regno, data);
218		break;
219	case 2:
220		bus_space_write_2(sc->st, sc->sh, regno, data);
221		break;
222	case 4:
223		bus_space_write_4(sc->st, sc->sh, regno, data);
224		break;
225	}
226}
227
228static void
229wrl(struct sc_info *sc, u_int32_t *ptr, u_int32_t val)
230{
231	*(volatile u_int32_t *)ptr = val;
232	bus_space_barrier(sc->st, sc->sh, 0, 0, BUS_SPACE_BARRIER_WRITE);
233}
234
235/* -------------------------------------------------------------------- */
236/* ac97 codec */
237static int
238ds_cdbusy(struct sc_info *sc, int sec)
239{
240	int i, reg;
241
242	reg = sec? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
243	i = YDSXG_AC97TIMEOUT;
244	while (i > 0) {
245		if (!(ds_rd(sc, reg, 2) & 0x8000))
246			return 0;
247		i--;
248	}
249	return ETIMEDOUT;
250}
251
252static u_int32_t
253ds_initcd(kobj_t obj, void *devinfo)
254{
255	struct sc_info *sc = (struct sc_info *)devinfo;
256	u_int32_t x;
257
258	x = pci_read_config(sc->dev, PCIR_DSXGCTRL, 1);
259	if (x & 0x03) {
260		pci_write_config(sc->dev, PCIR_DSXGCTRL, x & ~0x03, 1);
261		pci_write_config(sc->dev, PCIR_DSXGCTRL, x | 0x03, 1);
262		pci_write_config(sc->dev, PCIR_DSXGCTRL, x & ~0x03, 1);
263		/*
264		 * The YMF740 on some Intel motherboards requires a pretty
265		 * hefty delay after this reset for some reason...  Otherwise:
266		 * "pcm0: ac97 codec init failed"
267		 * Maybe this is needed for all YMF740's?
268		 * 400ms and 500ms here seem to work, 300ms does not.
269		 *
270		 * do it for all chips -cg
271		 */
272		DELAY(500000);
273	}
274
275	return ds_cdbusy(sc, 0)? 0 : 1;
276}
277
278static int
279ds_rdcd(kobj_t obj, void *devinfo, int regno)
280{
281	struct sc_info *sc = (struct sc_info *)devinfo;
282	int sec, cid, i;
283	u_int32_t cmd, reg;
284
285	sec = regno & 0x100;
286	regno &= 0xff;
287	cid = sec? (sc->cd2id << 8) : 0;
288	reg = sec? YDSXGR_SECSTATUSDATA : YDSXGR_PRISTATUSDATA;
289	if (sec && cid == 0)
290		return 0xffffffff;
291
292	cmd = YDSXG_AC97READCMD | cid | regno;
293	ds_wr(sc, YDSXGR_AC97CMDADR, cmd, 2);
294
295	if (ds_cdbusy(sc, sec))
296		return 0xffffffff;
297
298	if (sc->type == 11 && sc->rev < 2)
299		for (i = 0; i < 600; i++)
300			ds_rd(sc, reg, 2);
301
302	return ds_rd(sc, reg, 2);
303}
304
305static int
306ds_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
307{
308	struct sc_info *sc = (struct sc_info *)devinfo;
309	int sec, cid;
310	u_int32_t cmd;
311
312	sec = regno & 0x100;
313	regno &= 0xff;
314	cid = sec? (sc->cd2id << 8) : 0;
315	if (sec && cid == 0)
316		return ENXIO;
317
318	cmd = YDSXG_AC97WRITECMD | cid | regno;
319	cmd <<= 16;
320	cmd |= data;
321	ds_wr(sc, YDSXGR_AC97CMDDATA, cmd, 4);
322
323	return ds_cdbusy(sc, sec);
324}
325
326static kobj_method_t ds_ac97_methods[] = {
327    	KOBJMETHOD(ac97_init,		ds_initcd),
328    	KOBJMETHOD(ac97_read,		ds_rdcd),
329    	KOBJMETHOD(ac97_write,		ds_wrcd),
330	KOBJMETHOD_END
331};
332AC97_DECLARE(ds_ac97);
333
334/* -------------------------------------------------------------------- */
335
336static void
337ds_enadsp(struct sc_info *sc, int on)
338{
339	u_int32_t v, i;
340
341	v = on? 1 : 0;
342	if (on) {
343		ds_wr(sc, YDSXGR_CONFIG, 0x00000001, 4);
344	} else {
345		if (ds_rd(sc, YDSXGR_CONFIG, 4))
346			ds_wr(sc, YDSXGR_CONFIG, 0x00000000, 4);
347		i = YDSXG_WORKBITTIMEOUT;
348		while (i > 0) {
349			if (!(ds_rd(sc, YDSXGR_CONFIG, 4) & 0x00000002))
350				break;
351			i--;
352		}
353	}
354}
355
356static volatile struct pbank *
357ds_allocpslot(struct sc_info *sc)
358{
359	int slot;
360
361	if (sc->pslotfree > 63)
362		return NULL;
363	slot = sc->pslotfree++;
364	return sc->pbank[slot * 2];
365}
366
367static int
368ds_initpbank(volatile struct pbank *pb, int ch, int b16, int stereo, u_int32_t rate, bus_addr_t base, u_int32_t len)
369{
370	u_int32_t lv[] = {1, 1, 0, 0, 0};
371	u_int32_t rv[] = {1, 0, 1, 0, 0};
372	u_int32_t e1[] = {0, 0, 0, 0, 0};
373	u_int32_t e2[] = {1, 0, 0, 1, 0};
374	u_int32_t e3[] = {1, 0, 0, 0, 1};
375	int ss, i;
376	u_int32_t delta;
377
378	struct {
379		int rate, fK, fQ;
380	} speedinfo[] = {
381		{  100, 0x00570000, 0x35280000},
382		{ 2000, 0x06aa0000, 0x34a70000},
383		{ 8000, 0x18b20000, 0x32020000},
384		{11025, 0x20930000, 0x31770000},
385		{16000, 0x2b9a0000, 0x31390000},
386		{22050, 0x35a10000, 0x31c90000},
387		{32000, 0x3eaa0000, 0x33d00000},
388/*		{44100, 0x04646000, 0x370a0000},
389*/		{48000, 0x40000000, 0x40000000},
390	};
391
392	ss = b16? 1 : 0;
393	ss += stereo? 1 : 0;
394	delta = (65536 * rate) / 48000;
395	i = 0;
396	while (i < 7 && speedinfo[i].rate < rate)
397		i++;
398
399	pb->Format = stereo? 0x00010000 : 0;
400	pb->Format |= b16? 0 : 0x80000000;
401	pb->Format |= (stereo && (ch == 2 || ch == 4))? 0x00000001 : 0;
402	pb->LoopDefault = 0;
403	pb->PgBase = base;
404	pb->PgLoop = 0;
405	pb->PgLoopEnd = len >> ss;
406	pb->PgLoopFrac = 0;
407	pb->Status = 0;
408	pb->NumOfFrames = 0;
409	pb->LoopCount = 0;
410	pb->PgStart = 0;
411	pb->PgStartFrac = 0;
412	pb->PgDelta = pb->PgDeltaEnd = delta << 12;
413	pb->LpfQ = speedinfo[i].fQ;
414	pb->LpfK = pb->LpfKEnd = speedinfo[i].fK;
415	pb->LpfD1 = pb->LpfD2 = 0;
416	pb->EgGain = pb->EgGainEnd = 0x40000000;
417	pb->LchGain = pb->LchGainEnd = lv[ch] * 0x40000000;
418	pb->RchGain = pb->RchGainEnd = rv[ch] * 0x40000000;
419	pb->Effect1Gain = pb->Effect1GainEnd = e1[ch] * 0x40000000;
420	pb->Effect2Gain = pb->Effect2GainEnd = e2[ch] * 0x40000000;
421	pb->Effect3Gain = pb->Effect3GainEnd = e3[ch] * 0x40000000;
422
423	return 0;
424}
425
426static void
427ds_enapslot(struct sc_info *sc, int slot, int go)
428{
429	wrl(sc, &sc->pbase[slot + 1], go? (sc->pbankbase + 2 * slot * sc->pbanksize) : 0);
430	/* printf("pbase[%d] = 0x%x\n", slot + 1, go? (sc->pbankbase + 2 * slot * sc->pbanksize) : 0); */
431}
432
433static void
434ds_setuppch(struct sc_pchinfo *ch)
435{
436	int stereo, b16, c, sz;
437	bus_addr_t addr;
438
439	stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
440	b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
441	c = stereo? 1 : 0;
442	addr = sndbuf_getbufaddr(ch->buffer);
443	sz = sndbuf_getsize(ch->buffer);
444
445	ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, addr, sz);
446	ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, addr, sz);
447	ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, addr, sz);
448	ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, addr, sz);
449}
450
451static void
452ds_setuprch(struct sc_rchinfo *ch)
453{
454	struct sc_info *sc = ch->parent;
455	int stereo, b16, i, sz, pri;
456	u_int32_t x, y;
457	bus_addr_t addr;
458
459	stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
460	b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
461	addr = sndbuf_getbufaddr(ch->buffer);
462	sz = sndbuf_getsize(ch->buffer);
463	pri = (ch->num == DS1_RECPRIMARY)? 1 : 0;
464
465	for (i = 0; i < 2; i++) {
466		ch->slot[i].PgBase = addr;
467		ch->slot[i].PgLoopEnd = sz;
468		ch->slot[i].PgStart = 0;
469		ch->slot[i].NumOfLoops = 0;
470	}
471	x = (b16? 0x00 : 0x01) | (stereo? 0x02 : 0x00);
472	y = (48000 * 4096) / ch->spd;
473	y--;
474	/* printf("pri = %d, x = %d, y = %d\n", pri, x, y); */
475	ds_wr(sc, pri? YDSXGR_ADCFORMAT : YDSXGR_RECFORMAT, x, 4);
476	ds_wr(sc, pri? YDSXGR_ADCSLOTSR : YDSXGR_RECSLOTSR, y, 4);
477}
478
479/* -------------------------------------------------------------------- */
480/* play channel interface */
481static void *
482ds1pchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
483{
484	struct sc_info *sc = devinfo;
485	struct sc_pchinfo *ch;
486
487	KASSERT(dir == PCMDIR_PLAY, ("ds1pchan_init: bad direction"));
488
489	ch = &sc->pch[sc->pchn++];
490	ch->buffer = b;
491	ch->parent = sc;
492	ch->channel = c;
493	ch->dir = dir;
494	ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
495	ch->spd = 8000;
496	ch->run = 0;
497	if (sndbuf_alloc(ch->buffer, sc->buffer_dmat, 0, sc->bufsz) != 0)
498		return NULL;
499	else {
500		ch->lsnum = sc->pslotfree;
501		ch->lslot = ds_allocpslot(sc);
502		ch->rsnum = sc->pslotfree;
503		ch->rslot = ds_allocpslot(sc);
504		ds_setuppch(ch);
505		return ch;
506	}
507}
508
509static int
510ds1pchan_setformat(kobj_t obj, void *data, u_int32_t format)
511{
512	struct sc_pchinfo *ch = data;
513
514	ch->fmt = format;
515
516	return 0;
517}
518
519static u_int32_t
520ds1pchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
521{
522	struct sc_pchinfo *ch = data;
523
524	ch->spd = speed;
525
526	return speed;
527}
528
529static u_int32_t
530ds1pchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
531{
532	struct sc_pchinfo *ch = data;
533	struct sc_info *sc = ch->parent;
534	int drate;
535
536	/* irq rate is fixed at 187.5hz */
537	drate = ch->spd * sndbuf_getalign(ch->buffer);
538	blocksize = roundup2((drate << 8) / DS1_IRQHZ, 4);
539	sndbuf_resize(ch->buffer, sc->bufsz / blocksize, blocksize);
540
541	return blocksize;
542}
543
544/* semantic note: must start at beginning of buffer */
545static int
546ds1pchan_trigger(kobj_t obj, void *data, int go)
547{
548	struct sc_pchinfo *ch = data;
549	struct sc_info *sc = ch->parent;
550	int stereo;
551
552	if (!PCMTRIG_COMMON(go))
553		return 0;
554	stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
555	if (go == PCMTRIG_START) {
556		ch->run = 1;
557		ds_setuppch(ch);
558		ds_enapslot(sc, ch->lsnum, 1);
559		ds_enapslot(sc, ch->rsnum, stereo);
560		snd_mtxlock(sc->lock);
561		ds_wr(sc, YDSXGR_MODE, 0x00000003, 4);
562		snd_mtxunlock(sc->lock);
563	} else {
564		ch->run = 0;
565		/* ds_setuppch(ch); */
566		ds_enapslot(sc, ch->lsnum, 0);
567		ds_enapslot(sc, ch->rsnum, 0);
568	}
569
570	return 0;
571}
572
573static u_int32_t
574ds1pchan_getptr(kobj_t obj, void *data)
575{
576	struct sc_pchinfo *ch = data;
577	struct sc_info *sc = ch->parent;
578	volatile struct pbank *bank;
579	int ss;
580	u_int32_t ptr;
581
582	ss = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
583	ss += (ch->fmt & AFMT_16BIT)? 1 : 0;
584
585	bank = ch->lslot + sc->currbank;
586	/* printf("getptr: %d\n", bank->PgStart << ss); */
587	ptr = bank->PgStart;
588	ptr <<= ss;
589	return ptr;
590}
591
592static struct pcmchan_caps *
593ds1pchan_getcaps(kobj_t obj, void *data)
594{
595	return &ds_playcaps;
596}
597
598static kobj_method_t ds1pchan_methods[] = {
599    	KOBJMETHOD(channel_init,		ds1pchan_init),
600    	KOBJMETHOD(channel_setformat,		ds1pchan_setformat),
601    	KOBJMETHOD(channel_setspeed,		ds1pchan_setspeed),
602    	KOBJMETHOD(channel_setblocksize,	ds1pchan_setblocksize),
603    	KOBJMETHOD(channel_trigger,		ds1pchan_trigger),
604    	KOBJMETHOD(channel_getptr,		ds1pchan_getptr),
605    	KOBJMETHOD(channel_getcaps,		ds1pchan_getcaps),
606	KOBJMETHOD_END
607};
608CHANNEL_DECLARE(ds1pchan);
609
610/* -------------------------------------------------------------------- */
611/* record channel interface */
612static void *
613ds1rchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
614{
615	struct sc_info *sc = devinfo;
616	struct sc_rchinfo *ch;
617
618	KASSERT(dir == PCMDIR_REC, ("ds1rchan_init: bad direction"));
619
620	ch = &sc->rch[sc->rchn];
621	ch->num = sc->rchn++;
622	ch->buffer = b;
623	ch->parent = sc;
624	ch->channel = c;
625	ch->dir = dir;
626	ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
627	ch->spd = 8000;
628	if (sndbuf_alloc(ch->buffer, sc->buffer_dmat, 0, sc->bufsz) != 0)
629		return NULL;
630	else {
631		ch->slot = (ch->num == DS1_RECPRIMARY)? sc->rbank + 2: sc->rbank;
632		ds_setuprch(ch);
633		return ch;
634	}
635}
636
637static int
638ds1rchan_setformat(kobj_t obj, void *data, u_int32_t format)
639{
640	struct sc_rchinfo *ch = data;
641
642	ch->fmt = format;
643
644	return 0;
645}
646
647static u_int32_t
648ds1rchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
649{
650	struct sc_rchinfo *ch = data;
651
652	ch->spd = speed;
653
654	return speed;
655}
656
657static u_int32_t
658ds1rchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
659{
660	struct sc_rchinfo *ch = data;
661	struct sc_info *sc = ch->parent;
662	int drate;
663
664	/* irq rate is fixed at 187.5hz */
665	drate = ch->spd * sndbuf_getalign(ch->buffer);
666	blocksize = roundup2((drate << 8) / DS1_IRQHZ, 4);
667	sndbuf_resize(ch->buffer, sc->bufsz / blocksize, blocksize);
668
669	return blocksize;
670}
671
672/* semantic note: must start at beginning of buffer */
673static int
674ds1rchan_trigger(kobj_t obj, void *data, int go)
675{
676	struct sc_rchinfo *ch = data;
677	struct sc_info *sc = ch->parent;
678	u_int32_t x;
679
680	if (!PCMTRIG_COMMON(go))
681		return 0;
682	if (go == PCMTRIG_START) {
683		ch->run = 1;
684		ds_setuprch(ch);
685		snd_mtxlock(sc->lock);
686		x = ds_rd(sc, YDSXGR_MAPOFREC, 4);
687		x |= (ch->num == DS1_RECPRIMARY)? 0x02 : 0x01;
688		ds_wr(sc, YDSXGR_MAPOFREC, x, 4);
689		ds_wr(sc, YDSXGR_MODE, 0x00000003, 4);
690		snd_mtxunlock(sc->lock);
691	} else {
692		ch->run = 0;
693		snd_mtxlock(sc->lock);
694		x = ds_rd(sc, YDSXGR_MAPOFREC, 4);
695		x &= ~((ch->num == DS1_RECPRIMARY)? 0x02 : 0x01);
696		ds_wr(sc, YDSXGR_MAPOFREC, x, 4);
697		snd_mtxunlock(sc->lock);
698	}
699
700	return 0;
701}
702
703static u_int32_t
704ds1rchan_getptr(kobj_t obj, void *data)
705{
706	struct sc_rchinfo *ch = data;
707	struct sc_info *sc = ch->parent;
708
709	return ch->slot[sc->currbank].PgStart;
710}
711
712static struct pcmchan_caps *
713ds1rchan_getcaps(kobj_t obj, void *data)
714{
715	return &ds_reccaps;
716}
717
718static kobj_method_t ds1rchan_methods[] = {
719    	KOBJMETHOD(channel_init,		ds1rchan_init),
720    	KOBJMETHOD(channel_setformat,		ds1rchan_setformat),
721    	KOBJMETHOD(channel_setspeed,		ds1rchan_setspeed),
722    	KOBJMETHOD(channel_setblocksize,	ds1rchan_setblocksize),
723    	KOBJMETHOD(channel_trigger,		ds1rchan_trigger),
724    	KOBJMETHOD(channel_getptr,		ds1rchan_getptr),
725    	KOBJMETHOD(channel_getcaps,		ds1rchan_getcaps),
726	KOBJMETHOD_END
727};
728CHANNEL_DECLARE(ds1rchan);
729
730/* -------------------------------------------------------------------- */
731/* The interrupt handler */
732static void
733ds_intr(void *p)
734{
735	struct sc_info *sc = (struct sc_info *)p;
736	u_int32_t i, x;
737
738	snd_mtxlock(sc->lock);
739	i = ds_rd(sc, YDSXGR_STATUS, 4);
740	if (i & 0x00008000)
741		device_printf(sc->dev, "timeout irq\n");
742	if (i & 0x80008000) {
743		ds_wr(sc, YDSXGR_STATUS, i & 0x80008000, 4);
744		sc->currbank = ds_rd(sc, YDSXGR_CTRLSELECT, 4) & 0x00000001;
745
746		x = 0;
747		for (i = 0; i < DS1_CHANS; i++) {
748			if (sc->pch[i].run) {
749				x = 1;
750				snd_mtxunlock(sc->lock);
751				chn_intr(sc->pch[i].channel);
752				snd_mtxlock(sc->lock);
753			}
754		}
755		for (i = 0; i < 2; i++) {
756			if (sc->rch[i].run) {
757				x = 1;
758				snd_mtxunlock(sc->lock);
759				chn_intr(sc->rch[i].channel);
760				snd_mtxlock(sc->lock);
761			}
762		}
763		i = ds_rd(sc, YDSXGR_MODE, 4);
764		if (x)
765			ds_wr(sc, YDSXGR_MODE, i | 0x00000002, 4);
766
767	}
768	snd_mtxunlock(sc->lock);
769}
770
771/* -------------------------------------------------------------------- */
772
773/*
774 * Probe and attach the card
775 */
776
777static void
778ds_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
779{
780	struct sc_info *sc = arg;
781
782	sc->ctrlbase = error? 0 : (u_int32_t)segs->ds_addr;
783
784	if (bootverbose) {
785		printf("ds1: setmap (%lx, %lx), nseg=%d, error=%d\n",
786		       (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
787		       nseg, error);
788	}
789}
790
791static int
792ds_init(struct sc_info *sc)
793{
794	int i;
795	u_int32_t *ci, r, pcs, rcs, ecs, ws, memsz, cb;
796	u_int8_t *t;
797	void *buf;
798
799	ci = ds_devs[sc->type].mcode;
800
801	ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4);
802	ds_enadsp(sc, 0);
803	ds_wr(sc, YDSXGR_MODE, 0x00010000, 4);
804	ds_wr(sc, YDSXGR_MODE, 0x00000000, 4);
805	ds_wr(sc, YDSXGR_MAPOFREC, 0x00000000, 4);
806	ds_wr(sc, YDSXGR_MAPOFEFFECT, 0x00000000, 4);
807	ds_wr(sc, YDSXGR_PLAYCTRLBASE, 0x00000000, 4);
808	ds_wr(sc, YDSXGR_RECCTRLBASE, 0x00000000, 4);
809	ds_wr(sc, YDSXGR_EFFCTRLBASE, 0x00000000, 4);
810	r = ds_rd(sc, YDSXGR_GLOBALCTRL, 2);
811	ds_wr(sc, YDSXGR_GLOBALCTRL, r & ~0x0007, 2);
812
813	for (i = 0; i < YDSXG_DSPLENGTH; i += 4)
814		ds_wr(sc, YDSXGR_DSPINSTRAM + i, DspInst[i >> 2], 4);
815
816	for (i = 0; i < YDSXG_CTRLLENGTH; i += 4)
817		ds_wr(sc, YDSXGR_CTRLINSTRAM + i, ci[i >> 2], 4);
818
819	ds_enadsp(sc, 1);
820
821	pcs = 0;
822	for (i = 100; i > 0; i--) {
823		pcs = ds_rd(sc, YDSXGR_PLAYCTRLSIZE, 4) << 2;
824		if (pcs == sizeof(struct pbank))
825			break;
826		DELAY(1000);
827	}
828	if (pcs != sizeof(struct pbank)) {
829		device_printf(sc->dev, "preposterous playctrlsize (%d)\n", pcs);
830		return -1;
831	}
832	rcs = ds_rd(sc, YDSXGR_RECCTRLSIZE, 4) << 2;
833	ecs = ds_rd(sc, YDSXGR_EFFCTRLSIZE, 4) << 2;
834	ws = ds_rd(sc, YDSXGR_WORKSIZE, 4) << 2;
835
836	memsz = 64 * 2 * pcs + 2 * 2 * rcs + 5 * 2 * ecs + ws;
837	memsz += (64 + 1) * 4;
838
839	if (sc->regbase == NULL) {
840		if (bus_dma_tag_create(bus_get_dma_tag(sc->dev), 2, 0,
841				       BUS_SPACE_MAXADDR_32BIT,
842				       BUS_SPACE_MAXADDR,
843				       NULL, NULL, memsz, 1, memsz, 0, NULL,
844				       NULL, &sc->control_dmat))
845			return -1;
846		if (bus_dmamem_alloc(sc->control_dmat, &buf, BUS_DMA_NOWAIT, &sc->map))
847			return -1;
848		if (bus_dmamap_load(sc->control_dmat, sc->map, buf, memsz, ds_setmap, sc, 0) || !sc->ctrlbase) {
849			device_printf(sc->dev, "pcs=%d, rcs=%d, ecs=%d, ws=%d, memsz=%d\n",
850			      	      pcs, rcs, ecs, ws, memsz);
851			return -1;
852		}
853		sc->regbase = buf;
854	} else
855		buf = sc->regbase;
856
857	cb = 0;
858	t = buf;
859	ds_wr(sc, YDSXGR_WORKBASE, sc->ctrlbase + cb, 4);
860	cb += ws;
861	sc->pbase = (u_int32_t *)(t + cb);
862	/* printf("pbase = %p -> 0x%x\n", sc->pbase, sc->ctrlbase + cb); */
863	ds_wr(sc, YDSXGR_PLAYCTRLBASE, sc->ctrlbase + cb, 4);
864	cb += (64 + 1) * 4;
865	sc->rbank = (struct rbank *)(t + cb);
866	ds_wr(sc, YDSXGR_RECCTRLBASE, sc->ctrlbase + cb, 4);
867	cb += 2 * 2 * rcs;
868	ds_wr(sc, YDSXGR_EFFCTRLBASE, sc->ctrlbase + cb, 4);
869	cb += 5 * 2 * ecs;
870
871	sc->pbankbase = sc->ctrlbase + cb;
872	sc->pbanksize = pcs;
873	for (i = 0; i < 64; i++) {
874		wrl(sc, &sc->pbase[i + 1], 0);
875		sc->pbank[i * 2] = (struct pbank *)(t + cb);
876		/* printf("pbank[%d] = %p -> 0x%x; ", i * 2, (struct pbank *)(t + cb), sc->ctrlbase + cb - vtophys(t + cb)); */
877		cb += pcs;
878		sc->pbank[i * 2 + 1] = (struct pbank *)(t + cb);
879		/* printf("pbank[%d] = %p -> 0x%x\n", i * 2 + 1, (struct pbank *)(t + cb), sc->ctrlbase + cb - vtophys(t + cb)); */
880		cb += pcs;
881	}
882	wrl(sc, &sc->pbase[0], DS1_CHANS * 2);
883
884	sc->pchn = sc->rchn = 0;
885	ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff, 4);
886	ds_wr(sc, YDSXGR_NATIVEADCINVOL, 0x3fff3fff, 4);
887	ds_wr(sc, YDSXGR_NATIVEDACINVOL, 0x3fff3fff, 4);
888
889	return 0;
890}
891
892static int
893ds_uninit(struct sc_info *sc)
894{
895	ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4);
896	ds_wr(sc, YDSXGR_NATIVEADCINVOL, 0, 4);
897	ds_wr(sc, YDSXGR_NATIVEDACINVOL, 0, 4);
898	ds_enadsp(sc, 0);
899	ds_wr(sc, YDSXGR_MODE, 0x00010000, 4);
900	ds_wr(sc, YDSXGR_MAPOFREC, 0x00000000, 4);
901	ds_wr(sc, YDSXGR_MAPOFEFFECT, 0x00000000, 4);
902	ds_wr(sc, YDSXGR_PLAYCTRLBASE, 0x00000000, 4);
903	ds_wr(sc, YDSXGR_RECCTRLBASE, 0x00000000, 4);
904	ds_wr(sc, YDSXGR_EFFCTRLBASE, 0x00000000, 4);
905	ds_wr(sc, YDSXGR_GLOBALCTRL, 0, 2);
906
907	bus_dmamap_unload(sc->control_dmat, sc->map);
908	bus_dmamem_free(sc->control_dmat, sc->regbase, sc->map);
909
910	return 0;
911}
912
913static int
914ds_finddev(u_int32_t dev, u_int32_t subdev)
915{
916	int i;
917
918	for (i = 0; ds_devs[i].dev; i++) {
919		if (ds_devs[i].dev == dev &&
920		    (ds_devs[i].subdev == subdev || ds_devs[i].subdev == 0))
921			return i;
922	}
923	return -1;
924}
925
926static int
927ds_pci_probe(device_t dev)
928{
929	int i;
930	u_int32_t subdev;
931
932	subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
933	i = ds_finddev(pci_get_devid(dev), subdev);
934	if (i >= 0) {
935		device_set_desc(dev, ds_devs[i].name);
936		return BUS_PROBE_DEFAULT;
937	} else
938		return ENXIO;
939}
940
941static int
942ds_pci_attach(device_t dev)
943{
944	u_int32_t subdev, i;
945	struct sc_info *sc;
946	struct ac97_info *codec = NULL;
947	char 		status[SND_STATUSLEN];
948
949	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
950	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_ds1 softc");
951	sc->dev = dev;
952	subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
953	sc->type = ds_finddev(pci_get_devid(dev), subdev);
954	sc->rev = pci_get_revid(dev);
955
956	pci_enable_busmaster(dev);
957
958	sc->regid = PCIR_BAR(0);
959	sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->regid,
960					 RF_ACTIVE);
961	if (!sc->reg) {
962		device_printf(dev, "unable to map register space\n");
963		goto bad;
964	}
965
966	sc->st = rman_get_bustag(sc->reg);
967	sc->sh = rman_get_bushandle(sc->reg);
968
969	sc->bufsz = pcm_getbuffersize(dev, 4096, DS1_BUFFSIZE, 65536);
970
971	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
972		/*boundary*/0,
973		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
974		/*highaddr*/BUS_SPACE_MAXADDR,
975		/*filter*/NULL, /*filterarg*/NULL,
976		/*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
977		/*flags*/0, /*lockfunc*/NULL,
978		/*lockarg*/NULL, &sc->buffer_dmat) != 0) {
979		device_printf(dev, "unable to create dma tag\n");
980		goto bad;
981	}
982
983	sc->regbase = NULL;
984	if (ds_init(sc) == -1) {
985		device_printf(dev, "unable to initialize the card\n");
986		goto bad;
987	}
988
989	codec = AC97_CREATE(dev, sc, ds_ac97);
990	if (codec == NULL)
991		goto bad;
992	/*
993	 * Turn on inverted external amplifier sense flags for few
994	 * 'special' boards.
995	 */
996	switch (subdev) {
997	case 0x81171033:	/* NEC ValueStar (VT550/0) */
998		ac97_setflags(codec, ac97_getflags(codec) | AC97_F_EAPD_INV);
999		break;
1000	default:
1001		break;
1002	}
1003	mixer_init(dev, ac97_getmixerclass(), codec);
1004
1005	sc->irqid = 0;
1006	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
1007					 RF_ACTIVE | RF_SHAREABLE);
1008	if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ds_intr, sc, &sc->ih)) {
1009		device_printf(dev, "unable to map interrupt\n");
1010		goto bad;
1011	}
1012
1013	snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
1014		 rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_ds1));
1015
1016	if (pcm_register(dev, sc, DS1_CHANS, 2))
1017		goto bad;
1018	for (i = 0; i < DS1_CHANS; i++)
1019		pcm_addchan(dev, PCMDIR_PLAY, &ds1pchan_class, sc);
1020	for (i = 0; i < 2; i++)
1021		pcm_addchan(dev, PCMDIR_REC, &ds1rchan_class, sc);
1022	pcm_setstatus(dev, status);
1023
1024	return 0;
1025
1026bad:
1027	if (codec)
1028		ac97_destroy(codec);
1029	if (sc->reg)
1030		bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
1031	if (sc->ih)
1032		bus_teardown_intr(dev, sc->irq, sc->ih);
1033	if (sc->irq)
1034		bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
1035	if (sc->buffer_dmat)
1036		bus_dma_tag_destroy(sc->buffer_dmat);
1037	if (sc->control_dmat)
1038		bus_dma_tag_destroy(sc->control_dmat);
1039	if (sc->lock)
1040		snd_mtxfree(sc->lock);
1041	free(sc, M_DEVBUF);
1042	return ENXIO;
1043}
1044
1045static int
1046ds_pci_resume(device_t dev)
1047{
1048       struct sc_info *sc;
1049
1050       sc = pcm_getdevinfo(dev);
1051
1052       if (ds_init(sc) == -1) {
1053           device_printf(dev, "unable to reinitialize the card\n");
1054           return ENXIO;
1055       }
1056       if (mixer_reinit(dev) == -1) {
1057               device_printf(dev, "unable to reinitialize the mixer\n");
1058               return ENXIO;
1059       }
1060       return 0;
1061}
1062
1063static int
1064ds_pci_detach(device_t dev)
1065{
1066    	int r;
1067	struct sc_info *sc;
1068
1069	r = pcm_unregister(dev);
1070	if (r)
1071    		return r;
1072
1073	sc = pcm_getdevinfo(dev);
1074	ds_uninit(sc);
1075	bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
1076	bus_teardown_intr(dev, sc->irq, sc->ih);
1077	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
1078	bus_dma_tag_destroy(sc->buffer_dmat);
1079	bus_dma_tag_destroy(sc->control_dmat);
1080	snd_mtxfree(sc->lock);
1081	free(sc, M_DEVBUF);
1082       	return 0;
1083}
1084
1085static device_method_t ds1_methods[] = {
1086	/* Device interface */
1087	DEVMETHOD(device_probe,		ds_pci_probe),
1088	DEVMETHOD(device_attach,	ds_pci_attach),
1089	DEVMETHOD(device_detach,	ds_pci_detach),
1090	DEVMETHOD(device_resume,        ds_pci_resume),
1091	{ 0, 0 }
1092};
1093
1094static driver_t ds1_driver = {
1095	"pcm",
1096	ds1_methods,
1097	PCM_SOFTC_SIZE,
1098};
1099
1100DRIVER_MODULE(snd_ds1, pci, ds1_driver, pcm_devclass, 0, 0);
1101MODULE_DEPEND(snd_ds1, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1102MODULE_VERSION(snd_ds1, 1);
1103