aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vimc/vimc-common.c
diff options
context:
space:
mode:
authorHelen Fornazier <helen.koike@collabora.com>2019-03-13 14:29:37 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-04-22 10:58:51 -0400
commitb6c61a6c37317efd7327199bfe24770af3d7e799 (patch)
treec130cfb12c25543104b880a12d039ccac03ffa12 /drivers/media/platform/vimc/vimc-common.c
parentd82b921a7a8a00ec31ba76287245ec663534df9b (diff)
media: vimc: propagate pixel format in the stream
Media bus codes were being mapped to pixelformats, which causes a limitation on vimc because not all pixelformats can be mapped to media bus codes. Also, media bus codes are an internal configuration from the device. Userspace only assures media bus codes matches between pads and expects the image in a given pixelformat. So we can allow almost any media bus format to be configured between pads, except for debayer that expects a media bus code of type bayer in the sink pad. [hverkuil-cisco@xs4all.nl: drop use of v4l2_get_fourcc_name: not yet available] [hverkuil-cisco@xs4all.nl: made vimc_mbus_list static] Signed-off-by: Helen Koike <helen.koike@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/vimc/vimc-common.c')
-rw-r--r--drivers/media/platform/vimc/vimc-common.c309
1 files changed, 129 insertions, 180 deletions
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index e8e6c6b95db9..fad7c7c6de93 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -20,192 +20,139 @@
20 20
21#include "vimc-common.h" 21#include "vimc-common.h"
22 22
23/* 23static const __u32 vimc_mbus_list[] = {
24 * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code 24 MEDIA_BUS_FMT_FIXED,
25 * in the scaler) 25 MEDIA_BUS_FMT_RGB444_1X12,
26 */ 26 MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE,
27static const struct vimc_pix_map vimc_pix_map_list[] = { 27 MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE,
28 /* TODO: add all missing formats */ 28 MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
29 29 MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
30 /* RGB formats */ 30 MEDIA_BUS_FMT_RGB565_1X16,
31 { 31 MEDIA_BUS_FMT_BGR565_2X8_BE,
32 .code = MEDIA_BUS_FMT_BGR888_1X24, 32 MEDIA_BUS_FMT_BGR565_2X8_LE,
33 .pixelformat = V4L2_PIX_FMT_BGR24, 33 MEDIA_BUS_FMT_RGB565_2X8_BE,
34 .bpp = 3, 34 MEDIA_BUS_FMT_RGB565_2X8_LE,
35 .bayer = false, 35 MEDIA_BUS_FMT_RGB666_1X18,
36 }, 36 MEDIA_BUS_FMT_RBG888_1X24,
37 { 37 MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
38 .code = MEDIA_BUS_FMT_RGB888_1X24, 38 MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
39 .pixelformat = V4L2_PIX_FMT_RGB24, 39 MEDIA_BUS_FMT_BGR888_1X24,
40 .bpp = 3, 40 MEDIA_BUS_FMT_GBR888_1X24,
41 .bayer = false, 41 MEDIA_BUS_FMT_RGB888_1X24,
42 }, 42 MEDIA_BUS_FMT_RGB888_2X12_BE,
43 { 43 MEDIA_BUS_FMT_RGB888_2X12_LE,
44 .code = MEDIA_BUS_FMT_ARGB8888_1X32, 44 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
45 .pixelformat = V4L2_PIX_FMT_ARGB32, 45 MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
46 .bpp = 4, 46 MEDIA_BUS_FMT_ARGB8888_1X32,
47 .bayer = false, 47 MEDIA_BUS_FMT_RGB888_1X32_PADHI,
48 }, 48 MEDIA_BUS_FMT_RGB101010_1X30,
49 49 MEDIA_BUS_FMT_RGB121212_1X36,
50 /* Bayer formats */ 50 MEDIA_BUS_FMT_RGB161616_1X48,
51 { 51 MEDIA_BUS_FMT_Y8_1X8,
52 .code = MEDIA_BUS_FMT_SBGGR8_1X8, 52 MEDIA_BUS_FMT_UV8_1X8,
53 .pixelformat = V4L2_PIX_FMT_SBGGR8, 53 MEDIA_BUS_FMT_UYVY8_1_5X8,
54 .bpp = 1, 54 MEDIA_BUS_FMT_VYUY8_1_5X8,
55 .bayer = true, 55 MEDIA_BUS_FMT_YUYV8_1_5X8,
56 }, 56 MEDIA_BUS_FMT_YVYU8_1_5X8,
57 { 57 MEDIA_BUS_FMT_UYVY8_2X8,
58 .code = MEDIA_BUS_FMT_SGBRG8_1X8, 58 MEDIA_BUS_FMT_VYUY8_2X8,
59 .pixelformat = V4L2_PIX_FMT_SGBRG8, 59 MEDIA_BUS_FMT_YUYV8_2X8,
60 .bpp = 1, 60 MEDIA_BUS_FMT_YVYU8_2X8,
61 .bayer = true, 61 MEDIA_BUS_FMT_Y10_1X10,
62 }, 62 MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
63 { 63 MEDIA_BUS_FMT_UYVY10_2X10,
64 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 64 MEDIA_BUS_FMT_VYUY10_2X10,
65 .pixelformat = V4L2_PIX_FMT_SGRBG8, 65 MEDIA_BUS_FMT_YUYV10_2X10,
66 .bpp = 1, 66 MEDIA_BUS_FMT_YVYU10_2X10,
67 .bayer = true, 67 MEDIA_BUS_FMT_Y12_1X12,
68 }, 68 MEDIA_BUS_FMT_UYVY12_2X12,
69 { 69 MEDIA_BUS_FMT_VYUY12_2X12,
70 .code = MEDIA_BUS_FMT_SRGGB8_1X8, 70 MEDIA_BUS_FMT_YUYV12_2X12,
71 .pixelformat = V4L2_PIX_FMT_SRGGB8, 71 MEDIA_BUS_FMT_YVYU12_2X12,
72 .bpp = 1, 72 MEDIA_BUS_FMT_UYVY8_1X16,
73 .bayer = true, 73 MEDIA_BUS_FMT_VYUY8_1X16,
74 }, 74 MEDIA_BUS_FMT_YUYV8_1X16,
75 { 75 MEDIA_BUS_FMT_YVYU8_1X16,
76 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 76 MEDIA_BUS_FMT_YDYUYDYV8_1X16,
77 .pixelformat = V4L2_PIX_FMT_SBGGR10, 77 MEDIA_BUS_FMT_UYVY10_1X20,
78 .bpp = 2, 78 MEDIA_BUS_FMT_VYUY10_1X20,
79 .bayer = true, 79 MEDIA_BUS_FMT_YUYV10_1X20,
80 }, 80 MEDIA_BUS_FMT_YVYU10_1X20,
81 { 81 MEDIA_BUS_FMT_VUY8_1X24,
82 .code = MEDIA_BUS_FMT_SGBRG10_1X10, 82 MEDIA_BUS_FMT_YUV8_1X24,
83 .pixelformat = V4L2_PIX_FMT_SGBRG10, 83 MEDIA_BUS_FMT_UYYVYY8_0_5X24,
84 .bpp = 2, 84 MEDIA_BUS_FMT_UYVY12_1X24,
85 .bayer = true, 85 MEDIA_BUS_FMT_VYUY12_1X24,
86 }, 86 MEDIA_BUS_FMT_YUYV12_1X24,
87 { 87 MEDIA_BUS_FMT_YVYU12_1X24,
88 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 88 MEDIA_BUS_FMT_YUV10_1X30,
89 .pixelformat = V4L2_PIX_FMT_SGRBG10, 89 MEDIA_BUS_FMT_UYYVYY10_0_5X30,
90 .bpp = 2, 90 MEDIA_BUS_FMT_AYUV8_1X32,
91 .bayer = true, 91 MEDIA_BUS_FMT_UYYVYY12_0_5X36,
92 }, 92 MEDIA_BUS_FMT_YUV12_1X36,
93 { 93 MEDIA_BUS_FMT_YUV16_1X48,
94 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 94 MEDIA_BUS_FMT_UYYVYY16_0_5X48,
95 .pixelformat = V4L2_PIX_FMT_SRGGB10, 95 MEDIA_BUS_FMT_SBGGR8_1X8,
96 .bpp = 2, 96 MEDIA_BUS_FMT_SGBRG8_1X8,
97 .bayer = true, 97 MEDIA_BUS_FMT_SGRBG8_1X8,
98 }, 98 MEDIA_BUS_FMT_SRGGB8_1X8,
99 99 MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
100 /* 10bit raw bayer a-law compressed to 8 bits */ 100 MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
101 { 101 MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
102 .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, 102 MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
103 .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8, 103 MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
104 .bpp = 1, 104 MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
105 .bayer = true, 105 MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
106 }, 106 MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
107 { 107 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
108 .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, 108 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
109 .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8, 109 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE,
110 .bpp = 1, 110 MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE,
111 .bayer = true, 111 MEDIA_BUS_FMT_SBGGR10_1X10,
112 }, 112 MEDIA_BUS_FMT_SGBRG10_1X10,
113 { 113 MEDIA_BUS_FMT_SGRBG10_1X10,
114 .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, 114 MEDIA_BUS_FMT_SRGGB10_1X10,
115 .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8, 115 MEDIA_BUS_FMT_SBGGR12_1X12,
116 .bpp = 1, 116 MEDIA_BUS_FMT_SGBRG12_1X12,
117 .bayer = true, 117 MEDIA_BUS_FMT_SGRBG12_1X12,
118 }, 118 MEDIA_BUS_FMT_SRGGB12_1X12,
119 { 119 MEDIA_BUS_FMT_SBGGR14_1X14,
120 .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, 120 MEDIA_BUS_FMT_SGBRG14_1X14,
121 .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8, 121 MEDIA_BUS_FMT_SGRBG14_1X14,
122 .bpp = 1, 122 MEDIA_BUS_FMT_SRGGB14_1X14,
123 .bayer = true, 123 MEDIA_BUS_FMT_SBGGR16_1X16,
124 }, 124 MEDIA_BUS_FMT_SGBRG16_1X16,
125 125 MEDIA_BUS_FMT_SGRBG16_1X16,
126 /* 10bit raw bayer DPCM compressed to 8 bits */ 126 MEDIA_BUS_FMT_SRGGB16_1X16,
127 { 127 MEDIA_BUS_FMT_JPEG_1X8,
128 .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, 128 MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
129 .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8, 129 MEDIA_BUS_FMT_AHSV8888_1X32,
130 .bpp = 1,
131 .bayer = true,
132 },
133 {
134 .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
135 .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
136 .bpp = 1,
137 .bayer = true,
138 },
139 {
140 .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
141 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
142 .bpp = 1,
143 .bayer = true,
144 },
145 {
146 .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
147 .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
148 .bpp = 1,
149 .bayer = true,
150 },
151 {
152 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
153 .pixelformat = V4L2_PIX_FMT_SBGGR12,
154 .bpp = 2,
155 .bayer = true,
156 },
157 {
158 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
159 .pixelformat = V4L2_PIX_FMT_SGBRG12,
160 .bpp = 2,
161 .bayer = true,
162 },
163 {
164 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
165 .pixelformat = V4L2_PIX_FMT_SGRBG12,
166 .bpp = 2,
167 .bayer = true,
168 },
169 {
170 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
171 .pixelformat = V4L2_PIX_FMT_SRGGB12,
172 .bpp = 2,
173 .bayer = true,
174 },
175}; 130};
176 131
177const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i) 132/* Helper function to check mbus codes */
178{ 133bool vimc_mbus_code_supported(__u32 code)
179 if (i >= ARRAY_SIZE(vimc_pix_map_list))
180 return NULL;
181
182 return &vimc_pix_map_list[i];
183}
184EXPORT_SYMBOL_GPL(vimc_pix_map_by_index);
185
186const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
187{ 134{
188 unsigned int i; 135 unsigned int i;
189 136
190 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { 137 for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++)
191 if (vimc_pix_map_list[i].code == code) 138 if (code == vimc_mbus_list[i])
192 return &vimc_pix_map_list[i]; 139 return true;
193 } 140 return false;
194 return NULL;
195} 141}
196EXPORT_SYMBOL_GPL(vimc_pix_map_by_code); 142EXPORT_SYMBOL_GPL(vimc_mbus_code_supported);
197 143
198const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat) 144/* Helper function to enumerate mbus codes */
145int vimc_enum_mbus_code(struct v4l2_subdev *sd,
146 struct v4l2_subdev_pad_config *cfg,
147 struct v4l2_subdev_mbus_code_enum *code)
199{ 148{
200 unsigned int i; 149 if (code->index >= ARRAY_SIZE(vimc_mbus_list))
150 return -EINVAL;
201 151
202 for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { 152 code->code = vimc_mbus_list[code->index];
203 if (vimc_pix_map_list[i].pixelformat == pixelformat) 153 return 0;
204 return &vimc_pix_map_list[i];
205 }
206 return NULL;
207} 154}
208EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat); 155EXPORT_SYMBOL_GPL(vimc_enum_mbus_code);
209 156
210/* Helper function to allocate and initialize pads */ 157/* Helper function to allocate and initialize pads */
211struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) 158struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
@@ -277,15 +224,13 @@ static int vimc_get_mbus_format(struct media_pad *pad,
277 struct video_device, 224 struct video_device,
278 entity); 225 entity);
279 struct vimc_ent_device *ved = video_get_drvdata(vdev); 226 struct vimc_ent_device *ved = video_get_drvdata(vdev);
280 const struct vimc_pix_map *vpix;
281 struct v4l2_pix_format vdev_fmt; 227 struct v4l2_pix_format vdev_fmt;
282 228
283 if (!ved->vdev_get_format) 229 if (!ved->vdev_get_format)
284 return -ENOIOCTLCMD; 230 return -ENOIOCTLCMD;
285 231
286 ved->vdev_get_format(ved, &vdev_fmt); 232 ved->vdev_get_format(ved, &vdev_fmt);
287 vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat); 233 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0);
288 v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
289 } else { 234 } else {
290 return -EINVAL; 235 return -EINVAL;
291 } 236 }
@@ -325,8 +270,12 @@ int vimc_link_validate(struct media_link *link)
325 /* The width, height and code must match. */ 270 /* The width, height and code must match. */
326 if (source_fmt.format.width != sink_fmt.format.width 271 if (source_fmt.format.width != sink_fmt.format.width
327 || source_fmt.format.height != sink_fmt.format.height 272 || source_fmt.format.height != sink_fmt.format.height
328 || source_fmt.format.code != sink_fmt.format.code) 273 || (source_fmt.format.code && sink_fmt.format.code &&
274 source_fmt.format.code != sink_fmt.format.code)) {
275 pr_err("vimc: format doesn't match in link %s->%s\n",
276 link->source->entity->name, link->sink->entity->name);
329 return -EPIPE; 277 return -EPIPE;
278 }
330 279
331 /* 280 /*
332 * The field order must match, or the sink field order must be NONE 281 * The field order must match, or the sink field order must be NONE