/*
    btaudio - bt878 audio dma driver for linux 2.4.x

    (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/sound.h>
#include <linux/soundcard.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
#include <linux/mutex.h>

#include <asm/uaccess.h>
#include <asm/io.h>


/* mmio access */
#define btwrite(dat,adr)    writel((dat), (bta->mmio+(adr)))
#define btread(adr)         readl(bta->mmio+(adr))

#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)

/* registers (shifted because bta->mmio is long) */
#define REG_INT_STAT      (0x100 >> 2)
#define REG_INT_MASK      (0x104 >> 2)
#define REG_GPIO_DMA_CTL  (0x10c >> 2)
#define REG_PACKET_LEN    (0x110 >> 2)
#define REG_RISC_STRT_ADD (0x114 >> 2)
#define REG_RISC_COUNT    (0x120 >> 2)

/* IRQ bits - REG_INT_(STAT|MASK) */
#define IRQ_SCERR         (1 << 19)
#define IRQ_OCERR         (1 << 18)
#define IRQ_PABORT        (1 << 17)
#define IRQ_RIPERR        (1 << 16)
#define IRQ_PPERR         (1 << 15)
#define IRQ_FDSR          (1 << 14)
#define IRQ_FTRGT         (1 << 13)
#define IRQ_FBUS          (1 << 12)
#define IRQ_RISCI         (1 << 11)
#define IRQ_OFLOW         (1 <<  3)

#define IRQ_BTAUDIO       (IRQ_SCERR | IRQ_OCERR | IRQ_PABORT | IRQ_RIPERR |\
			   IRQ_PPERR | IRQ_FDSR  | IRQ_FTRGT  | IRQ_FBUS   |\
			   IRQ_RISCI)

/* REG_GPIO_DMA_CTL bits */
#define DMA_CTL_A_PWRDN   (1 << 26)
#define DMA_CTL_DA_SBR    (1 << 14)
#define DMA_CTL_DA_ES2    (1 << 13)
#define DMA_CTL_ACAP_EN   (1 <<  4)
#define DMA_CTL_RISC_EN   (1 <<  1)
#define DMA_CTL_FIFO_EN   (1 <<  0)

/* RISC instructions */
#define RISC_WRITE        (0x01 << 28)
#define RISC_JUMP         (0x07 << 28)
#define RISC_SYNC         (0x08 << 28)

/* RISC bits */
#define RISC_WR_SOL       (1 << 27)
#define RISC_WR_EOL       (1 << 26)
#define RISC_IRQ          (1 << 24)
#define RISC_SYNC_RESYNC  (1 << 15)
#define RISC_SYNC_FM1     0x06
#define RISC_SYNC_VRO     0x0c

#define HWBASE_AD (448000)

/* -------------------------------------------------------------- */

struct btaudio {
	/* linked list */
	struct btaudio *next;

	/* device info */
	int            dsp_digital;
	int            dsp_analog;
	int            mixer_dev;
	struct pci_dev *pci;
	unsigned int   irq;
	unsigned long  mem;
	unsigned long  __iomem *mmio;

	/* locking */
	int            users;
	struct mutex lock;

	/* risc instructions */
	unsigned int   risc_size;
	unsigned long  *risc_cpu;
	dma_addr_t     risc_dma;

	/* audio data */
	unsigned int   buf_size;
	unsigned char  *buf_cpu;
	dma_addr_t     buf_dma;

	/* buffer setup */
	int line_bytes;
	int line_count;
	int block_bytes;
	int block_count;

	/* read fifo management */
	int recording;
	int dma_block;
	int read_offset;
	int read_count;
	wait_queue_head_t readq;

	/* settings */
	int gain[3];
	int source;
	int bits;
	int decimation;
	int mixcount;
	int sampleshift;
	int channels;
	int analog;
	int rate;
};

struct cardinfo {
	char *name;
	int rate;
};

static struct btaudio *btaudios;
static unsigned int debug;
static unsigned int irq_debug;

/* -------------------------------------------------------------- */

#define BUF_DEFAULT 128*1024
#define BUF_MIN         8192

