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_notifier_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_notifier_add_fwnode_remote_subdev, 133 * @v4l2_async_notifier_add_fwnode_subdev, 134 * @v4l2_async_notifier_add_i2c_subdev, 135 * @__v4l2_async_notifier_add_subdev or 136 * @v4l2_async_notifier_parse_fwnode_endpoints. 137 */ 138 void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); 139 140 /** 141 * __v4l2_async_notifier_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_notifier_add_fwnode_subdev, 149 * @v4l2_async_notifier_add_fwnode_remote_subdev or 150 * @v4l2_async_notifier_add_i2c_subdev. 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_notifier_add_subdev(struct v4l2_async_notifier *notifier, 157 struct v4l2_async_subdev *asd); 158 159 struct v4l2_async_subdev * 160 __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, 161 struct fwnode_handle *fwnode, 162 unsigned int asd_struct_size); 163 /** 164 * v4l2_async_notifier_add_fwnode_subdev - 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_notifier_add_fwnode_subdev(notifier, fwnode, type) \ 179 ((type *)__v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, \ 180 sizeof(type))) 181 182 struct v4l2_async_subdev * 183 __v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, 184 struct fwnode_handle *endpoint, 185 unsigned int asd_struct_size); 186 /** 187 * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode 188 * remote async subdev to the 189 * notifier's master asd_list. 190 * 191 * @notifier: pointer to &struct v4l2_async_notifier 192 * @ep: local endpoint pointing to the remote sub-device to be matched, 193 * pointer to &struct fwnode_handle 194 * @type: Type of the driver's async sub-device struct. The &struct 195 * v4l2_async_subdev shall be the first member of the driver's async 196 * sub-device struct, i.e. both begin at the same memory address. 197 * 198 * Gets the remote endpoint of a given local endpoint, set it up for fwnode 199 * matching and adds the async sub-device to the notifier's @asd_list. The 200 * function also gets a reference of the fwnode which is released later at 201 * notifier cleanup time. 202 * 203 * This is just like @v4l2_async_notifier_add_fwnode_subdev, but with the 204 * exception that the fwnode refers to a local endpoint, not the remote one. 205 */ 206 #define v4l2_async_notifier_add_fwnode_remote_subdev(notifier, ep, type) \ 207 ((type *) \ 208 __v4l2_async_notifier_add_fwnode_remote_subdev(notifier, ep, \ 209 sizeof(type))) 210 211 struct v4l2_async_subdev * 212 __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, 213 int adapter_id, unsigned short address, 214 unsigned int asd_struct_size); 215 /** 216 * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async 217 * subdev to the notifier's master asd_list. 218 * 219 * @notifier: pointer to &struct v4l2_async_notifier 220 * @adapter: I2C adapter ID to be matched 221 * @address: I2C address of sub-device to be matched 222 * @type: Type of the driver's async sub-device struct. The &struct 223 * v4l2_async_subdev shall be the first member of the driver's async 224 * sub-device struct, i.e. both begin at the same memory address. 225 * 226 * Same as v4l2_async_notifier_add_fwnode_subdev() but for I2C matched 227 * sub-devices. 228 */ 229 #define v4l2_async_notifier_add_i2c_subdev(notifier, adapter, address, type) \ 230 ((type *)__v4l2_async_notifier_add_i2c_subdev(notifier, adapter, \ 231 address, sizeof(type))) 232 233 /** 234 * v4l2_async_notifier_register - registers a subdevice asynchronous notifier 235 * 236 * @v4l2_dev: pointer to &struct v4l2_device 237 * @notifier: pointer to &struct v4l2_async_notifier 238 */ 239 int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, 240 struct v4l2_async_notifier *notifier); 241 242 /** 243 * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous 244 * notifier for a sub-device 245 * 246 * @sd: pointer to &struct v4l2_subdev 247 * @notifier: pointer to &struct v4l2_async_notifier 248 */ 249 int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, 250 struct v4l2_async_notifier *notifier); 251 252 /** 253 * v4l2_async_notifier_unregister - unregisters a subdevice 254 * asynchronous notifier 255 * 256 * @notifier: pointer to &struct v4l2_async_notifier 257 */ 258 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); 259 260 /** 261 * v4l2_async_notifier_cleanup - clean up notifier resources 262 * @notifier: the notifier the resources of which are to be cleaned up 263 * 264 * Release memory resources related to a notifier, including the async 265 * sub-devices allocated for the purposes of the notifier but not the notifier 266 * itself. The user is responsible for calling this function to clean up the 267 * notifier after calling 268 * @v4l2_async_notifier_add_fwnode_remote_subdev, 269 * @v4l2_async_notifier_add_fwnode_subdev, 270 * @v4l2_async_notifier_add_i2c_subdev, 271 * @__v4l2_async_notifier_add_subdev or 272 * @v4l2_async_notifier_parse_fwnode_endpoints. 273 * 274 * There is no harm from calling v4l2_async_notifier_cleanup in other 275 * cases as long as its memory has been zeroed after it has been 276 * allocated. 277 */ 278 void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier); 279 280 /** 281 * v4l2_async_register_subdev - registers a sub-device to the asynchronous 282 * subdevice framework 283 * 284 * @sd: pointer to &struct v4l2_subdev 285 */ 286 int v4l2_async_register_subdev(struct v4l2_subdev *sd); 287 288 /** 289 * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the 290 * asynchronous sub-device framework and 291 * parse set up common sensor related 292 * devices 293 * 294 * @sd: pointer to struct &v4l2_subdev 295 * 296 * This function is just like v4l2_async_register_subdev() with the exception 297 * that calling it will also parse firmware interfaces for remote references 298 * using v4l2_async_notifier_parse_fwnode_sensor() and registers the 299 * async sub-devices. The sub-device is similarly unregistered by calling 300 * v4l2_async_unregister_subdev(). 301 * 302 * While registered, the subdev module is marked as in-use. 303 * 304 * An error is returned if the module is no longer loaded on any attempts 305 * to register it. 306 */ 307 int __must_check 308 v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd); 309 310 /** 311 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous 312 * subdevice framework 313 * 314 * @sd: pointer to &struct v4l2_subdev 315 */ 316 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); 317 #endif 318