Add the image quality bridge controls contrast, brightness, saturation,
blue balance, red balance and sharpness.
These controls are enabled only if no subdevice provides them.

Tested with the following devices:
"Terratec Cinergy 200 USB"
"Hauppauge HVR-900"
"SilverCrest 1.3MPix webcam"
"Hauppauge WinTV USB2"
"Speedlink VAD Laplace webcam"


Signed-off-by: Frank Schäfer <fschaefer....@googlemail.com>
Acked-by: Hans Verkuil <hans.verk...@cisco.com>
---
 drivers/media/usb/em28xx/em28xx-cards.c |    7 +---
 drivers/media/usb/em28xx/em28xx-video.c |   58 +++++++++++++++++++++++++++++--
 2 Dateien geändert, 57 Zeilen hinzugefügt(+), 8 Zeilen entfernt(-)

diff --git a/drivers/media/usb/em28xx/em28xx-cards.c 
b/drivers/media/usb/em28xx/em28xx-cards.c
index 0a5aa62..96de831 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -3089,7 +3089,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct 
usb_device *udev,
                return retval;
        }
 
-       v4l2_ctrl_handler_init(hdl, 4);
+       v4l2_ctrl_handler_init(hdl, 8);
        dev->v4l2_dev.ctrl_handler = hdl;
 
        /* register i2c bus */
@@ -3158,11 +3158,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct 
usb_device *udev,
                msleep(3);
        }
 
-       v4l2_ctrl_handler_setup(&dev->ctrl_handler);
-       retval = dev->ctrl_handler.error;
-       if (retval)
-               goto fail;
-
        retval = em28xx_register_analog_devices(dev);
        if (retval < 0) {
                goto fail;
diff --git a/drivers/media/usb/em28xx/em28xx-video.c 
b/drivers/media/usb/em28xx/em28xx-video.c
index 86fd907..48b937d 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -782,17 +782,38 @@ void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void 
*priv)
 static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct em28xx *dev = container_of(ctrl->handler, struct em28xx, 
ctrl_handler);
+       int ret = -EINVAL;
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
                dev->mute = ctrl->val;
+               ret = em28xx_audio_analog_set(dev);
                break;
        case V4L2_CID_AUDIO_VOLUME:
                dev->volume = ctrl->val;
+               ret = em28xx_audio_analog_set(dev);
+               break;
+       case V4L2_CID_CONTRAST:
+               ret = em28xx_write_reg(dev, EM28XX_R20_YGAIN, ctrl->val);
+               break;
+       case V4L2_CID_BRIGHTNESS:
+               ret = em28xx_write_reg(dev, EM28XX_R21_YOFFSET, ctrl->val);
+               break;
+       case V4L2_CID_SATURATION:
+               ret = em28xx_write_reg(dev, EM28XX_R22_UVGAIN, ctrl->val);
+               break;
+       case V4L2_CID_BLUE_BALANCE:
+               ret = em28xx_write_reg(dev, EM28XX_R23_UOFFSET, ctrl->val);
+               break;
+       case V4L2_CID_RED_BALANCE:
+               ret = em28xx_write_reg(dev, EM28XX_R24_VOFFSET, ctrl->val);
+               break;
+       case V4L2_CID_SHARPNESS:
+               ret = em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, ctrl->val);
                break;
        }
 
-       return em28xx_audio_analog_set(dev);
+       return (ret < 0) ? ret : 0;
 }
 
 const struct v4l2_ctrl_ops em28xx_ctrl_ops = {
@@ -1784,9 +1805,42 @@ int em28xx_register_analog_devices(struct em28xx *dev)
                         (EM28XX_XCLK_AUDIO_UNMUTE | val));
 
        em28xx_set_outfmt(dev);
-       em28xx_colorlevels_set_default(dev);
        em28xx_compression_disable(dev);
 
+       /* Add image controls */
+       /* NOTE: at this point, the subdevices are already registered, so bridge
+        * controls are only added/enabled when no subdevice provides them */
+       if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_CONTRAST))
+               v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
+                                 V4L2_CID_CONTRAST,
+                                 0, 0x1f, 1, CONTRAST_DEFAULT);
+       if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BRIGHTNESS))
+               v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
+                                 V4L2_CID_BRIGHTNESS,
+                                 -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT);
+       if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SATURATION))
+               v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
+                                 V4L2_CID_SATURATION,
+                                 0, 0x1f, 1, SATURATION_DEFAULT);
+       if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BLUE_BALANCE))
+               v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
+                                 V4L2_CID_BLUE_BALANCE,
+                                 -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT);
+       if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RED_BALANCE))
+               v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
+                                 V4L2_CID_RED_BALANCE,
+                                 -0x30, 0x30, 1, RED_BALANCE_DEFAULT);
+       if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SHARPNESS))
+               v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops,
+                                 V4L2_CID_SHARPNESS,
+                                 0, 0x0f, 1, SHARPNESS_DEFAULT);
+
+       /* Reset image controls */
+       em28xx_colorlevels_set_default(dev);
+       v4l2_ctrl_handler_setup(&dev->ctrl_handler);
+       if (dev->ctrl_handler.error)
+               return dev->ctrl_handler.error;
+
        /* allocate and fill video video_device struct */
        dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
        if (!dev->vdev) {
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to