static int alloc_buffer(struct btaudio *bta)
{
	if (NULL == bta->buf_cpu) {
		for (bta->buf_size = BUF_DEFAULT; bta->buf_size >= BUF_MIN;
		     bta->buf_size = bta->buf_size >> 1) {
			bta->buf_cpu = pci_alloc_consistent
				(bta->pci, bta->buf_size, &bta->buf_dma);
			if (NULL != bta->buf_cpu)
				break;
		}
		if (NULL == bta->buf_cpu)
			return -ENOMEM;
		memset(bta->buf_cpu,0,bta->buf_size);
	}
	if (NULL == bta->risc_cpu) {
		bta->risc_size = PAGE_SIZE;
		bta->risc_cpu = pci_alloc_consistent
			(bta->pci, bta->risc_size, &bta->risc_dma);
		if (NULL == bta->risc_cpu) {
			pci_free_consistent(bta->pci, bta->buf_size, bta->buf_cpu, bta->buf_dma);
			bta->buf_cpu = NULL;
			return -ENOMEM;
		}
	}
	return 0;
}

static void free_buffer(struct btaudio *bta)
{
	if (NULL != bta->buf_cpu) {
		pci_free_consistent(bta->pci, bta->buf_size,
				    bta->buf_cpu, bta->buf_dma);
		bta->buf_cpu = NULL;
	}
	if (NULL != bta->risc_cpu) {
		pci_free_consistent(bta->pci, bta->risc_size,
				    bta->risc_cpu, bta->risc_dma);
		bta->risc_cpu = NULL;
	}
}

static int make_risc(struct btaudio *bta)
{
	int rp, bp, line, block;
	unsigned long risc;

	bta->block_bytes = bta->buf_size >> 4;
	bta->block_count = 1 << 4;
	bta->line_bytes  = bta->block_bytes;
	bta->line_count  = bta->block_count;
	while (bta->line_bytes > 4095) {
		bta->line_bytes >>= 1;
		bta->line_count <<= 1;
	}
	if (bta->line_count > 255)
		return -EINVAL;
	if (debug)
		printk(KERN_DEBUG
		       "btaudio: bufsize=%d - bs=%d bc=%d - ls=%d, lc=%d\n",
		       bta->buf_size,bta->block_bytes,bta->block_count,
		       bta->line_bytes,bta->line_count);
        rp = 0; bp = 0;
	block = 0;
	bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_FM1);
	bta->risc_cpu[rp++] = cpu_to_le32(0);
	for (line = 0; line < bta->line_count; line++) {
		risc  = RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL;
		risc |= bta->line_bytes;
		if (0 == (bp & (bta->block_bytes-1))) {
			risc |= RISC_IRQ;
			risc |= (block  & 0x0f) << 16;
			risc |= (~block & 0x0f) << 20;
			block++;
		}
		bta->risc_cpu[rp++] = cpu_to_le32(risc);
		bta->risc_cpu[rp++] = cpu_to_le32(bta->buf_dma + bp);
		bp += bta->line_bytes;
	}
	bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_VRO);
	bta->risc_cpu[rp++] = cpu_to_le32(0);
	bta->risc_cpu[rp++] = cpu_to_le32(RISC_JUMP); 
	bta->risc_cpu[rp++] = cpu_to_le32(bta->risc_dma);
	return 0;
}

