Lines Matching +full:clock +full:- +full:noncontinuous
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>
31 #include "v4l2-subdev-priv.h"
45 "MIPI CSI-2 C-PHY",
49 "MIPI CSI-1",
57 "MIPI CSI-2 D-PHY",
91 return conv ? conv->mbus_type : V4L2_MBUS_INVALID; in v4l2_fwnode_bus_type_to_mbus()
100 return conv ? conv->name : "not found"; in v4l2_fwnode_bus_type_to_string()
121 return conv ? conv->name : "not found"; in v4l2_fwnode_mbus_type_to_string()
128 struct v4l2_mbus_config_mipi_csi2 *bus = &vep->bus.mipi_csi2; in v4l2_fwnode_endpoint_parse_csi2_bus()
144 num_data_lanes = min_t(u32, bus->num_data_lanes, in v4l2_fwnode_endpoint_parse_csi2_bus()
147 clock_lane = bus->clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
152 array[i] = bus->data_lanes[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
161 rval = fwnode_property_count_u32(fwnode, "data-lanes"); in v4l2_fwnode_endpoint_parse_csi2_bus()
166 fwnode_property_read_u32_array(fwnode, "data-lanes", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
171 pr_debug("data-lanes property exists; disabling default mapping\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
179 pr_warn("duplicated lane %u in data-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
189 rval = fwnode_property_count_u32(fwnode, "lane-polarities"); in v4l2_fwnode_endpoint_parse_csi2_bus()
191 if (rval != 1 + num_data_lanes /* clock+data */) { in v4l2_fwnode_endpoint_parse_csi2_bus()
192 pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
194 return -EINVAL; in v4l2_fwnode_endpoint_parse_csi2_bus()
200 rval = fwnode_property_count_u32(fwnode, "line-orders"); in v4l2_fwnode_endpoint_parse_csi2_bus()
203 pr_warn("invalid number of line-orders entries (need %u, got %u)\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
205 return -EINVAL; in v4l2_fwnode_endpoint_parse_csi2_bus()
211 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi2_bus()
213 pr_debug("clock lane position %u\n", v); in v4l2_fwnode_endpoint_parse_csi2_bus()
219 pr_warn("duplicated lane %u in clock-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
224 if (fwnode_property_present(fwnode, "clock-noncontinuous")) { in v4l2_fwnode_endpoint_parse_csi2_bus()
226 pr_debug("non-continuous clock\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
232 /* Only D-PHY has a clock lane. */ in v4l2_fwnode_endpoint_parse_csi2_bus()
236 bus->flags = flags; in v4l2_fwnode_endpoint_parse_csi2_bus()
238 vep->bus_type = V4L2_MBUS_CSI2_DPHY; in v4l2_fwnode_endpoint_parse_csi2_bus()
239 bus->num_data_lanes = num_data_lanes; in v4l2_fwnode_endpoint_parse_csi2_bus()
242 bus->clock_lane = 0; in v4l2_fwnode_endpoint_parse_csi2_bus()
244 bus->data_lanes[i] = dfl_data_lane_index + i; in v4l2_fwnode_endpoint_parse_csi2_bus()
246 bus->clock_lane = clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
248 bus->data_lanes[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
253 "lane-polarities", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
257 bus->lane_polarities[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
267 "line-orders", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
276 pr_warn("lane %u invalid line-order assuming ABC (got %u)\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
278 bus->line_orders[i] = in v4l2_fwnode_endpoint_parse_csi2_bus()
283 bus->line_orders[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
289 bus->line_orders[i] = in v4l2_fwnode_endpoint_parse_csi2_bus()
311 struct v4l2_mbus_config_parallel *bus = &vep->bus.parallel; in v4l2_fwnode_endpoint_parse_parallel_bus()
316 flags = bus->flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
318 if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
323 pr_debug("hsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
326 if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
331 pr_debug("vsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
334 if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
339 pr_debug("field-even-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
342 if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
349 pr_debug("pclk-sample low\n"); in v4l2_fwnode_endpoint_parse_parallel_bus()
353 pr_debug("pclk-sample high\n"); in v4l2_fwnode_endpoint_parse_parallel_bus()
357 pr_debug("pclk-sample dual edge\n"); in v4l2_fwnode_endpoint_parse_parallel_bus()
360 pr_warn("invalid argument for pclk-sample"); in v4l2_fwnode_endpoint_parse_parallel_bus()
365 if (!fwnode_property_read_u32(fwnode, "data-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
370 pr_debug("data-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
373 if (fwnode_property_present(fwnode, "slave-mode")) { in v4l2_fwnode_endpoint_parse_parallel_bus()
382 if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
383 bus->bus_width = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
384 pr_debug("bus-width %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
387 if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
388 bus->data_shift = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
389 pr_debug("data-shift %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
392 if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
397 pr_debug("sync-on-green-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
400 if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
405 pr_debug("data-enable-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
410 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
412 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
414 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
417 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
418 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
421 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
422 bus->flags = flags & ~PARALLEL_MBUS_FLAGS; in v4l2_fwnode_endpoint_parse_parallel_bus()
432 struct v4l2_mbus_config_mipi_csi1 *bus = &vep->bus.mipi_csi1; in v4l2_fwnode_endpoint_parse_csi1_bus()
435 if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
436 bus->clock_inv = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
437 pr_debug("clock-inv %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
441 bus->strobe = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
445 if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
446 bus->data_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
447 pr_debug("data-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
450 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
451 bus->clock_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
452 pr_debug("clock-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
456 vep->bus_type = V4L2_MBUS_CCP2; in v4l2_fwnode_endpoint_parse_csi1_bus()
458 vep->bus_type = V4L2_MBUS_CSI1; in v4l2_fwnode_endpoint_parse_csi1_bus()
470 fwnode_property_read_u32(fwnode, "bus-type", &bus_type); in __v4l2_fwnode_endpoint_parse()
473 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
474 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
478 return -EINVAL; in __v4l2_fwnode_endpoint_parse()
481 if (vep->bus_type != V4L2_MBUS_UNKNOWN) { in __v4l2_fwnode_endpoint_parse()
483 vep->bus_type != mbus_type) { in __v4l2_fwnode_endpoint_parse()
485 v4l2_fwnode_mbus_type_to_string(vep->bus_type)); in __v4l2_fwnode_endpoint_parse()
486 return -ENXIO; in __v4l2_fwnode_endpoint_parse()
489 vep->bus_type = mbus_type; in __v4l2_fwnode_endpoint_parse()
492 switch (vep->bus_type) { in __v4l2_fwnode_endpoint_parse()
499 if (vep->bus_type == V4L2_MBUS_UNKNOWN) in __v4l2_fwnode_endpoint_parse()
504 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
505 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
510 v4l2_fwnode_endpoint_parse_csi1_bus(fwnode, vep, vep->bus_type); in __v4l2_fwnode_endpoint_parse()
516 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
524 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
529 return -EINVAL; in __v4l2_fwnode_endpoint_parse()
532 fwnode_graph_parse_endpoint(fwnode, &vep->base); in __v4l2_fwnode_endpoint_parse()
555 kfree(vep->link_frequencies); in v4l2_fwnode_endpoint_free()
556 vep->link_frequencies = NULL; in v4l2_fwnode_endpoint_free()
569 rval = fwnode_property_count_u64(fwnode, "link-frequencies"); in v4l2_fwnode_endpoint_alloc_parse()
573 vep->link_frequencies = in v4l2_fwnode_endpoint_alloc_parse()
574 kmalloc_array(rval, sizeof(*vep->link_frequencies), in v4l2_fwnode_endpoint_alloc_parse()
576 if (!vep->link_frequencies) in v4l2_fwnode_endpoint_alloc_parse()
577 return -ENOMEM; in v4l2_fwnode_endpoint_alloc_parse()
579 vep->nr_of_link_frequencies = rval; in v4l2_fwnode_endpoint_alloc_parse()
582 "link-frequencies", in v4l2_fwnode_endpoint_alloc_parse()
583 vep->link_frequencies, in v4l2_fwnode_endpoint_alloc_parse()
584 vep->nr_of_link_frequencies); in v4l2_fwnode_endpoint_alloc_parse()
590 for (i = 0; i < vep->nr_of_link_frequencies; i++) in v4l2_fwnode_endpoint_alloc_parse()
591 pr_debug("link-frequencies %u value %llu\n", i, in v4l2_fwnode_endpoint_alloc_parse()
592 vep->link_frequencies[i]); in v4l2_fwnode_endpoint_alloc_parse()
609 link->local_id = fwep.id; in v4l2_fwnode_parse_link()
610 link->local_port = fwep.port; in v4l2_fwnode_parse_link()
611 link->local_node = fwnode_graph_get_port_parent(fwnode); in v4l2_fwnode_parse_link()
612 if (!link->local_node) in v4l2_fwnode_parse_link()
613 return -ENOLINK; in v4l2_fwnode_parse_link()
620 link->remote_id = fwep.id; in v4l2_fwnode_parse_link()
621 link->remote_port = fwep.port; in v4l2_fwnode_parse_link()
622 link->remote_node = fwnode_graph_get_port_parent(fwnode); in v4l2_fwnode_parse_link()
623 if (!link->remote_node) in v4l2_fwnode_parse_link()
632 fwnode_handle_put(link->local_node); in v4l2_fwnode_parse_link()
634 return -ENOLINK; in v4l2_fwnode_parse_link()
640 fwnode_handle_put(link->local_node); in v4l2_fwnode_put_link()
641 fwnode_handle_put(link->remote_node); in v4l2_fwnode_put_link()
651 .compatible = "composite-video-connector",
654 .compatible = "svideo-connector",
677 ret = fwnode_property_read_u32(fwnode, "sdtv-standards", &stds); in v4l2_fwnode_connector_parse_analog()
680 vc->connector.analog.sdtv_stds = ret ? V4L2_STD_ALL : stds; in v4l2_fwnode_connector_parse_analog()
687 if (IS_ERR_OR_NULL(connector) || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_free()
690 list_for_each_entry_safe(link, tmp, &connector->links, head) { in v4l2_fwnode_connector_free()
691 v4l2_fwnode_put_link(&link->fwnode_link); in v4l2_fwnode_connector_free()
692 list_del(&link->head); in v4l2_fwnode_connector_free()
696 kfree(connector->label); in v4l2_fwnode_connector_free()
697 connector->label = NULL; in v4l2_fwnode_connector_free()
698 connector->type = V4L2_CONN_UNKNOWN; in v4l2_fwnode_connector_free()
711 /* The connector-type is stored within the compatible string. */ in v4l2_fwnode_get_connector_type()
728 return -EINVAL; in v4l2_fwnode_connector_parse()
732 INIT_LIST_HEAD(&connector->links); in v4l2_fwnode_connector_parse()
744 err = -ENOTCONN; in v4l2_fwnode_connector_parse()
748 connector->type = connector_type; in v4l2_fwnode_connector_parse()
749 connector->name = fwnode_get_name(connector_node); in v4l2_fwnode_connector_parse()
751 connector->label = err ? NULL : kstrdup_const(label, GFP_KERNEL); in v4l2_fwnode_connector_parse()
754 switch (connector->type) { in v4l2_fwnode_connector_parse()
778 if (!fwnode || !connector || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_add_link()
779 return -EINVAL; in v4l2_fwnode_connector_add_link()
783 return -ENOTCONN; in v4l2_fwnode_connector_add_link()
787 err = -ENOMEM; in v4l2_fwnode_connector_add_link()
791 err = v4l2_fwnode_parse_link(connector_ep, &link->fwnode_link); in v4l2_fwnode_connector_add_link()
797 list_add(&link->head, &connector->links); in v4l2_fwnode_connector_add_link()
798 connector->nr_of_links++; in v4l2_fwnode_connector_add_link()
819 props->orientation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
829 return -EINVAL; in v4l2_fwnode_device_parse()
832 props->orientation = val; in v4l2_fwnode_device_parse()
836 props->rotation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
841 return -EINVAL; in v4l2_fwnode_device_parse()
844 props->rotation = val; in v4l2_fwnode_device_parse()
853 * v4l2_fwnode_reference_parse - parse references for async sub-devices
859 * -ENOENT if no entries were found
860 * -ENOMEM if memory allocation failed
861 * -EINVAL if property parsing failed
882 if (PTR_ERR(asd) == -EEXIST) in v4l2_fwnode_reference_parse()
889 /* -ENOENT here means successful parsing */ in v4l2_fwnode_reference_parse()
890 if (ret != -ENOENT) in v4l2_fwnode_reference_parse()
893 /* Return -ENOENT if no references were found */ in v4l2_fwnode_reference_parse()
894 return index ? 0 : -ENOENT; in v4l2_fwnode_reference_parse()
898 * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
928 * Documentation/firmware-guide/acpi/dsd/ instead and especially graph.txt,
929 * data-node-references.txt and leds.txt .
936 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
943 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
949 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
953 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
959 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
963 * "remote-endpoint",
978 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
985 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
989 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
996 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
1000 * "remote-endpoint",
1015 * @prop: "remote-endpoint"
1034 * remote-endpoint = <&isp 4 0>;
1045 * remote-endpoint = <&cam 0 0>;
1052 * -ENOENT if no entries (or the property itself) were found
1053 * -EINVAL if property parsing otherwise failed
1054 * -ENOMEM if memory allocation failed
1071 * Note that right now both -ENODATA and -ENOENT may signal in v4l2_fwnode_reference_get_int_prop()
1072 * out-of-bounds access. Return -ENOENT in that case. in v4l2_fwnode_reference_get_int_prop()
1077 return ERR_PTR(ret == -ENODATA ? -ENOENT : ret); in v4l2_fwnode_reference_get_int_prop()
1084 while (nprops--) { in v4l2_fwnode_reference_get_int_prop()
1101 fwnode = ERR_PTR(-ENOENT); in v4l2_fwnode_reference_get_int_prop()
1120 * v4l2_fwnode_reference_parse_int_props - parse references for async
1121 * sub-devices
1130 * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
1138 * -ENOENT if no entries (or the property itself) were found
1139 * -EINVAL if property parsing otherwisefailed
1140 * -ENOMEM if memory allocation failed
1150 const char *prop = p->name; in v4l2_fwnode_reference_parse_int_props()
1151 const char * const *props = p->props; in v4l2_fwnode_reference_parse_int_props()
1152 unsigned int nprops = p->nprops; in v4l2_fwnode_reference_parse_int_props()
1161 * Note that right now both -ENODATA and -ENOENT may in v4l2_fwnode_reference_parse_int_props()
1162 * signal out-of-bounds access. Return the error in in v4l2_fwnode_reference_parse_int_props()
1165 if (PTR_ERR(fwnode) != -ENOENT && in v4l2_fwnode_reference_parse_int_props()
1166 PTR_ERR(fwnode) != -ENODATA) in v4l2_fwnode_reference_parse_int_props()
1188 if (ret == -EEXIST) in v4l2_fwnode_reference_parse_int_props()
1195 return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); in v4l2_fwnode_reference_parse_int_props()
1199 * v4l2_async_nf_parse_fwnode_sensor - parse common references on
1200 * sensors for async sub-devices
1205 * sensor and set up async sub-devices for them.
1209 * sub-devices are no longer in use, even in the case the function returned an
1213 * -ENOMEM if memory allocation failed
1214 * -EINVAL if property parsing failed
1222 { "flash-leds", led_props, ARRAY_SIZE(led_props) }, in v4l2_async_nf_parse_fwnode_sensor()
1223 { "mipi-img-flash-leds", }, in v4l2_async_nf_parse_fwnode_sensor()
1224 { "lens-focus", }, in v4l2_async_nf_parse_fwnode_sensor()
1225 { "mipi-img-lens-focus", }, in v4l2_async_nf_parse_fwnode_sensor()
1239 if (ret && ret != -ENOENT) { in v4l2_async_nf_parse_fwnode_sensor()
1254 if (WARN_ON(!sd->dev)) in v4l2_async_register_subdev_sensor()
1255 return -ENODEV; in v4l2_async_register_subdev_sensor()
1259 return -ENOMEM; in v4l2_async_register_subdev_sensor()
1267 ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier); in v4l2_async_register_subdev_sensor()
1279 sd->subdev_notifier = notifier; in v4l2_async_register_subdev_sensor()