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