static int start_recording(struct btaudio *bta)
{
	int ret;

	if (0 != (ret = alloc_buffer(bta)))
		return ret;
	if (0 != (ret = make_risc(bta)))
		return ret;

	btwrite(bta->risc_dma, REG_RISC_STRT_ADD);
	btwrite((bta->line_count << 16) | bta->line_bytes,
		REG_PACKET_LEN);
	btwrite(IRQ_BTAUDIO, REG_INT_MASK);
	if (bta->analog) {
		btwrite(DMA_CTL_ACAP_EN |
			DMA_CTL_RISC_EN |
			DMA_CTL_FIFO_EN |
			DMA_CTL_DA_ES2  |
			((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) |
			(bta->gain[bta->source] << 28) |
			(bta->source            << 24) |
			(bta->decimation        <<  8),
			REG_GPIO_DMA_CTL);
	} else {
		btwrite(DMA_CTL_ACAP_EN |
			DMA_CTL_RISC_EN |
			DMA_CTL_FIFO_EN |
			DMA_CTL_DA_ES2  |
			DMA_CTL_A_PWRDN |
			(1 << 6)   |
			((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) |
			(bta->gain[bta->source] << 28) |
			(bta->source            << 24) |
			(bta->decimation        <<  8),
			REG_GPIO_DMA_CTL);
	}
	bta->dma_block = 0;
	bta->read_offset = 0;
	bta->read_count = 0;
	bta->recording = 1;
	if (debug)
		printk(KERN_DEBUG "btaudio: recording started\n");
	return 0;
}

static void stop_recording(struct btaudio *bta)
{
        btand(~15, REG_GPIO_DMA_CTL);
	bta->recording = 0;
	if (debug)
		printk(KERN_DEBUG "btaudio: recording stopped\n");
}


/* -------------------------------------------------------------- */

static int btaudio_mixer_open(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	struct btaudio *bta;

	for (bta = btaudios; bta != NULL; bta = bta->next)
		if (bta->mixer_dev == minor)
			break;
	if (NULL == bta)
		return -ENODEV;

	if (debug)
		printk("btaudio: open mixer [%d]\n",minor);
	file->private_data = bta;
	return 0;
}

static int btaudio_mixer_release(struct inode *inode, struct file *file)
{
	return 0;
}

static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
			       unsigned int cmd, unsigned long arg)
{
	struct btaudio *bta = file->private_data;
	int ret,val=0,i=0;
	void __user *argp = (void __user *)arg;

	if (cmd == SOUND_MIXER_INFO) {
		mixer_info info;
		memset(&info,0,sizeof(info));
                strlcpy(info.id,"bt878",sizeof(info.id));
                strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
                info.modify_counter = bta->mixcount;
                if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
		return 0;
	}
	if (cmd == SOUND_OLD_MIXER_INFO) {
		_old_mixer_info info;
		memset(&info,0,sizeof(info));
                strlcpy(info.id, "bt878", sizeof(info.id));
                strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
                if (copy_to_user(argp, &info, sizeof(info)))
                        return -EFAULT;
		return 0;
	}
	if (cmd == OSS_GETVERSION)
		return put_user(SOUND_VERSION, (int __user *)argp);

	/* read */
	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
		if (get_user(val, (int __user *)argp))
			return -EFAULT;

	switch (cmd) {
	case MIXER_READ(SOUND_MIXER_CAPS):
		ret = SOUND_CAP_EXCL_INPUT;
		break;
	case MIXER_READ(SOUND_MIXER_STEREODEVS):
		ret = 0;
		break;
	case MIXER_READ(SOUND_MIXER_RECMASK):
	case MIXER_READ(SOUND_MIXER_DEVMASK):
		ret = SOUND_MASK_LINE1|SOUND_MASK_LINE2|SOUND_MASK_LINE3;
		break;

	case MIXER_WRITE(SOUND_MIXER_RECSRC):
		if (val & SOUND_MASK_LINE1 && bta->source != 0)
			bta->source = 0;
		else if (val & SOUND_MASK_LINE2 && bta->source != 1)
			bta->source = 1;
		else if (val & SOUND_MASK_LINE3 && bta->source != 2)
			bta->source = 2;
		btaor((bta->gain[bta->source] << 28) |
		      (bta->source            << 24),
		      0x0cffffff, REG_GPIO_DMA_CTL);
	case MIXER_READ(SOUND_MIXER_RECSRC):
		switch (bta->source) {
		case 0:  ret = SOUND_MASK_LINE1; break;
		case 1:  ret = SOUND_MASK_LINE2; break;
		case 2:  ret = SOUND_MASK_LINE3; break;
		default: ret = 0;
		}
		break;

	case MIXER_WRITE(SOUND_MIXER_LINE1):
	case MIXER_WRITE(SOUND_MIXER_LINE2):
	case MIXER_WRITE(SOUND_MIXER_LINE3):
		if (MIXER_WRITE(SOUND_MIXER_LINE1) == cmd)
			i = 0;
		if (MIXER_WRITE(SOUND_MIXER_LINE2) == cmd)
			i = 1;
		if (MIXER_WRITE(SOUND_MIXER_LINE3) == cmd)
			i = 2;
		bta->gain[i] = (val & 0xff) * 15 / 100;
		if (bta->gain[i] > 15) bta->gain[i] = 15;
		if (bta->gain[i] <  0) bta->gain[i] =  0;
		if (i == bta->source)
			btaor((bta->gain[bta->source]<<28),
			      0x0fffffff, REG_GPIO_DMA_CTL);
		ret  = bta->gain[i] * 100 / 15;
		ret |= ret << 8;
		break;

	case MIXER_READ(SOUND_MIXER_LINE1):
	case MIXER_READ(SOUND_MIXER_LINE2):
	case MIXER_READ(SOUND_MIXER_LINE3):
		if (MIXER_READ(SOUND_MIXER_LINE1) == cmd)
			i = 0;
		if (MIXER_READ(SOUND_MIXER_LINE2) == cmd)
			i = 1;
		if (MIXER_READ(SOUND_MIXER_LINE3) == cmd)
			i = 2;
		ret  = bta->gain[i] * 100 / 15;
		ret |= ret << 8;
		break;

	default:
		return -EINVAL;
	}
	if (put_user(ret, (int __user *)argp))
		return -EFAULT;
	return 0;
}

static const struct file_operations btaudio_mixer_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.open		= btaudio_mixer_open,
	.release	= btaudio_mixer_release,
	.ioctl		= btaudio_mixer_ioctl,
};

