Commit f4af6595 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

[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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 32c67ecc
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
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