xref: /openbmc/linux/include/media/v4l2-device.h (revision ba76a6e6)
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 
2495db3a60SLaurent Pinchart #include <media/media-device.h>
252a1fcdf0SHans Verkuil #include <media/v4l2-subdev.h>
260f62fd6aSHans Verkuil #include <media/v4l2-dev.h>
272a1fcdf0SHans Verkuil 
282a1fcdf0SHans Verkuil /* Each instance of a V4L2 device should create the v4l2_device struct,
292a1fcdf0SHans Verkuil    either stand-alone or embedded in a larger struct.
302a1fcdf0SHans Verkuil 
312a1fcdf0SHans Verkuil    It allows easy access to sub-devices (see v4l2-subdev.h) and provides
322a1fcdf0SHans Verkuil    basic V4L2 device-level support.
332a1fcdf0SHans Verkuil  */
342a1fcdf0SHans Verkuil 
351351a58cSKay Sievers #define V4L2_DEVICE_NAME_SIZE (20 + 16)
362a1fcdf0SHans Verkuil 
370996517cSHans Verkuil struct v4l2_ctrl_handler;
380996517cSHans Verkuil 
392a1fcdf0SHans Verkuil struct v4l2_device {
403a63e449SHans Verkuil 	/* dev->driver_data points to this struct.
413a63e449SHans Verkuil 	   Note: dev might be NULL if there is no parent device
423a63e449SHans Verkuil 	   as is the case with e.g. ISA devices. */
432a1fcdf0SHans Verkuil 	struct device *dev;
4495db3a60SLaurent Pinchart #if defined(CONFIG_MEDIA_CONTROLLER)
4595db3a60SLaurent Pinchart 	struct media_device *mdev;
4695db3a60SLaurent Pinchart #endif
472a1fcdf0SHans Verkuil 	/* used to keep track of the registered subdevs */
482a1fcdf0SHans Verkuil 	struct list_head subdevs;
492a1fcdf0SHans Verkuil 	/* lock this struct; can be used by the driver as well if this
502a1fcdf0SHans Verkuil 	   struct is embedded into a larger struct. */
512a1fcdf0SHans Verkuil 	spinlock_t lock;
522a1fcdf0SHans Verkuil 	/* unique device name, by default the driver name + bus ID */
532a1fcdf0SHans Verkuil 	char name[V4L2_DEVICE_NAME_SIZE];
5498ec6339SHans Verkuil 	/* notify callback called by some sub-devices. */
5598ec6339SHans Verkuil 	void (*notify)(struct v4l2_subdev *sd,
5698ec6339SHans Verkuil 			unsigned int notification, void *arg);
570996517cSHans Verkuil 	/* The control handler. May be NULL. */
580996517cSHans Verkuil 	struct v4l2_ctrl_handler *ctrl_handler;
590f62fd6aSHans Verkuil 	/* Device's priority state */
600f62fd6aSHans Verkuil 	struct v4l2_prio_state prio;
61879aa24dSHans Verkuil 	/* BKL replacement mutex. Temporary solution only. */
62879aa24dSHans Verkuil 	struct mutex ioctl_lock;
63bedf8bcfSHans Verkuil 	/* Keep track of the references to this struct. */
64bedf8bcfSHans Verkuil 	struct kref ref;
65bedf8bcfSHans Verkuil 	/* Release function that is called when the ref count goes to 0. */
66bedf8bcfSHans Verkuil 	void (*release)(struct v4l2_device *v4l2_dev);
672a1fcdf0SHans Verkuil };
682a1fcdf0SHans Verkuil 
69bedf8bcfSHans Verkuil static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
70bedf8bcfSHans Verkuil {
71bedf8bcfSHans Verkuil 	kref_get(&v4l2_dev->ref);
72bedf8bcfSHans Verkuil }
73bedf8bcfSHans Verkuil 
74bedf8bcfSHans Verkuil int v4l2_device_put(struct v4l2_device *v4l2_dev);
75bedf8bcfSHans Verkuil 
763a63e449SHans Verkuil /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
773a63e449SHans Verkuil    dev may be NULL in rare cases (ISA devices). In that case you
783a63e449SHans Verkuil    must fill in the v4l2_dev->name field before calling this function. */
792a1fcdf0SHans Verkuil int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
80102e7813SHans Verkuil 
81102e7813SHans Verkuil /* Optional function to initialize the name field of struct v4l2_device using
82102e7813SHans Verkuil    the driver name and a driver-global atomic_t instance.
83102e7813SHans Verkuil    This function will increment the instance counter and returns the instance
84102e7813SHans Verkuil    value used in the name.
85102e7813SHans Verkuil 
86102e7813SHans Verkuil    Example:
87102e7813SHans Verkuil 
88102e7813SHans Verkuil    static atomic_t drv_instance = ATOMIC_INIT(0);
89102e7813SHans Verkuil 
90102e7813SHans Verkuil    ...
91102e7813SHans Verkuil 
92102e7813SHans Verkuil    instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance);
93102e7813SHans Verkuil 
94102e7813SHans Verkuil    The first time this is called the name field will be set to foo0 and
95102e7813SHans Verkuil    this function returns 0. If the name ends with a digit (e.g. cx18),
96102e7813SHans Verkuil    then the name will be set to cx18-0 since cx180 looks really odd. */
97102e7813SHans Verkuil int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
98102e7813SHans Verkuil 						atomic_t *instance);
99102e7813SHans Verkuil 
100ae6cfaacSHans Verkuil /* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects.
101ae6cfaacSHans Verkuil    Since the parent disappears this ensures that v4l2_dev doesn't have an
102ae6cfaacSHans Verkuil    invalid parent pointer. */
103ae6cfaacSHans Verkuil void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
104102e7813SHans Verkuil 
105ae6cfaacSHans Verkuil /* Unregister all sub-devices and any other resources related to v4l2_dev. */
1062a1fcdf0SHans Verkuil void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
1072a1fcdf0SHans Verkuil 
1082a1fcdf0SHans Verkuil /* Register a subdev with a v4l2 device. While registered the subdev module
1092a1fcdf0SHans Verkuil    is marked as in-use. An error is returned if the module is no longer
1102a1fcdf0SHans Verkuil    loaded when you attempt to register it. */
1113a63e449SHans Verkuil int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
1123a63e449SHans Verkuil 						struct v4l2_subdev *sd);
1132a1fcdf0SHans Verkuil /* Unregister a subdev with a v4l2 device. Can also be called if the subdev
1142a1fcdf0SHans Verkuil    wasn't registered. In that case it will do nothing. */
1152a1fcdf0SHans Verkuil void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
1162a1fcdf0SHans Verkuil 
1172096a5dcSLaurent Pinchart /* Register device nodes for all subdev of the v4l2 device that are marked with
1182096a5dcSLaurent Pinchart  * the V4L2_SUBDEV_FL_HAS_DEVNODE flag.
1192096a5dcSLaurent Pinchart  */
1202096a5dcSLaurent Pinchart int __must_check
1212096a5dcSLaurent Pinchart v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
1222096a5dcSLaurent Pinchart 
123ba76a6e6SHans Verkuil /* Send a notification to v4l2_device. */
124ba76a6e6SHans Verkuil static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
125ba76a6e6SHans Verkuil 				      unsigned int notification, void *arg)
126ba76a6e6SHans Verkuil {
127ba76a6e6SHans Verkuil 	if (sd && sd->v4l2_dev && sd->v4l2_dev->notify)
128ba76a6e6SHans Verkuil 		sd->v4l2_dev->notify(sd, notification, arg);
129ba76a6e6SHans Verkuil }
130ba76a6e6SHans Verkuil 
1312a1fcdf0SHans Verkuil /* Iterate over all subdevs. */
1323a63e449SHans Verkuil #define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
1333a63e449SHans Verkuil 	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
1342a1fcdf0SHans Verkuil 
1352a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching the condition.
1362a1fcdf0SHans Verkuil    Ignore any errors. Note that you cannot add or delete a subdev
1372a1fcdf0SHans Verkuil    while walking the subdevs list. */
1386c2d4dd1SGuennadi Liakhovetski #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
1396c2d4dd1SGuennadi Liakhovetski 	do { 								\
1406c2d4dd1SGuennadi Liakhovetski 		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
1416c2d4dd1SGuennadi Liakhovetski 			if ((cond) && (sd)->ops->o && (sd)->ops->o->f)	\
1426c2d4dd1SGuennadi Liakhovetski 				(sd)->ops->o->f((sd) , ##args);		\
1436c2d4dd1SGuennadi Liakhovetski 	} while (0)
1446c2d4dd1SGuennadi Liakhovetski 
1453a63e449SHans Verkuil #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
1462a1fcdf0SHans Verkuil 	do {								\
1476c2d4dd1SGuennadi Liakhovetski 		struct v4l2_subdev *__sd;				\
1482a1fcdf0SHans Verkuil 									\
1496c2d4dd1SGuennadi Liakhovetski 		__v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o,	\
1506c2d4dd1SGuennadi Liakhovetski 						f , ##args);		\
1512a1fcdf0SHans Verkuil 	} while (0)
1522a1fcdf0SHans Verkuil 
1532a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching the condition.
1542a1fcdf0SHans Verkuil    If the callback returns an error other than 0 or -ENOIOCTLCMD, then
1552a1fcdf0SHans Verkuil    return with that error code. Note that you cannot add or delete a
1562a1fcdf0SHans Verkuil    subdev while walking the subdevs list. */
1576c2d4dd1SGuennadi Liakhovetski #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
1582a1fcdf0SHans Verkuil ({ 									\
1596c2d4dd1SGuennadi Liakhovetski 	long __err = 0;							\
1602a1fcdf0SHans Verkuil 									\
1616c2d4dd1SGuennadi Liakhovetski 	list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) {		\
1626c2d4dd1SGuennadi Liakhovetski 		if ((cond) && (sd)->ops->o && (sd)->ops->o->f)		\
1636c2d4dd1SGuennadi Liakhovetski 			__err = (sd)->ops->o->f((sd) , ##args);		\
1646c2d4dd1SGuennadi Liakhovetski 		if (__err && __err != -ENOIOCTLCMD)			\
1652a1fcdf0SHans Verkuil 			break; 						\
1662a1fcdf0SHans Verkuil 	} 								\
1676c2d4dd1SGuennadi Liakhovetski 	(__err == -ENOIOCTLCMD) ? 0 : __err;				\
1686c2d4dd1SGuennadi Liakhovetski })
1696c2d4dd1SGuennadi Liakhovetski 
1706c2d4dd1SGuennadi Liakhovetski #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
1716c2d4dd1SGuennadi Liakhovetski ({									\
1726c2d4dd1SGuennadi Liakhovetski 	struct v4l2_subdev *__sd;					\
1736c2d4dd1SGuennadi Liakhovetski 	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o,	\
174c6c73544SGuennadi Liakhovetski 						f , ##args);		\
1752a1fcdf0SHans Verkuil })
1762a1fcdf0SHans Verkuil 
1772a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching grp_id (if 0, then
1782a1fcdf0SHans Verkuil    match them all). Ignore any errors. Note that you cannot add or delete
1792a1fcdf0SHans Verkuil    a subdev while walking the subdevs list. */
1803a63e449SHans Verkuil #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
1816c2d4dd1SGuennadi Liakhovetski 	do {								\
1826c2d4dd1SGuennadi Liakhovetski 		struct v4l2_subdev *__sd;				\
1836c2d4dd1SGuennadi Liakhovetski 									\
1846c2d4dd1SGuennadi Liakhovetski 		__v4l2_device_call_subdevs_p(v4l2_dev, __sd,		\
1856c2d4dd1SGuennadi Liakhovetski 			!(grpid) || __sd->grp_id == (grpid), o, f ,	\
1866c2d4dd1SGuennadi Liakhovetski 			##args);					\
1876c2d4dd1SGuennadi Liakhovetski 	} while (0)
1882a1fcdf0SHans Verkuil 
1892a1fcdf0SHans Verkuil /* Call the specified callback for all subdevs matching grp_id (if 0, then
1902a1fcdf0SHans Verkuil    match them all). If the callback returns an error other than 0 or
1912a1fcdf0SHans Verkuil    -ENOIOCTLCMD, then return with that error code. Note that you cannot
1922a1fcdf0SHans Verkuil    add or delete a subdev while walking the subdevs list. */
1933a63e449SHans Verkuil #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) 	\
1946c2d4dd1SGuennadi Liakhovetski ({									\
1956c2d4dd1SGuennadi Liakhovetski 	struct v4l2_subdev *__sd;					\
1966c2d4dd1SGuennadi Liakhovetski 	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,		\
1976c2d4dd1SGuennadi Liakhovetski 			!(grpid) || __sd->grp_id == (grpid), o, f ,	\
1986c2d4dd1SGuennadi Liakhovetski 			##args);					\
1996c2d4dd1SGuennadi Liakhovetski })
2002a1fcdf0SHans Verkuil 
2012180f92dSHans Verkuil #define v4l2_device_has_op(v4l2_dev, o, f)				\
2022180f92dSHans Verkuil ({									\
2032180f92dSHans Verkuil 	struct v4l2_subdev *__sd;					\
2042180f92dSHans Verkuil 	bool __result = false;						\
2052180f92dSHans Verkuil 	list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) {		\
2062180f92dSHans Verkuil 		if (v4l2_subdev_has_op(__sd, o, f)) {			\
2072180f92dSHans Verkuil 			__result = true;				\
2082180f92dSHans Verkuil 			break;						\
2092180f92dSHans Verkuil 		}							\
2102180f92dSHans Verkuil 	}								\
2112180f92dSHans Verkuil 	__result;							\
2122180f92dSHans Verkuil })
2132180f92dSHans Verkuil 
2142a1fcdf0SHans Verkuil #endif
215