diff options
Diffstat (limited to 'drivers/media/platform/vimc/vimc-common.c')
-rw-r--r-- | drivers/media/platform/vimc/vimc-common.c | 309 |
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 | ||
13 | static 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, | 17 | static 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 */ | 167 | const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i) |
123 | bool 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 | } | ||
174 | EXPORT_SYMBOL_GPL(vimc_pix_map_by_index); | ||
175 | |||
176 | const 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 | } |
132 | EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); | 186 | EXPORT_SYMBOL_GPL(vimc_pix_map_by_code); |
133 | 187 | ||
134 | /* Helper function to enumerate mbus codes */ | 188 | const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat) |
135 | int 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 | } |
145 | EXPORT_SYMBOL_GPL(vimc_enum_mbus_code); | 198 | EXPORT_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 */ |
148 | struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) | 201 | struct 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 |