1 /*
2  * v4l2-tpg-core.c - Test Pattern Generator
3  *
4  * Note: gen_twopix and tpg_gen_text are based on code from vivi.c. See the
5  * vivi.c source for the copyright information of those functions.
6  *
7  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8  *
9  * This program is free software; you may redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; version 2 of the License.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
17  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 
23 #include <linux/module.h>
24 #include <media/v4l2-tpg.h>
25 
26 /* Must remain in sync with enum tpg_pattern */
27 const char * const tpg_pattern_strings[] = {
28 	"75% Colorbar",
29 	"100% Colorbar",
30 	"CSC Colorbar",
31 	"Horizontal 100% Colorbar",
32 	"100% Color Squares",
33 	"100% Black",
34 	"100% White",
35 	"100% Red",
36 	"100% Green",
37 	"100% Blue",
38 	"16x16 Checkers",
39 	"2x2 Checkers",
40 	"1x1 Checkers",
41 	"2x2 Red/Green Checkers",
42 	"1x1 Red/Green Checkers",
43 	"Alternating Hor Lines",
44 	"Alternating Vert Lines",
45 	"One Pixel Wide Cross",
46 	"Two Pixels Wide Cross",
47 	"Ten Pixels Wide Cross",
48 	"Gray Ramp",
49 	"Noise",
50 	NULL
51 };
52 EXPORT_SYMBOL_GPL(tpg_pattern_strings);
53 
54 /* Must remain in sync with enum tpg_aspect */
55 const char * const tpg_aspect_strings[] = {
56 	"Source Width x Height",
57 	"4x3",
58 	"14x9",
59 	"16x9",
60 	"16x9 Anamorphic",
61 	NULL
62 };
63 EXPORT_SYMBOL_GPL(tpg_aspect_strings);
64 
65 /*
66  * Sine table: sin[0] = 127 * sin(-180 degrees)
67  *             sin[128] = 127 * sin(0 degrees)
68  *             sin[256] = 127 * sin(180 degrees)
69  */
70 static const s8 sin[257] = {
71 	   0,   -4,   -7,  -11,  -13,  -18,  -20,  -22,  -26,  -29,  -33,  -35,  -37,  -41,  -43,  -48,
72 	 -50,  -52,  -56,  -58,  -62,  -63,  -65,  -69,  -71,  -75,  -76,  -78,  -82,  -83,  -87,  -88,
73 	 -90,  -93,  -94,  -97,  -99, -101, -103, -104, -107, -108, -110, -111, -112, -114, -115, -117,
74 	-118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -127, -127, -127, -127,
75 	-127, -127, -127, -127, -126, -126, -125, -125, -124, -124, -123, -122, -121, -120, -119, -118,
76 	-117, -116, -114, -113, -111, -110, -109, -107, -105, -103, -101, -100,  -97,  -96,  -93,  -91,
77 	 -90,  -87,  -85,  -82,  -80,  -76,  -75,  -73,  -69,  -67,  -63,  -62,  -60,  -56,  -54,  -50,
78 	 -48,  -46,  -41,  -39,  -35,  -33,  -31,  -26,  -24,  -20,  -18,  -15,  -11,   -9,   -4,   -2,
79 	   0,    2,    4,    9,   11,   15,   18,   20,   24,   26,   31,   33,   35,   39,   41,   46,
80 	  48,   50,   54,   56,   60,   62,   64,   67,   69,   73,   75,   76,   80,   82,   85,   87,
81 	  90,   91,   93,   96,   97,  100,  101,  103,  105,  107,  109,  110,  111,  113,  114,  116,
82 	 117,  118,  119,  120,  121,  122,  123,  124,  124,  125,  125,  126,  126,  127,  127,  127,
83 	 127,  127,  127,  127,  127,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,
84 	 118,  117,  115,  114,  112,  111,  110,  108,  107,  104,  103,  101,   99,   97,   94,   93,
85 	  90,   88,   87,   83,   82,   78,   76,   75,   71,   69,   65,   64,   62,   58,   56,   52,
86 	  50,   48,   43,   41,   37,   35,   33,   29,   26,   22,   20,   18,   13,   11,    7,    4,
87 	   0,
88 };
89 
90 #define cos(idx) sin[((idx) + 64) % sizeof(sin)]
91 
92 /* Global font descriptor */
93 static const u8 *font8x16;
94 
95 void tpg_set_font(const u8 *f)
96 {
97 	font8x16 = f;
98 }
99 EXPORT_SYMBOL_GPL(tpg_set_font);
100 
101 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
102 {
103 	memset(tpg, 0, sizeof(*tpg));
104 	tpg->scaled_width = tpg->src_width = w;
105 	tpg->src_height = tpg->buf_height = h;
106 	tpg->crop.width = tpg->compose.width = w;
107 	tpg->crop.height = tpg->compose.height = h;
108 	tpg->recalc_colors = true;
109 	tpg->recalc_square_border = true;
110 	tpg->brightness = 128;
111 	tpg->contrast = 128;
112 	tpg->saturation = 128;
113 	tpg->hue = 0;
114 	tpg->mv_hor_mode = TPG_MOVE_NONE;
115 	tpg->mv_vert_mode = TPG_MOVE_NONE;
116 	tpg->field = V4L2_FIELD_NONE;
117 	tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
118 	tpg->colorspace = V4L2_COLORSPACE_SRGB;
119 	tpg->perc_fill = 100;
120 }
121 EXPORT_SYMBOL_GPL(tpg_init);
122 
123 int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
124 {
125 	unsigned pat;
126 	unsigned plane;
127 
128 	tpg->max_line_width = max_w;
129 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
130 		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
131 			unsigned pixelsz = plane ? 2 : 4;
132 
133 			tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
134 			if (!tpg->lines[pat][plane])
135 				return -ENOMEM;
136 			if (plane == 0)
137 				continue;
138 			tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
139 			if (!tpg->downsampled_lines[pat][plane])
140 				return -ENOMEM;
141 		}
142 	}
143 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
144 		unsigned pixelsz = plane ? 2 : 4;
145 
146 		tpg->contrast_line[plane] = vzalloc(max_w * pixelsz);
147 		if (!tpg->contrast_line[plane])
148 			return -ENOMEM;
149 		tpg->black_line[plane] = vzalloc(max_w * pixelsz);
150 		if (!tpg->black_line[plane])
151 			return -ENOMEM;
152 		tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz);
153 		if (!tpg->random_line[plane])
154 			return -ENOMEM;
155 	}
156 	return 0;
157 }
158 EXPORT_SYMBOL_GPL(tpg_alloc);
159 
160 void tpg_free(struct tpg_data *tpg)
161 {
162 	unsigned pat;
163 	unsigned plane;
164 
165 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
166 		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
167 			vfree(tpg->lines[pat][plane]);
168 			tpg->lines[pat][plane] = NULL;
169 			if (plane == 0)
170 				continue;
171 			vfree(tpg->downsampled_lines[pat][plane]);
172 			tpg->downsampled_lines[pat][plane] = NULL;
173 		}
174 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
175 		vfree(tpg->contrast_line[plane]);
176 		vfree(tpg->black_line[plane]);
177 		vfree(tpg->random_line[plane]);
178 		tpg->contrast_line[plane] = NULL;
179 		tpg->black_line[plane] = NULL;
180 		tpg->random_line[plane] = NULL;
181 	}
182 }
183 EXPORT_SYMBOL_GPL(tpg_free);
184 
185 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
186 {
187 	tpg->fourcc = fourcc;
188 	tpg->planes = 1;
189 	tpg->buffers = 1;
190 	tpg->recalc_colors = true;
191 	tpg->interleaved = false;
192 	tpg->vdownsampling[0] = 1;
193 	tpg->hdownsampling[0] = 1;
194 	tpg->hmask[0] = ~0;
195 	tpg->hmask[1] = ~0;
196 	tpg->hmask[2] = ~0;
197 
198 	switch (fourcc) {
199 	case V4L2_PIX_FMT_SBGGR8:
200 	case V4L2_PIX_FMT_SGBRG8:
201 	case V4L2_PIX_FMT_SGRBG8:
202 	case V4L2_PIX_FMT_SRGGB8:
203 	case V4L2_PIX_FMT_SBGGR10:
204 	case V4L2_PIX_FMT_SGBRG10:
205 	case V4L2_PIX_FMT_SGRBG10:
206 	case V4L2_PIX_FMT_SRGGB10:
207 	case V4L2_PIX_FMT_SBGGR12:
208 	case V4L2_PIX_FMT_SGBRG12:
209 	case V4L2_PIX_FMT_SGRBG12:
210 	case V4L2_PIX_FMT_SRGGB12:
211 		tpg->interleaved = true;
212 		tpg->vdownsampling[1] = 1;
213 		tpg->hdownsampling[1] = 1;
214 		tpg->planes = 2;
215 		/* fall through */
216 	case V4L2_PIX_FMT_RGB332:
217 	case V4L2_PIX_FMT_RGB565:
218 	case V4L2_PIX_FMT_RGB565X:
219 	case V4L2_PIX_FMT_RGB444:
220 	case V4L2_PIX_FMT_XRGB444:
221 	case V4L2_PIX_FMT_ARGB444:
222 	case V4L2_PIX_FMT_RGB555:
223 	case V4L2_PIX_FMT_XRGB555:
224 	case V4L2_PIX_FMT_ARGB555:
225 	case V4L2_PIX_FMT_RGB555X:
226 	case V4L2_PIX_FMT_XRGB555X:
227 	case V4L2_PIX_FMT_ARGB555X:
228 	case V4L2_PIX_FMT_BGR666:
229 	case V4L2_PIX_FMT_RGB24:
230 	case V4L2_PIX_FMT_BGR24:
231 	case V4L2_PIX_FMT_RGB32:
232 	case V4L2_PIX_FMT_BGR32:
233 	case V4L2_PIX_FMT_XRGB32:
234 	case V4L2_PIX_FMT_XBGR32:
235 	case V4L2_PIX_FMT_ARGB32:
236 	case V4L2_PIX_FMT_ABGR32:
237 		tpg->color_enc = TGP_COLOR_ENC_RGB;
238 		break;
239 	case V4L2_PIX_FMT_GREY:
240 	case V4L2_PIX_FMT_Y16:
241 	case V4L2_PIX_FMT_Y16_BE:
242 		tpg->color_enc = TGP_COLOR_ENC_LUMA;
243 		break;
244 	case V4L2_PIX_FMT_YUV444:
245 	case V4L2_PIX_FMT_YUV555:
246 	case V4L2_PIX_FMT_YUV565:
247 	case V4L2_PIX_FMT_YUV32:
248 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
249 		break;
250 	case V4L2_PIX_FMT_YUV420M:
251 	case V4L2_PIX_FMT_YVU420M:
252 		tpg->buffers = 3;
253 		/* fall through */
254 	case V4L2_PIX_FMT_YUV420:
255 	case V4L2_PIX_FMT_YVU420:
256 		tpg->vdownsampling[1] = 2;
257 		tpg->vdownsampling[2] = 2;
258 		tpg->hdownsampling[1] = 2;
259 		tpg->hdownsampling[2] = 2;
260 		tpg->planes = 3;
261 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
262 		break;
263 	case V4L2_PIX_FMT_YUV422M:
264 	case V4L2_PIX_FMT_YVU422M:
265 		tpg->buffers = 3;
266 		/* fall through */
267 	case V4L2_PIX_FMT_YUV422P:
268 		tpg->vdownsampling[1] = 1;
269 		tpg->vdownsampling[2] = 1;
270 		tpg->hdownsampling[1] = 2;
271 		tpg->hdownsampling[2] = 2;
272 		tpg->planes = 3;
273 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
274 		break;
275 	case V4L2_PIX_FMT_NV16M:
276 	case V4L2_PIX_FMT_NV61M:
277 		tpg->buffers = 2;
278 		/* fall through */
279 	case V4L2_PIX_FMT_NV16:
280 	case V4L2_PIX_FMT_NV61:
281 		tpg->vdownsampling[1] = 1;
282 		tpg->hdownsampling[1] = 1;
283 		tpg->hmask[1] = ~1;
284 		tpg->planes = 2;
285 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
286 		break;
287 	case V4L2_PIX_FMT_NV12M:
288 	case V4L2_PIX_FMT_NV21M:
289 		tpg->buffers = 2;
290 		/* fall through */
291 	case V4L2_PIX_FMT_NV12:
292 	case V4L2_PIX_FMT_NV21:
293 		tpg->vdownsampling[1] = 2;
294 		tpg->hdownsampling[1] = 1;
295 		tpg->hmask[1] = ~1;
296 		tpg->planes = 2;
297 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
298 		break;
299 	case V4L2_PIX_FMT_YUV444M:
300 	case V4L2_PIX_FMT_YVU444M:
301 		tpg->buffers = 3;
302 		tpg->planes = 3;
303 		tpg->vdownsampling[1] = 1;
304 		tpg->vdownsampling[2] = 1;
305 		tpg->hdownsampling[1] = 1;
306 		tpg->hdownsampling[2] = 1;
307 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
308 		break;
309 	case V4L2_PIX_FMT_NV24:
310 	case V4L2_PIX_FMT_NV42:
311 		tpg->vdownsampling[1] = 1;
312 		tpg->hdownsampling[1] = 1;
313 		tpg->planes = 2;
314 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
315 		break;
316 	case V4L2_PIX_FMT_YUYV:
317 	case V4L2_PIX_FMT_UYVY:
318 	case V4L2_PIX_FMT_YVYU:
319 	case V4L2_PIX_FMT_VYUY:
320 		tpg->hmask[0] = ~1;
321 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
322 		break;
323 	case V4L2_PIX_FMT_HSV24:
324 	case V4L2_PIX_FMT_HSV32:
325 		tpg->color_enc = TGP_COLOR_ENC_HSV;
326 		break;
327 	default:
328 		return false;
329 	}
330 
331 	switch (fourcc) {
332 	case V4L2_PIX_FMT_GREY:
333 	case V4L2_PIX_FMT_RGB332:
334 		tpg->twopixelsize[0] = 2;
335 		break;
336 	case V4L2_PIX_FMT_RGB565:
337 	case V4L2_PIX_FMT_RGB565X:
338 	case V4L2_PIX_FMT_RGB444:
339 	case V4L2_PIX_FMT_XRGB444:
340 	case V4L2_PIX_FMT_ARGB444:
341 	case V4L2_PIX_FMT_RGB555:
342 	case V4L2_PIX_FMT_XRGB555:
343 	case V4L2_PIX_FMT_ARGB555:
344 	case V4L2_PIX_FMT_RGB555X:
345 	case V4L2_PIX_FMT_XRGB555X:
346 	case V4L2_PIX_FMT_ARGB555X:
347 	case V4L2_PIX_FMT_YUYV:
348 	case V4L2_PIX_FMT_UYVY:
349 	case V4L2_PIX_FMT_YVYU:
350 	case V4L2_PIX_FMT_VYUY:
351 	case V4L2_PIX_FMT_YUV444:
352 	case V4L2_PIX_FMT_YUV555:
353 	case V4L2_PIX_FMT_YUV565:
354 	case V4L2_PIX_FMT_Y16:
355 	case V4L2_PIX_FMT_Y16_BE:
356 		tpg->twopixelsize[0] = 2 * 2;
357 		break;
358 	case V4L2_PIX_FMT_RGB24:
359 	case V4L2_PIX_FMT_BGR24:
360 	case V4L2_PIX_FMT_HSV24:
361 		tpg->twopixelsize[0] = 2 * 3;
362 		break;
363 	case V4L2_PIX_FMT_BGR666:
364 	case V4L2_PIX_FMT_RGB32:
365 	case V4L2_PIX_FMT_BGR32:
366 	case V4L2_PIX_FMT_XRGB32:
367 	case V4L2_PIX_FMT_XBGR32:
368 	case V4L2_PIX_FMT_ARGB32:
369 	case V4L2_PIX_FMT_ABGR32:
370 	case V4L2_PIX_FMT_YUV32:
371 	case V4L2_PIX_FMT_HSV32:
372 		tpg->twopixelsize[0] = 2 * 4;
373 		break;
374 	case V4L2_PIX_FMT_NV12:
375 	case V4L2_PIX_FMT_NV21:
376 	case V4L2_PIX_FMT_NV12M:
377 	case V4L2_PIX_FMT_NV21M:
378 	case V4L2_PIX_FMT_NV16:
379 	case V4L2_PIX_FMT_NV61:
380 	case V4L2_PIX_FMT_NV16M:
381 	case V4L2_PIX_FMT_NV61M:
382 	case V4L2_PIX_FMT_SBGGR8:
383 	case V4L2_PIX_FMT_SGBRG8:
384 	case V4L2_PIX_FMT_SGRBG8:
385 	case V4L2_PIX_FMT_SRGGB8:
386 		tpg->twopixelsize[0] = 2;
387 		tpg->twopixelsize[1] = 2;
388 		break;
389 	case V4L2_PIX_FMT_SRGGB10:
390 	case V4L2_PIX_FMT_SGRBG10:
391 	case V4L2_PIX_FMT_SGBRG10:
392 	case V4L2_PIX_FMT_SBGGR10:
393 	case V4L2_PIX_FMT_SRGGB12:
394 	case V4L2_PIX_FMT_SGRBG12:
395 	case V4L2_PIX_FMT_SGBRG12:
396 	case V4L2_PIX_FMT_SBGGR12:
397 		tpg->twopixelsize[0] = 4;
398 		tpg->twopixelsize[1] = 4;
399 		break;
400 	case V4L2_PIX_FMT_YUV444M:
401 	case V4L2_PIX_FMT_YVU444M:
402 	case V4L2_PIX_FMT_YUV422M:
403 	case V4L2_PIX_FMT_YVU422M:
404 	case V4L2_PIX_FMT_YUV422P:
405 	case V4L2_PIX_FMT_YUV420:
406 	case V4L2_PIX_FMT_YVU420:
407 	case V4L2_PIX_FMT_YUV420M:
408 	case V4L2_PIX_FMT_YVU420M:
409 		tpg->twopixelsize[0] = 2;
410 		tpg->twopixelsize[1] = 2;
411 		tpg->twopixelsize[2] = 2;
412 		break;
413 	case V4L2_PIX_FMT_NV24:
414 	case V4L2_PIX_FMT_NV42:
415 		tpg->twopixelsize[0] = 2;
416 		tpg->twopixelsize[1] = 4;
417 		break;
418 	}
419 	return true;
420 }
421 EXPORT_SYMBOL_GPL(tpg_s_fourcc);
422 
423 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
424 		const struct v4l2_rect *compose)
425 {
426 	tpg->crop = *crop;
427 	tpg->compose = *compose;
428 	tpg->scaled_width = (tpg->src_width * tpg->compose.width +
429 				 tpg->crop.width - 1) / tpg->crop.width;
430 	tpg->scaled_width &= ~1;
431 	if (tpg->scaled_width > tpg->max_line_width)
432 		tpg->scaled_width = tpg->max_line_width;
433 	if (tpg->scaled_width < 2)
434 		tpg->scaled_width = 2;
435 	tpg->recalc_lines = true;
436 }
437 EXPORT_SYMBOL_GPL(tpg_s_crop_compose);
438 
439 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
440 		       u32 field)
441 {
442 	unsigned p;
443 
444 	tpg->src_width = width;
445 	tpg->src_height = height;
446 	tpg->field = field;
447 	tpg->buf_height = height;
448 	if (V4L2_FIELD_HAS_T_OR_B(field))
449 		tpg->buf_height /= 2;
450 	tpg->scaled_width = width;
451 	tpg->crop.top = tpg->crop.left = 0;
452 	tpg->crop.width = width;
453 	tpg->crop.height = height;
454 	tpg->compose.top = tpg->compose.left = 0;
455 	tpg->compose.width = width;
456 	tpg->compose.height = tpg->buf_height;
457 	for (p = 0; p < tpg->planes; p++)
458 		tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
459 				       (2 * tpg->hdownsampling[p]);
460 	tpg->recalc_square_border = true;
461 }
462 EXPORT_SYMBOL_GPL(tpg_reset_source);
463 
464 static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
465 {
466 	switch (tpg->pattern) {
467 	case TPG_PAT_BLACK:
468 		return TPG_COLOR_100_WHITE;
469 	case TPG_PAT_CSC_COLORBAR:
470 		return TPG_COLOR_CSC_BLACK;
471 	default:
472 		return TPG_COLOR_100_BLACK;
473 	}
474 }
475 
476 static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
477 {
478 	switch (tpg->pattern) {
479 	case TPG_PAT_75_COLORBAR:
480 	case TPG_PAT_CSC_COLORBAR:
481 		return TPG_COLOR_CSC_WHITE;
482 	case TPG_PAT_BLACK:
483 		return TPG_COLOR_100_BLACK;
484 	default:
485 		return TPG_COLOR_100_WHITE;
486 	}
487 }
488 
489 static inline int rec709_to_linear(int v)
490 {
491 	v = clamp(v, 0, 0xff0);
492 	return tpg_rec709_to_linear[v];
493 }
494 
495 static inline int linear_to_rec709(int v)
496 {
497 	v = clamp(v, 0, 0xff0);
498 	return tpg_linear_to_rec709[v];
499 }
500 
501 static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
502 			   int *h, int *s, int *v)
503 {
504 	int max_rgb, min_rgb, diff_rgb;
505 	int aux;
506 	int third;
507 	int third_size;
508 
509 	r >>= 4;
510 	g >>= 4;
511 	b >>= 4;
512 
513 	/* Value */
514 	max_rgb = max3(r, g, b);
515 	*v = max_rgb;
516 	if (!max_rgb) {
517 		*h = 0;
518 		*s = 0;
519 		return;
520 	}
521 
522 	/* Saturation */
523 	min_rgb = min3(r, g, b);
524 	diff_rgb = max_rgb - min_rgb;
525 	aux = 255 * diff_rgb;
526 	aux += max_rgb / 2;
527 	aux /= max_rgb;
528 	*s = aux;
529 	if (!aux) {
530 		*h = 0;
531 		return;
532 	}
533 
534 	third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85;
535 
536 	/* Hue */
537 	if (max_rgb == r) {
538 		aux =  g - b;
539 		third = 0;
540 	} else if (max_rgb == g) {
541 		aux =  b - r;
542 		third = third_size;
543 	} else {
544 		aux =  r - g;
545 		third = third_size * 2;
546 	}
547 
548 	aux *= third_size / 2;
549 	aux += diff_rgb / 2;
550 	aux /= diff_rgb;
551 	aux += third;
552 
553 	/* Clamp Hue */
554 	if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) {
555 		if (aux < 0)
556 			aux += 180;
557 		else if (aux > 180)
558 			aux -= 180;
559 	} else {
560 		aux = aux & 0xff;
561 	}
562 
563 	*h = aux;
564 }
565 
566 static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
567 			int y_offset, int *y, int *cb, int *cr)
568 {
569 	*y  = ((m[0][0] * r + m[0][1] * g + m[0][2] * b) >> 16) + (y_offset << 4);
570 	*cb = ((m[1][0] * r + m[1][1] * g + m[1][2] * b) >> 16) + (128 << 4);
571 	*cr = ((m[2][0] * r + m[2][1] * g + m[2][2] * b) >> 16) + (128 << 4);
572 }
573 
574 static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
575 			   int *y, int *cb, int *cr)
576 {
577 #define COEFF(v, r) ((int)(0.5 + (v) * (r) * 256.0))
578 
579 	static const int bt601[3][3] = {
580 		{ COEFF(0.299, 219),   COEFF(0.587, 219),   COEFF(0.114, 219)   },
581 		{ COEFF(-0.1687, 224), COEFF(-0.3313, 224), COEFF(0.5, 224)     },
582 		{ COEFF(0.5, 224),     COEFF(-0.4187, 224), COEFF(-0.0813, 224) },
583 	};
584 	static const int bt601_full[3][3] = {
585 		{ COEFF(0.299, 255),   COEFF(0.587, 255),   COEFF(0.114, 255)   },
586 		{ COEFF(-0.1687, 255), COEFF(-0.3313, 255), COEFF(0.5, 255)     },
587 		{ COEFF(0.5, 255),     COEFF(-0.4187, 255), COEFF(-0.0813, 255) },
588 	};
589 	static const int rec709[3][3] = {
590 		{ COEFF(0.2126, 219),  COEFF(0.7152, 219),  COEFF(0.0722, 219)  },
591 		{ COEFF(-0.1146, 224), COEFF(-0.3854, 224), COEFF(0.5, 224)     },
592 		{ COEFF(0.5, 224),     COEFF(-0.4542, 224), COEFF(-0.0458, 224) },
593 	};
594 	static const int rec709_full[3][3] = {
595 		{ COEFF(0.2126, 255),  COEFF(0.7152, 255),  COEFF(0.0722, 255)  },
596 		{ COEFF(-0.1146, 255), COEFF(-0.3854, 255), COEFF(0.5, 255)     },
597 		{ COEFF(0.5, 255),     COEFF(-0.4542, 255), COEFF(-0.0458, 255) },
598 	};
599 	static const int smpte240m[3][3] = {
600 		{ COEFF(0.212, 219),  COEFF(0.701, 219),  COEFF(0.087, 219)  },
601 		{ COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224)    },
602 		{ COEFF(0.5, 224),    COEFF(-0.445, 224), COEFF(-0.055, 224) },
603 	};
604 	static const int smpte240m_full[3][3] = {
605 		{ COEFF(0.212, 255),  COEFF(0.701, 255),  COEFF(0.087, 255)  },
606 		{ COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255)    },
607 		{ COEFF(0.5, 255),    COEFF(-0.445, 255), COEFF(-0.055, 255) },
608 	};
609 	static const int bt2020[3][3] = {
610 		{ COEFF(0.2627, 219),  COEFF(0.6780, 219),  COEFF(0.0593, 219)  },
611 		{ COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224)     },
612 		{ COEFF(0.5, 224),     COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
613 	};
614 	static const int bt2020_full[3][3] = {
615 		{ COEFF(0.2627, 255),  COEFF(0.6780, 255),  COEFF(0.0593, 255)  },
616 		{ COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255)     },
617 		{ COEFF(0.5, 255),     COEFF(-0.4698, 255), COEFF(-0.0402, 255) },
618 	};
619 	static const int bt2020c[4] = {
620 		COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224),
621 		COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224),
622 	};
623 	static const int bt2020c_full[4] = {
624 		COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255),
625 		COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255),
626 	};
627 
628 	bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
629 	unsigned y_offset = full ? 0 : 16;
630 	int lin_y, yc;
631 
632 	switch (tpg->real_ycbcr_enc) {
633 	case V4L2_YCBCR_ENC_601:
634 		rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr);
635 		break;
636 	case V4L2_YCBCR_ENC_XV601:
637 		/* Ignore quantization range, there is only one possible
638 		 * Y'CbCr encoding. */
639 		rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr);
640 		break;
641 	case V4L2_YCBCR_ENC_XV709:
642 		/* Ignore quantization range, there is only one possible
643 		 * Y'CbCr encoding. */
644 		rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr);
645 		break;
646 	case V4L2_YCBCR_ENC_BT2020:
647 		rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr);
648 		break;
649 	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
650 		lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) +
651 			 COEFF(0.6780, 255) * rec709_to_linear(g) +
652 			 COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16;
653 		yc = linear_to_rec709(lin_y);
654 		*y = full ? yc : (yc * 219) / 255 + (16 << 4);
655 		if (b <= yc)
656 			*cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4);
657 		else
658 			*cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4);
659 		if (r <= yc)
660 			*cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4);
661 		else
662 			*cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4);
663 		break;
664 	case V4L2_YCBCR_ENC_SMPTE240M:
665 		rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr);
666 		break;
667 	case V4L2_YCBCR_ENC_709:
668 	default:
669 		rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr);
670 		break;
671 	}
672 }
673 
674 static void ycbcr2rgb(const int m[3][3], int y, int cb, int cr,
675 			int y_offset, int *r, int *g, int *b)
676 {
677 	y -= y_offset << 4;
678 	cb -= 128 << 4;
679 	cr -= 128 << 4;
680 	*r = m[0][0] * y + m[0][1] * cb + m[0][2] * cr;
681 	*g = m[1][0] * y + m[1][1] * cb + m[1][2] * cr;
682 	*b = m[2][0] * y + m[2][1] * cb + m[2][2] * cr;
683 	*r = clamp(*r >> 12, 0, 0xff0);
684 	*g = clamp(*g >> 12, 0, 0xff0);
685 	*b = clamp(*b >> 12, 0, 0xff0);
686 }
687 
688 static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
689 			   int *r, int *g, int *b)
690 {
691 #undef COEFF
692 #define COEFF(v, r) ((int)(0.5 + (v) * ((255.0 * 255.0 * 16.0) / (r))))
693 	static const int bt601[3][3] = {
694 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.4020, 224)  },
695 		{ COEFF(1, 219), COEFF(-0.3441, 224), COEFF(-0.7141, 224) },
696 		{ COEFF(1, 219), COEFF(1.7720, 224),  COEFF(0, 224)       },
697 	};
698 	static const int bt601_full[3][3] = {
699 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.4020, 255)  },
700 		{ COEFF(1, 255), COEFF(-0.3441, 255), COEFF(-0.7141, 255) },
701 		{ COEFF(1, 255), COEFF(1.7720, 255),  COEFF(0, 255)       },
702 	};
703 	static const int rec709[3][3] = {
704 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.5748, 224)  },
705 		{ COEFF(1, 219), COEFF(-0.1873, 224), COEFF(-0.4681, 224) },
706 		{ COEFF(1, 219), COEFF(1.8556, 224),  COEFF(0, 224)       },
707 	};
708 	static const int rec709_full[3][3] = {
709 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.5748, 255)  },
710 		{ COEFF(1, 255), COEFF(-0.1873, 255), COEFF(-0.4681, 255) },
711 		{ COEFF(1, 255), COEFF(1.8556, 255),  COEFF(0, 255)       },
712 	};
713 	static const int smpte240m[3][3] = {
714 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.5756, 224)  },
715 		{ COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) },
716 		{ COEFF(1, 219), COEFF(1.8270, 224),  COEFF(0, 224)       },
717 	};
718 	static const int smpte240m_full[3][3] = {
719 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.5756, 255)  },
720 		{ COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) },
721 		{ COEFF(1, 255), COEFF(1.8270, 255),  COEFF(0, 255)       },
722 	};
723 	static const int bt2020[3][3] = {
724 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.4746, 224)  },
725 		{ COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) },
726 		{ COEFF(1, 219), COEFF(1.8814, 224),  COEFF(0, 224)       },
727 	};
728 	static const int bt2020_full[3][3] = {
729 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.4746, 255)  },
730 		{ COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) },
731 		{ COEFF(1, 255), COEFF(1.8814, 255),  COEFF(0, 255)       },
732 	};
733 	static const int bt2020c[4] = {
734 		COEFF(1.9404, 224), COEFF(1.5816, 224),
735 		COEFF(1.7184, 224), COEFF(0.9936, 224),
736 	};
737 	static const int bt2020c_full[4] = {
738 		COEFF(1.9404, 255), COEFF(1.5816, 255),
739 		COEFF(1.7184, 255), COEFF(0.9936, 255),
740 	};
741 
742 	bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
743 	unsigned y_offset = full ? 0 : 16;
744 	int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219);
745 	int lin_r, lin_g, lin_b, lin_y;
746 
747 	switch (tpg->real_ycbcr_enc) {
748 	case V4L2_YCBCR_ENC_601:
749 		ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b);
750 		break;
751 	case V4L2_YCBCR_ENC_XV601:
752 		/* Ignore quantization range, there is only one possible
753 		 * Y'CbCr encoding. */
754 		ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b);
755 		break;
756 	case V4L2_YCBCR_ENC_XV709:
757 		/* Ignore quantization range, there is only one possible
758 		 * Y'CbCr encoding. */
759 		ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b);
760 		break;
761 	case V4L2_YCBCR_ENC_BT2020:
762 		ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b);
763 		break;
764 	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
765 		y -= full ? 0 : 16 << 4;
766 		cb -= 128 << 4;
767 		cr -= 128 << 4;
768 
769 		if (cb <= 0)
770 			*b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb;
771 		else
772 			*b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb;
773 		*b = *b >> 12;
774 		if (cr <= 0)
775 			*r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr;
776 		else
777 			*r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr;
778 		*r = *r >> 12;
779 		lin_r = rec709_to_linear(*r);
780 		lin_b = rec709_to_linear(*b);
781 		lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219));
782 
783 		lin_g = COEFF(1.0 / 0.6780, 255) * lin_y -
784 			COEFF(0.2627 / 0.6780, 255) * lin_r -
785 			COEFF(0.0593 / 0.6780, 255) * lin_b;
786 		*g = linear_to_rec709(lin_g >> 12);
787 		break;
788 	case V4L2_YCBCR_ENC_SMPTE240M:
789 		ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b);
790 		break;
791 	case V4L2_YCBCR_ENC_709:
792 	default:
793 		ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b);
794 		break;
795 	}
796 }
797 
798 /* precalculate color bar values to speed up rendering */
799 static void precalculate_color(struct tpg_data *tpg, int k)
800 {
801 	int col = k;
802 	int r = tpg_colors[col].r;
803 	int g = tpg_colors[col].g;
804 	int b = tpg_colors[col].b;
805 	int y, cb, cr;
806 	bool ycbcr_valid = false;
807 
808 	if (k == TPG_COLOR_TEXTBG) {
809 		col = tpg_get_textbg_color(tpg);
810 
811 		r = tpg_colors[col].r;
812 		g = tpg_colors[col].g;
813 		b = tpg_colors[col].b;
814 	} else if (k == TPG_COLOR_TEXTFG) {
815 		col = tpg_get_textfg_color(tpg);
816 
817 		r = tpg_colors[col].r;
818 		g = tpg_colors[col].g;
819 		b = tpg_colors[col].b;
820 	} else if (tpg->pattern == TPG_PAT_NOISE) {
821 		r = g = b = prandom_u32_max(256);
822 	} else if (k == TPG_COLOR_RANDOM) {
823 		r = g = b = tpg->qual_offset + prandom_u32_max(196);
824 	} else if (k >= TPG_COLOR_RAMP) {
825 		r = g = b = k - TPG_COLOR_RAMP;
826 	}
827 
828 	if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
829 		r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
830 		g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
831 		b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
832 	} else {
833 		r <<= 4;
834 		g <<= 4;
835 		b <<= 4;
836 	}
837 
838 	if (tpg->qual == TPG_QUAL_GRAY ||
839 	    tpg->color_enc ==  TGP_COLOR_ENC_LUMA) {
840 		/* Rec. 709 Luma function */
841 		/* (0.2126, 0.7152, 0.0722) * (255 * 256) */
842 		r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
843 	}
844 
845 	/*
846 	 * The assumption is that the RGB output is always full range,
847 	 * so only if the rgb_range overrides the 'real' rgb range do
848 	 * we need to convert the RGB values.
849 	 *
850 	 * Remember that r, g and b are still in the 0 - 0xff0 range.
851 	 */
852 	if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
853 	    tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL &&
854 	    tpg->color_enc == TGP_COLOR_ENC_RGB) {
855 		/*
856 		 * Convert from full range (which is what r, g and b are)
857 		 * to limited range (which is the 'real' RGB range), which
858 		 * is then interpreted as full range.
859 		 */
860 		r = (r * 219) / 255 + (16 << 4);
861 		g = (g * 219) / 255 + (16 << 4);
862 		b = (b * 219) / 255 + (16 << 4);
863 	} else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
864 		   tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
865 		   tpg->color_enc == TGP_COLOR_ENC_RGB) {
866 
867 		/*
868 		 * Clamp r, g and b to the limited range and convert to full
869 		 * range since that's what we deliver.
870 		 */
871 		r = clamp(r, 16 << 4, 235 << 4);
872 		g = clamp(g, 16 << 4, 235 << 4);
873 		b = clamp(b, 16 << 4, 235 << 4);
874 		r = (r - (16 << 4)) * 255 / 219;
875 		g = (g - (16 << 4)) * 255 / 219;
876 		b = (b - (16 << 4)) * 255 / 219;
877 	}
878 
879 	if ((tpg->brightness != 128 || tpg->contrast != 128 ||
880 	     tpg->saturation != 128 || tpg->hue) &&
881 	    tpg->color_enc != TGP_COLOR_ENC_LUMA) {
882 		/* Implement these operations */
883 		int tmp_cb, tmp_cr;
884 
885 		/* First convert to YCbCr */
886 
887 		color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
888 
889 		y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
890 		y += (tpg->brightness << 4) - (128 << 4);
891 
892 		cb -= 128 << 4;
893 		cr -= 128 << 4;
894 		tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
895 		tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
896 
897 		cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
898 		cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
899 		if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
900 			ycbcr_valid = true;
901 		else
902 			ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
903 	} else if ((tpg->brightness != 128 || tpg->contrast != 128) &&
904 		   tpg->color_enc == TGP_COLOR_ENC_LUMA) {
905 		r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128;
906 		r += (tpg->brightness << 4) - (128 << 4);
907 	}
908 
909 	switch (tpg->color_enc) {
910 	case TGP_COLOR_ENC_HSV:
911 	{
912 		int h, s, v;
913 
914 		color_to_hsv(tpg, r, g, b, &h, &s, &v);
915 		tpg->colors[k][0] = h;
916 		tpg->colors[k][1] = s;
917 		tpg->colors[k][2] = v;
918 		break;
919 	}
920 	case TGP_COLOR_ENC_YCBCR:
921 	{
922 		/* Convert to YCbCr */
923 		if (!ycbcr_valid)
924 			color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
925 
926 		y >>= 4;
927 		cb >>= 4;
928 		cr >>= 4;
929 		if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
930 			y = clamp(y, 16, 235);
931 			cb = clamp(cb, 16, 240);
932 			cr = clamp(cr, 16, 240);
933 		} else {
934 			y = clamp(y, 1, 254);
935 			cb = clamp(cb, 1, 254);
936 			cr = clamp(cr, 1, 254);
937 		}
938 		switch (tpg->fourcc) {
939 		case V4L2_PIX_FMT_YUV444:
940 			y >>= 4;
941 			cb >>= 4;
942 			cr >>= 4;
943 			break;
944 		case V4L2_PIX_FMT_YUV555:
945 			y >>= 3;
946 			cb >>= 3;
947 			cr >>= 3;
948 			break;
949 		case V4L2_PIX_FMT_YUV565:
950 			y >>= 3;
951 			cb >>= 2;
952 			cr >>= 3;
953 			break;
954 		}
955 		tpg->colors[k][0] = y;
956 		tpg->colors[k][1] = cb;
957 		tpg->colors[k][2] = cr;
958 		break;
959 	}
960 	case TGP_COLOR_ENC_LUMA:
961 	{
962 		tpg->colors[k][0] = r >> 4;
963 		break;
964 	}
965 	case TGP_COLOR_ENC_RGB:
966 	{
967 		if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
968 			r = (r * 219) / 255 + (16 << 4);
969 			g = (g * 219) / 255 + (16 << 4);
970 			b = (b * 219) / 255 + (16 << 4);
971 		}
972 		switch (tpg->fourcc) {
973 		case V4L2_PIX_FMT_RGB332:
974 			r >>= 9;
975 			g >>= 9;
976 			b >>= 10;
977 			break;
978 		case V4L2_PIX_FMT_RGB565:
979 		case V4L2_PIX_FMT_RGB565X:
980 			r >>= 7;
981 			g >>= 6;
982 			b >>= 7;
983 			break;
984 		case V4L2_PIX_FMT_RGB444:
985 		case V4L2_PIX_FMT_XRGB444:
986 		case V4L2_PIX_FMT_ARGB444:
987 			r >>= 8;
988 			g >>= 8;
989 			b >>= 8;
990 			break;
991 		case V4L2_PIX_FMT_RGB555:
992 		case V4L2_PIX_FMT_XRGB555:
993 		case V4L2_PIX_FMT_ARGB555:
994 		case V4L2_PIX_FMT_RGB555X:
995 		case V4L2_PIX_FMT_XRGB555X:
996 		case V4L2_PIX_FMT_ARGB555X:
997 			r >>= 7;
998 			g >>= 7;
999 			b >>= 7;
1000 			break;
1001 		case V4L2_PIX_FMT_BGR666:
1002 			r >>= 6;
1003 			g >>= 6;
1004 			b >>= 6;
1005 			break;
1006 		default:
1007 			r >>= 4;
1008 			g >>= 4;
1009 			b >>= 4;
1010 			break;
1011 		}
1012 
1013 		tpg->colors[k][0] = r;
1014 		tpg->colors[k][1] = g;
1015 		tpg->colors[k][2] = b;
1016 		break;
1017 	}
1018 	}
1019 }
1020 
1021 static void tpg_precalculate_colors(struct tpg_data *tpg)
1022 {
1023 	int k;
1024 
1025 	for (k = 0; k < TPG_COLOR_MAX; k++)
1026 		precalculate_color(tpg, k);
1027 }
1028 
1029 /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
1030 static void gen_twopix(struct tpg_data *tpg,
1031 		u8 buf[TPG_MAX_PLANES][8], int color, bool odd)
1032 {
1033 	unsigned offset = odd * tpg->twopixelsize[0] / 2;
1034 	u8 alpha = tpg->alpha_component;
1035 	u8 r_y_h, g_u_s, b_v;
1036 
1037 	if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
1038 				   color != TPG_COLOR_100_RED &&
1039 				   color != TPG_COLOR_75_RED)
1040 		alpha = 0;
1041 	if (color == TPG_COLOR_RANDOM)
1042 		precalculate_color(tpg, color);
1043 	r_y_h = tpg->colors[color][0]; /* R or precalculated Y, H */
1044 	g_u_s = tpg->colors[color][1]; /* G or precalculated U, V */
1045 	b_v = tpg->colors[color][2]; /* B or precalculated V */
1046 
1047 	switch (tpg->fourcc) {
1048 	case V4L2_PIX_FMT_GREY:
1049 		buf[0][offset] = r_y_h;
1050 		break;
1051 	case V4L2_PIX_FMT_Y16:
1052 		/*
1053 		 * Ideally both bytes should be set to r_y_h, but then you won't
1054 		 * be able to detect endian problems. So keep it 0 except for
1055 		 * the corner case where r_y_h is 0xff so white really will be
1056 		 * white (0xffff).
1057 		 */
1058 		buf[0][offset] = r_y_h == 0xff ? r_y_h : 0;
1059 		buf[0][offset+1] = r_y_h;
1060 		break;
1061 	case V4L2_PIX_FMT_Y16_BE:
1062 		/* See comment for V4L2_PIX_FMT_Y16 above */
1063 		buf[0][offset] = r_y_h;
1064 		buf[0][offset+1] = r_y_h == 0xff ? r_y_h : 0;
1065 		break;
1066 	case V4L2_PIX_FMT_YUV422M:
1067 	case V4L2_PIX_FMT_YUV422P:
1068 	case V4L2_PIX_FMT_YUV420:
1069 	case V4L2_PIX_FMT_YUV420M:
1070 		buf[0][offset] = r_y_h;
1071 		if (odd) {
1072 			buf[1][0] = (buf[1][0] + g_u_s) / 2;
1073 			buf[2][0] = (buf[2][0] + b_v) / 2;
1074 			buf[1][1] = buf[1][0];
1075 			buf[2][1] = buf[2][0];
1076 			break;
1077 		}
1078 		buf[1][0] = g_u_s;
1079 		buf[2][0] = b_v;
1080 		break;
1081 	case V4L2_PIX_FMT_YVU422M:
1082 	case V4L2_PIX_FMT_YVU420:
1083 	case V4L2_PIX_FMT_YVU420M:
1084 		buf[0][offset] = r_y_h;
1085 		if (odd) {
1086 			buf[1][0] = (buf[1][0] + b_v) / 2;
1087 			buf[2][0] = (buf[2][0] + g_u_s) / 2;
1088 			buf[1][1] = buf[1][0];
1089 			buf[2][1] = buf[2][0];
1090 			break;
1091 		}
1092 		buf[1][0] = b_v;
1093 		buf[2][0] = g_u_s;
1094 		break;
1095 
1096 	case V4L2_PIX_FMT_NV12:
1097 	case V4L2_PIX_FMT_NV12M:
1098 	case V4L2_PIX_FMT_NV16:
1099 	case V4L2_PIX_FMT_NV16M:
1100 		buf[0][offset] = r_y_h;
1101 		if (odd) {
1102 			buf[1][0] = (buf[1][0] + g_u_s) / 2;
1103 			buf[1][1] = (buf[1][1] + b_v) / 2;
1104 			break;
1105 		}
1106 		buf[1][0] = g_u_s;
1107 		buf[1][1] = b_v;
1108 		break;
1109 	case V4L2_PIX_FMT_NV21:
1110 	case V4L2_PIX_FMT_NV21M:
1111 	case V4L2_PIX_FMT_NV61:
1112 	case V4L2_PIX_FMT_NV61M:
1113 		buf[0][offset] = r_y_h;
1114 		if (odd) {
1115 			buf[1][0] = (buf[1][0] + b_v) / 2;
1116 			buf[1][1] = (buf[1][1] + g_u_s) / 2;
1117 			break;
1118 		}
1119 		buf[1][0] = b_v;
1120 		buf[1][1] = g_u_s;
1121 		break;
1122 
1123 	case V4L2_PIX_FMT_YUV444M:
1124 		buf[0][offset] = r_y_h;
1125 		buf[1][offset] = g_u_s;
1126 		buf[2][offset] = b_v;
1127 		break;
1128 
1129 	case V4L2_PIX_FMT_YVU444M:
1130 		buf[0][offset] = r_y_h;
1131 		buf[1][offset] = b_v;
1132 		buf[2][offset] = g_u_s;
1133 		break;
1134 
1135 	case V4L2_PIX_FMT_NV24:
1136 		buf[0][offset] = r_y_h;
1137 		buf[1][2 * offset] = g_u_s;
1138 		buf[1][2 * offset + 1] = b_v;
1139 		break;
1140 
1141 	case V4L2_PIX_FMT_NV42:
1142 		buf[0][offset] = r_y_h;
1143 		buf[1][2 * offset] = b_v;
1144 		buf[1][2 * offset + 1] = g_u_s;
1145 		break;
1146 
1147 	case V4L2_PIX_FMT_YUYV:
1148 		buf[0][offset] = r_y_h;
1149 		if (odd) {
1150 			buf[0][1] = (buf[0][1] + g_u_s) / 2;
1151 			buf[0][3] = (buf[0][3] + b_v) / 2;
1152 			break;
1153 		}
1154 		buf[0][1] = g_u_s;
1155 		buf[0][3] = b_v;
1156 		break;
1157 	case V4L2_PIX_FMT_UYVY:
1158 		buf[0][offset + 1] = r_y_h;
1159 		if (odd) {
1160 			buf[0][0] = (buf[0][0] + g_u_s) / 2;
1161 			buf[0][2] = (buf[0][2] + b_v) / 2;
1162 			break;
1163 		}
1164 		buf[0][0] = g_u_s;
1165 		buf[0][2] = b_v;
1166 		break;
1167 	case V4L2_PIX_FMT_YVYU:
1168 		buf[0][offset] = r_y_h;
1169 		if (odd) {
1170 			buf[0][1] = (buf[0][1] + b_v) / 2;
1171 			buf[0][3] = (buf[0][3] + g_u_s) / 2;
1172 			break;
1173 		}
1174 		buf[0][1] = b_v;
1175 		buf[0][3] = g_u_s;
1176 		break;
1177 	case V4L2_PIX_FMT_VYUY:
1178 		buf[0][offset + 1] = r_y_h;
1179 		if (odd) {
1180 			buf[0][0] = (buf[0][0] + b_v) / 2;
1181 			buf[0][2] = (buf[0][2] + g_u_s) / 2;
1182 			break;
1183 		}
1184 		buf[0][0] = b_v;
1185 		buf[0][2] = g_u_s;
1186 		break;
1187 	case V4L2_PIX_FMT_RGB332:
1188 		buf[0][offset] = (r_y_h << 5) | (g_u_s << 2) | b_v;
1189 		break;
1190 	case V4L2_PIX_FMT_YUV565:
1191 	case V4L2_PIX_FMT_RGB565:
1192 		buf[0][offset] = (g_u_s << 5) | b_v;
1193 		buf[0][offset + 1] = (r_y_h << 3) | (g_u_s >> 3);
1194 		break;
1195 	case V4L2_PIX_FMT_RGB565X:
1196 		buf[0][offset] = (r_y_h << 3) | (g_u_s >> 3);
1197 		buf[0][offset + 1] = (g_u_s << 5) | b_v;
1198 		break;
1199 	case V4L2_PIX_FMT_RGB444:
1200 	case V4L2_PIX_FMT_XRGB444:
1201 		alpha = 0;
1202 		/* fall through */
1203 	case V4L2_PIX_FMT_YUV444:
1204 	case V4L2_PIX_FMT_ARGB444:
1205 		buf[0][offset] = (g_u_s << 4) | b_v;
1206 		buf[0][offset + 1] = (alpha & 0xf0) | r_y_h;
1207 		break;
1208 	case V4L2_PIX_FMT_RGB555:
1209 	case V4L2_PIX_FMT_XRGB555:
1210 		alpha = 0;
1211 		/* fall through */
1212 	case V4L2_PIX_FMT_YUV555:
1213 	case V4L2_PIX_FMT_ARGB555:
1214 		buf[0][offset] = (g_u_s << 5) | b_v;
1215 		buf[0][offset + 1] = (alpha & 0x80) | (r_y_h << 2)
1216 						    | (g_u_s >> 3);
1217 		break;
1218 	case V4L2_PIX_FMT_RGB555X:
1219 	case V4L2_PIX_FMT_XRGB555X:
1220 		alpha = 0;
1221 		/* fall through */
1222 	case V4L2_PIX_FMT_ARGB555X:
1223 		buf[0][offset] = (alpha & 0x80) | (r_y_h << 2) | (g_u_s >> 3);
1224 		buf[0][offset + 1] = (g_u_s << 5) | b_v;
1225 		break;
1226 	case V4L2_PIX_FMT_RGB24:
1227 	case V4L2_PIX_FMT_HSV24:
1228 		buf[0][offset] = r_y_h;
1229 		buf[0][offset + 1] = g_u_s;
1230 		buf[0][offset + 2] = b_v;
1231 		break;
1232 	case V4L2_PIX_FMT_BGR24:
1233 		buf[0][offset] = b_v;
1234 		buf[0][offset + 1] = g_u_s;
1235 		buf[0][offset + 2] = r_y_h;
1236 		break;
1237 	case V4L2_PIX_FMT_BGR666:
1238 		buf[0][offset] = (b_v << 2) | (g_u_s >> 4);
1239 		buf[0][offset + 1] = (g_u_s << 4) | (r_y_h >> 2);
1240 		buf[0][offset + 2] = r_y_h << 6;
1241 		buf[0][offset + 3] = 0;
1242 		break;
1243 	case V4L2_PIX_FMT_RGB32:
1244 	case V4L2_PIX_FMT_XRGB32:
1245 	case V4L2_PIX_FMT_HSV32:
1246 		alpha = 0;
1247 		/* fall through */
1248 	case V4L2_PIX_FMT_YUV32:
1249 	case V4L2_PIX_FMT_ARGB32:
1250 		buf[0][offset] = alpha;
1251 		buf[0][offset + 1] = r_y_h;
1252 		buf[0][offset + 2] = g_u_s;
1253 		buf[0][offset + 3] = b_v;
1254 		break;
1255 	case V4L2_PIX_FMT_BGR32:
1256 	case V4L2_PIX_FMT_XBGR32:
1257 		alpha = 0;
1258 		/* fall through */
1259 	case V4L2_PIX_FMT_ABGR32:
1260 		buf[0][offset] = b_v;
1261 		buf[0][offset + 1] = g_u_s;
1262 		buf[0][offset + 2] = r_y_h;
1263 		buf[0][offset + 3] = alpha;
1264 		break;
1265 	case V4L2_PIX_FMT_SBGGR8:
1266 		buf[0][offset] = odd ? g_u_s : b_v;
1267 		buf[1][offset] = odd ? r_y_h : g_u_s;
1268 		break;
1269 	case V4L2_PIX_FMT_SGBRG8:
1270 		buf[0][offset] = odd ? b_v : g_u_s;
1271 		buf[1][offset] = odd ? g_u_s : r_y_h;
1272 		break;
1273 	case V4L2_PIX_FMT_SGRBG8:
1274 		buf[0][offset] = odd ? r_y_h : g_u_s;
1275 		buf[1][offset] = odd ? g_u_s : b_v;
1276 		break;
1277 	case V4L2_PIX_FMT_SRGGB8:
1278 		buf[0][offset] = odd ? g_u_s : r_y_h;
1279 		buf[1][offset] = odd ? b_v : g_u_s;
1280 		break;
1281 	case V4L2_PIX_FMT_SBGGR10:
1282 		buf[0][offset] = odd ? g_u_s << 2 : b_v << 2;
1283 		buf[0][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6;
1284 		buf[1][offset] = odd ? r_y_h << 2 : g_u_s << 2;
1285 		buf[1][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6;
1286 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1287 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1288 		break;
1289 	case V4L2_PIX_FMT_SGBRG10:
1290 		buf[0][offset] = odd ? b_v << 2 : g_u_s << 2;
1291 		buf[0][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6;
1292 		buf[1][offset] = odd ? g_u_s << 2 : r_y_h << 2;
1293 		buf[1][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6;
1294 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1295 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1296 		break;
1297 	case V4L2_PIX_FMT_SGRBG10:
1298 		buf[0][offset] = odd ? r_y_h << 2 : g_u_s << 2;
1299 		buf[0][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6;
1300 		buf[1][offset] = odd ? g_u_s << 2 : b_v << 2;
1301 		buf[1][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6;
1302 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1303 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1304 		break;
1305 	case V4L2_PIX_FMT_SRGGB10:
1306 		buf[0][offset] = odd ? g_u_s << 2 : r_y_h << 2;
1307 		buf[0][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6;
1308 		buf[1][offset] = odd ? b_v << 2 : g_u_s << 2;
1309 		buf[1][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6;
1310 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1311 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1312 		break;
1313 	case V4L2_PIX_FMT_SBGGR12:
1314 		buf[0][offset] = odd ? g_u_s << 4 : b_v << 4;
1315 		buf[0][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4;
1316 		buf[1][offset] = odd ? r_y_h << 4 : g_u_s << 4;
1317 		buf[1][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4;
1318 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1319 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1320 		break;
1321 	case V4L2_PIX_FMT_SGBRG12:
1322 		buf[0][offset] = odd ? b_v << 4 : g_u_s << 4;
1323 		buf[0][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4;
1324 		buf[1][offset] = odd ? g_u_s << 4 : r_y_h << 4;
1325 		buf[1][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4;
1326 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1327 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1328 		break;
1329 	case V4L2_PIX_FMT_SGRBG12:
1330 		buf[0][offset] = odd ? r_y_h << 4 : g_u_s << 4;
1331 		buf[0][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4;
1332 		buf[1][offset] = odd ? g_u_s << 4 : b_v << 4;
1333 		buf[1][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4;
1334 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1335 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1336 		break;
1337 	case V4L2_PIX_FMT_SRGGB12:
1338 		buf[0][offset] = odd ? g_u_s << 4 : r_y_h << 4;
1339 		buf[0][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4;
1340 		buf[1][offset] = odd ? b_v << 4 : g_u_s << 4;
1341 		buf[1][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4;
1342 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1343 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1344 		break;
1345 	}
1346 }
1347 
1348 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
1349 {
1350 	switch (tpg->fourcc) {
1351 	case V4L2_PIX_FMT_SBGGR8:
1352 	case V4L2_PIX_FMT_SGBRG8:
1353 	case V4L2_PIX_FMT_SGRBG8:
1354 	case V4L2_PIX_FMT_SRGGB8:
1355 	case V4L2_PIX_FMT_SBGGR10:
1356 	case V4L2_PIX_FMT_SGBRG10:
1357 	case V4L2_PIX_FMT_SGRBG10:
1358 	case V4L2_PIX_FMT_SRGGB10:
1359 	case V4L2_PIX_FMT_SBGGR12:
1360 	case V4L2_PIX_FMT_SGBRG12:
1361 	case V4L2_PIX_FMT_SGRBG12:
1362 	case V4L2_PIX_FMT_SRGGB12:
1363 		return buf_line & 1;
1364 	default:
1365 		return 0;
1366 	}
1367 }
1368 EXPORT_SYMBOL_GPL(tpg_g_interleaved_plane);
1369 
1370 /* Return how many pattern lines are used by the current pattern. */
1371 static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
1372 {
1373 	switch (tpg->pattern) {
1374 	case TPG_PAT_CHECKERS_16X16:
1375 	case TPG_PAT_CHECKERS_2X2:
1376 	case TPG_PAT_CHECKERS_1X1:
1377 	case TPG_PAT_COLOR_CHECKERS_2X2:
1378 	case TPG_PAT_COLOR_CHECKERS_1X1:
1379 	case TPG_PAT_ALTERNATING_HLINES:
1380 	case TPG_PAT_CROSS_1_PIXEL:
1381 	case TPG_PAT_CROSS_2_PIXELS:
1382 	case TPG_PAT_CROSS_10_PIXELS:
1383 		return 2;
1384 	case TPG_PAT_100_COLORSQUARES:
1385 	case TPG_PAT_100_HCOLORBAR:
1386 		return 8;
1387 	default:
1388 		return 1;
1389 	}
1390 }
1391 
1392 /* Which pattern line should be used for the given frame line. */
1393 static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
1394 {
1395 	switch (tpg->pattern) {
1396 	case TPG_PAT_CHECKERS_16X16:
1397 		return (line >> 4) & 1;
1398 	case TPG_PAT_CHECKERS_1X1:
1399 	case TPG_PAT_COLOR_CHECKERS_1X1:
1400 	case TPG_PAT_ALTERNATING_HLINES:
1401 		return line & 1;
1402 	case TPG_PAT_CHECKERS_2X2:
1403 	case TPG_PAT_COLOR_CHECKERS_2X2:
1404 		return (line & 2) >> 1;
1405 	case TPG_PAT_100_COLORSQUARES:
1406 	case TPG_PAT_100_HCOLORBAR:
1407 		return (line * 8) / tpg->src_height;
1408 	case TPG_PAT_CROSS_1_PIXEL:
1409 		return line == tpg->src_height / 2;
1410 	case TPG_PAT_CROSS_2_PIXELS:
1411 		return (line + 1) / 2 == tpg->src_height / 4;
1412 	case TPG_PAT_CROSS_10_PIXELS:
1413 		return (line + 10) / 20 == tpg->src_height / 40;
1414 	default:
1415 		return 0;
1416 	}
1417 }
1418 
1419 /*
1420  * Which color should be used for the given pattern line and X coordinate.
1421  * Note: x is in the range 0 to 2 * tpg->src_width.
1422  */
1423 static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
1424 				    unsigned pat_line, unsigned x)
1425 {
1426 	/* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code
1427 	   should be modified */
1428 	static const enum tpg_color bars[3][8] = {
1429 		/* Standard ITU-R 75% color bar sequence */
1430 		{ TPG_COLOR_CSC_WHITE,   TPG_COLOR_75_YELLOW,
1431 		  TPG_COLOR_75_CYAN,     TPG_COLOR_75_GREEN,
1432 		  TPG_COLOR_75_MAGENTA,  TPG_COLOR_75_RED,
1433 		  TPG_COLOR_75_BLUE,     TPG_COLOR_100_BLACK, },
1434 		/* Standard ITU-R 100% color bar sequence */
1435 		{ TPG_COLOR_100_WHITE,   TPG_COLOR_100_YELLOW,
1436 		  TPG_COLOR_100_CYAN,    TPG_COLOR_100_GREEN,
1437 		  TPG_COLOR_100_MAGENTA, TPG_COLOR_100_RED,
1438 		  TPG_COLOR_100_BLUE,    TPG_COLOR_100_BLACK, },
1439 		/* Color bar sequence suitable to test CSC */
1440 		{ TPG_COLOR_CSC_WHITE,   TPG_COLOR_CSC_YELLOW,
1441 		  TPG_COLOR_CSC_CYAN,    TPG_COLOR_CSC_GREEN,
1442 		  TPG_COLOR_CSC_MAGENTA, TPG_COLOR_CSC_RED,
1443 		  TPG_COLOR_CSC_BLUE,    TPG_COLOR_CSC_BLACK, },
1444 	};
1445 
1446 	switch (tpg->pattern) {
1447 	case TPG_PAT_75_COLORBAR:
1448 	case TPG_PAT_100_COLORBAR:
1449 	case TPG_PAT_CSC_COLORBAR:
1450 		return bars[tpg->pattern][((x * 8) / tpg->src_width) % 8];
1451 	case TPG_PAT_100_COLORSQUARES:
1452 		return bars[1][(pat_line + (x * 8) / tpg->src_width) % 8];
1453 	case TPG_PAT_100_HCOLORBAR:
1454 		return bars[1][pat_line];
1455 	case TPG_PAT_BLACK:
1456 		return TPG_COLOR_100_BLACK;
1457 	case TPG_PAT_WHITE:
1458 		return TPG_COLOR_100_WHITE;
1459 	case TPG_PAT_RED:
1460 		return TPG_COLOR_100_RED;
1461 	case TPG_PAT_GREEN:
1462 		return TPG_COLOR_100_GREEN;
1463 	case TPG_PAT_BLUE:
1464 		return TPG_COLOR_100_BLUE;
1465 	case TPG_PAT_CHECKERS_16X16:
1466 		return (((x >> 4) & 1) ^ (pat_line & 1)) ?
1467 			TPG_COLOR_100_BLACK : TPG_COLOR_100_WHITE;
1468 	case TPG_PAT_CHECKERS_1X1:
1469 		return ((x & 1) ^ (pat_line & 1)) ?
1470 			TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1471 	case TPG_PAT_COLOR_CHECKERS_1X1:
1472 		return ((x & 1) ^ (pat_line & 1)) ?
1473 			TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1474 	case TPG_PAT_CHECKERS_2X2:
1475 		return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1476 			TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1477 	case TPG_PAT_COLOR_CHECKERS_2X2:
1478 		return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1479 			TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1480 	case TPG_PAT_ALTERNATING_HLINES:
1481 		return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1482 	case TPG_PAT_ALTERNATING_VLINES:
1483 		return (x & 1) ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1484 	case TPG_PAT_CROSS_1_PIXEL:
1485 		if (pat_line || (x % tpg->src_width) == tpg->src_width / 2)
1486 			return TPG_COLOR_100_BLACK;
1487 		return TPG_COLOR_100_WHITE;
1488 	case TPG_PAT_CROSS_2_PIXELS:
1489 		if (pat_line || ((x % tpg->src_width) + 1) / 2 == tpg->src_width / 4)
1490 			return TPG_COLOR_100_BLACK;
1491 		return TPG_COLOR_100_WHITE;
1492 	case TPG_PAT_CROSS_10_PIXELS:
1493 		if (pat_line || ((x % tpg->src_width) + 10) / 20 == tpg->src_width / 40)
1494 			return TPG_COLOR_100_BLACK;
1495 		return TPG_COLOR_100_WHITE;
1496 	case TPG_PAT_GRAY_RAMP:
1497 		return TPG_COLOR_RAMP + ((x % tpg->src_width) * 256) / tpg->src_width;
1498 	default:
1499 		return TPG_COLOR_100_RED;
1500 	}
1501 }
1502 
1503 /*
1504  * Given the pixel aspect ratio and video aspect ratio calculate the
1505  * coordinates of a centered square and the coordinates of the border of
1506  * the active video area. The coordinates are relative to the source
1507  * frame rectangle.
1508  */
1509 static void tpg_calculate_square_border(struct tpg_data *tpg)
1510 {
1511 	unsigned w = tpg->src_width;
1512 	unsigned h = tpg->src_height;
1513 	unsigned sq_w, sq_h;
1514 
1515 	sq_w = (w * 2 / 5) & ~1;
1516 	if (((w - sq_w) / 2) & 1)
1517 		sq_w += 2;
1518 	sq_h = sq_w;
1519 	tpg->square.width = sq_w;
1520 	if (tpg->vid_aspect == TPG_VIDEO_ASPECT_16X9_ANAMORPHIC) {
1521 		unsigned ana_sq_w = (sq_w / 4) * 3;
1522 
1523 		if (((w - ana_sq_w) / 2) & 1)
1524 			ana_sq_w += 2;
1525 		tpg->square.width = ana_sq_w;
1526 	}
1527 	tpg->square.left = (w - tpg->square.width) / 2;
1528 	if (tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC)
1529 		sq_h = sq_w * 10 / 11;
1530 	else if (tpg->pix_aspect == TPG_PIXEL_ASPECT_PAL)
1531 		sq_h = sq_w * 59 / 54;
1532 	tpg->square.height = sq_h;
1533 	tpg->square.top = (h - sq_h) / 2;
1534 	tpg->border.left = 0;
1535 	tpg->border.width = w;
1536 	tpg->border.top = 0;
1537 	tpg->border.height = h;
1538 	switch (tpg->vid_aspect) {
1539 	case TPG_VIDEO_ASPECT_4X3:
1540 		if (tpg->pix_aspect)
1541 			return;
1542 		if (3 * w >= 4 * h) {
1543 			tpg->border.width = ((4 * h) / 3) & ~1;
1544 			if (((w - tpg->border.width) / 2) & ~1)
1545 				tpg->border.width -= 2;
1546 			tpg->border.left = (w - tpg->border.width) / 2;
1547 			break;
1548 		}
1549 		tpg->border.height = ((3 * w) / 4) & ~1;
1550 		tpg->border.top = (h - tpg->border.height) / 2;
1551 		break;
1552 	case TPG_VIDEO_ASPECT_14X9_CENTRE:
1553 		if (tpg->pix_aspect) {
1554 			tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 420 : 506;
1555 			tpg->border.top = (h - tpg->border.height) / 2;
1556 			break;
1557 		}
1558 		if (9 * w >= 14 * h) {
1559 			tpg->border.width = ((14 * h) / 9) & ~1;
1560 			if (((w - tpg->border.width) / 2) & ~1)
1561 				tpg->border.width -= 2;
1562 			tpg->border.left = (w - tpg->border.width) / 2;
1563 			break;
1564 		}
1565 		tpg->border.height = ((9 * w) / 14) & ~1;
1566 		tpg->border.top = (h - tpg->border.height) / 2;
1567 		break;
1568 	case TPG_VIDEO_ASPECT_16X9_CENTRE:
1569 		if (tpg->pix_aspect) {
1570 			tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 368 : 442;
1571 			tpg->border.top = (h - tpg->border.height) / 2;
1572 			break;
1573 		}
1574 		if (9 * w >= 16 * h) {
1575 			tpg->border.width = ((16 * h) / 9) & ~1;
1576 			if (((w - tpg->border.width) / 2) & ~1)
1577 				tpg->border.width -= 2;
1578 			tpg->border.left = (w - tpg->border.width) / 2;
1579 			break;
1580 		}
1581 		tpg->border.height = ((9 * w) / 16) & ~1;
1582 		tpg->border.top = (h - tpg->border.height) / 2;
1583 		break;
1584 	default:
1585 		break;
1586 	}
1587 }
1588 
1589 static void tpg_precalculate_line(struct tpg_data *tpg)
1590 {
1591 	enum tpg_color contrast;
1592 	u8 pix[TPG_MAX_PLANES][8];
1593 	unsigned pat;
1594 	unsigned p;
1595 	unsigned x;
1596 
1597 	switch (tpg->pattern) {
1598 	case TPG_PAT_GREEN:
1599 		contrast = TPG_COLOR_100_RED;
1600 		break;
1601 	case TPG_PAT_CSC_COLORBAR:
1602 		contrast = TPG_COLOR_CSC_GREEN;
1603 		break;
1604 	default:
1605 		contrast = TPG_COLOR_100_GREEN;
1606 		break;
1607 	}
1608 
1609 	for (pat = 0; pat < tpg_get_pat_lines(tpg); pat++) {
1610 		/* Coarse scaling with Bresenham */
1611 		unsigned int_part = tpg->src_width / tpg->scaled_width;
1612 		unsigned fract_part = tpg->src_width % tpg->scaled_width;
1613 		unsigned src_x = 0;
1614 		unsigned error = 0;
1615 
1616 		for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1617 			unsigned real_x = src_x;
1618 			enum tpg_color color1, color2;
1619 
1620 			real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1621 			color1 = tpg_get_color(tpg, pat, real_x);
1622 
1623 			src_x += int_part;
1624 			error += fract_part;
1625 			if (error >= tpg->scaled_width) {
1626 				error -= tpg->scaled_width;
1627 				src_x++;
1628 			}
1629 
1630 			real_x = src_x;
1631 			real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1632 			color2 = tpg_get_color(tpg, pat, real_x);
1633 
1634 			src_x += int_part;
1635 			error += fract_part;
1636 			if (error >= tpg->scaled_width) {
1637 				error -= tpg->scaled_width;
1638 				src_x++;
1639 			}
1640 
1641 			gen_twopix(tpg, pix, tpg->hflip ? color2 : color1, 0);
1642 			gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1643 			for (p = 0; p < tpg->planes; p++) {
1644 				unsigned twopixsize = tpg->twopixelsize[p];
1645 				unsigned hdiv = tpg->hdownsampling[p];
1646 				u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
1647 
1648 				memcpy(pos, pix[p], twopixsize / hdiv);
1649 			}
1650 		}
1651 	}
1652 
1653 	if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1654 		unsigned pat_lines = tpg_get_pat_lines(tpg);
1655 
1656 		for (pat = 0; pat < pat_lines; pat++) {
1657 			unsigned next_pat = (pat + 1) % pat_lines;
1658 
1659 			for (p = 1; p < tpg->planes; p++) {
1660 				unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
1661 				u8 *pos1 = tpg->lines[pat][p];
1662 				u8 *pos2 = tpg->lines[next_pat][p];
1663 				u8 *dest = tpg->downsampled_lines[pat][p];
1664 
1665 				for (x = 0; x < w; x++, pos1++, pos2++, dest++)
1666 					*dest = ((u16)*pos1 + (u16)*pos2) / 2;
1667 			}
1668 		}
1669 	}
1670 
1671 	gen_twopix(tpg, pix, contrast, 0);
1672 	gen_twopix(tpg, pix, contrast, 1);
1673 	for (p = 0; p < tpg->planes; p++) {
1674 		unsigned twopixsize = tpg->twopixelsize[p];
1675 		u8 *pos = tpg->contrast_line[p];
1676 
1677 		for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1678 			memcpy(pos, pix[p], twopixsize);
1679 	}
1680 
1681 	gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
1682 	gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
1683 	for (p = 0; p < tpg->planes; p++) {
1684 		unsigned twopixsize = tpg->twopixelsize[p];
1685 		u8 *pos = tpg->black_line[p];
1686 
1687 		for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1688 			memcpy(pos, pix[p], twopixsize);
1689 	}
1690 
1691 	for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1692 		gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
1693 		gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
1694 		for (p = 0; p < tpg->planes; p++) {
1695 			unsigned twopixsize = tpg->twopixelsize[p];
1696 			u8 *pos = tpg->random_line[p] + x * twopixsize / 2;
1697 
1698 			memcpy(pos, pix[p], twopixsize);
1699 		}
1700 	}
1701 
1702 	gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
1703 	gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
1704 	gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
1705 	gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 1);
1706 }
1707 
1708 /* need this to do rgb24 rendering */
1709 typedef struct { u16 __; u8 _; } __packed x24;
1710 
1711 #define PRINTSTR(PIXTYPE) do {	\
1712 	unsigned vdiv = tpg->vdownsampling[p]; \
1713 	unsigned hdiv = tpg->hdownsampling[p]; \
1714 	int line;	\
1715 	PIXTYPE fg;	\
1716 	PIXTYPE bg;	\
1717 	memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE));	\
1718 	memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE));	\
1719 	\
1720 	for (line = first; line < 16; line += vdiv * step) {	\
1721 		int l = tpg->vflip ? 15 - line : line; \
1722 		PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \
1723 			       ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
1724 			       (x / hdiv) * sizeof(PIXTYPE));	\
1725 		unsigned s;	\
1726 	\
1727 		for (s = 0; s < len; s++) {	\
1728 			u8 chr = font8x16[text[s] * 16 + line];	\
1729 	\
1730 			if (hdiv == 2 && tpg->hflip) { \
1731 				pos[3] = (chr & (0x01 << 6) ? fg : bg);	\
1732 				pos[2] = (chr & (0x01 << 4) ? fg : bg);	\
1733 				pos[1] = (chr & (0x01 << 2) ? fg : bg);	\
1734 				pos[0] = (chr & (0x01 << 0) ? fg : bg);	\
1735 			} else if (hdiv == 2) { \
1736 				pos[0] = (chr & (0x01 << 7) ? fg : bg);	\
1737 				pos[1] = (chr & (0x01 << 5) ? fg : bg);	\
1738 				pos[2] = (chr & (0x01 << 3) ? fg : bg);	\
1739 				pos[3] = (chr & (0x01 << 1) ? fg : bg);	\
1740 			} else if (tpg->hflip) { \
1741 				pos[7] = (chr & (0x01 << 7) ? fg : bg);	\
1742 				pos[6] = (chr & (0x01 << 6) ? fg : bg);	\
1743 				pos[5] = (chr & (0x01 << 5) ? fg : bg);	\
1744 				pos[4] = (chr & (0x01 << 4) ? fg : bg);	\
1745 				pos[3] = (chr & (0x01 << 3) ? fg : bg);	\
1746 				pos[2] = (chr & (0x01 << 2) ? fg : bg);	\
1747 				pos[1] = (chr & (0x01 << 1) ? fg : bg);	\
1748 				pos[0] = (chr & (0x01 << 0) ? fg : bg);	\
1749 			} else { \
1750 				pos[0] = (chr & (0x01 << 7) ? fg : bg);	\
1751 				pos[1] = (chr & (0x01 << 6) ? fg : bg);	\
1752 				pos[2] = (chr & (0x01 << 5) ? fg : bg);	\
1753 				pos[3] = (chr & (0x01 << 4) ? fg : bg);	\
1754 				pos[4] = (chr & (0x01 << 3) ? fg : bg);	\
1755 				pos[5] = (chr & (0x01 << 2) ? fg : bg);	\
1756 				pos[6] = (chr & (0x01 << 1) ? fg : bg);	\
1757 				pos[7] = (chr & (0x01 << 0) ? fg : bg);	\
1758 			} \
1759 	\
1760 			pos += (tpg->hflip ? -8 : 8) / hdiv;	\
1761 		}	\
1762 	}	\
1763 } while (0)
1764 
1765 static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1766 			unsigned p, unsigned first, unsigned div, unsigned step,
1767 			int y, int x, char *text, unsigned len)
1768 {
1769 	PRINTSTR(u8);
1770 }
1771 
1772 static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1773 			unsigned p, unsigned first, unsigned div, unsigned step,
1774 			int y, int x, char *text, unsigned len)
1775 {
1776 	PRINTSTR(u16);
1777 }
1778 
1779 static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1780 			unsigned p, unsigned first, unsigned div, unsigned step,
1781 			int y, int x, char *text, unsigned len)
1782 {
1783 	PRINTSTR(x24);
1784 }
1785 
1786 static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1787 			unsigned p, unsigned first, unsigned div, unsigned step,
1788 			int y, int x, char *text, unsigned len)
1789 {
1790 	PRINTSTR(u32);
1791 }
1792 
1793 void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1794 		  int y, int x, char *text)
1795 {
1796 	unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1797 	unsigned div = step;
1798 	unsigned first = 0;
1799 	unsigned len = strlen(text);
1800 	unsigned p;
1801 
1802 	if (font8x16 == NULL || basep == NULL)
1803 		return;
1804 
1805 	/* Checks if it is possible to show string */
1806 	if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1807 		return;
1808 
1809 	if (len > (tpg->compose.width - x) / 8)
1810 		len = (tpg->compose.width - x) / 8;
1811 	if (tpg->vflip)
1812 		y = tpg->compose.height - y - 16;
1813 	if (tpg->hflip)
1814 		x = tpg->compose.width - x - 8;
1815 	y += tpg->compose.top;
1816 	x += tpg->compose.left;
1817 	if (tpg->field == V4L2_FIELD_BOTTOM)
1818 		first = 1;
1819 	else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
1820 		div = 2;
1821 
1822 	for (p = 0; p < tpg->planes; p++) {
1823 		/* Print text */
1824 		switch (tpg->twopixelsize[p]) {
1825 		case 2:
1826 			tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
1827 					text, len);
1828 			break;
1829 		case 4:
1830 			tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
1831 					text, len);
1832 			break;
1833 		case 6:
1834 			tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
1835 					text, len);
1836 			break;
1837 		case 8:
1838 			tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
1839 					text, len);
1840 			break;
1841 		}
1842 	}
1843 }
1844 EXPORT_SYMBOL_GPL(tpg_gen_text);
1845 
1846 void tpg_update_mv_step(struct tpg_data *tpg)
1847 {
1848 	int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
1849 
1850 	if (tpg->hflip)
1851 		factor = -factor;
1852 	switch (tpg->mv_hor_mode) {
1853 	case TPG_MOVE_NEG_FAST:
1854 	case TPG_MOVE_POS_FAST:
1855 		tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
1856 		break;
1857 	case TPG_MOVE_NEG:
1858 	case TPG_MOVE_POS:
1859 		tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
1860 		break;
1861 	case TPG_MOVE_NEG_SLOW:
1862 	case TPG_MOVE_POS_SLOW:
1863 		tpg->mv_hor_step = 2;
1864 		break;
1865 	case TPG_MOVE_NONE:
1866 		tpg->mv_hor_step = 0;
1867 		break;
1868 	}
1869 	if (factor < 0)
1870 		tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
1871 
1872 	factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
1873 	switch (tpg->mv_vert_mode) {
1874 	case TPG_MOVE_NEG_FAST:
1875 	case TPG_MOVE_POS_FAST:
1876 		tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
1877 		break;
1878 	case TPG_MOVE_NEG:
1879 	case TPG_MOVE_POS:
1880 		tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
1881 		break;
1882 	case TPG_MOVE_NEG_SLOW:
1883 	case TPG_MOVE_POS_SLOW:
1884 		tpg->mv_vert_step = 1;
1885 		break;
1886 	case TPG_MOVE_NONE:
1887 		tpg->mv_vert_step = 0;
1888 		break;
1889 	}
1890 	if (factor < 0)
1891 		tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
1892 }
1893 EXPORT_SYMBOL_GPL(tpg_update_mv_step);
1894 
1895 /* Map the line number relative to the crop rectangle to a frame line number */
1896 static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
1897 				    unsigned field)
1898 {
1899 	switch (field) {
1900 	case V4L2_FIELD_TOP:
1901 		return tpg->crop.top + src_y * 2;
1902 	case V4L2_FIELD_BOTTOM:
1903 		return tpg->crop.top + src_y * 2 + 1;
1904 	default:
1905 		return src_y + tpg->crop.top;
1906 	}
1907 }
1908 
1909 /*
1910  * Map the line number relative to the compose rectangle to a destination
1911  * buffer line number.
1912  */
1913 static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
1914 				    unsigned field)
1915 {
1916 	y += tpg->compose.top;
1917 	switch (field) {
1918 	case V4L2_FIELD_SEQ_TB:
1919 		if (y & 1)
1920 			return tpg->buf_height / 2 + y / 2;
1921 		return y / 2;
1922 	case V4L2_FIELD_SEQ_BT:
1923 		if (y & 1)
1924 			return y / 2;
1925 		return tpg->buf_height / 2 + y / 2;
1926 	default:
1927 		return y;
1928 	}
1929 }
1930 
1931 static void tpg_recalc(struct tpg_data *tpg)
1932 {
1933 	if (tpg->recalc_colors) {
1934 		tpg->recalc_colors = false;
1935 		tpg->recalc_lines = true;
1936 		tpg->real_xfer_func = tpg->xfer_func;
1937 		tpg->real_ycbcr_enc = tpg->ycbcr_enc;
1938 		tpg->real_hsv_enc = tpg->hsv_enc;
1939 		tpg->real_quantization = tpg->quantization;
1940 
1941 		if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
1942 			tpg->real_xfer_func =
1943 				V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
1944 
1945 		if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1946 			tpg->real_ycbcr_enc =
1947 				V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
1948 
1949 		if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
1950 			tpg->real_quantization =
1951 				V4L2_MAP_QUANTIZATION_DEFAULT(
1952 					tpg->color_enc != TGP_COLOR_ENC_YCBCR,
1953 					tpg->colorspace, tpg->real_ycbcr_enc);
1954 
1955 		tpg_precalculate_colors(tpg);
1956 	}
1957 	if (tpg->recalc_square_border) {
1958 		tpg->recalc_square_border = false;
1959 		tpg_calculate_square_border(tpg);
1960 	}
1961 	if (tpg->recalc_lines) {
1962 		tpg->recalc_lines = false;
1963 		tpg_precalculate_line(tpg);
1964 	}
1965 }
1966 
1967 void tpg_calc_text_basep(struct tpg_data *tpg,
1968 		u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
1969 {
1970 	unsigned stride = tpg->bytesperline[p];
1971 	unsigned h = tpg->buf_height;
1972 
1973 	tpg_recalc(tpg);
1974 
1975 	basep[p][0] = vbuf;
1976 	basep[p][1] = vbuf;
1977 	h /= tpg->vdownsampling[p];
1978 	if (tpg->field == V4L2_FIELD_SEQ_TB)
1979 		basep[p][1] += h * stride / 2;
1980 	else if (tpg->field == V4L2_FIELD_SEQ_BT)
1981 		basep[p][0] += h * stride / 2;
1982 	if (p == 0 && tpg->interleaved)
1983 		tpg_calc_text_basep(tpg, basep, 1, vbuf);
1984 }
1985 EXPORT_SYMBOL_GPL(tpg_calc_text_basep);
1986 
1987 static int tpg_pattern_avg(const struct tpg_data *tpg,
1988 			   unsigned pat1, unsigned pat2)
1989 {
1990 	unsigned pat_lines = tpg_get_pat_lines(tpg);
1991 
1992 	if (pat1 == (pat2 + 1) % pat_lines)
1993 		return pat2;
1994 	if (pat2 == (pat1 + 1) % pat_lines)
1995 		return pat1;
1996 	return -1;
1997 }
1998 
1999 static const char *tpg_color_enc_str(enum tgp_color_enc
2000 						 color_enc)
2001 {
2002 	switch (color_enc) {
2003 	case TGP_COLOR_ENC_HSV:
2004 		return "HSV";
2005 	case TGP_COLOR_ENC_YCBCR:
2006 		return "Y'CbCr";
2007 	case TGP_COLOR_ENC_LUMA:
2008 		return "Luma";
2009 	case TGP_COLOR_ENC_RGB:
2010 	default:
2011 		return "R'G'B";
2012 
2013 	}
2014 }
2015 
2016 void tpg_log_status(struct tpg_data *tpg)
2017 {
2018 	pr_info("tpg source WxH: %ux%u (%s)\n",
2019 		tpg->src_width, tpg->src_height,
2020 		tpg_color_enc_str(tpg->color_enc));
2021 	pr_info("tpg field: %u\n", tpg->field);
2022 	pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
2023 			tpg->crop.left, tpg->crop.top);
2024 	pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
2025 			tpg->compose.left, tpg->compose.top);
2026 	pr_info("tpg colorspace: %d\n", tpg->colorspace);
2027 	pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
2028 	pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
2029 	pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc);
2030 	pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
2031 	pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
2032 }
2033 EXPORT_SYMBOL_GPL(tpg_log_status);
2034 
2035 /*
2036  * This struct contains common parameters used by both the drawing of the
2037  * test pattern and the drawing of the extras (borders, square, etc.)
2038  */
2039 struct tpg_draw_params {
2040 	/* common data */
2041 	bool is_tv;
2042 	bool is_60hz;
2043 	unsigned twopixsize;
2044 	unsigned img_width;
2045 	unsigned stride;
2046 	unsigned hmax;
2047 	unsigned frame_line;
2048 	unsigned frame_line_next;
2049 
2050 	/* test pattern */
2051 	unsigned mv_hor_old;
2052 	unsigned mv_hor_new;
2053 	unsigned mv_vert_old;
2054 	unsigned mv_vert_new;
2055 
2056 	/* extras */
2057 	unsigned wss_width;
2058 	unsigned wss_random_offset;
2059 	unsigned sav_eav_f;
2060 	unsigned left_pillar_width;
2061 	unsigned right_pillar_start;
2062 };
2063 
2064 static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
2065 				    struct tpg_draw_params *params)
2066 {
2067 	params->mv_hor_old =
2068 		tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
2069 	params->mv_hor_new =
2070 		tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
2071 			       tpg->src_width);
2072 	params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
2073 	params->mv_vert_new =
2074 		(tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
2075 }
2076 
2077 static void tpg_fill_params_extras(const struct tpg_data *tpg,
2078 				   unsigned p,
2079 				   struct tpg_draw_params *params)
2080 {
2081 	unsigned left_pillar_width = 0;
2082 	unsigned right_pillar_start = params->img_width;
2083 
2084 	params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
2085 		tpg->src_width / 2 - tpg->crop.left : 0;
2086 	if (params->wss_width > tpg->crop.width)
2087 		params->wss_width = tpg->crop.width;
2088 	params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
2089 	params->wss_random_offset =
2090 		params->twopixsize * prandom_u32_max(tpg->src_width / 2);
2091 
2092 	if (tpg->crop.left < tpg->border.left) {
2093 		left_pillar_width = tpg->border.left - tpg->crop.left;
2094 		if (left_pillar_width > tpg->crop.width)
2095 			left_pillar_width = tpg->crop.width;
2096 		left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
2097 	}
2098 	params->left_pillar_width = left_pillar_width;
2099 
2100 	if (tpg->crop.left + tpg->crop.width >
2101 	    tpg->border.left + tpg->border.width) {
2102 		right_pillar_start =
2103 			tpg->border.left + tpg->border.width - tpg->crop.left;
2104 		right_pillar_start =
2105 			tpg_hscale_div(tpg, p, right_pillar_start);
2106 		if (right_pillar_start > params->img_width)
2107 			right_pillar_start = params->img_width;
2108 	}
2109 	params->right_pillar_start = right_pillar_start;
2110 
2111 	params->sav_eav_f = tpg->field ==
2112 			(params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2113 }
2114 
2115 static void tpg_fill_plane_extras(const struct tpg_data *tpg,
2116 				  const struct tpg_draw_params *params,
2117 				  unsigned p, unsigned h, u8 *vbuf)
2118 {
2119 	unsigned twopixsize = params->twopixsize;
2120 	unsigned img_width = params->img_width;
2121 	unsigned frame_line = params->frame_line;
2122 	const struct v4l2_rect *sq = &tpg->square;
2123 	const struct v4l2_rect *b = &tpg->border;
2124 	const struct v4l2_rect *c = &tpg->crop;
2125 
2126 	if (params->is_tv && !params->is_60hz &&
2127 	    frame_line == 0 && params->wss_width) {
2128 		/*
2129 		 * Replace the first half of the top line of a 50 Hz frame
2130 		 * with random data to simulate a WSS signal.
2131 		 */
2132 		u8 *wss = tpg->random_line[p] + params->wss_random_offset;
2133 
2134 		memcpy(vbuf, wss, params->wss_width);
2135 	}
2136 
2137 	if (tpg->show_border && frame_line >= b->top &&
2138 	    frame_line < b->top + b->height) {
2139 		unsigned bottom = b->top + b->height - 1;
2140 		unsigned left = params->left_pillar_width;
2141 		unsigned right = params->right_pillar_start;
2142 
2143 		if (frame_line == b->top || frame_line == b->top + 1 ||
2144 		    frame_line == bottom || frame_line == bottom - 1) {
2145 			memcpy(vbuf + left, tpg->contrast_line[p],
2146 					right - left);
2147 		} else {
2148 			if (b->left >= c->left &&
2149 			    b->left < c->left + c->width)
2150 				memcpy(vbuf + left,
2151 					tpg->contrast_line[p], twopixsize);
2152 			if (b->left + b->width > c->left &&
2153 			    b->left + b->width <= c->left + c->width)
2154 				memcpy(vbuf + right - twopixsize,
2155 					tpg->contrast_line[p], twopixsize);
2156 		}
2157 	}
2158 	if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
2159 	    frame_line < b->top + b->height) {
2160 		memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
2161 		memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
2162 		       img_width - params->right_pillar_start);
2163 	}
2164 	if (tpg->show_square && frame_line >= sq->top &&
2165 	    frame_line < sq->top + sq->height &&
2166 	    sq->left < c->left + c->width &&
2167 	    sq->left + sq->width >= c->left) {
2168 		unsigned left = sq->left;
2169 		unsigned width = sq->width;
2170 
2171 		if (c->left > left) {
2172 			width -= c->left - left;
2173 			left = c->left;
2174 		}
2175 		if (c->left + c->width < left + width)
2176 			width -= left + width - c->left - c->width;
2177 		left -= c->left;
2178 		left = tpg_hscale_div(tpg, p, left);
2179 		width = tpg_hscale_div(tpg, p, width);
2180 		memcpy(vbuf + left, tpg->contrast_line[p], width);
2181 	}
2182 	if (tpg->insert_sav) {
2183 		unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
2184 		u8 *p = vbuf + offset;
2185 		unsigned vact = 0, hact = 0;
2186 
2187 		p[0] = 0xff;
2188 		p[1] = 0;
2189 		p[2] = 0;
2190 		p[3] = 0x80 | (params->sav_eav_f << 6) |
2191 			(vact << 5) | (hact << 4) |
2192 			((hact ^ vact) << 3) |
2193 			((hact ^ params->sav_eav_f) << 2) |
2194 			((params->sav_eav_f ^ vact) << 1) |
2195 			(hact ^ vact ^ params->sav_eav_f);
2196 	}
2197 	if (tpg->insert_eav) {
2198 		unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
2199 		u8 *p = vbuf + offset;
2200 		unsigned vact = 0, hact = 1;
2201 
2202 		p[0] = 0xff;
2203 		p[1] = 0;
2204 		p[2] = 0;
2205 		p[3] = 0x80 | (params->sav_eav_f << 6) |
2206 			(vact << 5) | (hact << 4) |
2207 			((hact ^ vact) << 3) |
2208 			((hact ^ params->sav_eav_f) << 2) |
2209 			((params->sav_eav_f ^ vact) << 1) |
2210 			(hact ^ vact ^ params->sav_eav_f);
2211 	}
2212 }
2213 
2214 static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
2215 				   const struct tpg_draw_params *params,
2216 				   unsigned p, unsigned h, u8 *vbuf)
2217 {
2218 	unsigned twopixsize = params->twopixsize;
2219 	unsigned img_width = params->img_width;
2220 	unsigned mv_hor_old = params->mv_hor_old;
2221 	unsigned mv_hor_new = params->mv_hor_new;
2222 	unsigned mv_vert_old = params->mv_vert_old;
2223 	unsigned mv_vert_new = params->mv_vert_new;
2224 	unsigned frame_line = params->frame_line;
2225 	unsigned frame_line_next = params->frame_line_next;
2226 	unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
2227 	bool even;
2228 	bool fill_blank = false;
2229 	unsigned pat_line_old;
2230 	unsigned pat_line_new;
2231 	u8 *linestart_older;
2232 	u8 *linestart_newer;
2233 	u8 *linestart_top;
2234 	u8 *linestart_bottom;
2235 
2236 	even = !(frame_line & 1);
2237 
2238 	if (h >= params->hmax) {
2239 		if (params->hmax == tpg->compose.height)
2240 			return;
2241 		if (!tpg->perc_fill_blank)
2242 			return;
2243 		fill_blank = true;
2244 	}
2245 
2246 	if (tpg->vflip) {
2247 		frame_line = tpg->src_height - frame_line - 1;
2248 		frame_line_next = tpg->src_height - frame_line_next - 1;
2249 	}
2250 
2251 	if (fill_blank) {
2252 		linestart_older = tpg->contrast_line[p];
2253 		linestart_newer = tpg->contrast_line[p];
2254 	} else if (tpg->qual != TPG_QUAL_NOISE &&
2255 		   (frame_line < tpg->border.top ||
2256 		    frame_line >= tpg->border.top + tpg->border.height)) {
2257 		linestart_older = tpg->black_line[p];
2258 		linestart_newer = tpg->black_line[p];
2259 	} else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
2260 		linestart_older = tpg->random_line[p] +
2261 				  twopixsize * prandom_u32_max(tpg->src_width / 2);
2262 		linestart_newer = tpg->random_line[p] +
2263 				  twopixsize * prandom_u32_max(tpg->src_width / 2);
2264 	} else {
2265 		unsigned frame_line_old =
2266 			(frame_line + mv_vert_old) % tpg->src_height;
2267 		unsigned frame_line_new =
2268 			(frame_line + mv_vert_new) % tpg->src_height;
2269 		unsigned pat_line_next_old;
2270 		unsigned pat_line_next_new;
2271 
2272 		pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
2273 		pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
2274 		linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
2275 		linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
2276 
2277 		if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
2278 			int avg_pat;
2279 
2280 			/*
2281 			 * Now decide whether we need to use downsampled_lines[].
2282 			 * That's necessary if the two lines use different patterns.
2283 			 */
2284 			pat_line_next_old = tpg_get_pat_line(tpg,
2285 					(frame_line_next + mv_vert_old) % tpg->src_height);
2286 			pat_line_next_new = tpg_get_pat_line(tpg,
2287 					(frame_line_next + mv_vert_new) % tpg->src_height);
2288 
2289 			switch (tpg->field) {
2290 			case V4L2_FIELD_INTERLACED:
2291 			case V4L2_FIELD_INTERLACED_BT:
2292 			case V4L2_FIELD_INTERLACED_TB:
2293 				avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
2294 				if (avg_pat < 0)
2295 					break;
2296 				linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
2297 				linestart_newer = linestart_older;
2298 				break;
2299 			case V4L2_FIELD_NONE:
2300 			case V4L2_FIELD_TOP:
2301 			case V4L2_FIELD_BOTTOM:
2302 			case V4L2_FIELD_SEQ_BT:
2303 			case V4L2_FIELD_SEQ_TB:
2304 				avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
2305 				if (avg_pat >= 0)
2306 					linestart_older = tpg->downsampled_lines[avg_pat][p] +
2307 						mv_hor_old;
2308 				avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
2309 				if (avg_pat >= 0)
2310 					linestart_newer = tpg->downsampled_lines[avg_pat][p] +
2311 						mv_hor_new;
2312 				break;
2313 			}
2314 		}
2315 		linestart_older += line_offset;
2316 		linestart_newer += line_offset;
2317 	}
2318 	if (tpg->field_alternate) {
2319 		linestart_top = linestart_bottom = linestart_older;
2320 	} else if (params->is_60hz) {
2321 		linestart_top = linestart_newer;
2322 		linestart_bottom = linestart_older;
2323 	} else {
2324 		linestart_top = linestart_older;
2325 		linestart_bottom = linestart_newer;
2326 	}
2327 
2328 	switch (tpg->field) {
2329 	case V4L2_FIELD_INTERLACED:
2330 	case V4L2_FIELD_INTERLACED_TB:
2331 	case V4L2_FIELD_SEQ_TB:
2332 	case V4L2_FIELD_SEQ_BT:
2333 		if (even)
2334 			memcpy(vbuf, linestart_top, img_width);
2335 		else
2336 			memcpy(vbuf, linestart_bottom, img_width);
2337 		break;
2338 	case V4L2_FIELD_INTERLACED_BT:
2339 		if (even)
2340 			memcpy(vbuf, linestart_bottom, img_width);
2341 		else
2342 			memcpy(vbuf, linestart_top, img_width);
2343 		break;
2344 	case V4L2_FIELD_TOP:
2345 		memcpy(vbuf, linestart_top, img_width);
2346 		break;
2347 	case V4L2_FIELD_BOTTOM:
2348 		memcpy(vbuf, linestart_bottom, img_width);
2349 		break;
2350 	case V4L2_FIELD_NONE:
2351 	default:
2352 		memcpy(vbuf, linestart_older, img_width);
2353 		break;
2354 	}
2355 }
2356 
2357 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2358 			   unsigned p, u8 *vbuf)
2359 {
2360 	struct tpg_draw_params params;
2361 	unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2362 
2363 	/* Coarse scaling with Bresenham */
2364 	unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2365 	unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2366 	unsigned src_y = 0;
2367 	unsigned error = 0;
2368 	unsigned h;
2369 
2370 	tpg_recalc(tpg);
2371 
2372 	params.is_tv = std;
2373 	params.is_60hz = std & V4L2_STD_525_60;
2374 	params.twopixsize = tpg->twopixelsize[p];
2375 	params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2376 	params.stride = tpg->bytesperline[p];
2377 	params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2378 
2379 	tpg_fill_params_pattern(tpg, p, &params);
2380 	tpg_fill_params_extras(tpg, p, &params);
2381 
2382 	vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
2383 
2384 	for (h = 0; h < tpg->compose.height; h++) {
2385 		unsigned buf_line;
2386 
2387 		params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2388 		params.frame_line_next = params.frame_line;
2389 		buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
2390 		src_y += int_part;
2391 		error += fract_part;
2392 		if (error >= tpg->compose.height) {
2393 			error -= tpg->compose.height;
2394 			src_y++;
2395 		}
2396 
2397 		/*
2398 		 * For line-interleaved formats determine the 'plane'
2399 		 * based on the buffer line.
2400 		 */
2401 		if (tpg_g_interleaved(tpg))
2402 			p = tpg_g_interleaved_plane(tpg, buf_line);
2403 
2404 		if (tpg->vdownsampling[p] > 1) {
2405 			/*
2406 			 * When doing vertical downsampling the field setting
2407 			 * matters: for SEQ_BT/TB we downsample each field
2408 			 * separately (i.e. lines 0+2 are combined, as are
2409 			 * lines 1+3), for the other field settings we combine
2410 			 * odd and even lines. Doing that for SEQ_BT/TB would
2411 			 * be really weird.
2412 			 */
2413 			if (tpg->field == V4L2_FIELD_SEQ_BT ||
2414 			    tpg->field == V4L2_FIELD_SEQ_TB) {
2415 				unsigned next_src_y = src_y;
2416 
2417 				if ((h & 3) >= 2)
2418 					continue;
2419 				next_src_y += int_part;
2420 				if (error + fract_part >= tpg->compose.height)
2421 					next_src_y++;
2422 				params.frame_line_next =
2423 					tpg_calc_frameline(tpg, next_src_y, tpg->field);
2424 			} else {
2425 				if (h & 1)
2426 					continue;
2427 				params.frame_line_next =
2428 					tpg_calc_frameline(tpg, src_y, tpg->field);
2429 			}
2430 
2431 			buf_line /= tpg->vdownsampling[p];
2432 		}
2433 		tpg_fill_plane_pattern(tpg, &params, p, h,
2434 				vbuf + buf_line * params.stride);
2435 		tpg_fill_plane_extras(tpg, &params, p, h,
2436 				vbuf + buf_line * params.stride);
2437 	}
2438 }
2439 EXPORT_SYMBOL_GPL(tpg_fill_plane_buffer);
2440 
2441 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
2442 {
2443 	unsigned offset = 0;
2444 	unsigned i;
2445 
2446 	if (tpg->buffers > 1) {
2447 		tpg_fill_plane_buffer(tpg, std, p, vbuf);
2448 		return;
2449 	}
2450 
2451 	for (i = 0; i < tpg_g_planes(tpg); i++) {
2452 		tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
2453 		offset += tpg_calc_plane_size(tpg, i);
2454 	}
2455 }
2456 EXPORT_SYMBOL_GPL(tpg_fillbuffer);
2457 
2458 MODULE_DESCRIPTION("V4L2 Test Pattern Generator");
2459 MODULE_AUTHOR("Hans Verkuil");
2460 MODULE_LICENSE("GPL");
2461