]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/media/v4l2-core/v4l2-of.c
570746853b4923a895df04a1b7d0d546b52e2305
[sojka/nv-tegra/linux-3.10.git] / drivers / media / v4l2-core / v4l2-of.c
1 /*
2  * V4L2 OF binding parsing library
3  *
4  * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
5  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
6  *
7  * Copyright (C) 2012 Renesas Electronics Corp.
8  * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of version 2 of the GNU General Public License as
12  * published by the Free Software Foundation.
13  */
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/slab.h>
18 #include <linux/string.h>
19 #include <linux/types.h>
20 #include <linux/err.h>
21
22 #include <media/v4l2-of.h>
23
24 static int v4l2_of_parse_csi_bus(const struct device_node *node,
25                                  struct v4l2_of_endpoint *endpoint)
26 {
27         struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2;
28         struct property *prop;
29         bool have_clk_lane = false;
30         unsigned int flags = 0;
31         u32 v;
32
33         prop = of_find_property(node, "data-lanes", NULL);
34         if (prop) {
35                 const __be32 *lane = NULL;
36                 unsigned int i;
37
38                 for (i = 0; i < ARRAY_SIZE(bus->data_lanes); i++) {
39                         lane = of_prop_next_u32(prop, lane, &v);
40                         if (!lane)
41                                 break;
42                         bus->data_lanes[i] = v;
43                 }
44                 bus->num_data_lanes = i;
45         }
46
47         prop = of_find_property(node, "lane-polarities", NULL);
48         if (prop) {
49                 const __be32 *polarity = NULL;
50                 unsigned int i;
51
52                 for (i = 0; i < ARRAY_SIZE(bus->lane_polarities); i++) {
53                         polarity = of_prop_next_u32(prop, polarity, &v);
54                         if (!polarity)
55                                 break;
56                         bus->lane_polarities[i] = v;
57                 }
58
59                 if (i < 1 + bus->num_data_lanes /* clock + data */) {
60                         pr_warn("%s: too few lane-polarities entries (need %u, got %u)\n",
61                                 node->full_name, 1 + bus->num_data_lanes, i);
62                         return -EINVAL;
63                 }
64         }
65
66         if (!of_property_read_u32(node, "clock-lanes", &v)) {
67                 bus->clock_lane = v;
68                 have_clk_lane = true;
69         }
70
71         if (of_get_property(node, "clock-noncontinuous", &v))
72                 flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
73         else if (have_clk_lane || bus->num_data_lanes > 0)
74                 flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
75
76         bus->flags = flags;
77         endpoint->bus_type = V4L2_MBUS_CSI2;
78
79         return 0;
80 }
81
82 static void v4l2_of_parse_parallel_bus(const struct device_node *node,
83                                        struct v4l2_of_endpoint *endpoint)
84 {
85         struct v4l2_of_bus_parallel *bus = &endpoint->bus.parallel;
86         unsigned int flags = 0;
87         u32 v;
88
89         if (!of_property_read_u32(node, "hsync-active", &v))
90                 flags |= v ? V4L2_MBUS_HSYNC_ACTIVE_HIGH :
91                         V4L2_MBUS_HSYNC_ACTIVE_LOW;
92
93         if (!of_property_read_u32(node, "vsync-active", &v))
94                 flags |= v ? V4L2_MBUS_VSYNC_ACTIVE_HIGH :
95                         V4L2_MBUS_VSYNC_ACTIVE_LOW;
96
97         if (!of_property_read_u32(node, "field-even-active", &v))
98                 flags |= v ? V4L2_MBUS_FIELD_EVEN_HIGH :
99                         V4L2_MBUS_FIELD_EVEN_LOW;
100         if (flags)
101                 endpoint->bus_type = V4L2_MBUS_PARALLEL;
102         else
103                 endpoint->bus_type = V4L2_MBUS_BT656;
104
105         if (!of_property_read_u32(node, "pclk-sample", &v))
106                 flags |= v ? V4L2_MBUS_PCLK_SAMPLE_RISING :
107                         V4L2_MBUS_PCLK_SAMPLE_FALLING;
108
109         if (!of_property_read_u32(node, "data-active", &v))
110                 flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
111                         V4L2_MBUS_DATA_ACTIVE_LOW;
112
113         if (of_get_property(node, "slave-mode", &v))
114                 flags |= V4L2_MBUS_SLAVE;
115         else
116                 flags |= V4L2_MBUS_MASTER;
117
118         if (!of_property_read_u32(node, "bus-width", &v))
119                 bus->bus_width = v;
120
121         if (!of_property_read_u32(node, "data-shift", &v))
122                 bus->data_shift = v;
123
124         if (!of_property_read_u32(node, "sync-on-green-active", &v))
125                 flags |= v ? V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH :
126                         V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW;
127
128         bus->flags = flags;
129
130 }
131
132 /**
133  * v4l2_of_parse_endpoint() - parse all endpoint node properties
134  * @node: pointer to endpoint device_node
135  * @endpoint: pointer to the V4L2 OF endpoint data structure
136  *
137  * All properties are optional. If none are found, we don't set any flags.
138  * This means the port has a static configuration and no properties have
139  * to be specified explicitly.
140  * If any properties that identify the bus as parallel are found and
141  * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
142  * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
143  * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
144  * The caller should hold a reference to @node.
145  *
146  * NOTE: This function does not parse properties the size of which is
147  * variable without a low fixed limit. Please use
148  * v4l2_of_alloc_parse_endpoint() in new drivers instead.
149  *
150  * Return: 0.
151  */
152 int v4l2_of_parse_endpoint(const struct device_node *node,
153                            struct v4l2_of_endpoint *endpoint)
154 {
155         int rval;
156
157         of_graph_parse_endpoint(node, &endpoint->base);
158         /* Zero fields from bus_type to until the end */
159         memset(&endpoint->bus_type, 0, sizeof(*endpoint) -
160                offsetof(typeof(*endpoint), bus_type));
161
162         rval = v4l2_of_parse_csi_bus(node, endpoint);
163         if (rval)
164                 return rval;
165         /*
166          * Parse the parallel video bus properties only if none
167          * of the MIPI CSI-2 specific properties were found.
168          */
169         if (endpoint->bus.mipi_csi2.flags == 0)
170                 v4l2_of_parse_parallel_bus(node, endpoint);
171
172         return 0;
173 }
174 EXPORT_SYMBOL(v4l2_of_parse_endpoint);
175
176 /*
177  * v4l2_of_free_endpoint() - free the endpoint acquired by
178  * v4l2_of_alloc_parse_endpoint()
179  * @endpoint - the endpoint the resources of which are to be released
180  *
181  * It is safe to call this function with NULL argument or on an
182  * endpoint the parsing of which failed.
183  */
184 void v4l2_of_free_endpoint(struct v4l2_of_endpoint *endpoint)
185 {
186         if (!endpoint)
187                 return;
188
189         kfree(endpoint->link_frequencies);
190         kfree(endpoint);
191 }
192 EXPORT_SYMBOL(v4l2_of_free_endpoint);
193
194 /**
195  * v4l2_of_alloc_parse_endpoint() - parse all endpoint node properties
196  * @node: pointer to endpoint device_node
197  *
198  * All properties are optional. If none are found, we don't set any flags.
199  * This means the port has a static configuration and no properties have
200  * to be specified explicitly.
201  * If any properties that identify the bus as parallel are found and
202  * slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if we recognise
203  * the bus as serial CSI-2 and clock-noncontinuous isn't set, we set the
204  * V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag.
205  * The caller should hold a reference to @node.
206  *
207  * v4l2_of_alloc_parse_endpoint() has two important differences to
208  * v4l2_of_parse_endpoint():
209  *
210  * 1. It also parses variable size data and
211  *
212  * 2. The memory it has allocated to store the variable size data must
213  *    be freed using v4l2_of_free_endpoint() when no longer needed.
214  *
215  * Return: Pointer to v4l2_of_endpoint if successful, on error a
216  * negative error code.
217  */
218 struct v4l2_of_endpoint *v4l2_of_alloc_parse_endpoint(
219         const struct device_node *node)
220 {
221         struct v4l2_of_endpoint *endpoint;
222         int len;
223         int rval;
224
225         endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
226         if (!endpoint)
227                 return -ENOMEM;
228
229         rval = v4l2_of_parse_endpoint(node, endpoint);
230         if (rval < 0)
231                 goto out_err;
232
233         if (of_get_property(node, "link-frequencies", &len)) {
234                 endpoint->link_frequencies = kmalloc(len, GFP_KERNEL);
235                 if (!endpoint->link_frequencies) {
236                         rval = -ENOMEM;
237                         goto out_err;
238                 }
239
240                 endpoint->nr_of_link_frequencies =
241                         len / sizeof(*endpoint->link_frequencies);
242
243                 rval = of_property_read_u64_array(
244                         node, "link-frequencies", endpoint->link_frequencies,
245                         endpoint->nr_of_link_frequencies);
246                 if (rval < 0)
247                         goto out_err;
248         }
249
250         return endpoint;
251
252 out_err:
253         v4l2_of_free_endpoint(endpoint);
254         return rval;
255 }
256 EXPORT_SYMBOL(v4l2_of_alloc_parse_endpoint);
257
258 /**
259  * v4l2_of_parse_link() - parse a link between two endpoints
260  * @node: pointer to the endpoint at the local end of the link
261  * @link: pointer to the V4L2 OF link data structure
262  *
263  * Fill the link structure with the local and remote nodes and port numbers.
264  * The local_node and remote_node fields are set to point to the local and
265  * remote port's parent nodes respectively (the port parent node being the
266  * parent node of the port node if that node isn't a 'ports' node, or the
267  * grand-parent node of the port node otherwise).
268  *
269  * A reference is taken to both the local and remote nodes, the caller must use
270  * v4l2_of_put_link() to drop the references when done with the link.
271  *
272  * Return: 0 on success, or -ENOLINK if the remote endpoint can't be found.
273  */
274 int v4l2_of_parse_link(const struct device_node *node,
275                        struct v4l2_of_link *link)
276 {
277         struct device_node *np;
278
279         memset(link, 0, sizeof(*link));
280
281         np = of_get_parent(node);
282         of_property_read_u32(np, "reg", &link->local_port);
283         np = of_get_next_parent(np);
284         if (of_node_cmp(np->name, "ports") == 0)
285                 np = of_get_next_parent(np);
286         link->local_node = np;
287
288         np = of_parse_phandle(node, "remote-endpoint", 0);
289         if (!np) {
290                 of_node_put(link->local_node);
291                 return -ENOLINK;
292         }
293
294         np = of_get_parent(np);
295         of_property_read_u32(np, "reg", &link->remote_port);
296         np = of_get_next_parent(np);
297         if (of_node_cmp(np->name, "ports") == 0)
298                 np = of_get_next_parent(np);
299         link->remote_node = np;
300
301         return 0;
302 }
303 EXPORT_SYMBOL(v4l2_of_parse_link);
304
305 /**
306  * v4l2_of_put_link() - drop references to nodes in a link
307  * @link: pointer to the V4L2 OF link data structure
308  *
309  * Drop references to the local and remote nodes in the link. This function must
310  * be called on every link parsed with v4l2_of_parse_link().
311  */
312 void v4l2_of_put_link(struct v4l2_of_link *link)
313 {
314         of_node_put(link->local_node);
315         of_node_put(link->remote_node);
316 }
317 EXPORT_SYMBOL(v4l2_of_put_link);