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