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