[media] pwc: switch to the new auto-cluster volatile handling
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 26 Aug 2011 11:40:43 +0000 (08:40 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 21 Sep 2011 13:50:54 +0000 (10:50 -0300)
Now that the auto cluster core changed to a different scheme of how to
handle volatile controls (including how to switch from auto to manual mode)
the pwc code can be simplified to use that new core support.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/pwc/pwc-v4l.c

index 6873bf5..0a41ebb 100644 (file)
@@ -83,6 +83,7 @@ static const struct v4l2_ctrl_config pwc_contour_cfg = {
        .id     = PWC_CID_CUSTOM(contour),
        .type   = V4L2_CTRL_TYPE_INTEGER,
        .name   = "Contour",
+       .flags  = V4L2_CTRL_FLAG_SLIDER,
        .min    = 0,
        .max    = 63,
        .step   = 1,
@@ -206,8 +207,7 @@ int pwc_init_controls(struct pwc_device *pdev)
        pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
                                V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);
 
-       v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual,
-                              pdev->auto_white_balance->cur.val == awb_auto);
+       v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual, true);
 
        /* autogain, gain */
        r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def);
@@ -331,12 +331,12 @@ int pwc_init_controls(struct pwc_device *pdev)
        pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
                                                  NULL);
        if (pdev->restore_user)
-               pdev->restore_user->flags = V4L2_CTRL_FLAG_UPDATE;
+               pdev->restore_user->flags |= V4L2_CTRL_FLAG_UPDATE;
        pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
                                                     &pwc_restore_factory_cfg,
                                                     NULL);
        if (pdev->restore_factory)
-               pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
+               pdev->restore_factory->flags |= V4L2_CTRL_FLAG_UPDATE;
 
        if (!(pdev->features & FEATURE_MOTOR_PANTILT))
                return hdl->error;
@@ -563,8 +563,10 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 
        switch (ctrl->id) {
        case V4L2_CID_AUTO_WHITE_BALANCE:
-               if (pdev->color_bal_valid && time_before(jiffies,
-                               pdev->last_color_bal_update + HZ / 4)) {
+               if (pdev->color_bal_valid &&
+                       (pdev->auto_white_balance->val != awb_auto ||
+                        time_before(jiffies,
+                               pdev->last_color_bal_update + HZ / 4))) {
                        pdev->red_balance->val  = pdev->last_red_balance;
                        pdev->blue_balance->val = pdev->last_blue_balance;
                        break;
@@ -630,7 +632,7 @@ leave:
 
 static int pwc_set_awb(struct pwc_device *pdev)
 {
-       int ret = 0;
+       int ret;
 
        if (pdev->auto_white_balance->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
@@ -639,52 +641,34 @@ static int pwc_set_awb(struct pwc_device *pdev)
                if (ret)
                        return ret;
 
-               /* Update val when coming from auto or going to a preset */
-               if ((pdev->red_balance->flags & V4L2_CTRL_FLAG_VOLATILE) ||
-                   pdev->auto_white_balance->val == awb_indoor ||
-                   pdev->auto_white_balance->val == awb_outdoor ||
-                   pdev->auto_white_balance->val == awb_fl) {
-                       if (!pdev->red_balance->is_new)
-                               pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
-                                       READ_RED_GAIN_FORMATTER,
-                                       &pdev->red_balance->val);
-                       if (!pdev->blue_balance->is_new)
-                               pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
-                                       READ_BLUE_GAIN_FORMATTER,
-                                       &pdev->blue_balance->val);
-               }
-               if (pdev->auto_white_balance->val == awb_auto) {
-                       pdev->red_balance->flags |= V4L2_CTRL_FLAG_VOLATILE;
-                       pdev->blue_balance->flags |= V4L2_CTRL_FLAG_VOLATILE;
+               if (pdev->auto_white_balance->val != awb_manual)
                        pdev->color_bal_valid = false; /* Force cache update */
-               } else {
-                       pdev->red_balance->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
-                       pdev->blue_balance->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
-               }
        }
+       if (pdev->auto_white_balance->val != awb_manual)
+               return 0;
 
-       if (ret == 0 && pdev->red_balance->is_new) {
-               if (pdev->auto_white_balance->val != awb_manual)
-                       return -EBUSY;
+       if (pdev->red_balance->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
                                      PRESET_MANUAL_RED_GAIN_FORMATTER,
                                      pdev->red_balance->val);
+               if (ret)
+                       return ret;
        }
 
-       if (ret == 0 && pdev->blue_balance->is_new) {
-               if (pdev->auto_white_balance->val != awb_manual)
-                       return -EBUSY;
+       if (pdev->blue_balance->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
                                      PRESET_MANUAL_BLUE_GAIN_FORMATTER,
                                      pdev->blue_balance->val);
+               if (ret)
+                       return ret;
        }
-       return ret;
+       return 0;
 }
 
 /* For CODEC2 models which have separate autogain and auto exposure */
 static int pwc_set_autogain(struct pwc_device *pdev)
 {
-       int ret = 0;
+       int ret;
 
        if (pdev->autogain->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
@@ -692,27 +676,28 @@ static int pwc_set_autogain(struct pwc_device *pdev)
                                      pdev->autogain->val ? 0 : 0xff);
                if (ret)
                        return ret;
+
                if (pdev->autogain->val)
                        pdev->gain_valid = false; /* Force cache update */
-               else if (!pdev->gain->is_new)
-                       pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
-                                       READ_AGC_FORMATTER,
-                                       &pdev->gain->val);
        }
