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 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi2_bus()
202 pr_debug("clock lane position %u\n", v); in v4l2_fwnode_endpoint_parse_csi2_bus()
208 pr_warn("duplicated lane %u in clock-lanes, using defaults\n", in v4l2_fwnode_endpoint_parse_csi2_bus()
213 if (fwnode_property_present(fwnode, "clock-noncontinuous")) { in v4l2_fwnode_endpoint_parse_csi2_bus()
215 pr_debug("non-continuous clock\n"); in v4l2_fwnode_endpoint_parse_csi2_bus()
221 /* Only D-PHY has a clock lane. */ in v4l2_fwnode_endpoint_parse_csi2_bus()
225 bus->flags = flags; in v4l2_fwnode_endpoint_parse_csi2_bus()
227 vep->bus_type = V4L2_MBUS_CSI2_DPHY; in v4l2_fwnode_endpoint_parse_csi2_bus()
228 bus->num_data_lanes = num_data_lanes; in v4l2_fwnode_endpoint_parse_csi2_bus()
231 bus->clock_lane = 0; in v4l2_fwnode_endpoint_parse_csi2_bus()
233 bus->data_lanes[i] = dfl_data_lane_index + i; in v4l2_fwnode_endpoint_parse_csi2_bus()
235 bus->clock_lane = clock_lane; in v4l2_fwnode_endpoint_parse_csi2_bus()
237 bus->data_lanes[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
242 "lane-polarities", array, in v4l2_fwnode_endpoint_parse_csi2_bus()
246 bus->lane_polarities[i] = array[i]; in v4l2_fwnode_endpoint_parse_csi2_bus()
270 struct v4l2_mbus_config_parallel *bus = &vep->bus.parallel; in v4l2_fwnode_endpoint_parse_parallel_bus()
275 flags = bus->flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
277 if (!fwnode_property_read_u32(fwnode, "hsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
282 pr_debug("hsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
285 if (!fwnode_property_read_u32(fwnode, "vsync-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
290 pr_debug("vsync-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
293 if (!fwnode_property_read_u32(fwnode, "field-even-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
298 pr_debug("field-even-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
301 if (!fwnode_property_read_u32(fwnode, "pclk-sample", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
308 pr_debug("pclk-sample low\n"); in v4l2_fwnode_endpoint_parse_parallel_bus()
312 pr_debug("pclk-sample high\n"); in v4l2_fwnode_endpoint_parse_parallel_bus()
316 pr_debug("pclk-sample dual edge\n"); in v4l2_fwnode_endpoint_parse_parallel_bus()
319 pr_warn("invalid argument for pclk-sample"); in v4l2_fwnode_endpoint_parse_parallel_bus()
324 if (!fwnode_property_read_u32(fwnode, "data-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
329 pr_debug("data-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
332 if (fwnode_property_present(fwnode, "slave-mode")) { in v4l2_fwnode_endpoint_parse_parallel_bus()
341 if (!fwnode_property_read_u32(fwnode, "bus-width", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
342 bus->bus_width = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
343 pr_debug("bus-width %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
346 if (!fwnode_property_read_u32(fwnode, "data-shift", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
347 bus->data_shift = v; in v4l2_fwnode_endpoint_parse_parallel_bus()
348 pr_debug("data-shift %u\n", v); in v4l2_fwnode_endpoint_parse_parallel_bus()
351 if (!fwnode_property_read_u32(fwnode, "sync-on-green-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
356 pr_debug("sync-on-green-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
359 if (!fwnode_property_read_u32(fwnode, "data-enable-active", &v)) { in v4l2_fwnode_endpoint_parse_parallel_bus()
364 pr_debug("data-enable-active %s\n", v ? "high" : "low"); in v4l2_fwnode_endpoint_parse_parallel_bus()
369 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
371 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
373 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
376 vep->bus_type = V4L2_MBUS_PARALLEL; in v4l2_fwnode_endpoint_parse_parallel_bus()
377 bus->flags = flags; in v4l2_fwnode_endpoint_parse_parallel_bus()
380 vep->bus_type = V4L2_MBUS_BT656; in v4l2_fwnode_endpoint_parse_parallel_bus()
381 bus->flags = flags & ~PARALLEL_MBUS_FLAGS; in v4l2_fwnode_endpoint_parse_parallel_bus()
391 struct v4l2_mbus_config_mipi_csi1 *bus = &vep->bus.mipi_csi1; in v4l2_fwnode_endpoint_parse_csi1_bus()
394 if (!fwnode_property_read_u32(fwnode, "clock-inv", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
395 bus->clock_inv = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
396 pr_debug("clock-inv %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
400 bus->strobe = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
404 if (!fwnode_property_read_u32(fwnode, "data-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
405 bus->data_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
406 pr_debug("data-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
409 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { in v4l2_fwnode_endpoint_parse_csi1_bus()
410 bus->clock_lane = v; in v4l2_fwnode_endpoint_parse_csi1_bus()
411 pr_debug("clock-lanes %u\n", v); in v4l2_fwnode_endpoint_parse_csi1_bus()
415 vep->bus_type = V4L2_MBUS_CCP2; in v4l2_fwnode_endpoint_parse_csi1_bus()
417 vep->bus_type = V4L2_MBUS_CSI1; in v4l2_fwnode_endpoint_parse_csi1_bus()
429 fwnode_property_read_u32(fwnode, "bus-type", &bus_type); in __v4l2_fwnode_endpoint_parse()
432 v4l2_fwnode_mbus_type_to_string(vep->bus_type), in __v4l2_fwnode_endpoint_parse()
433 vep->bus_type); in __v4l2_fwnode_endpoint_parse()
437 return -EINVAL; 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()
571 if (!link->local_node) in v4l2_fwnode_parse_link()
572 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()
582 if (!link->remote_node) in v4l2_fwnode_parse_link()
591 fwnode_handle_put(link->local_node); in v4l2_fwnode_parse_link()
593 return -ENOLINK; in v4l2_fwnode_parse_link()
599 fwnode_handle_put(link->local_node); in v4l2_fwnode_put_link()
600 fwnode_handle_put(link->remote_node); in v4l2_fwnode_put_link()
610 .compatible = "composite-video-connector",
613 .compatible = "svideo-connector",
636 ret = fwnode_property_read_u32(fwnode, "sdtv-standards", &stds); in v4l2_fwnode_connector_parse_analog()
639 vc->connector.analog.sdtv_stds = ret ? V4L2_STD_ALL : stds; in v4l2_fwnode_connector_parse_analog()
646 if (IS_ERR_OR_NULL(connector) || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_free()
649 list_for_each_entry_safe(link, tmp, &connector->links, head) { in v4l2_fwnode_connector_free()
650 v4l2_fwnode_put_link(&link->fwnode_link); in v4l2_fwnode_connector_free()
651 list_del(&link->head); in v4l2_fwnode_connector_free()
655 kfree(connector->label); in v4l2_fwnode_connector_free()
656 connector->label = NULL; in v4l2_fwnode_connector_free()
657 connector->type = V4L2_CONN_UNKNOWN; in v4l2_fwnode_connector_free()
670 /* The connector-type is stored within the compatible string. */ in v4l2_fwnode_get_connector_type()
687 return -EINVAL; in v4l2_fwnode_connector_parse()
691 INIT_LIST_HEAD(&connector->links); in v4l2_fwnode_connector_parse()
703 err = -ENOTCONN; in v4l2_fwnode_connector_parse()
707 connector->type = connector_type; in v4l2_fwnode_connector_parse()
708 connector->name = fwnode_get_name(connector_node); in v4l2_fwnode_connector_parse()
710 connector->label = err ? NULL : kstrdup_const(label, GFP_KERNEL); in v4l2_fwnode_connector_parse()
713 switch (connector->type) { in v4l2_fwnode_connector_parse()
737 if (!fwnode || !connector || connector->type == V4L2_CONN_UNKNOWN) in v4l2_fwnode_connector_add_link()
738 return -EINVAL; in v4l2_fwnode_connector_add_link()
742 return -ENOTCONN; in v4l2_fwnode_connector_add_link()
746 err = -ENOMEM; in v4l2_fwnode_connector_add_link()
750 err = v4l2_fwnode_parse_link(connector_ep, &link->fwnode_link); in v4l2_fwnode_connector_add_link()
756 list_add(&link->head, &connector->links); in v4l2_fwnode_connector_add_link()
757 connector->nr_of_links++; in v4l2_fwnode_connector_add_link()
778 props->orientation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
788 return -EINVAL; in v4l2_fwnode_device_parse()
791 props->orientation = val; in v4l2_fwnode_device_parse()
795 props->rotation = V4L2_FWNODE_PROPERTY_UNSET; in v4l2_fwnode_device_parse()
800 return -EINVAL; in v4l2_fwnode_device_parse()
803 props->rotation = val; in v4l2_fwnode_device_parse()
812 * v4l2_fwnode_reference_parse - parse references for async sub-devices
818 * -ENOENT if no entries were found
819 * -ENOMEM if memory allocation failed
820 * -EINVAL if property parsing failed
841 if (PTR_ERR(asd) == -EEXIST) in v4l2_fwnode_reference_parse()
848 /* -ENOENT here means successful parsing */ in v4l2_fwnode_reference_parse()
849 if (ret != -ENOENT) in v4l2_fwnode_reference_parse()
852 /* Return -ENOENT if no references were found */ in v4l2_fwnode_reference_parse()
853 return index ? 0 : -ENOENT; in v4l2_fwnode_reference_parse()
857 * v4l2_fwnode_reference_get_int_prop - parse a reference with integer
887 * Documentation/firmware-guide/acpi/dsd/ instead and especially graph.txt,
888 * data-node-references.txt and leds.txt .
895 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
902 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
908 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
912 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
918 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
922 * "remote-endpoint",
937 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
944 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
948 * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
955 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
959 * "remote-endpoint",
974 * @prop: "remote-endpoint"
993 * remote-endpoint = <&isp 4 0>;
1004 * remote-endpoint = <&cam 0 0>;
1011 * -ENOENT if no entries (or the property itself) were found
1012 * -EINVAL if property parsing otherwise failed
1013 * -ENOMEM if memory allocation failed
1030 * Note that right now both -ENODATA and -ENOENT may signal in v4l2_fwnode_reference_get_int_prop()
1031 * out-of-bounds access. Return -ENOENT in that case. in v4l2_fwnode_reference_get_int_prop()
1036 return ERR_PTR(ret == -ENODATA ? -ENOENT : ret); in v4l2_fwnode_reference_get_int_prop()
1043 while (nprops--) { in v4l2_fwnode_reference_get_int_prop()
1060 fwnode = ERR_PTR(-ENOENT); in v4l2_fwnode_reference_get_int_prop()
1079 * v4l2_fwnode_reference_parse_int_props - parse references for async
1080 * sub-devices
1089 * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier
1097 * -ENOENT if no entries (or the property itself) were found
1098 * -EINVAL if property parsing otherwisefailed
1099 * -ENOMEM if memory allocation failed
1109 const char *prop = p->name; in v4l2_fwnode_reference_parse_int_props()
1110 const char * const *props = p->props; in v4l2_fwnode_reference_parse_int_props()
1111 unsigned int nprops = p->nprops; in v4l2_fwnode_reference_parse_int_props()
1120 * Note that right now both -ENODATA and -ENOENT may in v4l2_fwnode_reference_parse_int_props()
1121 * signal out-of-bounds access. Return the error in in v4l2_fwnode_reference_parse_int_props()
1124 if (PTR_ERR(fwnode) != -ENOENT && in v4l2_fwnode_reference_parse_int_props()
1125 PTR_ERR(fwnode) != -ENODATA) in v4l2_fwnode_reference_parse_int_props()
1147 if (ret == -EEXIST) in v4l2_fwnode_reference_parse_int_props()
1154 return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); in v4l2_fwnode_reference_parse_int_props()
1158 * v4l2_async_nf_parse_fwnode_sensor - parse common references on
1159 * sensors for async sub-devices
1164 * sensor and set up async sub-devices for them.
1168 * sub-devices are no longer in use, even in the case the function returned an
1172 * -ENOMEM if memory allocation failed
1173 * -EINVAL if property parsing failed
1181 { "flash-leds", led_props, ARRAY_SIZE(led_props) }, in v4l2_async_nf_parse_fwnode_sensor()
1182 { "mipi-img-flash-leds", }, in v4l2_async_nf_parse_fwnode_sensor()
1183 { "lens-focus", }, in v4l2_async_nf_parse_fwnode_sensor()
1184 { "mipi-img-lens-focus", }, in v4l2_async_nf_parse_fwnode_sensor()
1198 if (ret && ret != -ENOENT) { in v4l2_async_nf_parse_fwnode_sensor()
1213 if (WARN_ON(!sd->dev)) in v4l2_async_register_subdev_sensor()
1214 return -ENODEV; in v4l2_async_register_subdev_sensor()
1218 return -ENOMEM; in v4l2_async_register_subdev_sensor()
1226 ret = v4l2_async_nf_parse_fwnode_sensor(sd->dev, notifier); in v4l2_async_register_subdev_sensor()
1238 sd->subdev_notifier = notifier; in v4l2_async_register_subdev_sensor()