]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/media/v4l2-core/v4l2-fwnode.c
media: v4l: fwnode: Support default CSI-2 lane mapping for drivers
[linux.git] / drivers / media / v4l2-core / v4l2-fwnode.c
1 /*
2  * V4L2 fwnode binding parsing library
3  *
4  * The origins of the V4L2 fwnode library are in V4L2 OF library that
5  * formerly was located in v4l2-of.c.
6  *
7  * Copyright (c) 2016 Intel Corporation.
8  * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
9  *
10  * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
11  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
12  *
13  * Copyright (C) 2012 Renesas Electronics Corp.
14  * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of version 2 of the GNU General Public License as
18  * published by the Free Software Foundation.
19  */
20 #include <linux/acpi.h>
21 #include <linux/kernel.h>
22 #include <linux/mm.h>
23 #include <linux/module.h>
24 #include <linux/of.h>
25 #include <linux/property.h>
26 #include <linux/slab.h>
27 #include <linux/string.h>
28 #include <linux/types.h>
29
30 #include <media/v4l2-async.h>
31 #include <media/v4l2-fwnode.h>
32 #include <media/v4l2-subdev.h>
33
34 enum v4l2_fwnode_bus_type {
35         V4L2_FWNODE_BUS_TYPE_GUESS = 0,
36         V4L2_FWNODE_BUS_TYPE_CSI2_CPHY,
37         V4L2_FWNODE_BUS_TYPE_CSI1,
38         V4L2_FWNODE_BUS_TYPE_CCP2,
39         V4L2_FWNODE_BUS_TYPE_CSI2_DPHY,
40         V4L2_FWNODE_BUS_TYPE_PARALLEL,
41         V4L2_FWNODE_BUS_TYPE_BT656,
42         NR_OF_V4L2_FWNODE_BUS_TYPE,
43 };
44
45 static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
46                                                struct v4l2_fwnode_endpoint *vep,
47                                                enum v4l2_fwnode_bus_type bus_type)
48 {
49         struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2;
50         bool have_clk_lane = false, have_data_lanes = false,
51                 have_lane_polarities = false;
52         unsigned int flags = 0, lanes_used = 0;
53         u32 array[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
54         u32 clock_lane = 0;
55         unsigned int num_data_lanes = 0;
56         bool use_default_lane_mapping = false;
57         unsigned int i;
58         u32 v;
59         int rval;
60
61         if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY) {
62                 use_default_lane_mapping = true;
63
64                 num_data_lanes = min_t(u32, bus->num_data_lanes,
65                                        V4L2_FWNODE_CSI2_MAX_DATA_LANES);
66
67                 clock_lane = bus->clock_lane;
68                 if (clock_lane)
69                         use_default_lane_mapping = false;
70
71                 for (i = 0; i < num_data_lanes; i++) {
72                         array[i] = bus->data_lanes[i];
73                         if (array[i])
74                                 use_default_lane_mapping = false;
75                 }
76
77                 if (use_default_lane_mapping)
78                         pr_debug("using default lane mapping\n");
79         }
80
81         rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
82         if (rval > 0) {
83                 num_data_lanes =
84                         min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval);
85
86                 fwnode_property_read_u32_array(fwnode, "data-lanes", array,
87                                                num_data_lanes);
88
89                 have_data_lanes = true;
90         }
91
92         for (i = 0; i < num_data_lanes; i++) {
93                 if (lanes_used & BIT(array[i])) {
94                         if (have_data_lanes || !use_default_lane_mapping)
95                                 pr_warn("duplicated lane %u in data-lanes, using defaults\n",
96                                         array[i]);
97                         use_default_lane_mapping = true;
98                 }
99                 lanes_used |= BIT(array[i]);
100
101                 if (have_data_lanes)
102                         pr_debug("lane %u position %u\n", i, array[i]);
103         }
104
105         rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
106                                               0);
107         if (rval > 0) {
108                 if (rval != 1 + num_data_lanes /* clock+data */) {
109                         pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
110                                 1 + num_data_lanes, rval);
111                         return -EINVAL;
112                 }
113
114                 have_lane_polarities = true;
115         }
116
117         if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
118                 clock_lane = v;
119                 pr_debug("clock lane position %u\n", v);
120                 have_clk_lane = true;
121         }
122
123         if (lanes_used & BIT(clock_lane)) {
124                 if (have_clk_lane || !use_default_lane_mapping)
125                         pr_warn("duplicated lane %u in clock-lanes, using defaults\n",
126                         v);
127                 use_default_lane_mapping = true;
128         }
129
130         if (fwnode_property_present(fwnode, "clock-noncontinuous")) {
131                 flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
132                 pr_debug("non-continuous clock\n");
133         } else {
134                 flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
135         }
136
137         if (bus_type == V4L2_FWNODE_BUS_TYPE_CSI2_DPHY || lanes_used ||
138             have_clk_lane || (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) {
139                 bus->flags = flags;
140                 vep->bus_type = V4L2_MBUS_CSI2_DPHY;
141                 bus->num_data_lanes = num_data_lanes;
142
143                 if (use_default_lane_mapping) {
144                         bus->clock_lane = 0;
145                         for (i = 0; i < num_data_lanes; i++)
146                                 bus->data_lanes[i] = 1 + i;
147                 } else {
148                         bus->clock_lane = clock_lane;
149                         for (i = 0; i < num_data_lanes; i++)
150                                 bus->data_lanes[i] = array[i];
151                 }
152
153                 if (have_lane_polarities) {
154                         fwnode_property_read_u32_array(fwnode,
155                                                        "lane-polarities", array,
156                                                        1 + num_data_lanes);
157
158                         for (i = 0; i < 1 + num_data_lanes; i++) {
159                                 bus->lane_polarities[i] = array[i];
160                                 pr_debug("lane %u polarity %sinverted",
161                                          i, array[i] ? "" : "not ");
162                         }
163                 } else {
164                         pr_debug("no lane polarities defined, assuming not inverted\n");
165                 }
166         }
167
168         return 0;
169 }
170
171 #define PARALLEL_MBUS_FLAGS (V4L2_MBUS_HSYNC_ACTIVE_HIGH |      \
172                              V4L2_MBUS_HSYNC_ACTIVE_LOW |       \
173                              V4L2_MBUS_VSYNC_ACTIVE_HIGH |      \
174                              V4L2_MBUS_VSYNC_ACTIVE_LOW |       \
175                              V4L2_MBUS_FIELD_EVEN_HIGH |        \
176                              V4L2_MBUS_FIELD_EVEN_LOW)
177
178 static void v4l2_fwnode_endpoint_parse_parallel_bus(
179         struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep,
180         enum v4l2_fwnode_bus_type bus_type)
181 {
182         struct v4l2_fwnode_bus_parallel *bus = &vep->bus.parallel;
183         unsigned int flags = 0;
184         u32 v;
185
186         if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) {
187                 flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
188                         V4L2_MBUS_HSYNC_ACTIVE_LOW;
189                 pr_debug("hsync-active %s\n", v ? "high" : "low");
190         }
191
192         if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) {
193                 flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
194                         V4L2_MBUS_VSYNC_ACTIVE_LOW;
195                 pr_debug("vsync-active %s\n", v ? "high" : "low");
196         }
197
198         if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) {
199                 flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
200                         V4L2_MBUS_FIELD_EVEN_LOW;
201                 pr_debug("field-even-active %s\n", v ? "high" : "low");
202         }
203
204         if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) {
205                 flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
206                         V4L2_MBUS_PCLK_SAMPLE_FALLING;
207                 pr_debug("pclk-sample %s\n", v ? "high" : "low");
208         }
209
210         if (!fwnode_property_read_u32(fwnode, "data-active", &v)) {
211                 flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
212                         V4L2_MBUS_DATA_ACTIVE_LOW;
213                 pr_debug("data-active %s\n", v ? "high" : "low");
214         }
215
216         if (fwnode_property_present(fwnode, "slave-mode")) {
217                 pr_debug("slave mode\n");
218                 flags |= V4L2_MBUS_SLAVE;
219         } else {
220                 flags |= V4L2_MBUS_MASTER;
221         }
222
223         if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) {
224                 bus->bus_width = v;
225                 pr_debug("bus-width %u\n", v);
226         }
227
228         if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) {
229                 bus->data_shift = v;
230                 pr_debug("data-shift %u\n", v);
231         }
232
233         if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) {
234                 flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
235                         V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
236                 pr_debug("sync-on-green-active %s\n", v ? "high" : "low");
237         }
238
239         if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) {
240                 flags |= v ? V4L2_MBUS_DATA_ENABLE_HIGH :
241                         V4L2_MBUS_DATA_ENABLE_LOW;
242                 pr_debug("data-enable-active %s\n", v ? "high" : "low");
243         }
244
245         switch (bus_type) {
246         default:
247                 bus->flags = flags;
248                 if (flags & PARALLEL_MBUS_FLAGS)
249                         vep->bus_type = V4L2_MBUS_PARALLEL;
250                 else
251                         vep->bus_type = V4L2_MBUS_BT656;
252                 break;
253         case V4L2_FWNODE_BUS_TYPE_PARALLEL:
254                 vep->bus_type = V4L2_MBUS_PARALLEL;
255                 bus->flags = flags;
256                 break;
257         case V4L2_FWNODE_BUS_TYPE_BT656:
258                 vep->bus_type = V4L2_MBUS_BT656;
259                 bus->flags = flags & ~PARALLEL_MBUS_FLAGS;
260                 break;
261         }
262 }
263
264 static void
265 v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode,
266                                     struct v4l2_fwnode_endpoint *vep,
267                                     enum v4l2_fwnode_bus_type bus_type)
268 {
269         struct v4l2_fwnode_bus_mipi_csi1 *bus = &vep->bus.mipi_csi1;
270         u32 v;
271
272         if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) {
273                 bus->clock_inv = v;
274                 pr_debug("clock-inv %u\n", v);
275         }
276
277         if (!fwnode_property_read_u32(fwnode, "strobe", &v)) {
278                 bus->strobe = v;
279                 pr_debug("strobe %u\n", v);
280         }
281
282         if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) {
283                 bus->data_lane = v;
284                 pr_debug("data-lanes %u\n", v);
285         }
286
287         if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) {
288                 bus->clock_lane = v;
289                 pr_debug("clock-lanes %u\n", v);
290         }
291
292         if (bus_type == V4L2_FWNODE_BUS_TYPE_CCP2)
293                 vep->bus_type = V4L2_MBUS_CCP2;
294         else
295                 vep->bus_type = V4L2_MBUS_CSI1;
296 }
297
298 static int __v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
299                                         struct v4l2_fwnode_endpoint *vep)
300 {
301         u32 bus_type = 0;
302         int rval;
303
304         pr_debug("===== begin V4L2 endpoint properties\n");
305
306         fwnode_graph_parse_endpoint(fwnode, &vep->base);
307
308         /* Zero fields from bus_type to until the end */
309         memset(&vep->bus_type, 0, sizeof(*vep) -
310                offsetof(typeof(*vep), bus_type));
311
312         fwnode_property_read_u32(fwnode, "bus-type", &bus_type);
313
314         switch (bus_type) {
315         case V4L2_FWNODE_BUS_TYPE_GUESS:
316                 rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
317                                                            bus_type);
318                 if (rval)
319                         return rval;
320
321                 if (vep->bus_type == V4L2_MBUS_UNKNOWN)
322                         v4l2_fwnode_endpoint_parse_parallel_bus(
323                                 fwnode, vep, V4L2_MBUS_UNKNOWN);
324
325                 break;
326         case V4L2_FWNODE_BUS_TYPE_CCP2:
327         case V4L2_FWNODE_BUS_TYPE_CSI1:
328                 v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, bus_type);
329
330                 break;
331         case V4L2_FWNODE_BUS_TYPE_CSI2_DPHY:
332                 vep->bus_type = V4L2_MBUS_CSI2_DPHY;
333                 rval = v4l2_fwnode_endpoint_parse_csi2_bus(fwnode, vep,
334                                                            bus_type);
335                 if (rval)
336                         return rval;
337
338                 break;
339         case V4L2_FWNODE_BUS_TYPE_PARALLEL:
340         case V4L2_FWNODE_BUS_TYPE_BT656:
341                 v4l2_fwnode_endpoint_parse_parallel_bus(fwnode, vep, bus_type);
342
343                 break;
344         default:
345                 pr_warn("unsupported bus type %u\n", bus_type);
346                 return -EINVAL;
347         }
348
349         return 0;
350 }
351
352 int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
353                                struct v4l2_fwnode_endpoint *vep)
354 {
355         int ret;
356
357         ret = __v4l2_fwnode_endpoint_parse(fwnode, vep);
358
359         pr_debug("===== end V4L2 endpoint properties\n");
360
361         return ret;
362 }
363 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse);
364
365 void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
366 {
367         if (IS_ERR_OR_NULL(vep))
368                 return;
369
370         kfree(vep->link_frequencies);
371 }
372 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);
373
374 int v4l2_fwnode_endpoint_alloc_parse(
375         struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep)
376 {
377         int rval;
378
379         rval = __v4l2_fwnode_endpoint_parse(fwnode, vep);
380         if (rval < 0)
381                 return rval;
382
383         rval = fwnode_property_read_u64_array(fwnode, "link-frequencies",
384                                               NULL, 0);
385         if (rval > 0) {
386                 unsigned int i;
387
388                 vep->link_frequencies =
389                         kmalloc_array(rval, sizeof(*vep->link_frequencies),
390                                       GFP_KERNEL);
391                 if (!vep->link_frequencies)
392                         return -ENOMEM;
393
394                 vep->nr_of_link_frequencies = rval;
395
396                 rval = fwnode_property_read_u64_array(
397                         fwnode, "link-frequencies", vep->link_frequencies,
398                         vep->nr_of_link_frequencies);
399                 if (rval < 0) {
400                         v4l2_fwnode_endpoint_free(vep);
401                         return rval;
402                 }
403
404                 for (i = 0; i < vep->nr_of_link_frequencies; i++)
405                         pr_info("link-frequencies %u value %llu\n", i,
406                                 vep->link_frequencies[i]);
407         }
408
409         pr_debug("===== end V4L2 endpoint properties\n");
410
411         return 0;
412 }
413 EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
414
415 int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,
416                            struct v4l2_fwnode_link *link)
417 {
418         const char *port_prop = is_of_node(__fwnode) ? "reg" : "port";
419         struct fwnode_handle *fwnode;
420
421         memset(link, 0, sizeof(*link));
422
423         fwnode = fwnode_get_parent(__fwnode);
424         fwnode_property_read_u32(fwnode, port_prop, &link->local_port);
425         fwnode = fwnode_get_next_parent(fwnode);
426         if (is_of_node(fwnode) &&
427             of_node_cmp(to_of_node(fwnode)->name, "ports") == 0)
428                 fwnode = fwnode_get_next_parent(fwnode);
429         link->local_node = fwnode;
430
431         fwnode = fwnode_graph_get_remote_endpoint(__fwnode);
432         if (!fwnode) {
433                 fwnode_handle_put(fwnode);
434                 return -ENOLINK;
435         }
436
437         fwnode = fwnode_get_parent(fwnode);
438         fwnode_property_read_u32(fwnode, port_prop, &link->remote_port);
439         fwnode = fwnode_get_next_parent(fwnode);
440         if (is_of_node(fwnode) &&
441             of_node_cmp(to_of_node(fwnode)->name, "ports") == 0)
442                 fwnode = fwnode_get_next_parent(fwnode);
443         link->remote_node = fwnode;
444
445         return 0;
446 }
447 EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link);
448
449 void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
450 {
451         fwnode_handle_put(link->local_node);
452         fwnode_handle_put(link->remote_node);
453 }
454 EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
455
456 static int v4l2_async_notifier_fwnode_parse_endpoint(
457         struct device *dev, struct v4l2_async_notifier *notifier,
458         struct fwnode_handle *endpoint, unsigned int asd_struct_size,
459         int (*parse_endpoint)(struct device *dev,
460                             struct v4l2_fwnode_endpoint *vep,
461                             struct v4l2_async_subdev *asd))
462 {
463         struct v4l2_fwnode_endpoint vep = { .bus_type = 0 };
464         struct v4l2_async_subdev *asd;
465         int ret;
466
467         asd = kzalloc(asd_struct_size, GFP_KERNEL);
468         if (!asd)
469                 return -ENOMEM;
470
471         asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
472         asd->match.fwnode =
473                 fwnode_graph_get_remote_port_parent(endpoint);
474         if (!asd->match.fwnode) {
475                 dev_warn(dev, "bad remote port parent\n");
476                 ret = -ENOTCONN;
477                 goto out_err;
478         }
479
480         ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &vep);
481         if (ret) {
482                 dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n",
483                          ret);
484                 goto out_err;
485         }
486
487         ret = parse_endpoint ? parse_endpoint(dev, &vep, asd) : 0;
488         if (ret == -ENOTCONN)
489                 dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep.base.port,
490                         vep.base.id);
491         else if (ret < 0)
492                 dev_warn(dev,
493                          "driver could not parse port@%u/endpoint@%u (%d)\n",
494                          vep.base.port, vep.base.id, ret);
495         v4l2_fwnode_endpoint_free(&vep);
496         if (ret < 0)
497                 goto out_err;
498
499         ret = v4l2_async_notifier_add_subdev(notifier, asd);
500         if (ret < 0) {
501                 /* not an error if asd already exists */
502                 if (ret == -EEXIST)
503                         ret = 0;
504                 goto out_err;
505         }
506
507         return 0;
508
509 out_err:
510         fwnode_handle_put(asd->match.fwnode);
511         kfree(asd);
512
513         return ret == -ENOTCONN ? 0 : ret;
514 }
515
516 static int __v4l2_async_notifier_parse_fwnode_endpoints(
517         struct device *dev, struct v4l2_async_notifier *notifier,
518         size_t asd_struct_size, unsigned int port, bool has_port,
519         int (*parse_endpoint)(struct device *dev,
520                             struct v4l2_fwnode_endpoint *vep,
521                             struct v4l2_async_subdev *asd))
522 {
523         struct fwnode_handle *fwnode;
524         int ret = 0;
525
526         if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev)))
527                 return -EINVAL;
528
529         fwnode_graph_for_each_endpoint(dev_fwnode(dev), fwnode) {
530                 struct fwnode_handle *dev_fwnode;
531                 bool is_available;
532
533                 dev_fwnode = fwnode_graph_get_port_parent(fwnode);
534                 is_available = fwnode_device_is_available(dev_fwnode);
535                 fwnode_handle_put(dev_fwnode);
536                 if (!is_available)
537                         continue;
538
539                 if (has_port) {
540                         struct fwnode_endpoint ep;
541
542                         ret = fwnode_graph_parse_endpoint(fwnode, &ep);
543                         if (ret)
544                                 break;
545
546                         if (ep.port != port)
547                                 continue;
548                 }
549
550                 ret = v4l2_async_notifier_fwnode_parse_endpoint(
551                         dev, notifier, fwnode, asd_struct_size, parse_endpoint);
552                 if (ret < 0)
553                         break;
554         }
555
556         fwnode_handle_put(fwnode);
557
558         return ret;
559 }
560
561 int v4l2_async_notifier_parse_fwnode_endpoints(
562         struct device *dev, struct v4l2_async_notifier *notifier,
563         size_t asd_struct_size,
564         int (*parse_endpoint)(struct device *dev,
565                             struct v4l2_fwnode_endpoint *vep,
566                             struct v4l2_async_subdev *asd))
567 {
568         return __v4l2_async_notifier_parse_fwnode_endpoints(
569                 dev, notifier, asd_struct_size, 0, false, parse_endpoint);
570 }
571 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints);
572
573 int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
574         struct device *dev, struct v4l2_async_notifier *notifier,
575         size_t asd_struct_size, unsigned int port,
576         int (*parse_endpoint)(struct device *dev,
577                             struct v4l2_fwnode_endpoint *vep,
578                             struct v4l2_async_subdev *asd))
579 {
580         return __v4l2_async_notifier_parse_fwnode_endpoints(
581                 dev, notifier, asd_struct_size, port, true, parse_endpoint);
582 }
583 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port);
584
585 /*
586  * v4l2_fwnode_reference_parse - parse references for async sub-devices
587  * @dev: the device node the properties of which are parsed for references
588  * @notifier: the async notifier where the async subdevs will be added
589  * @prop: the name of the property
590  *
591  * Return: 0 on success
592  *         -ENOENT if no entries were found
593  *         -ENOMEM if memory allocation failed
594  *         -EINVAL if property parsing failed
595  */
596 static int v4l2_fwnode_reference_parse(
597         struct device *dev, struct v4l2_async_notifier *notifier,
598         const char *prop)
599 {
600         struct fwnode_reference_args args;
601         unsigned int index;
602         int ret;
603
604         for (index = 0;
605              !(ret = fwnode_property_get_reference_args(
606                        dev_fwnode(dev), prop, NULL, 0, index, &args));
607              index++)
608                 fwnode_handle_put(args.fwnode);
609
610         if (!index)
611                 return -ENOENT;
612
613         /*
614          * Note that right now both -ENODATA and -ENOENT may signal
615          * out-of-bounds access. Return the error in cases other than that.
616          */
617         if (ret != -ENOENT && ret != -ENODATA)
618                 return ret;
619
620         for (index = 0; !fwnode_property_get_reference_args(
621                      dev_fwnode(dev), prop, NULL, 0, index, &args);
622              index++) {
623                 struct v4l2_async_subdev *asd;
624
625                 asd = v4l2_async_notifier_add_fwnode_subdev(
626                         notifier, args.fwnode, sizeof(*asd));
627                 if (IS_ERR(asd)) {
628                         ret = PTR_ERR(asd);
629                         /* not an error if asd already exists */
630                         if (ret == -EEXIST) {
631                                 fwnode_handle_put(args.fwnode);
632                                 continue;
633                         }
634
635                         goto error;
636                 }
637         }
638
639         return 0;
640
641 error:
642         fwnode_handle_put(args.fwnode);
643         return ret;
644 }
645
646 /*
647  * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
648  *                                      arguments
649  * @fwnode: fwnode to read @prop from
650  * @notifier: notifier for @dev
651  * @prop: the name of the property
652  * @index: the index of the reference to get
653  * @props: the array of integer property names
654  * @nprops: the number of integer property names in @nprops
655  *
656  * First find an fwnode referred to by the reference at @index in @prop.
657  *
658  * Then under that fwnode, @nprops times, for each property in @props,
659  * iteratively follow child nodes starting from fwnode such that they have the
660  * property in @props array at the index of the child node distance from the
661  * root node and the value of that property matching with the integer argument
662  * of the reference, at the same index.
663  *
664  * The child fwnode reched at the end of the iteration is then returned to the
665  * caller.
666  *
667  * The core reason for this is that you cannot refer to just any node in ACPI.
668  * So to refer to an endpoint (easy in DT) you need to refer to a device, then
669  * provide a list of (property name, property value) tuples where each tuple
670  * uniquely identifies a child node. The first tuple identifies a child directly
671  * underneath the device fwnode, the next tuple identifies a child node
672  * underneath the fwnode identified by the previous tuple, etc. until you
673  * reached the fwnode you need.
674  *
675  * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt:
676  *
677  *      Scope (\_SB.PCI0.I2C2)
678  *      {
679  *              Device (CAM0)
680  *              {
681  *                      Name (_DSD, Package () {
682  *                              ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
683  *                              Package () {
684  *                                      Package () {
685  *                                              "compatible",
686  *                                              Package () { "nokia,smia" }
687  *                                      },
688  *                              },
689  *                              ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
690  *                              Package () {
691  *                                      Package () { "port0", "PRT0" },
692  *                              }
693  *                      })
694  *                      Name (PRT0, Package() {
695  *                              ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
696  *                              Package () {
697  *                                      Package () { "port", 0 },
698  *                              },
699  *                              ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
700  *                              Package () {
701  *                                      Package () { "endpoint0", "EP00" },
702  *                              }
703  *                      })
704  *                      Name (EP00, Package() {
705  *                              ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
706  *                              Package () {
707  *                                      Package () { "endpoint", 0 },
708  *                                      Package () {
709  *                                              "remote-endpoint",
710  *                                              Package() {
711  *                                                      \_SB.PCI0.ISP, 4, 0
712  *                                              }
713  *                                      },
714  *                              }
715  *                      })
716  *              }
717  *      }
718  *
719  *      Scope (\_SB.PCI0)
720  *      {
721  *              Device (ISP)
722  *              {
723  *                      Name (_DSD, Package () {
724  *                              ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
725  *                              Package () {
726  *                                      Package () { "port4", "PRT4" },
727  *                              }
728  *                      })
729  *
730  *                      Name (PRT4, Package() {
731  *                              ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
732  *                              Package () {
733  *                                      Package () { "port", 4 },
734  *                              },
735  *                              ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
736  *                              Package () {
737  *                                      Package () { "endpoint0", "EP40" },
738  *                              }
739  *                      })
740  *
741  *                      Name (EP40, Package() {
742  *                              ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
743  *                              Package () {
744  *                                      Package () { "endpoint", 0 },
745  *                                      Package () {
746  *                                              "remote-endpoint",
747  *                                              Package () {
748  *                                                      \_SB.PCI0.I2C2.CAM0,
749  *                                                      0, 0
750  *                                              }
751  *                                      },
752  *                              }
753  *                      })
754  *              }
755  *      }
756  *
757  * From the EP40 node under ISP device, you could parse the graph remote
758  * endpoint using v4l2_fwnode_reference_get_int_prop with these arguments:
759  *
760  *  @fwnode: fwnode referring to EP40 under ISP.
761  *  @prop: "remote-endpoint"
762  *  @index: 0
763  *  @props: "port", "endpoint"
764  *  @nprops: 2
765  *
766  * And you'd get back fwnode referring to EP00 under CAM0.
767  *
768  * The same works the other way around: if you use EP00 under CAM0 as the
769  * fwnode, you'll get fwnode referring to EP40 under ISP.
770  *
771  * The same example in DT syntax would look like this:
772  *
773  * cam: cam0 {
774  *      compatible = "nokia,smia";
775  *
776  *      port {
777  *              port = <0>;
778  *              endpoint {
779  *                      endpoint = <0>;
780  *                      remote-endpoint = <&isp 4 0>;
781  *              };
782  *      };
783  * };
784  *
785  * isp: isp {
786  *      ports {
787  *              port@4 {
788  *                      port = <4>;
789  *                      endpoint {
790  *                              endpoint = <0>;
791  *                              remote-endpoint = <&cam 0 0>;
792  *                      };
793  *              };
794  *      };
795  * };
796  *
797  * Return: 0 on success
798  *         -ENOENT if no entries (or the property itself) were found
799  *         -EINVAL if property parsing otherwise failed
800  *         -ENOMEM if memory allocation failed
801  */
802 static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
803         struct fwnode_handle *fwnode, const char *prop, unsigned int index,
804         const char * const *props, unsigned int nprops)
805 {
806         struct fwnode_reference_args fwnode_args;
807         u64 *args = fwnode_args.args;
808         struct fwnode_handle *child;
809         int ret;
810
811         /*
812          * Obtain remote fwnode as well as the integer arguments.
813          *
814          * Note that right now both -ENODATA and -ENOENT may signal
815          * out-of-bounds access. Return -ENOENT in that case.
816          */
817         ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops,
818                                                  index, &fwnode_args);
819         if (ret)
820                 return ERR_PTR(ret == -ENODATA ? -ENOENT : ret);
821
822         /*
823          * Find a node in the tree under the referred fwnode corresponding to
824          * the integer arguments.
825          */
826         fwnode = fwnode_args.fwnode;
827         while (nprops--) {
828                 u32 val;
829
830                 /* Loop over all child nodes under fwnode. */
831                 fwnode_for_each_child_node(fwnode, child) {
832                         if (fwnode_property_read_u32(child, *props, &val))
833                                 continue;
834
835                         /* Found property, see if its value matches. */
836                         if (val == *args)
837                                 break;
838                 }
839
840                 fwnode_handle_put(fwnode);
841
842                 /* No property found; return an error here. */
843                 if (!child) {
844                         fwnode = ERR_PTR(-ENOENT);
845                         break;
846                 }
847
848                 props++;
849                 args++;
850                 fwnode = child;
851         }
852
853         return fwnode;
854 }
855
856 /*
857  * v4l2_fwnode_reference_parse_int_props - parse references for async
858  *                                         sub-devices
859  * @dev: struct device pointer
860  * @notifier: notifier for @dev
861  * @prop: the name of the property
862  * @props: the array of integer property names
863  * @nprops: the number of integer properties
864  *
865  * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in
866  * property @prop with integer arguments with child nodes matching in properties
867  * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
868  * accordingly.
869  *
870  * While it is technically possible to use this function on DT, it is only
871  * meaningful on ACPI. On Device tree you can refer to any node in the tree but
872  * on ACPI the references are limited to devices.
873  *
874  * Return: 0 on success
875  *         -ENOENT if no entries (or the property itself) were found
876  *         -EINVAL if property parsing otherwisefailed
877  *         -ENOMEM if memory allocation failed
878  */
879 static int v4l2_fwnode_reference_parse_int_props(
880         struct device *dev, struct v4l2_async_notifier *notifier,
881         const char *prop, const char * const *props, unsigned int nprops)
882 {
883         struct fwnode_handle *fwnode;
884         unsigned int index;
885         int ret;
886
887         index = 0;
888         do {
889                 fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev),
890                                                             prop, index,
891                                                             props, nprops);
892                 if (IS_ERR(fwnode)) {
893                         /*
894                          * Note that right now both -ENODATA and -ENOENT may
895                          * signal out-of-bounds access. Return the error in
896                          * cases other than that.
897                          */
898                         if (PTR_ERR(fwnode) != -ENOENT &&
899                             PTR_ERR(fwnode) != -ENODATA)
900                                 return PTR_ERR(fwnode);
901                         break;
902                 }
903                 fwnode_handle_put(fwnode);
904                 index++;
905         } while (1);
906
907         for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(
908                                          dev_fwnode(dev), prop, index, props,
909                                          nprops))); index++) {
910                 struct v4l2_async_subdev *asd;
911
912                 asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
913                                                             sizeof(*asd));
914                 if (IS_ERR(asd)) {
915                         ret = PTR_ERR(asd);
916                         /* not an error if asd already exists */
917                         if (ret == -EEXIST) {
918                                 fwnode_handle_put(fwnode);
919                                 continue;
920                         }
921
922                         goto error;
923                 }
924         }
925
926         return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
927
928 error:
929         fwnode_handle_put(fwnode);
930         return ret;
931 }
932
933 int v4l2_async_notifier_parse_fwnode_sensor_common(
934         struct device *dev, struct v4l2_async_notifier *notifier)
935 {
936         static const char * const led_props[] = { "led" };
937         static const struct {
938                 const char *name;
939                 const char * const *props;
940                 unsigned int nprops;
941         } props[] = {
942                 { "flash-leds", led_props, ARRAY_SIZE(led_props) },
943                 { "lens-focus", NULL, 0 },
944         };
945         unsigned int i;
946
947         for (i = 0; i < ARRAY_SIZE(props); i++) {
948                 int ret;
949
950                 if (props[i].props && is_acpi_node(dev_fwnode(dev)))
951                         ret = v4l2_fwnode_reference_parse_int_props(
952                                 dev, notifier, props[i].name,
953                                 props[i].props, props[i].nprops);
954                 else
955                         ret = v4l2_fwnode_reference_parse(
956                                 dev, notifier, props[i].name);
957                 if (ret && ret != -ENOENT) {
958                         dev_warn(dev, "parsing property \"%s\" failed (%d)\n",
959                                  props[i].name, ret);
960                         return ret;
961                 }
962         }
963
964         return 0;
965 }
966 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common);
967
968 int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
969 {
970         struct v4l2_async_notifier *notifier;
971         int ret;
972
973         if (WARN_ON(!sd->dev))
974                 return -ENODEV;
975
976         notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
977         if (!notifier)
978                 return -ENOMEM;
979
980         v4l2_async_notifier_init(notifier);
981
982         ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev,
983                                                              notifier);
984         if (ret < 0)
985                 goto out_cleanup;
986
987         ret = v4l2_async_subdev_notifier_register(sd, notifier);
988         if (ret < 0)
989                 goto out_cleanup;
990
991         ret = v4l2_async_register_subdev(sd);
992         if (ret < 0)
993                 goto out_unregister;
994
995         sd->subdev_notifier = notifier;
996
997         return 0;
998
999 out_unregister:
1000         v4l2_async_notifier_unregister(notifier);
1001
1002 out_cleanup:
1003         v4l2_async_notifier_cleanup(notifier);
1004         kfree(notifier);
1005
1006         return ret;
1007 }
1008 EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
1009
1010 int v4l2_async_register_fwnode_subdev(
1011         struct v4l2_subdev *sd, size_t asd_struct_size,
1012         unsigned int *ports, unsigned int num_ports,
1013         int (*parse_endpoint)(struct device *dev,
1014                               struct v4l2_fwnode_endpoint *vep,
1015                               struct v4l2_async_subdev *asd))
1016 {
1017         struct v4l2_async_notifier *notifier;
1018         struct device *dev = sd->dev;
1019         struct fwnode_handle *fwnode;
1020         int ret;
1021
1022         if (WARN_ON(!dev))
1023                 return -ENODEV;
1024
1025         fwnode = dev_fwnode(dev);
1026         if (!fwnode_device_is_available(fwnode))
1027                 return -ENODEV;
1028
1029         notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
1030         if (!notifier)
1031                 return -ENOMEM;
1032
1033         v4l2_async_notifier_init(notifier);
1034
1035         if (!ports) {
1036                 ret = v4l2_async_notifier_parse_fwnode_endpoints(
1037                         dev, notifier, asd_struct_size, parse_endpoint);
1038                 if (ret < 0)
1039                         goto out_cleanup;
1040         } else {
1041                 unsigned int i;
1042
1043                 for (i = 0; i < num_ports; i++) {
1044                         ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
1045                                 dev, notifier, asd_struct_size,
1046                                 ports[i], parse_endpoint);
1047                         if (ret < 0)
1048                                 goto out_cleanup;
1049                 }
1050         }
1051
1052         ret = v4l2_async_subdev_notifier_register(sd, notifier);
1053         if (ret < 0)
1054                 goto out_cleanup;
1055
1056         ret = v4l2_async_register_subdev(sd);
1057         if (ret < 0)
1058                 goto out_unregister;
1059
1060         sd->subdev_notifier = notifier;
1061
1062         return 0;
1063
1064 out_unregister:
1065         v4l2_async_notifier_unregister(notifier);
1066 out_cleanup:
1067         v4l2_async_notifier_cleanup(notifier);
1068         kfree(notifier);
1069
1070         return ret;
1071 }
1072 EXPORT_SYMBOL_GPL(v4l2_async_register_fwnode_subdev);
1073
1074 MODULE_LICENSE("GPL");
1075 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
1076 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1077 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");