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