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("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_DATA_ACTIVE_HIGH | 314 V4L2_MBUS_DATA_ACTIVE_LOW); 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) && of_node_name_eq(to_of_node(fwnode), "ports")) 568 fwnode = fwnode_get_next_parent(fwnode); 569 link->local_node = fwnode; 570 571 fwnode = fwnode_graph_get_remote_endpoint(__fwnode); 572 if (!fwnode) { 573 fwnode_handle_put(fwnode); 574 return -ENOLINK; 575 } 576 577 fwnode = fwnode_get_parent(fwnode); 578 fwnode_property_read_u32(fwnode, port_prop, &link->remote_port); 579 fwnode = fwnode_get_next_parent(fwnode); 580 if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports")) 581 fwnode = fwnode_get_next_parent(fwnode); 582 link->remote_node = fwnode; 583 584 return 0; 585 } 586 EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link); 587 588 void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link) 589 { 590 fwnode_handle_put(link->local_node); 591 fwnode_handle_put(link->remote_node); 592 } 593 EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link); 594 595 static int 596 v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev, 597 struct v4l2_async_notifier *notifier, 598 struct fwnode_handle *endpoint, 599 unsigned int asd_struct_size, 600 parse_endpoint_func parse_endpoint) 601 { 602 struct v4l2_fwnode_endpoint vep = { .bus_type = 0 }; 603 struct v4l2_async_subdev *asd; 604 int ret; 605 606 asd = kzalloc(asd_struct_size, GFP_KERNEL); 607 if (!asd) 608 return -ENOMEM; 609 610 asd->match_type = V4L2_ASYNC_MATCH_FWNODE; 611 asd->match.fwnode = 612 fwnode_graph_get_remote_port_parent(endpoint); 613 if (!asd->match.fwnode) { 614 dev_dbg(dev, "no remote endpoint found\n"); 615 ret = -ENOTCONN; 616 goto out_err; 617 } 618 619 ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &vep); 620 if (ret) { 621 dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n", 622 ret); 623 goto out_err; 624 } 625 626 ret = parse_endpoint ? parse_endpoint(dev, &vep, asd) : 0; 627 if (ret == -ENOTCONN) 628 dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep.base.port, 629 vep.base.id); 630 else if (ret < 0) 631 dev_warn(dev, 632 "driver could not parse port@%u/endpoint@%u (%d)\n", 633 vep.base.port, vep.base.id, ret); 634 v4l2_fwnode_endpoint_free(&vep); 635 if (ret < 0) 636 goto out_err; 637 638 ret = v4l2_async_notifier_add_subdev(notifier, asd); 639 if (ret < 0) { 640 /* not an error if asd already exists */ 641 if (ret == -EEXIST) 642 ret = 0; 643 goto out_err; 644 } 645 646 return 0; 647 648 out_err: 649 fwnode_handle_put(asd->match.fwnode); 650 kfree(asd); 651 652 return ret == -ENOTCONN ? 0 : ret; 653 } 654 655 static int 656 __v4l2_async_notifier_parse_fwnode_ep(struct device *dev, 657 struct v4l2_async_notifier *notifier, 658 size_t asd_struct_size, 659 unsigned int port, 660 bool has_port, 661 parse_endpoint_func parse_endpoint) 662 { 663 struct fwnode_handle *fwnode; 664 int ret = 0; 665 666 if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev))) 667 return -EINVAL; 668 669 fwnode_graph_for_each_endpoint(dev_fwnode(dev), fwnode) { 670 struct fwnode_handle *dev_fwnode; 671 bool is_available; 672 673 dev_fwnode = fwnode_graph_get_port_parent(fwnode); 674 is_available = fwnode_device_is_available(dev_fwnode); 675 fwnode_handle_put(dev_fwnode); 676 if (!is_available) 677 continue; 678 679 if (has_port) { 680 struct fwnode_endpoint ep; 681 682 ret = fwnode_graph_parse_endpoint(fwnode, &ep); 683 if (ret) 684 break; 685 686 if (ep.port != port) 687 continue; 688 } 689 690 ret = v4l2_async_notifier_fwnode_parse_endpoint(dev, 691 notifier, 692 fwnode, 693 asd_struct_size, 694 parse_endpoint); 695 if (ret < 0) 696 break; 697 } 698 699 fwnode_handle_put(fwnode); 700 701 return ret; 702 } 703 704 int 705 v4l2_async_notifier_parse_fwnode_endpoints(struct device *dev, 706 struct v4l2_async_notifier *notifier, 707 size_t asd_struct_size, 708 parse_endpoint_func parse_endpoint) 709 { 710 return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier, 711 asd_struct_size, 0, 712 false, parse_endpoint); 713 } 714 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints); 715 716 int 717 v4l2_async_notifier_parse_fwnode_endpoints_by_port(struct device *dev, 718 struct v4l2_async_notifier *notifier, 719 size_t asd_struct_size, 720 unsigned int port, 721 parse_endpoint_func parse_endpoint) 722 { 723 return __v4l2_async_notifier_parse_fwnode_ep(dev, notifier, 724 asd_struct_size, 725 port, true, 726 parse_endpoint); 727 } 728 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port); 729 730 /* 731 * v4l2_fwnode_reference_parse - parse references for async sub-devices 732 * @dev: the device node the properties of which are parsed for references 733 * @notifier: the async notifier where the async subdevs will be added 734 * @prop: the name of the property 735 * 736 * Return: 0 on success 737 * -ENOENT if no entries were found 738 * -ENOMEM if memory allocation failed 739 * -EINVAL if property parsing failed 740 */ 741 static int v4l2_fwnode_reference_parse(struct device *dev, 742 struct v4l2_async_notifier *notifier, 743 const char *prop) 744 { 745 struct fwnode_reference_args args; 746 unsigned int index; 747 int ret; 748 749 for (index = 0; 750 !(ret = fwnode_property_get_reference_args(dev_fwnode(dev), 751 prop, NULL, 0, 752 index, &args)); 753 index++) 754 fwnode_handle_put(args.fwnode); 755 756 if (!index) 757 return -ENOENT; 758 759 /* 760 * Note that right now both -ENODATA and -ENOENT may signal 761 * out-of-bounds access. Return the error in cases other than that. 762 */ 763 if (ret != -ENOENT && ret != -ENODATA) 764 return ret; 765 766 for (index = 0; 767 !fwnode_property_get_reference_args(dev_fwnode(dev), prop, NULL, 768 0, index, &args); 769 index++) { 770 struct v4l2_async_subdev *asd; 771 772 asd = v4l2_async_notifier_add_fwnode_subdev(notifier, 773 args.fwnode, 774 sizeof(*asd)); 775 if (IS_ERR(asd)) { 776 ret = PTR_ERR(asd); 777 /* not an error if asd already exists */ 778 if (ret == -EEXIST) { 779 fwnode_handle_put(args.fwnode); 780 continue; 781 } 782 783 goto error; 784 } 785 } 786 787 return 0; 788 789 error: 790 fwnode_handle_put(args.fwnode); 791 return ret; 792 } 793 794 /* 795 * v4l2_fwnode_reference_get_int_prop - parse a reference with integer 796 * arguments 797 * @fwnode: fwnode to read @prop from 798 * @notifier: notifier for @dev 799 * @prop: the name of the property 800 * @index: the index of the reference to get 801 * @props: the array of integer property names 802 * @nprops: the number of integer property names in @nprops 803 * 804 * First find an fwnode referred to by the reference at @index in @prop. 805 * 806 * Then under that fwnode, @nprops times, for each property in @props, 807 * iteratively follow child nodes starting from fwnode such that they have the 808 * property in @props array at the index of the child node distance from the 809 * root node and the value of that property matching with the integer argument 810 * of the reference, at the same index. 811 * 812 * The child fwnode reached at the end of the iteration is then returned to the 813 * caller. 814 * 815 * The core reason for this is that you cannot refer to just any node in ACPI. 816 * So to refer to an endpoint (easy in DT) you need to refer to a device, then 817 * provide a list of (property name, property value) tuples where each tuple 818 * uniquely identifies a child node. The first tuple identifies a child directly 819 * underneath the device fwnode, the next tuple identifies a child node 820 * underneath the fwnode identified by the previous tuple, etc. until you 821 * reached the fwnode you need. 822 * 823 * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt: 824 * 825 * Scope (\_SB.PCI0.I2C2) 826 * { 827 * Device (CAM0) 828 * { 829 * Name (_DSD, Package () { 830 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 831 * Package () { 832 * Package () { 833 * "compatible", 834 * Package () { "nokia,smia" } 835 * }, 836 * }, 837 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 838 * Package () { 839 * Package () { "port0", "PRT0" }, 840 * } 841 * }) 842 * Name (PRT0, Package() { 843 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 844 * Package () { 845 * Package () { "port", 0 }, 846 * }, 847 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 848 * Package () { 849 * Package () { "endpoint0", "EP00" }, 850 * } 851 * }) 852 * Name (EP00, Package() { 853 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 854 * Package () { 855 * Package () { "endpoint", 0 }, 856 * Package () { 857 * "remote-endpoint", 858 * Package() { 859 * \_SB.PCI0.ISP, 4, 0 860 * } 861 * }, 862 * } 863 * }) 864 * } 865 * } 866 * 867 * Scope (\_SB.PCI0) 868 * { 869 * Device (ISP) 870 * { 871 * Name (_DSD, Package () { 872 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 873 * Package () { 874 * Package () { "port4", "PRT4" }, 875 * } 876 * }) 877 * 878 * Name (PRT4, Package() { 879 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 880 * Package () { 881 * Package () { "port", 4 }, 882 * }, 883 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 884 * Package () { 885 * Package () { "endpoint0", "EP40" }, 886 * } 887 * }) 888 * 889 * Name (EP40, Package() { 890 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 891 * Package () { 892 * Package () { "endpoint", 0 }, 893 * Package () { 894 * "remote-endpoint", 895 * Package () { 896 * \_SB.PCI0.I2C2.CAM0, 897 * 0, 0 898 * } 899 * }, 900 * } 901 * }) 902 * } 903 * } 904 * 905 * From the EP40 node under ISP device, you could parse the graph remote 906 * endpoint using v4l2_fwnode_reference_get_int_prop with these arguments: 907 * 908 * @fwnode: fwnode referring to EP40 under ISP. 909 * @prop: "remote-endpoint" 910 * @index: 0 911 * @props: "port", "endpoint" 912 * @nprops: 2 913 * 914 * And you'd get back fwnode referring to EP00 under CAM0. 915 * 916 * The same works the other way around: if you use EP00 under CAM0 as the 917 * fwnode, you'll get fwnode referring to EP40 under ISP. 918 * 919 * The same example in DT syntax would look like this: 920 * 921 * cam: cam0 { 922 * compatible = "nokia,smia"; 923 * 924 * port { 925 * port = <0>; 926 * endpoint { 927 * endpoint = <0>; 928 * remote-endpoint = <&isp 4 0>; 929 * }; 930 * }; 931 * }; 932 * 933 * isp: isp { 934 * ports { 935 * port@4 { 936 * port = <4>; 937 * endpoint { 938 * endpoint = <0>; 939 * remote-endpoint = <&cam 0 0>; 940 * }; 941 * }; 942 * }; 943 * }; 944 * 945 * Return: 0 on success 946 * -ENOENT if no entries (or the property itself) were found 947 * -EINVAL if property parsing otherwise failed 948 * -ENOMEM if memory allocation failed 949 */ 950 static struct fwnode_handle * 951 v4l2_fwnode_reference_get_int_prop(struct fwnode_handle *fwnode, 952 const char *prop, 953 unsigned int index, 954 const char * const *props, 955 unsigned int nprops) 956 { 957 struct fwnode_reference_args fwnode_args; 958 u64 *args = fwnode_args.args; 959 struct fwnode_handle *child; 960 int ret; 961 962 /* 963 * Obtain remote fwnode as well as the integer arguments. 964 * 965 * Note that right now both -ENODATA and -ENOENT may signal 966 * out-of-bounds access. Return -ENOENT in that case. 967 */ 968 ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops, 969 index, &fwnode_args); 970 if (ret) 971 return ERR_PTR(ret == -ENODATA ? -ENOENT : ret); 972 973 /* 974 * Find a node in the tree under the referred fwnode corresponding to 975 * the integer arguments. 976 */ 977 fwnode = fwnode_args.fwnode; 978 while (nprops--) { 979 u32 val; 980 981 /* Loop over all child nodes under fwnode. */ 982 fwnode_for_each_child_node(fwnode, child) { 983 if (fwnode_property_read_u32(child, *props, &val)) 984 continue; 985 986 /* Found property, see if its value matches. */ 987 if (val == *args) 988 break; 989 } 990 991 fwnode_handle_put(fwnode); 992 993 /* No property found; return an error here. */ 994 if (!child) { 995 fwnode = ERR_PTR(-ENOENT); 996 break; 997 } 998 999 props++; 1000 args++; 1001 fwnode = child; 1002 } 1003 1004 return fwnode; 1005 } 1006 1007 struct v4l2_fwnode_int_props { 1008 const char *name; 1009 const char * const *props; 1010 unsigned int nprops; 1011 }; 1012 1013 /* 1014 * v4l2_fwnode_reference_parse_int_props - parse references for async 1015 * sub-devices 1016 * @dev: struct device pointer 1017 * @notifier: notifier for @dev 1018 * @prop: the name of the property 1019 * @props: the array of integer property names 1020 * @nprops: the number of integer properties 1021 * 1022 * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in 1023 * property @prop with integer arguments with child nodes matching in properties 1024 * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier 1025 * accordingly. 1026 * 1027 * While it is technically possible to use this function on DT, it is only 1028 * meaningful on ACPI. On Device tree you can refer to any node in the tree but 1029 * on ACPI the references are limited to devices. 1030 * 1031 * Return: 0 on success 1032 * -ENOENT if no entries (or the property itself) were found 1033 * -EINVAL if property parsing otherwisefailed 1034 * -ENOMEM if memory allocation failed 1035 */ 1036 static int 1037 v4l2_fwnode_reference_parse_int_props(struct device *dev, 1038 struct v4l2_async_notifier *notifier, 1039 const struct v4l2_fwnode_int_props *p) 1040 { 1041 struct fwnode_handle *fwnode; 1042 unsigned int index; 1043 int ret; 1044 const char *prop = p->name; 1045 const char * const *props = p->props; 1046 unsigned int nprops = p->nprops; 1047 1048 index = 0; 1049 do { 1050 fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev), 1051 prop, index, 1052 props, nprops); 1053 if (IS_ERR(fwnode)) { 1054 /* 1055 * Note that right now both -ENODATA and -ENOENT may 1056 * signal out-of-bounds access. Return the error in 1057 * cases other than that. 1058 */ 1059 if (PTR_ERR(fwnode) != -ENOENT && 1060 PTR_ERR(fwnode) != -ENODATA) 1061 return PTR_ERR(fwnode); 1062 break; 1063 } 1064 fwnode_handle_put(fwnode); 1065 index++; 1066 } while (1); 1067 1068 for (index = 0; 1069 !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop(dev_fwnode(dev), 1070 prop, index, 1071 props, 1072 nprops))); 1073 index++) { 1074 struct v4l2_async_subdev *asd; 1075 1076 asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, 1077 sizeof(*asd)); 1078 if (IS_ERR(asd)) { 1079 ret = PTR_ERR(asd); 1080 /* not an error if asd already exists */ 1081 if (ret == -EEXIST) { 1082 fwnode_handle_put(fwnode); 1083 continue; 1084 } 1085 1086 goto error; 1087 } 1088 } 1089 1090 return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); 1091 1092 error: 1093 fwnode_handle_put(fwnode); 1094 return ret; 1095 } 1096 1097 int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev, 1098 struct v4l2_async_notifier *notifier) 1099 { 1100 static const char * const led_props[] = { "led" }; 1101 static const struct v4l2_fwnode_int_props props[] = { 1102 { "flash-leds", led_props, ARRAY_SIZE(led_props) }, 1103 { "lens-focus", NULL, 0 }, 1104 }; 1105 unsigned int i; 1106 1107 for (i = 0; i < ARRAY_SIZE(props); i++) { 1108 int ret; 1109 1110 if (props[i].props && is_acpi_node(dev_fwnode(dev))) 1111 ret = v4l2_fwnode_reference_parse_int_props(dev, 1112 notifier, 1113 &props[i]); 1114 else 1115 ret = v4l2_fwnode_reference_parse(dev, notifier, 1116 props[i].name); 1117 if (ret && ret != -ENOENT) { 1118 dev_warn(dev, "parsing property \"%s\" failed (%d)\n", 1119 props[i].name, ret); 1120 return ret; 1121 } 1122 } 1123 1124 return 0; 1125 } 1126 EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common); 1127 1128 int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd) 1129 { 1130 struct v4l2_async_notifier *notifier; 1131 int ret; 1132 1133 if (WARN_ON(!sd->dev)) 1134 return -ENODEV; 1135 1136 notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); 1137 if (!notifier) 1138 return -ENOMEM; 1139 1140 v4l2_async_notifier_init(notifier); 1141 1142 ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev, 1143 notifier); 1144 if (ret < 0) 1145 goto out_cleanup; 1146 1147 ret = v4l2_async_subdev_notifier_register(sd, notifier); 1148 if (ret < 0) 1149 goto out_cleanup; 1150 1151 ret = v4l2_async_register_subdev(sd); 1152 if (ret < 0) 1153 goto out_unregister; 1154 1155 sd->subdev_notifier = notifier; 1156 1157 return 0; 1158 1159 out_unregister: 1160 v4l2_async_notifier_unregister(notifier); 1161 1162 out_cleanup: 1163 v4l2_async_notifier_cleanup(notifier); 1164 kfree(notifier); 1165 1166 return ret; 1167 } 1168 EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common); 1169 1170 int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd, 1171 size_t asd_struct_size, 1172 unsigned int *ports, 1173 unsigned int num_ports, 1174 parse_endpoint_func parse_endpoint) 1175 { 1176 struct v4l2_async_notifier *notifier; 1177 struct device *dev = sd->dev; 1178 struct fwnode_handle *fwnode; 1179 int ret; 1180 1181 if (WARN_ON(!dev)) 1182 return -ENODEV; 1183 1184 fwnode = dev_fwnode(dev); 1185 if (!fwnode_device_is_available(fwnode)) 1186 return -ENODEV; 1187 1188 notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); 1189 if (!notifier) 1190 return -ENOMEM; 1191 1192 v4l2_async_notifier_init(notifier); 1193 1194 if (!ports) { 1195 ret = v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier, 1196 asd_struct_size, 1197 parse_endpoint); 1198 if (ret < 0) 1199 goto out_cleanup; 1200 } else { 1201 unsigned int i; 1202 1203 for (i = 0; i < num_ports; i++) { 1204 ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(dev, notifier, asd_struct_size, ports[i], parse_endpoint); 1205 if (ret < 0) 1206 goto out_cleanup; 1207 } 1208 } 1209 1210 ret = v4l2_async_subdev_notifier_register(sd, notifier); 1211 if (ret < 0) 1212 goto out_cleanup; 1213 1214 ret = v4l2_async_register_subdev(sd); 1215 if (ret < 0) 1216 goto out_unregister; 1217 1218 sd->subdev_notifier = notifier; 1219 1220 return 0; 1221 1222 out_unregister: 1223 v4l2_async_notifier_unregister(notifier); 1224 out_cleanup: 1225 v4l2_async_notifier_cleanup(notifier); 1226 kfree(notifier); 1227 1228 return ret; 1229 } 1230 EXPORT_SYMBOL_GPL(v4l2_async_register_fwnode_subdev); 1231 1232 MODULE_LICENSE("GPL"); 1233 MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>"); 1234 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); 1235 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); 1236