/* -------------------------------------------------------------- */

static int btaudio_dsp_open(struct inode *inode, struct file *file,
			    struct btaudio *bta, int analog)
{
	mutex_lock(&bta->lock);
	if (bta->users)
		goto busy;
	bta->users++;
	file->private_data = bta;

	bta->analog = analog;
	bta->dma_block = 0;
	bta->read_offset = 0;
	bta->read_count = 0;
	bta->sampleshift = 0;

	mutex_unlock(&bta->lock);
	return 0;

 busy:
	mutex_unlock(&bta->lock);
	return -EBUSY;
}

static int btaudio_dsp_open_digital(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	struct btaudio *bta;

	for (bta = btaudios; bta != NULL; bta = bta->next)
		if (bta->dsp_digital == minor)
			break;
	if (NULL == bta)
		return -ENODEV;
	
	if (debug)
		printk("btaudio: open digital dsp [%d]\n",minor);
	return btaudio_dsp_open(inode,file,bta,0);
}

static int btaudio_dsp_open_analog(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	struct btaudio *bta;

	for (bta = btaudios; bta != NULL; bta = bta->next)
		if (bta->dsp_analog == minor)
			break;
	if (NULL == bta)
		return -ENODEV;

	if (debug)
		printk("btaudio: open analog dsp [%d]\n",minor);
	return btaudio_dsp_open(inode,file,bta,1);
}

static int btaudio_dsp_release(struct inode *inode, struct file *file)
{
	struct btaudio *bta = file->private_data;

	mutex_lock(&bta->lock);
	if (bta->recording)
		stop_recording(bta);
	bta->users--;
	mutex_unlock(&bta->lock);
	return 0;
}

static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
				size_t swcount, loff_t *ppos)
{
	struct btaudio *bta = file->private_data;
	int hwcount = swcount << bta->sampleshift;
	int nsrc, ndst, err, ret = 0;
	DECLARE_WAITQUEUE(wait, current);

	add_wait_queue(&bta->readq, &wait);
	mutex_lock(&bta->lock);
	while (swcount > 0) {
		if (0 == bta->read_count) {
			if (!bta->recording) {
				if (0 != (err = start_recording(bta))) {
					if (0 == ret)
						ret = err;
					break;
				}
			}
			if (file->f_flags & O_NONBLOCK) {
				if (0 == ret)
					ret = -EAGAIN;
				break;
			}
			mutex_unlock(&bta->lock);
			current->state = TASK_INTERRUPTIBLE;
			schedule();
			mutex_lock(&bta->lock);
			if(signal_pending(current)) {
				if (0 == ret)
					ret = -EINTR;
				break;
			}
		}
		nsrc = (bta->read_count < hwcount) ? bta->read_count : hwcount;
		if (nsrc > bta->buf_size - bta->read_offset)
			nsrc = bta->buf_size - bta->read_offset;
		ndst = nsrc >> bta->sampleshift;
		
		if ((bta->analog  && 0 == bta->sampleshift) ||
		    (!bta->analog && 2 == bta->channels)) {
			/* just copy */
			if (copy_to_user(buffer + ret, bta->buf_cpu + bta->read_offset, nsrc)) {
				if (0 == ret)
					ret = -EFAULT;
				break;
			}

		} else if (!bta->analog) {
			/* stereo => mono (digital audio) */
			__s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset);
			__s16 __user *dst = (__s16 __user *)(buffer + ret);
			__s16 avg;
			int n = ndst>>1;
			if (!access_ok(VERIFY_WRITE, dst, ndst)) {
				if (0 == ret)
					ret = -EFAULT;
				break;
			}
			for (; n; n--, dst++) {
				avg  = (__s16)le16_to_cpu(*src) / 2; src++;
				avg += (__s16)le16_to_cpu(*src) / 2; src++;
				__put_user(cpu_to_le16(avg),dst);
			}

		} else if (8 == bta->bits) {
			/* copy + byte downsampling (audio A/D) */
			__u8 *src = bta->buf_cpu + bta->read_offset;
			__u8 __user *dst = buffer + ret;
			int n = ndst;
			if (!access_ok(VERIFY_WRITE, dst, ndst)) {
				if (0 == ret)
					ret = -EFAULT;
				break;
			}
			for (; n; n--, src += (1 << bta->sampleshift), dst++)
				__put_user(*src, dst);

		} else {
			/* copy + word downsampling (audio A/D) */
			__u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset);
			__u16 __user *dst = (__u16 __user *)(buffer + ret);
			int n = ndst>>1;
			if (!access_ok(VERIFY_WRITE,dst,ndst)) {
				if (0 == ret)
					ret = -EFAULT;
				break;
			}
			for (; n; n--, src += (1 << bta->sampleshift), dst++)
				__put_user(*src, dst);
		}

		ret     += ndst;
		swcount -= ndst;
		hwcount -= nsrc;
		bta->read_count  -= nsrc;
		bta->read_offset += nsrc;
		if (bta->read_offset == bta->buf_size)
			bta->read_offset = 0;
	}
	mutex_unlock(&bta->lock);
	remove_wait_queue(&bta->readq, &wait);
	current->state = TASK_RUNNING;
	return ret;
}

