Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+7 −57
Original line number Diff line number Diff line
@@ -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;
	}
+48 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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;