xref: /linux/include/media/v4l2-async.h (revision 6fd600d742744dc7ef7fc65ca26daa2b1163158a)
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_TYPE_I2C: Match will check for I2C adapter ID and address
26   * @V4L2_ASYNC_MATCH_TYPE_FWNODE: Match will use firmware node
27   *
28   * This enum is used by the asynchronous connection 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_TYPE_I2C,
33  	V4L2_ASYNC_MATCH_TYPE_FWNODE,
34  };
35  
36  /**
37   * struct v4l2_async_match_desc - async connection match information
38   *
39   * @type:	type of match that will be used
40   * @fwnode:	pointer to &struct fwnode_handle to be matched.
41   *		Used if @match_type is %V4L2_ASYNC_MATCH_TYPE_FWNODE.
42   * @i2c:	embedded struct with I2C parameters to be matched.
43   *		Both @match.i2c.adapter_id and @match.i2c.address
44   *		should be matched.
45   *		Used if @match_type is %V4L2_ASYNC_MATCH_TYPE_I2C.
46   * @i2c.adapter_id:
47   *		I2C adapter ID to be matched.
48   *		Used if @match_type is %V4L2_ASYNC_MATCH_TYPE_I2C.
49   * @i2c.address:
50   *		I2C address to be matched.
51   *		Used if @match_type is %V4L2_ASYNC_MATCH_TYPE_I2C.
52   */
53  struct v4l2_async_match_desc {
54  	enum v4l2_async_match_type type;
55  	union {
56  		struct fwnode_handle *fwnode;
57  		struct {
58  			int adapter_id;
59  			unsigned short address;
60  		} i2c;
61  	};
62  };
63  
64  /**
65   * struct v4l2_async_connection - sub-device connection descriptor, as known to
66   *				  a bridge
67   *
68   * @match:	struct of match type and per-bus type matching data sets
69   * @notifier:	the async notifier the connection is related to
70   * @asc_entry:	used to add struct v4l2_async_connection objects to the
71   *		notifier @waiting_list or @done_list
72   * @asc_subdev_entry:	entry in struct v4l2_async_subdev.asc_list list
73   * @sd:		the related sub-device
74   *
75   * When this struct is used as a member in a driver specific struct, the driver
76   * specific struct shall contain the &struct v4l2_async_connection as its first
77   * member.
78   */
79  struct v4l2_async_connection {
80  	struct v4l2_async_match_desc match;
81  	struct v4l2_async_notifier *notifier;
82  	struct list_head asc_entry;
83  	struct list_head asc_subdev_entry;
84  	struct v4l2_subdev *sd;
85  };
86  
87  /**
88   * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
89   * @bound:	a sub-device has been bound by the given connection
90   * @complete:	All connections have been bound successfully. The complete
91   *		callback is only executed for the root notifier.
92   * @unbind:	a subdevice is leaving
93   * @destroy:	the asc is about to be freed
94   */
95  struct v4l2_async_notifier_operations {
96  	int (*bound)(struct v4l2_async_notifier *notifier,
97  		     struct v4l2_subdev *subdev,
98  		     struct v4l2_async_connection *asc);
99  	int (*complete)(struct v4l2_async_notifier *notifier);
100  	void (*unbind)(struct v4l2_async_notifier *notifier,
101  		       struct v4l2_subdev *subdev,
102  		       struct v4l2_async_connection *asc);
103  	void (*destroy)(struct v4l2_async_connection *asc);
104  };
105  
106  /**
107   * struct v4l2_async_notifier - v4l2_device notifier data
108   *
109   * @ops:	notifier operations
110   * @v4l2_dev:	v4l2_device of the root notifier, NULL otherwise
111   * @sd:		sub-device that registered the notifier, NULL otherwise
112   * @parent:	parent notifier
113   * @waiting_list: list of struct v4l2_async_connection, waiting for their
114   *		  drivers
115   * @done_list:	list of struct v4l2_subdev, already probed
116   * @notifier_entry: member in a global list of notifiers
117   */
118  struct v4l2_async_notifier {
119  	const struct v4l2_async_notifier_operations *ops;
120  	struct v4l2_device *v4l2_dev;
121  	struct v4l2_subdev *sd;
122  	struct v4l2_async_notifier *parent;
123  	struct list_head waiting_list;
124  	struct list_head done_list;
125  	struct list_head notifier_entry;
126  };
127  
128  /**
129   * struct v4l2_async_subdev_endpoint - Entry in sub-device's fwnode list
130   *
131   * @async_subdev_endpoint_entry: An entry in async_subdev_endpoint_list of
132   *				 &struct v4l2_subdev
133   * @endpoint: Endpoint fwnode agains which to match the sub-device
134   */
135  struct v4l2_async_subdev_endpoint {
136  	struct list_head async_subdev_endpoint_entry;
137  	struct fwnode_handle *endpoint;
138  };
139  
140  /**
141   * v4l2_async_debug_init - Initialize debugging tools.
142   *
143   * @debugfs_dir: pointer to the parent debugfs &struct dentry
144   */
145  void v4l2_async_debug_init(struct dentry *debugfs_dir);
146  
147  /**
148   * v4l2_async_nf_init - Initialize a notifier.
149   *
150   * @notifier: pointer to &struct v4l2_async_notifier
151   * @v4l2_dev: pointer to &struct v4l2_device
152   *
153   * This function initializes the notifier @asc_entry. It must be called
154   * before adding a subdevice to a notifier, using one of:
155   * v4l2_async_nf_add_fwnode_remote(),
156   * v4l2_async_nf_add_fwnode() or
157   * v4l2_async_nf_add_i2c().
158   */
159  void v4l2_async_nf_init(struct v4l2_async_notifier *notifier,
160  			struct v4l2_device *v4l2_dev);
161  
162  /**
163   * v4l2_async_subdev_nf_init - Initialize a sub-device notifier.
164   *
165   * @notifier: pointer to &struct v4l2_async_notifier
166   * @sd: pointer to &struct v4l2_subdev
167   *
168   * This function initializes the notifier @asc_list. It must be called
169   * before adding a subdevice to a notifier, using one of:
170   * v4l2_async_nf_add_fwnode_remote(), v4l2_async_nf_add_fwnode() or
171   * v4l2_async_nf_add_i2c().
172   */
173  void v4l2_async_subdev_nf_init(struct v4l2_async_notifier *notifier,
174  			       struct v4l2_subdev *sd);
175  
176  struct v4l2_async_connection *
177  __v4l2_async_nf_add_fwnode(struct v4l2_async_notifier *notifier,
178  			   struct fwnode_handle *fwnode,
179  			   unsigned int asc_struct_size);
180  /**
181   * v4l2_async_nf_add_fwnode - Allocate and add a fwnode async
182   *				subdev to the notifier's master asc_list.
183   *
184   * @notifier: pointer to &struct v4l2_async_notifier
185   * @fwnode: fwnode handle of the sub-device to be matched, pointer to
186   *	    &struct fwnode_handle
187   * @type: Type of the driver's async sub-device or connection struct. The
188   *	  &struct v4l2_async_connection shall be the first member of the
189   *	  driver's async struct, i.e. both begin at the same memory address.
190   *
191   * Allocate a fwnode-matched asc of size asc_struct_size, and add it to the
192   * notifiers @asc_list. The function also gets a reference of the fwnode which
193   * is released later at notifier cleanup time.
194   */
195  #define v4l2_async_nf_add_fwnode(notifier, fwnode, type)		\
196  	((type *)__v4l2_async_nf_add_fwnode(notifier, fwnode, sizeof(type)))
197  
198  struct v4l2_async_connection *
199  __v4l2_async_nf_add_fwnode_remote(struct v4l2_async_notifier *notif,
200  				  struct fwnode_handle *endpoint,
201  				  unsigned int asc_struct_size);
202  /**
203   * v4l2_async_nf_add_fwnode_remote - Allocate and add a fwnode
204   *						  remote async subdev to the
205   *						  notifier's master asc_list.
206   *
207   * @notifier: pointer to &struct v4l2_async_notifier
208   * @ep: local endpoint pointing to the remote connection to be matched,
209   *	pointer to &struct fwnode_handle
210   * @type: Type of the driver's async connection struct. The &struct
211   *	  v4l2_async_connection shall be the first member of the driver's async
212   *	  connection struct, i.e. both begin at the same memory address.
213   *
214   * Gets the remote endpoint of a given local endpoint, set it up for fwnode
215   * matching and adds the async connection to the notifier's @asc_list. The
216   * function also gets a reference of the fwnode which is released later at
217   * notifier cleanup time.
218   *
219   * This is just like v4l2_async_nf_add_fwnode(), but with the
220   * exception that the fwnode refers to a local endpoint, not the remote one.
221   */
222  #define v4l2_async_nf_add_fwnode_remote(notifier, ep, type) \
223  	((type *)__v4l2_async_nf_add_fwnode_remote(notifier, ep, sizeof(type)))
224  
225  struct v4l2_async_connection *
226  __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier,
227  			int adapter_id, unsigned short address,
228  			unsigned int asc_struct_size);
229  /**
230   * v4l2_async_nf_add_i2c - Allocate and add an i2c async
231   *				subdev to the notifier's master asc_list.
232   *
233   * @notifier: pointer to &struct v4l2_async_notifier
234   * @adapter: I2C adapter ID to be matched
235   * @address: I2C address of connection to be matched
236   * @type: Type of the driver's async connection struct. The &struct
237   *	  v4l2_async_connection shall be the first member of the driver's async
238   *	  connection struct, i.e. both begin at the same memory address.
239   *
240   * Same as v4l2_async_nf_add_fwnode() but for I2C matched
241   * connections.
242   */
243  #define v4l2_async_nf_add_i2c(notifier, adapter, address, type) \
244  	((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \
245  					 sizeof(type)))
246  
247  /**
248   * v4l2_async_subdev_endpoint_add - Add an endpoint fwnode to async sub-device
249   *				    matching list
250   *
251   * @sd: the sub-device
252   * @fwnode: the endpoint fwnode to match
253   *
254   * Add a fwnode to the async sub-device's matching list. This allows registering
255   * multiple async sub-devices from a single device.
256   *
257   * Note that calling v4l2_subdev_cleanup() as part of the sub-device's cleanup
258   * if endpoints have been added to the sub-device's fwnode matching list.
259   *
260   * Returns an error on failure, 0 on success.
261   */
262  int v4l2_async_subdev_endpoint_add(struct v4l2_subdev *sd,
263  				   struct fwnode_handle *fwnode);
264  
265  /**
266   * v4l2_async_connection_unique - return a unique &struct v4l2_async_connection
267   *				  for a sub-device
268   * @sd: the sub-device
269   *
270   * Return an async connection for a sub-device, when there is a single
271   * one only.
272   */
273  struct v4l2_async_connection *
274  v4l2_async_connection_unique(struct v4l2_subdev *sd);
275  
276  /**
277   * v4l2_async_nf_register - registers a subdevice asynchronous notifier
278   *
279   * @notifier: pointer to &struct v4l2_async_notifier
280   */
281  int v4l2_async_nf_register(struct v4l2_async_notifier *notifier);
282  
283  /**
284   * v4l2_async_nf_unregister - unregisters a subdevice
285   *	asynchronous notifier
286   *
287   * @notifier: pointer to &struct v4l2_async_notifier
288   */
289  void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier);
290  
291  /**
292   * v4l2_async_nf_cleanup - clean up notifier resources
293   * @notifier: the notifier the resources of which are to be cleaned up
294   *
295   * Release memory resources related to a notifier, including the async
296   * connections allocated for the purposes of the notifier but not the notifier
297   * itself. The user is responsible for calling this function to clean up the
298   * notifier after calling v4l2_async_nf_add_fwnode_remote(),
299   * v4l2_async_nf_add_fwnode() or v4l2_async_nf_add_i2c().
300   *
301   * There is no harm from calling v4l2_async_nf_cleanup() in other
302   * cases as long as its memory has been zeroed after it has been
303   * allocated.
304   */
305  void v4l2_async_nf_cleanup(struct v4l2_async_notifier *notifier);
306  
307  /**
308   * v4l2_async_register_subdev - registers a sub-device to the asynchronous
309   *	subdevice framework
310   *
311   * @sd: pointer to &struct v4l2_subdev
312   */
313  #define v4l2_async_register_subdev(sd) \
314  	__v4l2_async_register_subdev(sd, THIS_MODULE)
315  int __v4l2_async_register_subdev(struct v4l2_subdev *sd, struct module *module);
316  
317  /**
318   * v4l2_async_register_subdev_sensor - registers a sensor sub-device to the
319   *				       asynchronous sub-device framework and
320   *				       parse set up common sensor related
321   *				       devices
322   *
323   * @sd: pointer to struct &v4l2_subdev
324   *
325   * This function is just like v4l2_async_register_subdev() with the exception
326   * that calling it will also parse firmware interfaces for remote references
327   * using v4l2_async_nf_parse_fwnode_sensor() and registers the
328   * async sub-devices. The sub-device is similarly unregistered by calling
329   * v4l2_async_unregister_subdev().
330   *
331   * While registered, the subdev module is marked as in-use.
332   *
333   * An error is returned if the module is no longer loaded on any attempts
334   * to register it.
335   */
336  int __must_check
337  v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd);
338  
339  /**
340   * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
341   *	subdevice framework
342   *
343   * @sd: pointer to &struct v4l2_subdev
344   */
345  void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
346  #endif
347