static ssize_t btaudio_dsp_write(struct file *file, const char __user *buffer,
				 size_t count, loff_t *ppos)
{
	return -EINVAL;
}

static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
			     unsigned int cmd, unsigned long arg)
{
	struct btaudio *bta = file->private_data;
	int s, i, ret, val = 0;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	
        switch (cmd) {
        case OSS_GETVERSION:
                return put_user(SOUND_VERSION, p);
        case SNDCTL_DSP_GETCAPS:
		return 0;

        case SNDCTL_DSP_SPEED:
		if (get_user(val, p))
			return -EFAULT;
		if (bta->analog) {
			for (s = 0; s < 16; s++)
				if (val << s >= HWBASE_AD*4/15)
					break;
			for (i = 15; i >= 5; i--)
				if (val << s <= HWBASE_AD*4/i)
					break;
			bta->sampleshift = s;
			bta->decimation  = i;
			if (debug)
				printk(KERN_DEBUG "btaudio: rate: req=%d  "
				       "dec=%d shift=%d hwrate=%d swrate=%d\n",
				       val,i,s,(HWBASE_AD*4/i),(HWBASE_AD*4/i)>>s);
		} else {
			bta->sampleshift = (bta->channels == 2) ? 0 : 1;
			bta->decimation  = 0;
		}
		if (bta->recording) {
			mutex_lock(&bta->lock);
			stop_recording(bta);
			start_recording(bta);
			mutex_unlock(&bta->lock);
		}
		/* fall through */
        case SOUND_PCM_READ_RATE:
		if (bta->analog) {
			return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, p);
		} else {
			return put_user(bta->rate, p);
		}

        case SNDCTL_DSP_STEREO:
		if (!bta->analog) {
			if (get_user(val, p))
				return -EFAULT;
			bta->channels    = (val > 0) ? 2 : 1;
			bta->sampleshift = (bta->channels == 2) ? 0 : 1;
			if (debug)
				printk(KERN_INFO
				       "btaudio: stereo=%d channels=%d\n",
				       val,bta->channels);
		} else {
			if (val == 1)
				return -EFAULT;
			else {
				bta->channels = 1;
				if (debug)
					printk(KERN_INFO
					       "btaudio: stereo=0 channels=1\n");
			}
		}
		return put_user((bta->channels)-1, p);

        case SNDCTL_DSP_CHANNELS:
		if (!bta->analog) {
			if (get_user(val, p))
				return -EFAULT;
			bta->channels    = (val > 1) ? 2 : 1;
			bta->sampleshift = (bta->channels == 2) ? 0 : 1;
			if (debug)
				printk(KERN_DEBUG
				       "btaudio: val=%d channels=%d\n",
				       val,bta->channels);
		}
		/* fall through */
        case SOUND_PCM_READ_CHANNELS:
		return put_user(bta->channels, p);
		
        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
		if (bta->analog)
			return put_user(AFMT_S16_LE|AFMT_S8, p);
		else
			return put_user(AFMT_S16_LE, p);

        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
		if (get_user(val, p))
			return -EFAULT;
                if (val != AFMT_QUERY) {
			if (bta->analog)
				bta->bits = (val == AFMT_S8) ? 8 : 16;
			else
				bta->bits = 16;
			if (bta->recording) {
				mutex_lock(&bta->lock);
				stop_recording(bta);
				start_recording(bta);
				mutex_unlock(&bta->lock);
			}
		}
		if (debug)
			printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits);
                return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8,
				p);
		break;
        case SOUND_PCM_READ_BITS:
		return put_user(bta->bits, p);

        case SNDCTL_DSP_NONBLOCK:
                file->f_flags |= O_NONBLOCK;
                return 0;

        case SNDCTL_DSP_RESET:
		if (bta->recording) {
			mutex_lock(&bta->lock);
			stop_recording(bta);
			mutex_unlock(&bta->lock);
		}
		return 0;
        case SNDCTL_DSP_GETBLKSIZE:
		if (!bta->recording) {
			if (0 != (ret = alloc_buffer(bta)))
				return ret;
			if (0 != (ret = make_risc(bta)))
				return ret;
		}
		return put_user(bta->block_bytes>>bta->sampleshift,p);

        case SNDCTL_DSP_SYNC:
		/* NOP */
		return 0;
	case SNDCTL_DSP_GETISPACE:
	{
		audio_buf_info info;
		if (!bta->recording)
			return -EINVAL;
		info.fragsize = bta->block_bytes>>bta->sampleshift;
		info.fragstotal = bta->block_count;
		info.bytes = bta->read_count;
		info.fragments = info.bytes / info.fragsize;
		if (debug)
			printk(KERN_DEBUG "btaudio: SNDCTL_DSP_GETISPACE "
			       "returns %d/%d/%d/%d\n",
			       info.fragsize, info.fragstotal,
			       info.bytes, info.fragments);
		if (copy_to_user(argp, &info, sizeof(info)))
			return -EFAULT;
		return 0;
	}
