PageRenderTime 35ms CodeModel.GetById 15ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/media/video/soc_mediabus.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 400 lines | 378 code | 13 blank | 9 comment | 5 complexity | 5cad2a159fb4a8d05233401cd7edc6a0 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  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
 18static 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
319int 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}
344EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
345
346s32 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}
362EXPORT_SYMBOL(soc_mbus_bytes_per_line);
363
364const 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}
377EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
378
379const 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}
384EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
385
386static int __init soc_mbus_init(void)
387{
388	return 0;
389}
390
391static void __exit soc_mbus_exit(void)
392{
393}
394
395module_init(soc_mbus_init);
396module_exit(soc_mbus_exit);
397
398MODULE_DESCRIPTION("soc-camera media bus interface");
399MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
400MODULE_LICENSE("GPL v2");