aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/vimc/vimc-common.c')
-rw-r--r--drivers/media/platform/vimc/vimc-common.c309
1 files changed, 180 insertions, 129 deletions
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index 03016f204d05..7e1ae0b12f1e 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -10,139 +10,192 @@
10 10
11#include "vimc-common.h" 11#include "vimc-common.h"
12 12
13static const __u32 vimc_mbus_list[] = { 13/*
14 MEDIA_BUS_FMT_FIXED, 14 * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
15 MEDIA_BUS_FMT_RGB444_1X12, 15 * in the scaler)
16 MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, 16 */
17 MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, 17static const struct vimc_pix_map vimc_pix_map_list[] = {
18 MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, 18 /* TODO: add all missing formats */
19 MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, 19
20 MEDIA_BUS_FMT_RGB565_1X16, 20 /* RGB formats */
21 MEDIA_BUS_FMT_BGR565_2X8_BE, 21 {
22 MEDIA_BUS_FMT_BGR565_2X8_LE, 22 .code = MEDIA_BUS_FMT_BGR888_1X24,
23 MEDIA_BUS_FMT_RGB565_2X8_BE, 23 .pixelformat = V4L2_PIX_FMT_BGR24,
24 MEDIA_BUS_FMT_RGB565_2X8_LE, 24 .bpp = 3,
25 MEDIA_BUS_FMT_RGB666_1X18, 25 .bayer = false,
26 MEDIA_BUS_FMT_RBG888_1X24, 26 },
27 MEDIA_BUS_FMT_RGB666_1X24_CPADHI, 27 {
28 MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 28 .code = MEDIA_BUS_FMT_RGB888_1X24,
29 MEDIA_BUS_FMT_BGR888_1X24, 29 .pixelformat = V4L2_PIX_FMT_RGB24,
30 MEDIA_BUS_FMT_GBR888_1X24, 30 .bpp = 3,
31 MEDIA_BUS_FMT_RGB888_1X24, 31 .bayer = false,
32 MEDIA_BUS_FMT_RGB888_2X12_BE, 32 },
33 MEDIA_BUS_FMT_RGB888_2X12_LE, 33 {
34 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 34 .code = MEDIA_BUS_FMT_ARGB8888_1X32,
35 MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 35 .pixelformat = V4L2_PIX_FMT_ARGB32,
36 MEDIA_BUS_FMT_ARGB8888_1X32, 36 .bpp = 4,
37 MEDIA_BUS_FMT_RGB888_1X32_PADHI, 37 .bayer = false,
38 MEDIA_BUS_FMT_RGB101010_1X30, 38 },
39 MEDIA_BUS_FMT_RGB121212_1X36, 39
40 MEDIA_BUS_FMT_RGB161616_1X48, 40 /* Bayer formats */
41 MEDIA_BUS_FMT_Y8_1X8, 41 {
42 MEDIA_BUS_FMT_UV8_1X8, 42 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
43 MEDIA_BUS_FMT_UYVY8_1_5X8, 43 .pixelformat = V4L2_PIX_FMT_SBGGR8,
44 MEDIA_BUS_FMT_VYUY8_1_5X8, 44 .bpp = 1,
45 MEDIA_BUS_FMT_YUYV8_1_5X8, 45 .bayer = true,
46 MEDIA_BUS_FMT_YVYU8_1_5X8, 46 },
47 MEDIA_BUS_FMT_UYVY8_2X8, 47 {
48 MEDIA_BUS_FMT_VYUY8_2X8, 48 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
49 MEDIA_BUS_FMT_YUYV8_2X8, 49 .pixelformat = V4L2_PIX_FMT_SGBRG8,
50 MEDIA_BUS_FMT_YVYU8_2X8, 50 .bpp = 1,
51 MEDIA_BUS_FMT_Y10_1X10, 51 .bayer = true,
52 MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 52 },
53 MEDIA_BUS_FMT_UYVY10_2X10, 53 {
54 MEDIA_BUS_FMT_VYUY10_2X10, 54 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
55 MEDIA_BUS_FMT_YUYV10_2X10, 55 .pixelformat = V4L2_PIX_FMT_SGRBG8,
56 MEDIA_BUS_FMT_YVYU10_2X10, 56 .bpp = 1,
57 MEDIA_BUS_FMT_Y12_1X12, 57 .bayer = true,
58 MEDIA_BUS_FMT_UYVY12_2X12, 58 },
59 MEDIA_BUS_FMT_VYUY12_2X12, 59 {
60 MEDIA_BUS_FMT_YUYV12_2X12, 60 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
61 MEDIA_BUS_FMT_YVYU12_2X12, 61 .pixelformat = V4L2_PIX_FMT_SRGGB8,
62 MEDIA_BUS_FMT_UYVY8_1X16, 62 .bpp = 1,
63 MEDIA_BUS_FMT_VYUY8_1X16, 63 .bayer = true,
64 MEDIA_BUS_FMT_YUYV8_1X16, 64 },
65 MEDIA_BUS_FMT_YVYU8_1X16, 65 {
66 MEDIA_BUS_FMT_YDYUYDYV8_1X16, 66 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
67 MEDIA_BUS_FMT_UYVY10_1X20, 67 .pixelformat = V4L2_PIX_FMT_SBGGR10,
68 MEDIA_BUS_FMT_VYUY10_1X20, 68 .bpp = 2,
69 MEDIA_BUS_FMT_YUYV10_1X20, 69 .bayer = true,
70 MEDIA_BUS_FMT_YVYU10_1X20, 70 },
71 MEDIA_BUS_FMT_VUY8_1X24, 71 {
72 MEDIA_BUS_FMT_YUV8_1X24, 72 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
73 MEDIA_BUS_FMT_UYYVYY8_0_5X24, 73 .pixelformat = V4L2_PIX_FMT_SGBRG10,
74 MEDIA_BUS_FMT_UYVY12_1X24, 74 .bpp = 2,
75 MEDIA_BUS_FMT_VYUY12_1X24, 75 .bayer = true,
76 MEDIA_BUS_FMT_YUYV12_1X24, 76 },
77 MEDIA_BUS_FMT_YVYU12_1X24, 77 {
78 MEDIA_BUS_FMT_YUV10_1X30, 78 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
79 MEDIA_BUS_FMT_UYYVYY10_0_5X30, 79 .pixelformat = V4L2_PIX_FMT_SGRBG10,
80 MEDIA_BUS_FMT_AYUV8_1X32, 80 .bpp = 2,
81 MEDIA_BUS_FMT_UYYVYY12_0_5X36, 81 .bayer = true,
82 MEDIA_BUS_FMT_YUV12_1X36, 82 },
83 MEDIA_BUS_FMT_YUV16_1X48, 83 {
84 MEDIA_BUS_FMT_UYYVYY16_0_5X48, 84 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
85 MEDIA_BUS_FMT_SBGGR8_1X8, 85 .pixelformat = V4L2_PIX_FMT_SRGGB10,
86 MEDIA_BUS_FMT_SGBRG8_1X8, 86 .bpp = 2,
87 MEDIA_BUS_FMT_SGRBG8_1X8, 87 .bayer = true,
88 MEDIA_BUS_FMT_SRGGB8_1X8, 88 },
89 MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, 89
90 MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, 90 /* 10bit raw bayer a-law compressed to 8 bits */
91 MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, 91 {
92 MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, 92 .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
93 MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 93 .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
94 MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, 94 .bpp = 1,
95 MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, 95 .bayer = true,
96 MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, 96 },
97 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, 97 {
98 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 98 .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
99 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, 99 .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
100 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, 100 .bpp = 1,
101 MEDIA_BUS_FMT_SBGGR10_1X10, 101 .bayer = true,
102 MEDIA_BUS_FMT_SGBRG10_1X10, 102 },
103 MEDIA_BUS_FMT_SGRBG10_1X10, 103 {
104 MEDIA_BUS_FMT_SRGGB10_1X10, 104 .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
105 MEDIA_BUS_FMT_SBGGR12_1X12, 105 .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
106 MEDIA_BUS_FMT_SGBRG12_1X12, 106 .bpp = 1,
107 MEDIA_BUS_FMT_SGRBG12_1X12, 107 .bayer = true,
108 MEDIA_BUS_FMT_SRGGB12_1X12, 108 },
109 MEDIA_BUS_FMT_SBGGR14_1X14, 109 {
110 MEDIA_BUS_FMT_SGBRG14_1X14, 110 .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
111 MEDIA_BUS_FMT_SGRBG14_1X14, 111 .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
112 MEDIA_BUS_FMT_SRGGB14_1X14, 112 .bpp = 1,
113 MEDIA_BUS_FMT_SBGGR16_1X16, 113 .bayer = true,
114 MEDIA_BUS_FMT_SGBRG16_1X16, 114 },
115 MEDIA_BUS_FMT_SGRBG16_1X16, 115
116 MEDIA_BUS_FMT_SRGGB16_1X16, 116 /* 10bit raw bayer DPCM compressed to 8 bits */
117 MEDIA_BUS_FMT_JPEG_1X8, 117 {
118 MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, 118 .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
119 MEDIA_BUS_FMT_AHSV8888_1X32, 119 .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
120 .bpp = 1,
121 .bayer = true,
122 },
123 {
124 .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
125 .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
126 .bpp = 1,
127 .bayer = true,
128 },
129 {
130 .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
131 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
132 .bpp = 1,
133 .bayer = true,
134 },
135 {
136 .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
137 .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
138 .bpp = 1,
139 .bayer = true,
140 },
141 {
142 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
143 .pixelformat = V4L2_PIX_FMT_SBGGR12,
144 .bpp = 2,
145 .bayer = true,
146 },
147 {
148 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
149 .pixelformat = V4L2_PIX_FMT_SGBRG12,
150 .bpp = 2,
151 .bayer = true,
152 },
153 {
154 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
155 .pixelformat = V4L2_PIX_FMT_SGRBG12,
156 .bpp = 2,
157 .bayer = true,
158 },
159 {
160 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
161 .pixelformat = V4L2_PIX_FMT_SRGGB12,
162 .bpp = 2,
163 .bayer = true,
164 },
120}; 165};
121 166
122/* Helper function to check mbus codes */ 167const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
123bool vimc_mbus_code_supported(__u32 code) 168{
169 if (i >= ARRAY_SIZE(vimc_pix_map_list))
170 return NULL;
171
172 return &vimc_pix_map_list[i];
173}
174EXPORT_SYMBOL_GPL(vimc_pix_map_by_index);
175
176const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
124{ 177{
125 unsigned int i; 178 unsigned int i;
126 179
127 for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++) 180 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
128 if (code == vimc_mbus_list[i]) 181 if (vimc_pix_map_list[i].code == code)
129 return true; 182 return &vimc_pix_map_list[i];
130 return false; 183 }
184 return NULL;
131} 185}
132EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); 186EXPORT_SYMBOL_GPL(vimc_pix_map_by_code);
133 187
134/* Helper function to enumerate mbus codes */ 188const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
135int vimc_enum_mbus_code(struct v4l2_subdev *sd,
136 struct v4l2_subdev_pad_config *cfg,
137 struct v4l2_subdev_mbus_code_enum *code)
138{ 189{
139 if (code->index >= ARRAY_SIZE(vimc_mbus_list)) 190 unsigned int i;
140 return -EINVAL;
141 191
142 code->code = vimc_mbus_list[code->index]; 192 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
143 return 0; 193 if (vimc_pix_map_list[i].pixelformat == pixelformat)
194 return &vimc_pix_map_list[i];
195 }
196 return NULL;
144} 197}
145EXPORT_SYMBOL_GPL(vimc_enum_mbus_code); 198EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat);
146 199
147/* Helper function to allocate and initialize pads */ 200/* Helper function to allocate and initialize pads */
148struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) 201struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
@@ -214,13 +267,15 @@ static int vimc_get_mbus_format(struct media_pad *pad,
214 struct video_device, 267 struct video_device,
215 entity); 268 entity);
216 struct vimc_ent_device *ved = video_get_drvdata(vdev); 269 struct vimc_ent_device *ved = video_get_drvdata(vdev);
270 const struct vimc_pix_map *vpix;
217 struct v4l2_pix_format vdev_fmt; 271 struct v4l2_pix_format vdev_fmt;
218 272
219 if (!ved->vdev_get_format) 273 if (!ved->vdev_get_format)
220 return -ENOIOCTLCMD; 274 return -ENOIOCTLCMD;
221 275
222 ved->vdev_get_format(ved, &vdev_fmt); 276 ved->vdev_get_format(ved, &vdev_fmt);
223 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0); 277 vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat);
278 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
224 } else { 279 } else {
225 return -EINVAL; 280 return -EINVAL;
226 } 281 }
@@ -260,12 +315,8 @@ int vimc_link_validate(struct media_link *link)
260 /* The width, height and code must match. */ 315 /* The width, height and code must match. */
261 if (source_fmt.format.width != sink_fmt.format.width 316 if (source_fmt.format.width != sink_fmt.format.width
262 || source_fmt.format.height != sink_fmt.format.height 317 || source_fmt.format.height != sink_fmt.format.height
263 || (source_fmt.format.code && sink_fmt.format.code && 318 || source_fmt.format.code != sink_fmt.format.code)
264 source_fmt.format.code != sink_fmt.format.code)) {
265 pr_err("vimc: format doesn't match in link %s->%s\n",
266 link->source->entity->name, link->sink->entity->name);
267 return -EPIPE; 319 return -EPIPE;
268 }
269 320
270 /* 321 /*
271 * The field order must match, or the sink field order must be NONE 322 * The field order must match, or the sink field order must be NONE