Message ID | 20241018171104.1624426-1-tomm.merciai@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | media: v4l2-subdev: Refactor events | expand |
Hi Tommaso, Thanks for working on this. On Fri, Oct 18, 2024 at 07:11:03PM +0200, Tommaso Merciai wrote: > Controls can be exposed to userspace via a v4l-subdevX device, and > userspace has to be able to subscribe to control events so that it is > notified when the control changes value. > If a control handler is set for the subdev then set the HAS_EVENTS > flag automatically into v4l2_subdev_init_finalize() and use > v4l2_ctrl_subdev_subscribe_event() and v4l2_event_subdev_unsubscribe() > as default if subdev don't have .(un)subscribe control operations. > > Signed-off-by: Tommaso Merciai <tomm.merciai@gmail.com> > --- > drivers/media/v4l2-core/v4l2-subdev.c | 22 ++++++++++++++++++++-- > 1 file changed, 20 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c > index 3a4ba08810d2..77ca829b9983 100644 > --- a/drivers/media/v4l2-core/v4l2-subdev.c > +++ b/drivers/media/v4l2-core/v4l2-subdev.c > @@ -691,10 +691,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg, > return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); > > case VIDIOC_SUBSCRIBE_EVENT: > - return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); > + if (v4l2_subdev_has_op(sd, core, subscribe_event)) > + return v4l2_subdev_call(sd, core, subscribe_event, > + vfh, arg); > + > + if ((sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) && > + vfh->ctrl_handler) > + return v4l2_ctrl_subdev_subscribe_event(sd, vfh, arg); > + > + return -ENOIOCTLCMD; While this mostly does the same thing, I prefer the order of tests below. Could you align event subscription with unsubscription? > > case VIDIOC_UNSUBSCRIBE_EVENT: > - return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); > + if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) > + return -ENOIOCTLCMD; > + > + if (v4l2_subdev_has_op(sd, core, unsubscribe_event)) > + return v4l2_subdev_call(sd, core, unsubscribe_event, > + vfh, arg); > + > + return v4l2_event_subdev_unsubscribe(sd, vfh, arg); > > #ifdef CONFIG_VIDEO_ADV_DEBUG > case VIDIOC_DBG_G_REGISTER: > @@ -1641,6 +1656,9 @@ int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name, > } > } > > + if (sd->ctrl_handler) > + sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS; > + > state = __v4l2_subdev_state_alloc(sd, name, key); > if (IS_ERR(state)) > return PTR_ERR(state);
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 3a4ba08810d2..77ca829b9983 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -691,10 +691,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg, return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); case VIDIOC_SUBSCRIBE_EVENT: - return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); + if (v4l2_subdev_has_op(sd, core, subscribe_event)) + return v4l2_subdev_call(sd, core, subscribe_event, + vfh, arg); + + if ((sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) && + vfh->ctrl_handler) + return v4l2_ctrl_subdev_subscribe_event(sd, vfh, arg); + + return -ENOIOCTLCMD; case VIDIOC_UNSUBSCRIBE_EVENT: - return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); + if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) + return -ENOIOCTLCMD; + + if (v4l2_subdev_has_op(sd, core, unsubscribe_event)) + return v4l2_subdev_call(sd, core, unsubscribe_event, + vfh, arg); + + return v4l2_event_subdev_unsubscribe(sd, vfh, arg); #ifdef CONFIG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: @@ -1641,6 +1656,9 @@ int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name, } } + if (sd->ctrl_handler) + sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS; + state = __v4l2_subdev_state_alloc(sd, name, key); if (IS_ERR(state)) return PTR_ERR(state);
Controls can be exposed to userspace via a v4l-subdevX device, and userspace has to be able to subscribe to control events so that it is notified when the control changes value. If a control handler is set for the subdev then set the HAS_EVENTS flag automatically into v4l2_subdev_init_finalize() and use v4l2_ctrl_subdev_subscribe_event() and v4l2_event_subdev_unsubscribe() as default if subdev don't have .(un)subscribe control operations. Signed-off-by: Tommaso Merciai <tomm.merciai@gmail.com> --- drivers/media/v4l2-core/v4l2-subdev.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)