Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/media/v4l2-async.h
26281 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* V4L2 asynchronous subdevice registration API
4
*
5
* Copyright (C) 2012-2013, Guennadi Liakhovetski <[email protected]>
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
348