]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
media: v4l2-ctrls.c: fix broken auto cluster handling
authorHans Verkuil <hverkuil@xs4all.nl>
Fri, 29 Jun 2018 10:12:43 +0000 (06:12 -0400)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 27 Sep 2018 06:20:47 +0000 (08:20 +0200)
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>
Signed-off-by: Sam Bobrowicz <sam@elite-embedded.com>
drivers/media/v4l2-core/v4l2-ctrls.c

index dd1db678718c80568c6520b69e4e7b34d22df7b1..00adcd007e3acf3840a3de240b71e399ca8b1f49 100644 (file)
@@ -3014,9 +3014,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;
 }