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