-       if (ret == 0 && pdev->gain->is_new) {
-               if (pdev->autogain->val)
-                       return -EBUSY;
+
+       if (pdev->autogain->val)
+               return 0;
+
+       if (pdev->gain->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
                                      PRESET_AGC_FORMATTER,
                                      pdev->gain->val);
+               if (ret)
+                       return ret;
        }
-       return ret;
+       return 0;
 }
 
 /* For CODEC2 models which have separate autogain and auto exposure */
 static int pwc_set_exposure_auto(struct pwc_device *pdev)
 {
-       int ret = 0;
+       int ret;
        int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;
 
        if (pdev->exposure_auto->is_new) {
@@ -721,27 +706,28 @@ static int pwc_set_exposure_auto(struct pwc_device *pdev)
                                      is_auto ? 0 : 0xff);
                if (ret)
                        return ret;
+
                if (is_auto)
                        pdev->exposure_valid = false; /* Force cache update */
-               else if (!pdev->exposure->is_new)
-                       pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
-                                        READ_SHUTTER_FORMATTER,
-                                        &pdev->exposure->val);
        }
-       if (ret == 0 && pdev->exposure->is_new) {
-               if (is_auto)
-                       return -EBUSY;
+
+       if (is_auto)
+               return 0;
+
+       if (pdev->exposure->is_new) {
                ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
                                       PRESET_SHUTTER_FORMATTER,
                                       pdev->exposure->val);
+               if (ret)
+                       return ret;
        }
-       return ret;
+       return 0;
 }
 
 /* For CODEC3 models which have autogain controlling both gain and exposure */
 static int pwc_set_autogain_expo(struct pwc_device *pdev)
 {
-       int ret = 0;
+       int ret;
 
        if (pdev->autogain->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
@@ -749,35 +735,32 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev)
                                      pdev->autogain->val ? 0 : 0xff);
                if (ret)
                        return ret;
+
                if (pdev->autogain->val) {
                        pdev->gain_valid     = false; /* Force cache update */
                        pdev->exposure_valid = false; /* Force cache update */
-               } else {
-                       if (!pdev->gain->is_new)
-                               pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
-                                               READ_AGC_FORMATTER,
-                                               &pdev->gain->val);
-                       if (!pdev->exposure->is_new)
-                               pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
-                                                READ_SHUTTER_FORMATTER,
-                                                &pdev->exposure->val);
                }
        }
-       if (ret == 0 && pdev->gain->is_new) {
-               if (pdev->autogain->val)
-                       return -EBUSY;
+
+       if (pdev->autogain->val)
+               return 0;
+
+       if (pdev->gain->is_new) {
                ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
                                      PRESET_AGC_FORMATTER,
                                      pdev->gain->val);
+               if (ret)
+                       return ret;
        }
-       if (ret == 0 && pdev->exposure->is_new) {
-               if (pdev->autogain->val)
-                       return -EBUSY;
+
+       if (pdev->exposure->is_new) {
                ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
                                       PRESET_SHUTTER_FORMATTER,
                                       pdev->exposure->val);
+               if (ret)
+                       return ret;
        }
-       return ret;
+       return 0;
 }
 
 static int pwc_set_motor(struct pwc_device *pdev)
@@ -878,10 +861,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
                                        pdev->autocontour->val ? 0 : 0xff);
                }
                if (ret == 0 && pdev->contour->is_new) {
-                       if (pdev->autocontour->val) {
-                               ret = -EBUSY;
-                               break;
-                       }
                        ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
                                              PRESET_CONTOUR_FORMATTER,
                                              pdev->contour->val);