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