Use dentry_path() to create full path to inode object
[pohmelfs.git] / drivers / media / video / soc_mediabus.c
blobcf7f2194ded46d88853162e0912dc0f9a0e7e530
1 /*
2 * soc-camera media bus helper routines
4 * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
14 #include <media/v4l2-device.h>
15 #include <media/v4l2-mediabus.h>
16 #include <media/soc_mediabus.h>
18 static const struct soc_mbus_lookup mbus_fmt[] = {
20 .code = V4L2_MBUS_FMT_YUYV8_2X8,
21 .fmt = {
22 .fourcc = V4L2_PIX_FMT_YUYV,
23 .name = "YUYV",
24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE,
28 }, {
29 .code = V4L2_MBUS_FMT_YVYU8_2X8,
30 .fmt = {
31 .fourcc = V4L2_PIX_FMT_YVYU,
32 .name = "YVYU",
33 .bits_per_sample = 8,
34 .packing = SOC_MBUS_PACKING_2X8_PADHI,
35 .order = SOC_MBUS_ORDER_LE,
37 }, {
38 .code = V4L2_MBUS_FMT_UYVY8_2X8,
39 .fmt = {
40 .fourcc = V4L2_PIX_FMT_UYVY,
41 .name = "UYVY",
42 .bits_per_sample = 8,
43 .packing = SOC_MBUS_PACKING_2X8_PADHI,
44 .order = SOC_MBUS_ORDER_LE,
46 }, {
47 .code = V4L2_MBUS_FMT_VYUY8_2X8,
48 .fmt = {
49 .fourcc = V4L2_PIX_FMT_VYUY,
50 .name = "VYUY",
51 .bits_per_sample = 8,
52 .packing = SOC_MBUS_PACKING_2X8_PADHI,
53 .order = SOC_MBUS_ORDER_LE,
55 }, {
56 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
57 .fmt = {
58 .fourcc = V4L2_PIX_FMT_RGB555,
59 .name = "RGB555",
60 .bits_per_sample = 8,
61 .packing = SOC_MBUS_PACKING_2X8_PADHI,
62 .order = SOC_MBUS_ORDER_LE,
64 }, {
65 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
66 .fmt = {
67 .fourcc = V4L2_PIX_FMT_RGB555X,
68 .name = "RGB555X",
69 .bits_per_sample = 8,
70 .packing = SOC_MBUS_PACKING_2X8_PADHI,
71 .order = SOC_MBUS_ORDER_LE,
73 }, {
74 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
75 .fmt = {
76 .fourcc = V4L2_PIX_FMT_RGB565,
77 .name = "RGB565",
78 .bits_per_sample = 8,
79 .packing = SOC_MBUS_PACKING_2X8_PADHI,
80 .order = SOC_MBUS_ORDER_LE,
82 }, {
83 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
84 .fmt = {
85 .fourcc = V4L2_PIX_FMT_RGB565X,
86 .name = "RGB565X",
87 .bits_per_sample = 8,
88 .packing = SOC_MBUS_PACKING_2X8_PADHI,
89 .order = SOC_MBUS_ORDER_LE,
91 }, {
92 .code = V4L2_MBUS_FMT_SBGGR8_1X8,
93 .fmt = {
94 .fourcc = V4L2_PIX_FMT_SBGGR8,
95 .name = "Bayer 8 BGGR",
96 .bits_per_sample = 8,
97 .packing = SOC_MBUS_PACKING_NONE,
98 .order = SOC_MBUS_ORDER_LE,
100 }, {
101 .code = V4L2_MBUS_FMT_SBGGR10_1X10,
102 .fmt = {
103 .fourcc = V4L2_PIX_FMT_SBGGR10,
104 .name = "Bayer 10 BGGR",
105 .bits_per_sample = 10,
106 .packing = SOC_MBUS_PACKING_EXTEND16,
107 .order = SOC_MBUS_ORDER_LE,
109 }, {
110 .code = V4L2_MBUS_FMT_Y8_1X8,
111 .fmt = {
112 .fourcc = V4L2_PIX_FMT_GREY,
113 .name = "Grey",
114 .bits_per_sample = 8,
115 .packing = SOC_MBUS_PACKING_NONE,
116 .order = SOC_MBUS_ORDER_LE,
118 }, {
119 .code = V4L2_MBUS_FMT_Y10_1X10,
120 .fmt = {
121 .fourcc = V4L2_PIX_FMT_Y10,
122 .name = "Grey 10bit",
123 .bits_per_sample = 10,
124 .packing = SOC_MBUS_PACKING_EXTEND16,
125 .order = SOC_MBUS_ORDER_LE,
127 }, {
128 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
129 .fmt = {
130 .fourcc = V4L2_PIX_FMT_SBGGR10,
131 .name = "Bayer 10 BGGR",
132 .bits_per_sample = 8,
133 .packing = SOC_MBUS_PACKING_2X8_PADHI,
134 .order = SOC_MBUS_ORDER_LE,
136 }, {
137 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
138 .fmt = {
139 .fourcc = V4L2_PIX_FMT_SBGGR10,
140 .name = "Bayer 10 BGGR",
141 .bits_per_sample = 8,
142 .packing = SOC_MBUS_PACKING_2X8_PADLO,
143 .order = SOC_MBUS_ORDER_LE,
145 }, {
146 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
147 .fmt = {
148 .fourcc = V4L2_PIX_FMT_SBGGR10,
149 .name = "Bayer 10 BGGR",
150 .bits_per_sample = 8,
151 .packing = SOC_MBUS_PACKING_2X8_PADHI,
152 .order = SOC_MBUS_ORDER_BE,
154 }, {
155 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
156 .fmt = {
157 .fourcc = V4L2_PIX_FMT_SBGGR10,
158 .name = "Bayer 10 BGGR",
159 .bits_per_sample = 8,
160 .packing = SOC_MBUS_PACKING_2X8_PADLO,
161 .order = SOC_MBUS_ORDER_BE,
163 }, {
164 .code = V4L2_MBUS_FMT_JPEG_1X8,
165 .fmt = {
166 .fourcc = V4L2_PIX_FMT_JPEG,
167 .name = "JPEG",
168 .bits_per_sample = 8,
169 .packing = SOC_MBUS_PACKING_VARIABLE,
170 .order = SOC_MBUS_ORDER_LE,
172 }, {
173 .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
174 .fmt = {
175 .fourcc = V4L2_PIX_FMT_RGB444,
176 .name = "RGB444",
177 .bits_per_sample = 8,
178 .packing = SOC_MBUS_PACKING_2X8_PADHI,
179 .order = SOC_MBUS_ORDER_BE,
181 }, {
182 .code = V4L2_MBUS_FMT_YUYV8_1_5X8,
183 .fmt = {
184 .fourcc = V4L2_PIX_FMT_YUV420,
185 .name = "YUYV 4:2:0",
186 .bits_per_sample = 8,
187 .packing = SOC_MBUS_PACKING_1_5X8,
188 .order = SOC_MBUS_ORDER_LE,
190 }, {
191 .code = V4L2_MBUS_FMT_YVYU8_1_5X8,
192 .fmt = {
193 .fourcc = V4L2_PIX_FMT_YVU420,
194 .name = "YVYU 4:2:0",
195 .bits_per_sample = 8,
196 .packing = SOC_MBUS_PACKING_1_5X8,
197 .order = SOC_MBUS_ORDER_LE,
199 }, {
200 .code = V4L2_MBUS_FMT_UYVY8_1X16,
201 .fmt = {
202 .fourcc = V4L2_PIX_FMT_UYVY,
203 .name = "UYVY 16bit",
204 .bits_per_sample = 16,
205 .packing = SOC_MBUS_PACKING_EXTEND16,
206 .order = SOC_MBUS_ORDER_LE,
208 }, {
209 .code = V4L2_MBUS_FMT_VYUY8_1X16,
210 .fmt = {
211 .fourcc = V4L2_PIX_FMT_VYUY,
212 .name = "VYUY 16bit",
213 .bits_per_sample = 16,
214 .packing = SOC_MBUS_PACKING_EXTEND16,
215 .order = SOC_MBUS_ORDER_LE,
217 }, {
218 .code = V4L2_MBUS_FMT_YUYV8_1X16,
219 .fmt = {
220 .fourcc = V4L2_PIX_FMT_YUYV,
221 .name = "YUYV 16bit",
222 .bits_per_sample = 16,
223 .packing = SOC_MBUS_PACKING_EXTEND16,
224 .order = SOC_MBUS_ORDER_LE,
226 }, {
227 .code = V4L2_MBUS_FMT_YVYU8_1X16,
228 .fmt = {
229 .fourcc = V4L2_PIX_FMT_YVYU,
230 .name = "YVYU 16bit",
231 .bits_per_sample = 16,
232 .packing = SOC_MBUS_PACKING_EXTEND16,
233 .order = SOC_MBUS_ORDER_LE,
235 }, {
236 .code = V4L2_MBUS_FMT_SGRBG8_1X8,
237 .fmt = {
238 .fourcc = V4L2_PIX_FMT_SGRBG8,
239 .name = "Bayer 8 GRBG",
240 .bits_per_sample = 8,
241 .packing = SOC_MBUS_PACKING_NONE,
242 .order = SOC_MBUS_ORDER_LE,
244 }, {
245 .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
246 .fmt = {
247 .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8,
248 .name = "Bayer 10 BGGR DPCM 8",
249 .bits_per_sample = 8,
250 .packing = SOC_MBUS_PACKING_NONE,
251 .order = SOC_MBUS_ORDER_LE,
253 }, {
254 .code = V4L2_MBUS_FMT_SGBRG10_1X10,
255 .fmt = {
256 .fourcc = V4L2_PIX_FMT_SGBRG10,
257 .name = "Bayer 10 GBRG",
258 .bits_per_sample = 10,
259 .packing = SOC_MBUS_PACKING_EXTEND16,
260 .order = SOC_MBUS_ORDER_LE,
262 }, {
263 .code = V4L2_MBUS_FMT_SGRBG10_1X10,
264 .fmt = {
265 .fourcc = V4L2_PIX_FMT_SGRBG10,
266 .name = "Bayer 10 GRBG",
267 .bits_per_sample = 10,
268 .packing = SOC_MBUS_PACKING_EXTEND16,
269 .order = SOC_MBUS_ORDER_LE,
271 }, {
272 .code = V4L2_MBUS_FMT_SRGGB10_1X10,
273 .fmt = {
274 .fourcc = V4L2_PIX_FMT_SRGGB10,
275 .name = "Bayer 10 RGGB",
276 .bits_per_sample = 10,
277 .packing = SOC_MBUS_PACKING_EXTEND16,
278 .order = SOC_MBUS_ORDER_LE,
280 }, {
281 .code = V4L2_MBUS_FMT_SBGGR12_1X12,
282 .fmt = {
283 .fourcc = V4L2_PIX_FMT_SBGGR12,
284 .name = "Bayer 12 BGGR",
285 .bits_per_sample = 12,
286 .packing = SOC_MBUS_PACKING_EXTEND16,
287 .order = SOC_MBUS_ORDER_LE,
289 }, {
290 .code = V4L2_MBUS_FMT_SGBRG12_1X12,
291 .fmt = {
292 .fourcc = V4L2_PIX_FMT_SGBRG12,
293 .name = "Bayer 12 GBRG",
294 .bits_per_sample = 12,
295 .packing = SOC_MBUS_PACKING_EXTEND16,
296 .order = SOC_MBUS_ORDER_LE,
298 }, {
299 .code = V4L2_MBUS_FMT_SGRBG12_1X12,
300 .fmt = {
301 .fourcc = V4L2_PIX_FMT_SGRBG12,
302 .name = "Bayer 12 GRBG",
303 .bits_per_sample = 12,
304 .packing = SOC_MBUS_PACKING_EXTEND16,
305 .order = SOC_MBUS_ORDER_LE,
307 }, {
308 .code = V4L2_MBUS_FMT_SRGGB12_1X12,
309 .fmt = {
310 .fourcc = V4L2_PIX_FMT_SRGGB12,
311 .name = "Bayer 12 RGGB",
312 .bits_per_sample = 12,
313 .packing = SOC_MBUS_PACKING_EXTEND16,
314 .order = SOC_MBUS_ORDER_LE,
319 int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
320 unsigned int *numerator, unsigned int *denominator)
322 switch (mf->packing) {
323 case SOC_MBUS_PACKING_NONE:
324 case SOC_MBUS_PACKING_EXTEND16:
325 *numerator = 1;
326 *denominator = 1;
327 return 0;
328 case SOC_MBUS_PACKING_2X8_PADHI:
329 case SOC_MBUS_PACKING_2X8_PADLO:
330 *numerator = 2;
331 *denominator = 1;
332 return 0;
333 case SOC_MBUS_PACKING_1_5X8:
334 *numerator = 3;
335 *denominator = 2;
336 return 0;
337 case SOC_MBUS_PACKING_VARIABLE:
338 *numerator = 0;
339 *denominator = 1;
340 return 0;
342 return -EINVAL;
344 EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
346 s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
348 switch (mf->packing) {
349 case SOC_MBUS_PACKING_NONE:
350 return width * mf->bits_per_sample / 8;
351 case SOC_MBUS_PACKING_2X8_PADHI:
352 case SOC_MBUS_PACKING_2X8_PADLO:
353 case SOC_MBUS_PACKING_EXTEND16:
354 return width * 2;
355 case SOC_MBUS_PACKING_1_5X8:
356 return width * 3 / 2;
357 case SOC_MBUS_PACKING_VARIABLE:
358 return 0;
360 return -EINVAL;
362 EXPORT_SYMBOL(soc_mbus_bytes_per_line);
364 const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
365 enum v4l2_mbus_pixelcode code,
366 const struct soc_mbus_lookup *lookup,
367 int n)
369 int i;
371 for (i = 0; i < n; i++)
372 if (lookup[i].code == code)
373 return &lookup[i].fmt;
375 return NULL;
377 EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
379 const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
380 enum v4l2_mbus_pixelcode code)
382 return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
384 EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
386 unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
387 unsigned int flags)
389 unsigned long common_flags;
390 bool hsync = true, vsync = true, pclk, data, mode;
391 bool mipi_lanes, mipi_clock;
393 common_flags = cfg->flags & flags;
395 switch (cfg->type) {
396 case V4L2_MBUS_PARALLEL:
397 hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
398 V4L2_MBUS_HSYNC_ACTIVE_LOW);
399 vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
400 V4L2_MBUS_VSYNC_ACTIVE_LOW);
401 case V4L2_MBUS_BT656:
402 pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
403 V4L2_MBUS_PCLK_SAMPLE_FALLING);
404 data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
405 V4L2_MBUS_DATA_ACTIVE_LOW);
406 mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
407 return (!hsync || !vsync || !pclk || !data || !mode) ?
408 0 : common_flags;
409 case V4L2_MBUS_CSI2:
410 mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
411 mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
412 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
413 return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
415 return 0;
417 EXPORT_SYMBOL(soc_mbus_config_compatible);
419 static int __init soc_mbus_init(void)
421 return 0;
424 static void __exit soc_mbus_exit(void)
428 module_init(soc_mbus_init);
429 module_exit(soc_mbus_exit);
431 MODULE_DESCRIPTION("soc-camera media bus interface");
432 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
433 MODULE_LICENSE("GPL v2");