Hi Hans,
On Friday 04 March 2011 10:47:11 Hans Verkuil wrote:
> Hi Laurent,
>
> I'm afraid this approach won't work. See below for the details.
>
> On Thursday, March 03, 2011 16:13:33 Laurent Pinchart wrote:
> > Some hardware supports controls transactions. For instance, the MT9T001
> > sensor can optionally shadow registers that influence the output image,
> > allowing the host to explicitly control the shadow process.
> >
> > To support such hardware, drivers need to be notified when a control
> > transation is about to start and when it has finished. Add begin() and
> > commit() callback functions to the v4l2_ctrl_handler structure to
> > support such notifications.
> >
> > Signed-off-by: Laurent Pinchart <[email protected]>
> > ---
> >
> > drivers/media/video/v4l2-ctrls.c | 42
> > +++++++++++++++++++++++++++++++++++-- include/media/v4l2-ctrls.h
> > | 8 +++++++
> > 2 files changed, 47 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/media/video/v4l2-ctrls.c
> > b/drivers/media/video/v4l2-ctrls.c index 2412f08..d0e6265 100644
> > --- a/drivers/media/video/v4l2-ctrls.c
> > +++ b/drivers/media/video/v4l2-ctrls.c
> > @@ -1264,13 +1264,22 @@ EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
> >
> > int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
> > {
> >
> > struct v4l2_ctrl *ctrl;
> >
> > + unsigned int count = 0;
> >
> > int ret = 0;
> >
> > if (hdl == NULL)
> >
> > return 0;
> >
> > mutex_lock(&hdl->lock);
> >
> > - list_for_each_entry(ctrl, &hdl->ctrls, node)
> > + list_for_each_entry(ctrl, &hdl->ctrls, node) {
> >
> > ctrl->done = false;
> >
> > + count++;
> > + }
> > +
> > + if (hdl->begin) {
> > + ret = hdl->begin(hdl, count == 1);
>
> Note that count can be 0! In any case, rather then adding a counter you can
> use list_empty() and list_is_singular().
OK.
> > + if (ret)
> > + goto done;
> > + }
> >
> > list_for_each_entry(ctrl, &hdl->ctrls, node) {
> >
> > struct v4l2_ctrl *master = ctrl->cluster[0];
> >
> > @@ -1298,6 +1307,11 @@ int v4l2_ctrl_handler_setup(struct
> > v4l2_ctrl_handler *hdl)
> >
> > if (master->cluster[i])
> >
> > master->cluster[i]->done = true;
> >
> > }
> >
> > +
> > + if (hdl->commit)
> > + hdl->commit(hdl, ret != 0);
> > +
>
> > +done:
> I understand that you assume that all controls registered to a handler can
> be used in a transaction. But isn't it possible that only a subset of the
> controls is shadowed? And so only certain controls can be in a
> transaction?
>
> > mutex_unlock(&hdl->lock);
> > return ret;
> >
> > }
> >
> > @@ -1717,6 +1731,12 @@ static int try_or_set_ext_ctrls(struct
> > v4l2_ctrl_handler *hdl,
> >
> > return -EBUSY;
> >
> > }
> >
> > + if (set && hdl->begin) {
> > + ret = hdl->begin(hdl, cs->count == 1);
> > + if (ret)
> > + return ret;
> > + }
> > +
>
> You are assuming that all controls here are owned by the given control
> handler. That's not necessarily the case though as a control handler can
> inherit controls from another handler. So the cs array is an array of
> controls where each control can be owned by a different handler.
Right. That will indeed be an issue.
> > for (i = 0; !ret && i < cs->count; i++) {
> >
> > struct v4l2_ctrl *ctrl = helpers[i].ctrl;
> > struct v4l2_ctrl *master = ctrl->cluster[0];
> >
> > @@ -1747,6 +1767,10 @@ static int try_or_set_ext_ctrls(struct
> > v4l2_ctrl_handler *hdl,
> >
> > v4l2_ctrl_unlock(ctrl);
> > cluster_done(i, cs, helpers);
> >
> > }
> >
> > +
> > + if (set && hdl->commit)
> > + hdl->commit(hdl, ret == 0);
> > +
>
> If you rollback a transaction, then you also have a problem: if some of the
> controls of the transaction succeeded then try_or_set_control_cluster()
> will have set the current control value to the new value (since the 'set'
> succeeded).
>
> But if you rollback the transaction, then that means that the old value
> isn't restored for such controls.
>
> I don't see an easy solution for that offhand.
>
> I really wonder whether you are not reinventing the control cluster here.
>
> If you put all shadowed controls in a cluster, then it will behave exactly
> the same as a transaction.
>
> Yes, that might mean that all controls of a subdev are in a single cluster.
> But so what? That's the way to atomically handle controls that in some
> manner are related.
More and more sensors start to support control transactions. The MT9V034 even
supports two sets of control-related registers, with a single command to
switch between them. We need a way to support that in the control framework.
Putting all controls into a cluster seems like a dirty hack to workaround the
problem. The control framework will be less useful then.
If this is the only possible solution, then I would rename cluster to
something else, as the controls are definitely not a cluster. We could have a
flag that ask the control framework to handle all controls as if they're a big
cluster, and call s_ctrl only once per transaction.
It won't provide a way to configure two sets of controls and quickly swicth
between them though. This might need to be supported at some point.
--
Regards,
Laurent Pinchart
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html