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 * Call this function before registering a notifier to link the provided @asd to 143 * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as 144 * it will be freed by the framework when the notifier is destroyed. 145 */ 146 int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, 147 struct v4l2_async_subdev *asd); 148 149 /** 150 * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async 151 * subdev to the notifier's master asd_list. 152 * 153 * @notifier: pointer to &struct v4l2_async_notifier 154 * @fwnode: fwnode handle of the sub-device to be matched 155 * @asd_struct_size: size of the driver's async sub-device struct, including 156 * sizeof(struct v4l2_async_subdev). The &struct 157 * v4l2_async_subdev shall be the first member of 158 * the driver's async sub-device struct, i.e. both 159 * begin at the same memory address. 160 * 161 * Allocate a fwnode-matched asd of size asd_struct_size, and add it to the 162 * notifiers @asd_list. The function also gets a reference of the fwnode which 163 * is released later at notifier cleanup time. 164 */ 165 struct v4l2_async_subdev * 166 v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, 167 struct fwnode_handle *fwnode, 168 unsigned int asd_struct_size); 169 170 /** 171 * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode 172 * remote async subdev to the 173 * notifier's master asd_list. 174 * 175 * @notif: pointer to &struct v4l2_async_notifier 176 * @endpoint: local endpoint pointing to the remote sub-device to be matched 177 * @asd_struct_size: size of the driver's async sub-device struct, including 178 * sizeof(struct v4l2_async_subdev). The &struct 179 * v4l2_async_subdev shall be the first member of 180 * the driver's async sub-device struct, i.e. both 181 * begin at the same memory address. 182 * 183 * Gets the remote endpoint of a given local endpoint, set it up for fwnode 184 * matching and adds the async sub-device to the notifier's @asd_list. The 185 * function also gets a reference of the fwnode which is released later at 186 * notifier cleanup time. 187 * 188 * This is just like @v4l2_async_notifier_add_fwnode_subdev, but with the 189 * exception that the fwnode refers to a local endpoint, not the remote one. 190 */ 191 struct v4l2_async_subdev * 192 v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, 193 struct fwnode_handle *endpoint, 194 unsigned int asd_struct_size); 195 196 /** 197 * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async 198 * subdev to the notifier's master asd_list. 199 * 200 * @notifier: pointer to &struct v4l2_async_notifier 201 * @adapter_id: I2C adapter ID to be matched 202 * @address: I2C address of sub-device to be matched 203 * @asd_struct_size: size of the driver's async sub-device struct, including 204 * sizeof(struct v4l2_async_subdev). The &struct 205 * v4l2_async_subdev shall be the first member of 206 * the driver's async sub-device struct, i.e. both 207 * begin at the same memory address. 208 * 209 * Same as above but for I2C matched sub-devices. 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 /** 217 * v4l2_async_notifier_register - registers a subdevice asynchronous notifier 218 * 219 * @v4l2_dev: pointer to &struct v4l2_device 220 * @notifier: pointer to &struct v4l2_async_notifier 221 */ 222 int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, 223 struct v4l2_async_notifier *notifier); 224 225 /** 226 * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous 227 * notifier for a sub-device 228 * 229 * @sd: pointer to &struct v4l2_subdev 230 * @notifier: pointer to &struct v4l2_async_notifier 231 */ 232 int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, 233 struct v4l2_async_notifier *notifier); 234 235 /** 236 * v4l2_async_notifier_unregister - unregisters a subdevice 237 * asynchronous notifier 238 * 239 * @notifier: pointer to &struct v4l2_async_notifier 240 */ 241 void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); 242 243 /** 244 * v4l2_async_notifier_cleanup - clean up notifier resources 245 * @notifier: the notifier the resources of which are to be cleaned up 246 * 247 * Release memory resources related to a notifier, including the async 248 * sub-devices allocated for the purposes of the notifier but not the notifier 249 * itself. The user is responsible for calling this function to clean up the 250 * notifier after calling 251 * @v4l2_async_notifier_add_subdev, 252 * @v4l2_async_notifier_parse_fwnode_endpoints or 253 * @v4l2_fwnode_reference_parse_sensor_common. 254 * 255 * There is no harm from calling v4l2_async_notifier_cleanup in other 256 * cases as long as its memory has been zeroed after it has been 257 * allocated. 258 */ 259 void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier); 260 261 /** 262 * v4l2_async_register_subdev - registers a sub-device to the asynchronous 263 * subdevice framework 264 * 265 * @sd: pointer to &struct v4l2_subdev 266 */ 267 int v4l2_async_register_subdev(struct v4l2_subdev *sd); 268 269 /** 270 * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to 271 * the asynchronous sub-device 272 * framework and parse set up common 273 * sensor related devices 274 * 275 * @sd: pointer to struct &v4l2_subdev 276 * 277 * This function is just like v4l2_async_register_subdev() with the exception 278 * that calling it will also parse firmware interfaces for remote references 279 * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the 280 * async sub-devices. The sub-device is similarly unregistered by calling 281 * v4l2_async_unregister_subdev(). 282 * 283 * While registered, the subdev module is marked as in-use. 284 * 285 * An error is returned if the module is no longer loaded on any attempts 286 * to register it. 287 */ 288 int __must_check 289 v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd); 290 291 /** 292 * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous 293 * subdevice framework 294 * 295 * @sd: pointer to &struct v4l2_subdev 296 */ 297 void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); 298 #endif 299