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
13static 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
241const 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
252int 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