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