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