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