2019-05-27 09:55:05 +03:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2008-11-30 03:36:58 +03:00
/*
V4L2 device support header .
Copyright ( C ) 2008 Hans Verkuil < hverkuil @ xs4all . nl >
*/
# ifndef _V4L2_DEVICE_H
# define _V4L2_DEVICE_H
2009-12-09 14:40:05 +03:00
# include <media/media-device.h>
2008-11-30 03:36:58 +03:00
# include <media/v4l2-subdev.h>
2011-02-24 16:42:24 +03:00
# include <media/v4l2-dev.h>
2008-11-30 03:36:58 +03:00
2009-04-16 20:30:38 +04:00
# define V4L2_DEVICE_NAME_SIZE (20 + 16)
2008-11-30 03:36:58 +03:00
2010-08-01 21:32:42 +04:00
struct v4l2_ctrl_handler ;
2016-07-20 19:05:05 +03:00
/**
* struct v4l2_device - main struct to for V4L2 device drivers
*
* @ dev : pointer to struct device .
2018-05-03 17:52:51 +03:00
* @ mdev : pointer to struct media_device , may be NULL .
2016-07-20 19:05:05 +03:00
* @ subdevs : used to keep track of the registered subdevs
* @ lock : lock this struct ; can be used by the driver as well
* if this struct is embedded into a larger struct .
* @ name : unique device name , by default the driver name + bus ID
2017-09-22 19:31:02 +03:00
* @ notify : notify operation called by some sub - devices .
2016-08-31 01:16:25 +03:00
* @ ctrl_handler : The control handler . May be % NULL .
2016-07-20 19:05:05 +03:00
* @ prio : Device ' s priority state
* @ ref : Keep track of the references to this struct .
* @ release : Release function that is called when the ref count
* goes to 0.
*
* Each instance of a V4L2 device should create the v4l2_device struct ,
* either stand - alone or embedded in a larger struct .
*
* It allows easy access to sub - devices ( see v4l2 - subdev . h ) and provides
* basic V4L2 device - level support .
*
* . . note : :
*
2016-08-31 01:16:25 +03:00
* # ) @ dev - > driver_data points to this struct .
* # ) @ dev might be % NULL if there is no parent device
2016-07-20 19:05:05 +03:00
*/
2008-11-30 03:36:58 +03:00
struct v4l2_device {
struct device * dev ;
2009-12-09 14:40:05 +03:00
struct media_device * mdev ;
2008-11-30 03:36:58 +03:00
struct list_head subdevs ;
spinlock_t lock ;
char name [ V4L2_DEVICE_NAME_SIZE ] ;
2009-03-08 23:02:10 +03:00
void ( * notify ) ( struct v4l2_subdev * sd ,
unsigned int notification , void * arg ) ;
2010-08-01 21:32:42 +04:00
struct v4l2_ctrl_handler * ctrl_handler ;
2011-02-24 16:42:24 +03:00
struct v4l2_prio_state prio ;
2011-03-12 12:37:19 +03:00
struct kref ref ;
void ( * release ) ( struct v4l2_device * v4l2_dev ) ;
2008-11-30 03:36:58 +03:00
} ;
2016-07-20 19:05:05 +03:00
/**
* v4l2_device_get - gets a V4L2 device reference
*
2016-08-31 01:16:25 +03:00
* @ v4l2_dev : pointer to struct & v4l2_device
2016-07-20 19:05:05 +03:00
*
* This is an ancillary routine meant to increment the usage for the
2016-08-31 01:16:25 +03:00
* struct & v4l2_device pointed by @ v4l2_dev .
2016-07-20 19:05:05 +03:00
*/
2011-03-12 12:37:19 +03:00
static inline void v4l2_device_get ( struct v4l2_device * v4l2_dev )
{
kref_get ( & v4l2_dev - > ref ) ;
}
2016-07-20 19:05:05 +03:00
/**
2019-11-05 11:17:28 +03:00
* v4l2_device_put - puts a V4L2 device reference
2016-07-20 19:05:05 +03:00
*
2016-08-31 01:16:25 +03:00
* @ v4l2_dev : pointer to struct & v4l2_device
2016-07-20 19:05:05 +03:00
*
* This is an ancillary routine meant to decrement the usage for the
2016-08-31 01:16:25 +03:00
* struct & v4l2_device pointed by @ v4l2_dev .
2016-07-20 19:05:05 +03:00
*/
2011-03-12 12:37:19 +03:00
int v4l2_device_put ( struct v4l2_device * v4l2_dev ) ;
2016-07-20 19:05:05 +03:00
/**
2016-08-31 01:16:25 +03:00
* v4l2_device_register - Initialize v4l2_dev and make @ dev - > driver_data
* point to @ v4l2_dev .
2016-07-20 19:05:05 +03:00
*
2016-08-31 01:16:25 +03:00
* @ dev : pointer to struct & device
* @ v4l2_dev : pointer to struct & v4l2_device
2016-07-20 19:05:05 +03:00
*
* . . note : :
2016-08-31 01:16:25 +03:00
* @ dev may be % NULL in rare cases ( ISA devices ) .
* In such case the caller must fill in the @ v4l2_dev - > name field
2016-07-20 19:05:05 +03:00
* before calling this function .
*/
int __must_check v4l2_device_register ( struct device * dev ,
struct v4l2_device * v4l2_dev ) ;
/**
* v4l2_device_set_name - Optional function to initialize the
2016-08-31 01:16:25 +03:00
* name field of struct & v4l2_device
2016-07-20 19:05:05 +03:00
*
2016-08-31 01:16:25 +03:00
* @ v4l2_dev : pointer to struct & v4l2_device
2016-07-20 19:05:05 +03:00
* @ basename : base name for the device name
* @ instance : pointer to a static atomic_t var with the instance usage for
2016-08-31 01:16:25 +03:00
* the device driver .
2016-07-20 19:05:05 +03:00
*
2016-08-31 01:16:25 +03:00
* v4l2_device_set_name ( ) initializes the name field of struct & v4l2_device
2016-07-20 19:05:05 +03:00
* using the driver name and a driver - global atomic_t instance .
*
* This function will increment the instance counter and returns the
* instance value used in the name .
*
* Example :
*
* static atomic_t drv_instance = ATOMIC_INIT ( 0 ) ;
*
* . . .
*
2016-08-31 01:16:25 +03:00
* instance = v4l2_device_set_name ( & \ v4l2_dev , " foo " , & \ drv_instance ) ;
2016-07-20 19:05:05 +03:00
*
* The first time this is called the name field will be set to foo0 and
* this function returns 0. If the name ends with a digit ( e . g . cx18 ) ,
* then the name will be set to cx18 - 0 since cx180 would look really odd .
*/
2009-05-02 17:12:50 +04:00
int v4l2_device_set_name ( struct v4l2_device * v4l2_dev , const char * basename ,
2016-07-20 19:05:05 +03:00
atomic_t * instance ) ;
/**
* v4l2_device_disconnect - Change V4L2 device state to disconnected .
*
* @ v4l2_dev : pointer to struct v4l2_device
*
* Should be called when the USB parent disconnects .
2016-08-31 01:16:25 +03:00
* Since the parent disappears , this ensures that @ v4l2_dev doesn ' t have
2016-07-20 19:05:05 +03:00
* an invalid parent pointer .
*
2016-08-31 01:16:25 +03:00
* . . note : : This function sets @ v4l2_dev - > dev to NULL .
2016-07-20 19:05:05 +03:00
*/
2009-03-14 14:28:45 +03:00
void v4l2_device_disconnect ( struct v4l2_device * v4l2_dev ) ;
2009-05-02 17:12:50 +04:00
2016-07-20 19:05:05 +03:00
/**
* v4l2_device_unregister - Unregister all sub - devices and any other
2016-08-31 01:16:25 +03:00
* resources related to @ v4l2_dev .
2016-07-20 19:05:05 +03:00
*
* @ v4l2_dev : pointer to struct v4l2_device
*/
2008-11-30 03:36:58 +03:00
void v4l2_device_unregister ( struct v4l2_device * v4l2_dev ) ;
2016-07-20 19:05:05 +03:00
/**
* v4l2_device_register_subdev - Registers a subdev with a v4l2 device .
*
2016-08-31 01:16:25 +03:00
* @ v4l2_dev : pointer to struct & v4l2_device
2017-09-22 19:31:02 +03:00
* @ sd : pointer to & struct v4l2_subdev
2016-07-20 19:05:05 +03:00
*
* While registered , the subdev module is marked as in - use .
*
* An error is returned if the module is no longer loaded on any attempts
* to register it .
*/
2009-02-14 17:54:23 +03:00
int __must_check v4l2_device_register_subdev ( struct v4l2_device * v4l2_dev ,
2016-07-20 19:05:05 +03:00
struct v4l2_subdev * sd ) ;
/**
* v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device .
*
2017-09-22 19:31:02 +03:00
* @ sd : pointer to & struct v4l2_subdev
2016-07-20 19:05:05 +03:00
*
* . . note : :
*
* Can also be called if the subdev wasn ' t registered . In such
* case , it will do nothing .
*/
2008-11-30 03:36:58 +03:00
void v4l2_device_unregister_subdev ( struct v4l2_subdev * sd ) ;
2016-07-20 19:05:05 +03:00
/**
* v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs
* of the v4l2 device that are marked with
2016-08-31 01:16:25 +03:00
* the % V4L2_SUBDEV_FL_HAS_DEVNODE flag .
2016-07-20 19:05:05 +03:00
*
* @ v4l2_dev : pointer to struct v4l2_device
2009-12-09 14:38:49 +03:00
*/
int __must_check
v4l2_device_register_subdev_nodes ( struct v4l2_device * v4l2_dev ) ;
2016-07-20 19:05:05 +03:00
/**
* v4l2_subdev_notify - Sends a notification to v4l2_device .
*
2017-09-22 19:31:02 +03:00
* @ sd : pointer to & struct v4l2_subdev
2016-07-20 19:05:05 +03:00
* @ notification : type of notification . Please notice that the notification
2016-08-31 01:16:25 +03:00
* type is driver - specific .
2016-07-20 19:05:05 +03:00
* @ arg : arguments for the notification . Those are specific to each
* notification type .
*/
2014-03-17 16:54:19 +04:00
static inline void v4l2_subdev_notify ( struct v4l2_subdev * sd ,
unsigned int notification , void * arg )
{
if ( sd & & sd - > v4l2_dev & & sd - > v4l2_dev - > notify )
sd - > v4l2_dev - > notify ( sd , notification , arg ) ;
}
2018-05-23 14:11:06 +03:00
/**
* v4l2_device_supports_requests - Test if requests are supported .
*
* @ v4l2_dev : pointer to struct v4l2_device
*/
static inline bool v4l2_device_supports_requests ( struct v4l2_device * v4l2_dev )
{
return v4l2_dev - > mdev & & v4l2_dev - > mdev - > ops & &
v4l2_dev - > mdev - > ops - > req_queue ;
}
2017-09-22 19:31:02 +03:00
/* Helper macros to iterate over all subdevs. */
/**
* v4l2_device_for_each_subdev - Helper macro that interates over all
* sub - devices of a given & v4l2_device .
*
* @ sd : pointer that will be filled by the macro with all
* & struct v4l2_subdev pointer used as an iterator by the loop .
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
*
* This macro iterates over all sub - devices owned by the @ v4l2_dev device .
* It acts as a for loop iterator and executes the next statement with
* the @ sd variable pointing to each sub - device in turn .
*/
2009-02-14 17:54:23 +03:00
# define v4l2_device_for_each_subdev(sd, v4l2_dev) \
list_for_each_entry ( sd , & ( v4l2_dev ) - > subdevs , list )
2008-11-30 03:36:58 +03:00
2017-09-22 19:31:02 +03:00
/**
* __v4l2_device_call_subdevs_p - Calls the specified operation for
* all subdevs matching the condition .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ sd : pointer that will be filled by the macro with all
* & struct v4l2_subdev pointer used as an iterator by the loop .
* @ cond : condition to be match
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Ignore any errors .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
*/
2010-08-13 00:16:00 +04:00
# define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \
2016-08-31 01:16:25 +03:00
do { \
2010-08-13 00:16:00 +04:00
list_for_each_entry ( ( sd ) , & ( v4l2_dev ) - > subdevs , list ) \
if ( ( cond ) & & ( sd ) - > ops - > o & & ( sd ) - > ops - > o - > f ) \
( sd ) - > ops - > o - > f ( ( sd ) , # # args ) ; \
} while ( 0 )
2017-09-22 19:31:02 +03:00
/**
* __v4l2_device_call_subdevs - Calls the specified operation for
* all subdevs matching the condition .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ cond : condition to be match
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Ignore any errors .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
*/
2010-08-13 00:16:00 +04:00
# define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \
do { \
struct v4l2_subdev * __sd ; \
2008-11-30 03:36:58 +03:00
\
2010-08-13 00:16:00 +04:00
__v4l2_device_call_subdevs_p ( v4l2_dev , __sd , cond , o , \
f , # # args ) ; \
2008-11-30 03:36:58 +03:00
} while ( 0 )
2017-09-22 19:31:02 +03:00
/**
* __v4l2_device_call_subdevs_until_err_p - Calls the specified operation for
* all subdevs matching the condition .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ sd : pointer that will be filled by the macro with all
* & struct v4l2_subdev sub - devices associated with @ v4l2_dev .
* @ cond : condition to be match
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Return :
*
* If the operation returns an error other than 0 or ` ` - ENOIOCTLCMD ` `
* for any subdevice , then abort and return with that error code , zero
* otherwise .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
*/
2010-08-13 00:16:00 +04:00
# define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
2016-08-31 01:16:25 +03:00
( { \
2010-08-13 00:16:00 +04:00
long __err = 0 ; \
2008-11-30 03:36:58 +03:00
\
2010-08-13 00:16:00 +04:00
list_for_each_entry ( ( sd ) , & ( v4l2_dev ) - > subdevs , list ) { \
if ( ( cond ) & & ( sd ) - > ops - > o & & ( sd ) - > ops - > o - > f ) \
__err = ( sd ) - > ops - > o - > f ( ( sd ) , # # args ) ; \
if ( __err & & __err ! = - ENOIOCTLCMD ) \
2016-08-31 01:16:25 +03:00
break ; \
} \
2010-08-13 00:16:00 +04:00
( __err = = - ENOIOCTLCMD ) ? 0 : __err ; \
} )
2017-09-22 19:31:02 +03:00
/**
* __v4l2_device_call_subdevs_until_err - Calls the specified operation for
* all subdevs matching the condition .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ cond : condition to be match
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Return :
*
* If the operation returns an error other than 0 or ` ` - ENOIOCTLCMD ` `
* for any subdevice , then abort and return with that error code ,
* zero otherwise .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
*/
2010-08-13 00:16:00 +04:00
# define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
( { \
struct v4l2_subdev * __sd ; \
__v4l2_device_call_subdevs_until_err_p ( v4l2_dev , __sd , cond , o , \
2011-03-22 15:32:51 +03:00
f , # # args ) ; \
2008-11-30 03:36:58 +03:00
} )
2017-09-22 19:31:02 +03:00
/**
* v4l2_device_call_all - Calls the specified operation for
* all subdevs matching the & v4l2_subdev . grp_id , as assigned
* by the bridge driver .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ grpid : & struct v4l2_subdev - > grp_id group ID to match .
* Use 0 to match them all .
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Ignore any errors .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
*/
2010-08-13 00:16:00 +04:00
# define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \
do { \
struct v4l2_subdev * __sd ; \
\
__v4l2_device_call_subdevs_p ( v4l2_dev , __sd , \
2019-12-09 00:11:40 +03:00
( grpid ) = = 0 | | __sd - > grp_id = = ( grpid ) , o , f , \
2010-08-13 00:16:00 +04:00
# #args); \
} while ( 0 )
2008-11-30 03:36:58 +03:00
2017-09-22 19:31:02 +03:00
/**
* v4l2_device_call_until_err - Calls the specified operation for
* all subdevs matching the & v4l2_subdev . grp_id , as assigned
* by the bridge driver , until an error occurs .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ grpid : & struct v4l2_subdev - > grp_id group ID to match .
* Use 0 to match them all .
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Return :
*
* If the operation returns an error other than 0 or ` ` - ENOIOCTLCMD ` `
* for any subdevice , then abort and return with that error code ,
* zero otherwise .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
*/
2016-08-31 01:16:25 +03:00
# define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \
2010-08-13 00:16:00 +04:00
( { \
struct v4l2_subdev * __sd ; \
__v4l2_device_call_subdevs_until_err_p ( v4l2_dev , __sd , \
2019-12-09 00:11:40 +03:00
( grpid ) = = 0 | | __sd - > grp_id = = ( grpid ) , o , f , \
2010-08-13 00:16:00 +04:00
# #args); \
} )
2008-11-30 03:36:58 +03:00
2017-09-22 19:31:02 +03:00
/**
* v4l2_device_mask_call_all - Calls the specified operation for
* all subdevices where a group ID matches a specified bitmask .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ grpmsk : bitmask to be checked against & struct v4l2_subdev - > grp_id
* group ID to be matched . Use 0 to match them all .
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Ignore any errors .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
2016-04-03 23:44:16 +03:00
*/
# define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...) \
do { \
struct v4l2_subdev * __sd ; \
\
__v4l2_device_call_subdevs_p ( v4l2_dev , __sd , \
2019-12-09 00:11:40 +03:00
( grpmsk ) = = 0 | | ( __sd - > grp_id & ( grpmsk ) ) , o , \
f , # # args ) ; \
2016-04-03 23:44:16 +03:00
} while ( 0 )
2017-09-22 19:31:02 +03:00
/**
* v4l2_device_mask_call_until_err - Calls the specified operation for
* all subdevices where a group ID matches a specified bitmask .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ grpmsk : bitmask to be checked against & struct v4l2_subdev - > grp_id
* group ID to be matched . Use 0 to match them all .
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2020-02-27 23:42:36 +03:00
* @ args : arguments for @ f .
2017-09-22 19:31:02 +03:00
*
* Return :
*
* If the operation returns an error other than 0 or ` ` - ENOIOCTLCMD ` `
* for any subdevice , then abort and return with that error code ,
* zero otherwise .
*
* Note : subdevs cannot be added or deleted while walking
* the subdevs list .
2016-04-03 23:44:16 +03:00
*/
# define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
( { \
struct v4l2_subdev * __sd ; \
__v4l2_device_call_subdevs_until_err_p ( v4l2_dev , __sd , \
2019-12-09 00:11:40 +03:00
( grpmsk ) = = 0 | | ( __sd - > grp_id & ( grpmsk ) ) , o , \
f , # # args ) ; \
2016-04-03 23:44:16 +03:00
} )
2017-09-22 19:31:02 +03:00
/**
* v4l2_device_has_op - checks if any subdev with matching grpid has a
* given ops .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ grpid : & struct v4l2_subdev - > grp_id group ID to match .
* Use 0 to match them all .
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2016-04-03 23:44:16 +03:00
*/
# define v4l2_device_has_op(v4l2_dev, grpid, o, f) \
( { \
struct v4l2_subdev * __sd ; \
bool __result = false ; \
list_for_each_entry ( __sd , & ( v4l2_dev ) - > subdevs , list ) { \
if ( ( grpid ) & & __sd - > grp_id ! = ( grpid ) ) \
continue ; \
if ( v4l2_subdev_has_op ( __sd , o , f ) ) { \
__result = true ; \
break ; \
} \
} \
__result ; \
} )
2017-09-22 19:31:02 +03:00
/**
* v4l2_device_mask_has_op - checks if any subdev with matching group
* mask has a given ops .
*
* @ v4l2_dev : & struct v4l2_device owning the sub - devices to iterate over .
* @ grpmsk : bitmask to be checked against & struct v4l2_subdev - > grp_id
* group ID to be matched . Use 0 to match them all .
* @ o : name of the element at & struct v4l2_subdev_ops that contains @ f .
* Each element there groups a set of operations functions .
* @ f : operation function that will be called if @ cond matches .
* The operation functions are defined in groups , according to
* each element at & struct v4l2_subdev_ops .
2016-04-03 23:44:16 +03:00
*/
# define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f) \
2013-03-04 03:12:31 +04:00
( { \
struct v4l2_subdev * __sd ; \
bool __result = false ; \
list_for_each_entry ( __sd , & ( v4l2_dev ) - > subdevs , list ) { \
2016-04-03 23:44:16 +03:00
if ( ( grpmsk ) & & ! ( __sd - > grp_id & ( grpmsk ) ) ) \
continue ; \
2013-03-04 03:12:31 +04:00
if ( v4l2_subdev_has_op ( __sd , o , f ) ) { \
__result = true ; \
break ; \
} \
} \
__result ; \
} )
2008-11-30 03:36:58 +03:00
# endif