]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/sound/pci/ds1.c
Merge r254306:
[FreeBSD/releng/9.2.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
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
40 SND_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
49 struct 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
82 struct 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
89 struct sc_info;
90
91 /* channel registers */
92 struct 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
101 struct 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 */
110 struct 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
136 struct {
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 */
164 static int       ds_init(struct sc_info *);
165 static void      ds_intr(void *);
166
167 /* talk to the card */
168 static u_int32_t ds_rd(struct sc_info *, int, int);
169 static void      ds_wr(struct sc_info *, int, u_int32_t, int);
170
171 /* -------------------------------------------------------------------- */
172
173 static 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 };
184 static struct pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0};
185
186 static 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 };
193 static struct pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
194
195 /* -------------------------------------------------------------------- */
196 /* Hardware */
197 static u_int32_t
198 ds_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
212 static void
213 ds_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
228 static void
229 wrl(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 */
237 static int
238 ds_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
252 static u_int32_t
253 ds_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
278 static int
279 ds_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
305 static int
306 ds_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
326 static 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 };
332 AC97_DECLARE(ds_ac97);
333
334 /* -------------------------------------------------------------------- */
335
336 static void
337 ds_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
356 static volatile struct pbank *
357 ds_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
367 static int
368 ds_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
426 static void
427 ds_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
433 static void
434 ds_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
451 static void
452 ds_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 */
481 static void *
482 ds1pchan_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
509 static int
510 ds1pchan_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
519 static u_int32_t
520 ds1pchan_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
529 static u_int32_t
530 ds1pchan_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 */
545 static int
546 ds1pchan_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
573 static u_int32_t
574 ds1pchan_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
592 static struct pcmchan_caps *
593 ds1pchan_getcaps(kobj_t obj, void *data)
594 {
595         return &ds_playcaps;
596 }
597
598 static 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 };
608 CHANNEL_DECLARE(ds1pchan);
609
610 /* -------------------------------------------------------------------- */
611 /* record channel interface */
612 static void *
613 ds1rchan_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
637 static int
638 ds1rchan_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
647 static u_int32_t
648 ds1rchan_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
657 static u_int32_t
658 ds1rchan_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 */
673 static int
674 ds1rchan_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
703 static u_int32_t
704 ds1rchan_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
712 static struct pcmchan_caps *
713 ds1rchan_getcaps(kobj_t obj, void *data)
714 {
715         return &ds_reccaps;
716 }
717
718 static 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 };
728 CHANNEL_DECLARE(ds1rchan);
729
730 /* -------------------------------------------------------------------- */
731 /* The interrupt handler */
732 static void
733 ds_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
777 static void
778 ds_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
791 static int
792 ds_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
892 static int
893 ds_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
913 static int
914 ds_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
926 static int
927 ds_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
941 static int
942 ds_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
1026 bad:
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
1045 static int
1046 ds_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
1063 static int
1064 ds_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
1085 static 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
1094 static driver_t ds1_driver = {
1095         "pcm",
1096         ds1_methods,
1097         PCM_SOFTC_SIZE,
1098 };
1099
1100 DRIVER_MODULE(snd_ds1, pci, ds1_driver, pcm_devclass, 0, 0);
1101 MODULE_DEPEND(snd_ds1, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1102 MODULE_VERSION(snd_ds1, 1);