blob: ed77aa055b633713f696cacb4612857cfa18c308 [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
18#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1)
19
20static const struct soc_mbus_pixelfmt mbus_fmt[] = {
Guennadi Liakhovetskiace6e972010-07-22 16:52:51 -030021 [MBUS_IDX(YUYV8_2X8)] = {
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 Liakhovetskiace6e972010-07-22 16:52:51 -030028 [MBUS_IDX(YVYU8_2X8)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030029 .fourcc = V4L2_PIX_FMT_YVYU,
30 .name = "YVYU",
31 .bits_per_sample = 8,
32 .packing = SOC_MBUS_PACKING_2X8_PADHI,
33 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010034 },
Guennadi Liakhovetskiace6e972010-07-22 16:52:51 -030035 [MBUS_IDX(UYVY8_2X8)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030036 .fourcc = V4L2_PIX_FMT_UYVY,
37 .name = "UYVY",
38 .bits_per_sample = 8,
39 .packing = SOC_MBUS_PACKING_2X8_PADHI,
40 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010041 },
Guennadi Liakhovetskiace6e972010-07-22 16:52:51 -030042 [MBUS_IDX(VYUY8_2X8)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030043 .fourcc = V4L2_PIX_FMT_VYUY,
44 .name = "VYUY",
45 .bits_per_sample = 8,
46 .packing = SOC_MBUS_PACKING_2X8_PADHI,
47 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010048 },
49 [MBUS_IDX(RGB555_2X8_PADHI_LE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030050 .fourcc = V4L2_PIX_FMT_RGB555,
51 .name = "RGB555",
52 .bits_per_sample = 8,
53 .packing = SOC_MBUS_PACKING_2X8_PADHI,
54 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010055 },
56 [MBUS_IDX(RGB555_2X8_PADHI_BE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030057 .fourcc = V4L2_PIX_FMT_RGB555X,
58 .name = "RGB555X",
59 .bits_per_sample = 8,
60 .packing = SOC_MBUS_PACKING_2X8_PADHI,
61 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010062 },
63 [MBUS_IDX(RGB565_2X8_LE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030064 .fourcc = V4L2_PIX_FMT_RGB565,
65 .name = "RGB565",
66 .bits_per_sample = 8,
67 .packing = SOC_MBUS_PACKING_2X8_PADHI,
68 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010069 },
70 [MBUS_IDX(RGB565_2X8_BE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030071 .fourcc = V4L2_PIX_FMT_RGB565X,
72 .name = "RGB565X",
73 .bits_per_sample = 8,
74 .packing = SOC_MBUS_PACKING_2X8_PADHI,
75 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010076 },
77 [MBUS_IDX(SBGGR8_1X8)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030078 .fourcc = V4L2_PIX_FMT_SBGGR8,
79 .name = "Bayer 8 BGGR",
80 .bits_per_sample = 8,
81 .packing = SOC_MBUS_PACKING_NONE,
82 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010083 },
84 [MBUS_IDX(SBGGR10_1X10)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030085 .fourcc = V4L2_PIX_FMT_SBGGR10,
86 .name = "Bayer 10 BGGR",
87 .bits_per_sample = 10,
88 .packing = SOC_MBUS_PACKING_EXTEND16,
89 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010090 },
Laurent Pinchart076704332010-09-28 07:01:44 -030091 [MBUS_IDX(Y8_1X8)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030092 .fourcc = V4L2_PIX_FMT_GREY,
93 .name = "Grey",
94 .bits_per_sample = 8,
95 .packing = SOC_MBUS_PACKING_NONE,
96 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +010097 },
98 [MBUS_IDX(Y10_1X10)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -030099 .fourcc = V4L2_PIX_FMT_Y10,
100 .name = "Grey 10bit",
101 .bits_per_sample = 10,
102 .packing = SOC_MBUS_PACKING_EXTEND16,
103 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100104 },
105 [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300106 .fourcc = V4L2_PIX_FMT_SBGGR10,
107 .name = "Bayer 10 BGGR",
108 .bits_per_sample = 8,
109 .packing = SOC_MBUS_PACKING_2X8_PADHI,
110 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100111 },
112 [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300113 .fourcc = V4L2_PIX_FMT_SBGGR10,
114 .name = "Bayer 10 BGGR",
115 .bits_per_sample = 8,
116 .packing = SOC_MBUS_PACKING_2X8_PADLO,
117 .order = SOC_MBUS_ORDER_LE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100118 },
119 [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300120 .fourcc = V4L2_PIX_FMT_SBGGR10,
121 .name = "Bayer 10 BGGR",
122 .bits_per_sample = 8,
123 .packing = SOC_MBUS_PACKING_2X8_PADHI,
124 .order = SOC_MBUS_ORDER_BE,
Guennadi Liakhovetski81355e42009-12-24 14:12:15 +0100125 },
126 [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = {
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300127 .fourcc = V4L2_PIX_FMT_SBGGR10,
128 .name = "Bayer 10 BGGR",
129 .bits_per_sample = 8,
130 .packing = SOC_MBUS_PACKING_2X8_PADLO,
131 .order = SOC_MBUS_ORDER_BE,
132 },
133};
134
Alberto Panizzo48a3c772011-01-12 08:16:19 -0300135int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
136{
137 switch (mf->packing) {
138 case SOC_MBUS_PACKING_NONE:
139 case SOC_MBUS_PACKING_EXTEND16:
140 return 1;
141 case SOC_MBUS_PACKING_2X8_PADHI:
142 case SOC_MBUS_PACKING_2X8_PADLO:
143 return 2;
144 }
145 return -EINVAL;
146}
147EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
148
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300149s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
150{
151 switch (mf->packing) {
152 case SOC_MBUS_PACKING_NONE:
153 return width * mf->bits_per_sample / 8;
154 case SOC_MBUS_PACKING_2X8_PADHI:
155 case SOC_MBUS_PACKING_2X8_PADLO:
156 case SOC_MBUS_PACKING_EXTEND16:
157 return width * 2;
158 }
159 return -EINVAL;
160}
161EXPORT_SYMBOL(soc_mbus_bytes_per_line);
162
163const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
164 enum v4l2_mbus_pixelcode code)
165{
Baruch Siach84f37512010-02-19 14:09:25 -0300166 if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) ||
167 code <= V4L2_MBUS_FMT_FIXED)
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300168 return NULL;
169 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
170}
171EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
172
173static int __init soc_mbus_init(void)
174{
175 return 0;
176}
177
178static void __exit soc_mbus_exit(void)
179{
180}
181
182module_init(soc_mbus_init);
183module_exit(soc_mbus_exit);
184
185MODULE_DESCRIPTION("soc-camera media bus interface");
186MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
187MODULE_LICENSE("GPL v2");