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