summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/es1370.c1123
-rw-r--r--sys/pci/es1370_reg.h134
2 files changed, 0 insertions, 1257 deletions
diff --git a/sys/pci/es1370.c b/sys/pci/es1370.c
deleted file mode 100644
index d1370aa..0000000
--- a/sys/pci/es1370.c
+++ /dev/null
@@ -1,1123 +0,0 @@
-/*
- * Support the ENSONIQ AudioPCI board based on the ES1370 and Codec
- * AK4531.
- *
- * Copyright (c) 1998 by Joachim Kuebart. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgement:
- * This product includes software developed by Joachim Kuebart.
- *
- * 4. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include "pcm.h"
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/kernel.h>
-#include <machine/bus_pio.h>
-#include <machine/bus_memio.h>
-#include <machine/bus.h>
-#include <pci/pcireg.h>
-#include <pci/pcivar.h>
-
-#include <pci/es1370_reg.h>
-#include <i386/isa/snd/sound.h>
-#define DSP_ULAW_NOT_WANTED
-#include <i386/isa/snd/ulaw.h>
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * #defines
- */
-
-#ifdef __alpha__
-#define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO
-#define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM
-#else /* not __alpha__ */
-#define IO_SPACE_MAPPING I386_BUS_SPACE_IO
-#define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM
-#endif /* not __alpha__ */
-
-#define DMA_ALIGN_THRESHOLD 4
-#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1))
-#define DMA_READ_THRESHOLD 0x200
-
-#define MEM_MAP_REG 0x14
-
-#define UNIT(minor) ((minor) >> 4)
-#define DEV(minor) ((minor) & 0xf)
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * PCI IDs of supported chips
- */
-
-#define ES1370_PCI_ID 0x50001274
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * device private data
- */
-
-struct es_info {
- bus_space_tag_t st;
- bus_space_handle_t sh;
-
- bus_dma_tag_t parent_dmat;
- bus_dmamap_t dmam_in, dmam_out;
-
- /* Contents of board's registers */
- u_long ctrl;
- u_long sctrl;
-};
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * prototypes
- */
-
-static void dma_wrintr(snddev_info *);
-static void dma_rdintr(snddev_info *);
-static int es_init(snddev_info *);
-static snd_callback_t es_callback;
-static d_open_t es_dsp_open;
-static d_close_t es_dsp_close;
-static d_ioctl_t es_dsp_ioctl;
-static d_read_t es_dsp_read;
-static d_write_t es_dsp_write;
-static void es_intr(void *);
-static int es_rdabort(snddev_info *);
-static void es_rd_map(void *, bus_dma_segment_t *, int, int);
-static int es_wrabort(snddev_info *);
-static void es_wr_map(void *, bus_dma_segment_t *, int, int);
-static const char *es_pci_probe __P((pcici_t, pcidi_t));
-static void es_pci_attach __P((pcici_t, int));
-static int es_rd_dmaupdate(snddev_info *);
-static d_select_t es_select;
-static int es_wr_dmaupdate(snddev_info *);
-static int alloc_dmabuf(snddev_info *, int);
-static int write_codec(snddev_info *, u_char, u_char);
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * PCI driver and PCM driver method tables
- */
-
-static struct pci_device es_pci_driver = {
- "pcm",
- es_pci_probe,
- es_pci_attach,
- &nsnd,
- NULL
-};
-
-COMPAT_PCI_DRIVER(es_pci, es_pci_driver);
-
-static snddev_info es_op_desc = {
- "ENSONIQ AudioPCI",
-
- 0, /* type, apparently unused */
- NULL, /* ISA probe */
- NULL, /* ISA attach */
-
- es_dsp_open,
- es_dsp_close,
- es_dsp_read,
- es_dsp_write,
- es_dsp_ioctl,
- es_select,
-
- NULL, /* Interrupt Service Routine */
- es_callback,
-
- ES_BUFFSIZE,
-
- AFMT_FULLDUPLEX | AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, /* brag :-) */
-};
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * The mixer interface
- */
-
-static const struct {
- unsigned volidx:4;
- unsigned left:4;
- unsigned right:4;
- unsigned stereo:1;
- unsigned recmask:13;
- unsigned avail:1;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
- [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 },
- [SOUND_MIXER_PCM] = { 1, 0x2, 0x3, 1, 0x0400, 1 },
- [SOUND_MIXER_SYNTH] = { 2, 0x4, 0x5, 1, 0x0060, 1 },
- [SOUND_MIXER_CD] = { 3, 0x6, 0x7, 1, 0x0006, 1 },
- [SOUND_MIXER_LINE] = { 4, 0x8, 0x9, 1, 0x0018, 1 },
- [SOUND_MIXER_LINE1] = { 5, 0xa, 0xb, 1, 0x1800, 1 },
- [SOUND_MIXER_LINE2] = { 6, 0xc, 0x0, 0, 0x0100, 1 },
- [SOUND_MIXER_LINE3] = { 7, 0xd, 0x0, 0, 0x0200, 1 },
- [SOUND_MIXER_MIC] = { 8, 0xe, 0x0, 0, 0x0001, 1 },
- [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } };
-
-static int
-mixer_ioctl(snddev_info *d, u_long cmd, caddr_t data, int fflag, struct proc *p)
-{
- int i, j, *val, ret = 0;
-
- val = (int *)data;
- i = cmd & 0xff;
-
- switch (cmd & IOC_DIRMASK) {
- case IOC_IN | IOC_OUT: /* _IOWR */
- switch (i) {
- case SOUND_MIXER_RECSRC:
- for (i = j = 0; i != SOUND_MIXER_NRDEVICES; i++)
- if ((*val & (1 << i)) != 0) {
- if (!mixtable[i].recmask)
- *val &= ~(1 << i);
- else
- j |= mixtable[i].recmask;
- }
- d->mix_recsrc = *val;
- write_codec(d, CODEC_LIMIX1, j & 0x55);
- write_codec(d, CODEC_RIMIX1, j & 0xaa);
- write_codec(d, CODEC_LIMIX2, (j >> 8) & 0x17);
- write_codec(d, CODEC_RIMIX2, (j >> 8) & 0x0f);
- write_codec(d, CODEC_OMIX1, 0x7f);
- write_codec(d, CODEC_OMIX2, 0x3f);
- break;
-
- default:
- if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
- ret = EINVAL;
- else {
- int l, r, rl, rr;
-
- l = *val & 0xff;
- if (l > 100)
- l = 100;
- if (mixtable[i].left == 0xf) {
- if (l < 2)
- rl = 0x80;
- else
- rl = 7 - (l - 2) / 14;
- } else {
- if (l < 10)
- rl = 0x80;
- else
- rl = 15 - (l - 10) / 6;
- }
- if (mixtable[i].stereo) {
- r = (*val >> 8) & 0xff;
- if (r > 100)
- r = 100;
- if (r < 10)
- rr = 0x80;
- else
- rr = 15 - (r - 10) / 6;
- write_codec(d, mixtable[i].right, rr);
- } else
- r = l;
- write_codec(d, mixtable[i].left, rl);
- *val = d->mix_levels[i] = ((u_int) r << 8) | l;
- }
- break;
- }
- break;
-
- default:
- ret = ENOSYS;
- break;
- }
-
- return (ret);
-}
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * File operations
- */
-
-static int
-es_dsp_open(dev_t dev, int oflags, int devtype, struct proc *p)
-{
- int unit = UNIT(minor(dev));
- snddev_info *d = &pcm_info[unit];
-
- if (d->flags & SND_F_BUSY)
- return (EBUSY);
- d->flags = 0;
-
- d->dbuf_out.total = d->dbuf_out.prev_total =
- d->dbuf_in.total = d->dbuf_in.prev_total = 0;
-
- switch (DEV(minor(dev))) {
- case SND_DEV_DSP16:
- d->play_fmt = d->rec_fmt = AFMT_S16_LE;
- break;
-
- case SND_DEV_DSP:
- d->play_fmt = d->rec_fmt = AFMT_U8;
- break;
-
- case SND_DEV_AUDIO:
- d->play_fmt = d->rec_fmt = AFMT_MU_LAW;
- break;
-
- default:
- return (ENXIO);
- }
-
- if ((oflags & FREAD) == 0)
- d->rec_fmt = 0;
- else if ((oflags & FWRITE) == 0)
- d->play_fmt = 0;
-
- d->play_speed = d->rec_speed = DSP_DEFAULT_SPEED;
-
- d->flags |= SND_F_BUSY;
- if (oflags & O_NONBLOCK)
- d->flags |= SND_F_NBIO;
-
- ask_init(d);
-
- return (0);
-}
-
-static int
-es_dsp_close(dev_t dev, int cflags, int devtype, struct proc *p)
-{
- int unit = UNIT(minor(dev));
- snddev_info *d = &pcm_info[unit];
-
- d->flags &= ~SND_F_BUSY;
-
- es_rdabort(d);
-
- return (0);
-}
-
-static int
-es_dsp_read(dev_t dev, struct uio *buf, int flag)
-{
- int l, l1, limit, ret = 0, unit = UNIT(minor(dev));
- long s;
- snddev_info *d = &pcm_info[unit];
- snd_dbuf *b = &d->dbuf_in;
-
- if (d->flags & SND_F_READING) {
- /* This shouldn't happen and is actually silly */
- tsleep(&s, PZERO, "sndar", hz);
- return (EBUSY);
- }
- d->flags |= SND_F_READING;
-
- /*
- * XXX Check for SND_F_INIT. If set, wait for DMA to run empty and
- * re-initialize the board
- */
-
- if (buf->uio_resid - d->rec_blocksize > 0)
- limit = buf->uio_resid - d->rec_blocksize;
- else
- limit = 0;
-
- while ((l = buf->uio_resid) > limit) {
- s = spltty();
- es_rd_dmaupdate(d);
- if ((l = min(l, b->rl)) == 0) {
- int timeout;
- if (b->dl == 0)
- dma_rdintr(d);
- if (d->flags & SND_F_NBIO) {
- splx(s);
- break;
- }
- if (buf->uio_resid - limit > b->dl)
- timeout = hz;
- else
- timeout = 1;
- splx(s);
- switch (ret = tsleep((caddr_t)b, PRIBIO | PCATCH,
- "dsprd", timeout)) {
- case EINTR:
- es_rdabort(d);
- /* FALLTHROUGH */
-
- case ERESTART:
- break;
-
- default:
- continue;
- }
- break;
- }
- splx(s);
-
- if ((l1 = b->bufsize - b->rp) < l) {
- if (d->flags & SND_F_XLAT8) {
- translate_bytes(ulaw_dsp, b->buf + b->rp, l1);
- translate_bytes(ulaw_dsp, b->buf, l - l1);
- }
- uiomove(b->buf + b->rp, l1, buf);
- uiomove(b->buf, l - l1, buf);
- } else {
- if (d->flags & SND_F_XLAT8)
- translate_bytes(ulaw_dsp, b->buf + b->rp, l);
- uiomove(b->buf + b->rp, l, buf);
- }
-
- s = spltty();
- b->fl += l;
- b->rl -= l;
- b->rp = (b->rp + l) % b->bufsize;
- splx(s);
- }
-
- d->flags &= ~SND_F_READING;
-
- return (ret);
-}
-
-static int
-es_dsp_write(dev_t dev, struct uio *buf, int flag)
-{
- int l, l1, ret = 0, unit = UNIT(minor(dev));
- long s;
- snddev_info *d = &pcm_info[unit];
- snd_dbuf *b = &d->dbuf_out;
-
- if (d->flags & SND_F_WRITING) {
- /* This shouldn't happen and is actually silly */
- tsleep(&s, PZERO, "sndaw", hz);
- return (EBUSY);
- }
- d->flags |= SND_F_WRITING;
-
- /*
- * XXX Check for SND_F_INIT. If set, wait for DMA to run empty and
- * re-initialize the board
- */
-
- while ((l = buf->uio_resid) != 0) {
- s = spltty();
- es_wr_dmaupdate(d);
- if ((l = min(l, b->fl)) == 0) {
- int timeout;
- if (d->flags & SND_F_NBIO) {
- splx(s);
- break;
- }
- if (buf->uio_resid >= b->dl)
- timeout = hz;
- else
- timeout = 1;
- splx(s);
- switch (ret = tsleep((caddr_t)b, PRIBIO | PCATCH,
- "dspwr", timeout)) {
- case EINTR:
- es_wrabort(d);
- /* FALLTHROUGH */
-
- case ERESTART:
- break;
-
- default:
- continue;
- }
- break;
- }
- splx(s);
-
- if ((l1 = b->bufsize - b->fp) < l) {
- uiomove(b->buf + b->fp, l1, buf);
- uiomove(b->buf, l - l1, buf);
- if (d->flags & SND_F_XLAT8) {
- translate_bytes(ulaw_dsp, b->buf + b->fp, l1);
- translate_bytes(ulaw_dsp, b->buf, l - l1);
- }
- } else {
- uiomove(b->buf + b->fp, l, buf);
- if (d->flags & SND_F_XLAT8)
- translate_bytes(ulaw_dsp, b->buf + b->fp, l);
- }
-
- s = spltty();
- b->rl += l;
- b->fl -= l;
- b->fp = (b->fp + l) % b->bufsize;
- if (b->dl == 0)
- dma_wrintr(d);
- splx(s);
- }
-
- d->flags &= ~SND_F_WRITING;
-
- return (ret);
-}
-
-static int
-es_dsp_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
-{
- int ret = 0, unit = UNIT(minor(dev));
- snddev_info *d = &pcm_info[unit];
- long s;
-
- if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0))
- return mixer_ioctl(d, cmd, data, fflag, p);
-
- switch(cmd) {
- case AIONWRITE:
- if (d->dbuf_out.dl != 0) {
- s = spltty();
- es_wr_dmaupdate(d);
- splx(s);
- }
- *(int *)data = d->dbuf_out.fl;
- break;
-
- case FIONREAD:
- if (d->dbuf_in.dl != 0) {
- s = spltty();
- es_rd_dmaupdate(d);
- splx(s);
- }
- *(int *)data = d->dbuf_in.rl;
- break;
-
- case SNDCTL_DSP_GETISPACE:
- {
- audio_buf_info *a = (audio_buf_info *)data;
- snd_dbuf *b = &d->dbuf_in;
- if (b->dl != 0) {
- s = spltty();
- es_rd_dmaupdate(d);
- splx(s);
- }
- a->bytes = b->fl;
- a->fragments = b->fl / d->rec_blocksize;
- a->fragstotal = b->bufsize / d->rec_blocksize;
- a->fragsize = d->rec_blocksize;
- }
- break;
-
- case SNDCTL_DSP_GETOSPACE:
- {
- audio_buf_info *a = (audio_buf_info *)data;
- snd_dbuf *b = &d->dbuf_out;
- if (b->dl != 0) {
- s = spltty();
- es_wr_dmaupdate(d);
- splx(s);
- }
- a->bytes = b->fl;
- a->fragments = b->fl / d->rec_blocksize;
- a->fragstotal = b->bufsize / d->play_blocksize;
- a->fragsize = d->play_blocksize;
- }
- break;
-
- case SNDCTL_DSP_GETIPTR:
- {
- count_info *c = (count_info *)data;
- snd_dbuf *b = &d->dbuf_in;
- if (b->dl != 0) {
- s = spltty();
- es_rd_dmaupdate(d);
- splx(s);
- }
- c->bytes = b->total;
- c->blocks = (b->total - b->prev_total +
- d->rec_blocksize - 1) / d->rec_blocksize;
- c->ptr = b->fp;
- b->prev_total = b->total;
- }
- break;
-
- case SNDCTL_DSP_GETOPTR:
- {
- count_info *c = (count_info *)data;
- snd_dbuf *b = &d->dbuf_out;
- if (b->dl != 0) {
- s = spltty();
- es_wr_dmaupdate(d);
- splx(s);
- }
- c->bytes = b->total;
- c->blocks = (b->total - b->prev_total +
- d->play_blocksize - 1) / d->play_blocksize;
- c->ptr = b->rp;
- b->prev_total = b->total;
- }
- break;
-
- case AIOSTOP:
- case SNDCTL_DSP_RESET:
- case SNDCTL_DSP_SYNC:
- ret = EINVAL;
- break;
-
- default:
- ret = ENOSYS;
- break;
- }
- return (ret);
-}
-
-static int
-es_select(dev_t i_dev, int rw, struct proc * p)
-{
- return (ENOSYS);
-}
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * The interrupt handler
- */
-
-static void
-es_intr (void *p)
-{
- snddev_info *d = (snddev_info *)p;
- struct es_info *es = (struct es_info *)d->device_data;
- unsigned intsrc, sctrl;
-
- intsrc = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
- if ((intsrc & STAT_INTR) == 0)
- return;
-
- sctrl = es->sctrl;
- if (intsrc & STAT_ADC)
- sctrl &= ~SCTRL_R1INTEN;
- if (intsrc & STAT_DAC1)
- sctrl &= ~SCTRL_P1INTEN;
- if (intsrc & STAT_DAC2) {
- sctrl &= ~SCTRL_P2INTEN;
- }
- bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, sctrl);
- bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL,
- es->sctrl);
- if (intsrc & STAT_DAC2)
- dma_wrintr(d);
- if (intsrc & STAT_ADC)
- dma_rdintr(d);
-}
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * DMA hassle
- */
-
-static int
-alloc_dmabuf(snddev_info *d, int rd)
-{
- struct es_info *es = (struct es_info *)d->device_data;
- snd_dbuf *b = rd ? &d->dbuf_in : &d->dbuf_out;
- bus_dmamap_t *dmam = rd ? &es->dmam_in : &es->dmam_out;
-
- if (bus_dmamem_alloc(es->parent_dmat, (void **)&b->buf, BUS_DMA_NOWAIT,
- dmam) != 0 ||
- bus_dmamap_load(es->parent_dmat, *dmam, b->buf, d->bufsize,
- rd ? es_rd_map : es_wr_map, es, 0) != 0)
- return -1;
-
- b->rp = b->fp = b->dl = b->rl = 0;
- b->fl = b->bufsize = d->bufsize;
- return (0);
-}
-
-static int
-es_wr_dmaupdate(snddev_info *d)
-{
- struct es_info *es = (struct es_info *)d->device_data;
- unsigned hwptr, delta;
-
- bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE,
- ES1370_REG_DAC2_FRAMECNT >> 8);
- hwptr = (bus_space_read_4(es->st, es->sh,
- ES1370_REG_DAC2_FRAMECNT & 0xff) >> 14) & 0x3fffc;
- delta = (d->dbuf_out.bufsize + hwptr - d->dbuf_out.rp) %
- d->dbuf_out.bufsize;
- d->dbuf_out.rp = hwptr;
- d->dbuf_out.rl -= delta;
- d->dbuf_out.fl += delta;
- d->dbuf_out.total += delta;
-
- return delta;
-}
-
-static int
-es_rd_dmaupdate(snddev_info *d)
-{
- struct es_info *es = (struct es_info *)d->device_data;
- unsigned hwptr, delta;
-
- bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE,
- ES1370_REG_ADC_FRAMECNT >> 8);
- hwptr = (bus_space_read_4(es->st, es->sh,
- ES1370_REG_ADC_FRAMECNT & 0xff) >> 14) & 0x3fffc;
- delta = (d->dbuf_in.bufsize + hwptr - d->dbuf_in.fp) %
- d->dbuf_in.bufsize;
- d->dbuf_in.fp = hwptr;
- d->dbuf_in.rl += delta;
- d->dbuf_in.fl -= delta;
- d->dbuf_in.total += delta;
- return delta;
-}
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * Hardware
- */
-
-static int
-es_callback(snddev_info *d, int reason)
-{
- struct es_info *es = (struct es_info *)d->device_data;
- int rd = reason & SND_CB_RD;
-
- switch(reason & SND_CB_REASON_MASK) {
- case SND_CB_INIT:
- es->ctrl = (es->ctrl & ~CTRL_PCLKDIV) |
- (DAC2_SRTODIV(d->play_speed) << CTRL_SH_PCLKDIV);
- snd_set_blocksize(d);
-
- es->sctrl &= ~(SCTRL_R1FMT | SCTRL_P2FMT);
- d->flags &= ~SND_F_XLAT8;
- switch(d->play_fmt) {
- case 0:
- case AFMT_U8:
- break;
-
- case AFMT_S16_LE:
- es->sctrl |= SCTRL_P2SEB;
- break;
-
- case AFMT_MU_LAW:
- d->flags |= SND_F_XLAT8;
- break;
-
- default:
- return (-1);
- }
-
- switch(d->rec_fmt) {
- case 0:
- case AFMT_U8:
- break;
-
- case AFMT_S16_LE:
- es->sctrl |= SCTRL_R1SEB;
- break;
-
- case AFMT_MU_LAW:
- d->flags |= SND_F_XLAT8;
- break;
-
- default:
- return (-1);
- }
-
- if (d->flags & SND_F_STEREO)
- es->sctrl |= SCTRL_P2SMB | SCTRL_R1SMB;
-
- bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL,
- es->ctrl);
- bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL,
- es->sctrl);
- break;
-
- case SND_CB_START:
- if (rd) {
- es->ctrl |= CTRL_ADC_EN;
- es->sctrl = (es->sctrl & ~SCTRL_R1LOOPSEL) |
- SCTRL_R1INTEN;
- bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_SCOUNT,
- d->dbuf_in.dl / d->dbuf_in.sample_size - 1);
- } else {
- es->ctrl |= CTRL_DAC2_EN;
- es->sctrl = (es->sctrl & ~(SCTRL_P2ENDINC |
- SCTRL_P2STINC | SCTRL_P2LOOPSEL | SCTRL_P2PAUSE |
- SCTRL_P2DACSEN)) | SCTRL_P2INTEN |
- (((d->play_fmt == AFMT_S16_LE) ? 2 : 1)
- << SCTRL_SH_P2ENDINC);
- bus_space_write_4(es->st, es->sh,
- ES1370_REG_DAC2_SCOUNT,
- d->dbuf_out.dl / d->dbuf_out.sample_size - 1);
- }
- bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL,
- es->sctrl);
- bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
- break;
-
- case SND_CB_ABORT:
- case SND_CB_STOP:
- if (rd)
- es->ctrl &= ~CTRL_ADC_EN;
- else
- es->ctrl &= ~CTRL_DAC2_EN;
- bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
- break;
-
- default:
- return (-1);
- }
- return (0);
-}
-
-static int
-write_codec(snddev_info *d, u_char i, u_char data)
-{
- struct es_info *es = (struct es_info *)d->device_data;
- int wait = 100; /* 100 msec timeout */
-
- do {
- if ((bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS) &
- STAT_CSTAT) == 0) {
- bus_space_write_2(es->st, es->sh, ES1370_REG_CODEC,
- ((u_short)i << CODEC_INDEX_SHIFT) | data);
- return (0);
- }
- DELAY(1000);
- /* tsleep(&wait, PZERO, "sndaw", hz / 1000); */
- } while (--wait);
- printf("pcm: write_codec timed out\n");
- return (-1);
-}
-
-static void
-es_wr_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct es_info *es = (struct es_info *)arg;
-
- bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE,
- ES1370_REG_DAC2_FRAMEADR >> 8);
- bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff,
- segs->ds_addr);
- bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMECNT & 0xff,
- (segs->ds_len >> 2) - 1);
-}
-
-static void
-es_rd_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct es_info *es = (struct es_info *)arg;
-
- bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE,
- ES1370_REG_ADC_FRAMEADR >> 8);
- bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMEADR & 0xff,
- segs->ds_addr);
- bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff,
- (segs->ds_len >> 2) - 1);
-}
-
-static void
-dma_wrintr(snddev_info *d)
-{
- snd_dbuf *b = &d->dbuf_out;
-
- /*
- * According to Linux driver:
- * dmaupdate()
- * Bei underrun error++
- * wake_up(dac2.wait)
- */
-
- if (b->dl != 0) {
- es_wr_dmaupdate(d);
- wakeup(b);
- }
-
- if (b->rl >= DMA_ALIGN_THRESHOLD &&
- !(d->flags & SND_F_ABORTING)) {
- int l = min(b->rl, d->play_blocksize);
- l &= DMA_ALIGN_MASK;
-
- if (l != b->dl) {
- if (b->dl != 0) {
- d->callback(d, SND_CB_WR | SND_CB_STOP);
- es_wr_dmaupdate(d);
- l = min(b->rl, d->play_blocksize);
- l &= DMA_ALIGN_MASK;
- }
- b->dl = l;
- d->callback(d, SND_CB_WR | SND_CB_START);
- }
- } else if (b->dl != 0) {
- b->dl = 0;
- d->callback(d, SND_CB_WR | SND_CB_STOP);
- es_wr_dmaupdate(d);
- }
-}
-
-static void
-dma_rdintr(snddev_info *d)
-{
- snd_dbuf *b = &d->dbuf_in;
-
- if (b->dl != 0) {
- es_rd_dmaupdate(d);
- wakeup(b);
- }
-
- if (b->fl >= DMA_READ_THRESHOLD &&
- !(d->flags & SND_F_ABORTING)) {
- int l = min(b->fl, d->rec_blocksize);
- l &= DMA_ALIGN_MASK;
-
- if (l != b->dl) {
- if (b->dl != 0) {
- d->callback(d, SND_CB_RD | SND_CB_STOP);
- es_rd_dmaupdate(d);
- l = min(b->fl, d->rec_blocksize);
- l &= DMA_ALIGN_MASK;
- }
- b->dl = l;
- d->callback(d, SND_CB_RD | SND_CB_START);
- }
- } else {
- if (b->dl != 0) {
- b->dl = 0;
- d->callback(d, SND_CB_RD | SND_CB_STOP);
- es_rd_dmaupdate(d);
- }
- }
-}
-
-static int
-es_wrabort(snddev_info *d)
-{
- snd_dbuf *b = &d->dbuf_out;
- long s;
- int missing;
-
- s = spltty();
- if (b->dl != 0) {
- wakeup(b);
- b->dl = 0;
- d->callback(d, SND_CB_WR | SND_CB_ABORT);
- }
- es_wr_dmaupdate(d);
- missing = b->rl;
- b->rl = 0;
- b->fp = b->rp;
- b->fl = b->bufsize;
- splx(s);
- return missing;
-}
-
-static int
-es_rdabort(snddev_info *d)
-{
- snd_dbuf *b = &d->dbuf_in;
- long s;
- int missing;
-
- s = spltty();
- if (b->dl != 0) {
- wakeup(b);
- b->dl = 0;
- d->callback(d, SND_CB_RD | SND_CB_ABORT);
- es_rd_dmaupdate(d);
- }
- missing = b->rl;
- b->rl = 0;
- b->fp = b->rp;
- b->fl = b->bufsize;
- splx(s);
- return missing;
-}
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * Probe and attach the card
- */
-
-static int
-es_init(snddev_info *d)
-{
- struct es_info *es = (struct es_info *)d->device_data;
- u_int i;
-
- es->ctrl = CTRL_CDC_EN | CTRL_SERR_DIS |
- (DAC2_SRTODIV(DSP_DEFAULT_SPEED) << CTRL_SH_PCLKDIV);
- bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
- es->sctrl = 0;
- bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
- write_codec(d, CODEC_RES_PD, 3);/* No RST, PD */
- write_codec(d, CODEC_CSEL, 0); /* CODEC ADC and CODEC DAC use
- * {LR,B}CLK2 and run off the LRCLK2
- * PLL; program DAC_SYNC=0! */
- write_codec(d, CODEC_ADSEL, 0); /* Recording source is mixer */
- write_codec(d, CODEC_MGAIN, 0); /* MIC amp is 0db */
-
- i = SOUND_MASK_MIC;
- mixer_ioctl(d, SOUND_MIXER_WRITE_RECSRC, (caddr_t) &i, 0, NULL);
- i = 0;
- mixer_ioctl(d, SOUND_MIXER_WRITE_VOLUME, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_PCM, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_SYNTH, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_CD, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_LINE, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_LINE1, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_LINE2, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_LINE3, (caddr_t) &i, 0, NULL);
- mixer_ioctl(d, SOUND_MIXER_WRITE_MIC, (caddr_t) &i, 0, NULL);
-
- return (0);
-}
-
-static const char *
-es_pci_probe(pcici_t tag, pcidi_t type)
-{
- if (type == ES1370_PCI_ID)
- return ("AudioPCI ES1370");
-
- return (NULL);
-}
-
-static void
-es_pci_attach(pcici_t config_id, int unit)
-{
- snddev_info *d;
- u_int32_t data;
- struct es_info *es;
- pci_port_t io_port;
- int i, mapped;
- vm_offset_t vaddr, paddr;
-
- if (unit > NPCM_MAX)
- return;
-
- d = &pcm_info[unit];
- *d = es_op_desc;
- if ((es = malloc(sizeof(*es), M_DEVBUF, M_NOWAIT)) == NULL) {
- printf("pcm%d: cannot allocate softc\n", unit);
- return;
- }
- bzero(es, sizeof(*es));
- d->device_data = es;
-
- vaddr = paddr = NULL;
- mapped = 0;
- data = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
- if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
- if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {
- es->st = MEM_SPACE_MAPPING;
- es->sh = vaddr;
- mapped++;
- }
- }
- if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
- if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {
- es->st = IO_SPACE_MAPPING;
- es->sh = io_port;
- mapped++;
- }
- }
- if (mapped == 0) {
- printf("pcm%d: unable to map any ports\n", unit);
- free(es, M_DEVBUF);
- return;
- }
- printf("pcm%d: using %s space register mapping at %#x\n", unit,
- es->st == IO_SPACE_MAPPING ? "I/O" : "Memory", es->sh);
-
- d->io_base = es->sh;
- d->mix_devs = 0;
- for (i = 0; i != SOUND_MIXER_NRDEVICES; i++)
- if (mixtable[i].avail)
- d->mix_devs |= (1 << i);
- d->mix_rec_devs = 0;
- for (i = 0; i != SOUND_MIXER_NRDEVICES; i++)
- if (mixtable[i].recmask)
- d->mix_rec_devs |= (1 << i);
-
- if (es_init(d) == -1) {
- printf("pcm%d: unable to initialize the card\n", unit);
- free(es, M_DEVBUF);
- d->io_base = 0;
- return;
- }
- if (pci_map_int(config_id, es_intr, d, &tty_imask) == 0) {
- printf("pcm%d: unable to map interrupt\n", unit);
- free(es, M_DEVBUF);
- d->io_base = 0;
- return;
- }
- if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
- /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/BUS_SPACE_MAXADDR,
- /*filter*/NULL, /*filterarg*/NULL,
- /*maxsize*/d->bufsize, /*nsegments*/1, /*maxsegz*/0x3ffff,
- /*flags*/0, &es->parent_dmat) != 0) {
- printf("pcm%d: unable to create dma tag\n", unit);
- free(es, M_DEVBUF);
- d->io_base = 0;
- return;
- }
-
- if (alloc_dmabuf(d, 0) == -1 ||
- alloc_dmabuf(d, 1) == -1) {
- printf("pcm%d: unable to allocate dma buffers\n", unit);
- free(es, M_DEVBUF);
- d->io_base = 0;
- return;
- }
-
- pcminit(d, unit);
-
- return;
-}
diff --git a/sys/pci/es1370_reg.h b/sys/pci/es1370_reg.h
deleted file mode 100644
index a1adc35..0000000
--- a/sys/pci/es1370_reg.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * This supports the ENSONIQ AudioPCI board based on the ES1370.
- *
- * Copyright (c) 1998 Joachim Kuebart <joki@kuebart.stuttgart.netsurf.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Absolutely no warranty of function or purpose is made by the author
- * Joachim Kuebart.
- * 4. Modifications may be freely made to this file if the above conditions
- * are met.
- *
- * $FreeBSD$
- */
-
-#ifndef _ES1370_REG_H
-#define _ES1370_REG_H
-
-#define ES1370_REG_CONTROL 0x00
-#define ES1370_REG_STATUS 0x04
-#define ES1370_REG_UART_DATA 0x08
-#define ES1370_REG_UART_STATUS 0x09
-#define ES1370_REG_UART_CONTROL 0x09
-#define ES1370_REG_UART_TEST 0x0a
-#define ES1370_REG_MEMPAGE 0x0c
-#define ES1370_REG_CODEC 0x10
-#define CODEC_INDEX_SHIFT 8
-#define ES1370_REG_SERIAL_CONTROL 0x20
-#define ES1370_REG_DAC1_SCOUNT 0x24
-#define ES1370_REG_DAC2_SCOUNT 0x28
-#define ES1370_REG_ADC_SCOUNT 0x2c
-
-#define ES1370_REG_DAC1_FRAMEADR 0xc30
-#define ES1370_REG_DAC1_FRAMECNT 0xc34
-#define ES1370_REG_DAC2_FRAMEADR 0xc38
-#define ES1370_REG_DAC2_FRAMECNT 0xc3c
-#define ES1370_REG_ADC_FRAMEADR 0xd30
-#define ES1370_REG_ADC_FRAMECNT 0xd34
-
-#define DAC2_SRTODIV(x) (((1411200 + (x) / 2) / (x) - 2) & 0x1fff)
-#define DAC2_DIVTOSR(x) (1411200 / ((x) + 2))
-
-#define CTRL_ADC_STOP 0x80000000 /* 1 = ADC stopped */
-#define CTRL_XCTL1 0x40000000 /* SERR pin if enabled */
-#define CTRL_OPEN 0x20000000 /* no function, can be read and
- * written */
-#define CTRL_PCLKDIV 0x1fff0000 /* ADC/DAC2 clock divider */
-#define CTRL_SH_PCLKDIV 16
-#define CTRL_MSFMTSEL 0x00008000 /* MPEG serial data fmt: 0 = Sony, 1
- * = I2S */
-#define CTRL_M_SBB 0x00004000 /* DAC2 clock: 0 = PCLKDIV, 1 = MPEG */
-#define CTRL_WTSRSEL 0x00003000 /* DAC1 clock freq: 0=5512, 1=11025,
- * 2=22050, 3=44100 */
-#define CTRL_SH_WTSRSEL 12
-#define CTRL_DAC_SYNC 0x00000800 /* 1 = DAC2 runs off DAC1 clock */
-#define CTRL_CCB_INTRM 0x00000400 /* 1 = CCB "voice" ints enabled */
-#define CTRL_M_CB 0x00000200 /* recording source: 0 = ADC, 1 =
- * MPEG */
-#define CTRL_XCTL0 0x00000100 /* 0 = Line in, 1 = Line out */
-#define CTRL_BREQ 0x00000080 /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN 0x00000040 /* enable DAC1 */
-#define CTRL_DAC2_EN 0x00000020 /* enable DAC2 */
-#define CTRL_ADC_EN 0x00000010 /* enable ADC */
-#define CTRL_UART_EN 0x00000008 /* enable MIDI uart */
-#define CTRL_JYSTK_EN 0x00000004 /* enable Joystick port (presumably
- * at address 0x200) */
-#define CTRL_CDC_EN 0x00000002 /* enable serial (CODEC) interface */
-#define CTRL_SERR_DIS 0x00000001 /* 1 = disable PCI SERR signal */
-
-#define SCTRL_P2ENDINC 0x00380000 /* */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC 0x00070000 /* */
-#define SCTRL_SH_P2STINC 16
-#define SCTRL_R1LOOPSEL 0x00008000 /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL 0x00004000 /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL 0x00002000 /* 0 = loop mode */
-#define SCTRL_P2PAUSE 0x00001000 /* 1 = pause mode */
-#define SCTRL_P1PAUSE 0x00000800 /* 1 = pause mode */
-#define SCTRL_R1INTEN 0x00000400 /* enable interrupt */
-#define SCTRL_P2INTEN 0x00000200 /* enable interrupt */
-#define SCTRL_P1INTEN 0x00000100 /* enable interrupt */
-#define SCTRL_P1SCTRLD 0x00000080 /* reload sample count register for
- * DAC1 */
-#define SCTRL_P2DACSEN 0x00000040 /* 1 = DAC2 play back last sample
- * when disabled */
-#define SCTRL_R1SEB 0x00000020 /* 1 = 16bit */
-#define SCTRL_R1SMB 0x00000010 /* 1 = stereo */
-#define SCTRL_R1FMT 0x00000030 /* format mask */
-#define SCTRL_SH_R1FMT 4
-#define SCTRL_P2SEB 0x00000008 /* 1 = 16bit */
-#define SCTRL_P2SMB 0x00000004 /* 1 = stereo */
-#define SCTRL_P2FMT 0x0000000c /* format mask */
-#define SCTRL_SH_P2FMT 2
-#define SCTRL_P1SEB 0x00000002 /* 1 = 16bit */
-#define SCTRL_P1SMB 0x00000001 /* 1 = stereo */
-#define SCTRL_P1FMT 0x00000003 /* format mask */
-#define SCTRL_SH_P1FMT 0
-
-#define STAT_INTR 0x80000000 /* wired or of all interrupt bits */
-#define STAT_CSTAT 0x00000400 /* 1 = codec busy or codec write in
- * progress */
-#define STAT_CBUSY 0x00000200 /* 1 = codec busy */
-#define STAT_CWRIP 0x00000100 /* 1 = codec write in progress */
-#define STAT_VC 0x00000060 /* CCB int source, 0=DAC1, 1=DAC2,
- * 2=ADC, 3=undef */
-#define STAT_SH_VC 5
-#define STAT_MCCB 0x00000010 /* CCB int pending */
-#define STAT_UART 0x00000008 /* UART int pending */
-#define STAT_DAC1 0x00000004 /* DAC1 int pending */
-#define STAT_DAC2 0x00000002 /* DAC2 int pending */
-#define STAT_ADC 0x00000001 /* ADC int pending */
-
-#define CODEC_OMIX1 0x10
-#define CODEC_OMIX2 0x11
-#define CODEC_LIMIX1 0x12
-#define CODEC_RIMIX1 0x13
-#define CODEC_LIMIX2 0x14
-#define CODEC_RIMIX2 0x15
-#define CODEC_RES_PD 0x16
-#define CODEC_CSEL 0x17
-#define CODEC_ADSEL 0x18
-#define CODEC_MGAIN 0x19
-
-#define ES_BUFFSIZE 0x20000 /* We're PCI! Use a large buffer */
-
-#endif
OpenPOWER on IntegriCloud