FreeBSD/Linux Kernel Cross Reference
sys/pci/es1370.c
1 /*
2 * Support the ENSONIQ AudioPCI board based on the ES1370 and Codec
3 * AK4531.
4 *
5 * Copyright (c) 1998 by Joachim Kuebart. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgement:
21 * This product includes software developed by Joachim Kuebart.
22 *
23 * 4. The name of the author may not be used to endorse or promote
24 * products derived from this software without specific prior
25 * written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
28 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
37 * OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * $FreeBSD$
40 */
41
42 #include "pci.h"
43 #include "pcm.h"
44
45 #include <sys/param.h>
46 #include <sys/queue.h>
47 #include <sys/kernel.h>
48 #include <machine/bus_pio.h>
49 #include <machine/bus_memio.h>
50 #include <machine/bus.h>
51 #include <pci/pcireg.h>
52 #include <pci/pcivar.h>
53 #include <sys/sysctl.h>
54
55 #include <i386/isa/snd/sound.h>
56 #include <i386/isa/snd/ulaw.h>
57
58 #include <pci/es1370_reg.h>
59 #if NPCI != 0
60
61
62 /* -------------------------------------------------------------------- */
63
64 /*
65 * #defines
66 */
67
68 #ifdef __alpha__
69 #define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO
70 #define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM
71 #else /* not __alpha__ */
72 #define IO_SPACE_MAPPING I386_BUS_SPACE_IO
73 #define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM
74 #endif /* not __alpha__ */
75
76 #define DMA_ALIGN_THRESHOLD 4
77 #define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
78 #define DMA_READ_THRESHOLD 0x200
79
80 #define MEM_MAP_REG 0x14
81
82 #define UNIT(minor) ((minor) >> 4)
83 #define DEV(minor) ((minor) & 0xf)
84
85
86 /* -------------------------------------------------------------------- */
87
88 /*
89 * PCI IDs of supported chips
90 */
91
92 #define ES1370_PCI_ID 0x50001274
93 #define ES1371_PCI_ID 0x13711274
94
95 /* -------------------------------------------------------------------- */
96
97 SYSCTL_INT(_debug, OID_AUTO, es_debug, CTLFLAG_RW, &es_debug, 0, "");
98
99 /* -------------------------------------------------------------------- */
100
101 /*
102 * prototypes
103 */
104
105 static void dma_wrintr(snddev_info *);
106 static void dma_rdintr(snddev_info *);
107 static int es_init(snddev_info *);
108 static snd_callback_t es_callback;
109 static d_open_t es_dsp_open;
110 static d_close_t es_dsp_close;
111 static d_ioctl_t es_dsp_ioctl;
112 static d_read_t es_dsp_read;
113 static d_write_t es_dsp_write;
114 static void es_intr(void *);
115 static int es_rdabort(snddev_info *);
116 static void es_rd_map(void *, bus_dma_segment_t *, int, int);
117 static int es_wrabort(snddev_info *);
118 static void es_wr_map(void *, bus_dma_segment_t *, int, int);
119 static const char *es_pci_probe __P((pcici_t, pcidi_t));
120 static void es_pci_attach __P((pcici_t, int));
121 static int es_rd_dmaupdate(snddev_info *);
122 static d_select_t es_select;
123 static int es_wr_dmaupdate(snddev_info *);
124 static int alloc_dmabuf(snddev_info *, int);
125 static int write_codec(snddev_info *, u_char, u_char);
126
127 /* -------------------------------------------------------------------- */
128
129 /*
130 * PCI driver and PCM driver method tables
131 */
132
133 static struct pci_device es_pci_driver = {
134 "es",
135 es_pci_probe,
136 es_pci_attach,
137 &nsnd,
138 NULL
139 };
140
141 DATA_SET(pcidevice_set, es_pci_driver);
142
143 static snddev_info es_op_desc = {
144 "ENSONIQ AudioPCI",
145
146 0, /* type, apparently unused */ /* RMC: use to store board type */
147 NULL, /* ISA probe */
148 NULL, /* ISA attach */
149
150 es_dsp_open,
151 es_dsp_close,
152 es_dsp_read,
153 es_dsp_write,
154 es_dsp_ioctl,
155 es_select,
156
157 NULL, /* Interrupt Service Routine */
158 es_callback,
159
160 ES_BUFFSIZE,
161
162 AFMT_FULLDUPLEX | AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, /* brag :-) */
163 };
164
165
166 /* -------------------------------------------------------------------- */
167
168 /*
169 * The mixer interface
170 */
171
172 static const struct {
173 unsigned volidx:4;
174 unsigned left:4;
175 unsigned right:4;
176 unsigned stereo:1;
177 unsigned recmask:13;
178 unsigned avail:1;
179 } mixtable[SOUND_MIXER_NRDEVICES] = {
180 [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 },
181 [SOUND_MIXER_PCM] = { 1, 0x2, 0x3, 1, 0x0400, 1 },
182 [SOUND_MIXER_SYNTH] = { 2, 0x4, 0x5, 1, 0x0060, 1 },
183 [SOUND_MIXER_CD] = { 3, 0x6, 0x7, 1, 0x0006, 1 },
184 [SOUND_MIXER_LINE] = { 4, 0x8, 0x9, 1, 0x0018, 1 },
185 [SOUND_MIXER_LINE1] = { 5, 0xa, 0xb, 1, 0x1800, 1 },
186 [SOUND_MIXER_LINE2] = { 6, 0xc, 0x0, 0, 0x0100, 1 },
187 [SOUND_MIXER_LINE3] = { 7, 0xd, 0x0, 0, 0x0200, 1 },
188 [SOUND_MIXER_MIC] = { 8, 0xe, 0x0, 0, 0x0001, 1 },
189 [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } };
190
191 static int
192 mixer_ioctl(snddev_info *d, u_long cmd, caddr_t data, int fflag, struct proc *p)
193 {
194 int i, j, *val, ret = 0;
195
196 val = (int *)data;
197 i = cmd & 0xff;
198
199 switch (cmd & IOC_DIRMASK) {
200 case IOC_IN | IOC_OUT: /* _IOWR */
201 switch (i) {
202 case SOUND_MIXER_RECSRC:
203 for (i = j = 0; i != SOUND_MIXER_NRDEVICES; i++)
204 if ((*val & (1 << i)) != 0) {
205 if (!mixtable[i].recmask)
206 *val &= ~(1 << i);
207 else
208 j |= mixtable[i].recmask;
209 }
210 d->mix_recsrc = *val;
211 write_codec(d, CODEC_LIMIX1, j & 0x55);
212 write_codec(d, CODEC_RIMIX1, j & 0xaa);
213 write_codec(d, CODEC_LIMIX2, (j >> 8) & 0x17);
214 write_codec(d, CODEC_RIMIX2, (j >> 8) & 0x0f);
215 write_codec(d, CODEC_OMIX1, 0x7f);
216 write_codec(d, CODEC_OMIX2, 0x3f);
217 break;
218
219 default:
220 if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
221 ret = EINVAL;
222 else {
223 int l, r, rl, rr;
224
225 l = *val & 0xff;
226 if (l > 100)
227 l = 100;
228 if (mixtable[i].left == 0xf) {
229 if (l < 2)
230 rl = 0x80;
231 else
232 rl = 7 - (l - 2) / 14;
233 } else {
234 if (l < 10)
235 rl = 0x80;
236 else
237 rl = 15 - (l - 10) / 6;
238 }
239 if (mixtable[i].stereo) {
240 r = (*val >> 8) & 0xff;
241 if (r > 100)
242 r = 100;
243 if (r < 10)
244 rr = 0x80;
245 else
246 rr = 15 - (r - 10) / 6;
247 write_codec(d, mixtable[i].right, rr);
248 } else
249 r = l;
250 write_codec(d, mixtable[i].left, rl);
251 *val = d->mix_levels[i] = ((u_int) r << 8) | l;
252 }
253 break;
254 }
255 break;
256
257 default:
258 ret = ENOSYS;
259 break;
260 }
261
262 return (ret);
263 }
264
265
266 /* -------------------------------------------------------------------- */
267
268 /*
269 * File operations
270 */
271
272 static int
273 es_dsp_open(dev_t dev, int oflags, int devtype, struct proc *p)
274 {
275 int unit = UNIT(minor(dev));
276 snddev_info *d = &pcm_info[unit];
277
278 if(es_debug > 0) printf("es_dsp_open\n");
279
280 if (d->flags & SND_F_BUSY)
281 return (EBUSY);
282 d->flags = 0;
283
284 d->dbuf_out.total = d->dbuf_out.prev_total =
285 d->dbuf_in.total = d->dbuf_in.prev_total = 0;
286
287 switch (DEV(minor(dev))) {
288 case SND_DEV_DSP16:
289 d->play_fmt = d->rec_fmt = AFMT_S16_LE;
290 break;
291
292 case SND_DEV_DSP:
293 d->play_fmt = d->rec_fmt = AFMT_U8;
294 break;
295
296 case SND_DEV_AUDIO:
297 d->play_fmt = d->rec_fmt = AFMT_MU_LAW;
298 break;
299
300 default:
301 return (ENXIO);
302 }
303
304 if ((oflags & FREAD) == 0)
305 d->rec_fmt = 0;
306 else if ((oflags & FWRITE) == 0)
307 d->play_fmt = 0;
308
309 d->play_speed = d->rec_speed = DSP_DEFAULT_SPEED;
310
311 d->flags |= SND_F_BUSY;
312 if (oflags & O_NONBLOCK)
313 d->flags |= SND_F_NBIO;
314
315 ask_init(d);
316
317 return (0);
318 }
319
320 static int
321 es_dsp_close(dev_t dev, int cflags, int devtype, struct proc *p)
322 {
323 int unit = UNIT(minor(dev));
324 snddev_info *d = &pcm_info[unit];
325
326 d->flags &= ~SND_F_BUSY;
327
328 es_rdabort(d);
329
330 return (0);
331 }
332
333 static int
334 es_dsp_read(dev_t dev, struct uio *buf, int flag)
335 {
336 int l, l1, limit, ret = 0, unit = UNIT(minor(dev));
337 long s;
338 snddev_info *d = &pcm_info[unit];
339 snd_dbuf *b = &d->dbuf_in;
340
341 if(es_debug > 0) printf ("es_dsp_read\n");
342 if (d->flags & SND_F_READING) {
343 /* This shouldn't happen and is actually silly */
344 tsleep(&s, PZERO, "sndar", hz);
345 return (EBUSY);
346 }
347 d->flags |= SND_F_READING;
348
349 /*
350 * XXX Check for SND_F_INIT. If set, wait for DMA to run empty and
351 * re-initialize the board
352 */
353
354 if (buf->uio_resid - d->rec_blocksize > 0)
355 limit = buf->uio_resid - d->rec_blocksize;
356 else
357 limit = 0;
358
359 while ((l = buf->uio_resid) > limit) {
360 s = spltty();
361 es_rd_dmaupdate(d);
362 if ((l = min(l, b->rl)) == 0) {
363 int timeout;
364 if (b->dl == 0)
365 dma_rdintr(d);
366 if (d->flags & SND_F_NBIO) {
367 splx(s);
368 break;
369 }
370 if (buf->uio_resid - limit > b->dl)
371 timeout = hz;
372 else
373 timeout = 1;
374 splx(s);
375 switch (ret = tsleep((caddr_t)b, PRIBIO | PCATCH,
376 "dsprd", timeout)) {
377 case EINTR:
378 es_rdabort(d);
379 /* FALLTHROUGH */
380
381 case ERESTART:
382 break;
383
384 default:
385 continue;
386 }
387 break;
388 }
389 splx(s);
390
391 if ((l1 = b->bufsize - b->rp) < l) {
392 if (d->flags & SND_F_XLAT8) {
393 translate_bytes(dsp_ulaw, b->buf + b->rp, l1);
394 translate_bytes(dsp_ulaw, b->buf, l - l1);
395 }
396 uiomove(b->buf + b->rp, l1, buf);
397 uiomove(b->buf, l - l1, buf);
398 } else {
399 if (d->flags & SND_F_XLAT8)
400 translate_bytes(dsp_ulaw, b->buf + b->rp, l);
401 uiomove(b->buf + b->rp, l, buf);
402 }
403
404 s = spltty();
405 b->fl += l;
406 b->rl -= l;
407 b->rp = (b->rp + l) % b->bufsize;
408 splx(s);
409 }
410
411 d->flags &= ~SND_F_READING;
412
413 return (ret);
414 }
415
416 static int
417 es_dsp_write(dev_t dev, struct uio *buf, int flag)
418 {
419 int l, l1, ret = 0, unit = UNIT(minor(dev));
420 long s;
421 snddev_info *d = &pcm_info[unit];
422 snd_dbuf *b = &d->dbuf_out;
423
424 if (d->flags & SND_F_WRITING) {
425 /* This shouldn't happen and is actually silly */
426 tsleep(&s, PZERO, "sndaw", hz);
427 return (EBUSY);
428 }
429 d->flags |= SND_F_WRITING;
430
431 /*
432 * XXX Check for SND_F_INIT. If set, wait for DMA to run empty and
433 * re-initialize the board
434 */
435
436 while ((l = buf->uio_resid) != 0) {
437 s = spltty();
438 es_wr_dmaupdate(d);
439 if ((l = min(l, b->fl)) == 0) {
440 int timeout;
441 if (d->flags & SND_F_NBIO) {
442 splx(s);
443 break;
444 }
445 if (buf->uio_resid >= b->dl)
446 timeout = hz;
447 else
448 timeout = 1;
449 splx(s);
450 switch (ret = tsleep((caddr_t)b, PRIBIO | PCATCH,
451 "dspwr", timeout)) {
452 case EINTR:
453 es_wrabort(d);
454 /* FALLTHROUGH */
455
456 case ERESTART:
457 break;
458
459 default:
460 continue;
461 }
462 break;
463 }
464 splx(s);
465
466 if ((l1 = b->bufsize - b->fp) < l) {
467 uiomove(b->buf + b->fp, l1, buf);
468 uiomove(b->buf, l - l1, buf);
469 if (d->flags & SND_F_XLAT8) {
470 translate_bytes(ulaw_dsp, b->buf + b->fp, l1);
471 translate_bytes(ulaw_dsp, b->buf, l - l1);
472 }
473 } else {
474 uiomove(b->buf + b->fp, l, buf);
475 if (d->flags & SND_F_XLAT8)
476 translate_bytes(ulaw_dsp, b->buf + b->fp, l);
477 }
478
479 s = spltty();
480 b->rl += l;
481 b->fl -= l;
482 b->fp = (b->fp + l) % b->bufsize;
483 if (b->dl == 0)
484 dma_wrintr(d);
485 splx(s);
486 }
487
488 d->flags &= ~SND_F_WRITING;
489
490 return (ret);
491 }
492
493 static int
494 es_dsp_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
495 {
496 int ret = 0, unit = UNIT(minor(dev));
497 snddev_info *d = &pcm_info[unit];
498 long s;
499 int cmdi = cmd & 0xff;
500
501 if(es_debug > 0) printf("es_dsp_ioctl cmd 0x%x cmdi 0x%x write %s read %s ",(int)cmd,cmdi,
502 (((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0))?"yes":"no"),
503 (((cmd & MIXER_READ(0)) == MIXER_READ(0))?"yes":"no"));
504
505
506 if ((d->type == ES1371_PCI_ID) &&
507 ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0) ||
508 (cmd & MIXER_READ(0)) == MIXER_READ(0)))
509 return mixer_ioctl_1371(d, cmd, data, fflag, p);
510
511 if ((d->type == ES1370_PCI_ID) &&
512 (cmd & MIXER_WRITE(0)) == MIXER_WRITE(0))
513 ret = mixer_ioctl(d, cmd, data, fflag, p);
514
515
516 switch(cmd) {
517 case AIONWRITE:
518 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld AIONWRITE\n",cmd);
519 if (d->dbuf_out.dl != 0) {
520 s = spltty();
521 es_wr_dmaupdate(d);
522 splx(s);
523 }
524 *(int *)data = d->dbuf_out.fl;
525 break;
526
527 case FIONREAD:
528 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld FIONREAD\n",cmd);
529 if (d->dbuf_in.dl != 0) {
530 s = spltty();
531 es_rd_dmaupdate(d);
532 splx(s);
533 }
534 *(int *)data = d->dbuf_in.rl;
535 break;
536
537 case SNDCTL_DSP_GETISPACE:
538 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld SNDCTL_DSP_GETISPACE\n",cmd);
539 {
540 audio_buf_info *a = (audio_buf_info *)data;
541 snd_dbuf *b = &d->dbuf_in;
542 if (b->dl != 0) {
543 s = spltty();
544 es_rd_dmaupdate(d);
545 splx(s);
546 }
547 a->bytes = b->fl;
548 a->fragments = b->fl / d->rec_blocksize;
549 a->fragstotal = b->bufsize / d->rec_blocksize;
550 a->fragsize = d->rec_blocksize;
551 }
552 break;
553
554 case SNDCTL_DSP_GETOSPACE:
555 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld SNDCTL_DSP_GETOSPACE\n",cmd);
556 {
557 audio_buf_info *a = (audio_buf_info *)data;
558 snd_dbuf *b = &d->dbuf_out;
559 if (b->dl != 0) {
560 s = spltty();
561 es_wr_dmaupdate(d);
562 splx(s);
563 }
564 a->bytes = b->fl;
565 a->fragments = b->fl / d->rec_blocksize;
566 a->fragstotal = b->bufsize / d->play_blocksize;
567 a->fragsize = d->play_blocksize;
568 }
569 break;
570
571 case SNDCTL_DSP_GETIPTR:
572 if(es_debug > 0) printf("es_dsp_ioctl cmd: 0x%x SNDCTL_DSP_GETIPTR\n",(u_int)cmd);
573 {
574 count_info *c = (count_info *)data;
575 snd_dbuf *b = &d->dbuf_in;
576 if (b->dl != 0) {
577 s = spltty();
578 es_rd_dmaupdate(d);
579 splx(s);
580 }
581 c->bytes = b->total;
582 c->blocks = (b->total - b->prev_total +
583 d->rec_blocksize - 1) / d->rec_blocksize;
584 c->ptr = b->fp;
585 b->prev_total = b->total;
586 }
587 break;
588
589 case SNDCTL_DSP_GETOPTR:
590 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld SNDCTL_DSP_GETOPTR\n",cmd);
591 {
592 count_info *c = (count_info *)data;
593 snd_dbuf *b = &d->dbuf_out;
594 if (b->dl != 0) {
595 s = spltty();
596 es_wr_dmaupdate(d);
597 splx(s);
598 }
599 c->bytes = b->total;
600 c->blocks = (b->total - b->prev_total +
601 d->play_blocksize - 1) / d->play_blocksize;
602 c->ptr = b->rp;
603 b->prev_total = b->total;
604 }
605 break;
606
607 case AIOSTOP:
608 case SNDCTL_DSP_RESET:
609 case SNDCTL_DSP_SYNC:
610 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld SNDCTL_DSP_SYNC or SNDCTL_DSP_RESET or AIOSTOP \n",cmd);
611 /* this was removed from the driver for some reason ....
612 * and relplace with a return EINVAL
613 * this causes mpg123 to complain "Can't reset Audio"
614 * So I'm going to put it back RMC 10/22/99
615 */
616 es_wrabort(d);
617 es_rdabort(d);
618 break;
619
620 default:
621 if(es_debug > 0) printf("es_dsp_ioctl cmd: %ld default... ret ENOSYS\n",cmd);
622 ret = ENOSYS;
623 break;
624 }
625 return (ret);
626 }
627
628 static int
629 es_select(dev_t i_dev, int rw, struct proc * p)
630 {
631 return (ENOSYS);
632 }
633
634
635 /* -------------------------------------------------------------------- */
636
637 /*
638 * The interrupt handler
639 */
640
641 static void
642 es_intr (void *p)
643 {
644 snddev_info *d = (snddev_info *)p;
645 struct es_info *es = (struct es_info *)d->device_data;
646 unsigned intsrc, sctrl;
647
648 intsrc = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
649 /* if (es_debug > 2) printf("es_intr intsrc:%d p:0x%p es:0x%p\n",intsrc,p,es); */
650
651 if ((intsrc & STAT_INTR) == 0)
652 return;
653
654 sctrl = es->sctrl;
655 if (intsrc & STAT_ADC)
656 sctrl &= ~SCTRL_R1INTEN;
657 if (intsrc & STAT_DAC1)
658 sctrl &= ~SCTRL_P1INTEN;
659 if (intsrc & STAT_DAC2) {
660 sctrl &= ~SCTRL_P2INTEN;
661 }
662 bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, sctrl);
663 bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
664 if (intsrc & STAT_DAC2)
665 dma_wrintr(d);
666 if (intsrc & STAT_ADC)
667 dma_rdintr(d);
668 }
669
670
671 /* -------------------------------------------------------------------- */
672
673 /*
674 * DMA hassle
675 */
676
677 static int
678 alloc_dmabuf(snddev_info *d, int rd)
679 {
680 struct es_info *es = (struct es_info *)d->device_data;
681 snd_dbuf *b = rd ? &d->dbuf_in : &d->dbuf_out;
682 bus_dmamap_t *dmam = rd ? &es->dmam_in : &es->dmam_out;
683
684 if (bus_dmamem_alloc(es->parent_dmat, (void **)&b->buf, BUS_DMA_NOWAIT,
685 dmam) != 0 ||
686 bus_dmamap_load(es->parent_dmat, *dmam, b->buf, d->bufsize,
687 rd ? es_rd_map : es_wr_map, es, 0) != 0)
688 return -1;
689
690 b->rp = b->fp = b->dl = b->rl = 0;
691 b->fl = b->bufsize = d->bufsize;
692 return (0);
693 }
694
695 static int
696 es_wr_dmaupdate(snddev_info *d)
697 {
698 struct es_info *es = (struct es_info *)d->device_data;
699 unsigned hwptr, delta;
700
701 bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE,
702 ES1370_REG_DAC2_FRAMECNT >> 8);
703 hwptr = (bus_space_read_4(es->st, es->sh,
704 ES1370_REG_DAC2_FRAMECNT & 0xff) >> 14) & 0x3fffc;
705 delta = (d->dbuf_out.bufsize + hwptr - d->dbuf_out.rp) %
706 d->dbuf_out.bufsize;
707 d->dbuf_out.rp = hwptr;
708 d->dbuf_out.rl -= delta;
709 d->dbuf_out.fl += delta;
710 d->dbuf_out.total += delta;
711
712 return delta;
713 }
714
715 static int
716 es_rd_dmaupdate(snddev_info *d)
717 {
718 struct es_info *es = (struct es_info *)d->device_data;
719 unsigned hwptr, delta;
720
721 bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE,
722 ES1370_REG_ADC_FRAMECNT >> 8);
723 hwptr = (bus_space_read_4(es->st, es->sh,
724 ES1370_REG_ADC_FRAMECNT & 0xff) >> 14) & 0x3fffc;
725 delta = (d->dbuf_in.bufsize + hwptr - d->dbuf_in.fp) %
726 d->dbuf_in.bufsize;
727 d->dbuf_in.fp = hwptr;
728 d->dbuf_in.rl += delta;
729 d->dbuf_in.fl -= delta;
730 d->dbuf_in.total += delta;
731 return delta;
732 }
733
734
735 /* -------------------------------------------------------------------- */
736
737 /*
738 * Hardware
739 */
740
741 static int
742 es_callback(snddev_info *d, int reason)
743 {
744 struct es_info *es = (struct es_info *)d->device_data;
745 int rd = reason & SND_CB_RD;
746
747 if(es_debug > 0) printf("es_callback reason %d speed %d \t",reason ,d->play_speed);
748 switch(reason & SND_CB_REASON_MASK) {
749 case SND_CB_INIT:
750 /* if(es_debug > 0) printf("case SND_CB_INIT\n"); */
751 if (d->type == ES1371_PCI_ID){
752 es1371_dac2_rate(d,d->play_speed,1); /* codec DAC */
753 es1371_dac1_rate(d,d->play_speed,1); /* codec FM DAC */ /* NOT used */
754 es1371_adc_rate(d, d->rec_speed, 1); /* record */
755 } else /* 1370 */ {
756 es->ctrl = (es->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(d->play_speed) << CTRL_SH_PCLKDIV);
757 }
758 snd_set_blocksize(d);
759
760 es->sctrl &= ~(SCTRL_R1FMT | SCTRL_P2FMT);
761 d->flags &= ~SND_F_XLAT8;
762 switch(d->play_fmt) {
763 case 0:
764 case AFMT_U8:
765 break;
766
767 case AFMT_S16_LE:
768 es->sctrl |= SCTRL_P2SEB;
769 break;
770
771 case AFMT_MU_LAW:
772 d->flags |= SND_F_XLAT8;
773 break;
774
775 default:
776 return (-1);
777 }
778
779 switch(d->rec_fmt) {
780 case 0:
781 case AFMT_U8:
782 break;
783
784 case AFMT_S16_LE:
785 es->sctrl |= SCTRL_R1SEB;
786 break;
787
788 case AFMT_MU_LAW:
789 d->flags |= SND_F_XLAT8;
790 break;
791
792 default:
793 return (-1);
794 }
795
796 if (d->flags & SND_F_STEREO)
797 es->sctrl |= SCTRL_P2SMB | SCTRL_R1SMB;
798
799 bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
800 bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
801 break;
802
803 case SND_CB_START:
804 if(es_debug > 0) printf("case SND_CB_START flag rd 0x%x\n",rd);
805 if (rd) {
806 es->ctrl |= CTRL_ADC_EN;
807 es->sctrl = (es->sctrl & ~SCTRL_R1LOOPSEL) |
808 SCTRL_R1INTEN;
809 bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_SCOUNT,
810 d->dbuf_in.dl / d->dbuf_in.sample_size - 1);
811 } else {
812 #if 0
813 if(es_debug > 0) printf("CB_START CONTROL 0x%x\n",bus_space_read_4(es->st, es->sh, ES1370_REG_CONTROL));
814 if(es_debug > 0) printf("CB_START DAC2_SCOUNT 0x%x\n",bus_space_read_4(es->st, es->sh, ES1370_REG_DAC2_SCOUNT));
815 #endif
816 es->ctrl |= CTRL_DAC2_EN;
817 es->sctrl = (es->sctrl & ~(SCTRL_P2ENDINC |
818 SCTRL_P2STINC |
819 SCTRL_P2LOOPSEL |
820 SCTRL_P2PAUSE |
821 SCTRL_P2DACSEN)) |
822 SCTRL_P2INTEN |
823 (((d->play_fmt == AFMT_S16_LE) ? 2 : 1)
824 << SCTRL_SH_P2ENDINC);
825 bus_space_write_4(es->st, es->sh,
826 ES1370_REG_DAC2_SCOUNT,
827 d->dbuf_out.dl / d->dbuf_out.sample_size - 1);
828 }
829 bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
830 bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
831 #if 0
832 if(es_debug > 0) printf("CB_START CONTROL 0x%x\n",bus_space_read_4(es->st, es->sh, ES1370_REG_CONTROL));
833 if(es_debug > 0) printf("CB_START DAC2_SCOUNT 0x%x\n",bus_space_read_4(es->st, es->sh, ES1370_REG_DAC2_SCOUNT));
834 #endif
835 break;
836
837 case SND_CB_ABORT:
838 case SND_CB_STOP:
839 if(es_debug > 0) printf("case SND_CB_STOP flag rd 0x%x\n",rd);
840 if (rd)
841 es->ctrl &= ~CTRL_ADC_EN;
842 else
843 es->ctrl &= ~CTRL_DAC2_EN;
844 bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
845 break;
846
847 default:
848 return (-1);
849 }
850 return (0);
851 }
852
853 static int
854 write_codec(snddev_info *d, u_char i, u_char data)
855 {
856 struct es_info *es = (struct es_info *)d->device_data;
857 int wait = 100; /* 100 msec timeout */
858
859 if (es_debug > 1) printf("write_codec \n");
860 do {
861 if ((bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS) &
862 STAT_CSTAT) == 0) {
863 bus_space_write_2(es->st, es->sh, ES1370_REG_CODEC,
864 ((u_short)i << CODEC_INDEX_SHIFT) | data);
865 return (0);
866 }
867 DELAY(1000);
868 /* tsleep(&wait, PZERO, "sndaw", hz / 1000); */
869 } while (--wait);
870 printf("pcm: write_codec timed out\n");
871 return (-1);
872 }
873
874 static void
875 es_wr_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
876 {
877 struct es_info *es = (struct es_info *)arg;
878
879 bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE,
880 ES1370_REG_DAC2_FRAMEADR >> 8);
881 bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff,
882 segs->ds_addr);
883 bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff,
884 (segs->ds_len >> 2) - 1);
885 }
886
887 static void
888 es_rd_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
889 {
890 struct es_info *es = (struct es_info *)arg;
891
892 bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE,
893 ES1370_REG_ADC_FRAMEADR >> 8);
894 bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMEADR & 0xff,
895 segs->ds_addr);
896 bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff,
897 (segs->ds_len >> 2) - 1);
898 }
899
900 static void
901 dma_wrintr(snddev_info *d)
902 {
903 snd_dbuf *b = &d->dbuf_out;
904
905 /*
906 * According to Linux driver:
907 * dmaupdate()
908 * Bei underrun error++
909 * wake_up(dac2.wait)
910 */
911
912 if (b->dl != 0) {
913 es_wr_dmaupdate(d);
914 wakeup(b);
915 }
916
917 if (b->rl >= DMA_ALIGN_THRESHOLD &&
918 !(d->flags & SND_F_ABORTING)) {
919 int l = min(b->rl, d->play_blocksize);
920 l &= DMA_ALIGN_MASK;
921
922 if (l != b->dl) {
923 if (b->dl != 0) {
924 d->callback(d, SND_CB_WR | SND_CB_STOP);
925 es_wr_dmaupdate(d);
926 l = min(b->rl, d->play_blocksize);
927 l &= DMA_ALIGN_MASK;
928 }
929 b->dl = l;
930 d->callback(d, SND_CB_WR | SND_CB_START);
931 }
932 } else if (b->dl != 0) {
933 b->dl = 0;
934 d->callback(d, SND_CB_WR | SND_CB_STOP);
935 es_wr_dmaupdate(d);
936 }
937 }
938
939 static void
940 dma_rdintr(snddev_info *d)
941 {
942 snd_dbuf *b = &d->dbuf_in;
943
944 if (b->dl != 0) {
945 es_rd_dmaupdate(d);
946 wakeup(b);
947 }
948
949 if (b->fl >= DMA_READ_THRESHOLD &&
950 !(d->flags & SND_F_ABORTING)) {
951 int l = min(b->fl, d->rec_blocksize);
952 l &= DMA_ALIGN_MASK;
953
954 if (l != b->dl) {
955 if (b->dl != 0) {
956 d->callback(d, SND_CB_RD | SND_CB_STOP);
957 es_rd_dmaupdate(d);
958 l = min(b->fl, d->rec_blocksize);
959 l &= DMA_ALIGN_MASK;
960 }
961 b->dl = l;
962 d->callback(d, SND_CB_RD | SND_CB_START);
963 }
964 } else {
965 if (b->dl != 0) {
966 b->dl = 0;
967 d->callback(d, SND_CB_RD | SND_CB_STOP);
968 es_rd_dmaupdate(d);
969 }
970 }
971 }
972
973 static int
974 es_wrabort(snddev_info *d)
975 {
976 snd_dbuf *b = &d->dbuf_out;
977 long s;
978 int missing;
979
980 s = spltty();
981 if (b->dl != 0) {
982 wakeup(b);
983 b->dl = 0;
984 d->callback(d, SND_CB_WR | SND_CB_ABORT);
985 }
986 es_wr_dmaupdate(d);
987 missing = b->rl;
988 b->rl = 0;
989 b->fp = b->rp;
990 b->fl = b->bufsize;
991 splx(s);
992 return missing;
993 }
994
995 static int
996 es_rdabort(snddev_info *d)
997 {
998 snd_dbuf *b = &d->dbuf_in;
999 long s;
1000 int missing;
1001
1002 s = spltty();
1003 if (b->dl != 0) {
1004 wakeup(b);
1005 b->dl = 0;
1006 d->callback(d, SND_CB_RD | SND_CB_ABORT);
1007 es_rd_dmaupdate(d);
1008 }
1009 missing = b->rl;
1010 b->rl = 0;
1011 b->fp = b->rp;
1012 b->fl = b->bufsize;
1013 splx(s);
1014 return missing;
1015 }
1016
1017
1018 /* -------------------------------------------------------------------- */
1019
1020 /*
1021 * Probe and attach the card
1022 */
1023
1024 static int
1025 es_init(snddev_info *d)
1026 {
1027 struct es_info *es = (struct es_info *)d->device_data;
1028 u_int i;
1029
1030 es->ctrl = CTRL_CDC_EN | CTRL_SERR_DIS |
1031 (DAC2_SRTODIV(DSP_DEFAULT_SPEED) << CTRL_SH_PCLKDIV);
1032 bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
1033 es->sctrl = 0;
1034 bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
1035 write_codec(d, CODEC_RES_PD, 3);/* No RST, PD */
1036 write_codec(d, CODEC_CSEL, 0); /* CODEC ADC and CODEC DAC use
1037 * {LR,B}CLK2 and run off the LRCLK2
1038 * PLL; program DAC_SYNC=0! */
1039 write_codec(d, CODEC_ADSEL, 0); /* Recording source is mixer */
1040 write_codec(d, CODEC_MGAIN, 0); /* MIC amp is 0db */
1041
1042 i = SOUND_MASK_MIC;
1043 mixer_ioctl(d, SOUND_MIXER_WRITE_RECSRC, (caddr_t) &i, 0, NULL);
1044 i = 0;
1045 mixer_ioctl(d, SOUND_MIXER_WRITE_VOLUME, (caddr_t) &i, 0, NULL);
1046 mixer_ioctl(d, SOUND_MIXER_WRITE_PCM, (caddr_t) &i, 0, NULL);
1047 mixer_ioctl(d, SOUND_MIXER_WRITE_SYNTH, (caddr_t) &i, 0, NULL);
1048 mixer_ioctl(d, SOUND_MIXER_WRITE_CD, (caddr_t) &i, 0, NULL);
1049 mixer_ioctl(d, SOUND_MIXER_WRITE_LINE, (caddr_t) &i, 0, NULL);
1050 mixer_ioctl(d, SOUND_MIXER_WRITE_LINE1, (caddr_t) &i, 0, NULL);
1051 mixer_ioctl(d, SOUND_MIXER_WRITE_LINE2, (caddr_t) &i, 0, NULL);
1052 mixer_ioctl(d, SOUND_MIXER_WRITE_LINE3, (caddr_t) &i, 0, NULL);
1053 mixer_ioctl(d, SOUND_MIXER_WRITE_MIC, (caddr_t) &i, 0, NULL);
1054
1055 return (0);
1056 }
1057
1058 static const char *
1059 es_pci_probe(pcici_t tag, pcidi_t type)
1060 {
1061 if(es_debug > 0) printf ("es_pci_probe 0x%x\n",type);
1062 switch(type){
1063 case ES1370_PCI_ID:
1064 return ("AudioPCI ES1370");
1065 case ES1371_PCI_ID:
1066 return ("AudioPCI ES1371");
1067 default:
1068 return (NULL);
1069 };
1070 }
1071
1072 static void
1073 es_pci_attach(pcici_t config_id, int unit)
1074 {
1075 snddev_info *d;
1076 u_int32_t data;
1077 struct es_info *es;
1078 pci_port_t io_port;
1079 int i, mapped;
1080 vm_offset_t vaddr, paddr;
1081 int ret;
1082
1083 if(es_debug > 0) printf("es_pci_attach\n");
1084 if (unit > NPCM_MAX)
1085 return;
1086
1087 d = &pcm_info[unit];
1088 *d = es_op_desc;
1089 if ((es = malloc(sizeof(*es), M_DEVBUF, M_NOWAIT)) == NULL) {
1090 printf("pcm%d: cannot allocate softc\n", unit);
1091 return;
1092 }
1093 bzero(es, sizeof(*es));
1094 d->device_data = es;
1095 d->type = ((config_id->device << 16) | config_id->vendor);
1096 if (es_debug >0 ) printf("es_pci_attach device_data %p d->type 0x%x\n",d->device_data,d->type);
1097 vaddr = paddr = NULL;
1098 mapped = 0;
1099 data = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
1100 if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
1101 if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {
1102 es->st = MEM_SPACE_MAPPING;
1103 es->sh = vaddr;
1104 mapped++;
1105 }
1106 }
1107 if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
1108 if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {
1109 es->st = IO_SPACE_MAPPING;
1110 es->sh = io_port;
1111 mapped++;
1112 }
1113 }
1114 if (mapped == 0) {
1115 printf("pcm%d: unable to map any ports\n", unit);
1116 free(es, M_DEVBUF);
1117 return;
1118 }
1119 printf("pcm%d: using %s space register mapping at %#x\n", unit,
1120 es->st == IO_SPACE_MAPPING ? "I/O" : "Memory", es->sh);
1121
1122 d->io_base = es->sh;
1123 d->mix_devs = 0;
1124 for (i = 0; i != SOUND_MIXER_NRDEVICES; i++)
1125 if (mixtable[i].avail)
1126 d->mix_devs |= (1 << i);
1127 d->mix_rec_devs = 0;
1128 for (i = 0; i != SOUND_MIXER_NRDEVICES; i++)
1129 if (mixtable[i].recmask)
1130 d->mix_rec_devs |= (1 << i);
1131
1132 switch (d->type){
1133 case ES1370_PCI_ID:
1134 ret = es_init(d);
1135 break;
1136 case ES1371_PCI_ID:
1137 ret = es_init_1371(d);
1138 break;
1139 default:
1140 printf("pcm%d: unknow card type 0x%x\n",unit,d->type);
1141 ret = -1;
1142 }
1143
1144 if (ret == -1) {
1145 printf("pcm%d: unable to initialize the card\n", unit);
1146 free(es, M_DEVBUF);
1147 d->io_base = 0;
1148 return;
1149 }
1150
1151 if (pci_map_int(config_id, es_intr, d, &tty_imask) == 0) {
1152 printf("pcm%d: unable to map interrupt\n", unit);
1153 free(es, M_DEVBUF);
1154 d->io_base = 0;
1155 return;
1156 }
1157 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
1158 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1159 /*highaddr*/BUS_SPACE_MAXADDR,
1160 /*filter*/NULL, /*filterarg*/NULL,
1161 /*maxsize*/d->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff,
1162 /*flags*/0, &es->parent_dmat) != 0) {
1163 printf("pcm%d: unable to create dma tag\n", unit);
1164 free(es, M_DEVBUF);
1165 d->io_base = 0;
1166 return;
1167 }
1168
1169 if (alloc_dmabuf(d, 0) == -1 ||
1170 alloc_dmabuf(d, 1) == -1) {
1171 printf("pcm%d: unable to allocate dma buffers\n", unit);
1172 free(es, M_DEVBUF);
1173 d->io_base = 0;
1174 return;
1175 }
1176
1177 pcminit(d, unit);
1178
1179 return;
1180 }
1181
1182
1183 #endif /* NPCI != 0 */
Cache object: e1e83eb46d6ede07ca215fbaaebc66ad
|