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>"); 1244