/*
- $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $
bttv - Bt848 frame grabber driver
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include "bttvp.h"
+#include "rds.h"
+
+
unsigned int bttv_num; /* number of Bt848s in use */
struct bttv bttvs[BTTV_MAX];
static unsigned int uv_ratio = 50;
static unsigned int full_luma_range = 0;
static unsigned int coring = 0;
+extern int no_overlay;
/* API features (turn on/off stuff for testing) */
static unsigned int v4l2 = 1;
static
void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
{
-#if 1 /* DEBUG */
if ((fh->resources & bits) != bits) {
/* trying to free ressources not allocated by us ... */
printk("bttv: BUG! (btres)\n");
}
-#endif
down(&btv->reslock);
fh->resources &= ~bits;
btv->resources &= ~bits;
i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
if (btv->opt_automute && !signal && !btv->radio_user)
mux = AUDIO_OFF;
-#if 0
- printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n",
- btv->c.nr, mode, btv->audio, signal ? "yes" : "no",
- mux, i2c_mux, in_interrupt() ? "yes" : "no");
-#endif
val = bttv_tvcards[btv->c.type].audiomux[mux];
gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
case BTTV_VOODOOTV_FM:
bttv_tda9880_setnorm(btv,norm);
break;
-#if 0
- case BTTV_OSPREY540:
- osprey_540_set_norm(btv,norm);
- break;
-#endif
}
return 0;
}
if (unlikely(f->tuner != 0))
return -EINVAL;
- if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
+ if (unlikely (f->type != V4L2_TUNER_ANALOG_TV))
return -EINVAL;
down(&btv->lock);
btv->freq = f->frequency;
return 0;
}
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ if (no_overlay > 0) {
+ printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+ return -EINVAL;
+ }
return setup_window(fh, btv, &f->fmt.win, 1);
case V4L2_BUF_TYPE_VBI_CAPTURE:
retval = bttv_switch_type(fh,f->type);
/* others */
cap->type = VID_TYPE_CAPTURE|
VID_TYPE_TUNER|
- VID_TYPE_OVERLAY|
VID_TYPE_CLIPPING|
VID_TYPE_SCALES;
+ if (no_overlay <= 0)
+ cap->type |= VID_TYPE_OVERLAY;
+
cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
cap->minwidth = 48;
struct video_window *win = arg;
struct v4l2_window w2;
+ if (no_overlay > 0) {
+ printk ("VIDIOCSWIN: no_overlay\n");
+ return -EINVAL;
+ }
+
w2.field = V4L2_FIELD_ANY;
w2.w.left = win->x;
w2.w.top = win->y;
cap->version = BTTV_VERSION_CODE;
cap->capabilities =
V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VIDEO_OVERLAY |
V4L2_CAP_VBI_CAPTURE |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING;
+ if (no_overlay <= 0)
+ cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
+
if (bttv_tvcards[btv->c.type].tuner != UNSET &&
bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER;
static struct video_device bttv_video_template =
{
.name = "UNSET",
- .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+ .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
VID_TYPE_CLIPPING|VID_TYPE_SCALES,
.hardware = VID_HARDWARE_BT848,
.fops = &bttv_fops,
dprintk("bttv%d: open called (radio)\n",btv->c.nr);
down(&btv->lock);
- if (btv->radio_user) {
- up(&btv->lock);
- return -EBUSY;
- }
+
btv->radio_user++;
+
file->private_data = btv;
- i2c_vidiocschan(btv);
- bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
+ bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
audio_mux(btv,AUDIO_RADIO);
up(&btv->lock);
static int radio_release(struct inode *inode, struct file *file)
{
- struct bttv *btv = file->private_data;
+ struct bttv *btv = file->private_data;
+ struct rds_command cmd;
btv->radio_user--;
+
+ bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+
return 0;
}
return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
}
+static ssize_t radio_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct bttv *btv = file->private_data;
+ struct rds_command cmd;
+ cmd.block_count = count/3;
+ cmd.buffer = data;
+ cmd.instance = file;
+ cmd.result = -ENODEV;
+
+ bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+
+ return cmd.result;
+}
+
+static unsigned int radio_poll(struct file *file, poll_table *wait)
+{
+ struct bttv *btv = file->private_data;
+ struct rds_command cmd;
+ cmd.instance = file;
+ cmd.event_list = wait;
+ cmd.result = -ENODEV;
+ bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+
+ return cmd.result;
+}
+
static struct file_operations radio_fops =
{
.owner = THIS_MODULE,
.open = radio_open,
+ .read = radio_read,
.release = radio_release,
.ioctl = radio_ioctl,
.llseek = no_llseek,
+ .poll = radio_poll,
};
static struct video_device radio_template =
/* register video4linux devices */
static int __devinit bttv_register_video(struct bttv *btv)
{
+ if (no_overlay <= 0) {
+ bttv_video_template.type |= VID_TYPE_OVERLAY;
+ } else {
+ printk("bttv: Overlay support disabled.\n");
+ }
+
/* video */
btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
if (NULL == btv->video_dev)
btv->c.nr);
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
+ if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
btv->c.nr);
return -EIO;
pci_set_master(dev);
pci_set_command(dev);
pci_set_drvdata(dev,btv);
- if (!pci_dma_supported(dev,0xffffffff)) {
- printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->c.nr);
- result = -EIO;
- goto fail1;
- }
pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
struct bttv_buffer_set idle;
unsigned long flags;
- dprintk("bttv%d: suspend %d\n", btv->c.nr, state);
/* stop dma + irqs */
spin_lock_irqsave(&btv->s_lock,flags);
{
struct bttv *btv = pci_get_drvdata(pci_dev);
unsigned long flags;
+ int err;
dprintk("bttv%d: resume\n", btv->c.nr);
/* restore pci state */
if (btv->state.disabled) {
- pci_enable_device(pci_dev);
+ err=pci_enable_device(pci_dev);
+ if (err) {
+ printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+ btv->c.nr);
+ return err;
+ }
btv->state.disabled = 0;
}
- pci_set_power_state(pci_dev, PCI_D0);
+ err=pci_set_power_state(pci_dev, PCI_D0);
+ if (err) {
+ pci_disable_device(pci_dev);
+ printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+ btv->c.nr);
+ btv->state.disabled = 1;
+ return err;
+ }
+
pci_restore_state(pci_dev);
/* restore bt878 state */