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