root/drivers/media/platform/xilinx/xilinx-tpg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_tpg
  2. xtpg_get_bayer_phase
  3. __xtpg_update_pattern_control
  4. xtpg_update_pattern_control
  5. xtpg_s_stream
  6. __xtpg_get_pad_format
  7. xtpg_get_format
  8. xtpg_set_format
  9. xtpg_enum_frame_size
  10. xtpg_open
  11. xtpg_close
  12. xtpg_s_ctrl
  13. xtpg_pm_suspend
  14. xtpg_pm_resume
  15. xtpg_parse_of
  16. xtpg_probe
  17. xtpg_remove

   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  */
  88 struct 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 
 110 static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
 111 {
 112         return container_of(subdev, struct xtpg_device, xvip.subdev);
 113 }
 114 
 115 static 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 
 131 static 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 
 155 static 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 
 167 static 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 
 252 static 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 
 267 static 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 
 278 static 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 
 320 static 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 
 349 static 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 
 365 static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
 366 {
 367         return 0;
 368 }
 369 
 370 static 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 
 456 static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
 457         .s_ctrl = xtpg_s_ctrl,
 458 };
 459 
 460 static const struct v4l2_subdev_core_ops xtpg_core_ops = {
 461 };
 462 
 463 static const struct v4l2_subdev_video_ops xtpg_video_ops = {
 464         .s_stream = xtpg_s_stream,
 465 };
 466 
 467 static 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 
 474 static const struct v4l2_subdev_ops xtpg_ops = {
 475         .core   = &xtpg_core_ops,
 476         .video  = &xtpg_video_ops,
 477         .pad    = &xtpg_pad_ops,
 478 };
 479 
 480 static 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 
 489 static 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 
 508 static 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 
 678 static const struct media_entity_operations xtpg_media_ops = {
 679         .link_validate = v4l2_subdev_link_validate,
 680 };
 681 
 682 /* -----------------------------------------------------------------------------
 683  * Power Management
 684  */
 685 
 686 static 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 
 695 static 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 
 708 static 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 
 767 static 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 
 885 error:
 886         v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
 887         media_entity_cleanup(&subdev->entity);
 888         xvtc_put(xtpg->vtc);
 889 error_resource:
 890         xvip_cleanup_resources(&xtpg->xvip);
 891         return ret;
 892 }
 893 
 894 static 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 
 908 static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
 909 
 910 static const struct of_device_id xtpg_of_id_table[] = {
 911         { .compatible = "xlnx,v-tpg-5.0" },
 912         { }
 913 };
 914 MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
 915 
 916 static 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 
 926 module_platform_driver(xtpg_driver);
 927 
 928 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
 929 MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
 930 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */