[media] stk-webcam: convert to the control framework
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 4 Feb 2013 11:53:11 +0000 (08:53 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 5 Mar 2013 17:39:40 +0000 (14:39 -0300)
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Tested-by: Arvydas Sidorenko <asido4@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/stkwebcam/stk-webcam.h

index eaf152c51ae2e159ea1b0801d9dd42aae0c26bce..f1cf9060ce71eae330c614dae421364c08d9d2ce 100644 (file)
@@ -806,99 +806,25 @@ static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
                return 0;
 }
 
-/* List of all V4Lv2 controls supported by the driver */
-static struct v4l2_queryctrl stk_controls[] = {
-       {
-               .id      = V4L2_CID_BRIGHTNESS,
-               .type    = V4L2_CTRL_TYPE_INTEGER,
-               .name    = "Brightness",
-               .minimum = 0,
-               .maximum = 0xffff,
-               .step    = 0x0100,
-               .default_value = 0x6000,
-       },
-       {
-               .id      = V4L2_CID_HFLIP,
-               .type    = V4L2_CTRL_TYPE_BOOLEAN,
-               .name    = "Horizontal Flip",
-               .minimum = 0,
-               .maximum = 1,
-               .step    = 1,
-               .default_value = 1,
-       },
-       {
-               .id      = V4L2_CID_VFLIP,
-               .type    = V4L2_CTRL_TYPE_BOOLEAN,
-               .name    = "Vertical Flip",
-               .minimum = 0,
-               .maximum = 1,
-               .step    = 1,
-               .default_value = 1,
-       },
-};
-
-static int stk_vidioc_queryctrl(struct file *filp,
-               void *priv, struct v4l2_queryctrl *c)
+static int stk_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-       int i;
-       int nbr;
-       nbr = ARRAY_SIZE(stk_controls);
-
-       for (i = 0; i < nbr; i++) {
-               if (stk_controls[i].id == c->id) {
-                       memcpy(c, &stk_controls[i],
-                               sizeof(struct v4l2_queryctrl));
-                       return 0;
-               }
-       }
-       return -EINVAL;
-}
-
-static int stk_vidioc_g_ctrl(struct file *filp,
-               void *priv, struct v4l2_control *c)
-{
-       struct stk_camera *dev = priv;
-       switch (c->id) {
-       case V4L2_CID_BRIGHTNESS:
-               c->value = dev->vsettings.brightness;
-               break;
-       case V4L2_CID_HFLIP:
-               if (dmi_check_system(stk_upside_down_dmi_table))
-                       c->value = !dev->vsettings.hflip;
-               else
-                       c->value = dev->vsettings.hflip;
-               break;
-       case V4L2_CID_VFLIP:
-               if (dmi_check_system(stk_upside_down_dmi_table))
-                       c->value = !dev->vsettings.vflip;
-               else
-                       c->value = dev->vsettings.vflip;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
+       struct stk_camera *dev =
+               container_of(ctrl->handler, struct stk_camera, hdl);
 
-static int stk_vidioc_s_ctrl(struct file *filp,
-               void *priv, struct v4l2_control *c)
-{
-       struct stk_camera *dev = priv;
-       switch (c->id) {
+       switch (ctrl->id) {
        case V4L2_CID_BRIGHTNESS:
-               dev->vsettings.brightness = c->value;
-               return stk_sensor_set_brightness(dev, c->value >> 8);
+               return stk_sensor_set_brightness(dev, ctrl->val);
        case V4L2_CID_HFLIP:
                if (dmi_check_system(stk_upside_down_dmi_table))
-                       dev->vsettings.hflip = !c->value;
+                       dev->vsettings.hflip = !ctrl->val;
                else
-                       dev->vsettings.hflip = c->value;
+                       dev->vsettings.hflip = ctrl->val;
                return 0;
        case V4L2_CID_VFLIP:
                if (dmi_check_system(stk_upside_down_dmi_table))
-                       dev->vsettings.vflip = !c->value;
+                       dev->vsettings.vflip = !ctrl->val;
                else
-                       dev->vsettings.vflip = c->value;
+                       dev->vsettings.vflip = ctrl->val;
                return 0;
        default:
                return -EINVAL;
@@ -1238,6 +1164,10 @@ static int stk_vidioc_enum_framesizes(struct file *filp,
        }
 }
 
+static const struct v4l2_ctrl_ops stk_ctrl_ops = {
+       .s_ctrl = stk_s_ctrl,
+};
+
 static struct v4l2_file_operations v4l_stk_fops = {
        .owner = THIS_MODULE,
        .open = v4l_stk_open,
@@ -1263,9 +1193,6 @@ static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
        .vidioc_dqbuf = stk_vidioc_dqbuf,
        .vidioc_streamon = stk_vidioc_streamon,
        .vidioc_streamoff = stk_vidioc_streamoff,
-       .vidioc_queryctrl = stk_vidioc_queryctrl,
-       .vidioc_g_ctrl = stk_vidioc_g_ctrl,
-       .vidioc_s_ctrl = stk_vidioc_s_ctrl,
        .vidioc_g_parm = stk_vidioc_g_parm,
        .vidioc_enum_framesizes = stk_vidioc_enum_framesizes,
 };
@@ -1310,8 +1237,9 @@ static int stk_register_video_device(struct stk_camera *dev)
 static int stk_camera_probe(struct usb_interface *interface,
                const struct usb_device_id *id)
 {
-       int i;
+       struct v4l2_ctrl_handler *hdl;
        int err = 0;
+       int i;
 
        struct stk_camera *dev = NULL;
        struct usb_device *udev = interface_to_usbdev(interface);
@@ -1329,6 +1257,20 @@ static int stk_camera_probe(struct usb_interface *interface,
                kfree(dev);
                return err;
        }
+       hdl = &dev->hdl;
+       v4l2_ctrl_handler_init(hdl, 3);
+       v4l2_ctrl_new_std(hdl, &stk_ctrl_ops,
+                         V4L2_CID_BRIGHTNESS, 0, 0xff, 0x1, 0x60);
+       v4l2_ctrl_new_std(hdl, &stk_ctrl_ops,
+                         V4L2_CID_HFLIP, 0, 1, 1, 1);
+       v4l2_ctrl_new_std(hdl, &stk_ctrl_ops,
+                         V4L2_CID_VFLIP, 0, 1, 1, 1);
+       if (hdl->error) {
+               err = hdl->error;
+               dev_err(&udev->dev, "couldn't register control\n");
+               goto error;
+       }
+       dev->v4l2_dev.ctrl_handler = hdl;
 
        spin_lock_init(&dev->spinlock);
        init_waitqueue_head(&dev->wait_frame);
@@ -1372,7 +1314,6 @@ static int stk_camera_probe(struct usb_interface *interface,
                err = -ENODEV;
                goto error;
        }
-       dev->vsettings.brightness = 0x7fff;
        dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
        dev->vsettings.mode = MODE_VGA;
        dev->frame_size = 640 * 480 * 2;
@@ -1389,6 +1330,7 @@ static int stk_camera_probe(struct usb_interface *interface,
        return 0;
 
 error:
+       v4l2_ctrl_handler_free(hdl);
        v4l2_device_unregister(&dev->v4l2_dev);
        kfree(dev);
        return err;
@@ -1407,6 +1349,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
                 video_device_node_name(&dev->vdev));
 
        video_unregister_device(&dev->vdev);
+       v4l2_ctrl_handler_free(&dev->hdl);
        v4l2_device_unregister(&dev->v4l2_dev);
 }
 
index 49ebe855cba658dacd7a5169f2ce73aae272feef..901f0df21bc75f7add396555bcaa6e74b77e8c0c 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/usb.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-common.h>
 
 #define DRIVER_VERSION         "v0.0.1"
@@ -60,7 +61,6 @@ enum stk_mode {MODE_VGA, MODE_SXGA, MODE_CIF, MODE_QVGA, MODE_QCIF};
 
 struct stk_video {
        enum stk_mode mode;
-       int brightness;
        __u32 palette;
        int hflip;
        int vflip;
@@ -93,6 +93,7 @@ struct regval {
 
 struct stk_camera {
        struct v4l2_device v4l2_dev;
+       struct v4l2_ctrl_handler hdl;
        struct video_device vdev;
        struct usb_device *udev;
        struct usb_interface *interface;