summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2018-06-29 06:12:43 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-07-04 08:33:32 -0400
commit0245abf8206fb573a3977558de2b7b2be6f3d9f8 (patch)
tree3a56b7c6a6c1e5c4b87057fbadedde034ade631a
parent662a99e145661c2b35155cf375044deae9b79896 (diff)
downloadlinux-stable-0245abf8206fb573a3977558de2b7b2be6f3d9f8.tar.gz
linux-stable-0245abf8206fb573a3977558de2b7b2be6f3d9f8.tar.bz2
linux-stable-0245abf8206fb573a3977558de2b7b2be6f3d9f8.zip
media: v4l2-ctrls.c: fix broken auto cluster handling
When you switch from auto to manual mode for an auto-cluster (e.g. autogain+gain controls), then the current HW value has to be copied to the current control value. However, has_changed was never set to true, so new_to_cur didn't actually copy this value. Reported-by: Hugues FRUCHET <hugues.fruchet@st.com> Tested-by: Hugues FRUCHET <hugues.fruchet@st.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index d29e45516eb7..d1087573da34 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -3137,9 +3137,22 @@ static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master,
/* If OK, then make the new values permanent. */
update_flag = is_cur_manual(master) != is_new_manual(master);
- for (i = 0; i < master->ncontrols; i++)
+
+ for (i = 0; i < master->ncontrols; i++) {
+ /*
+ * If we switch from auto to manual mode, and this cluster
+ * contains volatile controls, then all non-master controls
+ * have to be marked as changed. The 'new' value contains
+ * the volatile value (obtained by update_from_auto_cluster),
+ * which now has to become the current value.
+ */
+ if (i && update_flag && is_new_manual(master) &&
+ master->has_volatiles && master->cluster[i])
+ master->cluster[i]->has_changed = true;
+
new_to_cur(fh, master->cluster[i], ch_flags |
((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0));
+ }
return 0;
}