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