Pull bugzilla-7897 into release branch
[sfrench/cifs-2.6.git] / drivers / media / video / saa7134 / saa7134-empress.c
index 1d972edb3be6b2cbb3e9c167e24754c5c27cf02f..f521603482cab0ed249995eb740889ef2c2fa4ff 100644 (file)
@@ -64,8 +64,10 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
 
 static int ts_init_encoder(struct saa7134_dev* dev)
 {
+       struct v4l2_ext_controls ctrls = { V4L2_CTRL_CLASS_MPEG, 0 };
+
        ts_reset_encoder(dev);
-       saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
+       saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, &ctrls);
        dev->empress_started = 1;
        return 0;
 }
@@ -162,6 +164,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
                       unsigned int cmd, void *arg)
 {
        struct saa7134_dev *dev = file->private_data;
+       struct v4l2_ext_controls *ctrls = arg;
 
        if (debug > 1)
                v4l_print_ioctl(dev->name,cmd);
@@ -278,12 +281,31 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
                return saa7134_common_ioctl(dev, cmd, arg);
 
        case VIDIOC_S_MPEGCOMP:
+               printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
+                                   "Replace with VIDIOC_S_EXT_CTRLS!");
                saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
                ts_init_encoder(dev);
                return 0;
        case VIDIOC_G_MPEGCOMP:
+               printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
+                                   "Replace with VIDIOC_G_EXT_CTRLS!");
                saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
                return 0;
+       case VIDIOC_S_EXT_CTRLS:
+               /* count == 0 is abused in saa6752hs.c, so that special
+                  case is handled here explicitly. */
+               if (ctrls->count == 0)
+                       return 0;
+               if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+                       return -EINVAL;
+               saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, arg);
+               ts_init_encoder(dev);
+               return 0;
+       case VIDIOC_G_EXT_CTRLS:
+               if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+                       return -EINVAL;
+               saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, arg);
+               return 0;
 
        default:
                return -ENOIOCTLCMD;
@@ -297,7 +319,7 @@ static int ts_ioctl(struct inode *inode, struct file *file,
        return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
 }
 
-static struct file_operations ts_fops =
+static const struct file_operations ts_fops =
 {
        .owner    = THIS_MODULE,
        .open     = ts_open,
@@ -321,9 +343,10 @@ static struct video_device saa7134_empress_template =
        .minor         = -1,
 };
 
-static void empress_signal_update(void* data)
+static void empress_signal_update(struct work_struct *work)
 {
-       struct saa7134_dev* dev = (struct saa7134_dev*) data;
+       struct saa7134_dev* dev =
+               container_of(work, struct saa7134_dev, empress_workqueue);
 
        if (dev->nosignal) {
                dprintk("no video signal\n");
@@ -356,7 +379,7 @@ static int empress_init(struct saa7134_dev *dev)
                 "%s empress (%s)", dev->name,
                 saa7134_boards[dev->board].name);
 
-       INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev);
+       INIT_WORK(&dev->empress_workqueue, empress_signal_update);
 
        err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
                                    empress_nr[dev->nr]);
@@ -377,7 +400,7 @@ static int empress_init(struct saa7134_dev *dev)
                            sizeof(struct saa7134_buf),
                            dev);
 
-       empress_signal_update(dev);
+       empress_signal_update(&dev->empress_workqueue);
        return 0;
 }