* [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling.
@ 2011-08-26 12:00 Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
2011-08-27 10:35 ` [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling Hans de Goede
0 siblings, 2 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede
This is the second patch for this. The first is here:
http://comments.gmane.org/gmane.linux.drivers.video-input-infrastructure/36650
This second version changes the pwc code as suggested by Hans de Goede and it
adds documentation. The v4l2-ctrls.c code has also been improved to avoid
unnecessary calls to update_from_auto_cluster(). Thanks to Hans de Goede for
pointing me in the right direction.
If there are no additional comments, then I will make a pull request early next
week.
This will also be the basis for converting soc-camera to the control framework.
Regards,
Hans
^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE.
2011-08-26 12:00 [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 2/8] v4l2-ctrls: replace is_volatile with V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
` (6 more replies)
2011-08-27 10:35 ` [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling Hans de Goede
1 sibling, 7 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Add a new VOLATILE control flag that is set for volatile controls.
That way applications know whether the value of the control is volatile
(i.e. can change continuously) or not.
Until now this was an internal property, but it is useful to know in
userspace as well.
A typical use case is the gain value when autogain is on. In that case the
hardware will continuously adjust the gain based various environmental
factors.
This patch just adds and documents the flag, it's not yet used.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/DocBook/media/v4l/compat.xml | 8 ++++++++
Documentation/DocBook/media/v4l/v4l2.xml | 9 ++++++++-
.../DocBook/media/v4l/vidioc-queryctrl.xml | 9 +++++++++
include/linux/videodev2.h | 1 +
4 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index ce1004a..91410b6 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2370,6 +2370,14 @@ that used it. It was originally scheduled for removal in 2.6.35.
</listitem>
</orderedlist>
</section>
+ <section>
+ <title>V4L2 in Linux 3.2</title>
+ <orderedlist>
+ <listitem>
+ <para>V4L2_CTRL_FLAG_VOLATILE was added to signal volatile controls to userspace.</para>
+ </listitem>
+ </orderedlist>
+ </section>
<section id="other">
<title>Relation of V4L2 to other Linux multimedia APIs</title>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 0d05e87..40132c2 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -128,6 +128,13 @@ structs, ioctls) must be noted in more detail in the history chapter
applications. -->
<revision>
+ <revnumber>3.2</revnumber>
+ <date>2011-08-26</date>
+ <authorinitials>hv</authorinitials>
+ <revremark>Added V4L2_CTRL_FLAG_VOLATILE.</revremark>
+ </revision>
+
+ <revision>
<revnumber>3.1</revnumber>
<date>2011-06-27</date>
<authorinitials>mcc, po, hv</authorinitials>
@@ -410,7 +417,7 @@ and discussions on the V4L mailing list.</revremark>
</partinfo>
<title>Video for Linux Two API Specification</title>
- <subtitle>Revision 3.1</subtitle>
+ <subtitle>Revision 3.2</subtitle>
<chapter id="common">
&sub-common;
diff --git a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
index 677ea64..0ac0057 100644
--- a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
@@ -406,6 +406,15 @@ flag is typically present for relative controls or action controls where
writing a value will cause the device to carry out a given action
(⪚ motor control) but no meaningful value can be returned.</entry>
</row>
+ <row>
+ <entry><constant>V4L2_CTRL_FLAG_VOLATILE</constant></entry>
+ <entry>0x0080</entry>
+ <entry>This control is volatile, which means that the value of the control
+changes continuously. A typical example would be the current gain value if the device
+is in auto-gain mode. In such a case the hardware calculates the gain value based on
+the lighting conditions which can change over time. Note that setting a new value for
+a volatile control will have no effect. The new value will just be ignored.</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index fca24cc..c027766 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1082,6 +1082,7 @@ struct v4l2_querymenu {
#define V4L2_CTRL_FLAG_INACTIVE 0x0010
#define V4L2_CTRL_FLAG_SLIDER 0x0020
#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040
+#define V4L2_CTRL_FLAG_VOLATILE 0x0080
/* Query flag, to be ORed with the control ID */
#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 2/8] v4l2-ctrls: replace is_volatile with V4L2_CTRL_FLAG_VOLATILE.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 3/8] v4l2-ctrls: implement new volatile autocluster scheme Hans Verkuil
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
With the new flag there is no need anymore to have a separate is_volatile
field. Modify all users to use the new flag.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/video4linux/v4l2-controls.txt | 13 ++++-----
drivers/media/radio/radio-wl1273.c | 2 +-
drivers/media/radio/wl128x/fmdrv_v4l2.c | 2 +-
drivers/media/video/adp1653.c | 2 +-
drivers/media/video/pwc/pwc-v4l.c | 10 +++---
drivers/media/video/s5p-mfc/s5p_mfc_dec.c | 4 +-
drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 2 +-
drivers/media/video/saa7115.c | 2 +-
drivers/media/video/v4l2-ctrls.c | 36 ++++++++++++--------------
include/media/v4l2-ctrls.h | 12 +--------
10 files changed, 36 insertions(+), 49 deletions(-)
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt
index 9346fc8..f92ee30 100644
--- a/Documentation/video4linux/v4l2-controls.txt
+++ b/Documentation/video4linux/v4l2-controls.txt
@@ -285,11 +285,11 @@ implement g_volatile_ctrl like this:
Note that you use the 'new value' union as well in g_volatile_ctrl. In general
controls that need to implement g_volatile_ctrl are read-only controls.
-To mark a control as volatile you have to set the is_volatile flag:
+To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
if (ctrl)
- ctrl->is_volatile = 1;
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
For try/s_ctrl the new values (i.e. as passed by the user) are filled in and
you can modify them in try_ctrl or set them in s_ctrl. The 'cur' union
@@ -367,8 +367,7 @@ Driver specific controls can be created using v4l2_ctrl_new_custom():
The last argument is the priv pointer which can be set to driver-specific
private data.
-The v4l2_ctrl_config struct also has fields to set the is_private and is_volatile
-flags.
+The v4l2_ctrl_config struct also has a field to set the is_private flag.
If the name field is not set, then the framework will assume this is a standard
control and will fill in the name, type and flags fields accordingly.
@@ -506,8 +505,8 @@ operation should return the value that the hardware's automatic mode set up
automatically.
If the cluster is put in manual mode, then the manual controls should become
-active again and the is_volatile flag should be ignored (so g_volatile_ctrl is
-no longer called while in manual mode).
+active again and V4L2_CTRL_FLAG_VOLATILE should be ignored (so g_volatile_ctrl
+is no longer called while in manual mode).
Finally the V4L2_CTRL_FLAG_UPDATE should be set for the auto control since
changing that control affects the control flags of the manual controls.
@@ -520,7 +519,7 @@ void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
The first two arguments are identical to v4l2_ctrl_cluster. The third argument
tells the framework which value switches the cluster into manual mode. The
-last argument will optionally set the is_volatile flag for the non-auto controls.
+last argument will optionally set V4L2_CTRL_FLAG_VOLATILE for the non-auto controls.
The first control of the cluster is assumed to be the 'auto' control.
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 46cacf8..6d1e4e7 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -2109,7 +2109,7 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
V4L2_CID_TUNE_ANTENNA_CAPACITOR,
0, 255, 1, 255);
if (ctrl)
- ctrl->is_volatile = 1;
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
if (radio->ctrl_handler.error) {
r = radio->ctrl_handler.error;
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
index 8c0e192..54b34e5 100644
--- a/drivers/media/radio/wl128x/fmdrv_v4l2.c
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -557,7 +557,7 @@ int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
255, 1, 255);
if (ctrl)
- ctrl->is_volatile = 1;
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
return 0;
}
diff --git a/drivers/media/video/adp1653.c b/drivers/media/video/adp1653.c
index 279d75d..d0e8ac1 100644
--- a/drivers/media/video/adp1653.c
+++ b/drivers/media/video/adp1653.c
@@ -258,7 +258,7 @@ static int adp1653_init_controls(struct adp1653_flash *flash)
if (flash->ctrls.error)
return flash->ctrls.error;
- fault->is_volatile = 1;
+ fault->flags |= V4L2_CTRL_FLAG_VOLATILE;
flash->subdev.ctrl_handler = &flash->ctrls;
return 0;
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index e9a0e94..b6c20aa 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -640,7 +640,7 @@ static int pwc_set_awb(struct pwc_device *pdev)
return ret;
/* Update val when coming from auto or going to a preset */
- if (pdev->red_balance->is_volatile ||
+ 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) {
@@ -654,12 +654,12 @@ static int pwc_set_awb(struct pwc_device *pdev)
&pdev->blue_balance->val);
}
if (pdev->auto_white_balance->val == awb_auto) {
- pdev->red_balance->is_volatile = true;
- pdev->blue_balance->is_volatile = true;
+ pdev->red_balance->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ pdev->blue_balance->flags |= V4L2_CTRL_FLAG_VOLATILE;
pdev->color_bal_valid = false; /* Force cache update */
} else {
- pdev->red_balance->is_volatile = false;
- pdev->blue_balance->is_volatile = false;
+ pdev->red_balance->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
+ pdev->blue_balance->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
}
}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index b2c5052..bbf8ac7 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -165,7 +165,7 @@ static struct mfc_control controls[] = {
.maximum = 32,
.step = 1,
.default_value = 1,
- .is_volatile = 1,
+ .flags = V4L2_CTRL_FLAG_VOLATILE,
},
};
@@ -1020,7 +1020,7 @@ int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx)
return ctx->ctrl_handler.error;
}
if (controls[i].is_volatile && ctx->ctrls[i])
- ctx->ctrls[i]->is_volatile = 1;
+ ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
}
return 0;
}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index fee094a..59ef5da 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1814,7 +1814,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
return ctx->ctrl_handler.error;
}
if (controls[i].is_volatile && ctx->ctrls[i])
- ctx->ctrls[i]->is_volatile = 1;
+ ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
}
return 0;
}
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index f2ae405..e443d0d 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -1601,7 +1601,7 @@ static int saa711x_probe(struct i2c_client *client,
V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
- state->gain->is_volatile = 1;
+ state->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
sd->ctrl_handler = hdl;
if (hdl->error) {
int err = hdl->error;
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 06b6014..1667621 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -43,7 +43,7 @@ struct v4l2_ctrl_helper {
};
/* Small helper function to determine if the autocluster is set to manual
- mode. In that case the is_volatile flag should be ignored. */
+ mode. */
static bool is_cur_manual(const struct v4l2_ctrl *master)
{
return master->is_auto && master->cur.val == master->manual_mode_value;
@@ -1394,10 +1394,8 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
type, min, max,
is_menu ? cfg->menu_skip_mask : step,
def, flags, qmenu, priv);
- if (ctrl) {
+ if (ctrl)
ctrl->is_private = cfg->is_private;
- ctrl->is_volatile = cfg->is_volatile;
- }
return ctrl;
}
EXPORT_SYMBOL(v4l2_ctrl_new_custom);
@@ -1519,12 +1517,12 @@ void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
master->manual_mode_value = manual_val;
master->flags |= V4L2_CTRL_FLAG_UPDATE;
flag = is_cur_manual(master) ? 0 : V4L2_CTRL_FLAG_INACTIVE;
+ if (set_volatile)
+ flag |= V4L2_CTRL_FLAG_VOLATILE;
for (i = 1; i < ncontrols; i++)
- if (controls[i]) {
- controls[i]->is_volatile = set_volatile;
+ if (controls[i])
controls[i]->flags |= flag;
- }
}
EXPORT_SYMBOL(v4l2_ctrl_auto_cluster);
@@ -1579,9 +1577,6 @@ EXPORT_SYMBOL(v4l2_ctrl_grab);
static void log_ctrl(const struct v4l2_ctrl *ctrl,
const char *prefix, const char *colon)
{
- int fl_inact = ctrl->flags & V4L2_CTRL_FLAG_INACTIVE;
- int fl_grabbed = ctrl->flags & V4L2_CTRL_FLAG_GRABBED;
-
if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY))
return;
if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
@@ -1612,14 +1607,17 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
printk(KERN_CONT "unknown type %d", ctrl->type);
break;
}
- if (fl_inact && fl_grabbed)
- printk(KERN_CONT " (inactive, grabbed)\n");
- else if (fl_inact)
- printk(KERN_CONT " (inactive)\n");
- else if (fl_grabbed)
- printk(KERN_CONT " (grabbed)\n");
- else
- printk(KERN_CONT "\n");
+ if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
+ V4L2_CTRL_FLAG_GRABBED |
+ V4L2_CTRL_FLAG_VOLATILE)) {
+ if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+ printk(KERN_CONT " inactive");
+ if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)
+ printk(KERN_CONT " grabbed");
+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE)
+ printk(KERN_CONT " volatile");
+ }
+ printk(KERN_CONT "\n");
}
/* Log all controls owned by the handler */
@@ -2004,7 +2002,7 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, s32 *val)
v4l2_ctrl_lock(master);
/* g_volatile_ctrl will update the current control values */
- if (ctrl->is_volatile && !is_cur_manual(master)) {
+ if ((ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) && !is_cur_manual(master)) {
for (i = 0; i < master->ncontrols; i++)
cur_to_new(master->cluster[i]);
ret = call_op(master, g_volatile_ctrl);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 13fe4d7..bd6a4a7 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -65,10 +65,6 @@ struct v4l2_ctrl_ops {
* @is_private: If set, then this control is private to its handler and it
* will not be added to any other handlers. Drivers can set
* this flag.
- * @is_volatile: If set, then this control is volatile. This means that the
- * control's current value cannot be cached and needs to be
- * retrieved through the g_volatile_ctrl op. Drivers can set
- * this flag.
* @is_auto: If set, then this control selects whether the other cluster
* members are in 'automatic' mode or 'manual' mode. This is
* used for autogain/gain type clusters. Drivers should never
@@ -118,7 +114,6 @@ struct v4l2_ctrl {
unsigned int is_new:1;
unsigned int is_private:1;
- unsigned int is_volatile:1;
unsigned int is_auto:1;
unsigned int manual_mode_value:8;
@@ -208,9 +203,6 @@ struct v4l2_ctrl_handler {
* must be NULL.
* @is_private: If set, then this control is private to its handler and it
* will not be added to any other handlers.
- * @is_volatile: If set, then this control is volatile. This means that the
- * control's current value cannot be cached and needs to be
- * retrieved through the g_volatile_ctrl op.
*/
struct v4l2_ctrl_config {
const struct v4l2_ctrl_ops *ops;
@@ -225,7 +217,6 @@ struct v4l2_ctrl_config {
u32 menu_skip_mask;
const char * const *qmenu;
unsigned int is_private:1;
- unsigned int is_volatile:1;
};
/** v4l2_ctrl_fill() - Fill in the control fields based on the control ID.
@@ -389,8 +380,7 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls);
* @manual_val: The value for the first control in the cluster that equals the
* manual setting.
* @set_volatile: If true, then all controls except the first auto control will
- * have is_volatile set to true. If false, then is_volatile will not
- * be touched.
+ * be volatile.
*
* Use for control groups where one control selects some automatic feature and
* the other controls are only active whenever the automatic feature is turned
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 3/8] v4l2-ctrls: implement new volatile autocluster scheme.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 2/8] v4l2-ctrls: replace is_volatile with V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 4/8] v4l2-controls.txt: update auto cluster documentation Hans Verkuil
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
The problem tackled in this patch is how to handle volatile autoclusters
correctly. A volatile autocluster is a cluster of related controls where one
control is the control that toggles between manual and auto mode and the other
controls are the values for the manual mode. For example autogain and gain,
autoexposure and exposure, etc.
If the hardware lets you read out the automatically calculated manual values
while in automode, then those manual controls should be marked volatile.
E.g.: if autogain is on, and the hardware allows you to read out the current
gain value as calculated by the autogain circuitry, then you would mark the
gain control as volatile (i.e. continuously changing).
The question in such use cases is what to do when switching from the auto
mode to the manual mode. Should we switch to the last set manual values or
should the volatile values be copied and used as the initial manual values.
For example: suppose the mode is manual gain and gain is set to 5. Then
autogain is turned on and the gain is set by the hardware to 2. Finally
the user switches back to manual gain. What should the gain be? 2 or 5?
After a long discussion the decisions was made to keep the last value as
calculated by the auto mode (so 2 in the example above).
The reason is that webcams that do such things will adapt themselves to
the current light conditions and when you switch back to manual mode you
expect that you keep the same picture. If you would switch back to old
manual values, then that would give you a suddenly different picture,
which is jarring for the user.
Additionally, this would be difficult to implement in applications that
store and restore the control values at application exit and start.
If you want to keep the old manual values when you switch from auto to
manual, then there would have to be a way for applications to get hold
of those old values while in auto mode, but there isn't.
So this patch will do all the heavy lifting in v4l2-ctrls.c: if you go
from auto mode to manual mode and the manual controls are volatile, then
g_volatile_ctrl will be called to get the current values for the manual
controls before switching to manual mode.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/video/v4l2-ctrls.c | 74 +++++++++++++++++++++++++++++++++----
include/media/v4l2-ctrls.h | 3 ++
2 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 1667621..fc8666a 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -937,9 +937,14 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
break;
}
if (update_inactive) {
- ctrl->flags &= ~V4L2_CTRL_FLAG_INACTIVE;
- if (!is_cur_manual(ctrl->cluster[0]))
+ /* Note: update_inactive can only be true for auto clusters. */
+ ctrl->flags &=
+ ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE);
+ if (!is_cur_manual(ctrl->cluster[0])) {
ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ if (ctrl->cluster[0]->has_volatiles)
+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ }
}
if (changed || update_inactive) {
/* If a control was changed that was not one of the controls
@@ -1489,6 +1494,7 @@ EXPORT_SYMBOL(v4l2_ctrl_add_handler);
/* Cluster controls */
void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
{
+ bool has_volatiles = false;
int i;
/* The first control is the master control and it must not be NULL */
@@ -1498,8 +1504,11 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
if (controls[i]) {
controls[i]->cluster = controls;
controls[i]->ncontrols = ncontrols;
+ if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE)
+ has_volatiles = true;
}
}
+ controls[0]->has_volatiles = has_volatiles;
}
EXPORT_SYMBOL(v4l2_ctrl_cluster);
@@ -1507,18 +1516,21 @@ void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
u8 manual_val, bool set_volatile)
{
struct v4l2_ctrl *master = controls[0];
- u32 flag;
+ u32 flag = 0;
int i;
v4l2_ctrl_cluster(ncontrols, controls);
WARN_ON(ncontrols <= 1);
WARN_ON(manual_val < master->minimum || manual_val > master->maximum);
+ WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl));
master->is_auto = true;
+ master->has_volatiles = set_volatile;
master->manual_mode_value = manual_val;
master->flags |= V4L2_CTRL_FLAG_UPDATE;
- flag = is_cur_manual(master) ? 0 : V4L2_CTRL_FLAG_INACTIVE;
- if (set_volatile)
- flag |= V4L2_CTRL_FLAG_VOLATILE;
+
+ if (!is_cur_manual(master))
+ flag = V4L2_CTRL_FLAG_INACTIVE |
+ (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0);
for (i = 1; i < ncontrols; i++)
if (controls[i])
@@ -1957,7 +1969,8 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs
v4l2_ctrl_lock(master);
/* g_volatile_ctrl will update the new control values */
- if (has_op(master, g_volatile_ctrl) && !is_cur_manual(master)) {
+ if ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||
+ (master->has_volatiles && !is_cur_manual(master))) {
for (j = 0; j < master->ncontrols; j++)
cur_to_new(master->cluster[j]);
ret = call_op(master, g_volatile_ctrl);
@@ -2002,7 +2015,7 @@ static int get_ctrl(struct v4l2_ctrl *ctrl, s32 *val)
v4l2_ctrl_lock(master);
/* g_volatile_ctrl will update the current control values */
- if ((ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) && !is_cur_manual(master)) {
+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
for (i = 0; i < master->ncontrols; i++)
cur_to_new(master->cluster[i]);
ret = call_op(master, g_volatile_ctrl);
@@ -2118,6 +2131,20 @@ static int validate_ctrls(struct v4l2_ext_controls *cs,
return 0;
}
+/* Obtain the current volatile values of an autocluster and mark them
+ as new. */
+static void update_from_auto_cluster(struct v4l2_ctrl *master)
+{
+ int i;
+
+ for (i = 0; i < master->ncontrols; i++)
+ cur_to_new(master->cluster[i]);
+ if (!call_op(master, g_volatile_ctrl))
+ for (i = 1; i < master->ncontrols; i++)
+ if (master->cluster[i])
+ master->cluster[i]->is_new = 1;
+}
+
/* Try or try-and-set controls */
static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
struct v4l2_ext_controls *cs,
@@ -2163,6 +2190,31 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
if (master->cluster[j])
master->cluster[j]->is_new = 0;
+ /* For volatile autoclusters that are currently in auto mode
+ we need to discover if it will be set to manual mode.
+ If so, then we have to copy the current volatile values
+ first since those will become the new manual values (which
+ may be overwritten by explicit new values from this set
+ of controls). */
+ if (master->is_auto && master->has_volatiles &&
+ !is_cur_manual(master)) {
+ /* Pick an initial non-manual value */
+ s32 new_auto_val = master->manual_mode_value + 1;
+ u32 tmp_idx = idx;
+
+ do {
+ /* Check if the auto control is part of the
+ list, and remember the new value. */
+ if (helpers[tmp_idx].ctrl == master)
+ new_auto_val = cs->controls[tmp_idx].value;
+ tmp_idx = helpers[tmp_idx].next;
+ } while (tmp_idx);
+ /* If the new value == the manual value, then copy
+ the current volatile values. */
+ if (new_auto_val == master->manual_mode_value)
+ update_from_auto_cluster(master);
+ }
+
/* Copy the new caller-supplied control values.
user_to_new() sets 'is_new' to 1. */
do {
@@ -2233,6 +2285,12 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, s32 *val)
if (master->cluster[i])
master->cluster[i]->is_new = 0;
+ /* For autoclusters with volatiles that are switched from auto to
+ manual mode we have to update the current volatile values since
+ those will become the initial manual values after such a switch. */
+ if (master->is_auto && master->has_volatiles && ctrl == master &&
+ !is_cur_manual(master) && *val == master->manual_mode_value)
+ update_from_auto_cluster(master);
ctrl->val = *val;
ctrl->is_new = 1;
ret = try_or_set_cluster(fh, master, true);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index bd6a4a7..eeb3df6 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -69,6 +69,8 @@ struct v4l2_ctrl_ops {
* members are in 'automatic' mode or 'manual' mode. This is
* used for autogain/gain type clusters. Drivers should never
* set this flag directly.
+ * @has_volatiles: If set, then one or more members of the cluster are volatile.
+ * Drivers should never touch this flag.
* @manual_mode_value: If the is_auto flag is set, then this is the value
* of the auto control that determines if that control is in
* manual mode. So if the value of the auto control equals this
@@ -115,6 +117,7 @@ struct v4l2_ctrl {
unsigned int is_new:1;
unsigned int is_private:1;
unsigned int is_auto:1;
+ unsigned int has_volatiles:1;
unsigned int manual_mode_value:8;
const struct v4l2_ctrl_ops *ops;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 4/8] v4l2-controls.txt: update auto cluster documentation.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 2/8] v4l2-ctrls: replace is_volatile with V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 3/8] v4l2-ctrls: implement new volatile autocluster scheme Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 5/8] pwc: switch to the new auto-cluster volatile handling Hans Verkuil
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/video4linux/v4l2-controls.txt | 34 +++++++++-----------------
1 files changed, 12 insertions(+), 22 deletions(-)
diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt
index f92ee30..26aa057 100644
--- a/Documentation/video4linux/v4l2-controls.txt
+++ b/Documentation/video4linux/v4l2-controls.txt
@@ -495,18 +495,20 @@ Handling autogain/gain-type Controls with Auto Clusters
A common type of control cluster is one that handles 'auto-foo/foo'-type
controls. Typical examples are autogain/gain, autoexposure/exposure,
-autowhitebalance/red balance/blue balance. In all cases you have one controls
+autowhitebalance/red balance/blue balance. In all cases you have one control
that determines whether another control is handled automatically by the hardware,
or whether it is under manual control from the user.
If the cluster is in automatic mode, then the manual controls should be
-marked inactive. When the volatile controls are read the g_volatile_ctrl
-operation should return the value that the hardware's automatic mode set up
-automatically.
+marked inactive and volatile. When the volatile controls are read the
+g_volatile_ctrl operation should return the value that the hardware's automatic
+mode set up automatically.
If the cluster is put in manual mode, then the manual controls should become
-active again and V4L2_CTRL_FLAG_VOLATILE should be ignored (so g_volatile_ctrl
-is no longer called while in manual mode).
+active again and the volatile flag is cleared (so g_volatile_ctrl is no longer
+called while in manual mode). In addition just before switching to manual mode
+the current values as determined by the auto mode are copied as the new manual
+values.
Finally the V4L2_CTRL_FLAG_UPDATE should be set for the auto control since
changing that control affects the control flags of the manual controls.
@@ -520,6 +522,10 @@ void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
The first two arguments are identical to v4l2_ctrl_cluster. The third argument
tells the framework which value switches the cluster into manual mode. The
last argument will optionally set V4L2_CTRL_FLAG_VOLATILE for the non-auto controls.
+If it is false, then the manual controls are never volatile. You would typically
+use that if the hardware does not give you the option to read back to values as
+determined by the auto mode (e.g. if autogain is on, the hardware doesn't allow
+you to obtain the current gain value).
The first control of the cluster is assumed to be the 'auto' control.
@@ -680,16 +686,6 @@ if there are no controls at all.
count if nothing was done yet. If it is less than count then only the controls
up to error_idx-1 were successfully applied.
-3) When attempting to read a button control the framework will return -EACCES
-instead of -EINVAL as stated in the spec. It seems to make more sense since
-button controls are write-only controls.
-
-4) Attempting to write to a read-only control will return -EACCES instead of
--EINVAL as the spec says.
-
-5) The spec does not mention what should happen when you try to set/get a
-control class controls. The framework will return -EACCES.
-
Proposals for Extensions
========================
@@ -702,9 +698,3 @@ decimal. Useful for e.g. video_mute_yuv.
2) It is possible to mark in the controls array which controls have been
successfully written and which failed by for example adding a bit to the
control ID. Not sure if it is worth the effort, though.
-
-3) Trying to set volatile inactive controls should result in -EACCESS.
-
-4) Add a new flag to mark volatile controls. Any application that wants
-to store the state of the controls can then skip volatile inactive controls.
-Currently it is not possible to detect such controls.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 5/8] pwc: switch to the new auto-cluster volatile handling.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
` (2 preceding siblings ...)
2011-08-26 12:00 ` [RFCv2 PATCH 4/8] v4l2-controls.txt: update auto cluster documentation Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 6/8] vivi: add support for VIDIOC_LOG_STATUS Hans Verkuil
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
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: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/video/pwc/pwc-v4l.c | 127 +++++++++++++++---------------------
1 files changed, 53 insertions(+), 74 deletions(-)
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index b6c20aa..d15ae89 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -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 @@ leave:
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 (pdev->auto_white_balance->val != awb_manual)
+ return 0;
- if (ret == 0 && pdev->red_balance->is_new) {
- if (pdev->auto_white_balance->val != awb_manual)
- return -EBUSY;
+ 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 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;
+
+ if (pdev->autogain->val)
+ 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 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;
+
+ if (is_auto)
+ 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 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,35 +735,32 @@ 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;
+
+ if (pdev->autogain->val)
+ 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 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);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 6/8] vivi: add support for VIDIOC_LOG_STATUS.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
` (3 preceding siblings ...)
2011-08-26 12:00 ` [RFCv2 PATCH 5/8] pwc: switch to the new auto-cluster volatile handling Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 7/8] pwc: " Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 8/8] saa7115: use the new auto cluster support Hans Verkuil
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/video/vivi.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index a848bd2..da6149c 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -948,6 +948,14 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
return vb2_streamoff(&dev->vb_vidq, i);
}
+static int vidioc_log_status(struct file *file, void *priv)
+{
+ struct vivi_dev *dev = video_drvdata(file);
+
+ v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name);
+ return 0;
+}
+
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
{
return 0;
@@ -1191,6 +1199,7 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
+ .vidioc_log_status = vidioc_log_status,
.vidioc_subscribe_event = vidioc_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 7/8] pwc: add support for VIDIOC_LOG_STATUS.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
` (4 preceding siblings ...)
2011-08-26 12:00 ` [RFCv2 PATCH 6/8] vivi: add support for VIDIOC_LOG_STATUS Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 8/8] saa7115: use the new auto cluster support Hans Verkuil
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/video/pwc/pwc-v4l.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index d15ae89..bdc369c 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1078,6 +1078,14 @@ static int pwc_enum_frameintervals(struct file *file, void *fh,
return 0;
}
+static int pwc_log_status(struct file *file, void *priv)
+{
+ struct pwc_device *pdev = video_drvdata(file);
+
+ v4l2_ctrl_handler_log_status(&pdev->ctrl_handler, PWC_NAME);
+ return 0;
+}
+
static long pwc_default(struct file *file, void *fh, bool valid_prio,
int cmd, void *arg)
{
@@ -1101,6 +1109,7 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
.vidioc_dqbuf = pwc_dqbuf,
.vidioc_streamon = pwc_streamon,
.vidioc_streamoff = pwc_streamoff,
+ .vidioc_log_status = pwc_log_status,
.vidioc_enum_framesizes = pwc_enum_framesizes,
.vidioc_enum_frameintervals = pwc_enum_frameintervals,
.vidioc_default = pwc_default,
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFCv2 PATCH 8/8] saa7115: use the new auto cluster support.
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
` (5 preceding siblings ...)
2011-08-26 12:00 ` [RFCv2 PATCH 7/8] pwc: " Hans Verkuil
@ 2011-08-26 12:00 ` Hans Verkuil
6 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2011-08-26 12:00 UTC (permalink / raw)
To: linux-media; +Cc: Hans de Goede, Hans Verkuil
From: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/video/saa7115.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index e443d0d..cee98ea 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -793,7 +793,6 @@ static int saa711x_s_ctrl(struct v4l2_ctrl *ctrl)
saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val);
else
saa711x_write(sd, R_0F_CHROMA_GAIN_CNTL, state->gain->val | 0x80);
- v4l2_ctrl_activate(state->gain, !state->agc->val);
break;
default:
@@ -1601,7 +1600,6 @@ static int saa711x_probe(struct i2c_client *client,
V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
state->gain = v4l2_ctrl_new_std(hdl, &saa711x_ctrl_ops,
V4L2_CID_CHROMA_GAIN, 0, 127, 1, 40);
- state->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
sd->ctrl_handler = hdl;
if (hdl->error) {
int err = hdl->error;
@@ -1610,8 +1608,7 @@ static int saa711x_probe(struct i2c_client *client,
kfree(state);
return err;
}
- state->agc->flags |= V4L2_CTRL_FLAG_UPDATE;
- v4l2_ctrl_cluster(2, &state->agc);
+ v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
state->input = -1;
state->output = SAA7115_IPORT_ON;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling.
2011-08-26 12:00 [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
@ 2011-08-27 10:35 ` Hans de Goede
1 sibling, 0 replies; 10+ messages in thread
From: Hans de Goede @ 2011-08-27 10:35 UTC (permalink / raw)
To: Hans Verkuil; +Cc: linux-media
Looks good ACK series.
Acked-by: Hans de Goede <hdegoede@redhat.com>
On 08/26/2011 02:00 PM, Hans Verkuil wrote:
> This is the second patch for this. The first is here:
>
> http://comments.gmane.org/gmane.linux.drivers.video-input-infrastructure/36650
>
> This second version changes the pwc code as suggested by Hans de Goede and it
> adds documentation. The v4l2-ctrls.c code has also been improved to avoid
> unnecessary calls to update_from_auto_cluster(). Thanks to Hans de Goede for
> pointing me in the right direction.
>
> If there are no additional comments, then I will make a pull request early next
> week.
>
> This will also be the basis for converting soc-camera to the control framework.
>
> Regards,
>
> Hans
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-08-27 10:33 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-26 12:00 [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 1/8] videodev2.h: add V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 2/8] v4l2-ctrls: replace is_volatile with V4L2_CTRL_FLAG_VOLATILE Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 3/8] v4l2-ctrls: implement new volatile autocluster scheme Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 4/8] v4l2-controls.txt: update auto cluster documentation Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 5/8] pwc: switch to the new auto-cluster volatile handling Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 6/8] vivi: add support for VIDIOC_LOG_STATUS Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 7/8] pwc: " Hans Verkuil
2011-08-26 12:00 ` [RFCv2 PATCH 8/8] saa7115: use the new auto cluster support Hans Verkuil
2011-08-27 10:35 ` [RFCv2 PATCH 0/8] Add V4L2_CTRL_FLAG_VOLATILE and change volatile autocluster handling Hans de Goede
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.