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