diff options
-rw-r--r-- | drivers/media/v4l2-core/v4l2-of.c | 41 | ||||
-rw-r--r-- | include/media/v4l2-of.h | 3 |
2 files changed, 35 insertions, 9 deletions
diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c index b4ed9a955fbe..58e401f4893a 100644 --- a/drivers/media/v4l2-core/v4l2-of.c +++ b/drivers/media/v4l2-core/v4l2-of.c | |||
@@ -19,11 +19,10 @@ | |||
19 | 19 | ||
20 | #include <media/v4l2-of.h> | 20 | #include <media/v4l2-of.h> |
21 | 21 | ||
22 | static void v4l2_of_parse_csi_bus(const struct device_node *node, | 22 | static int v4l2_of_parse_csi_bus(const struct device_node *node, |
23 | struct v4l2_of_endpoint *endpoint) | 23 | struct v4l2_of_endpoint *endpoint) |
24 | { | 24 | { |
25 | struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2; | 25 | struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2; |
26 | u32 data_lanes[ARRAY_SIZE(bus->data_lanes)]; | ||
27 | struct property *prop; | 26 | struct property *prop; |
28 | bool have_clk_lane = false; | 27 | bool have_clk_lane = false; |
29 | unsigned int flags = 0; | 28 | unsigned int flags = 0; |
@@ -32,16 +31,34 @@ static void v4l2_of_parse_csi_bus(const struct device_node *node, | |||
32 | prop = of_find_property(node, "data-lanes", NULL); | 31 | prop = of_find_property(node, "data-lanes", NULL); |
33 | if (prop) { | 32 | if (prop) { |
34 | const __be32 *lane = NULL; | 33 | const __be32 *lane = NULL; |
35 | int i; | 34 | unsigned int i; |
36 | 35 | ||
37 | for (i = 0; i < ARRAY_SIZE(data_lanes); i++) { | 36 | for (i = 0; i < ARRAY_SIZE(bus->data_lanes); i++) { |
38 | lane = of_prop_next_u32(prop, lane, &data_lanes[i]); | 37 | lane = of_prop_next_u32(prop, lane, &v); |
39 | if (!lane) | 38 | if (!lane) |
40 | break; | 39 | break; |
40 | bus->data_lanes[i] = v; | ||
41 | } | 41 | } |
42 | bus->num_data_lanes = i; | 42 | bus->num_data_lanes = i; |
43 | while (i--) | 43 | } |
44 | bus->data_lanes[i] = data_lanes[i]; | 44 | |
45 | prop = of_find_property(node, "lane-polarities", NULL); | ||
46 | if (prop) { | ||
47 | const __be32 *polarity = NULL; | ||
48 | unsigned int i; | ||
49 | |||
50 | for (i = 0; i < ARRAY_SIZE(bus->lane_polarities); i++) { | ||
51 | polarity = of_prop_next_u32(prop, polarity, &v); | ||
52 | if (!polarity) | ||
53 | break; | ||
54 | bus->lane_polarities[i] = v; | ||
55 | } | ||
56 | |||
57 | if (i < 1 + bus->num_data_lanes /* clock + data */) { | ||
58 | pr_warn("%s: too few lane-polarities entries (need %u, got %u)\n", | ||
59 | node->full_name, 1 + bus->num_data_lanes, i); | ||
60 | return -EINVAL; | ||
61 | } | ||
45 | } | 62 | } |
46 | 63 | ||
47 | if (!of_property_read_u32(node, "clock-lanes", &v)) { | 64 | if (!of_property_read_u32(node, "clock-lanes", &v)) { |
@@ -56,6 +73,8 @@ static void v4l2_of_parse_csi_bus(const struct device_node *node, | |||
56 | 73 | ||
57 | bus->flags = flags; | 74 | bus->flags = flags; |
58 | endpoint->bus_type = V4L2_MBUS_CSI2; | 75 | endpoint->bus_type = V4L2_MBUS_CSI2; |
76 | |||
77 | return 0; | ||
59 | } | 78 | } |
60 | 79 | ||
61 | static void v4l2_of_parse_parallel_bus(const struct device_node *node, | 80 | static void v4l2_of_parse_parallel_bus(const struct device_node *node, |
@@ -127,11 +146,15 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node, | |||
127 | int v4l2_of_parse_endpoint(const struct device_node *node, | 146 | int v4l2_of_parse_endpoint(const struct device_node *node, |
128 | struct v4l2_of_endpoint *endpoint) | 147 | struct v4l2_of_endpoint *endpoint) |
129 | { | 148 | { |
149 | int rval; | ||
150 | |||
130 | of_graph_parse_endpoint(node, &endpoint->base); | 151 | of_graph_parse_endpoint(node, &endpoint->base); |
131 | endpoint->bus_type = 0; | 152 | endpoint->bus_type = 0; |
132 | memset(&endpoint->bus, 0, sizeof(endpoint->bus)); | 153 | memset(&endpoint->bus, 0, sizeof(endpoint->bus)); |
133 | 154 | ||
134 | v4l2_of_parse_csi_bus(node, endpoint); | 155 | rval = v4l2_of_parse_csi_bus(node, endpoint); |
156 | if (rval) | ||
157 | return rval; | ||
135 | /* | 158 | /* |
136 | * Parse the parallel video bus properties only if none | 159 | * Parse the parallel video bus properties only if none |
137 | * of the MIPI CSI-2 specific properties were found. | 160 | * of the MIPI CSI-2 specific properties were found. |
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h index 70fa7b7b0487..2de42c584eb2 100644 --- a/include/media/v4l2-of.h +++ b/include/media/v4l2-of.h | |||
@@ -29,12 +29,15 @@ struct device_node; | |||
29 | * @data_lanes: an array of physical data lane indexes | 29 | * @data_lanes: an array of physical data lane indexes |
30 | * @clock_lane: physical lane index of the clock lane | 30 | * @clock_lane: physical lane index of the clock lane |
31 | * @num_data_lanes: number of data lanes | 31 | * @num_data_lanes: number of data lanes |
32 | * @lane_polarities: polarity of the lanes. The order is the same of | ||
33 | * the physical lanes. | ||
32 | */ | 34 | */ |
33 | struct v4l2_of_bus_mipi_csi2 { | 35 | struct v4l2_of_bus_mipi_csi2 { |
34 | unsigned int flags; | 36 | unsigned int flags; |
35 | unsigned char data_lanes[4]; | 37 | unsigned char data_lanes[4]; |
36 | unsigned char clock_lane; | 38 | unsigned char clock_lane; |
37 | unsigned short num_data_lanes; | 39 | unsigned short num_data_lanes; |
40 | bool lane_polarities[5]; | ||
38 | }; | 41 | }; |
39 | 42 | ||
40 | /** | 43 | /** |