From f4af65958a6ea987ff61504ad9f053f8ba8da674 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 9 Oct 2011 09:56:23 -0300 Subject: [PATCH] [media] pwc: Make auto white balance speed and delay available as v4l2 controls 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 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-ctrl.c | 64 ++++-------------------------- drivers/media/video/pwc/pwc-v4l.c | 48 ++++++++++++++++++++++ drivers/media/video/pwc/pwc.h | 2 + 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index b42c239de9c..def9120b607 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -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; } diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index a10ff6b64ac..1303641c70c 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -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; diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index dd75b9dbe82..04e9524a94d 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -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; -- 2.39.5