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

Commit 43d23f36 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] pwc: switch to the new auto-cluster volatile handling



Now that the auto cluster core changed to a different scheme of how to
handle volatile controls (including how to switch from auto to manual mode)
the pwc code can be simplified to use that new core support.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 882a935c
Loading
Loading
Loading
Loading
+53 −74
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ static const struct v4l2_ctrl_config pwc_contour_cfg = {
	.id	= PWC_CID_CUSTOM(contour),
	.type	= V4L2_CTRL_TYPE_INTEGER,
	.name	= "Contour",
	.flags  = V4L2_CTRL_FLAG_SLIDER,
	.min	= 0,
	.max	= 63,
	.step	= 1,
@@ -206,8 +207,7 @@ int pwc_init_controls(struct pwc_device *pdev)
	pdev->blue_balance = v4l2_ctrl_new_std(hdl, &pwc_ctrl_ops,
				V4L2_CID_BLUE_BALANCE, 0, 255, 1, def);

	v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual,
			       pdev->auto_white_balance->cur.val == awb_auto);
	v4l2_ctrl_auto_cluster(3, &pdev->auto_white_balance, awb_manual, true);

	/* autogain, gain */
	r = pwc_get_u8_ctrl(pdev, GET_LUM_CTL, AGC_MODE_FORMATTER, &def);
@@ -331,12 +331,12 @@ int pwc_init_controls(struct pwc_device *pdev)
	pdev->restore_user = v4l2_ctrl_new_custom(hdl, &pwc_restore_user_cfg,
						  NULL);
	if (pdev->restore_user)
		pdev->restore_user->flags = V4L2_CTRL_FLAG_UPDATE;
		pdev->restore_user->flags |= V4L2_CTRL_FLAG_UPDATE;
	pdev->restore_factory = v4l2_ctrl_new_custom(hdl,
						     &pwc_restore_factory_cfg,
						     NULL);
	if (pdev->restore_factory)
		pdev->restore_factory->flags = V4L2_CTRL_FLAG_UPDATE;
		pdev->restore_factory->flags |= V4L2_CTRL_FLAG_UPDATE;

	if (!(pdev->features & FEATURE_MOTOR_PANTILT))
		return hdl->error;
@@ -563,8 +563,10 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)

	switch (ctrl->id) {
	case V4L2_CID_AUTO_WHITE_BALANCE:
		if (pdev->color_bal_valid && time_before(jiffies,
				pdev->last_color_bal_update + HZ / 4)) {
		if (pdev->color_bal_valid &&
			(pdev->auto_white_balance->val != awb_auto ||
			 time_before(jiffies,
				pdev->last_color_bal_update + HZ / 4))) {
			pdev->red_balance->val  = pdev->last_red_balance;
			pdev->blue_balance->val = pdev->last_blue_balance;
			break;
@@ -630,7 +632,7 @@ static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)

static int pwc_set_awb(struct pwc_device *pdev)
{
	int ret = 0;
	int ret;

	if (pdev->auto_white_balance->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
@@ -639,52 +641,34 @@ static int pwc_set_awb(struct pwc_device *pdev)
		if (ret)
			return ret;

		/* Update val when coming from auto or going to a preset */
		if ((pdev->red_balance->flags & V4L2_CTRL_FLAG_VOLATILE) ||
		    pdev->auto_white_balance->val == awb_indoor ||
		    pdev->auto_white_balance->val == awb_outdoor ||
		    pdev->auto_white_balance->val == awb_fl) {
			if (!pdev->red_balance->is_new)
				pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
					READ_RED_GAIN_FORMATTER,
					&pdev->red_balance->val);
			if (!pdev->blue_balance->is_new)
				pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
					READ_BLUE_GAIN_FORMATTER,
					&pdev->blue_balance->val);
		}
		if (pdev->auto_white_balance->val == awb_auto) {
			pdev->red_balance->flags |= V4L2_CTRL_FLAG_VOLATILE;
			pdev->blue_balance->flags |= V4L2_CTRL_FLAG_VOLATILE;
		if (pdev->auto_white_balance->val != awb_manual)
			pdev->color_bal_valid = false; /* Force cache update */
		} else {
			pdev->red_balance->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
			pdev->blue_balance->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
	}
	}

	if (ret == 0 && pdev->red_balance->is_new) {
	if (pdev->auto_white_balance->val != awb_manual)
			return -EBUSY;
		return 0;

	if (pdev->red_balance->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
				      PRESET_MANUAL_RED_GAIN_FORMATTER,
				      pdev->red_balance->val);
		if (ret)
			return ret;
	}

	if (ret == 0 && pdev->blue_balance->is_new) {
		if (pdev->auto_white_balance->val != awb_manual)
			return -EBUSY;
	if (pdev->blue_balance->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_CHROM_CTL,
				      PRESET_MANUAL_BLUE_GAIN_FORMATTER,
				      pdev->blue_balance->val);
	}
		if (ret)
			return ret;
	}
	return 0;
}

