blob: 13e86df78e56ed2fb23efebd1bc95437881680d4 [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 },
Kassey Li64149de2011-05-20 04:08:39 -0300133 [MBUS_IDX(JPEG_1X8)] = {
134 .fourcc = V4L2_PIX_FMT_JPEG,
135 .name = "JPEG",
136 .bits_per_sample = 8,
137 .packing = SOC_MBUS_PACKING_VARIABLE,
138 .order = SOC_MBUS_ORDER_LE,
139 },
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300140};
141
Alberto Panizzo48a3c772011-01-12 08:16:19 -0300142int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
143{
144 switch (mf->packing) {
145 case SOC_MBUS_PACKING_NONE:
146 case SOC_MBUS_PACKING_EXTEND16:
147 return 1;
148 case SOC_MBUS_PACKING_2X8_PADHI:
149 case SOC_MBUS_PACKING_2X8_PADLO:
150 return 2;
Kassey Li64149de2011-05-20 04:08:39 -0300151 case SOC_MBUS_PACKING_VARIABLE:
152 return 0;
Alberto Panizzo48a3c772011-01-12 08:16:19 -0300153 }
154 return -EINVAL;
155}
156EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
157
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300158s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
159{
160 switch (mf->packing) {
161 case SOC_MBUS_PACKING_NONE:
162 return width * mf->bits_per_sample / 8;
163 case SOC_MBUS_PACKING_2X8_PADHI:
164 case SOC_MBUS_PACKING_2X8_PADLO:
165 case SOC_MBUS_PACKING_EXTEND16:
166 return width * 2;
Kassey Li64149de2011-05-20 04:08:39 -0300167 case SOC_MBUS_PACKING_VARIABLE:
168 return 0;
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300169 }
170 return -EINVAL;
171}
172EXPORT_SYMBOL(soc_mbus_bytes_per_line);
173
174const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
175 enum v4l2_mbus_pixelcode code)
176{
Baruch Siach84f37512010-02-19 14:09:25 -0300177 if (code - V4L2_MBUS_FMT_FIXED > ARRAY_SIZE(mbus_fmt) ||
178 code <= V4L2_MBUS_FMT_FIXED)
Guennadi Liakhovetski9a742512009-12-11 11:41:28 -0300179 return NULL;
180 return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1;
181}
182EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
183
184static int __init soc_mbus_init(void)
185{
186 return 0;
187}
188
189static void __exit soc_mbus_exit(void)
190{
191}
192
193module_init(soc_mbus_init);
194module_exit(soc_mbus_exit);
195
196MODULE_DESCRIPTION("soc-camera media bus interface");
197MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
198MODULE_LICENSE("GPL v2");