blob: 1b0018a588048c4c6a0424ba24cd8e25c01143fe [file] [log] [blame]
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -03001/*
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
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030018static const struct soc_mbus_lookup mbus_fmt[] = {
19{
20 .code = V4L2_MBUS_FMT_YUYV8_2X8,
21 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030022 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010027 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030028}, {
29 .code = V4L2_MBUS_FMT_YVYU8_2X8,
30 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030031 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010036 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030037}, {
38 .code = V4L2_MBUS_FMT_UYVY8_2X8,
39 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030040 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010045 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030046}, {
47 .code = V4L2_MBUS_FMT_VYUY8_2X8,
48 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030049 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010054 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030055}, {
56 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
57 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030058 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010063 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030064}, {
65 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
66 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030067 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010072 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030073}, {
74 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
75 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030076 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010081 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030082}, {
83 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
84 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030085 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010090 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -030091}, {
92 .code = V4L2_MBUS_FMT_SBGGR8_1X8,
93 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030094 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010099 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300100}, {
101 .code = V4L2_MBUS_FMT_SBGGR10_1X10,
102 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300103 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100108 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300109}, {
110 .code = V4L2_MBUS_FMT_Y8_1X8,
111 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300112 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100117 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300118}, {
119 .code = V4L2_MBUS_FMT_Y10_1X10,
120 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300121 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100126 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300127}, {
128 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
129 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300130 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100135 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300136}, {
137 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
138 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300139 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100144 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300145}, {
146 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
147 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300148 .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,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100153 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300154}, {
155 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
156 .fmt = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300157 .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 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300163}, {
164 .code = V4L2_MBUS_FMT_JPEG_1X8,
165 .fmt = {
Kassey Li64149de2011-05-20 04:08:39 -0300166 .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 },
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300172},
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300173};
174
Alberto Panizzo48a3c772011-01-12 08:16:19 -0300175int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
176{
177 switch (mf->packing) {
178 case SOC_MBUS_PACKING_NONE:
179 case SOC_MBUS_PACKING_EXTEND16:
180 return 1;
181 case SOC_MBUS_PACKING_2X8_PADHI:
182 case SOC_MBUS_PACKING_2X8_PADLO:
183 return 2;
Kassey Li64149de2011-05-20 04:08:39 -0300184 case SOC_MBUS_PACKING_VARIABLE:
185 return 0;
Alberto Panizzo48a3c772011-01-12 08:16:19 -0300186 }
187 return -EINVAL;
188}
189EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
190
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300191s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
192{
193 switch (mf->packing) {
194 case SOC_MBUS_PACKING_NONE:
195 return width * mf->bits_per_sample / 8;
196 case SOC_MBUS_PACKING_2X8_PADHI:
197 case SOC_MBUS_PACKING_2X8_PADLO:
198 case SOC_MBUS_PACKING_EXTEND16:
199 return width * 2;
Kassey Li64149de2011-05-20 04:08:39 -0300200 case SOC_MBUS_PACKING_VARIABLE:
201 return 0;
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300202 }
203 return -EINVAL;
204}
205EXPORT_SYMBOL(soc_mbus_bytes_per_line);
206
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300207const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
208 enum v4l2_mbus_pixelcode code,
209 const struct soc_mbus_lookup *lookup,
210 int n)
211{
212 int i;
213
214 for (i = 0; i < n; i++)
215 if (lookup[i].code == code)
216 return &lookup[i].fmt;
217
218 return NULL;
219}
220EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
221
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300222const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
223 enum v4l2_mbus_pixelcode code)
224{
Guennadi Liakhovetski93f116d2011-05-13 13:21:36 -0300225 return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300226}
227EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
228
229static int __init soc_mbus_init(void)
230{
231 return 0;
232}
233
234static void __exit soc_mbus_exit(void)
235{
236}
237
238module_init(soc_mbus_init);
239module_exit(soc_mbus_exit);
240
241MODULE_DESCRIPTION("soc-camera media bus interface");
242MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
243MODULE_LICENSE("GPL v2");