]> Pileus Git - ~andy/linux/blob - drivers/media/video/soc_mediabus.c
e13c663d6d0448941311428f9cc5cb826d9e9253
[~andy/linux] / 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 };
174
175 int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
176                         unsigned int *numerator, unsigned int *denominator)
177 {
178         switch (mf->packing) {
179         case SOC_MBUS_PACKING_NONE:
180         case SOC_MBUS_PACKING_EXTEND16:
181                 *numerator = 1;
182                 *denominator = 1;
183                 return 0;
184         case SOC_MBUS_PACKING_2X8_PADHI:
185         case SOC_MBUS_PACKING_2X8_PADLO:
186                 *numerator = 2;
187                 *denominator = 1;
188                 return 0;
189         case SOC_MBUS_PACKING_1_5X8:
190                 *numerator = 3;
191                 *denominator = 2;
192                 return 0;
193         case SOC_MBUS_PACKING_VARIABLE:
194                 *numerator = 0;
195                 *denominator = 1;
196                 return 0;
197         }
198         return -EINVAL;
199 }
200 EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
201
202 s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
203 {
204         switch (mf->packing) {
205         case SOC_MBUS_PACKING_NONE:
206                 return width * mf->bits_per_sample / 8;
207         case SOC_MBUS_PACKING_2X8_PADHI:
208         case SOC_MBUS_PACKING_2X8_PADLO:
209         case SOC_MBUS_PACKING_EXTEND16:
210                 return width * 2;
211         case SOC_MBUS_PACKING_1_5X8:
212                 return width * 3 / 2;
213         case SOC_MBUS_PACKING_VARIABLE:
214                 return 0;
215         }
216         return -EINVAL;
217 }
218 EXPORT_SYMBOL(soc_mbus_bytes_per_line);
219
220 const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
221         enum v4l2_mbus_pixelcode code,
222         const struct soc_mbus_lookup *lookup,
223         int n)
224 {
225         int i;
226
227         for (i = 0; i < n; i++)
228                 if (lookup[i].code == code)
229                         return &lookup[i].fmt;
230
231         return NULL;
232 }
233 EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
234
235 const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
236         enum v4l2_mbus_pixelcode code)
237 {
238         return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
239 }
240 EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
241
242 static int __init soc_mbus_init(void)
243 {
244         return 0;
245 }
246
247 static void __exit soc_mbus_exit(void)
248 {
249 }
250
251 module_init(soc_mbus_init);
252 module_exit(soc_mbus_exit);
253
254 MODULE_DESCRIPTION("soc-camera media bus interface");
255 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
256 MODULE_LICENSE("GPL v2");