linux/drivers/media/platform/xilinx/xilinx-tpg.c
<<
>>
Prefs
   1/*
   2 * Xilinx Test Pattern Generator
   3 *
   4 * Copyright (C) 2013-2015 Ideas on Board
   5 * Copyright (C) 2013-2015 Xilinx, Inc.
   6 *
   7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
   8 *           Laurent Pinchart <laurent.pinchart@ideasonboard.com>
   9 *
  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.
  13 */
  14
  15#include <linux/device.h>
  16#include <linux/gpio/consumer.h>
  17#include <linux/module.h>
  18#include <linux/of.h>
  19#include <linux/platform_device.h>
  20#include <linux/xilinx-v4l2-controls.h>
  21
  22#include <media/v4l2-async.h>
  23#include <media/v4l2-ctrls.h>
  24#include <media/v4l2-subdev.h>
  25
  26#include "xilinx-vip.h"
  27#include "xilinx-vtc.h"
  28
  29#define XTPG_CTRL_STATUS_SLAVE_ERROR            (1 << 16)
  30#define XTPG_CTRL_IRQ_SLAVE_ERROR               (1 << 16)
  31
  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
  63
  64/*
  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.
  67 */
  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)
  72
  73/**
  74 * struct xtpg_device - Xilinx Test Pattern Generator device structure
  75 * @xvip: Xilinx Video IP device
  76 * @pads: media pads
  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
  90 */
  91struct xtpg_device {
  92        struct xvip_device xvip;
  93
  94        struct media_pad pads[2];
  95        unsigned int npads;
  96        bool has_input;
  97
  98        struct v4l2_mbus_framefmt formats[2];
  99        struct v4l2_mbus_framefmt default_format;
 100        const struct xvip_video_format *vip_format;
 101        bool bayer;
 102
 103        struct v4l2_ctrl_handler ctrl_handler;
 104        struct v4l2_ctrl *hblank;
 105        struct v4l2_ctrl *vblank;
 106        struct v4l2_ctrl *pattern;
 107        bool streaming;
 108
 109        struct xvtc_device *vtc;
 110        struct gpio_desc *vtmux_gpio;
 111};
 112
 113static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
 114{
 115        return container_of(subdev, struct xtpg_device, xvip.subdev);
 116}
 117
 118static u32 xtpg_get_bayer_phase(unsigned int code)
 119{
 120        switch (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;
 129        default:
 130                return XTPG_BAYER_PHASE_OFF;
 131        }
 132}
 133
 134static void __xtpg_update_pattern_control(struct xtpg_device *xtpg,
 135                                          bool passthrough, bool pattern)
 136{
 137        u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1;
 138
 139        /*
 140         * If the TPG has no sink pad or no input connected to its sink pad
 141         * passthrough mode can't be enabled.
 142         */
 143        if (xtpg->npads == 1 || !xtpg->has_input)
 144                passthrough = false;
 145
 146        /* If passthrough mode is allowed unmask bit 0. */
 147        if (passthrough)
 148                pattern_mask &= ~1;
 149
 150        /* If test pattern mode is allowed unmask all other bits. */
 151        if (pattern)
 152                pattern_mask &= 1;
 153
 154        __v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum,
 155                                 pattern_mask, pattern ? 9 : 0);
 156}
 157
 158static void xtpg_update_pattern_control(struct xtpg_device *xtpg,
 159                                        bool passthrough, bool pattern)
 160{
 161        mutex_lock(xtpg->ctrl_handler.lock);
 162        __xtpg_update_pattern_control(xtpg, passthrough, pattern);
 163        mutex_unlock(xtpg->ctrl_handler.lock);
 164}
 165
 166/* -----------------------------------------------------------------------------
 167 * V4L2 Subdevice Video Operations
 168 */
 169
 170static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
 171{
 172        struct xtpg_device *xtpg = to_tpg(subdev);
 173        unsigned int width = xtpg->formats[0].width;
 174        unsigned int height = xtpg->formats[0].height;
 175        bool passthrough;
 176        u32 bayer_phase;
 177
 178        if (!enable) {
 179                xvip_stop(&xtpg->xvip);
 180                if (xtpg->vtc)
 181                        xvtc_generator_stop(xtpg->vtc);
 182
 183                xtpg_update_pattern_control(xtpg, true, true);
 184                xtpg->streaming = false;
 185                return 0;
 186        }
 187
 188        xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]);
 189
 190        if (xtpg->vtc) {
 191                struct xvtc_config config = {
 192                        .hblank_start = width,
 193                        .hsync_start = width + 1,
 194                        .vblank_start = height,
 195                        .vsync_start = height + 1,
 196                };
 197                unsigned int htotal;
 198                unsigned int vtotal;
 199
 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);
 204
 205                config.hsync_end = htotal - 1;
 206                config.hsize = htotal;
 207                config.vsync_end = vtotal - 1;
 208                config.vsize = vtotal;
 209
 210                xvtc_generator_start(xtpg->vtc, &config);
 211        }
 212
 213        /*
 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.
 218         */
 219        mutex_lock(xtpg->ctrl_handler.lock);
 220
 221        xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
 222                         XTPG_PATTERN_MASK, xtpg->pattern->cur.val);
 223
 224        /*
 225         * Switching between passthrough and test pattern generation modes isn't
 226         * allowed during streaming, update the control range accordingly.
 227         */
 228        passthrough = xtpg->pattern->cur.val == 0;
 229        __xtpg_update_pattern_control(xtpg, passthrough, !passthrough);
 230
 231        xtpg->streaming = true;
 232
 233        mutex_unlock(xtpg->ctrl_handler.lock);
 234
 235        /*
 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.
 238         */
 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);
 242
 243        if (xtpg->vtmux_gpio)
 244                gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough);
 245
 246        xvip_start(&xtpg->xvip);
 247
 248        return 0;
 249}
 250
 251/* -----------------------------------------------------------------------------
 252 * V4L2 Subdevice Pad Operations
 253 */
 254
 255static 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)
 259{
 260        switch (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];
 265        default:
 266                return NULL;
 267        }
 268}
 269
 270static int xtpg_get_format(struct v4l2_subdev *subdev,
 271                           struct v4l2_subdev_pad_config *cfg,
 272                           struct v4l2_subdev_format *fmt)
 273{
 274        struct xtpg_device *xtpg = to_tpg(subdev);
 275
 276        fmt->format = *__xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which);
 277
 278        return 0;
 279}
 280
 281static int xtpg_set_format(struct v4l2_subdev *subdev,
 282                           struct v4l2_subdev_pad_config *cfg,
 283                           struct v4l2_subdev_format *fmt)
 284{
 285        struct xtpg_device *xtpg = to_tpg(subdev);
 286        struct v4l2_mbus_framefmt *__format;
 287        u32 bayer_phase;
 288
 289        __format = __xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which);
 290
 291        /* In two pads mode the source pad format is always identical to the
 292         * sink pad format.
 293         */
 294        if (xtpg->npads == 2 && fmt->pad == 1) {
 295                fmt->format = *__format;
 296                return 0;
 297        }
 298
 299        /* Bayer phase is configurable at runtime */
 300        if (xtpg->bayer) {
 301                bayer_phase = xtpg_get_bayer_phase(fmt->format.code);
 302                if (bayer_phase != XTPG_BAYER_PHASE_OFF)
 303                        __format->code = fmt->format.code;
 304        }
 305
 306        xvip_set_format_size(__format, fmt);
 307
 308        fmt->format = *__format;
 309
 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;
 314        }
 315
 316        return 0;
 317}
 318
 319/* -----------------------------------------------------------------------------
 320 * V4L2 Subdevice Operations
 321 */
 322
 323static int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
 324                                struct v4l2_subdev_pad_config *cfg,
 325                                struct v4l2_subdev_frame_size_enum *fse)
 326{
 327        struct v4l2_mbus_framefmt *format;
 328
 329        format = v4l2_subdev_get_try_format(subdev, cfg, 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
 352static 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_get_try_format(subdev, fh->pad, 0);
 358        *format = xtpg->default_format;
 359
 360        if (xtpg->npads == 2) {
 361                format = v4l2_subdev_get_try_format(subdev, fh->pad, 1);
 362                *format = xtpg->default_format;
 363        }
 364
 365        return 0;
 366}
 367
 368static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
 369{
 370        return 0;
 371}
 372
 373static 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
 459static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
 460        .s_ctrl = xtpg_s_ctrl,
 461};
 462
 463static const struct v4l2_subdev_core_ops xtpg_core_ops = {
 464};
 465
 466static const struct v4l2_subdev_video_ops xtpg_video_ops = {
 467        .s_stream = xtpg_s_stream,
 468};
 469
 470static 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
 477static const struct v4l2_subdev_ops xtpg_ops = {
 478        .core   = &xtpg_core_ops,
 479        .video  = &xtpg_video_ops,
 480        .pad    = &xtpg_pad_ops,
 481};
 482
 483static 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
 492static 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
 511static 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
 681static const struct media_entity_operations xtpg_media_ops = {
 682        .link_validate = v4l2_subdev_link_validate,
 683};
 684
 685/* -----------------------------------------------------------------------------
 686 * Power Management
 687 */
 688
 689static 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
 698static 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
 711static 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        struct device_node *ports;
 716        struct device_node *port;
 717        unsigned int nports = 0;
 718        bool has_endpoint = false;
 719
 720        ports = of_get_child_by_name(node, "ports");
 721        if (ports == NULL)
 722                ports = node;
 723
 724        for_each_child_of_node(ports, port) {
 725                const struct xvip_video_format *format;
 726                struct device_node *endpoint;
 727
 728                if (!port->name || of_node_cmp(port->name, "port"))
 729                        continue;
 730
 731                format = xvip_of_get_format(port);
 732                if (IS_ERR(format)) {
 733                        dev_err(dev, "invalid format in DT");
 734                        of_node_put(port);
 735                        return PTR_ERR(format);
 736                }
 737
 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");
 743                        of_node_put(port);
 744                        return -EINVAL;
 745                }
 746
 747                if (nports == 0) {
 748                        endpoint = of_get_next_child(port, NULL);
 749                        if (endpoint)
 750                                has_endpoint = true;
 751                        of_node_put(endpoint);
 752                }
 753
 754                /* Count the number of ports. */
 755                nports++;
 756        }
 757
 758        if (nports != 1 && nports != 2) {
 759                dev_err(dev, "invalid number of ports %u\n", nports);
 760                return -EINVAL;
 761        }
 762
 763        xtpg->npads = nports;
 764        if (nports == 2 && has_endpoint)
 765                xtpg->has_input = true;
 766
 767        return 0;
 768}
 769
 770static int xtpg_probe(struct platform_device *pdev)
 771{
 772        struct v4l2_subdev *subdev;
 773        struct xtpg_device *xtpg;
 774        u32 i, bayer_phase;
 775        int ret;
 776
 777        xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL);
 778        if (!xtpg)
 779                return -ENOMEM;
 780
 781        xtpg->xvip.dev = &pdev->dev;
 782
 783        ret = xtpg_parse_of(xtpg);
 784        if (ret < 0)
 785                return ret;
 786
 787        ret = xvip_init_resources(&xtpg->xvip);
 788        if (ret < 0)
 789                return ret;
 790
 791        xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing",
 792                                                   GPIOD_OUT_HIGH);
 793        if (IS_ERR(xtpg->vtmux_gpio)) {
 794                ret = PTR_ERR(xtpg->vtmux_gpio);
 795                goto error_resource;
 796        }
 797
 798        xtpg->vtc = xvtc_of_get(pdev->dev.of_node);
 799        if (IS_ERR(xtpg->vtc)) {
 800                ret = PTR_ERR(xtpg->vtc);
 801                goto error_resource;
 802        }
 803
 804        /* Reset and initialize the core */
 805        xvip_reset(&xtpg->xvip);
 806
 807        /* Initialize V4L2 subdevice and media entity. Pad numbers depend on the
 808         * number of pads.
 809         */
 810        if (xtpg->npads == 2) {
 811                xtpg->pads[0].flags = MEDIA_PAD_FL_SINK;
 812                xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE;
 813        } else {
 814                xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE;
 815        }
 816
 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);
 822
 823        bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code);
 824        if (bayer_phase != XTPG_BAYER_PHASE_OFF)
 825                xtpg->bayer = true;
 826
 827        xtpg->formats[0] = xtpg->default_format;
 828        if (xtpg->npads == 2)
 829                xtpg->formats[1] = xtpg->default_format;
 830
 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;
 840
 841        ret = media_entity_pads_init(&subdev->entity, xtpg->npads, xtpg->pads);
 842        if (ret < 0)
 843                goto error;
 844
 845        v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls));
 846
 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);
 857
 858        for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++)
 859                v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL);
 860
 861        if (xtpg->ctrl_handler.error) {
 862                dev_err(&pdev->dev, "failed to add controls\n");
 863                ret = xtpg->ctrl_handler.error;
 864                goto error;
 865        }
 866        subdev->ctrl_handler = &xtpg->ctrl_handler;
 867
 868        xtpg_update_pattern_control(xtpg, true, true);
 869
 870        ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler);
 871        if (ret < 0) {
 872                dev_err(&pdev->dev, "failed to set controls\n");
 873                goto error;
 874        }
 875
 876        platform_set_drvdata(pdev, xtpg);
 877
 878        xvip_print_version(&xtpg->xvip);
 879
 880        ret = v4l2_async_register_subdev(subdev);
 881        if (ret < 0) {
 882                dev_err(&pdev->dev, "failed to register subdev\n");
 883                goto error;
 884        }
 885
 886        return 0;
 887
 888error:
 889        v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
 890        media_entity_cleanup(&subdev->entity);
 891        xvtc_put(xtpg->vtc);
 892error_resource:
 893        xvip_cleanup_resources(&xtpg->xvip);
 894        return ret;
 895}
 896
 897static int xtpg_remove(struct platform_device *pdev)
 898{
 899        struct xtpg_device *xtpg = platform_get_drvdata(pdev);
 900        struct v4l2_subdev *subdev = &xtpg->xvip.subdev;
 901
 902        v4l2_async_unregister_subdev(subdev);
 903        v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
 904        media_entity_cleanup(&subdev->entity);
 905
 906        xvip_cleanup_resources(&xtpg->xvip);
 907
 908        return 0;
 909}
 910
 911static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
 912
 913static const struct of_device_id xtpg_of_id_table[] = {
 914        { .compatible = "xlnx,v-tpg-5.0" },
 915        { }
 916};
 917MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
 918
 919static struct platform_driver xtpg_driver = {
 920        .driver = {
 921                .name           = "xilinx-tpg",
 922                .pm             = &xtpg_pm_ops,
 923                .of_match_table = xtpg_of_id_table,
 924        },
 925        .probe                  = xtpg_probe,
 926        .remove                 = xtpg_remove,
 927};
 928
 929module_platform_driver(xtpg_driver);
 930
 931MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
 932MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
 933MODULE_LICENSE("GPL v2");
 934