linux/drivers/media/v4l2-core/v4l2-subdev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * V4L2 sub-device
   4 *
   5 * Copyright (C) 2010 Nokia Corporation
   6 *
   7 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
   8 *          Sakari Ailus <sakari.ailus@iki.fi>
   9 */
  10
  11#include <linux/ioctl.h>
  12#include <linux/mm.h>
  13#include <linux/module.h>
  14#include <linux/slab.h>
  15#include <linux/types.h>
  16#include <linux/videodev2.h>
  17#include <linux/export.h>
  18#include <linux/version.h>
  19
  20#include <media/v4l2-ctrls.h>
  21#include <media/v4l2-device.h>
  22#include <media/v4l2-ioctl.h>
  23#include <media/v4l2-fh.h>
  24#include <media/v4l2-event.h>
  25
  26#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
  27static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
  28{
  29        if (sd->entity.num_pads) {
  30                fh->pad = v4l2_subdev_alloc_pad_config(sd);
  31                if (fh->pad == NULL)
  32                        return -ENOMEM;
  33        }
  34
  35        return 0;
  36}
  37
  38static void subdev_fh_free(struct v4l2_subdev_fh *fh)
  39{
  40        v4l2_subdev_free_pad_config(fh->pad);
  41        fh->pad = NULL;
  42}
  43
  44static int subdev_open(struct file *file)
  45{
  46        struct video_device *vdev = video_devdata(file);
  47        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
  48        struct v4l2_subdev_fh *subdev_fh;
  49        int ret;
  50
  51        subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
  52        if (subdev_fh == NULL)
  53                return -ENOMEM;
  54
  55        ret = subdev_fh_init(subdev_fh, sd);
  56        if (ret) {
  57                kfree(subdev_fh);
  58                return ret;
  59        }
  60
  61        v4l2_fh_init(&subdev_fh->vfh, vdev);
  62        v4l2_fh_add(&subdev_fh->vfh);
  63        file->private_data = &subdev_fh->vfh;
  64#if defined(CONFIG_MEDIA_CONTROLLER)
  65        if (sd->v4l2_dev->mdev && sd->entity.graph_obj.mdev->dev) {
  66                struct module *owner;
  67
  68                owner = sd->entity.graph_obj.mdev->dev->driver->owner;
  69                if (!try_module_get(owner)) {
  70                        ret = -EBUSY;
  71                        goto err;
  72                }
  73                subdev_fh->owner = owner;
  74        }
  75#endif
  76
  77        if (sd->internal_ops && sd->internal_ops->open) {
  78                ret = sd->internal_ops->open(sd, subdev_fh);
  79                if (ret < 0)
  80                        goto err;
  81        }
  82
  83        return 0;
  84
  85err:
  86        module_put(subdev_fh->owner);
  87        v4l2_fh_del(&subdev_fh->vfh);
  88        v4l2_fh_exit(&subdev_fh->vfh);
  89        subdev_fh_free(subdev_fh);
  90        kfree(subdev_fh);
  91
  92        return ret;
  93}
  94
  95static int subdev_close(struct file *file)
  96{
  97        struct video_device *vdev = video_devdata(file);
  98        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
  99        struct v4l2_fh *vfh = file->private_data;
 100        struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
 101
 102        if (sd->internal_ops && sd->internal_ops->close)
 103                sd->internal_ops->close(sd, subdev_fh);
 104        module_put(subdev_fh->owner);
 105        v4l2_fh_del(vfh);
 106        v4l2_fh_exit(vfh);
 107        subdev_fh_free(subdev_fh);
 108        kfree(subdev_fh);
 109        file->private_data = NULL;
 110
 111        return 0;
 112}
 113#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 114static int subdev_open(struct file *file)
 115{
 116        return -ENODEV;
 117}
 118
 119static int subdev_close(struct file *file)
 120{
 121        return -ENODEV;
 122}
 123#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 124
 125static inline int check_which(u32 which)
 126{
 127        if (which != V4L2_SUBDEV_FORMAT_TRY &&
 128            which != V4L2_SUBDEV_FORMAT_ACTIVE)
 129                return -EINVAL;
 130
 131        return 0;
 132}
 133
 134static inline int check_pad(struct v4l2_subdev *sd, u32 pad)
 135{
 136#if defined(CONFIG_MEDIA_CONTROLLER)
 137        if (sd->entity.num_pads) {
 138                if (pad >= sd->entity.num_pads)
 139                        return -EINVAL;
 140                return 0;
 141        }
 142#endif
 143        /* allow pad 0 on subdevices not registered as media entities */
 144        if (pad > 0)
 145                return -EINVAL;
 146        return 0;
 147}
 148
 149static int check_cfg(u32 which, struct v4l2_subdev_pad_config *cfg)
 150{
 151        if (which == V4L2_SUBDEV_FORMAT_TRY && !cfg)
 152                return -EINVAL;
 153
 154        return 0;
 155}
 156
 157static inline int check_format(struct v4l2_subdev *sd,
 158                               struct v4l2_subdev_pad_config *cfg,
 159                               struct v4l2_subdev_format *format)
 160{
 161        if (!format)
 162                return -EINVAL;
 163
 164        return check_which(format->which) ? : check_pad(sd, format->pad) ? :
 165               check_cfg(format->which, cfg);
 166}
 167
 168static int call_get_fmt(struct v4l2_subdev *sd,
 169                        struct v4l2_subdev_pad_config *cfg,
 170                        struct v4l2_subdev_format *format)
 171{
 172        return check_format(sd, cfg, format) ? :
 173               sd->ops->pad->get_fmt(sd, cfg, format);
 174}
 175
 176static int call_set_fmt(struct v4l2_subdev *sd,
 177                        struct v4l2_subdev_pad_config *cfg,
 178                        struct v4l2_subdev_format *format)
 179{
 180        return check_format(sd, cfg, format) ? :
 181               sd->ops->pad->set_fmt(sd, cfg, format);
 182}
 183
 184static int call_enum_mbus_code(struct v4l2_subdev *sd,
 185                               struct v4l2_subdev_pad_config *cfg,
 186                               struct v4l2_subdev_mbus_code_enum *code)
 187{
 188        if (!code)
 189                return -EINVAL;
 190
 191        return check_which(code->which) ? : check_pad(sd, code->pad) ? :
 192               check_cfg(code->which, cfg) ? :
 193               sd->ops->pad->enum_mbus_code(sd, cfg, code);
 194}
 195
 196static int call_enum_frame_size(struct v4l2_subdev *sd,
 197                                struct v4l2_subdev_pad_config *cfg,
 198                                struct v4l2_subdev_frame_size_enum *fse)
 199{
 200        if (!fse)
 201                return -EINVAL;
 202
 203        return check_which(fse->which) ? : check_pad(sd, fse->pad) ? :
 204               check_cfg(fse->which, cfg) ? :
 205               sd->ops->pad->enum_frame_size(sd, cfg, fse);
 206}
 207
 208static inline int check_frame_interval(struct v4l2_subdev *sd,
 209                                       struct v4l2_subdev_frame_interval *fi)
 210{
 211        if (!fi)
 212                return -EINVAL;
 213
 214        return check_pad(sd, fi->pad);
 215}
 216
 217static int call_g_frame_interval(struct v4l2_subdev *sd,
 218                                 struct v4l2_subdev_frame_interval *fi)
 219{
 220        return check_frame_interval(sd, fi) ? :
 221               sd->ops->video->g_frame_interval(sd, fi);
 222}
 223
 224static int call_s_frame_interval(struct v4l2_subdev *sd,
 225                                 struct v4l2_subdev_frame_interval *fi)
 226{
 227        return check_frame_interval(sd, fi) ? :
 228               sd->ops->video->s_frame_interval(sd, fi);
 229}
 230
 231static int call_enum_frame_interval(struct v4l2_subdev *sd,
 232                                    struct v4l2_subdev_pad_config *cfg,
 233                                    struct v4l2_subdev_frame_interval_enum *fie)
 234{
 235        if (!fie)
 236                return -EINVAL;
 237
 238        return check_which(fie->which) ? : check_pad(sd, fie->pad) ? :
 239               check_cfg(fie->which, cfg) ? :
 240               sd->ops->pad->enum_frame_interval(sd, cfg, fie);
 241}
 242
 243static inline int check_selection(struct v4l2_subdev *sd,
 244                                  struct v4l2_subdev_pad_config *cfg,
 245                                  struct v4l2_subdev_selection *sel)
 246{
 247        if (!sel)
 248                return -EINVAL;
 249
 250        return check_which(sel->which) ? : check_pad(sd, sel->pad) ? :
 251               check_cfg(sel->which, cfg);
 252}
 253
 254static int call_get_selection(struct v4l2_subdev *sd,
 255                              struct v4l2_subdev_pad_config *cfg,
 256                              struct v4l2_subdev_selection *sel)
 257{
 258        return check_selection(sd, cfg, sel) ? :
 259               sd->ops->pad->get_selection(sd, cfg, sel);
 260}
 261
 262static int call_set_selection(struct v4l2_subdev *sd,
 263                              struct v4l2_subdev_pad_config *cfg,
 264                              struct v4l2_subdev_selection *sel)
 265{
 266        return check_selection(sd, cfg, sel) ? :
 267               sd->ops->pad->set_selection(sd, cfg, sel);
 268}
 269
 270static inline int check_edid(struct v4l2_subdev *sd,
 271                             struct v4l2_subdev_edid *edid)
 272{
 273        if (!edid)
 274                return -EINVAL;
 275
 276        if (edid->blocks && edid->edid == NULL)
 277                return -EINVAL;
 278
 279        return check_pad(sd, edid->pad);
 280}
 281
 282static int call_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
 283{
 284        return check_edid(sd, edid) ? : sd->ops->pad->get_edid(sd, edid);
 285}
 286
 287static int call_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
 288{
 289        return check_edid(sd, edid) ? : sd->ops->pad->set_edid(sd, edid);
 290}
 291
 292static int call_dv_timings_cap(struct v4l2_subdev *sd,
 293                               struct v4l2_dv_timings_cap *cap)
 294{
 295        if (!cap)
 296                return -EINVAL;
 297
 298        return check_pad(sd, cap->pad) ? :
 299               sd->ops->pad->dv_timings_cap(sd, cap);
 300}
 301
 302static int call_enum_dv_timings(struct v4l2_subdev *sd,
 303                                struct v4l2_enum_dv_timings *dvt)
 304{
 305        if (!dvt)
 306                return -EINVAL;
 307
 308        return check_pad(sd, dvt->pad) ? :
 309               sd->ops->pad->enum_dv_timings(sd, dvt);
 310}
 311
 312static int call_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
 313                                struct v4l2_mbus_config *config)
 314{
 315        return check_pad(sd, pad) ? :
 316               sd->ops->pad->get_mbus_config(sd, pad, config);
 317}
 318
 319static int call_set_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
 320                                struct v4l2_mbus_config *config)
 321{
 322        return check_pad(sd, pad) ? :
 323               sd->ops->pad->get_mbus_config(sd, pad, config);
 324}
 325
 326static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers = {
 327        .get_fmt                = call_get_fmt,
 328        .set_fmt                = call_set_fmt,
 329        .enum_mbus_code         = call_enum_mbus_code,
 330        .enum_frame_size        = call_enum_frame_size,
 331        .enum_frame_interval    = call_enum_frame_interval,
 332        .get_selection          = call_get_selection,
 333        .set_selection          = call_set_selection,
 334        .get_edid               = call_get_edid,
 335        .set_edid               = call_set_edid,
 336        .dv_timings_cap         = call_dv_timings_cap,
 337        .enum_dv_timings        = call_enum_dv_timings,
 338        .get_mbus_config        = call_get_mbus_config,
 339        .set_mbus_config        = call_set_mbus_config,
 340};
 341
 342static const struct v4l2_subdev_video_ops v4l2_subdev_call_video_wrappers = {
 343        .g_frame_interval       = call_g_frame_interval,
 344        .s_frame_interval       = call_s_frame_interval,
 345};
 346
 347const struct v4l2_subdev_ops v4l2_subdev_call_wrappers = {
 348        .pad    = &v4l2_subdev_call_pad_wrappers,
 349        .video  = &v4l2_subdev_call_video_wrappers,
 350};
 351EXPORT_SYMBOL(v4l2_subdev_call_wrappers);
 352
 353#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 354static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 355{
 356        struct video_device *vdev = video_devdata(file);
 357        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
 358        struct v4l2_fh *vfh = file->private_data;
 359        struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
 360        bool ro_subdev = test_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags);
 361        int rval;
 362
 363        switch (cmd) {
 364        case VIDIOC_SUBDEV_QUERYCAP: {
 365                struct v4l2_subdev_capability *cap = arg;
 366
 367                memset(cap->reserved, 0, sizeof(cap->reserved));
 368                cap->version = LINUX_VERSION_CODE;
 369                cap->capabilities = ro_subdev ? V4L2_SUBDEV_CAP_RO_SUBDEV : 0;
 370
 371                return 0;
 372        }
 373
 374        case VIDIOC_QUERYCTRL:
 375                /*
 376                 * TODO: this really should be folded into v4l2_queryctrl (this
 377                 * currently returns -EINVAL for NULL control handlers).
 378                 * However, v4l2_queryctrl() is still called directly by
 379                 * drivers as well and until that has been addressed I believe
 380                 * it is safer to do the check here. The same is true for the
 381                 * other control ioctls below.
 382                 */
 383                if (!vfh->ctrl_handler)
 384                        return -ENOTTY;
 385                return v4l2_queryctrl(vfh->ctrl_handler, arg);
 386
 387        case VIDIOC_QUERY_EXT_CTRL:
 388                if (!vfh->ctrl_handler)
 389                        return -ENOTTY;
 390                return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg);
 391
 392        case VIDIOC_QUERYMENU:
 393                if (!vfh->ctrl_handler)
 394                        return -ENOTTY;
 395                return v4l2_querymenu(vfh->ctrl_handler, arg);
 396
 397        case VIDIOC_G_CTRL:
 398                if (!vfh->ctrl_handler)
 399                        return -ENOTTY;
 400                return v4l2_g_ctrl(vfh->ctrl_handler, arg);
 401
 402        case VIDIOC_S_CTRL:
 403                if (!vfh->ctrl_handler)
 404                        return -ENOTTY;
 405                return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg);
 406
 407        case VIDIOC_G_EXT_CTRLS:
 408                if (!vfh->ctrl_handler)
 409                        return -ENOTTY;
 410                return v4l2_g_ext_ctrls(vfh->ctrl_handler,
 411                                        vdev, sd->v4l2_dev->mdev, arg);
 412
 413        case VIDIOC_S_EXT_CTRLS:
 414                if (!vfh->ctrl_handler)
 415                        return -ENOTTY;
 416                return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
 417                                        vdev, sd->v4l2_dev->mdev, arg);
 418
 419        case VIDIOC_TRY_EXT_CTRLS:
 420                if (!vfh->ctrl_handler)
 421                        return -ENOTTY;
 422                return v4l2_try_ext_ctrls(vfh->ctrl_handler,
 423                                          vdev, sd->v4l2_dev->mdev, arg);
 424
 425        case VIDIOC_DQEVENT:
 426                if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
 427                        return -ENOIOCTLCMD;
 428
 429                return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
 430
 431        case VIDIOC_SUBSCRIBE_EVENT:
 432                return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
 433
 434        case VIDIOC_UNSUBSCRIBE_EVENT:
 435                return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
 436
 437#ifdef CONFIG_VIDEO_ADV_DEBUG
 438        case VIDIOC_DBG_G_REGISTER:
 439        {
 440                struct v4l2_dbg_register *p = arg;
 441
 442                if (!capable(CAP_SYS_ADMIN))
 443                        return -EPERM;
 444                return v4l2_subdev_call(sd, core, g_register, p);
 445        }
 446        case VIDIOC_DBG_S_REGISTER:
 447        {
 448                struct v4l2_dbg_register *p = arg;
 449
 450                if (!capable(CAP_SYS_ADMIN))
 451                        return -EPERM;
 452                return v4l2_subdev_call(sd, core, s_register, p);
 453        }
 454        case VIDIOC_DBG_G_CHIP_INFO:
 455        {
 456                struct v4l2_dbg_chip_info *p = arg;
 457
 458                if (p->match.type != V4L2_CHIP_MATCH_SUBDEV || p->match.addr)
 459                        return -EINVAL;
 460                if (sd->ops->core && sd->ops->core->s_register)
 461                        p->flags |= V4L2_CHIP_FL_WRITABLE;
 462                if (sd->ops->core && sd->ops->core->g_register)
 463                        p->flags |= V4L2_CHIP_FL_READABLE;
 464                strscpy(p->name, sd->name, sizeof(p->name));
 465                return 0;
 466        }
 467#endif
 468
 469        case VIDIOC_LOG_STATUS: {
 470                int ret;
 471
 472                pr_info("%s: =================  START STATUS  =================\n",
 473                        sd->name);
 474                ret = v4l2_subdev_call(sd, core, log_status);
 475                pr_info("%s: ==================  END STATUS  ==================\n",
 476                        sd->name);
 477                return ret;
 478        }
 479
 480        case VIDIOC_SUBDEV_G_FMT: {
 481                struct v4l2_subdev_format *format = arg;
 482
 483                memset(format->reserved, 0, sizeof(format->reserved));
 484                memset(format->format.reserved, 0, sizeof(format->format.reserved));
 485                return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format);
 486        }
 487
 488        case VIDIOC_SUBDEV_S_FMT: {
 489                struct v4l2_subdev_format *format = arg;
 490
 491                if (format->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
 492                        return -EPERM;
 493
 494                memset(format->reserved, 0, sizeof(format->reserved));
 495                memset(format->format.reserved, 0, sizeof(format->format.reserved));
 496                return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format);
 497        }
 498
 499        case VIDIOC_SUBDEV_G_CROP: {
 500                struct v4l2_subdev_crop *crop = arg;
 501                struct v4l2_subdev_selection sel;
 502
 503                memset(crop->reserved, 0, sizeof(crop->reserved));
 504                memset(&sel, 0, sizeof(sel));
 505                sel.which = crop->which;
 506                sel.pad = crop->pad;
 507                sel.target = V4L2_SEL_TGT_CROP;
 508
 509                rval = v4l2_subdev_call(
 510                        sd, pad, get_selection, subdev_fh->pad, &sel);
 511
 512                crop->rect = sel.r;
 513
 514                return rval;
 515        }
 516
 517        case VIDIOC_SUBDEV_S_CROP: {
 518                struct v4l2_subdev_crop *crop = arg;
 519                struct v4l2_subdev_selection sel;
 520
 521                if (crop->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
 522                        return -EPERM;
 523
 524                memset(crop->reserved, 0, sizeof(crop->reserved));
 525                memset(&sel, 0, sizeof(sel));
 526                sel.which = crop->which;
 527                sel.pad = crop->pad;
 528                sel.target = V4L2_SEL_TGT_CROP;
 529                sel.r = crop->rect;
 530
 531                rval = v4l2_subdev_call(
 532                        sd, pad, set_selection, subdev_fh->pad, &sel);
 533
 534                crop->rect = sel.r;
 535
 536                return rval;
 537        }
 538
 539        case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
 540                struct v4l2_subdev_mbus_code_enum *code = arg;
 541
 542                memset(code->reserved, 0, sizeof(code->reserved));
 543                return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad,
 544                                        code);
 545        }
 546
 547        case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {
 548                struct v4l2_subdev_frame_size_enum *fse = arg;
 549
 550                memset(fse->reserved, 0, sizeof(fse->reserved));
 551                return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad,
 552                                        fse);
 553        }
 554
 555        case VIDIOC_SUBDEV_G_FRAME_INTERVAL: {
 556                struct v4l2_subdev_frame_interval *fi = arg;
 557
 558                memset(fi->reserved, 0, sizeof(fi->reserved));
 559                return v4l2_subdev_call(sd, video, g_frame_interval, arg);
 560        }
 561
 562        case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {
 563                struct v4l2_subdev_frame_interval *fi = arg;
 564
 565                if (ro_subdev)
 566                        return -EPERM;
 567
 568                memset(fi->reserved, 0, sizeof(fi->reserved));
 569                return v4l2_subdev_call(sd, video, s_frame_interval, arg);
 570        }
 571
 572        case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {
 573                struct v4l2_subdev_frame_interval_enum *fie = arg;
 574
 575                memset(fie->reserved, 0, sizeof(fie->reserved));
 576                return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad,
 577                                        fie);
 578        }
 579
 580        case VIDIOC_SUBDEV_G_SELECTION: {
 581                struct v4l2_subdev_selection *sel = arg;
 582
 583                memset(sel->reserved, 0, sizeof(sel->reserved));
 584                return v4l2_subdev_call(
 585                        sd, pad, get_selection, subdev_fh->pad, sel);
 586        }
 587
 588        case VIDIOC_SUBDEV_S_SELECTION: {
 589                struct v4l2_subdev_selection *sel = arg;
 590
 591                if (sel->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)
 592                        return -EPERM;
 593
 594                memset(sel->reserved, 0, sizeof(sel->reserved));
 595                return v4l2_subdev_call(
 596                        sd, pad, set_selection, subdev_fh->pad, sel);
 597        }
 598
 599        case VIDIOC_G_EDID: {
 600                struct v4l2_subdev_edid *edid = arg;
 601
 602                return v4l2_subdev_call(sd, pad, get_edid, edid);
 603        }
 604
 605        case VIDIOC_S_EDID: {
 606                struct v4l2_subdev_edid *edid = arg;
 607
 608                return v4l2_subdev_call(sd, pad, set_edid, edid);
 609        }
 610
 611        case VIDIOC_SUBDEV_DV_TIMINGS_CAP: {
 612                struct v4l2_dv_timings_cap *cap = arg;
 613
 614                return v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
 615        }
 616
 617        case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: {
 618                struct v4l2_enum_dv_timings *dvt = arg;
 619
 620                return v4l2_subdev_call(sd, pad, enum_dv_timings, dvt);
 621        }
 622
 623        case VIDIOC_SUBDEV_QUERY_DV_TIMINGS:
 624                return v4l2_subdev_call(sd, video, query_dv_timings, arg);
 625
 626        case VIDIOC_SUBDEV_G_DV_TIMINGS:
 627                return v4l2_subdev_call(sd, video, g_dv_timings, arg);
 628
 629        case VIDIOC_SUBDEV_S_DV_TIMINGS:
 630                if (ro_subdev)
 631                        return -EPERM;
 632
 633                return v4l2_subdev_call(sd, video, s_dv_timings, arg);
 634
 635        case VIDIOC_SUBDEV_G_STD:
 636                return v4l2_subdev_call(sd, video, g_std, arg);
 637
 638        case VIDIOC_SUBDEV_S_STD: {
 639                v4l2_std_id *std = arg;
 640
 641                if (ro_subdev)
 642                        return -EPERM;
 643
 644                return v4l2_subdev_call(sd, video, s_std, *std);
 645        }
 646
 647        case VIDIOC_SUBDEV_ENUMSTD: {
 648                struct v4l2_standard *p = arg;
 649                v4l2_std_id id;
 650
 651                if (v4l2_subdev_call(sd, video, g_tvnorms, &id))
 652                        return -EINVAL;
 653
 654                return v4l_video_std_enumstd(p, id);
 655        }
 656
 657        case VIDIOC_SUBDEV_QUERYSTD:
 658                return v4l2_subdev_call(sd, video, querystd, arg);
 659
 660        default:
 661                return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
 662        }
 663
 664        return 0;
 665}
 666
 667static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg)
 668{
 669        struct video_device *vdev = video_devdata(file);
 670        struct mutex *lock = vdev->lock;
 671        long ret = -ENODEV;
 672
 673        if (lock && mutex_lock_interruptible(lock))
 674                return -ERESTARTSYS;
 675        if (video_is_registered(vdev))
 676                ret = subdev_do_ioctl(file, cmd, arg);
 677        if (lock)
 678                mutex_unlock(lock);
 679        return ret;
 680}
 681
 682static long subdev_ioctl(struct file *file, unsigned int cmd,
 683        unsigned long arg)
 684{
 685        return video_usercopy(file, cmd, arg, subdev_do_ioctl_lock);
 686}
 687
 688#ifdef CONFIG_COMPAT
 689static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,
 690        unsigned long arg)
 691{
 692        struct video_device *vdev = video_devdata(file);
 693        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
 694
 695        return v4l2_subdev_call(sd, core, compat_ioctl32, cmd, arg);
 696}
 697#endif
 698
 699#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 700static long subdev_ioctl(struct file *file, unsigned int cmd,
 701                         unsigned long arg)
 702{
 703        return -ENODEV;
 704}
 705
 706#ifdef CONFIG_COMPAT
 707static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,
 708                                  unsigned long arg)
 709{
 710        return -ENODEV;
 711}
 712#endif
 713#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
 714
 715static __poll_t subdev_poll(struct file *file, poll_table *wait)
 716{
 717        struct video_device *vdev = video_devdata(file);
 718        struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
 719        struct v4l2_fh *fh = file->private_data;
 720
 721        if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
 722                return EPOLLERR;
 723
 724        poll_wait(file, &fh->wait, wait);
 725
 726        if (v4l2_event_pending(fh))
 727                return EPOLLPRI;
 728
 729        return 0;
 730}
 731
 732const struct v4l2_file_operations v4l2_subdev_fops = {
 733        .owner = THIS_MODULE,
 734        .open = subdev_open,
 735        .unlocked_ioctl = subdev_ioctl,
 736#ifdef CONFIG_COMPAT
 737        .compat_ioctl32 = subdev_compat_ioctl32,
 738#endif
 739        .release = subdev_close,
 740        .poll = subdev_poll,
 741};
 742
 743#ifdef CONFIG_MEDIA_CONTROLLER
 744
 745int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity,
 746                                      struct fwnode_endpoint *endpoint)
 747{
 748        struct fwnode_handle *fwnode;
 749        struct v4l2_subdev *sd;
 750
 751        if (!is_media_entity_v4l2_subdev(entity))
 752                return -EINVAL;
 753
 754        sd = media_entity_to_v4l2_subdev(entity);
 755
 756        fwnode = fwnode_graph_get_port_parent(endpoint->local_fwnode);
 757        fwnode_handle_put(fwnode);
 758
 759        if (dev_fwnode(sd->dev) == fwnode)
 760                return endpoint->port;
 761
 762        return -ENXIO;
 763}
 764EXPORT_SYMBOL_GPL(v4l2_subdev_get_fwnode_pad_1_to_1);
 765
 766int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
 767                                      struct media_link *link,
 768                                      struct v4l2_subdev_format *source_fmt,
 769                                      struct v4l2_subdev_format *sink_fmt)
 770{
 771        bool pass = true;
 772
 773        /* The width, height and code must match. */
 774        if (source_fmt->format.width != sink_fmt->format.width) {
 775                dev_dbg(sd->entity.graph_obj.mdev->dev,
 776                        "%s: width does not match (source %u, sink %u)\n",
 777                        __func__,
 778                        source_fmt->format.width, sink_fmt->format.width);
 779                pass = false;
 780        }
 781
 782        if (source_fmt->format.height != sink_fmt->format.height) {
 783                dev_dbg(sd->entity.graph_obj.mdev->dev,
 784                        "%s: height does not match (source %u, sink %u)\n",
 785                        __func__,
 786                        source_fmt->format.height, sink_fmt->format.height);
 787                pass = false;
 788        }
 789
 790        if (source_fmt->format.code != sink_fmt->format.code) {
 791                dev_dbg(sd->entity.graph_obj.mdev->dev,
 792                        "%s: media bus code does not match (source 0x%8.8x, sink 0x%8.8x)\n",
 793                        __func__,
 794                        source_fmt->format.code, sink_fmt->format.code);
 795                pass = false;
 796        }
 797
 798        /* The field order must match, or the sink field order must be NONE
 799         * to support interlaced hardware connected to bridges that support
 800         * progressive formats only.
 801         */
 802        if (source_fmt->format.field != sink_fmt->format.field &&
 803            sink_fmt->format.field != V4L2_FIELD_NONE) {
 804                dev_dbg(sd->entity.graph_obj.mdev->dev,
 805                        "%s: field does not match (source %u, sink %u)\n",
 806                        __func__,
 807                        source_fmt->format.field, sink_fmt->format.field);
 808                pass = false;
 809        }
 810
 811        if (pass)
 812                return 0;
 813
 814        dev_dbg(sd->entity.graph_obj.mdev->dev,
 815                "%s: link was \"%s\":%u -> \"%s\":%u\n", __func__,
 816                link->source->entity->name, link->source->index,
 817                link->sink->entity->name, link->sink->index);
 818
 819        return -EPIPE;
 820}
 821EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);
 822
 823static int
 824v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 825                                     struct v4l2_subdev_format *fmt)
 826{
 827        if (is_media_entity_v4l2_subdev(pad->entity)) {
 828                struct v4l2_subdev *sd =
 829                        media_entity_to_v4l2_subdev(pad->entity);
 830
 831                fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
 832                fmt->pad = pad->index;
 833                return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
 834        }
 835
 836        WARN(pad->entity->function != MEDIA_ENT_F_IO_V4L,
 837             "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
 838             pad->entity->function, pad->entity->name);
 839
 840        return -EINVAL;
 841}
 842
 843int v4l2_subdev_link_validate(struct media_link *link)
 844{
 845        struct v4l2_subdev *sink;
 846        struct v4l2_subdev_format sink_fmt, source_fmt;
 847        int rval;
 848
 849        rval = v4l2_subdev_link_validate_get_format(
 850                link->source, &source_fmt);
 851        if (rval < 0)
 852                return 0;
 853
 854        rval = v4l2_subdev_link_validate_get_format(
 855                link->sink, &sink_fmt);
 856        if (rval < 0)
 857                return 0;
 858
 859        sink = media_entity_to_v4l2_subdev(link->sink->entity);
 860
 861        rval = v4l2_subdev_call(sink, pad, link_validate, link,
 862                                &source_fmt, &sink_fmt);
 863        if (rval != -ENOIOCTLCMD)
 864                return rval;
 865
 866        return v4l2_subdev_link_validate_default(
 867                sink, link, &source_fmt, &sink_fmt);
 868}
 869EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);
 870
 871struct v4l2_subdev_pad_config *
 872v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd)
 873{
 874        struct v4l2_subdev_pad_config *cfg;
 875        int ret;
 876
 877        if (!sd->entity.num_pads)
 878                return NULL;
 879
 880        cfg = kvmalloc_array(sd->entity.num_pads, sizeof(*cfg),
 881                             GFP_KERNEL | __GFP_ZERO);
 882        if (!cfg)
 883                return NULL;
 884
 885        ret = v4l2_subdev_call(sd, pad, init_cfg, cfg);
 886        if (ret < 0 && ret != -ENOIOCTLCMD) {
 887                kvfree(cfg);
 888                return NULL;
 889        }
 890
 891        return cfg;
 892}
 893EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config);
 894
 895void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg)
 896{
 897        kvfree(cfg);
 898}
 899EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config);
 900#endif /* CONFIG_MEDIA_CONTROLLER */
 901
 902void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
 903{
 904        INIT_LIST_HEAD(&sd->list);
 905        BUG_ON(!ops);
 906        sd->ops = ops;
 907        sd->v4l2_dev = NULL;
 908        sd->flags = 0;
 909        sd->name[0] = '\0';
 910        sd->grp_id = 0;
 911        sd->dev_priv = NULL;
 912        sd->host_priv = NULL;
 913#if defined(CONFIG_MEDIA_CONTROLLER)
 914        sd->entity.name = sd->name;
 915        sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;
 916        sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
 917#endif
 918}
 919EXPORT_SYMBOL(v4l2_subdev_init);
 920
 921void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
 922                              const struct v4l2_event *ev)
 923{
 924        v4l2_event_queue(sd->devnode, ev);
 925        v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, (void *)ev);
 926}
 927EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event);
 928