Skip to content

Commit

Permalink
[media] pwc: Make auto white balance speed and delay available as v4l…
Browse files Browse the repository at this point in the history
…2 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 <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Hans de Goede authored and Mauro Carvalho Chehab committed Jan 6, 2012
1 parent 32c67ec commit f4af659
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 57 deletions.
64 changes: 7 additions & 57 deletions drivers/media/video/pwc/pwc-ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
48 changes: 48 additions & 0 deletions drivers/media/video/pwc/pwc-v4l.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions drivers/media/video/pwc/pwc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit f4af659

Please sign in to comment.