Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * V4L2 asynchronous subdevice registration API
0004  *
0005  * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
0006  */
0007 
0008 #ifndef V4L2_ASYNC_H
0009 #define V4L2_ASYNC_H
0010 
0011 #include <linux/list.h>
0012 #include <linux/mutex.h>
0013 
0014 struct dentry;
0015 struct device;
0016 struct device_node;
0017 struct v4l2_device;
0018 struct v4l2_subdev;
0019 struct v4l2_async_notifier;
0020 
0021 /**
0022  * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used
0023  *  in order to identify a match
0024  *
0025  * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
0026  * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
0027  *
0028  * This enum is used by the asynchronous sub-device logic to define the
0029  * algorithm that will be used to match an asynchronous device.
0030  */
0031 enum v4l2_async_match_type {
0032     V4L2_ASYNC_MATCH_I2C,
0033     V4L2_ASYNC_MATCH_FWNODE,
0034 };
0035 
0036 /**
0037  * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
0038  *
0039  * @match_type: type of match that will be used
0040  * @match:  union of per-bus type matching data sets
0041  * @match.fwnode:
0042  *      pointer to &struct fwnode_handle to be matched.
0043  *      Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
0044  * @match.i2c:  embedded struct with I2C parameters to be matched.
0045  *      Both @match.i2c.adapter_id and @match.i2c.address
0046  *      should be matched.
0047  *      Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
0048  * @match.i2c.adapter_id:
0049  *      I2C adapter ID to be matched.
0050  *      Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
0051  * @match.i2c.address:
0052  *      I2C address to be matched.
0053  *      Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
0054  * @asd_list:   used to add struct v4l2_async_subdev objects to the
0055  *      master notifier @asd_list
0056  * @list:   used to link struct v4l2_async_subdev objects, waiting to be
0057  *      probed, to a notifier->waiting list
0058  *
0059  * When this struct is used as a member in a driver specific struct,
0060  * the driver specific struct shall contain the &struct
0061  * v4l2_async_subdev as its first member.
0062  */
0063 struct v4l2_async_subdev {
0064     enum v4l2_async_match_type match_type;
0065     union {
0066         struct fwnode_handle *fwnode;
0067         struct {
0068             int adapter_id;
0069             unsigned short address;
0070         } i2c;
0071     } match;
0072 
0073     /* v4l2-async core private: not to be used by drivers */
0074     struct list_head list;
0075     struct list_head asd_list;
0076 };
0077 
0078 /**
0079  * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
0080  * @bound:  a subdevice driver has successfully probed one of the subdevices
0081  * @complete:   All subdevices have been probed successfully. The complete
0082  *      callback is only executed for the root notifier.
0083  * @unbind: a subdevice is leaving
0084  * @destroy:    the asd is about to be freed
0085  */
0086 struct v4l2_async_notifier_operations {
0087     int (*bound)(struct v4l2_async_notifier *notifier,
0088              struct v4l2_subdev *subdev,
0089              struct v4l2_async_subdev *asd);
0090     int (*complete)(struct v4l2_async_notifier *notifier);
0091     void (*unbind)(struct v4l2_async_notifier *notifier,
0092                struct v4l2_subdev *subdev,
0093                struct v4l2_async_subdev *asd);
0094     void (*destroy)(struct v4l2_async_subdev *asd);
0095 };
0096 
0097 /**
0098  * struct v4l2_async_notifier - v4l2_device notifier data
0099  *
0100  * @ops:    notifier operations
0101  * @v4l2_dev:   v4l2_device of the root notifier, NULL otherwise
0102  * @sd:     sub-device that registered the notifier, NULL otherwise
0103  * @parent: parent notifier
0104  * @asd_list:   master list of struct v4l2_async_subdev
0105  * @waiting:    list of struct v4l2_async_subdev, waiting for their drivers
0106  * @done:   list of struct v4l2_subdev, already probed
0107  * @list:   member in a global list of notifiers
0108  */
0109 struct v4l2_async_notifier {
0110     const struct v4l2_async_notifier_operations *ops;
0111     struct v4l2_device *v4l2_dev;
0112     struct v4l2_subdev *sd;
0113     struct v4l2_async_notifier *parent;
0114     struct list_head asd_list;
0115     struct list_head waiting;
0116     struct list_head done;
0117     struct list_head list;
0118 };
0119 
0120 /**
0121  * v4l2_async_debug_init - Initialize debugging tools.
0122  *
0123  * @debugfs_dir: pointer to the parent debugfs &struct dentry
0124  */
0125 void v4l2_async_debug_init(struct dentry *debugfs_dir);
0126 
0127 /**
0128  * v4l2_async_nf_init - Initialize a notifier.
0129  *
0130  * @notifier: pointer to &struct v4l2_async_notifier
0131  *
0132  * This function initializes the notifier @asd_list. It must be called
0133  * before adding a subdevice to a notifier, using one of:
0134  * v4l2_async_nf_add_fwnode_remote(),
0135  * v4l2_async_nf_add_fwnode(),
0136  * v4l2_async_nf_add_i2c(),
0137  * __v4l2_async_nf_add_subdev() or
0138  * v4l2_async_nf_parse_fwnode_endpoints().
0139  */
0140 void v4l2_async_nf_init(struct v4l2_async_notifier *notifier);
0141 
0142 /**
0143  * __v4l2_async_nf_add_subdev - Add an async subdev to the
0144  *              notifier's master asd list.
0145  *
0146  * @notifier: pointer to &struct v4l2_async_notifier
0147  * @asd: pointer to &struct v4l2_async_subdev
0148  *
0149  * \warning: Drivers should avoid using this function and instead use one of:
0150  * v4l2_async_nf_add_fwnode(),
0151  * v4l2_async_nf_add_fwnode_remote() or
0152  * v4l2_async_nf_add_i2c().
0153  *
0154  * Call this function before registering a notifier to link the provided @asd to
0155  * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as
0156  * it will be freed by the framework when the notifier is destroyed.
0157  */
0158 int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier,
0159                    struct v4l2_async_subdev *asd);
0160 
0161 struct v4l2_async_subdev *
0162 __v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier,
0163                struct fwnode_handle *fwnode,
0164                unsigned int asd_struct_size);
0165 /**
0166  * v4l2_async_nf_add_fwnode - Allocate and add a fwnode async
0167  *              subdev to the notifier's master asd_list.
0168  *
0169  * @notifier: pointer to &struct v4l2_async_notifier
0170  * @fwnode: fwnode handle of the sub-device to be matched, pointer to
0171  *      &struct fwnode_handle
0172  * @type: Type of the driver's async sub-device struct. The &struct
0173  *    v4l2_async_subdev shall be the first member of the driver's async
0174  *    sub-device struct, i.e. both begin at the same memory address.
0175  *
0176  * Allocate a fwnode-matched asd of size asd_struct_size, and add it to the
0177  * notifiers @asd_list. The function also gets a reference of the fwnode which
0178  * is released later at notifier cleanup time.
0179  */
0180 #define v4l2_async_nf_add_fwnode(notifier, fwnode, type)        \
0181     ((type *)__v4l2_async_nf_add_fwnode(notifier, fwnode, sizeof(type)))
0182 
0183 struct v4l2_async_subdev *
0184 __v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif,
0185                   struct fwnode_handle *endpoint,
0186                   unsigned int asd_struct_size);
0187 /**
0188  * v4l2_async_nf_add_fwnode_remote - Allocate and add a fwnode
0189  *                        remote async subdev to the
0190  *                        notifier's master asd_list.
0191  *
0192  * @notifier: pointer to &struct v4l2_async_notifier
0193  * @ep: local endpoint pointing to the remote sub-device to be matched,
0194  *  pointer to &struct fwnode_handle
0195  * @type: Type of the driver's async sub-device struct. The &struct
0196  *    v4l2_async_subdev shall be the first member of the driver's async
0197  *    sub-device struct, i.e. both begin at the same memory address.
0198  *
0199  * Gets the remote endpoint of a given local endpoint, set it up for fwnode
0200  * matching and adds the async sub-device to the notifier's @asd_list. The
0201  * function also gets a reference of the fwnode which is released later at
0202  * notifier cleanup time.
0203  *
0204  * This is just like v4l2_async_nf_add_fwnode(), but with the
0205  * exception that the fwnode refers to a local endpoint, not the remote one.
0206  */
0207 #define v4l2_async_nf_add_fwnode_remote(notifier, ep, type) \
0208     ((type *)__v4l2_async_nf_add_fwnode_remote(notifier, ep, sizeof(type)))
0209 
0210 struct v4l2_async_subdev *
0211 __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier,
0212             int adapter_id, unsigned short address,
0213             unsigned int asd_struct_size);
0214 /**
0215  * v4l2_async_nf_add_i2c - Allocate and add an i2c async
0216  *              subdev to the notifier's master asd_list.
0217  *
0218  * @notifier: pointer to &struct v4l2_async_notifier
0219  * @adapter: I2C adapter ID to be matched
0220  * @address: I2C address of sub-device to be matched
0221  * @type: Type of the driver's async sub-device struct. The &struct
0222  *    v4l2_async_subdev shall be the first member of the driver's async
0223  *    sub-device struct, i.e. both begin at the same memory address.
0224  *
0225  * Same as v4l2_async_nf_add_fwnode() but for I2C matched
0226  * sub-devices.
0227  */
0228 #define v4l2_async_nf_add_i2c(notifier, adapter, address, type) \
0229     ((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \
0230                      sizeof(type)))
0231 
0232 /**
0233  * v4l2_async_nf_register - registers a subdevice asynchronous notifier
0234  *
0235  * @v4l2_dev: pointer to &struct v4l2_device
0236  * @notifier: pointer to &struct v4l2_async_notifier
0237  */
0238 int v4l2_async_nf_register(struct v4l2_device *v4l2_dev,
0239                struct v4l2_async_notifier *notifier);
0240 
0241 /**
0242  * v4l2_async_subdev_nf_register - registers a subdevice asynchronous
0243  *                   notifier for a sub-device
0244  *
0245  * @sd: pointer to &struct v4l2_subdev
0246  * @notifier: pointer to &struct v4l2_async_notifier
0247  */
0248 int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd,
0249                   struct v4l2_async_notifier *notifier);
0250 
0251 /**
0252  * v4l2_async_nf_unregister - unregisters a subdevice
0253  *  asynchronous notifier
0254  *
0255  * @notifier: pointer to &struct v4l2_async_notifier
0256  */
0257 void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier);
0258 
0259 /**
0260  * v4l2_async_nf_cleanup - clean up notifier resources
0261  * @notifier: the notifier the resources of which are to be cleaned up
0262  *
0263  * Release memory resources related to a notifier, including the async
0264  * sub-devices allocated for the purposes of the notifier but not the notifier
0265  * itself. The user is responsible for calling this function to clean up the
0266  * notifier after calling
0267  * v4l2_async_nf_add_fwnode_remote(),
0268  * v4l2_async_nf_add_fwnode(),
0269  * v4l2_async_nf_add_i2c(),
0270  * __v4l2_async_nf_add_subdev() or
0271  * v4l2_async_nf_parse_fwnode_endpoints().
0272  *
0273  * There is no harm from calling v4l2_async_nf_cleanup() in other
0274  * cases as long as its memory has been zeroed after it has been
0275  * allocated.
0276  */
0277 void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier);
0278 
0279 /**
0280  * v4l2_async_register_subdev - registers a sub-device to the asynchronous
0281  *  subdevice framework
0282  *
0283  * @sd: pointer to &struct v4l2_subdev
0284  */
0285 int v4l2_async_register_subdev(struct v4l2_subdev *sd);
0286 
0287 /**
0288  * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the
0289  *                     asynchronous sub-device framework and
0290  *                     parse set up common sensor related
0291  *                     devices
0292  *
0293  * @sd: pointer to struct &v4l2_subdev
0294  *
0295  * This function is just like v4l2_async_register_subdev() with the exception
0296  * that calling it will also parse firmware interfaces for remote references
0297  * using v4l2_async_nf_parse_fwnode_sensor() and registers the
0298  * async sub-devices. The sub-device is similarly unregistered by calling
0299  * v4l2_async_unregister_subdev().
0300  *
0301  * While registered, the subdev module is marked as in-use.
0302  *
0303  * An error is returned if the module is no longer loaded on any attempts
0304  * to register it.
0305  */
0306 int __must_check
0307 v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd);
0308 
0309 /**
0310  * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
0311  *  subdevice framework
0312  *
0313  * @sd: pointer to &struct v4l2_subdev
0314  */
0315 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
0316 #endif