/*
*
* device driver for philips saa7134 based TV cards
* oss dsp interface
*
* (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
* 2005 conversion to standalone module:
* Ricardo Cerqueira <v4l@cerqueira.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/init.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/sound.h>
#include <linux/soundcard.h>
#include "saa7134-reg.h"
#include "saa7134.h"
/* ------------------------------------------------------------------ */
static unsigned int debug = 0;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable debug messages [oss]");
static unsigned int rate = 0;
module_param(rate, int, 0444);
MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)");
static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s).");
module_param_array(dsp_nr, int, NULL, 0444);
static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s).");
module_param_array(mixer_nr, int, NULL, 0444);
#define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
/* ------------------------------------------------------------------ */
static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
{
if (blksize < 0x100)
blksize = 0x100;
if (blksize > 0x10000)
blksize = 0x10000;
if (blocks < 2)
blocks = 2;
if ((blksize * blocks) > 1024*1024)
blocks = 1024*1024 / blksize;
dev->dmasound.blocks = blocks;
dev->dmasound.blksize = blksize;
dev->dmasound.bufsize = blksize * blocks;
dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
blocks,blksize,blksize * blocks / 1024);
return 0;
}
static int dsp_buffer_init(struct saa7134_dev *dev)
{
int err;
BUG_ON(!dev->dmasound.bufsize);
videobuf_dma_init(&dev->dmasound.dma);
err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
(dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
if (0 != err)
return err;
return 0;
}
static int dsp_buffer_free(struct saa7134_dev *dev)
{
BUG_ON(!dev->dmasound.blksize);
videobuf_dma_free(&dev->dmasound.dma);
dev->dmasound.blocks = 0;
dev->dmasound.blksize = 0;
dev->dmasound.bufsize = 0;
return 0;
}
static void dsp_dma_start(struct saa7134_dev *dev)
{
dev->dmasound.dma_blk = 0;
dev->dmasound.dma_running = 1;
saa7134_set_dmabits(dev);
}
static void dsp_dma_stop(struct saa7134_dev *dev)
{
dev->dmasound.dma_blk = -1;
dev->dmasound.dma_running = 0;
saa7134_set_dmabits(dev);
}
static int dsp_rec_start(struct saa7134_dev *dev)
{
int err, bswap, sign;
u32 fmt, control;
unsigned long flags;
/* prepare buffer */
if (0 != (err = videobuf_pci_dma_map(dev->pci,&dev->dmasound.dma)))
return err;
if (0 != (err =