#if 0 /* TODO */
        case SNDCTL_DSP_GETTRIGGER:
        case SNDCTL_DSP_SETTRIGGER:
        case SNDCTL_DSP_SETFRAGMENT:
#endif
	default:
		return -EINVAL;
	}
}

static unsigned int btaudio_dsp_poll(struct file *file, struct poll_table_struct *wait)
{
	struct btaudio *bta = file->private_data;
	unsigned int mask = 0;

	poll_wait(file, &bta->readq, wait);

	if (0 != bta->read_count)
		mask |= (POLLIN | POLLRDNORM);

	return mask;
}

static const struct file_operations btaudio_digital_dsp_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.open		= btaudio_dsp_open_digital,
	.release	= btaudio_dsp_release,
	.read		= btaudio_dsp_read,
	.write		= btaudio_dsp_write,
	.ioctl		= btaudio_dsp_ioctl,
	.poll		= btaudio_dsp_poll,
};

static const struct file_operations btaudio_analog_dsp_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.open		= btaudio_dsp_open_analog,
	.release	= btaudio_dsp_release,
	.read		= btaudio_dsp_read,
	.write		= btaudio_dsp_write,
	.ioctl		= btaudio_dsp_ioctl,
	.poll		= btaudio_dsp_poll,
};

/* -------------------------------------------------------------- */

static char *irq_name[] = { "", "", "", "OFLOW", "", "", "", "", "", "", "",
			    "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR",
			    "RIPERR", "PABORT", "OCERR", "SCERR" };

