1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * V4L2 asynchronous subdevice registration API 4 * 5 * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de> 6 */ 7 8 #ifndef V4L2_ASYNC_H 9 #define V4L2_ASYNC_H 10 11 #include <linux/list.h> 12 #include <linux/mutex.h> 13 14 struct dentry; 15 struct device; 16 struct device_node; 17 struct v4l2_device; 18 struct v4l2_subdev; 19 struct v4l2_async_notifier; 20 21 /** 22 * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used 23 * in order to identify a match 24 * 25 * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address 26 * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node 27 * 28 * This enum is used by the asynchronous sub-device logic to define the 29 * algorithm that will be used to match an asynchronous device. 30 */ 31 enum v4l2_async_match_type { 32 V4L2_ASYNC_MATCH_I2C, 33 V4L2_ASYNC_MATCH_FWNODE, 34 }; 35 36 /** 37 * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge 38 * 39 * @match_type: type of match that will be used 40 * @match: union of per-bus type matching data sets 41 * @match.fwnode: 42 * pointer to &struct fwnode_handle to be matched. 43 * Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE. 44 * @match.i2c: embedded struct with I2C parameters to be matched. 45 * Both @match.i2c.adapter_id and @match.i2c.address 46 * should be matched. 47 * Used if @match_type is %V4L2_ASYNC_MATCH_I2C. 48 * @match.i2c.adapter_id: 49 * I2C adapter ID to be matched. 50 * Used if @match_type is %V4L2_ASYNC_MATCH_I2C. 51 * @match.i2c.address: 52 * I2C address to be matched. 53 * Used if @match_type is %V4L2_ASYNC_MATCH_I2C. 54 * @asd_list: used to add struct v4l2_async_subdev objects to the 55 * master notifier @asd_list 56 * @list: used to link struct v4l2_async_subdev objects, waiting to be 57 * probed, to a notifier->waiting list 58 * 59 * When this struct is used as a member in a driver specific struct, 60 * the driver specific struct shall contain the &struct 61 * v4l2_async_subdev as its first member. 62 */ 63 struct v4l2_async_subdev { 64 enum v4l2_async_match_type match_type; 65 union { 66 struct fwnode_handle *fwnode; 67 struct { 68 int adapter_id; 69 unsigned short address; 70 } i2c; 71 } match; 72 73 /* v4l2-async core private: not to be used by drivers */ 74 struct list_head list; 75 struct list_head asd_list; 76 }; 77 78 /** 79 * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations 80 * @bound: a subdevice driver has successfully probed one of the subdevices 81 * @complete: All subdevices have been probed successfully. The complete 82 * callback is only executed for the root notifier. 83 * @unbind: a subdevice is leaving 84 */ 85 struct v4l2_async_notifier_operations { 86 int (*bound)(struct v4l2_async_notifier *notifier, 87 struct v4l2_subdev *subdev, 88 struct v4l2_async_subdev *asd); 89 int (*complete)(struct v4l2_async_notifier *notifier); 90 void (*unbind)(struct v4l2_async_notifier *notifier, 91 struct v4l2_subdev *subdev, 92 struct v4l2_async_subdev *asd); 93 }; 94 95 /** 96 * struct v4l2_async_notifier - v4l2_device notifier data 97 * 98 * @ops: notifier operations 99 * @v4l2_dev: v4l2_device of the root notifier, NULL otherwise 100 * @sd: sub-device that registered the notifier, NULL otherwise 101 * @parent: parent notifier 102 * @asd_list: master list of struct v4l2_async_subdev 103 * @waiting: list of struct v4l2_async_subdev, waiting for their drivers 104 * @done: list of struct v4l2_subdev, already probed 105 * @list: member in a global list of notifiers 106 */ 107 struct v4l2_async_notifier { 108 const struct v4l2_async_notifier_operations *ops; 109 struct v4l2_device *v4l2_dev; 110 struct v4l2_subdev *sd; 111 struct v4l2_async_notifier *parent; 112 struct list_head asd_list; 113 struct list_head waiting; 114 struct list_head done; 115 struct list_head list; 116 }; 117 118 /** 119 * v4l2_async_debug_init - Initialize debugging tools. 120 * 121 * @debugfs_dir: pointer to the parent debugfs &struct dentry 122 */ 123 void v4l2_async_debug_init(struct dentry *debugfs_dir); 124 125 /** 126 * v4l2_async_nf_init - Initialize a notifier. 127 * 128 * @notifier: pointer to &struct v4l2_async_notifier 129 * 130 * This function initializes the notifier @asd_list. It must be called 131 * before adding a subdevice to a notifier, using one of: 132 * v4l2_async_nf_add_fwnode_remote(), 133 * v4l2_async_nf_add_fwnode(), 134 * v4l2_async_nf_add_i2c(), 135 * __v4l2_async_nf_add_subdev() or 136 * v4l2_async_nf_parse_fwnode_endpoints(). 137 */ 138 void v4l2_async_nf_init(struct v4l2_async_notifier *notifier); 139 140 /** 141 * __v4l2_async_nf_add_subdev - Add an async subdev to the 142 * notifier's master asd list. 143 * 144 * @notifier: pointer to &struct v4l2_async_notifier 145 * @asd: pointer to &struct v4l2_async_subdev 146 * 147 * \warning: Drivers should avoid using this function and instead use one of: 148 * v4l2_async_nf_add_fwnode(), 149 * v4l2_async_nf_add_fwnode_remote() or 150 * v4l2_async_nf_add_i2c(). 151 * 152 * Call this function before registering a notifier to link the provided @asd to 153 * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as 154 * it will be freed by the framework when the notifier is destroyed. 155 */ 156 int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier, 157 struct v4l2_async_subdev *asd); 158 159 struct v4l2_async_subdev * 160 __v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier, 161 struct fwnode_handle *fwnode, 162 unsigned int asd_struct_size); 163 /** 164 * v4l2_async_nf_add_fwnode - Allocate and add a fwnode async 165 * subdev to the notifier's master asd_list. 166 * 167 * @notifier: pointer to &struct v4l2_async_notifier 168 * @fwnode: fwnode handle of the sub-device to be matched, pointer to 169 * &struct fwnode_handle 170 * @type: Type of the driver's async sub-device struct. The &struct 171 * v4l2_async_subdev shall be the first member of the driver's async 172 * sub-device struct, i.e. both begin at the same memory address. 173 * 174 * Allocate a fwnode-matched asd of size asd_struct_size, and add it to the 175 * notifiers @asd_list. The function also gets a reference of the fwnode which 176 * is released later at notifier cleanup time. 177 */ 178 #define v4l2_async_nf_add_fwnode(notifier, fwnode, type) \ 179 ((type *)__v4l2_async_nf_add_fwnode(notifier, fwnode, sizeof(type))) 180 181 struct v4l2_async_subdev * 182 __v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif, 183 struct fwnode_handle *endpoint, 184 unsigned int asd_struct_size); 185 /** 186 * v4l2_async_nf_add_fwnode_remote - Allocate and add a fwnode 187 * remote async subdev to the 188 * notifier's master asd_list. 189 * 190 * @notifier: pointer to &struct v4l2_async_notifier 191 * @ep: local endpoint pointing to the remote sub-device to be matched, 192 * pointer to &struct fwnode_handle 193 * @type: Type of the driver's async sub-device struct. The &struct 194 * v4l2_async_subdev shall be the first member of the driver's async 195 * sub-device struct, i.e. both begin at the same memory address. 196 * 197 * Gets the remote endpoint of a given local endpoint, set it up for fwnode 198 * matching and adds the async sub-device to the notifier's @asd_list. The 199 * function also gets a reference of the fwnode which is released later at 200 * notifier cleanup time. 201 * 202 * This is just like v4l2_async_nf_add_fwnode(), but with the 203 * exception that the fwnode refers to a local endpoint, not the remote one. 204 */ 205 #define v4l2_async_nf_add_fwnode_remote(notifier, ep, type) \ 206 ((type *)__v4l2_async_nf_add_fwnode_remote(notifier, ep, sizeof(type))) 207 208 struct v4l2_async_subdev * 209 __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, 210 int adapter_id, unsigned short address, 211 unsigned int asd_struct_size); 212 /** 213 * v4l2_async_nf_add_i2c - Allocate and add an i2c async 214 * subdev to the notifier's master asd_list. 215 * 216 * @notifier: pointer to &struct v4l2_async_notifier 217 * @adapter: I2C adapter ID to be matched 218 * @address: I2C address of sub-device to be matched 219 * @type: Type of the driver's async sub-device struct. The &struct 220 * v4l2_async_subdev shall be the first member of the driver's async 221 * sub-device struct, i.e. both begin at the same memory address. 222 * 223 * Same as v4l2_async_nf_add_fwnode() but for I2C matched 224 * sub-devices. 225 */ 226 #define v4l2_async_nf_add_i2c(notifier, adapter, address, type) \ 227 ((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \ 228 sizeof(type))) 229 230 /** 231 * v4l2_async_nf_register - registers a subdevice asynchronous notifier 232 * 233 * @v4l2_dev: pointer to &struct v4l2_device 234 * @notifier: pointer to &struct v4l2_async_notifier 235 */ 236 int v4l2_async_nf_register(struct v4l2_device *v4l2_dev, 237 struct v4l2_async_notifier *notifier); 238 239 /** 240 * v4l2_async_subdev_nf_register - registers a subdevice asynchronous 241 * notifier for a sub-device 242 * 243 * @sd: pointer to &struct v4l2_subdev 244 * @notifier: pointer to &struct v4l2_async_notifier 245 */ 246 int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd, 247 struct v4l2_async_notifier *notifier); 248 249 /** 250 * v4l2_async_nf_unregister - unregisters a subdevice 251 * asynchronous notifier 252 * 253 * @notifier: pointer to &struct v4l2_async_notifier 254 */ 255 void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier); 256 257 /** 258 * v4l2_async_nf_cleanup - clean up notifier resources 259 * @notifier: the notifier the resources of which are to be cleaned up 260 * 261 * Release memory resources related to a notifier, including the async 262 * sub-devices allocated for the purposes of the notifier but not the notifier 263 * itself. The user is responsible for calling this function to clean up the 264 * notifier after calling 265 * v4l2_async_nf_add_fwnode_remote(), 266 * v4l2_async_nf_add_fwnode(), 267 * v4l2_async_nf_add_i2c(), 268 * __v4l2_async_nf_add_subdev() or 269 * v4l2_async_nf_parse_fwnode_endpoints(). 270 * 271 * There is no harm from calling v4l2_async_nf_cleanup() in other 272 * cases as long as its memory has been zeroed after it has been 273 * allocated. 274 */ 275 void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier); 276 277 /** 278 * v4l2_async_register_subdev - registers a sub-device to the asynchronous 279 * subdevice framework 280 * 281 * @sd: pointer to &struct v4l2_subdev 282 */ 283 int v4l2_async_register_subdev(struct v4l2_subdev *sd); 284 285 /** 286 * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the 287 * asynchronous sub-device framework and 288 * parse set up common sensor related 289 * devices 290 * 291 * @sd: pointer to struct &v4l2_subdev 292 * 293 * This function is just like v4l2_async_register_subdev() with the exception 294 * that calling it will also parse firmware interfaces for remote references 295 * using v4l2_async_nf_parse_fwnode_sensor() and registers the 296 * async sub-devices. The sub-device is similarly unregistered by calling 297 * v4l2_async_unregister_subdev(). 298 * 299 * While registered, the subdev module is marked as in-use. 300 * 301 * An error is returned if the module is no longer loaded on any attempts 302 * to register it. 303 */ 304 int __must_check 305 v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd); 306 307 /** 308 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous 309 * subdevice framework 310 * 311 * @sd: pointer to &struct v4l2_subdev 312 */ 313 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); 314 #endif 315