[media] pwc: Make auto white balance speed and delay available as v4l2 controls
authorHans de Goede <hdegoede@redhat.com>
Sun, 9 Oct 2011 12:56:23 +0000 (09:56 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 6 Jan 2012 12:42:44 +0000 (10:42 -0200)
Currently auto white balance speed and delay are only available through custom
ioctls, which are deprecated and will be going away in 3.3 .

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/pwc/pwc-ctrl.c
drivers/media/video/pwc/pwc-v4l.c
drivers/media/video/pwc/pwc.h

index b42c239..def9120 100644 (file)
@@ -597,54 +597,6 @@ void pwc_camera_power(struct pwc_device *pdev, int power)
                          power ? "on" : "off", r);
 }
 
-static int pwc_set_wb_speed(struct pwc_device *pdev, int speed)
-{
-       unsigned char buf;
-
-       /* useful range is 0x01..0x20 */
-       buf = speed / 0x7f0;
-       return send_control_msg(pdev,
-               SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
-}
-
-static int pwc_get_wb_speed(struct pwc_device *pdev, int *value)
-{
-       unsigned char buf;
-       int ret;
-
-       ret = recv_control_msg(pdev,
-               GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-       *value = buf * 0x7f0;
-       return 0;
-}
-
-
-static int pwc_set_wb_delay(struct pwc_device *pdev, int delay)
-{
-       unsigned char buf;
-
-       /* useful range is 0x01..0x3F */
-       buf = (delay >> 10);
-       return send_control_msg(pdev,
-               SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
-}
-
-static int pwc_get_wb_delay(struct pwc_device *pdev, int *value)
-{
-       unsigned char buf;
-       int ret;
-
-       ret = recv_control_msg(pdev,
-               GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf));
-       if (ret < 0)
-               return ret;
-       *value = buf << 10;
-       return 0;
-}
-
-
 int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
 {
        unsigned char buf[2];
@@ -963,10 +915,12 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
                ARG_DEF(struct pwc_wb_speed, wbs)
 
                if (ARGR(wbs).control_speed > 0) {
-                       ret = pwc_set_wb_speed(pdev, ARGR(wbs).control_speed);
+                       ret = pwc_ioctl_s_ctrl(pdev->awb_speed,
+                                              ARGR(wbs).control_speed);
                }
-               if (ARGR(wbs).control_delay > 0) {
-                       ret = pwc_set_wb_delay(pdev, ARGR(wbs).control_delay);
+               if (ret == 0 && ARGR(wbs).control_delay > 0) {
+                       ret = pwc_ioctl_s_ctrl(pdev->awb_delay,
+                                              ARGR(wbs).control_delay);
                }
                break;
        }
@@ -975,12 +929,8 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
        {
                ARG_DEF(struct pwc_wb_speed, wbs)
 
-               ret = pwc_get_wb_speed(pdev, &ARGR(wbs).control_speed);
-               if (ret < 0)
-                       break;
-               ret = pwc_get_wb_delay(pdev, &ARGR(wbs).control_delay);
-               if (ret < 0)
-                       break;
+               ARGR(wbs).control_speed = v4l2_ctrl_g_ctrl(pdev->awb_speed);
+               ARGR(wbs).control_delay = v4l2_ctrl_g_ctrl(pdev->awb_delay);
                ARG_OUT(wbs)
                break;
        }
index a10ff6b..1303641 100644 (file)
@@ -49,6 +49,7 @@ static const struct v4l2_ctrl_ops pwc_ctrl_ops = {
 
 enum { awb_indoor, awb_outdoor, awb_fl, awb_manual, awb_auto };
 enum { custom_autocontour, custom_contour, custom_noise_reduction,
+       custom_awb_speed, custom_awb_delay,
        custom_save_user, custom_restore_user, custom_restore_factory };
 
 const char * const pwc_auto_whitebal_qmenu[] = {
@@ -138,6 +139,26 @@ static const struct v4l2_ctrl_config pwc_restore_factory_cfg = {
        .name    = "Restore Factory Settings",
 };
 
+static const struct v4l2_ctrl_config pwc_awb_speed_cfg = {
+       .ops    = &pwc_ctrl_ops,
+       .id     = PWC_CID_CUSTOM(awb_speed),
+       .type   = V4L2_CTRL_TYPE_INTEGER,
+       .name   = "Auto White Balance Speed",
+       .min    = 1,
+       .max    = 32,
+       .step   = 1,
+};
+
+static const struct v4l2_ctrl_config pwc_awb_delay_cfg = {
+       .ops    = &pwc_ctrl_ops,
+       .id     = PWC_CID_CUSTOM(awb_delay),
+       .type   = V4L2_CTRL_TYPE_INTEGER,
+       .name   = "Auto White Balance Delay",
+       .min    = 0,
+       .max    = 63,
+       .step   = 1,
+};
+
 int pwc_init_controls(struct pwc_device *pdev)
 {
        struct v4l2_ctrl_handler *hdl;
@@ -338,6 +359,23 @@ int pwc_init_controls(struct pwc_device *pdev)
        if (pdev->restore_factory)
                pdev->restore_factory->flags |= V4L2_CTRL_FLAG_UPDATE;
 
+       /* Auto White Balance speed & delay */
+       r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
+                           AWB_CONTROL_SPEED_FORMATTER, &def);
+       if (r || def < 1 || def > 32)
+               def = 1;
+       cfg = pwc_awb_speed_cfg;
+       cfg.def = def;
+       pdev->awb_speed = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
+
+       r = pwc_get_u8_ctrl(pdev, GET_CHROM_CTL,
+                           AWB_CONTROL_DELAY_FORMATTER, &def);
+       if (r || def > 63)
+               def = 0;
+       cfg = pwc_awb_delay_cfg;
+       cfg.def = def;
+       pdev->awb_delay = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
+
        if (!(pdev->features & FEATURE_MOTOR_PANTILT))
                return hdl->error;
 
@@ -891,6 +929,16 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
                ret = pwc_button_ctrl(pdev,
                                      RESTORE_FACTORY_DEFAULTS_FORMATTER);
                break;
+       case PWC_CID_CUSTOM(awb_speed):
+               ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
+                                     AWB_CONTROL_SPEED_FORMATTER,
+                                     ctrl->val);
+               break;
+       case PWC_CID_CUSTOM(awb_delay):
+               ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
+                                     AWB_CONTROL_DELAY_FORMATTER,
+                                     ctrl->val);
+               break;
        case V4L2_CID_PAN_RELATIVE:
                ret = pwc_set_motor(pdev);
                break;
index dd75b9d..04e9524 100644 (file)
@@ -332,6 +332,8 @@ struct pwc_device
        struct v4l2_ctrl                *save_user;
        struct v4l2_ctrl                *restore_user;
        struct v4l2_ctrl                *restore_factory;
+       struct v4l2_ctrl                *awb_speed;
+       struct v4l2_ctrl                *awb_delay;
        struct {
                /* motor control cluster */
                struct v4l2_ctrl        *motor_pan;