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.
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
,
22 .fourcc
= V4L2_PIX_FMT_YUYV
,
25 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
26 .order
= SOC_MBUS_ORDER_LE
,
29 .code
= V4L2_MBUS_FMT_YVYU8_2X8
,
31 .fourcc
= V4L2_PIX_FMT_YVYU
,
34 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
35 .order
= SOC_MBUS_ORDER_LE
,
38 .code
= V4L2_MBUS_FMT_UYVY8_2X8
,
40 .fourcc
= V4L2_PIX_FMT_UYVY
,
43 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
44 .order
= SOC_MBUS_ORDER_LE
,
47 .code
= V4L2_MBUS_FMT_VYUY8_2X8
,
49 .fourcc
= V4L2_PIX_FMT_VYUY
,
52 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
53 .order
= SOC_MBUS_ORDER_LE
,
56 .code
= V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE
,
58 .fourcc
= V4L2_PIX_FMT_RGB555
,
61 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
62 .order
= SOC_MBUS_ORDER_LE
,
65 .code
= V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE
,
67 .fourcc
= V4L2_PIX_FMT_RGB555X
,
70 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
71 .order
= SOC_MBUS_ORDER_LE
,
74 .code
= V4L2_MBUS_FMT_RGB565_2X8_LE
,
76 .fourcc
= V4L2_PIX_FMT_RGB565
,
79 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
80 .order
= SOC_MBUS_ORDER_LE
,
83 .code
= V4L2_MBUS_FMT_RGB565_2X8_BE
,
85 .fourcc
= V4L2_PIX_FMT_RGB565X
,
88 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
89 .order
= SOC_MBUS_ORDER_LE
,
92 .code
= V4L2_MBUS_FMT_SBGGR8_1X8
,
94 .fourcc
= V4L2_PIX_FMT_SBGGR8
,
95 .name
= "Bayer 8 BGGR",
97 .packing
= SOC_MBUS_PACKING_NONE
,
98 .order
= SOC_MBUS_ORDER_LE
,
101 .code
= V4L2_MBUS_FMT_SBGGR10_1X10
,
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
,
110 .code
= V4L2_MBUS_FMT_Y8_1X8
,
112 .fourcc
= V4L2_PIX_FMT_GREY
,
114 .bits_per_sample
= 8,
115 .packing
= SOC_MBUS_PACKING_NONE
,
116 .order
= SOC_MBUS_ORDER_LE
,
119 .code
= V4L2_MBUS_FMT_Y10_1X10
,
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
,
128 .code
= V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE
,
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
,
137 .code
= V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE
,
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
,
146 .code
= V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE
,
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
,
155 .code
= V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE
,
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
,
164 .code
= V4L2_MBUS_FMT_JPEG_1X8
,
166 .fourcc
= V4L2_PIX_FMT_JPEG
,
168 .bits_per_sample
= 8,
169 .packing
= SOC_MBUS_PACKING_VARIABLE
,
170 .order
= SOC_MBUS_ORDER_LE
,
173 .code
= V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE
,
175 .fourcc
= V4L2_PIX_FMT_RGB444
,
177 .bits_per_sample
= 8,
178 .packing
= SOC_MBUS_PACKING_2X8_PADHI
,
179 .order
= SOC_MBUS_ORDER_BE
,
182 .code
= V4L2_MBUS_FMT_YUYV8_1_5X8
,
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
,
191 .code
= V4L2_MBUS_FMT_YVYU8_1_5X8
,
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
,
200 .code
= V4L2_MBUS_FMT_UYVY8_1X16
,
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
,
209 .code
= V4L2_MBUS_FMT_VYUY8_1X16
,
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
,
218 .code
= V4L2_MBUS_FMT_YUYV8_1X16
,
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
,
227 .code
= V4L2_MBUS_FMT_YVYU8_1X16
,
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
,
236 .code
= V4L2_MBUS_FMT_SGRBG8_1X8
,
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
,
245 .code
= V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8
,
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
,
254 .code
= V4L2_MBUS_FMT_SGBRG10_1X10
,
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
,
263 .code
= V4L2_MBUS_FMT_SGRBG10_1X10
,
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
,
272 .code
= V4L2_MBUS_FMT_SRGGB10_1X10
,
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
,
281 .code
= V4L2_MBUS_FMT_SBGGR12_1X12
,
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
,
290 .code
= V4L2_MBUS_FMT_SGBRG12_1X12
,
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
,
299 .code
= V4L2_MBUS_FMT_SGRBG12_1X12
,
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
,
308 .code
= V4L2_MBUS_FMT_SRGGB12_1X12
,
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
:
328 case SOC_MBUS_PACKING_2X8_PADHI
:
329 case SOC_MBUS_PACKING_2X8_PADLO
:
333 case SOC_MBUS_PACKING_1_5X8
:
337 case SOC_MBUS_PACKING_VARIABLE
:
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
:
355 case SOC_MBUS_PACKING_1_5X8
:
356 return width
* 3 / 2;
357 case SOC_MBUS_PACKING_VARIABLE
:
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
,
371 for (i
= 0; i
< n
; i
++)
372 if (lookup
[i
].code
== code
)
373 return &lookup
[i
].fmt
;
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
,
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
;
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
) ?
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
;
417 EXPORT_SYMBOL(soc_mbus_config_compatible
);
419 static int __init
soc_mbus_init(void)
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");