/* For CODEC2 models which have separate autogain and auto exposure */
static int pwc_set_autogain(struct pwc_device *pdev)
{
	int ret = 0;
	int ret;

	if (pdev->autogain->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
@@ -692,27 +676,28 @@ static int pwc_set_autogain(struct pwc_device *pdev)
				      pdev->autogain->val ? 0 : 0xff);
		if (ret)
			return ret;

		if (pdev->autogain->val)
			pdev->gain_valid = false; /* Force cache update */
		else if (!pdev->gain->is_new)
			pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
					READ_AGC_FORMATTER,
					&pdev->gain->val);
	}
	if (ret == 0 && pdev->gain->is_new) {

	if (pdev->autogain->val)
			return -EBUSY;
		return 0;

	if (pdev->gain->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
				      PRESET_AGC_FORMATTER,
				      pdev->gain->val);
	}
		if (ret)
			return ret;
	}
	return 0;
}

/* For CODEC2 models which have separate autogain and auto exposure */
static int pwc_set_exposure_auto(struct pwc_device *pdev)
{
	int ret = 0;
	int ret;
	int is_auto = pdev->exposure_auto->val == V4L2_EXPOSURE_AUTO;

	if (pdev->exposure_auto->is_new) {
@@ -721,27 +706,28 @@ static int pwc_set_exposure_auto(struct pwc_device *pdev)
				      is_auto ? 0 : 0xff);
		if (ret)
			return ret;

		if (is_auto)
			pdev->exposure_valid = false; /* Force cache update */
		else if (!pdev->exposure->is_new)
			pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
					 READ_SHUTTER_FORMATTER,
					 &pdev->exposure->val);
	}
	if (ret == 0 && pdev->exposure->is_new) {

	if (is_auto)
			return -EBUSY;
		return 0;

	if (pdev->exposure->is_new) {
		ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
				       PRESET_SHUTTER_FORMATTER,
				       pdev->exposure->val);
	}
		if (ret)
			return ret;
	}
	return 0;
}

/* For CODEC3 models which have autogain controlling both gain and exposure */
static int pwc_set_autogain_expo(struct pwc_device *pdev)
{
	int ret = 0;
	int ret;

	if (pdev->autogain->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
@@ -749,36 +735,33 @@ static int pwc_set_autogain_expo(struct pwc_device *pdev)
				      pdev->autogain->val ? 0 : 0xff);
		if (ret)
			return ret;

		if (pdev->autogain->val) {
			pdev->gain_valid     = false; /* Force cache update */
			pdev->exposure_valid = false; /* Force cache update */
		} else {
			if (!pdev->gain->is_new)
				pwc_get_u8_ctrl(pdev, GET_STATUS_CTL,
						READ_AGC_FORMATTER,
						&pdev->gain->val);
			if (!pdev->exposure->is_new)
				pwc_get_u16_ctrl(pdev, GET_STATUS_CTL,
						 READ_SHUTTER_FORMATTER,
						 &pdev->exposure->val);
		}
	}
	if (ret == 0 && pdev->gain->is_new) {

	if (pdev->autogain->val)
			return -EBUSY;
		return 0;

	if (pdev->gain->is_new) {
		ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
				      PRESET_AGC_FORMATTER,
				      pdev->gain->val);
		if (ret)
			return ret;
	}
	if (ret == 0 && pdev->exposure->is_new) {
		if (pdev->autogain->val)
			return -EBUSY;

	if (pdev->exposure->is_new) {
		ret = pwc_set_u16_ctrl(pdev, SET_LUM_CTL,
				       PRESET_SHUTTER_FORMATTER,
				       pdev->exposure->val);
	}
		if (ret)
			return ret;
	}
	return 0;
}

static int pwc_set_motor(struct pwc_device *pdev)
{
@@ -878,10 +861,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
					pdev->autocontour->val ? 0 : 0xff);
		}
		if (ret == 0 && pdev->contour->is_new) {
			if (pdev->autocontour->val) {
				ret = -EBUSY;
				break;
			}
			ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
					      PRESET_CONTOUR_FORMATTER,
					      pdev->contour->val);