Commit 43d23f36 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] pwc: switch to the new auto-cluster volatile handling

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: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 882a935c
...@@ -83,6 +83,7 @@ static const struct v4l2_ctrl_config pwc_contour_cfg = { ...@@ -83,6 +83,7 @@ static const struct v4l2_ctrl_config pwc_contour_cfg = {
.id = PWC_CID_CUSTOM(contour), .id = PWC_CID_CUSTOM(contour),
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
.name = "Contour", .name = "Contour",
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = 0, .min = 0,
.max = 63, .max = 63,
.step = 1, .step = 1,
...@@ -206,8 +207,7 @@ int pwc_init_controls(struct pwc_device *pdev) ...@@ -206,8 +207,7 @@ int pwc_init_controls(struct pwc_device *pdev)
pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops, pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
V4L2_CID_BLUE_BALANCE, 0, 255, 1, def); V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);
v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual, v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual, true);
pdev->auto_white_balance->cur.val == awb_auto);
/* autogain, gain */ /* autogain, gain */
r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def); 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) ...@@ -331,12 +331,12 @@ int pwc_init_controls(struct pwc_device *pdev)
pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg, pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
NULL); NULL);
if (pdev->restore_user) 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, pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
&pwc_restore_factory_cfg, &pwc_restore_factory_cfg,
NULL); NULL);
if (pdev->restore_factory) 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)) if (!(pdev->features & FEATURE_MOTOR_PANTILT))
return hdl->error; return hdl->error;
...@@ -563,8 +563,10 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl) ...@@ -563,8 +563,10 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_AUTO_WHITE_BALANCE: case V4L2_CID_AUTO_WHITE_BALANCE:
if (pdev->color_bal_valid && time_before(jiffies, if (pdev->color_bal_valid &&
pdev->last_color_bal_update + HZ / 4)) { (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->red_balance->val = pdev->last_red_balance;
pdev->blue_balance->val = pdev->last_blue_balance; pdev->blue_balance->val = pdev->last_blue_balance;
break; break;
...@@ -630,7 +632,7 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl) ...@@ -630,7 +632,7 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
static int pwc_set_awb(struct pwc_device *pdev) static int pwc_set_awb(struct pwc_device *pdev)
{ {
int ret = 0; int ret;
if (pdev->auto_white_balance->is_new) { if (pdev->auto_white_balance->is_new) {
ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
...@@ -639,52 +641,34 @@ static int pwc_set_awb(struct pwc_device *pdev) ...@@ -639,52 +641,34 @@ static int pwc_set_awb(struct pwc_device *pdev)
if (ret) if (ret)
return ret; return ret;
/* Update val when coming from auto or going to a preset */ if (pdev->auto_white_balance->val != awb_manual)
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;
pdev->color_bal_valid = false; /* Force cache update */ 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->red_balance->is_new) {
if (pdev->auto_white_balance->val != awb_manual)
return -EBUSY;
ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
PRESET_MANUAL_RED_GAIN_FORMATTER, PRESET_MANUAL_RED_GAIN_FORMATTER,
pdev->red_balance->val); pdev->red_balance->val);
if (ret)
return ret;
} }
if (ret == 0 && pdev->blue_balance->is_new) { if (pdev->blue_balance->is_new) {
if (pdev->auto_white_balance->val != awb_manual)
return -EBUSY;
ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
PRESET_MANUAL_BLUE_GAIN_FORMATTER, PRESET_MANUAL_BLUE_GAIN_FORMATTER,
pdev->blue_balance->val); pdev->blue_balance->val);
if (ret)
return ret;
} }
return ret; return 0;
} }
/* For CODEC2 models which have separate autogain and auto exposure */ /* For CODEC2 models which have separate autogain and auto exposure */
static int pwc_set_autogain(struct pwc_device *pdev) static int pwc_set_autogain(struct pwc_device *pdev)
{ {
int ret = 0; int ret;
if (pdev->autogain->is_new) { if (pdev->autogain->is_new) {
ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
...@@ -692,27 +676,28 @@ static int pwc_set_autogain(struct pwc_device *pdev) ...@@ -692,27 +676,28 @@ static int pwc_set_autogain(struct pwc_device *pdev)
pdev->autogain->val ? 0 : 0xff); pdev->autogain->val ? 0 : 0xff);
if (ret) if (ret)
return ret; return ret;
if (pdev->autogain->val) if (pdev->autogain->val)
pdev->gain_valid = false; /* Force cache update */ 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) if (pdev->autogain->val)
return -EBUSY; return 0;
if (pdev->gain->is_new) {
ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
PRESET_AGC_FORMATTER, PRESET_AGC_FORMATTER,
pdev->gain->val); pdev->gain->val);
if (ret)
return ret;
} }
return ret; return 0;
} }
/* For CODEC2 models which have separate autogain and auto exposure */ /* For CODEC2 models which have separate autogain and auto exposure */
static int pwc_set_exposure_auto(struct pwc_device *pdev) 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; int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;
if (pdev->exposure_auto->is_new) { if (pdev->exposure_auto->is_new) {
...@@ -721,27 +706,28 @@ static int pwc_set_exposure_auto(struct pwc_device *pdev) ...@@ -721,27 +706,28 @@ static int pwc_set_exposure_auto(struct pwc_device *pdev)
is_auto ? 0 : 0xff); is_auto ? 0 : 0xff);
if (ret) if (ret)
return ret; return ret;
if (is_auto) if (is_auto)
pdev->exposure_valid = false; /* Force cache update */ 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) if (is_auto)
return -EBUSY; return 0;
if (pdev->exposure->is_new) {
ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
PRESET_SHUTTER_FORMATTER, PRESET_SHUTTER_FORMATTER,
pdev->exposure->val); pdev->exposure->val);
if (ret)
return ret;
} }
return ret; return 0;
} }
/* For CODEC3 models which have autogain controlling both gain and exposure */ /* For CODEC3 models which have autogain controlling both gain and exposure */
static int pwc_set_autogain_expo(struct pwc_device *pdev) static int pwc_set_autogain_expo(struct pwc_device *pdev)
{ {
int ret = 0; int ret;
if (pdev->autogain->is_new) { if (pdev->autogain->is_new) {
ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
...@@ -749,35 +735,32 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev) ...@@ -749,35 +735,32 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev)
pdev->autogain->val ? 0 : 0xff); pdev->autogain->val ? 0 : 0xff);
if (ret) if (ret)
return ret; return ret;
if (pdev->autogain->val) { if (pdev->autogain->val) {
pdev->gain_valid = false; /* Force cache update */ pdev->gain_valid = false; /* Force cache update */
pdev->exposure_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) if (pdev->autogain->val)
return -EBUSY; return 0;
if (pdev->gain->is_new) {
ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
PRESET_AGC_FORMATTER, PRESET_AGC_FORMATTER,
pdev->gain->val); pdev->gain->val);
if (ret)
return ret;
} }
if (ret == 0 && pdev->exposure->is_new) {
if (pdev->autogain->val) if (pdev->exposure->is_new) {
return -EBUSY;
ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
PRESET_SHUTTER_FORMATTER, PRESET_SHUTTER_FORMATTER,
pdev->exposure->val); pdev->exposure->val);
if (ret)
return ret;
} }
return ret; return 0;
} }
static int pwc_set_motor(struct pwc_device *pdev) static int pwc_set_motor(struct pwc_device *pdev)
...@@ -878,10 +861,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl) ...@@ -878,10 +861,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
pdev->autocontour->val ? 0 : 0xff); pdev->autocontour->val ? 0 : 0xff);
} }
if (ret == 0 && pdev->contour->is_new) { if (ret == 0 && pdev->contour->is_new) {
if (pdev->autocontour->val) {
ret = -EBUSY;
break;
}
ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
PRESET_CONTOUR_FORMATTER, PRESET_CONTOUR_FORMATTER,
pdev->contour->val); pdev->contour->val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment