xref: /linux/include/media/v4l2-device.h (revision f9129a2e537a4849c5194f98577bc274cda0d726)
12a1fcdf0SHans Verkuil /*
22a1fcdf0SHans Verkuil     V4L2 device support header.
32a1fcdf0SHans Verkuil 
42a1fcdf0SHans Verkuil     Copyright (C) 2008  Hans Verkuil <hverkuil@xs4all.nl>
52a1fcdf0SHans Verkuil 
62a1fcdf0SHans Verkuil     This program is free software; you can redistribute it and/or modify
72a1fcdf0SHans Verkuil     it under the terms of the GNU General Public License as published by
82a1fcdf0SHans Verkuil     the Free Software Foundation; either version 2 of the License, or
92a1fcdf0SHans Verkuil     (at your option) any later version.
102a1fcdf0SHans Verkuil 
112a1fcdf0SHans Verkuil     This program is distributed in the hope that it will be useful,
122a1fcdf0SHans Verkuil     but WITHOUT ANY WARRANTY; without even the implied warranty of
132a1fcdf0SHans Verkuil     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142a1fcdf0SHans Verkuil     GNU General Public License for more details.
152a1fcdf0SHans Verkuil 
162a1fcdf0SHans Verkuil     You should have received a copy of the GNU General Public License
172a1fcdf0SHans Verkuil     along with this program; if not, write to the Free Software
182a1fcdf0SHans Verkuil     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
192a1fcdf0SHans Verkuil  */
202a1fcdf0SHans Verkuil 
212a1fcdf0SHans Verkuil #ifndef _V4L2_DEVICE_H
222a1fcdf0SHans Verkuil #define _V4L2_DEVICE_H
232a1fcdf0SHans Verkuil 
242a1fcdf0SHans Verkuil #include <media/v4l2-subdev.h>
252a1fcdf0SHans Verkuil 
262a1fcdf0SHans Verkuil /* Each instance of a V4L2 device should create the v4l2_device struct,
272a1fcdf0SHans Verkuil    either stand-alone or embedded in a larger struct.
282a1fcdf0SHans Verkuil 
292a1fcdf0SHans Verkuil    It allows easy access to sub-devices (see v4l2-subdev.h) and provides
302a1fcdf0SHans Verkuil    basic V4L2 device-level support.
312a1fcdf0SHans Verkuil  */
322a1fcdf0SHans Verkuil 
332a1fcdf0SHans Verkuil #define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16)
342a1fcdf0SHans Verkuil 
352a1fcdf0SHans Verkuil struct v4l2_device {
362a1fcdf0SHans Verkuil 	/* dev->driver_data points to this struct */
372a1fcdf0SHans Verkuil 	struct device *dev;
382a1fcdf0SHans Verkuil 	/* used to keep track of the registered subdevs */
392a1fcdf0SHans Verkuil 	struct list_head subdevs;
402a1fcdf0SHans Verkuil 	/* lock this struct; can be used by the driver as well if this
412a1fcdf0SHans Verkuil 	   struct is embedded into a larger struct. */
422a1fcdf0SHans Verkuil 	spinlock_t lock;
432a1fcdf0SHans Verkuil 	/* unique device name, by default the driver name + bus ID */
442a1fcdf0SHans Verkuil 	char name[V4L2_DEVICE_NAME_SIZE];
452a1fcdf0SHans Verkuil };
462a1fcdf0SHans Verkuil 
472a1fcdf0SHans Verkuil /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev */
482a1fcdf0SHans Verkuil int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
492a1fcdf0SHans Verkuil /* Set v4l2_dev->dev->driver_data to NULL and unregister all sub-devices */
502a1fcdf0SHans Verkuil void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
512a1fcdf0SHans Verkuil 
522a1fcdf0SHans Verkuil /* Register a subdev with a v4l2 device. While registered the subdev module
532a1fcdf0SHans Verkuil    is marked as in-use. An error is returned if the module is no longer
542a1fcdf0SHans Verkuil    loaded when you attempt to register it. */
552a1fcdf0SHans Verkuil int __must_check v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd);
562a1fcdf0SHans Verkuil /* Unregister a subdev with a v4l2 device. Can also be called if the subdev
572a1fcdf0SHans Verkuil    wasn't registered. In that case it will do nothing. */
582a1fcdf0SHans Verkuil void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
592a1fcdf0SHans Verkuil 
602a1fcdf0SHans Verkuil /* Iterate over all subdevs. */
612a1fcdf0SHans Verkuil #define v4l2_device_for_each_subdev(sd, dev)				\
622a1fcdf0SHans Verkuil 	list_for_each_entry(sd, &(dev)->subdevs, list)
632a1fcdf0SHans Verkuil 
642a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching the condition.
652a1fcdf0SHans Verkuil    Ignore any errors. Note that you cannot add or delete a subdev
662a1fcdf0SHans Verkuil    while walking the subdevs list. */
672a1fcdf0SHans Verkuil #define __v4l2_device_call_subdevs(dev, cond, o, f, args...) 		\
682a1fcdf0SHans Verkuil 	do { 								\
692a1fcdf0SHans Verkuil 		struct v4l2_subdev *sd; 				\
702a1fcdf0SHans Verkuil 									\
712a1fcdf0SHans Verkuil 		list_for_each_entry(sd, &(dev)->subdevs, list)   	\
722a1fcdf0SHans Verkuil 			if ((cond) && sd->ops->o && sd->ops->o->f) 	\
732a1fcdf0SHans Verkuil 				sd->ops->o->f(sd , ##args); 		\
742a1fcdf0SHans Verkuil 	} while (0)
752a1fcdf0SHans Verkuil 
762a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching the condition.
772a1fcdf0SHans Verkuil    If the callback returns an error other than 0 or -ENOIOCTLCMD, then
782a1fcdf0SHans Verkuil    return with that error code. Note that you cannot add or delete a
792a1fcdf0SHans Verkuil    subdev while walking the subdevs list. */
802a1fcdf0SHans Verkuil #define __v4l2_device_call_subdevs_until_err(dev, cond, o, f, args...)  \
812a1fcdf0SHans Verkuil ({ 									\
822a1fcdf0SHans Verkuil 	struct v4l2_subdev *sd; 					\
83069b7479SHans Verkuil 	long err = 0; 							\
842a1fcdf0SHans Verkuil 									\
852a1fcdf0SHans Verkuil 	list_for_each_entry(sd, &(dev)->subdevs, list) { 		\
862a1fcdf0SHans Verkuil 		if ((cond) && sd->ops->o && sd->ops->o->f) 		\
872a1fcdf0SHans Verkuil 			err = sd->ops->o->f(sd , ##args); 		\
882a1fcdf0SHans Verkuil 		if (err && err != -ENOIOCTLCMD)				\
892a1fcdf0SHans Verkuil 			break; 						\
902a1fcdf0SHans Verkuil 	} 								\
912a1fcdf0SHans Verkuil 	(err == -ENOIOCTLCMD) ? 0 : err; 				\
922a1fcdf0SHans Verkuil })
932a1fcdf0SHans Verkuil 
942a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching grp_id (if 0, then
952a1fcdf0SHans Verkuil    match them all). Ignore any errors. Note that you cannot add or delete
962a1fcdf0SHans Verkuil    a subdev while walking the subdevs list. */
97*f9129a2eSHans Verkuil #define v4l2_device_call_all(dev, grpid, o, f, args...) 		\
982a1fcdf0SHans Verkuil 	__v4l2_device_call_subdevs(dev, 				\
99*f9129a2eSHans Verkuil 			!(grpid) || sd->grp_id == (grpid), o, f , ##args)
1002a1fcdf0SHans Verkuil 
1012a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching grp_id (if 0, then
1022a1fcdf0SHans Verkuil    match them all). If the callback returns an error other than 0 or
1032a1fcdf0SHans Verkuil    -ENOIOCTLCMD, then return with that error code. Note that you cannot
1042a1fcdf0SHans Verkuil    add or delete a subdev while walking the subdevs list. */
105*f9129a2eSHans Verkuil #define v4l2_device_call_until_err(dev, grpid, o, f, args...) 		\
1062a1fcdf0SHans Verkuil 	__v4l2_device_call_subdevs_until_err(dev,			\
107*f9129a2eSHans Verkuil 		       !(grpid) || sd->grp_id == (grpid), o, f , ##args)
1082a1fcdf0SHans Verkuil 
1092a1fcdf0SHans Verkuil #endif
110