1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2020 Jernej Skrabec <jernej.skrabec@siol.net> */
3 
4 #include "sun8i-formats.h"
5 #include "sun8i-rotate.h"
6 
7 /*
8  * Formats not included in array:
9  * ROTATE_FORMAT_BGR565
10  * ROTATE_FORMAT_VYUV
11  */
12 
13 static const struct rotate_format rotate_formats[] = {
14 	{
15 		.fourcc = V4L2_PIX_FMT_ARGB32,
16 		.hw_format = ROTATE_FORMAT_ARGB32,
17 		.planes = 1,
18 		.bpp = { 4, 0, 0 },
19 		.hsub = 1,
20 		.vsub = 1,
21 		.flags = ROTATE_FLAG_OUTPUT
22 	}, {
23 		.fourcc = V4L2_PIX_FMT_ABGR32,
24 		.hw_format = ROTATE_FORMAT_ABGR32,
25 		.planes = 1,
26 		.bpp = { 4, 0, 0 },
27 		.hsub = 1,
28 		.vsub = 1,
29 		.flags = ROTATE_FLAG_OUTPUT
30 	}, {
31 		.fourcc = V4L2_PIX_FMT_RGBA32,
32 		.hw_format = ROTATE_FORMAT_RGBA32,
33 		.planes = 1,
34 		.bpp = { 4, 0, 0 },
35 		.hsub = 1,
36 		.vsub = 1,
37 		.flags = ROTATE_FLAG_OUTPUT
38 	}, {
39 		.fourcc = V4L2_PIX_FMT_BGRA32,
40 		.hw_format = ROTATE_FORMAT_BGRA32,
41 		.planes = 1,
42 		.bpp = { 4, 0, 0 },
43 		.hsub = 1,
44 		.vsub = 1,
45 		.flags = ROTATE_FLAG_OUTPUT
46 	}, {
47 		.fourcc = V4L2_PIX_FMT_XRGB32,
48 		.hw_format = ROTATE_FORMAT_XRGB32,
49 		.planes = 1,
50 		.bpp = { 4, 0, 0 },
51 		.hsub = 1,
52 		.vsub = 1,
53 		.flags = ROTATE_FLAG_OUTPUT
54 	}, {
55 		.fourcc = V4L2_PIX_FMT_XBGR32,
56 		.hw_format = ROTATE_FORMAT_XBGR32,
57 		.planes = 1,
58 		.bpp = { 4, 0, 0 },
59 		.hsub = 1,
60 		.vsub = 1,
61 		.flags = ROTATE_FLAG_OUTPUT
62 	}, {
63 		.fourcc = V4L2_PIX_FMT_RGB32,
64 		.hw_format = ROTATE_FORMAT_RGBX32,
65 		.planes = 1,
66 		.bpp = { 4, 0, 0 },
67 		.hsub = 1,
68 		.vsub = 1,
69 		.flags = ROTATE_FLAG_OUTPUT
70 	}, {
71 		.fourcc = V4L2_PIX_FMT_BGR32,
72 		.hw_format = ROTATE_FORMAT_BGRX32,
73 		.planes = 1,
74 		.bpp = { 4, 0, 0 },
75 		.hsub = 1,
76 		.vsub = 1,
77 		.flags = ROTATE_FLAG_OUTPUT
78 	}, {
79 		.fourcc = V4L2_PIX_FMT_RGB24,
80 		.hw_format = ROTATE_FORMAT_RGB24,
81 		.planes = 1,
82 		.bpp = { 3, 0, 0 },
83 		.hsub = 1,
84 		.vsub = 1,
85 		.flags = ROTATE_FLAG_OUTPUT
86 	}, {
87 		.fourcc = V4L2_PIX_FMT_BGR24,
88 		.hw_format = ROTATE_FORMAT_BGR24,
89 		.planes = 1,
90 		.bpp = { 3, 0, 0 },
91 		.hsub = 1,
92 		.vsub = 1,
93 		.flags = ROTATE_FLAG_OUTPUT
94 	}, {
95 		.fourcc = V4L2_PIX_FMT_RGB565,
96 		.hw_format = ROTATE_FORMAT_RGB565,
97 		.planes = 1,
98 		.bpp = { 2, 0, 0 },
99 		.hsub = 1,
100 		.vsub = 1,
101 		.flags = ROTATE_FLAG_OUTPUT
102 	}, {
103 		.fourcc = V4L2_PIX_FMT_ARGB444,
104 		.hw_format = ROTATE_FORMAT_ARGB4444,
105 		.planes = 1,
106 		.bpp = { 2, 0, 0 },
107 		.hsub = 1,
108 		.vsub = 1,
109 		.flags = ROTATE_FLAG_OUTPUT
110 	}, {
111 		.fourcc = V4L2_PIX_FMT_ABGR444,
112 		.hw_format = ROTATE_FORMAT_ABGR4444,
113 		.planes = 1,
114 		.bpp = { 2, 0, 0 },
115 		.hsub = 1,
116 		.vsub = 1,
117 		.flags = ROTATE_FLAG_OUTPUT
118 	}, {
119 		.fourcc = V4L2_PIX_FMT_RGBA444,
120 		.hw_format = ROTATE_FORMAT_RGBA4444,
121 		.planes = 1,
122 		.bpp = { 2, 0, 0 },
123 		.hsub = 1,
124 		.vsub = 1,
125 		.flags = ROTATE_FLAG_OUTPUT
126 	}, {
127 		.fourcc = V4L2_PIX_FMT_BGRA444,
128 		.hw_format = ROTATE_FORMAT_BGRA4444,
129 		.planes = 1,
130 		.bpp = { 2, 0, 0 },
131 		.hsub = 1,
132 		.vsub = 1,
133 		.flags = ROTATE_FLAG_OUTPUT
134 	}, {
135 		.fourcc = V4L2_PIX_FMT_ARGB555,
136 		.hw_format = ROTATE_FORMAT_ARGB1555,
137 		.planes = 1,
138 		.bpp = { 2, 0, 0 },
139 		.hsub = 1,
140 		.vsub = 1,
141 		.flags = ROTATE_FLAG_OUTPUT
142 	}, {
143 		.fourcc = V4L2_PIX_FMT_ABGR555,
144 		.hw_format = ROTATE_FORMAT_ABGR1555,
145 		.planes = 1,
146 		.bpp = { 2, 0, 0 },
147 		.hsub = 1,
148 		.vsub = 1,
149 		.flags = ROTATE_FLAG_OUTPUT
150 	}, {
151 		.fourcc = V4L2_PIX_FMT_RGBA555,
152 		.hw_format = ROTATE_FORMAT_RGBA5551,
153 		.planes = 1,
154 		.bpp = { 2, 0, 0 },
155 		.hsub = 1,
156 		.vsub = 1,
157 		.flags = ROTATE_FLAG_OUTPUT
158 	}, {
159 		.fourcc = V4L2_PIX_FMT_BGRA555,
160 		.hw_format = ROTATE_FORMAT_BGRA5551,
161 		.planes = 1,
162 		.bpp = { 2, 0, 0 },
163 		.hsub = 1,
164 		.vsub = 1,
165 		.flags = ROTATE_FLAG_OUTPUT
166 	}, {
167 		.fourcc = V4L2_PIX_FMT_YVYU,
168 		.hw_format = ROTATE_FORMAT_YVYU,
169 		.planes = 1,
170 		.bpp = { 2, 0, 0 },
171 		.hsub = 2,
172 		.vsub = 1,
173 		.flags = ROTATE_FLAG_YUV
174 	}, {
175 		.fourcc = V4L2_PIX_FMT_UYVY,
176 		.hw_format = ROTATE_FORMAT_UYVY,
177 		.planes = 1,
178 		.bpp = { 2, 0, 0 },
179 		.hsub = 2,
180 		.vsub = 1,
181 		.flags = ROTATE_FLAG_YUV
182 	}, {
183 		.fourcc = V4L2_PIX_FMT_YUYV,
184 		.hw_format = ROTATE_FORMAT_YUYV,
185 		.planes = 1,
186 		.bpp = { 2, 0, 0 },
187 		.hsub = 2,
188 		.vsub = 1,
189 		.flags = ROTATE_FLAG_YUV
190 	}, {
191 		.fourcc = V4L2_PIX_FMT_NV61,
192 		.hw_format = ROTATE_FORMAT_NV61,
193 		.planes = 2,
194 		.bpp = { 1, 2, 0 },
195 		.hsub = 2,
196 		.vsub = 1,
197 		.flags = ROTATE_FLAG_YUV
198 	}, {
199 		.fourcc = V4L2_PIX_FMT_NV16,
200 		.hw_format = ROTATE_FORMAT_NV16,
201 		.planes = 2,
202 		.bpp = { 1, 2, 0 },
203 		.hsub = 2,
204 		.vsub = 1,
205 		.flags = ROTATE_FLAG_YUV
206 	}, {
207 		.fourcc = V4L2_PIX_FMT_YUV422P,
208 		.hw_format = ROTATE_FORMAT_YUV422P,
209 		.planes = 3,
210 		.bpp = { 1, 1, 1 },
211 		.hsub = 2,
212 		.vsub = 1,
213 		.flags = ROTATE_FLAG_YUV
214 	}, {
215 		.fourcc = V4L2_PIX_FMT_NV21,
216 		.hw_format = ROTATE_FORMAT_NV21,
217 		.planes = 2,
218 		.bpp = { 1, 2, 0 },
219 		.hsub = 2,
220 		.vsub = 2,
221 		.flags = ROTATE_FLAG_YUV
222 	}, {
223 		.fourcc = V4L2_PIX_FMT_NV12,
224 		.hw_format = ROTATE_FORMAT_NV12,
225 		.planes = 2,
226 		.bpp = { 1, 2, 0 },
227 		.hsub = 2,
228 		.vsub = 2,
229 		.flags = ROTATE_FLAG_YUV
230 	}, {
231 		.fourcc = V4L2_PIX_FMT_YUV420,
232 		.hw_format = ROTATE_FORMAT_YUV420P,
233 		.planes = 3,
234 		.bpp = { 1, 1, 1 },
235 		.hsub = 2,
236 		.vsub = 2,
237 		.flags = ROTATE_FLAG_YUV | ROTATE_FLAG_OUTPUT
238 	},
239 };
240 
241 const struct rotate_format *rotate_find_format(u32 pixelformat)
242 {
243 	unsigned int i;
244 
245 	for (i = 0; i < ARRAY_SIZE(rotate_formats); i++)
246 		if (rotate_formats[i].fourcc == pixelformat)
247 			return &rotate_formats[i];
248 
249 	return NULL;
250 }
251 
252 int rotate_enum_fmt(struct v4l2_fmtdesc *f, bool dst)
253 {
254 	int i, index;
255 
256 	index = 0;
257 
258 	for (i = 0; i < ARRAY_SIZE(rotate_formats); i++) {
259 		/* not all formats can be used for capture buffers */
260 		if (dst && !(rotate_formats[i].flags & ROTATE_FLAG_OUTPUT))
261 			continue;
262 
263 		if (index == f->index) {
264 			f->pixelformat = rotate_formats[i].fourcc;
265 
266 			return 0;
267 		}
268 
269 		index++;
270 	}
271 
272 	return -EINVAL;
273 }
274