static irqreturn_t btaudio_irq(int irq, void *dev_id)
{
	int count = 0;
	u32 stat,astat;
	struct btaudio *bta = dev_id;
	int handled = 0;

	for (;;) {
		count++;
		stat  = btread(REG_INT_STAT);
		astat = stat & btread(REG_INT_MASK);
		if (!astat)
			return IRQ_RETVAL(handled);
		handled = 1;
		btwrite(astat,REG_INT_STAT);

		if (irq_debug) {
			int i;
			printk(KERN_DEBUG "btaudio: irq loop=%d risc=%x, bits:",
			       count, stat>>28);
			for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) {
				if (stat & (1 << i))
					printk(" %s",irq_name[i]);
				if (astat & (1 << i))
					printk("*");
			}
			printk("\n");
		}
		if (stat & IRQ_RISCI) {
			int blocks;
			blocks = (stat >> 28) - bta->dma_block;
			if (blocks < 0)
				blocks += bta->block_count;
			bta->dma_block = stat >> 28;
			if (bta->read_count + 2*bta->block_bytes > bta->buf_size) {
				stop_recording(bta);
				printk(KERN_INFO "btaudio: buffer overrun\n");
			}
			if (blocks > 0) {
				bta->read_count += blocks * bta->block_bytes;
				wake_up_interruptible(&bta->readq);
			}
		}
		if (count > 10) {
			printk(KERN_WARNING
			       "btaudio: Oops - irq mask cleared\n");
			btwrite(0, REG_INT_MASK);
		}
	}
	return IRQ_NONE;
}

/* -------------------------------------------------------------- */

static unsigned int dsp1 = -1;
static unsigned int dsp2 = -1;
static unsigned int mixer = -1;
static int latency = -1;
static int digital = 1;
static int analog = 1;
static int rate;

#define BTA_OSPREY200 1

static struct cardinfo cards[] = {
	[0] = {
		.name	= "default",
		.rate	= 32000,
	},
	[BTA_OSPREY200] = {
		.name	= "Osprey 200",
		.rate	= 44100,
	},
};

static int __devinit btaudio_probe(struct pci_dev *pci_dev,
				   const struct pci_device_id *pci_id)
{
	struct btaudio *bta;
	struct cardinfo *card = &cards[pci_id->driver_data];
	unsigned char revision,lat;
	int rc = -EBUSY;

	if (pci_enable_device(pci_dev))
		return -EIO;
	if (!request_mem_region(pci_resource_start(pci_dev,0),
				pci_resource_len(pci_dev,0),
				"btaudio")) {
		return -EBUSY;
	}

	bta = kzalloc(sizeof(*bta),GFP_ATOMIC);
	if (!bta) {
		rc = -ENOMEM;
		goto fail0;
	}

	bta->pci  = pci_dev;
	bta->irq  = pci_dev->irq;
	bta->mem  = pci_resource_start(pci_dev,0);
	bta->mmio = ioremap(pci_resource_start(pci_dev,0),
			    pci_resource_len(pci_dev,0));

	bta->source     = 1;
	bta->bits       = 8;
	bta->channels   = 1;
	if (bta->analog) {
		bta->decimation  = 15;
	} else {
		bta->decimation  = 0;
		bta->sampleshift = 1;
	}

	/* sample rate */
	bta->rate = card->rate;
	if (rate)
		bta->rate = rate;
	
	mutex_init(&bta->lock);
        init_waitqueue_head(&bta->readq);

	if (-1 != latency) {
		printk(KERN_INFO "btaudio: setting pci latency timer to %d\n",
		       latency);
		pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
	}
        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
        pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &lat);
        printk(KERN_INFO "btaudio: Bt%x (rev %d) at %02x:%02x.%x, ",
	       pci_dev->device,revision,pci_dev->bus->number,
	       PCI_SLOT(pci_dev->devfn),PCI_FUNC(pci_dev->devfn));
        printk("irq: %d, latency: %d, mmio: 0x%lx\n",
	       bta->irq, lat, bta->mem);
	printk("btaudio: using card config \"%s\"\n", card->name);

	/* init hw */
        btwrite(0, REG_GPIO_DMA_CTL);
        btwrite(0, REG_INT_MASK);
        btwrite(~0U, REG_INT_STAT);
	pci_set_master(pci_dev);

	if ((rc = request_irq(bta->irq, btaudio_irq, IRQF_SHARED|IRQF_DISABLED,
			      "btaudio",(void *)bta)) < 0) {
		printk(KERN_WARNING
		       "btaudio: can't request irq (rc=%d)\n",rc);
		goto fail1;
	}

	/* register devices */
	if (digital) {
		rc = bta->dsp_digital =
			register_sound_dsp(&btaudio_digital_dsp_fops,dsp1);
		if (rc < 0) {
			printk(KERN_WARNING
			       "btaudio: can't register digital dsp (rc=%d)\n",rc);
			goto fail2;
		}
		printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n",
		       bta->dsp_digital >> 4);
	}
	if (analog) {
		rc = bta->dsp_analog =
			register_sound_dsp(&btaudio_analog_dsp_fops,dsp2);
		if (rc < 0) {
			printk(KERN_WARNING
			       "btaudio: can't register analog dsp (rc=%d)\n",rc);
			goto fail3;
		}
		printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n",
		       bta->dsp_analog >> 4);
		rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops,mixer);
		if (rc < 0) {
			printk(KERN_WARNING
			       "btaudio: can't register mixer (rc=%d)\n",rc);
			goto fail4;
		}
		printk(KERN_INFO "btaudio: registered device mixer%d\n",
		       bta->mixer_dev >> 4);
	}

	/* hook into linked list */
	bta->next = btaudios;
	btaudios = bta;

	pci_set_drvdata(pci_dev,bta);
        return 0;

 fail4:
	unregister_sound_dsp(bta->dsp_analog);
 fail3:
	if (digital)
		unregister_sound_dsp(bta->dsp_digital);
 fail2:
        free_irq(bta->irq,bta);	
 fail1:
	iounmap(bta->mmio);
	kfree(bta);
 fail0:
	release_mem_region(pci_resource_start(pci_dev,0),
			   pci_resource_len(pci_dev,0));
	return rc;
}

