summary refs log tree commit diff
path: root/sound/oss/btaudio.c
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@kernel.org>2008-02-06 01:36:36 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 10:41:02 -0800
commit83bad1d764b836a482b88e0a1f44d7a5c3e1fee0 (patch)
tree2fe0844d81a178ab51c22f41accef9b332ea86b6 /sound/oss/btaudio.c
parentb4cf9c342a2887f425780c23ad2be3077949cee2 (diff)
downloadlinux-83bad1d764b836a482b88e0a1f44d7a5c3e1fee0.tar.gz
scheduled OSS driver removal
This patch contains the scheduled removal of OSS drivers whose config
options have been removed in 2.6.23.

Signed-off-by: Adrian Bunk <bunk@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'sound/oss/btaudio.c')
-rw-r--r--sound/oss/btaudio.c1139
1 files changed, 0 insertions, 1139 deletions
diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c
deleted file mode 100644
index 4d5cf05b8922..000000000000
--- a/sound/oss/btaudio.c
+++ /dev/null
@@ -1,1139 +0,0 @@
-/*
-    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:
- */