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