From: Hans de Goede Date: Sun, 9 Oct 2011 12:56:23 +0000 (-0300) Subject: [media] pwc: Make auto white balance speed and delay available as v4l2 controls X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=f4af65958a6ea987ff61504ad9f053f8ba8da674;p=linux-beck.git [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 --- diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index b42c239de9cf..def9120b607d 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 a10ff6b64acf..1303641c70c1 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 dd75b9dbe829..04e9524a94dd 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;