static void __devexit btaudio_remove(struct pci_dev *pci_dev)
{
	struct btaudio *bta = pci_get_drvdata(pci_dev);
	struct btaudio *walk;

	/* turn off all DMA / IRQs */
        btand(~15, REG_GPIO_DMA_CTL);
        btwrite(0, REG_INT_MASK);
        btwrite(~0U, REG_INT_STAT);

	/* unregister devices */
	if (digital) {
		unregister_sound_dsp(bta->dsp_digital);
	}
	if (analog) {
		unregister_sound_dsp(bta->dsp_analog);
		unregister_sound_mixer(bta->mixer_dev);
	}

	/* free resources */
	free_buffer(bta);
        free_irq(bta->irq,bta);
	release_mem_region(pci_resource_start(pci_dev,0),
			   pci_resource_len(pci_dev,0));
	iounmap(bta->mmio);

	/* remove from linked list */
	if (bta == btaudios) {
		btaudios = NULL;
	} else {
		for (walk = btaudios; walk->next != bta; walk = walk->next)
			; /* if (NULL == walk->next) BUG(); */
		walk->next = bta->next;
	}

	pci_set_drvdata(pci_dev, NULL);
	kfree(bta);
	return;
}

/* -------------------------------------------------------------- */

static struct pci_device_id btaudio_pci_tbl[] = {
        {
		.vendor		= PCI_VENDOR_ID_BROOKTREE,
		.device		= 0x0878,
		.subvendor	= 0x0070,
		.subdevice	= 0xff01,
		.driver_data	= BTA_OSPREY200,
	},{
		.vendor		= PCI_VENDOR_ID_BROOKTREE,
		.device		= 0x0878,
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
	},{
		.vendor		= PCI_VENDOR_ID_BROOKTREE,
		.device		= 0x0878,
		.subvendor	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
        },{
		/* --- end of list --- */
	}
};

static struct pci_driver btaudio_pci_driver = {
        .name		= "btaudio",
        .id_table	= btaudio_pci_tbl,
        .probe		= btaudio_probe,
        .remove		=  __devexit_p(btaudio_remove),
};

static int btaudio_init_module(void)
{
	printk(KERN_INFO "btaudio: driver version 0.7 loaded [%s%s%s]\n",
	       digital ? "digital" : "",
	       analog && digital ? "+" : "",
	       analog ? "analog" : "");
	return pci_register_driver(&btaudio_pci_driver);
}

static void btaudio_cleanup_module(void)
{
	pci_unregister_driver(&btaudio_pci_driver);
	return;
}

module_init(btaudio_init_module);
module_exit(btaudio_cleanup_module);

module_param(dsp1, int, S_IRUGO);
module_param(dsp2, int, S_IRUGO);
module_param(mixer, int, S_IRUGO);
module_param(debug, int, S_IRUGO | S_IWUSR);
module_param(irq_debug, int, S_IRUGO | S_IWUSR);
module_param(digital, int, S_IRUGO);
module_param(analog, int, S_IRUGO);
module_param(rate, int, S_IRUGO);
module_param(latency, int, S_IRUGO);
MODULE_PARM_DESC(latency,"pci latency timer");

MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl);
MODULE_DESCRIPTION("bt878 audio dma driver");
MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL");

/*
 * Local variables:
 * c-basic-offset: 8
 * End:
 */
