2 * Xilinx Test Pattern Generator
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/device.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/xilinx-v4l2-controls.h>
22 #include <media/v4l2-async.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-subdev.h>
26 #include "xilinx-vip.h"
27 #include "xilinx-vtc.h"
29 #define XTPG_CTRL_STATUS_SLAVE_ERROR (1 << 16)
30 #define XTPG_CTRL_IRQ_SLAVE_ERROR (1 << 16)
32 #define XTPG_PATTERN_CONTROL 0x0100
33 #define XTPG_PATTERN_MASK (0xf << 0)
34 #define XTPG_PATTERN_CONTROL_CROSS_HAIRS (1 << 4)
35 #define XTPG_PATTERN_CONTROL_MOVING_BOX (1 << 5)
36 #define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT 6
37 #define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK (0xf << 6)
38 #define XTPG_PATTERN_CONTROL_STUCK_PIXEL (1 << 9)
39 #define XTPG_PATTERN_CONTROL_NOISE (1 << 10)
40 #define XTPG_PATTERN_CONTROL_MOTION (1 << 12)
41 #define XTPG_MOTION_SPEED 0x0104
42 #define XTPG_CROSS_HAIRS 0x0108
43 #define XTPG_CROSS_HAIRS_ROW_SHIFT 0
44 #define XTPG_CROSS_HAIRS_ROW_MASK (0xfff << 0)
45 #define XTPG_CROSS_HAIRS_COLUMN_SHIFT 16
46 #define XTPG_CROSS_HAIRS_COLUMN_MASK (0xfff << 16)
47 #define XTPG_ZPLATE_HOR_CONTROL 0x010c
48 #define XTPG_ZPLATE_VER_CONTROL 0x0110
49 #define XTPG_ZPLATE_START_SHIFT 0
50 #define XTPG_ZPLATE_START_MASK (0xffff << 0)
51 #define XTPG_ZPLATE_SPEED_SHIFT 16
52 #define XTPG_ZPLATE_SPEED_MASK (0xffff << 16)
53 #define XTPG_BOX_SIZE 0x0114
54 #define XTPG_BOX_COLOR 0x0118
55 #define XTPG_STUCK_PIXEL_THRESH 0x011c
56 #define XTPG_NOISE_GAIN 0x0120
57 #define XTPG_BAYER_PHASE 0x0124
58 #define XTPG_BAYER_PHASE_RGGB 0
59 #define XTPG_BAYER_PHASE_GRBG 1
60 #define XTPG_BAYER_PHASE_GBRG 2
61 #define XTPG_BAYER_PHASE_BGGR 3
62 #define XTPG_BAYER_PHASE_OFF 4
65 * The minimum blanking value is one clock cycle for the front porch, one clock
66 * cycle for the sync pulse and one clock cycle for the back porch.
68 #define XTPG_MIN_HBLANK 3
69 #define XTPG_MAX_HBLANK (XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
70 #define XTPG_MIN_VBLANK 3
71 #define XTPG_MAX_VBLANK (XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
74 * struct xtpg_device - Xilinx Test Pattern Generator device structure
75 * @xvip: Xilinx Video IP device
77 * @npads: number of pads (1 or 2)
78 * @has_input: whether an input is connected to the sink pad
79 * @formats: active V4L2 media bus format for each pad
80 * @default_format: default V4L2 media bus format
81 * @vip_format: format information corresponding to the active format
82 * @bayer: boolean flag if TPG is set to any bayer format
83 * @ctrl_handler: control handler
84 * @hblank: horizontal blanking control
85 * @vblank: vertical blanking control
86 * @pattern: test pattern control
87 * @streaming: is the video stream active
88 * @vtc: video timing controller
89 * @vtmux_gpio: video timing mux GPIO
92 struct xvip_device xvip
;
94 struct media_pad pads
[2];
98 struct v4l2_mbus_framefmt formats
[2];
99 struct v4l2_mbus_framefmt default_format
;
100 const struct xvip_video_format
*vip_format
;
103 struct v4l2_ctrl_handler ctrl_handler
;
104 struct v4l2_ctrl
*hblank
;
105 struct v4l2_ctrl
*vblank
;
106 struct v4l2_ctrl
*pattern
;
109 struct xvtc_device
*vtc
;
110 struct gpio_desc
*vtmux_gpio
;
113 static inline struct xtpg_device
*to_tpg(struct v4l2_subdev
*subdev
)
115 return container_of(subdev
, struct xtpg_device
, xvip
.subdev
);
118 static u32
xtpg_get_bayer_phase(unsigned int code
)
121 case MEDIA_BUS_FMT_SRGGB8_1X8
:
122 return XTPG_BAYER_PHASE_RGGB
;
123 case MEDIA_BUS_FMT_SGRBG8_1X8
:
124 return XTPG_BAYER_PHASE_GRBG
;
125 case MEDIA_BUS_FMT_SGBRG8_1X8
:
126 return XTPG_BAYER_PHASE_GBRG
;
127 case MEDIA_BUS_FMT_SBGGR8_1X8
:
128 return XTPG_BAYER_PHASE_BGGR
;
130 return XTPG_BAYER_PHASE_OFF
;
134 static void __xtpg_update_pattern_control(struct xtpg_device
*xtpg
,
135 bool passthrough
, bool pattern
)
137 u32 pattern_mask
= (1 << (xtpg
->pattern
->maximum
+ 1)) - 1;
140 * If the TPG has no sink pad or no input connected to its sink pad
141 * passthrough mode can't be enabled.
143 if (xtpg
->npads
== 1 || !xtpg
->has_input
)
146 /* If passthrough mode is allowed unmask bit 0. */
150 /* If test pattern mode is allowed unmask all other bits. */
154 __v4l2_ctrl_modify_range(xtpg
->pattern
, 0, xtpg
->pattern
->maximum
,
155 pattern_mask
, pattern
? 9 : 0);
158 static void xtpg_update_pattern_control(struct xtpg_device
*xtpg
,
159 bool passthrough
, bool pattern
)
161 mutex_lock(xtpg
->ctrl_handler
.lock
);
162 __xtpg_update_pattern_control(xtpg
, passthrough
, pattern
);
163 mutex_unlock(xtpg
->ctrl_handler
.lock
);
166 /* -----------------------------------------------------------------------------
167 * V4L2 Subdevice Video Operations
170 static int xtpg_s_stream(struct v4l2_subdev
*subdev
, int enable
)
172 struct xtpg_device
*xtpg
= to_tpg(subdev
);
173 unsigned int width
= xtpg
->formats
[0].width
;
174 unsigned int height
= xtpg
->formats
[0].height
;
179 xvip_stop(&xtpg
->xvip
);
181 xvtc_generator_stop(xtpg
->vtc
);
183 xtpg_update_pattern_control(xtpg
, true, true);
184 xtpg
->streaming
= false;
188 xvip_set_frame_size(&xtpg
->xvip
, &xtpg
->formats
[0]);
191 struct xvtc_config config
= {
192 .hblank_start
= width
,
193 .hsync_start
= width
+ 1,
194 .vblank_start
= height
,
195 .vsync_start
= height
+ 1,
200 htotal
= min_t(unsigned int, XVTC_MAX_HSIZE
,
201 v4l2_ctrl_g_ctrl(xtpg
->hblank
) + width
);
202 vtotal
= min_t(unsigned int, XVTC_MAX_VSIZE
,
203 v4l2_ctrl_g_ctrl(xtpg
->vblank
) + height
);
205 config
.hsync_end
= htotal
- 1;
206 config
.hsize
= htotal
;
207 config
.vsync_end
= vtotal
- 1;
208 config
.vsize
= vtotal
;
210 xvtc_generator_start(xtpg
->vtc
, &config
);
214 * Configure the bayer phase and video timing mux based on the
215 * operation mode (passthrough or test pattern generation). The test
216 * pattern can be modified by the control set handler, we thus need to
217 * take the control lock here to avoid races.
219 mutex_lock(xtpg
->ctrl_handler
.lock
);
221 xvip_clr_and_set(&xtpg
->xvip
, XTPG_PATTERN_CONTROL
,
222 XTPG_PATTERN_MASK
, xtpg
->pattern
->cur
.val
);
225 * Switching between passthrough and test pattern generation modes isn't
226 * allowed during streaming, update the control range accordingly.
228 passthrough
= xtpg
->pattern
->cur
.val
== 0;
229 __xtpg_update_pattern_control(xtpg
, passthrough
, !passthrough
);
231 xtpg
->streaming
= true;
233 mutex_unlock(xtpg
->ctrl_handler
.lock
);
236 * For TPG v5.0, the bayer phase needs to be off for the pass through
237 * mode, otherwise the external input would be subsampled.
239 bayer_phase
= passthrough
? XTPG_BAYER_PHASE_OFF
240 : xtpg_get_bayer_phase(xtpg
->formats
[0].code
);
241 xvip_write(&xtpg
->xvip
, XTPG_BAYER_PHASE
, bayer_phase
);
243 if (xtpg
->vtmux_gpio
)
244 gpiod_set_value_cansleep(xtpg
->vtmux_gpio
, !passthrough
);
246 xvip_start(&xtpg
->xvip
);
251 /* -----------------------------------------------------------------------------
252 * V4L2 Subdevice Pad Operations
255 static struct v4l2_mbus_framefmt
*
256 __xtpg_get_pad_format(struct xtpg_device
*xtpg
,
257 struct v4l2_subdev_pad_config
*cfg
,
258 unsigned int pad
, u32 which
)
261 case V4L2_SUBDEV_FORMAT_TRY
:
262 return v4l2_subdev_get_try_format(&xtpg
->xvip
.subdev
, cfg
, pad
);
263 case V4L2_SUBDEV_FORMAT_ACTIVE
:
264 return &xtpg
->formats
[pad
];
270 static int xtpg_get_format(struct v4l2_subdev
*subdev
,
271 struct v4l2_subdev_pad_config
*cfg
,
272 struct v4l2_subdev_format
*fmt
)
274 struct xtpg_device
*xtpg
= to_tpg(subdev
);
276 fmt
->format
= *__xtpg_get_pad_format(xtpg
, cfg
, fmt
->pad
, fmt
->which
);
281 static int xtpg_set_format(struct v4l2_subdev
*subdev
,
282 struct v4l2_subdev_pad_config
*cfg
,
283 struct v4l2_subdev_format
*fmt
)
285 struct xtpg_device
*xtpg
= to_tpg(subdev
);
286 struct v4l2_mbus_framefmt
*__format
;
289 __format
= __xtpg_get_pad_format(xtpg
, cfg
, fmt
->pad
, fmt
->which
);
291 /* In two pads mode the source pad format is always identical to the
294 if (xtpg
->npads
== 2 && fmt
->pad
== 1) {
295 fmt
->format
= *__format
;
299 /* Bayer phase is configurable at runtime */
301 bayer_phase
= xtpg_get_bayer_phase(fmt
->format
.code
);
302 if (bayer_phase
!= XTPG_BAYER_PHASE_OFF
)
303 __format
->code
= fmt
->format
.code
;
306 xvip_set_format_size(__format
, fmt
);
308 fmt
->format
= *__format
;
310 /* Propagate the format to the source pad. */
311 if (xtpg
->npads
== 2) {
312 __format
= __xtpg_get_pad_format(xtpg
, cfg
, 1, fmt
->which
);
313 *__format
= fmt
->format
;
319 /* -----------------------------------------------------------------------------
320 * V4L2 Subdevice Operations
323 static int xtpg_enum_frame_size(struct v4l2_subdev
*subdev
,
324 struct v4l2_subdev_pad_config
*cfg
,
325 struct v4l2_subdev_frame_size_enum
*fse
)
327 struct v4l2_mbus_framefmt
*format
;
329 format
= v4l2_subdev_get_try_format(subdev
, cfg
, fse
->pad
);
331 if (fse
->index
|| fse
->code
!= format
->code
)
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 */
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
;
343 fse
->min_width
= format
->width
;
344 fse
->max_width
= format
->width
;
345 fse
->min_height
= format
->height
;
346 fse
->max_height
= format
->height
;
352 static int xtpg_open(struct v4l2_subdev
*subdev
, struct v4l2_subdev_fh
*fh
)
354 struct xtpg_device
*xtpg
= to_tpg(subdev
);
355 struct v4l2_mbus_framefmt
*format
;
357 format
= v4l2_subdev_get_try_format(subdev
, fh
->pad
, 0);
358 *format
= xtpg
->default_format
;
360 if (xtpg
->npads
== 2) {
361 format
= v4l2_subdev_get_try_format(subdev
, fh
->pad
, 1);
362 *format
= xtpg
->default_format
;
368 static int xtpg_close(struct v4l2_subdev
*subdev
, struct v4l2_subdev_fh
*fh
)
373 static int xtpg_s_ctrl(struct v4l2_ctrl
*ctrl
)
375 struct xtpg_device
*xtpg
= container_of(ctrl
->handler
,
379 case V4L2_CID_TEST_PATTERN
:
380 xvip_clr_and_set(&xtpg
->xvip
, XTPG_PATTERN_CONTROL
,
381 XTPG_PATTERN_MASK
, ctrl
->val
);
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
);
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
);
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
,
395 XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT
);
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
);
401 case V4L2_CID_XILINX_TPG_NOISE
:
402 xvip_clr_or_set(&xtpg
->xvip
, XTPG_PATTERN_CONTROL
,
403 XTPG_PATTERN_CONTROL_NOISE
, ctrl
->val
);
405 case V4L2_CID_XILINX_TPG_MOTION
:
406 xvip_clr_or_set(&xtpg
->xvip
, XTPG_PATTERN_CONTROL
,
407 XTPG_PATTERN_CONTROL_MOTION
, ctrl
->val
);
409 case V4L2_CID_XILINX_TPG_MOTION_SPEED
:
410 xvip_write(&xtpg
->xvip
, XTPG_MOTION_SPEED
, ctrl
->val
);
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
);
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
);
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
);
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
);
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
);
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
);
442 case V4L2_CID_XILINX_TPG_BOX_SIZE
:
443 xvip_write(&xtpg
->xvip
, XTPG_BOX_SIZE
, ctrl
->val
);
445 case V4L2_CID_XILINX_TPG_BOX_COLOR
:
446 xvip_write(&xtpg
->xvip
, XTPG_BOX_COLOR
, ctrl
->val
);
448 case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH
:
449 xvip_write(&xtpg
->xvip
, XTPG_STUCK_PIXEL_THRESH
, ctrl
->val
);
451 case V4L2_CID_XILINX_TPG_NOISE_GAIN
:
452 xvip_write(&xtpg
->xvip
, XTPG_NOISE_GAIN
, ctrl
->val
);
459 static const struct v4l2_ctrl_ops xtpg_ctrl_ops
= {
460 .s_ctrl
= xtpg_s_ctrl
,
463 static struct v4l2_subdev_core_ops xtpg_core_ops
= {
466 static struct v4l2_subdev_video_ops xtpg_video_ops
= {
467 .s_stream
= xtpg_s_stream
,
470 static 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
,
477 static struct v4l2_subdev_ops xtpg_ops
= {
478 .core
= &xtpg_core_ops
,
479 .video
= &xtpg_video_ops
,
480 .pad
= &xtpg_pad_ops
,
483 static const struct v4l2_subdev_internal_ops xtpg_internal_ops
= {
492 static const char *const xtpg_pattern_strings
[] = {
507 "Vertical/Horizontal Ramps",
508 "Black/White Checker Board",
511 static struct v4l2_ctrl_config xtpg_ctrls
[] = {
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
,
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
,
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
,
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
,
548 .ops
= &xtpg_ctrl_ops
,
549 .id
= V4L2_CID_XILINX_TPG_NOISE
,
550 .name
= "Test Pattern: Noise",
551 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
557 .ops
= &xtpg_ctrl_ops
,
558 .id
= V4L2_CID_XILINX_TPG_MOTION
,
559 .name
= "Test Pattern: Motion",
560 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
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
,
574 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
581 .max
= (1 << 12) - 1,
584 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
591 .max
= (1 << 12) - 1,
594 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
601 .max
= (1 << 16) - 1,
604 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
611 .max
= (1 << 16) - 1,
614 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
621 .max
= (1 << 16) - 1,
624 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
631 .max
= (1 << 16) - 1,
634 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
641 .max
= (1 << 12) - 1,
644 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
651 .max
= (1 << 24) - 1,
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
,
660 .max
= (1 << 16) - 1,
663 .flags
= V4L2_CTRL_FLAG_SLIDER
,
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
,
673 .flags
= V4L2_CTRL_FLAG_SLIDER
,
677 /* -----------------------------------------------------------------------------
681 static const struct media_entity_operations xtpg_media_ops
= {
682 .link_validate
= v4l2_subdev_link_validate
,
685 /* -----------------------------------------------------------------------------
689 static int __maybe_unused
xtpg_pm_suspend(struct device
*dev
)
691 struct xtpg_device
*xtpg
= dev_get_drvdata(dev
);
693 xvip_suspend(&xtpg
->xvip
);
698 static int __maybe_unused
xtpg_pm_resume(struct device
*dev
)
700 struct xtpg_device
*xtpg
= dev_get_drvdata(dev
);
702 xvip_resume(&xtpg
->xvip
);
707 /* -----------------------------------------------------------------------------
708 * Platform Device Driver
711 static int xtpg_parse_of(struct xtpg_device
*xtpg
)
713 struct device
*dev
= xtpg
->xvip
.dev
;
714 struct device_node
*node
= xtpg
->xvip
.dev
->of_node
;
715 struct device_node
*ports
;
716 struct device_node
*port
;
717 unsigned int nports
= 0;
718 bool has_endpoint
= false;
720 ports
= of_get_child_by_name(node
, "ports");
724 for_each_child_of_node(ports
, port
) {
725 const struct xvip_video_format
*format
;
726 struct device_node
*endpoint
;
728 if (!port
->name
|| of_node_cmp(port
->name
, "port"))
731 format
= xvip_of_get_format(port
);
732 if (IS_ERR(format
)) {
733 dev_err(dev
, "invalid format in DT");
735 return PTR_ERR(format
);
738 /* Get and check the format description */
739 if (!xtpg
->vip_format
) {
740 xtpg
->vip_format
= format
;
741 } else if (xtpg
->vip_format
!= format
) {
742 dev_err(dev
, "in/out format mismatch in DT");
748 endpoint
= of_get_next_child(port
, NULL
);
751 of_node_put(endpoint
);
754 /* Count the number of ports. */
758 if (nports
!= 1 && nports
!= 2) {
759 dev_err(dev
, "invalid number of ports %u\n", nports
);
763 xtpg
->npads
= nports
;
764 if (nports
== 2 && has_endpoint
)
765 xtpg
->has_input
= true;
770 static int xtpg_probe(struct platform_device
*pdev
)
772 struct v4l2_subdev
*subdev
;
773 struct xtpg_device
*xtpg
;
777 xtpg
= devm_kzalloc(&pdev
->dev
, sizeof(*xtpg
), GFP_KERNEL
);
781 xtpg
->xvip
.dev
= &pdev
->dev
;
783 ret
= xtpg_parse_of(xtpg
);
787 ret
= xvip_init_resources(&xtpg
->xvip
);
791 xtpg
->vtmux_gpio
= devm_gpiod_get_optional(&pdev
->dev
, "timing",
793 if (IS_ERR(xtpg
->vtmux_gpio
)) {
794 ret
= PTR_ERR(xtpg
->vtmux_gpio
);
798 xtpg
->vtc
= xvtc_of_get(pdev
->dev
.of_node
);
799 if (IS_ERR(xtpg
->vtc
)) {
800 ret
= PTR_ERR(xtpg
->vtc
);
804 /* Reset and initialize the core */
805 xvip_reset(&xtpg
->xvip
);
807 /* Initialize V4L2 subdevice and media entity. Pad numbers depend on the
810 if (xtpg
->npads
== 2) {
811 xtpg
->pads
[0].flags
= MEDIA_PAD_FL_SINK
;
812 xtpg
->pads
[1].flags
= MEDIA_PAD_FL_SOURCE
;
814 xtpg
->pads
[0].flags
= MEDIA_PAD_FL_SOURCE
;
817 /* Initialize the default format */
818 xtpg
->default_format
.code
= xtpg
->vip_format
->code
;
819 xtpg
->default_format
.field
= V4L2_FIELD_NONE
;
820 xtpg
->default_format
.colorspace
= V4L2_COLORSPACE_SRGB
;
821 xvip_get_frame_size(&xtpg
->xvip
, &xtpg
->default_format
);
823 bayer_phase
= xtpg_get_bayer_phase(xtpg
->vip_format
->code
);
824 if (bayer_phase
!= XTPG_BAYER_PHASE_OFF
)
827 xtpg
->formats
[0] = xtpg
->default_format
;
828 if (xtpg
->npads
== 2)
829 xtpg
->formats
[1] = xtpg
->default_format
;
831 /* Initialize V4L2 subdevice and media entity */
832 subdev
= &xtpg
->xvip
.subdev
;
833 v4l2_subdev_init(subdev
, &xtpg_ops
);
834 subdev
->dev
= &pdev
->dev
;
835 subdev
->internal_ops
= &xtpg_internal_ops
;
836 strlcpy(subdev
->name
, dev_name(&pdev
->dev
), sizeof(subdev
->name
));
837 v4l2_set_subdevdata(subdev
, xtpg
);
838 subdev
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
839 subdev
->entity
.ops
= &xtpg_media_ops
;
841 ret
= media_entity_pads_init(&subdev
->entity
, xtpg
->npads
, xtpg
->pads
);
845 v4l2_ctrl_handler_init(&xtpg
->ctrl_handler
, 3 + ARRAY_SIZE(xtpg_ctrls
));
847 xtpg
->vblank
= v4l2_ctrl_new_std(&xtpg
->ctrl_handler
, &xtpg_ctrl_ops
,
848 V4L2_CID_VBLANK
, XTPG_MIN_VBLANK
,
849 XTPG_MAX_VBLANK
, 1, 100);
850 xtpg
->hblank
= v4l2_ctrl_new_std(&xtpg
->ctrl_handler
, &xtpg_ctrl_ops
,
851 V4L2_CID_HBLANK
, XTPG_MIN_HBLANK
,
852 XTPG_MAX_HBLANK
, 1, 100);
853 xtpg
->pattern
= v4l2_ctrl_new_std_menu_items(&xtpg
->ctrl_handler
,
854 &xtpg_ctrl_ops
, V4L2_CID_TEST_PATTERN
,
855 ARRAY_SIZE(xtpg_pattern_strings
) - 1,
856 1, 9, xtpg_pattern_strings
);
858 for (i
= 0; i
< ARRAY_SIZE(xtpg_ctrls
); i
++)
859 v4l2_ctrl_new_custom(&xtpg
->ctrl_handler
, &xtpg_ctrls
[i
], NULL
);
861 if (xtpg
->ctrl_handler
.error
) {
862 dev_err(&pdev
->dev
, "failed to add controls\n");
863 ret
= xtpg
->ctrl_handler
.error
;
866 subdev
->ctrl_handler
= &xtpg
->ctrl_handler
;
868 xtpg_update_pattern_control(xtpg
, true, true);
870 ret
= v4l2_ctrl_handler_setup(&xtpg
->ctrl_handler
);
872 dev_err(&pdev
->dev
, "failed to set controls\n");
876 platform_set_drvdata(pdev
, xtpg
);
878 xvip_print_version(&xtpg
->xvip
);
880 ret
= v4l2_async_register_subdev(subdev
);
882 dev_err(&pdev
->dev
, "failed to register subdev\n");
889 v4l2_ctrl_handler_free(&xtpg
->ctrl_handler
);
890 media_entity_cleanup(&subdev
->entity
);
893 xvip_cleanup_resources(&xtpg
->xvip
);
897 static int xtpg_remove(struct platform_device
*pdev
)
899 struct xtpg_device
*xtpg
= platform_get_drvdata(pdev
);
900 struct v4l2_subdev
*subdev
= &xtpg
->xvip
.subdev
;
902 v4l2_async_unregister_subdev(subdev
);
903 v4l2_ctrl_handler_free(&xtpg
->ctrl_handler
);
904 media_entity_cleanup(&subdev
->entity
);
906 xvip_cleanup_resources(&xtpg
->xvip
);
911 static SIMPLE_DEV_PM_OPS(xtpg_pm_ops
, xtpg_pm_suspend
, xtpg_pm_resume
);
913 static const struct of_device_id xtpg_of_id_table
[] = {
914 { .compatible
= "xlnx,v-tpg-5.0" },
917 MODULE_DEVICE_TABLE(of
, xtpg_of_id_table
);
919 static struct platform_driver xtpg_driver
= {
921 .name
= "xilinx-tpg",
923 .of_match_table
= xtpg_of_id_table
,
926 .remove
= xtpg_remove
,
929 module_platform_driver(xtpg_driver
);
931 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
932 MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
933 MODULE_LICENSE("GPL v2");