diff options
Diffstat (limited to 'drivers/media/common/saa7146_fops.c')
-rw-r--r-- | drivers/media/common/saa7146_fops.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 09ec964dec5..f8cf73ed49a 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -239,13 +239,12 @@ static int fops_open(struct inode *inode, struct file *file) } /* allocate per open data */ - fh = kmalloc(sizeof(*fh),GFP_KERNEL); + fh = kzalloc(sizeof(*fh),GFP_KERNEL); if (NULL == fh) { DEB_S(("cannot allocate memory for per open data.\n")); result = -ENOMEM; goto out; } - memset(fh,0,sizeof(*fh)); file->private_data = fh; fh->dev = dev; @@ -253,7 +252,10 @@ static int fops_open(struct inode *inode, struct file *file) if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { DEB_S(("initializing vbi...\n")); - result = saa7146_vbi_uops.open(dev,file); + if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) + result = saa7146_vbi_uops.open(dev,file); + if (dev->ext_vv_data->vbi_fops.open) + dev->ext_vv_data->vbi_fops.open(inode, file); } else { DEB_S(("initializing video...\n")); result = saa7146_video_uops.open(dev,file); @@ -289,7 +291,10 @@ static int fops_release(struct inode *inode, struct file *file) return -ERESTARTSYS; if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - saa7146_vbi_uops.release(dev,file); + if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) + saa7146_vbi_uops.release(dev,file); + if (dev->ext_vv_data->vbi_fops.release) + dev->ext_vv_data->vbi_fops.release(inode, file); } else { saa7146_video_uops.release(dev,file); } @@ -332,6 +337,7 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma) BUG(); return 0; } + return videobuf_mmap_mapper(q,vma); } @@ -381,7 +387,10 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof } case V4L2_BUF_TYPE_VBI_CAPTURE: { // DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); - return saa7146_vbi_uops.read(file,data,count,ppos); + if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) + return saa7146_vbi_uops.read(file,data,count,ppos); + else + return -EINVAL; } break; default: @@ -390,12 +399,31 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof } } +static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) +{ + struct saa7146_fh *fh = file->private_data; + + switch (fh->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return -EINVAL; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (fh->dev->ext_vv_data->vbi_fops.write) + return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); + else + return -EINVAL; + default: + BUG(); + return -EINVAL; + } +} + static struct file_operations video_fops = { .owner = THIS_MODULE, .open = fops_open, .release = fops_release, .read = fops_read, + .write = fops_write, .poll = fops_poll, .mmap = fops_mmap, .ioctl = fops_ioctl, @@ -435,12 +463,11 @@ static struct video_device device_template = int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) { - struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL); + struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL); if( NULL == vv ) { ERR(("out of memory. aborting.\n")); return -1; } - memset(vv, 0x0, sizeof(*vv)); DEB_EE(("dev:%p\n",dev)); @@ -467,7 +494,8 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); saa7146_video_uops.init(dev,vv); - saa7146_vbi_uops.init(dev,vv); + if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) + saa7146_vbi_uops.init(dev,vv); dev->vv_data = vv; dev->vv_callback = &vv_callback; |