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 * @destroy: the asd is about to be freed 85 */ 86 struct v4l2_async_notifier_operations { 87 int (*bound)(struct v4l2_async_notifier *notifier, 88 struct v4l2_subdev *subdev, 89 struct v4l2_async_subdev *asd); 90 int (*complete)(struct v4l2_async_notifier *notifier); 91 void (*unbind)(struct v4l2_async_notifier *notifier, 92 struct v4l2_subdev *subdev, 93 struct v4l2_async_subdev *asd); 94 void (*destroy)(struct v4l2_async_subdev *asd); 95 }; 96 97 /** 98 * struct v4l2_async_notifier - v4l2_device notifier data 99 * 100 * @ops: notifier operations 101 * @v4l2_dev: v4l2_device of the root notifier, NULL otherwise 102 * @sd: sub-device that registered the notifier, NULL otherwise 103 * @parent: parent notifier 104 * @asd_list: master list of struct v4l2_async_subdev 105 * @waiting: list of struct v4l2_async_subdev, waiting for their drivers 106 * @done: list of struct v4l2_subdev, already probed 107 * @list: member in a global list of notifiers 108 */ 109 struct v4l2_async_notifier { 110 const struct v4l2_async_notifier_operations *ops; 111 struct v4l2_device *v4l2_dev; 112 struct v4l2_subdev *sd; 113 struct v4l2_async_notifier *parent; 114 struct list_head asd_list; 115 struct list_head waiting; 116 struct list_head done; 117 struct list_head list; 118 }; 119 120 /** 121 * v4l2_async_debug_init - Initialize debugging tools. 122 * 123 * @debugfs_dir: pointer to the parent debugfs &struct dentry 124 */ 125 void v4l2_async_debug_init(struct dentry *debugfs_dir); 126 127 /** 128 * v4l2_async_nf_init - Initialize a notifier. 129 * 130 * @notifier: pointer to &struct v4l2_async_notifier 131 * 132 * This function initializes the notifier @asd_list. It must be called 133 * before adding a subdevice to a notifier, using one of: 134 * v4l2_async_nf_add_fwnode_remote(), 135 * v4l2_async_nf_add_fwnode(), 136 * v4l2_async_nf_add_i2c(), 137 * __v4l2_async_nf_add_subdev() or 138 * v4l2_async_nf_parse_fwnode_endpoints(). 139 */ 140 void v4l2_async_nf_init(struct v4l2_async_notifier *notifier); 141 142 /** 143 * __v4l2_async_nf_add_subdev - Add an async subdev to the 144 * notifier's master asd list. 145 * 146 * @notifier: pointer to &struct v4l2_async_notifier 147 * @asd: pointer to &struct v4l2_async_subdev 148 * 149 * \warning: Drivers should avoid using this function and instead use one of: 150 * v4l2_async_nf_add_fwnode(), 151 * v4l2_async_nf_add_fwnode_remote() or 152 * v4l2_async_nf_add_i2c(). 153 * 154 * Call this function before registering a notifier to link the provided @asd to 155 * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as 156 * it will be freed by the framework when the notifier is destroyed. 157 */ 158 int __v4l2_async_nf_add_subdev(struct v4l2_async_notifier *notifier, 159 struct v4l2_async_subdev *asd); 160 161 struct v4l2_async_subdev * 162 __v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier, 163 struct fwnode_handle *fwnode, 164 unsigned int asd_struct_size); 165 /** 166 * v4l2_async_nf_add_fwnode - Allocate and add a fwnode async 167 * subdev to the notifier's master asd_list. 168 * 169 * @notifier: pointer to &struct v4l2_async_notifier 170 * @fwnode: fwnode handle of the sub-device to be matched, pointer to 171 * &struct fwnode_handle 172 * @type: Type of the driver's async sub-device struct. The &struct 173 * v4l2_async_subdev shall be the first member of the driver's async 174 * sub-device struct, i.e. both begin at the same memory address. 175 * 176 * Allocate a fwnode-matched asd of size asd_struct_size, and add it to the 177 * notifiers @asd_list. The function also gets a reference of the fwnode which 178 * is released later at notifier cleanup time. 179 */ 180 #define v4l2_async_nf_add_fwnode(notifier, fwnode, type) \ 181 ((type *)__v4l2_async_nf_add_fwnode(notifier, fwnode, sizeof(type))) 182 183 struct v4l2_async_subdev * 184 __v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif, 185 struct fwnode_handle *endpoint, 186 unsigned int asd_struct_size); 187 /** 188 * v4l2_async_nf_add_fwnode_remote - Allocate and add a fwnode 189 * remote async subdev to the 190 * notifier's master asd_list. 191 * 192 * @notifier: pointer to &struct v4l2_async_notifier 193 * @ep: local endpoint pointing to the remote sub-device to be matched, 194 * pointer to &struct fwnode_handle 195 * @type: Type of the driver's async sub-device struct. The &struct 196 * v4l2_async_subdev shall be the first member of the driver's async 197 * sub-device struct, i.e. both begin at the same memory address. 198 * 199 * Gets the remote endpoint of a given local endpoint, set it up for fwnode 200 * matching and adds the async sub-device to the notifier's @asd_list. The 201 * function also gets a reference of the fwnode which is released later at 202 * notifier cleanup time. 203 * 204 * This is just like v4l2_async_nf_add_fwnode(), but with the 205 * exception that the fwnode refers to a local endpoint, not the remote one. 206 */ 207 #define v4l2_async_nf_add_fwnode_remote(notifier, ep, type) \ 208 ((type *)__v4l2_async_nf_add_fwnode_remote(notifier, ep, sizeof(type))) 209 210 struct v4l2_async_subdev * 211 __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, 212 int adapter_id, unsigned short address, 213 unsigned int asd_struct_size); 214 /** 215 * v4l2_async_nf_add_i2c - Allocate and add an i2c async 216 * subdev to the notifier's master asd_list. 217 * 218 * @notifier: pointer to &struct v4l2_async_notifier 219 * @adapter: I2C adapter ID to be matched 220 * @address: I2C address of sub-device to be matched 221 * @type: Type of the driver's async sub-device struct. The &struct 222 * v4l2_async_subdev shall be the first member of the driver's async 223 * sub-device struct, i.e. both begin at the same memory address. 224 * 225 * Same as v4l2_async_nf_add_fwnode() but for I2C matched 226 * sub-devices. 227 */ 228 #define v4l2_async_nf_add_i2c(notifier, adapter, address, type) \ 229 ((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \ 230 sizeof(type))) 231 232 /** 233 * v4l2_async_nf_register - registers a subdevice asynchronous notifier 234 * 235 * @v4l2_dev: pointer to &struct v4l2_device 236 * @notifier: pointer to &struct v4l2_async_notifier 237 */ 238 int v4l2_async_nf_register(struct v4l2_device *v4l2_dev, 239 struct v4l2_async_notifier *notifier); 240 241 /** 242 * v4l2_async_subdev_nf_register - registers a subdevice asynchronous 243 * notifier for a sub-device 244 * 245 * @sd: pointer to &struct v4l2_subdev 246 * @notifier: pointer to &struct v4l2_async_notifier 247 */ 248 int v4l2_async_subdev_nf_register(struct v4l2_subdev *sd, 249 struct v4l2_async_notifier *notifier); 250 251 /** 252 * v4l2_async_nf_unregister - unregisters a subdevice 253 * asynchronous notifier 254 * 255 * @notifier: pointer to &struct v4l2_async_notifier 256 */ 257 void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier); 258 259 /** 260 * v4l2_async_nf_cleanup - clean up notifier resources 261 * @notifier: the notifier the resources of which are to be cleaned up 262 * 263 * Release memory resources related to a notifier, including the async 264 * sub-devices allocated for the purposes of the notifier but not the notifier 265 * itself. The user is responsible for calling this function to clean up the 266 * notifier after calling 267 * v4l2_async_nf_add_fwnode_remote(), 268 * v4l2_async_nf_add_fwnode(), 269 * v4l2_async_nf_add_i2c(), 270 * __v4l2_async_nf_add_subdev() or 271 * v4l2_async_nf_parse_fwnode_endpoints(). 272 * 273 * There is no harm from calling v4l2_async_nf_cleanup() in other 274 * cases as long as its memory has been zeroed after it has been 275 * allocated. 276 */ 277 void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier); 278 279 /** 280 * v4l2_async_register_subdev - registers a sub-device to the asynchronous 281 * subdevice framework 282 * 283 * @sd: pointer to &struct v4l2_subdev 284 */ 285 int v4l2_async_register_subdev(struct v4l2_subdev *sd); 286 287 /** 288 * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the 289 * asynchronous sub-device framework and 290 * parse set up common sensor related 291 * devices 292 * 293 * @sd: pointer to struct &v4l2_subdev 294 * 295 * This function is just like v4l2_async_register_subdev() with the exception 296 * that calling it will also parse firmware interfaces for remote references 297 * using v4l2_async_nf_parse_fwnode_sensor() and registers the 298 * async sub-devices. The sub-device is similarly unregistered by calling 299 * v4l2_async_unregister_subdev(). 300 * 301 * While registered, the subdev module is marked as in-use. 302 * 303 * An error is returned if the module is no longer loaded on any attempts 304 * to register it. 305 */ 306 int __must_check 307 v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd); 308 309 /** 310 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous 311 * subdevice framework 312 * 313 * @sd: pointer to &struct v4l2_subdev 314 */ 315 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); 316 #endif 317