]> Git Repo - J-linux.git/blob - drivers/media/platform/xilinx/xilinx-tpg.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / media / platform / xilinx / xilinx-tpg.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Xilinx Test Pattern Generator
4  *
5  * Copyright (C) 2013-2015 Ideas on Board
6  * Copyright (C) 2013-2015 Xilinx, Inc.
7  *
8  * Contacts: Hyun Kwon <[email protected]>
9  *           Laurent Pinchart <[email protected]>
10  */
11
12 #include <linux/device.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_graph.h>
17 #include <linux/platform_device.h>
18 #include <linux/xilinx-v4l2-controls.h>
19
20 #include <media/v4l2-async.h>
21 #include <media/v4l2-ctrls.h>
22 #include <media/v4l2-subdev.h>
23
24 #include "xilinx-vip.h"
25 #include "xilinx-vtc.h"
26
27 #define XTPG_CTRL_STATUS_SLAVE_ERROR            (1 << 16)
28 #define XTPG_CTRL_IRQ_SLAVE_ERROR               (1 << 16)
29
30 #define XTPG_PATTERN_CONTROL                    0x0100
31 #define XTPG_PATTERN_MASK                       (0xf << 0)
32 #define XTPG_PATTERN_CONTROL_CROSS_HAIRS        (1 << 4)
33 #define XTPG_PATTERN_CONTROL_MOVING_BOX         (1 << 5)
34 #define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT   6
35 #define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK    (0xf << 6)
36 #define XTPG_PATTERN_CONTROL_STUCK_PIXEL        (1 << 9)
37 #define XTPG_PATTERN_CONTROL_NOISE              (1 << 10)
38 #define XTPG_PATTERN_CONTROL_MOTION             (1 << 12)
39 #define XTPG_MOTION_SPEED                       0x0104
40 #define XTPG_CROSS_HAIRS                        0x0108
41 #define XTPG_CROSS_HAIRS_ROW_SHIFT              0
42 #define XTPG_CROSS_HAIRS_ROW_MASK               (0xfff << 0)
43 #define XTPG_CROSS_HAIRS_COLUMN_SHIFT           16
44 #define XTPG_CROSS_HAIRS_COLUMN_MASK            (0xfff << 16)
45 #define XTPG_ZPLATE_HOR_CONTROL                 0x010c
46 #define XTPG_ZPLATE_VER_CONTROL                 0x0110
47 #define XTPG_ZPLATE_START_SHIFT                 0
48 #define XTPG_ZPLATE_START_MASK                  (0xffff << 0)
49 #define XTPG_ZPLATE_SPEED_SHIFT                 16
50 #define XTPG_ZPLATE_SPEED_MASK                  (0xffff << 16)
51 #define XTPG_BOX_SIZE                           0x0114
52 #define XTPG_BOX_COLOR                          0x0118
53 #define XTPG_STUCK_PIXEL_THRESH                 0x011c
54 #define XTPG_NOISE_GAIN                         0x0120
55 #define XTPG_BAYER_PHASE                        0x0124
56 #define XTPG_BAYER_PHASE_RGGB                   0
57 #define XTPG_BAYER_PHASE_GRBG                   1
58 #define XTPG_BAYER_PHASE_GBRG                   2
59 #define XTPG_BAYER_PHASE_BGGR                   3
60 #define XTPG_BAYER_PHASE_OFF                    4
61
62 /*
63  * The minimum blanking value is one clock cycle for the front porch, one clock
64  * cycle for the sync pulse and one clock cycle for the back porch.
65  */
66 #define XTPG_MIN_HBLANK                 3
67 #define XTPG_MAX_HBLANK                 (XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
68 #define XTPG_MIN_VBLANK                 3
69 #define XTPG_MAX_VBLANK                 (XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
70
71 /**
72  * struct xtpg_device - Xilinx Test Pattern Generator device structure
73  * @xvip: Xilinx Video IP device
74  * @pads: media pads
75  * @npads: number of pads (1 or 2)
76  * @has_input: whether an input is connected to the sink pad
77  * @formats: active V4L2 media bus format for each pad
78  * @default_format: default V4L2 media bus format
79  * @vip_format: format information corresponding to the active format
80  * @bayer: boolean flag if TPG is set to any bayer format
81  * @ctrl_handler: control handler
82  * @hblank: horizontal blanking control
83  * @vblank: vertical blanking control
84  * @pattern: test pattern control
85  * @streaming: is the video stream active
86  * @vtc: video timing controller
87  * @vtmux_gpio: video timing mux GPIO
88  */
89 struct xtpg_device {
90         struct xvip_device xvip;
91
92         struct media_pad pads[2];
93         unsigned int npads;
94         bool has_input;
95
96         struct v4l2_mbus_framefmt formats[2];
97         struct v4l2_mbus_framefmt default_format;
98         const struct xvip_video_format *vip_format;
99         bool bayer;
100
101         struct v4l2_ctrl_handler ctrl_handler;
102         struct v4l2_ctrl *hblank;
103         struct v4l2_ctrl *vblank;
104         struct v4l2_ctrl *pattern;
105         bool streaming;
106
107         struct xvtc_device *vtc;
108         struct gpio_desc *vtmux_gpio;
109 };
110
111 static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
112 {
113         return container_of(subdev, struct xtpg_device, xvip.subdev);
114 }
115
116 static u32 xtpg_get_bayer_phase(unsigned int code)
117 {
118         switch (code) {
119         case MEDIA_BUS_FMT_SRGGB8_1X8:
120                 return XTPG_BAYER_PHASE_RGGB;
121         case MEDIA_BUS_FMT_SGRBG8_1X8:
122                 return XTPG_BAYER_PHASE_GRBG;
123         case MEDIA_BUS_FMT_SGBRG8_1X8:
124                 return XTPG_BAYER_PHASE_GBRG;
125         case MEDIA_BUS_FMT_SBGGR8_1X8:
126                 return XTPG_BAYER_PHASE_BGGR;
127         default:
128                 return XTPG_BAYER_PHASE_OFF;
129         }
130 }
131
132 static void __xtpg_update_pattern_control(struct xtpg_device *xtpg,
133                                           bool passthrough, bool pattern)
134 {
135         u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1;
136
137         /*
138          * If the TPG has no sink pad or no input connected to its sink pad
139          * passthrough mode can't be enabled.
140          */
141         if (xtpg->npads == 1 || !xtpg->has_input)
142                 passthrough = false;
143
144         /* If passthrough mode is allowed unmask bit 0. */
145         if (passthrough)
146                 pattern_mask &= ~1;
147
148         /* If test pattern mode is allowed unmask all other bits. */
149         if (pattern)
150                 pattern_mask &= 1;
151
152         __v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum,
153                                  pattern_mask, pattern ? 9 : 0);
154 }
155
156 static void xtpg_update_pattern_control(struct xtpg_device *xtpg,
157                                         bool passthrough, bool pattern)
158 {
159         mutex_lock(xtpg->ctrl_handler.lock);
160         __xtpg_update_pattern_control(xtpg, passthrough, pattern);
161         mutex_unlock(xtpg->ctrl_handler.lock);
162 }
163
164 /* -----------------------------------------------------------------------------
165  * V4L2 Subdevice Video Operations
166  */
167
168 static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
169 {
170         struct xtpg_device *xtpg = to_tpg(subdev);
171         unsigned int width = xtpg->formats[0].width;
172         unsigned int height = xtpg->formats[0].height;
173         bool passthrough;
174         u32 bayer_phase;
175
176         if (!enable) {
177                 xvip_stop(&xtpg->xvip);
178                 if (xtpg->vtc)
179                         xvtc_generator_stop(xtpg->vtc);
180
181                 xtpg_update_pattern_control(xtpg, true, true);
182                 xtpg->streaming = false;
183                 return 0;
184         }
185
186         xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]);
187
188         if (xtpg->vtc) {
189                 struct xvtc_config config = {
190                         .hblank_start = width,
191                         .hsync_start = width + 1,
192                         .vblank_start = height,
193                         .vsync_start = height + 1,
194                 };
195                 unsigned int htotal;
196                 unsigned int vtotal;
197
198                 htotal = min_t(unsigned int, XVTC_MAX_HSIZE,
199                                v4l2_ctrl_g_ctrl(xtpg->hblank) + width);
200                 vtotal = min_t(unsigned int, XVTC_MAX_VSIZE,
201                                v4l2_ctrl_g_ctrl(xtpg->vblank) + height);
202
203                 config.hsync_end = htotal - 1;
204                 config.hsize = htotal;
205                 config.vsync_end = vtotal - 1;
206                 config.vsize = vtotal;
207
208                 xvtc_generator_start(xtpg->vtc, &config);
209         }
210
211         /*
212          * Configure the bayer phase and video timing mux based on the
213          * operation mode (passthrough or test pattern generation). The test
214          * pattern can be modified by the control set handler, we thus need to
215          * take the control lock here to avoid races.
216          */
217         mutex_lock(xtpg->ctrl_handler.lock);
218
219         xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
220                          XTPG_PATTERN_MASK, xtpg->pattern->cur.val);
221
222         /*
223          * Switching between passthrough and test pattern generation modes isn't
224          * allowed during streaming, update the control range accordingly.
225          */
226         passthrough = xtpg->pattern->cur.val == 0;
227         __xtpg_update_pattern_control(xtpg, passthrough, !passthrough);
228
229         xtpg->streaming = true;
230
231         mutex_unlock(xtpg->ctrl_handler.lock);
232
233         /*
234          * For TPG v5.0, the bayer phase needs to be off for the pass through
235          * mode, otherwise the external input would be subsampled.
236          */
237         bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF
238                     : xtpg_get_bayer_phase(xtpg->formats[0].code);
239         xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase);
240
241         if (xtpg->vtmux_gpio)
242                 gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough);
243
244         xvip_start(&xtpg->xvip);
245
246         return 0;
247 }
248
249 /* -----------------------------------------------------------------------------
250  * V4L2 Subdevice Pad Operations
251  */
252
253 static struct v4l2_mbus_framefmt *
254 __xtpg_get_pad_format(struct xtpg_device *xtpg,
255                       struct v4l2_subdev_state *sd_state,
256                       unsigned int pad, u32 which)
257 {
258         switch (which) {
259         case V4L2_SUBDEV_FORMAT_TRY:
260                 return v4l2_subdev_state_get_format(sd_state, pad);
261         case V4L2_SUBDEV_FORMAT_ACTIVE:
262                 return &xtpg->formats[pad];
263         default:
264                 return NULL;
265         }
266 }
267
268 static int xtpg_get_format(struct v4l2_subdev *subdev,
269                            struct v4l2_subdev_state *sd_state,
270                            struct v4l2_subdev_format *fmt)
271 {
272         struct xtpg_device *xtpg = to_tpg(subdev);
273
274         fmt->format = *__xtpg_get_pad_format(xtpg, sd_state, fmt->pad,
275                                              fmt->which);
276
277         return 0;
278 }
279
280 static int xtpg_set_format(struct v4l2_subdev *subdev,
281                            struct v4l2_subdev_state *sd_state,
282                            struct v4l2_subdev_format *fmt)
283 {
284         struct xtpg_device *xtpg = to_tpg(subdev);
285         struct v4l2_mbus_framefmt *__format;
286         u32 bayer_phase;
287
288         __format = __xtpg_get_pad_format(xtpg, sd_state, fmt->pad, fmt->which);
289
290         /* In two pads mode the source pad format is always identical to the
291          * sink pad format.
292          */
293         if (xtpg->npads == 2 && fmt->pad == 1) {
294                 fmt->format = *__format;
295                 return 0;
296         }
297
298         /* Bayer phase is configurable at runtime */
299         if (xtpg->bayer) {
300                 bayer_phase = xtpg_get_bayer_phase(fmt->format.code);
301                 if (bayer_phase != XTPG_BAYER_PHASE_OFF)
302                         __format->code = fmt->format.code;
303         }
304
305         xvip_set_format_size(__format, fmt);
306
307         fmt->format = *__format;
308
309         /* Propagate the format to the source pad. */
310         if (xtpg->npads == 2) {
311                 __format = __xtpg_get_pad_format(xtpg, sd_state, 1,
312                                                  fmt->which);
313                 *__format = fmt->format;
314         }
315
316         return 0;
317 }
318
319 /* -----------------------------------------------------------------------------
320  * V4L2 Subdevice Operations
321  */
322
323 static int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
324                                 struct v4l2_subdev_state *sd_state,
325                                 struct v4l2_subdev_frame_size_enum *fse)
326 {
327         struct v4l2_mbus_framefmt *format;
328
329         format = v4l2_subdev_state_get_format(sd_state, fse->pad);
330
331         if (fse->index || fse->code != format->code)
332                 return -EINVAL;
333
334         /* Min / max values for pad 0 is always fixed in both one and two pads
335          * modes. In two pads mode, the source pad(= 1) size is identical to
336          * the sink pad size */
337         if (fse->pad == 0) {
338                 fse->min_width = XVIP_MIN_WIDTH;
339                 fse->max_width = XVIP_MAX_WIDTH;
340                 fse->min_height = XVIP_MIN_HEIGHT;
341                 fse->max_height = XVIP_MAX_HEIGHT;
342         } else {
343                 fse->min_width = format->width;
344                 fse->max_width = format->width;
345                 fse->min_height = format->height;
346                 fse->max_height = format->height;
347         }
348
349         return 0;
350 }
351
352 static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
353 {
354         struct xtpg_device *xtpg = to_tpg(subdev);
355         struct v4l2_mbus_framefmt *format;
356
357         format = v4l2_subdev_state_get_format(fh->state, 0);
358         *format = xtpg->default_format;
359
360         if (xtpg->npads == 2) {
361                 format = v4l2_subdev_state_get_format(fh->state, 1);
362                 *format = xtpg->default_format;
363         }
364
365         return 0;
366 }
367
368 static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
369 {
370         return 0;
371 }
372
373 static int xtpg_s_ctrl(struct v4l2_ctrl *ctrl)
374 {
375         struct xtpg_device *xtpg = container_of(ctrl->handler,
376                                                 struct xtpg_device,
377                                                 ctrl_handler);
378         switch (ctrl->id) {
379         case V4L2_CID_TEST_PATTERN:
380                 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
381                                  XTPG_PATTERN_MASK, ctrl->val);
382                 return 0;
383         case V4L2_CID_XILINX_TPG_CROSS_HAIRS:
384                 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
385                                 XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val);
386                 return 0;
387         case V4L2_CID_XILINX_TPG_MOVING_BOX:
388                 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
389                                 XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val);
390                 return 0;
391         case V4L2_CID_XILINX_TPG_COLOR_MASK:
392                 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
393                                  XTPG_PATTERN_CONTROL_COLOR_MASK_MASK,
394                                  ctrl->val <<
395                                  XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT);
396                 return 0;
397         case V4L2_CID_XILINX_TPG_STUCK_PIXEL:
398                 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
399                                 XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val);
400                 return 0;
401         case V4L2_CID_XILINX_TPG_NOISE:
402                 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
403                                 XTPG_PATTERN_CONTROL_NOISE, ctrl->val);
404                 return 0;
405         case V4L2_CID_XILINX_TPG_MOTION:
406                 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
407                                 XTPG_PATTERN_CONTROL_MOTION, ctrl->val);
408                 return 0;
409         case V4L2_CID_XILINX_TPG_MOTION_SPEED:
410                 xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val);
411                 return 0;
412         case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW:
413                 xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
414                                  XTPG_CROSS_HAIRS_ROW_MASK,
415                                  ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT);
416                 return 0;
417         case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN:
418                 xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
419                                  XTPG_CROSS_HAIRS_COLUMN_MASK,
420                                  ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT);
421                 return 0;
422         case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START:
423                 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
424                                  XTPG_ZPLATE_START_MASK,
425                                  ctrl->val << XTPG_ZPLATE_START_SHIFT);
426                 return 0;
427         case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED:
428                 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
429                                  XTPG_ZPLATE_SPEED_MASK,
430                                  ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
431                 return 0;
432         case V4L2_CID_XILINX_TPG_ZPLATE_VER_START:
433                 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
434                                  XTPG_ZPLATE_START_MASK,
435                                  ctrl->val << XTPG_ZPLATE_START_SHIFT);
436                 return 0;
437         case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED:
438                 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
439                                  XTPG_ZPLATE_SPEED_MASK,
440                                  ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
441                 return 0;
442         case V4L2_CID_XILINX_TPG_BOX_SIZE:
443                 xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val);
444                 return 0;
445         case V4L2_CID_XILINX_TPG_BOX_COLOR:
446                 xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val);
447                 return 0;
448         case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH:
449                 xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val);
450                 return 0;
451         case V4L2_CID_XILINX_TPG_NOISE_GAIN:
452                 xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val);
453                 return 0;
454         }
455
456         return 0;
457 }
458
459 static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
460         .s_ctrl = xtpg_s_ctrl,
461 };
462
463 static const struct v4l2_subdev_core_ops xtpg_core_ops = {
464 };
465
466 static const struct v4l2_subdev_video_ops xtpg_video_ops = {
467         .s_stream = xtpg_s_stream,
468 };
469
470 static const struct v4l2_subdev_pad_ops xtpg_pad_ops = {
471         .enum_mbus_code         = xvip_enum_mbus_code,
472         .enum_frame_size        = xtpg_enum_frame_size,
473         .get_fmt                = xtpg_get_format,
474         .set_fmt                = xtpg_set_format,
475 };
476
477 static const struct v4l2_subdev_ops xtpg_ops = {
478         .core   = &xtpg_core_ops,
479         .video  = &xtpg_video_ops,
480         .pad    = &xtpg_pad_ops,
481 };
482
483 static const struct v4l2_subdev_internal_ops xtpg_internal_ops = {
484         .open   = xtpg_open,
485         .close  = xtpg_close,
486 };
487
488 /*
489  * Control Config
490  */
491
492 static const char *const xtpg_pattern_strings[] = {
493         "Passthrough",
494         "Horizontal Ramp",
495         "Vertical Ramp",
496         "Temporal Ramp",
497         "Solid Red",
498         "Solid Green",
499         "Solid Blue",
500         "Solid Black",
501         "Solid White",
502         "Color Bars",
503         "Zone Plate",
504         "Tartan Color Bars",
505         "Cross Hatch",
506         "None",
507         "Vertical/Horizontal Ramps",
508         "Black/White Checker Board",
509 };
510
511 static struct v4l2_ctrl_config xtpg_ctrls[] = {
512         {
513                 .ops    = &xtpg_ctrl_ops,
514                 .id     = V4L2_CID_XILINX_TPG_CROSS_HAIRS,
515                 .name   = "Test Pattern: Cross Hairs",
516                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
517                 .min    = false,
518                 .max    = true,
519                 .step   = 1,
520                 .def    = 0,
521         }, {
522                 .ops    = &xtpg_ctrl_ops,
523                 .id     = V4L2_CID_XILINX_TPG_MOVING_BOX,
524                 .name   = "Test Pattern: Moving Box",
525                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
526                 .min    = false,
527                 .max    = true,
528                 .step   = 1,
529                 .def    = 0,
530         }, {
531                 .ops    = &xtpg_ctrl_ops,
532                 .id     = V4L2_CID_XILINX_TPG_COLOR_MASK,
533                 .name   = "Test Pattern: Color Mask",
534                 .type   = V4L2_CTRL_TYPE_BITMASK,
535                 .min    = 0,
536                 .max    = 0xf,
537                 .def    = 0,
538         }, {
539                 .ops    = &xtpg_ctrl_ops,
540                 .id     = V4L2_CID_XILINX_TPG_STUCK_PIXEL,
541                 .name   = "Test Pattern: Stuck Pixel",
542                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
543                 .min    = false,
544                 .max    = true,
545                 .step   = 1,
546                 .def    = 0,
547         }, {
548                 .ops    = &xtpg_ctrl_ops,
549                 .id     = V4L2_CID_XILINX_TPG_NOISE,
550                 .name   = "Test Pattern: Noise",
551                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
552                 .min    = false,
553                 .max    = true,
554                 .step   = 1,
555                 .def    = 0,
556         }, {
557                 .ops    = &xtpg_ctrl_ops,
558                 .id     = V4L2_CID_XILINX_TPG_MOTION,
559                 .name   = "Test Pattern: Motion",
560                 .type   = V4L2_CTRL_TYPE_BOOLEAN,
561                 .min    = false,
562                 .max    = true,
563                 .step   = 1,
564                 .def    = 0,
565         }, {
566                 .ops    = &xtpg_ctrl_ops,
567                 .id     = V4L2_CID_XILINX_TPG_MOTION_SPEED,
568                 .name   = "Test Pattern: Motion Speed",
569                 .type   = V4L2_CTRL_TYPE_INTEGER,
570                 .min    = 0,
571                 .max    = (1 << 8) - 1,
572                 .step   = 1,
573                 .def    = 4,
574                 .flags  = V4L2_CTRL_FLAG_SLIDER,
575         }, {
576                 .ops    = &xtpg_ctrl_ops,
577                 .id     = V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW,
578                 .name   = "Test Pattern: Cross Hairs Row",
579                 .type   = V4L2_CTRL_TYPE_INTEGER,
580                 .min    = 0,
581                 .max    = (1 << 12) - 1,
582                 .step   = 1,
583                 .def    = 0x64,
584                 .flags  = V4L2_CTRL_FLAG_SLIDER,
585         }, {
586                 .ops    = &xtpg_ctrl_ops,
587                 .id     = V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN,
588                 .name   = "Test Pattern: Cross Hairs Column",
589                 .type   = V4L2_CTRL_TYPE_INTEGER,
590                 .min    = 0,
591                 .max    = (1 << 12) - 1,
592                 .step   = 1,
593                 .def    = 0x64,
594                 .flags  = V4L2_CTRL_FLAG_SLIDER,
595         }, {
596                 .ops    = &xtpg_ctrl_ops,
597                 .id     = V4L2_CID_XILINX_TPG_ZPLATE_HOR_START,
598                 .name   = "Test Pattern: Zplate Horizontal Start Pos",
599                 .type   = V4L2_CTRL_TYPE_INTEGER,
600                 .min    = 0,
601                 .max    = (1 << 16) - 1,
602                 .step   = 1,
603                 .def    = 0x1e,
604                 .flags  = V4L2_CTRL_FLAG_SLIDER,
605         }, {
606                 .ops    = &xtpg_ctrl_ops,
607                 .id     = V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED,
608                 .name   = "Test Pattern: Zplate Horizontal Speed",
609                 .type   = V4L2_CTRL_TYPE_INTEGER,
610                 .min    = 0,
611                 .max    = (1 << 16) - 1,
612                 .step   = 1,
613                 .def    = 0,
614                 .flags  = V4L2_CTRL_FLAG_SLIDER,
615         }, {
616                 .ops    = &xtpg_ctrl_ops,
617                 .id     = V4L2_CID_XILINX_TPG_ZPLATE_VER_START,
618                 .name   = "Test Pattern: Zplate Vertical Start Pos",
619                 .type   = V4L2_CTRL_TYPE_INTEGER,
620                 .min    = 0,
621                 .max    = (1 << 16) - 1,
622                 .step   = 1,
623                 .def    = 1,
624                 .flags  = V4L2_CTRL_FLAG_SLIDER,
625         }, {
626                 .ops    = &xtpg_ctrl_ops,
627                 .id     = V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED,
628                 .name   = "Test Pattern: Zplate Vertical Speed",
629                 .type   = V4L2_CTRL_TYPE_INTEGER,
630                 .min    = 0,
631                 .max    = (1 << 16) - 1,
632                 .step   = 1,
633                 .def    = 0,
634                 .flags  = V4L2_CTRL_FLAG_SLIDER,
635         }, {
636                 .ops    = &xtpg_ctrl_ops,
637                 .id     = V4L2_CID_XILINX_TPG_BOX_SIZE,
638                 .name   = "Test Pattern: Box Size",
639                 .type   = V4L2_CTRL_TYPE_INTEGER,
640                 .min    = 0,
641                 .max    = (1 << 12) - 1,
642                 .step   = 1,
643                 .def    = 0x32,
644                 .flags  = V4L2_CTRL_FLAG_SLIDER,
645         }, {
646                 .ops    = &xtpg_ctrl_ops,
647                 .id     = V4L2_CID_XILINX_TPG_BOX_COLOR,
648                 .name   = "Test Pattern: Box Color(RGB)",
649                 .type   = V4L2_CTRL_TYPE_INTEGER,
650                 .min    = 0,
651                 .max    = (1 << 24) - 1,
652                 .step   = 1,
653                 .def    = 0,
654         }, {
655                 .ops    = &xtpg_ctrl_ops,
656                 .id     = V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH,
657                 .name   = "Test Pattern: Stuck Pixel threshold",
658                 .type   = V4L2_CTRL_TYPE_INTEGER,
659                 .min    = 0,
660                 .max    = (1 << 16) - 1,
661                 .step   = 1,
662                 .def    = 0,
663                 .flags  = V4L2_CTRL_FLAG_SLIDER,
664         }, {
665                 .ops    = &xtpg_ctrl_ops,
666                 .id     = V4L2_CID_XILINX_TPG_NOISE_GAIN,
667                 .name   = "Test Pattern: Noise Gain",
668                 .type   = V4L2_CTRL_TYPE_INTEGER,
669                 .min    = 0,
670                 .max    = (1 << 8) - 1,
671                 .step   = 1,
672                 .def    = 0,
673                 .flags  = V4L2_CTRL_FLAG_SLIDER,
674         },
675 };
676
677 /* -----------------------------------------------------------------------------
678  * Media Operations
679  */
680
681 static const struct media_entity_operations xtpg_media_ops = {
682         .link_validate = v4l2_subdev_link_validate,
683 };
684
685 /* -----------------------------------------------------------------------------
686  * Power Management
687  */
688
689 static int __maybe_unused xtpg_pm_suspend(struct device *dev)
690 {
691         struct xtpg_device *xtpg = dev_get_drvdata(dev);
692
693         xvip_suspend(&xtpg->xvip);
694
695         return 0;
696 }
697
698 static int __maybe_unused xtpg_pm_resume(struct device *dev)
699 {
700         struct xtpg_device *xtpg = dev_get_drvdata(dev);
701
702         xvip_resume(&xtpg->xvip);
703
704         return 0;
705 }
706
707 /* -----------------------------------------------------------------------------
708  * Platform Device Driver
709  */
710
711 static int xtpg_parse_of(struct xtpg_device *xtpg)
712 {
713         struct device *dev = xtpg->xvip.dev;
714         struct device_node *node = xtpg->xvip.dev->of_node;
715         unsigned int nports = 0;
716         bool has_endpoint = false;
717
718         for_each_of_graph_port(node, port) {
719                 const struct xvip_video_format *format;
720                 struct device_node *endpoint;
721
722                 format = xvip_of_get_format(port);
723                 if (IS_ERR(format)) {
724                         dev_err(dev, "invalid format in DT");
725                         of_node_put(port);
726                         return PTR_ERR(format);
727                 }
728
729                 /* Get and check the format description */
730                 if (!xtpg->vip_format) {
731                         xtpg->vip_format = format;
732                 } else if (xtpg->vip_format != format) {
733                         dev_err(dev, "in/out format mismatch in DT");
734                         of_node_put(port);
735                         return -EINVAL;
736                 }
737
738                 if (nports == 0) {
739                         endpoint = of_graph_get_next_port_endpoint(port, NULL);
740                         if (endpoint)
741                                 has_endpoint = true;
742                         of_node_put(endpoint);
743                 }
744
745                 /* Count the number of ports. */
746                 nports++;
747         }
748
749         if (nports != 1 && nports != 2) {
750                 dev_err(dev, "invalid number of ports %u\n", nports);
751                 return -EINVAL;
752         }
753
754         xtpg->npads = nports;
755         if (nports == 2 && has_endpoint)
756                 xtpg->has_input = true;
757
758         return 0;
759 }
760
761 static int xtpg_probe(struct platform_device *pdev)
762 {
763         struct v4l2_subdev *subdev;
764         struct xtpg_device *xtpg;
765         u32 i, bayer_phase;
766         int ret;
767
768         xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL);
769         if (!xtpg)
770                 return -ENOMEM;
771
772         xtpg->xvip.dev = &pdev->dev;
773
774         ret = xtpg_parse_of(xtpg);
775         if (ret < 0)
776                 return ret;
777
778         ret = xvip_init_resources(&xtpg->xvip);
779         if (ret < 0)
780                 return ret;
781
782         xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing",
783                                                    GPIOD_OUT_HIGH);
784         if (IS_ERR(xtpg->vtmux_gpio)) {
785                 ret = PTR_ERR(xtpg->vtmux_gpio);
786                 goto error_resource;
787         }
788
789         xtpg->vtc = xvtc_of_get(pdev->dev.of_node);
790         if (IS_ERR(xtpg->vtc)) {
791                 ret = PTR_ERR(xtpg->vtc);
792                 goto error_resource;
793         }
794
795         /* Reset and initialize the core */
796         xvip_reset(&xtpg->xvip);
797
798         /* Initialize V4L2 subdevice and media entity. Pad numbers depend on the
799          * number of pads.
800          */
801         if (xtpg->npads == 2) {
802                 xtpg->pads[0].flags = MEDIA_PAD_FL_SINK;
803                 xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE;
804         } else {
805                 xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE;
806         }
807
808         /* Initialize the default format */
809         xtpg->default_format.code = xtpg->vip_format->code;
810         xtpg->default_format.field = V4L2_FIELD_NONE;
811         xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB;
812         xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format);
813
814         bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code);
815         if (bayer_phase != XTPG_BAYER_PHASE_OFF)
816                 xtpg->bayer = true;
817
818         xtpg->formats[0] = xtpg->default_format;
819         if (xtpg->npads == 2)
820                 xtpg->formats[1] = xtpg->default_format;
821
822         /* Initialize V4L2 subdevice and media entity */
823         subdev = &xtpg->xvip.subdev;
824         v4l2_subdev_init(subdev, &xtpg_ops);
825         subdev->dev = &pdev->dev;
826         subdev->internal_ops = &xtpg_internal_ops;
827         strscpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
828         v4l2_set_subdevdata(subdev, xtpg);
829         subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
830         subdev->entity.ops = &xtpg_media_ops;
831
832         ret = media_entity_pads_init(&subdev->entity, xtpg->npads, xtpg->pads);
833         if (ret < 0)
834                 goto error;
835
836         v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls));
837
838         xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
839                                          V4L2_CID_VBLANK, XTPG_MIN_VBLANK,
840                                          XTPG_MAX_VBLANK, 1, 100);
841         xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
842                                          V4L2_CID_HBLANK, XTPG_MIN_HBLANK,
843                                          XTPG_MAX_HBLANK, 1, 100);
844         xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler,
845                                         &xtpg_ctrl_ops, V4L2_CID_TEST_PATTERN,
846                                         ARRAY_SIZE(xtpg_pattern_strings) - 1,
847                                         1, 9, xtpg_pattern_strings);
848
849         for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++)
850                 v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL);
851
852         if (xtpg->ctrl_handler.error) {
853                 dev_err(&pdev->dev, "failed to add controls\n");
854                 ret = xtpg->ctrl_handler.error;
855                 goto error;
856         }
857         subdev->ctrl_handler = &xtpg->ctrl_handler;
858
859         xtpg_update_pattern_control(xtpg, true, true);
860
861         ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler);
862         if (ret < 0) {
863                 dev_err(&pdev->dev, "failed to set controls\n");
864                 goto error;
865         }
866
867         platform_set_drvdata(pdev, xtpg);
868
869         xvip_print_version(&xtpg->xvip);
870
871         ret = v4l2_async_register_subdev(subdev);
872         if (ret < 0) {
873                 dev_err(&pdev->dev, "failed to register subdev\n");
874                 goto error;
875         }
876
877         return 0;
878
879 error:
880         v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
881         media_entity_cleanup(&subdev->entity);
882         xvtc_put(xtpg->vtc);
883 error_resource:
884         xvip_cleanup_resources(&xtpg->xvip);
885         return ret;
886 }
887
888 static void xtpg_remove(struct platform_device *pdev)
889 {
890         struct xtpg_device *xtpg = platform_get_drvdata(pdev);
891         struct v4l2_subdev *subdev = &xtpg->xvip.subdev;
892
893         v4l2_async_unregister_subdev(subdev);
894         v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
895         media_entity_cleanup(&subdev->entity);
896
897         xvip_cleanup_resources(&xtpg->xvip);
898 }
899
900 static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
901
902 static const struct of_device_id xtpg_of_id_table[] = {
903         { .compatible = "xlnx,v-tpg-5.0" },
904         { }
905 };
906 MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
907
908 static struct platform_driver xtpg_driver = {
909         .driver = {
910                 .name           = "xilinx-tpg",
911                 .pm             = &xtpg_pm_ops,
912                 .of_match_table = xtpg_of_id_table,
913         },
914         .probe                  = xtpg_probe,
915         .remove                 = xtpg_remove,
916 };
917
918 module_platform_driver(xtpg_driver);
919
920 MODULE_AUTHOR("Laurent Pinchart <[email protected]>");
921 MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
922 MODULE_LICENSE("GPL v2");
This page took 0.082448 seconds and 4 git commands to generate.