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 the first call to @v4l2_async_notifier_add_subdev. 132 */ 133 void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); 134 135 /** 136 * __v4l2_async_notifier_add_subdev - Add an async subdev to the 137 * notifier's master asd list. 138 * 139 * @notifier: pointer to &struct v4l2_async_notifier 140 * @asd: pointer to &struct v4l2_async_subdev 141 * 142 * \warning: Drivers should avoid using this function and instead use one of: 143 * @v4l2_async_notifier_add_fwnode_subdev, 144 * @v4l2_async_notifier_add_fwnode_remote_subdev or 145 * @v4l2_async_notifier_add_i2c_subdev. 146 * 147 * Call this function before registering a notifier to link the provided @asd to 148 * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as 149 * it will be freed by the framework when the notifier is destroyed. 150 */ 151 int __v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, 152 struct v4l2_async_subdev *asd); 153 154 /** 155 * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async 156 * subdev to the notifier's master asd_list. 157 * 158 * @notifier: pointer to &struct v4l2_async_notifier 159 * @fwnode: fwnode handle of the sub-device to be matched 160 * @asd_struct_size: size of the driver's async sub-device struct, including 161 * sizeof(struct v4l2_async_subdev). The &struct 162 * v4l2_async_subdev shall be the first member of 163 * the driver's async sub-device struct, i.e. both 164 * begin at the same memory address. 165 * 166 * Allocate a fwnode-matched asd of size asd_struct_size, and add it to the 167 * notifiers @asd_list. The function also gets a reference of the fwnode which 168 * is released later at notifier cleanup time. 169 */ 170 struct v4l2_async_subdev * 171 __v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, 172 struct fwnode_handle *fwnode, 173 unsigned int asd_struct_size); 174 #define v4l2_async_notifier_add_fwnode_subdev(__notifier, __fwnode, __type) \ 175 ((__type *)__v4l2_async_notifier_add_fwnode_subdev(__notifier, __fwnode, \ 176 sizeof(__type))) 177 178 /** 179 * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode 180 * remote async subdev to the 181 * notifier's master asd_list. 182 * 183 * @notif: pointer to &struct v4l2_async_notifier 184 * @endpoint: local endpoint pointing to the remote sub-device to be matched 185 * @asd_struct_size: size of the driver's async sub-device struct, including 186 * sizeof(struct v4l2_async_subdev). The &struct 187 * v4l2_async_subdev shall be the first member of 188 * the driver's async sub-device struct, i.e. both 189 * begin at the same memory address. 190 * 191 * Gets the remote endpoint of a given local endpoint, set it up for fwnode 192 * matching and adds the async sub-device to the notifier's @asd_list. The 193 * function also gets a reference of the fwnode which is released later at 194 * notifier cleanup time. 195 * 196 * This is just like @v4l2_async_notifier_add_fwnode_subdev, but with the 197 * exception that the fwnode refers to a local endpoint, not the remote one. 198 */ 199 struct v4l2_async_subdev * 200 __v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, 201 struct fwnode_handle *endpoint, 202 unsigned int asd_struct_size); 203 #define v4l2_async_notifier_add_fwnode_remote_subdev(__notifier, __ep, __type) \ 204 ((__type *)__v4l2_async_notifier_add_fwnode_remote_subdev(__notifier, __ep, \ 205 sizeof(__type))) 206 207 /** 208 * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async 209 * subdev to the notifier's master asd_list. 210 * 211 * @notifier: pointer to &struct v4l2_async_notifier 212 * @adapter_id: I2C adapter ID to be matched 213 * @address: I2C address of sub-device to be matched 214 * @asd_struct_size: size of the driver's async sub-device struct, including 215 * sizeof(struct v4l2_async_subdev). The &struct 216 * v4l2_async_subdev shall be the first member of 217 * the driver's async sub-device struct, i.e. both 218 * begin at the same memory address. 219 * 220 * Same as above but for I2C matched sub-devices. 221 */ 222 struct v4l2_async_subdev * 223 __v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier, 224 int adapter_id, unsigned short address, 225 unsigned int asd_struct_size); 226 #define v4l2_async_notifier_add_i2c_subdev(__notifier, __adap, __addr, __type) \ 227 ((__type *)__v4l2_async_notifier_add_i2c_subdev(__notifier, __adap, __addr, \ 228 sizeof(__type))) 229 230 /** 231 * v4l2_async_notifier_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_notifier_register(struct v4l2_device *v4l2_dev, 237 struct v4l2_async_notifier *notifier); 238 239 /** 240 * v4l2_async_subdev_notifier_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_notifier_register(struct v4l2_subdev *sd, 247 struct v4l2_async_notifier *notifier); 248 249 /** 250 * v4l2_async_notifier_unregister - unregisters a subdevice 251 * asynchronous notifier 252 * 253 * @notifier: pointer to &struct v4l2_async_notifier 254 */ 255 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); 256 257 /** 258 * v4l2_async_notifier_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_notifier_add_subdev, 266 * @v4l2_async_notifier_parse_fwnode_endpoints or 267 * @v4l2_fwnode_reference_parse_sensor_common. 268 * 269 * There is no harm from calling v4l2_async_notifier_cleanup in other 270 * cases as long as its memory has been zeroed after it has been 271 * allocated. 272 */ 273 void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier); 274 275 /** 276 * v4l2_async_register_subdev - registers a sub-device to the asynchronous 277 * subdevice framework 278 * 279 * @sd: pointer to &struct v4l2_subdev 280 */ 281 int v4l2_async_register_subdev(struct v4l2_subdev *sd); 282 283 /** 284 * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to 285 * the asynchronous sub-device 286 * framework and parse set up common 287 * sensor related devices 288 * 289 * @sd: pointer to struct &v4l2_subdev 290 * 291 * This function is just like v4l2_async_register_subdev() with the exception 292 * that calling it will also parse firmware interfaces for remote references 293 * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the 294 * async sub-devices. The sub-device is similarly unregistered by calling 295 * v4l2_async_unregister_subdev(). 296 * 297 * While registered, the subdev module is marked as in-use. 298 * 299 * An error is returned if the module is no longer loaded on any attempts 300 * to register it. 301 */ 302 int __must_check 303 v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd); 304 305 /** 306 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous 307 * subdevice framework 308 * 309 * @sd: pointer to &struct v4l2_subdev 310 */ 311 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); 312 #endif 313