[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 <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Hans de Goede 2011-10-09 09:56:23 -03:00 committed by Mauro Carvalho Chehab
parent 32c67ecc4a
commit f4af65958a
3 changed files with 57 additions and 57 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;