Lines Matching +full:lane +full:- +full:polarities

1 // SPDX-License-Identifier: GPL-2.0-only
6 * formerly was located in v4l2-of.c.
11 * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
27 #include <media/v4l2-async.h>
28 #include <media/v4l2-fwnode.h>
29 #include <media/v4l2-subdev.h>
54 "MIPI CSI-2 C-PHY",
58 "MIPI CSI-1",
66 "MIPI CSI-2 D-PHY",
96 return conv ? conv->mbus_type : V4L2_MBUS_UNKNOWN; in v4l2_fwnode_bus_type_to_mbus()
105 return conv ? conv->name : "not found"; in v4l2_fwnode_bus_type_to_string()
126 return conv ? conv->name : "not found"; in v4l2_fwnode_mbus_type_to_string()
133 struct v4l2_fwnode_bus_mipi_csi2 *bus = &vep->bus.mipi_csi2; in v4l2_fwnode_endpoint_parse_csi2_bus()
149 num_data_lanes = min_t(u32, bus->num_data_lanes, in v4l2_fwnode_endpoint_parse_csi2_bus()
152 clock_lane = bus->clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
157 array[i] = bus->data_lanes[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
163 pr_debug("no lane mapping given, using defaults\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
166 rval = fwnode_property_count_u32(fwnode, "data-lanes"); in v4l2_fwnode_endpoint_parse_csi2_bus()
171 fwnode_property_read_u32_array(fwnode, "data-lanes", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
176 pr_debug("data-lanes property exists; disabling default mapping\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
184 pr_warn("duplicated lane %u in data-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
191 pr_debug("lane %u position %u\n", i, array[i]); in v4l2_fwnode_endpoint_parse_csi2_bus()
194 rval = fwnode_property_count_u32(fwnode, "lane-polarities"); in v4l2_fwnode_endpoint_parse_csi2_bus()
197 pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
199 return -EINVAL; in v4l2_fwnode_endpoint_parse_csi2_bus()
205 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi2_bus()
207 pr_debug("clock lane position %u\n", v); in v4l2_fwnode_endpoint_parse_csi2_bus()
213 pr_warn("duplicated lane %u in clock-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
218 if (fwnode_property_present(fwnode, "clock-noncontinuous")) { in v4l2_fwnode_endpoint_parse_csi2_bus()
220 pr_debug("non-continuous clock\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
228 /* Only D-PHY has a clock lane. */ in v4l2_fwnode_endpoint_parse_csi2_bus()
232 bus->flags = flags; in v4l2_fwnode_endpoint_parse_csi2_bus()
234 vep->bus_type = V4L2_MBUS_CSI2_DPHY; in v4l2_fwnode_endpoint_parse_csi2_bus()
235 bus->num_data_lanes = num_data_lanes; in v4l2_fwnode_endpoint_parse_csi2_bus()
238 bus->clock_lane = 0; in v4l2_fwnode_endpoint_parse_csi2_bus()
240 bus->data_lanes[i] = dfl_data_lane_index + i; in v4l2_fwnode_endpoint_parse_csi2_bus()
242 bus->clock_lane = clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
244 bus->data_lanes[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
249 "lane-polarities", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
253 bus->lane_polarities[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
254 pr_debug("lane %u polarity %sinverted", in v4l2_fwnode_endpoint_parse_csi2_bus()
258 pr_debug("no lane polarities defined, assuming not inverted\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
277 struct v4l2_fwnode_bus_parallel *bus = &vep->bus.parallel; in v4l2_fwnode_endpoint_parse_parallel_bus()
282 flags = bus->flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
284 if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
289 pr_debug("hsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
292 if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
297 pr_debug("vsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
300 if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
305 pr_debug("field-even-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
308 if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
313 pr_debug("pclk-sample %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
316 if (!fwnode_property_read_u32(fwnode, "data-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
321 pr_debug("data-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
324 if (fwnode_property_present(fwnode, "slave-mode")) { in v4l2_fwnode_endpoint_parse_parallel_bus()
333 if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
334 bus->bus_width = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
335 pr_debug("bus-width %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
338 if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
339 bus->data_shift = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
340 pr_debug("data-shift %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
343 if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
348 pr_debug("sync-on-green-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
351 if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
356 pr_debug("data-enable-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
361 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
363 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
365 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
368 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
369 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
372 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
373 bus->flags = flags & ~PARALLEL_MBUS_FLAGS; in v4l2_fwnode_endpoint_parse_parallel_bus()
383 struct v4l2_fwnode_bus_mipi_csi1 *bus = &vep->bus.mipi_csi1; in v4l2_fwnode_endpoint_parse_csi1_bus()
386 if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
387 bus->clock_inv = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
388 pr_debug("clock-inv %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
392 bus->strobe = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
396 if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
397 bus->data_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
398 pr_debug("data-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
401 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
402 bus->clock_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
403 pr_debug("clock-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
407 vep->bus_type = V4L2_MBUS_CCP2; in v4l2_fwnode_endpoint_parse_csi1_bus()
409 vep->bus_type = V4L2_MBUS_CSI1; in v4l2_fwnode_endpoint_parse_csi1_bus()
419 if (vep->bus_type == V4L2_MBUS_UNKNOWN) { in __v4l2_fwnode_endpoint_parse()
421 memset(&vep->bus, 0, in __v4l2_fwnode_endpoint_parse()
422 sizeof(*vep) - offsetof(typeof(*vep), bus)); in __v4l2_fwnode_endpoint_parse()
431 memset(&vep->base, 0, sizeof(vep->base)); in __v4l2_fwnode_endpoint_parse()
433 fwnode_property_read_u32(fwnode, "bus-type", &bus_type); in __v4l2_fwnode_endpoint_parse()
436 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
437 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
440 if (vep->bus_type != V4L2_MBUS_UNKNOWN) { in __v4l2_fwnode_endpoint_parse()
442 vep->bus_type != mbus_type) { in __v4l2_fwnode_endpoint_parse()
444 v4l2_fwnode_mbus_type_to_string(vep->bus_type)); in __v4l2_fwnode_endpoint_parse()
445 return -ENXIO; in __v4l2_fwnode_endpoint_parse()
448 vep->bus_type = mbus_type; in __v4l2_fwnode_endpoint_parse()
451 switch (vep->bus_type) { in __v4l2_fwnode_endpoint_parse()
458 if (vep->bus_type == V4L2_MBUS_UNKNOWN) in __v4l2_fwnode_endpoint_parse()
463 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
464 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
469 v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, vep->bus_type); in __v4l2_fwnode_endpoint_parse()
475 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
483 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
488 return -EINVAL; in __v4l2_fwnode_endpoint_parse()
491 fwnode_graph_parse_endpoint(fwnode, &vep->base); in __v4l2_fwnode_endpoint_parse()
514 kfree(vep->link_frequencies); in v4l2_fwnode_endpoint_free()
515 vep->link_frequencies = NULL; in v4l2_fwnode_endpoint_free()
528 rval = fwnode_property_count_u64(fwnode, "link-frequencies"); in v4l2_fwnode_endpoint_alloc_parse()
532 vep->link_frequencies = in v4l2_fwnode_endpoint_alloc_parse()
533 kmalloc_array(rval, sizeof(*vep->link_frequencies), in v4l2_fwnode_endpoint_alloc_parse()
535 if (!vep->link_frequencies) in v4l2_fwnode_endpoint_alloc_parse()
536 return -ENOMEM; in v4l2_fwnode_endpoint_alloc_parse()
538 vep->nr_of_link_frequencies = rval; in v4l2_fwnode_endpoint_alloc_parse()
541 "link-frequencies", in v4l2_fwnode_endpoint_alloc_parse()
542 vep->link_frequencies, in v4l2_fwnode_endpoint_alloc_parse()
543 vep->nr_of_link_frequencies); in v4l2_fwnode_endpoint_alloc_parse()
549 for (i = 0; i < vep->nr_of_link_frequencies; i++) in v4l2_fwnode_endpoint_alloc_parse()
550 pr_debug("link-frequencies %u value %llu\n", i, in v4l2_fwnode_endpoint_alloc_parse()
551 vep->link_frequencies[i]); in v4l2_fwnode_endpoint_alloc_parse()
568 link->local_id = fwep.id; in v4l2_fwnode_parse_link()
569 link->local_port = fwep.port; in v4l2_fwnode_parse_link()
570 link->local_node = fwnode_graph_get_port_parent(fwnode); in v4l2_fwnode_parse_link()
575 return -ENOLINK; in v4l2_fwnode_parse_link()
579 link->remote_id = fwep.id; in v4l2_fwnode_parse_link()
580 link->remote_port = fwep.port; in v4l2_fwnode_parse_link()
581 link->remote_node = fwnode_graph_get_port_parent(fwnode); in v4l2_fwnode_parse_link()
589 fwnode_handle_put(link->local_node); in v4l2_fwnode_put_link()
590 fwnode_handle_put(link->remote_node); in v4l2_fwnode_put_link()
600 .compatible = "composite-video-connector",
603 .compatible = "svideo-connector",
626 ret = fwnode_property_read_u32(fwnode, "sdtv-standards", &stds); in v4l2_fwnode_connector_parse_analog()
629 vc->connector.analog.sdtv_stds = ret ? V4L2_STD_ALL : stds; in v4l2_fwnode_connector_parse_analog()
636 if (IS_ERR_OR_NULL(connector) || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_free()
639 list_for_each_entry_safe(link, tmp, &connector->links, head) { in v4l2_fwnode_connector_free()
640 v4l2_fwnode_put_link(&link->fwnode_link); in v4l2_fwnode_connector_free()
641 list_del(&link->head); in v4l2_fwnode_connector_free()
645 kfree(connector->label); in v4l2_fwnode_connector_free()
646 connector->label = NULL; in v4l2_fwnode_connector_free()
647 connector->type = V4L2_CONN_UNKNOWN; in v4l2_fwnode_connector_free()
660 /* The connector-type is stored within the compatible string. */ in v4l2_fwnode_get_connector_type()
677 return -EINVAL; in v4l2_fwnode_connector_parse()
681 INIT_LIST_HEAD(&connector->links); in v4l2_fwnode_connector_parse()
693 err = -ENOTCONN; in v4l2_fwnode_connector_parse()
697 connector->type = connector_type; in v4l2_fwnode_connector_parse()
698 connector->name = fwnode_get_name(connector_node); in v4l2_fwnode_connector_parse()
700 connector->label = err ? NULL : kstrdup_const(label, GFP_KERNEL); in v4l2_fwnode_connector_parse()
703 switch (connector->type) { in v4l2_fwnode_connector_parse()
727 if (!fwnode || !connector || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_add_link()
728 return -EINVAL; in v4l2_fwnode_connector_add_link()
732 return -ENOTCONN; in v4l2_fwnode_connector_add_link()
736 err = -ENOMEM; in v4l2_fwnode_connector_add_link()
740 err = v4l2_fwnode_parse_link(connector_ep, &link->fwnode_link); in v4l2_fwnode_connector_add_link()
746 list_add(&link->head, &connector->links); in v4l2_fwnode_connector_add_link()
747 connector->nr_of_links++; in v4l2_fwnode_connector_add_link()
768 props->orientation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
778 return -EINVAL; in v4l2_fwnode_device_parse()
781 props->orientation = val; in v4l2_fwnode_device_parse()
785 props->rotation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
790 return -EINVAL; in v4l2_fwnode_device_parse()
793 props->rotation = val; in v4l2_fwnode_device_parse()
814 return -ENOMEM; in v4l2_async_notifier_fwnode_parse_endpoint()
816 asd->match_type = V4L2_ASYNC_MATCH_FWNODE; in v4l2_async_notifier_fwnode_parse_endpoint()
817 asd->match.fwnode = in v4l2_async_notifier_fwnode_parse_endpoint()
819 if (!asd->match.fwnode) { in v4l2_async_notifier_fwnode_parse_endpoint()
821 ret = -ENOTCONN; in v4l2_async_notifier_fwnode_parse_endpoint()
833 if (ret == -ENOTCONN) in v4l2_async_notifier_fwnode_parse_endpoint()
847 if (ret == -EEXIST) in v4l2_async_notifier_fwnode_parse_endpoint()
855 fwnode_handle_put(asd->match.fwnode); in v4l2_async_notifier_fwnode_parse_endpoint()
858 return ret == -ENOTCONN ? 0 : ret; in v4l2_async_notifier_fwnode_parse_endpoint()
873 return -EINVAL; in __v4l2_async_notifier_parse_fwnode_ep()
937 * v4l2_fwnode_reference_parse - parse references for async sub-devices
943 * -ENOENT if no entries were found
944 * -ENOMEM if memory allocation failed
945 * -EINVAL if property parsing failed
963 return -ENOENT; in v4l2_fwnode_reference_parse()
966 * Note that right now both -ENODATA and -ENOENT may signal in v4l2_fwnode_reference_parse()
967 * out-of-bounds access. Return the error in cases other than that. in v4l2_fwnode_reference_parse()
969 if (ret != -ENOENT && ret != -ENODATA) in v4l2_fwnode_reference_parse()
984 if (PTR_ERR(asd) == -EEXIST) in v4l2_fwnode_reference_parse()
995 * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
1025 * Documentation/firmware-guide/acpi/dsd/ instead and especially graph.txt,
1026 * data-node-references.txt and leds.txt .
1033 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1040 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
1046 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1050 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
1056 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1060 * "remote-endpoint",
1075 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
1082 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1086 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
1093 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1097 * "remote-endpoint",
1112 * @prop: "remote-endpoint"
1131 * remote-endpoint = <&isp 4 0>;
1142 * remote-endpoint = <&cam 0 0>;
1149 * -ENOENT if no entries (or the property itself) were found
1150 * -EINVAL if property parsing otherwise failed
1151 * -ENOMEM if memory allocation failed
1168 * Note that right now both -ENODATA and -ENOENT may signal in v4l2_fwnode_reference_get_int_prop()
1169 * out-of-bounds access. Return -ENOENT in that case. in v4l2_fwnode_reference_get_int_prop()
1174 return ERR_PTR(ret == -ENODATA ? -ENOENT : ret); in v4l2_fwnode_reference_get_int_prop()
1181 while (nprops--) { in v4l2_fwnode_reference_get_int_prop()
1198 fwnode = ERR_PTR(-ENOENT); in v4l2_fwnode_reference_get_int_prop()
1217 * v4l2_fwnode_reference_parse_int_props - parse references for async
1218 * sub-devices
1227 * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
1235 * -ENOENT if no entries (or the property itself) were found
1236 * -EINVAL if property parsing otherwisefailed
1237 * -ENOMEM if memory allocation failed
1247 const char *prop = p->name; in v4l2_fwnode_reference_parse_int_props()
1248 const char * const *props = p->props; in v4l2_fwnode_reference_parse_int_props()
1249 unsigned int nprops = p->nprops; in v4l2_fwnode_reference_parse_int_props()
1258 * Note that right now both -ENODATA and -ENOENT may in v4l2_fwnode_reference_parse_int_props()
1259 * signal out-of-bounds access. Return the error in in v4l2_fwnode_reference_parse_int_props()
1262 if (PTR_ERR(fwnode) != -ENOENT && in v4l2_fwnode_reference_parse_int_props()
1263 PTR_ERR(fwnode) != -ENODATA) in v4l2_fwnode_reference_parse_int_props()
1285 if (ret == -EEXIST) in v4l2_fwnode_reference_parse_int_props()
1292 return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); in v4l2_fwnode_reference_parse_int_props()
1300 { "flash-leds", led_props, ARRAY_SIZE(led_props) }, in v4l2_async_notifier_parse_fwnode_sensor_common()
1301 { "lens-focus", NULL, 0 }, in v4l2_async_notifier_parse_fwnode_sensor_common()
1315 if (ret && ret != -ENOENT) { in v4l2_async_notifier_parse_fwnode_sensor_common()
1331 if (WARN_ON(!sd->dev)) in v4l2_async_register_subdev_sensor_common()
1332 return -ENODEV; in v4l2_async_register_subdev_sensor_common()
1336 return -ENOMEM; in v4l2_async_register_subdev_sensor_common()
1340 ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev, in v4l2_async_register_subdev_sensor_common()
1353 sd->subdev_notifier = notifier; in v4l2_async_register_subdev_sensor_common()