media: tegra: Tegra V4L2 camera
[linux-2.6.git] / drivers / media / video / soc_mediabus.c
1 /*
2  * soc-camera media bus helper routines
3  *
4  * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5  *
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  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13
14 #include <media/v4l2-device.h>
15 #include <media/v4l2-mediabus.h>
16 #include <media/soc_mediabus.h>
17
18 static const struct soc_mbus_lookup mbus_fmt[] = {
19 {
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,
27         },
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,
36         },
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,
45         },
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,
54         },
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,
63         },
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,
72         },
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,
81         },
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,
90         },
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,
99         },
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,
108         },
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,
117         },
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,
126         },
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,
135         },
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,
144         },
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,
153         },
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,
162         },
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,
171         },
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,
180         },
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,
189         },
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,
198         },
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,
207         },
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,
216         },
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,
225         },
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,
234         },
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,
243         },
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,
252         },
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,
261         },
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,
270         },
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,
279         },
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,
288         },
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,
297         },
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,
306         },
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,
315         },
316 },
317 };
318
319 int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
320                         unsigned int *numerator, unsigned int *denominator)
321 {
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;
341         }
342         return -EINVAL;
343 }
344 EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
345
346 s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
347 {
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;
359         }
360         return -EINVAL;
361 }
362 EXPORT_SYMBOL(soc_mbus_bytes_per_line);
363
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)
368 {
369         int i;
370
371         for (i = 0; i < n; i++)
372                 if (lookup[i].code == code)
373                         return &lookup[i].fmt;
374
375         return NULL;
376 }
377 EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
378
379 const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
380         enum v4l2_mbus_pixelcode code)
381 {
382         return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
383 }
384 EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
385
386 static int __init soc_mbus_init(void)
387 {
388         return 0;
389 }
390
391 static void __exit soc_mbus_exit(void)
392 {
393 }
394
395 module_init(soc_mbus_init);
396 module_exit(soc_mbus_exit);
397
398 MODULE_DESCRIPTION("soc-camera media bus interface");
399 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
400 MODULE_LICENSE("GPL v2");