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>
43 "MIPI CSI-2 C-PHY",
47 "MIPI CSI-1",
55 "MIPI CSI-2 D-PHY",
89 return conv ? conv->mbus_type : V4L2_MBUS_INVALID; in v4l2_fwnode_bus_type_to_mbus()
98 return conv ? conv->name : "not found"; in v4l2_fwnode_bus_type_to_string()
119 return conv ? conv->name : "not found"; in v4l2_fwnode_mbus_type_to_string()
126 struct v4l2_mbus_config_mipi_csi2 *bus = &vep->bus.mipi_csi2; in v4l2_fwnode_endpoint_parse_csi2_bus()
142 num_data_lanes = min_t(u32, bus->num_data_lanes, in v4l2_fwnode_endpoint_parse_csi2_bus()
145 clock_lane = bus->clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
150 array[i] = bus->data_lanes[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
156 pr_debug("no lane mapping given, using defaults\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
159 rval = fwnode_property_count_u32(fwnode, "data-lanes"); in v4l2_fwnode_endpoint_parse_csi2_bus()
164 fwnode_property_read_u32_array(fwnode, "data-lanes", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
169 pr_debug("data-lanes property exists; disabling default mapping\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
177 pr_warn("duplicated lane %u in data-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
184 pr_debug("lane %u position %u\n", i, array[i]); in v4l2_fwnode_endpoint_parse_csi2_bus()
187 rval = fwnode_property_count_u32(fwnode, "lane-polarities"); in v4l2_fwnode_endpoint_parse_csi2_bus()
190 pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
192 return -EINVAL; in v4l2_fwnode_endpoint_parse_csi2_bus()
198 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi2_bus()
200 pr_debug("clock lane position %u\n", v); in v4l2_fwnode_endpoint_parse_csi2_bus()
206 pr_warn("duplicated lane %u in clock-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
211 if (fwnode_property_present(fwnode, "clock-noncontinuous")) { in v4l2_fwnode_endpoint_parse_csi2_bus()
213 pr_debug("non-continuous clock\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
219 /* Only D-PHY has a clock lane. */ in v4l2_fwnode_endpoint_parse_csi2_bus()
223 bus->flags = flags; in v4l2_fwnode_endpoint_parse_csi2_bus()
225 vep->bus_type = V4L2_MBUS_CSI2_DPHY; in v4l2_fwnode_endpoint_parse_csi2_bus()
226 bus->num_data_lanes = num_data_lanes; in v4l2_fwnode_endpoint_parse_csi2_bus()
229 bus->clock_lane = 0; in v4l2_fwnode_endpoint_parse_csi2_bus()
231 bus->data_lanes[i] = dfl_data_lane_index + i; in v4l2_fwnode_endpoint_parse_csi2_bus()
233 bus->clock_lane = clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
235 bus->data_lanes[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
240 "lane-polarities", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
244 bus->lane_polarities[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
245 pr_debug("lane %u polarity %sinverted", in v4l2_fwnode_endpoint_parse_csi2_bus()
249 pr_debug("no lane polarities defined, assuming not inverted\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
268 struct v4l2_mbus_config_parallel *bus = &vep->bus.parallel; in v4l2_fwnode_endpoint_parse_parallel_bus()
273 flags = bus->flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
275 if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
280 pr_debug("hsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
283 if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
288 pr_debug("vsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
291 if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
296 pr_debug("field-even-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
299 if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
304 pr_debug("pclk-sample %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
307 if (!fwnode_property_read_u32(fwnode, "data-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
312 pr_debug("data-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
315 if (fwnode_property_present(fwnode, "slave-mode")) { in v4l2_fwnode_endpoint_parse_parallel_bus()
324 if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
325 bus->bus_width = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
326 pr_debug("bus-width %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
329 if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
330 bus->data_shift = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
331 pr_debug("data-shift %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
334 if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
339 pr_debug("sync-on-green-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
342 if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
347 pr_debug("data-enable-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
352 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
354 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
356 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
359 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
360 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
363 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
364 bus->flags = flags & ~PARALLEL_MBUS_FLAGS; in v4l2_fwnode_endpoint_parse_parallel_bus()
374 struct v4l2_mbus_config_mipi_csi1 *bus = &vep->bus.mipi_csi1; in v4l2_fwnode_endpoint_parse_csi1_bus()
377 if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
378 bus->clock_inv = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
379 pr_debug("clock-inv %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
383 bus->strobe = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
387 if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
388 bus->data_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
389 pr_debug("data-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
392 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
393 bus->clock_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
394 pr_debug("clock-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
398 vep->bus_type = V4L2_MBUS_CCP2; in v4l2_fwnode_endpoint_parse_csi1_bus()
400 vep->bus_type = V4L2_MBUS_CSI1; in v4l2_fwnode_endpoint_parse_csi1_bus()
412 fwnode_property_read_u32(fwnode, "bus-type", &bus_type); in __v4l2_fwnode_endpoint_parse()
415 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
416 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
420 return -EINVAL; in __v4l2_fwnode_endpoint_parse()
423 if (vep->bus_type != V4L2_MBUS_UNKNOWN) { in __v4l2_fwnode_endpoint_parse()
425 vep->bus_type != mbus_type) { in __v4l2_fwnode_endpoint_parse()
427 v4l2_fwnode_mbus_type_to_string(vep->bus_type)); in __v4l2_fwnode_endpoint_parse()
428 return -ENXIO; in __v4l2_fwnode_endpoint_parse()
431 vep->bus_type = mbus_type; in __v4l2_fwnode_endpoint_parse()
434 switch (vep->bus_type) { in __v4l2_fwnode_endpoint_parse()
441 if (vep->bus_type == V4L2_MBUS_UNKNOWN) in __v4l2_fwnode_endpoint_parse()
446 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
447 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
452 v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, vep->bus_type); in __v4l2_fwnode_endpoint_parse()
458 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
466 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
471 return -EINVAL; in __v4l2_fwnode_endpoint_parse()
474 fwnode_graph_parse_endpoint(fwnode, &vep->base); in __v4l2_fwnode_endpoint_parse()
497 kfree(vep->link_frequencies); in v4l2_fwnode_endpoint_free()
498 vep->link_frequencies = NULL; in v4l2_fwnode_endpoint_free()
511 rval = fwnode_property_count_u64(fwnode, "link-frequencies"); in v4l2_fwnode_endpoint_alloc_parse()
515 vep->link_frequencies = in v4l2_fwnode_endpoint_alloc_parse()
516 kmalloc_array(rval, sizeof(*vep->link_frequencies), in v4l2_fwnode_endpoint_alloc_parse()
518 if (!vep->link_frequencies) in v4l2_fwnode_endpoint_alloc_parse()
519 return -ENOMEM; in v4l2_fwnode_endpoint_alloc_parse()
521 vep->nr_of_link_frequencies = rval; in v4l2_fwnode_endpoint_alloc_parse()
524 "link-frequencies", in v4l2_fwnode_endpoint_alloc_parse()
525 vep->link_frequencies, in v4l2_fwnode_endpoint_alloc_parse()
526 vep->nr_of_link_frequencies); in v4l2_fwnode_endpoint_alloc_parse()
532 for (i = 0; i < vep->nr_of_link_frequencies; i++) in v4l2_fwnode_endpoint_alloc_parse()
533 pr_debug("link-frequencies %u value %llu\n", i, in v4l2_fwnode_endpoint_alloc_parse()
534 vep->link_frequencies[i]); in v4l2_fwnode_endpoint_alloc_parse()
551 link->local_id = fwep.id; in v4l2_fwnode_parse_link()
552 link->local_port = fwep.port; in v4l2_fwnode_parse_link()
553 link->local_node = fwnode_graph_get_port_parent(fwnode); in v4l2_fwnode_parse_link()
558 return -ENOLINK; in v4l2_fwnode_parse_link()
562 link->remote_id = fwep.id; in v4l2_fwnode_parse_link()
563 link->remote_port = fwep.port; in v4l2_fwnode_parse_link()
564 link->remote_node = fwnode_graph_get_port_parent(fwnode); in v4l2_fwnode_parse_link()
572 fwnode_handle_put(link->local_node); in v4l2_fwnode_put_link()
573 fwnode_handle_put(link->remote_node); in v4l2_fwnode_put_link()
583 .compatible = "composite-video-connector",
586 .compatible = "svideo-connector",
609 ret = fwnode_property_read_u32(fwnode, "sdtv-standards", &stds); in v4l2_fwnode_connector_parse_analog()
612 vc->connector.analog.sdtv_stds = ret ? V4L2_STD_ALL : stds; in v4l2_fwnode_connector_parse_analog()
619 if (IS_ERR_OR_NULL(connector) || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_free()
622 list_for_each_entry_safe(link, tmp, &connector->links, head) { in v4l2_fwnode_connector_free()
623 v4l2_fwnode_put_link(&link->fwnode_link); in v4l2_fwnode_connector_free()
624 list_del(&link->head); in v4l2_fwnode_connector_free()
628 kfree(connector->label); in v4l2_fwnode_connector_free()
629 connector->label = NULL; in v4l2_fwnode_connector_free()
630 connector->type = V4L2_CONN_UNKNOWN; in v4l2_fwnode_connector_free()
643 /* The connector-type is stored within the compatible string. */ in v4l2_fwnode_get_connector_type()
660 return -EINVAL; in v4l2_fwnode_connector_parse()
664 INIT_LIST_HEAD(&connector->links); in v4l2_fwnode_connector_parse()
676 err = -ENOTCONN; in v4l2_fwnode_connector_parse()
680 connector->type = connector_type; in v4l2_fwnode_connector_parse()
681 connector->name = fwnode_get_name(connector_node); in v4l2_fwnode_connector_parse()
683 connector->label = err ? NULL : kstrdup_const(label, GFP_KERNEL); in v4l2_fwnode_connector_parse()
686 switch (connector->type) { in v4l2_fwnode_connector_parse()
710 if (!fwnode || !connector || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_add_link()
711 return -EINVAL; in v4l2_fwnode_connector_add_link()
715 return -ENOTCONN; in v4l2_fwnode_connector_add_link()
719 err = -ENOMEM; in v4l2_fwnode_connector_add_link()
723 err = v4l2_fwnode_parse_link(connector_ep, &link->fwnode_link); in v4l2_fwnode_connector_add_link()
729 list_add(&link->head, &connector->links); in v4l2_fwnode_connector_add_link()
730 connector->nr_of_links++; in v4l2_fwnode_connector_add_link()
751 props->orientation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
761 return -EINVAL; in v4l2_fwnode_device_parse()
764 props->orientation = val; in v4l2_fwnode_device_parse()
768 props->rotation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
773 return -EINVAL; in v4l2_fwnode_device_parse()
776 props->rotation = val; in v4l2_fwnode_device_parse()
797 return -ENOMEM; in v4l2_async_nf_fwnode_parse_endpoint()
799 asd->match_type = V4L2_ASYNC_MATCH_FWNODE; in v4l2_async_nf_fwnode_parse_endpoint()
800 asd->match.fwnode = in v4l2_async_nf_fwnode_parse_endpoint()
802 if (!asd->match.fwnode) { in v4l2_async_nf_fwnode_parse_endpoint()
804 ret = -ENOTCONN; in v4l2_async_nf_fwnode_parse_endpoint()
816 if (ret == -ENOTCONN) in v4l2_async_nf_fwnode_parse_endpoint()
830 if (ret == -EEXIST) in v4l2_async_nf_fwnode_parse_endpoint()
838 fwnode_handle_put(asd->match.fwnode); in v4l2_async_nf_fwnode_parse_endpoint()
841 return ret == -ENOTCONN ? 0 : ret; in v4l2_async_nf_fwnode_parse_endpoint()
854 return -EINVAL; in v4l2_async_nf_parse_fwnode_endpoints()
882 * v4l2_fwnode_reference_parse - parse references for async sub-devices
888 * -ENOENT if no entries were found
889 * -ENOMEM if memory allocation failed
890 * -EINVAL if property parsing failed
911 if (PTR_ERR(asd) == -EEXIST) in v4l2_fwnode_reference_parse()
918 /* -ENOENT here means successful parsing */ in v4l2_fwnode_reference_parse()
919 if (ret != -ENOENT) in v4l2_fwnode_reference_parse()
922 /* Return -ENOENT if no references were found */ in v4l2_fwnode_reference_parse()
923 return index ? 0 : -ENOENT; in v4l2_fwnode_reference_parse()
927 * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
957 * Documentation/firmware-guide/acpi/dsd/ instead and especially graph.txt,
958 * data-node-references.txt and leds.txt .
965 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
972 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
978 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
982 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
988 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
992 * "remote-endpoint",
1007 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
1014 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1018 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
1025 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1029 * "remote-endpoint",
1044 * @prop: "remote-endpoint"
1063 * remote-endpoint = <&isp 4 0>;
1074 * remote-endpoint = <&cam 0 0>;
1081 * -ENOENT if no entries (or the property itself) were found
1082 * -EINVAL if property parsing otherwise failed
1083 * -ENOMEM if memory allocation failed
1100 * Note that right now both -ENODATA and -ENOENT may signal in v4l2_fwnode_reference_get_int_prop()
1101 * out-of-bounds access. Return -ENOENT in that case. in v4l2_fwnode_reference_get_int_prop()
1106 return ERR_PTR(ret == -ENODATA ? -ENOENT : ret); in v4l2_fwnode_reference_get_int_prop()
1113 while (nprops--) { in v4l2_fwnode_reference_get_int_prop()
1130 fwnode = ERR_PTR(-ENOENT); in v4l2_fwnode_reference_get_int_prop()
1149 * v4l2_fwnode_reference_parse_int_props - parse references for async
1150 * sub-devices
1159 * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
1167 * -ENOENT if no entries (or the property itself) were found
1168 * -EINVAL if property parsing otherwisefailed
1169 * -ENOMEM if memory allocation failed
1179 const char *prop = p->name; in v4l2_fwnode_reference_parse_int_props()
1180 const char * const *props = p->props; in v4l2_fwnode_reference_parse_int_props()
1181 unsigned int nprops = p->nprops; in v4l2_fwnode_reference_parse_int_props()
1190 * Note that right now both -ENODATA and -ENOENT may in v4l2_fwnode_reference_parse_int_props()
1191 * signal out-of-bounds access. Return the error in in v4l2_fwnode_reference_parse_int_props()
1194 if (PTR_ERR(fwnode) != -ENOENT && in v4l2_fwnode_reference_parse_int_props()
1195 PTR_ERR(fwnode) != -ENODATA) in v4l2_fwnode_reference_parse_int_props()
1217 if (ret == -EEXIST) in v4l2_fwnode_reference_parse_int_props()
1224 return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); in v4l2_fwnode_reference_parse_int_props()
1228 * v4l2_async_nf_parse_fwnode_sensor - parse common references on
1229 * sensors for async sub-devices
1234 * sensor and set up async sub-devices for them.
1238 * sub-devices are no longer in use, even in the case the function returned an
1242 * -ENOMEM if memory allocation failed
1243 * -EINVAL if property parsing failed
1251 { "flash-leds", led_props, ARRAY_SIZE(led_props) }, in v4l2_async_nf_parse_fwnode_sensor()
1252 { "lens-focus", NULL, 0 }, in v4l2_async_nf_parse_fwnode_sensor()
1266 if (ret && ret != -ENOENT) { in v4l2_async_nf_parse_fwnode_sensor()
1281 if (WARN_ON(!sd->dev)) in v4l2_async_register_subdev_sensor()
1282 return -ENODEV; in v4l2_async_register_subdev_sensor()
1286 return -ENOMEM; in v4l2_async_register_subdev_sensor()
1290 ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier); in v4l2_async_register_subdev_sensor()
1302 sd->subdev_notifier = notifier; in v4l2_async_register_subdev_sensor()