2570 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * V4L2 sub-device4 *5 * Copyright (C) 2010 Nokia Corporation6 *7 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>8 * Sakari Ailus <sakari.ailus@iki.fi>9 */10 11#include <linux/export.h>12#include <linux/ioctl.h>13#include <linux/leds.h>14#include <linux/mm.h>15#include <linux/module.h>16#include <linux/overflow.h>17#include <linux/slab.h>18#include <linux/string.h>19#include <linux/types.h>20#include <linux/version.h>21#include <linux/videodev2.h>22 23#include <media/v4l2-ctrls.h>24#include <media/v4l2-device.h>25#include <media/v4l2-event.h>26#include <media/v4l2-fh.h>27#include <media/v4l2-ioctl.h>28 29#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)30/*31 * The Streams API is an experimental feature. To use the Streams API, set32 * 'v4l2_subdev_enable_streams_api' to 1 below.33 */34 35static bool v4l2_subdev_enable_streams_api;36#endif37 38/*39 * Maximum stream ID is 63 for now, as we use u64 bitmask to represent a set40 * of streams.41 *42 * Note that V4L2_FRAME_DESC_ENTRY_MAX is related: V4L2_FRAME_DESC_ENTRY_MAX43 * restricts the total number of streams in a pad, although the stream ID is44 * not restricted.45 */46#define V4L2_SUBDEV_MAX_STREAM_ID 6347 48#include "v4l2-subdev-priv.h"49 50#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)51static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)52{53 struct v4l2_subdev_state *state;54 static struct lock_class_key key;55 56 state = __v4l2_subdev_state_alloc(sd, "fh->state->lock", &key);57 if (IS_ERR(state))58 return PTR_ERR(state);59 60 fh->state = state;61 62 return 0;63}64 65static void subdev_fh_free(struct v4l2_subdev_fh *fh)66{67 __v4l2_subdev_state_free(fh->state);68 fh->state = NULL;69}70 71static int subdev_open(struct file *file)72{73 struct video_device *vdev = video_devdata(file);74 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);75 struct v4l2_subdev_fh *subdev_fh;76 int ret;77 78 subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);79 if (subdev_fh == NULL)80 return -ENOMEM;81 82 ret = subdev_fh_init(subdev_fh, sd);83 if (ret) {84 kfree(subdev_fh);85 return ret;86 }87 88 v4l2_fh_init(&subdev_fh->vfh, vdev);89 v4l2_fh_add(&subdev_fh->vfh);90 file->private_data = &subdev_fh->vfh;91 92 if (sd->v4l2_dev->mdev && sd->entity.graph_obj.mdev->dev) {93 struct module *owner;94 95 owner = sd->entity.graph_obj.mdev->dev->driver->owner;96 if (!try_module_get(owner)) {97 ret = -EBUSY;98 goto err;99 }100 subdev_fh->owner = owner;101 }102 103 if (sd->internal_ops && sd->internal_ops->open) {104 ret = sd->internal_ops->open(sd, subdev_fh);105 if (ret < 0)106 goto err;107 }108 109 return 0;110 111err:112 module_put(subdev_fh->owner);113 v4l2_fh_del(&subdev_fh->vfh);114 v4l2_fh_exit(&subdev_fh->vfh);115 subdev_fh_free(subdev_fh);116 kfree(subdev_fh);117 118 return ret;119}120 121static int subdev_close(struct file *file)122{123 struct video_device *vdev = video_devdata(file);124 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);125 struct v4l2_fh *vfh = file->private_data;126 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);127 128 if (sd->internal_ops && sd->internal_ops->close)129 sd->internal_ops->close(sd, subdev_fh);130 module_put(subdev_fh->owner);131 v4l2_fh_del(vfh);132 v4l2_fh_exit(vfh);133 subdev_fh_free(subdev_fh);134 kfree(subdev_fh);135 file->private_data = NULL;136 137 return 0;138}139#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */140static int subdev_open(struct file *file)141{142 return -ENODEV;143}144 145static int subdev_close(struct file *file)146{147 return -ENODEV;148}149#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */150 151static void v4l2_subdev_enable_privacy_led(struct v4l2_subdev *sd)152{153#if IS_REACHABLE(CONFIG_LEDS_CLASS)154 if (!IS_ERR_OR_NULL(sd->privacy_led))155 led_set_brightness(sd->privacy_led,156 sd->privacy_led->max_brightness);157#endif158}159 160static void v4l2_subdev_disable_privacy_led(struct v4l2_subdev *sd)161{162#if IS_REACHABLE(CONFIG_LEDS_CLASS)163 if (!IS_ERR_OR_NULL(sd->privacy_led))164 led_set_brightness(sd->privacy_led, 0);165#endif166}167 168static inline int check_which(u32 which)169{170 if (which != V4L2_SUBDEV_FORMAT_TRY &&171 which != V4L2_SUBDEV_FORMAT_ACTIVE)172 return -EINVAL;173 174 return 0;175}176 177static inline int check_pad(struct v4l2_subdev *sd, u32 pad)178{179#if defined(CONFIG_MEDIA_CONTROLLER)180 if (sd->entity.num_pads) {181 if (pad >= sd->entity.num_pads)182 return -EINVAL;183 return 0;184 }185#endif186 /* allow pad 0 on subdevices not registered as media entities */187 if (pad > 0)188 return -EINVAL;189 return 0;190}191 192static int check_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,193 u32 which, u32 pad, u32 stream)194{195 if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {196#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)197 if (!v4l2_subdev_state_get_format(state, pad, stream))198 return -EINVAL;199 return 0;200#else201 return -EINVAL;202#endif203 }204 205 if (stream != 0)206 return -EINVAL;207 208 if (which == V4L2_SUBDEV_FORMAT_TRY && (!state || !state->pads))209 return -EINVAL;210 211 return 0;212}213 214static inline int check_format(struct v4l2_subdev *sd,215 struct v4l2_subdev_state *state,216 struct v4l2_subdev_format *format)217{218 if (!format)219 return -EINVAL;220 221 return check_which(format->which) ? : check_pad(sd, format->pad) ? :222 check_state(sd, state, format->which, format->pad, format->stream);223}224 225static int call_get_fmt(struct v4l2_subdev *sd,226 struct v4l2_subdev_state *state,227 struct v4l2_subdev_format *format)228{229 return check_format(sd, state, format) ? :230 sd->ops->pad->get_fmt(sd, state, format);231}232 233static int call_set_fmt(struct v4l2_subdev *sd,234 struct v4l2_subdev_state *state,235 struct v4l2_subdev_format *format)236{237 return check_format(sd, state, format) ? :238 sd->ops->pad->set_fmt(sd, state, format);239}240 241static int call_enum_mbus_code(struct v4l2_subdev *sd,242 struct v4l2_subdev_state *state,243 struct v4l2_subdev_mbus_code_enum *code)244{245 if (!code)246 return -EINVAL;247 248 return check_which(code->which) ? : check_pad(sd, code->pad) ? :249 check_state(sd, state, code->which, code->pad, code->stream) ? :250 sd->ops->pad->enum_mbus_code(sd, state, code);251}252 253static int call_enum_frame_size(struct v4l2_subdev *sd,254 struct v4l2_subdev_state *state,255 struct v4l2_subdev_frame_size_enum *fse)256{257 if (!fse)258 return -EINVAL;259 260 return check_which(fse->which) ? : check_pad(sd, fse->pad) ? :261 check_state(sd, state, fse->which, fse->pad, fse->stream) ? :262 sd->ops->pad->enum_frame_size(sd, state, fse);263}264 265static int call_enum_frame_interval(struct v4l2_subdev *sd,266 struct v4l2_subdev_state *state,267 struct v4l2_subdev_frame_interval_enum *fie)268{269 if (!fie)270 return -EINVAL;271 272 return check_which(fie->which) ? : check_pad(sd, fie->pad) ? :273 check_state(sd, state, fie->which, fie->pad, fie->stream) ? :274 sd->ops->pad->enum_frame_interval(sd, state, fie);275}276 277static inline int check_selection(struct v4l2_subdev *sd,278 struct v4l2_subdev_state *state,279 struct v4l2_subdev_selection *sel)280{281 if (!sel)282 return -EINVAL;283 284 return check_which(sel->which) ? : check_pad(sd, sel->pad) ? :285 check_state(sd, state, sel->which, sel->pad, sel->stream);286}287 288static int call_get_selection(struct v4l2_subdev *sd,289 struct v4l2_subdev_state *state,290 struct v4l2_subdev_selection *sel)291{292 return check_selection(sd, state, sel) ? :293 sd->ops->pad->get_selection(sd, state, sel);294}295 296static int call_set_selection(struct v4l2_subdev *sd,297 struct v4l2_subdev_state *state,298 struct v4l2_subdev_selection *sel)299{300 return check_selection(sd, state, sel) ? :301 sd->ops->pad->set_selection(sd, state, sel);302}303 304static inline int check_frame_interval(struct v4l2_subdev *sd,305 struct v4l2_subdev_state *state,306 struct v4l2_subdev_frame_interval *fi)307{308 if (!fi)309 return -EINVAL;310 311 return check_which(fi->which) ? : check_pad(sd, fi->pad) ? :312 check_state(sd, state, fi->which, fi->pad, fi->stream);313}314 315static int call_get_frame_interval(struct v4l2_subdev *sd,316 struct v4l2_subdev_state *state,317 struct v4l2_subdev_frame_interval *fi)318{319 return check_frame_interval(sd, state, fi) ? :320 sd->ops->pad->get_frame_interval(sd, state, fi);321}322 323static int call_set_frame_interval(struct v4l2_subdev *sd,324 struct v4l2_subdev_state *state,325 struct v4l2_subdev_frame_interval *fi)326{327 return check_frame_interval(sd, state, fi) ? :328 sd->ops->pad->set_frame_interval(sd, state, fi);329}330 331static int call_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,332 struct v4l2_mbus_frame_desc *fd)333{334 unsigned int i;335 int ret;336 337 memset(fd, 0, sizeof(*fd));338 339 ret = sd->ops->pad->get_frame_desc(sd, pad, fd);340 if (ret)341 return ret;342 343 dev_dbg(sd->dev, "Frame descriptor on pad %u, type %s\n", pad,344 fd->type == V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL ? "parallel" :345 fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2 ? "CSI-2" :346 "unknown");347 348 for (i = 0; i < fd->num_entries; i++) {349 struct v4l2_mbus_frame_desc_entry *entry = &fd->entry[i];350 char buf[20] = "";351 352 if (fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2)353 WARN_ON(snprintf(buf, sizeof(buf),354 ", vc %u, dt 0x%02x",355 entry->bus.csi2.vc,356 entry->bus.csi2.dt) >= sizeof(buf));357 358 dev_dbg(sd->dev,359 "\tstream %u, code 0x%04x, length %u, flags 0x%04x%s\n",360 entry->stream, entry->pixelcode, entry->length,361 entry->flags, buf);362 }363 364 return 0;365}366 367static inline int check_edid(struct v4l2_subdev *sd,368 struct v4l2_subdev_edid *edid)369{370 if (!edid)371 return -EINVAL;372 373 if (edid->blocks && edid->edid == NULL)374 return -EINVAL;375 376 return check_pad(sd, edid->pad);377}378 379static int call_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)380{381 return check_edid(sd, edid) ? : sd->ops->pad->get_edid(sd, edid);382}383 384static int call_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)385{386 return check_edid(sd, edid) ? : sd->ops->pad->set_edid(sd, edid);387}388 389static int call_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,390 struct v4l2_dv_timings *timings)391{392 if (!timings)393 return -EINVAL;394 395 return check_pad(sd, pad) ? :396 sd->ops->pad->s_dv_timings(sd, pad, timings);397}398 399static int call_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,400 struct v4l2_dv_timings *timings)401{402 if (!timings)403 return -EINVAL;404 405 return check_pad(sd, pad) ? :406 sd->ops->pad->g_dv_timings(sd, pad, timings);407}408 409static int call_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,410 struct v4l2_dv_timings *timings)411{412 if (!timings)413 return -EINVAL;414 415 return check_pad(sd, pad) ? :416 sd->ops->pad->query_dv_timings(sd, pad, timings);417}418 419static int call_dv_timings_cap(struct v4l2_subdev *sd,420 struct v4l2_dv_timings_cap *cap)421{422 if (!cap)423 return -EINVAL;424 425 return check_pad(sd, cap->pad) ? :426 sd->ops->pad->dv_timings_cap(sd, cap);427}428 429static int call_enum_dv_timings(struct v4l2_subdev *sd,430 struct v4l2_enum_dv_timings *dvt)431{432 if (!dvt)433 return -EINVAL;434 435 return check_pad(sd, dvt->pad) ? :436 sd->ops->pad->enum_dv_timings(sd, dvt);437}438 439static int call_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,440 struct v4l2_mbus_config *config)441{442 return check_pad(sd, pad) ? :443 sd->ops->pad->get_mbus_config(sd, pad, config);444}445 446static int call_s_stream(struct v4l2_subdev *sd, int enable)447{448 int ret;449 450 /*451 * The .s_stream() operation must never be called to start or stop an452 * already started or stopped subdev. Catch offenders but don't return453 * an error yet to avoid regressions.454 */455 if (WARN_ON(sd->s_stream_enabled == !!enable))456 return 0;457 458 ret = sd->ops->video->s_stream(sd, enable);459 460 if (!enable && ret < 0) {461 dev_warn(sd->dev, "disabling streaming failed (%d)\n", ret);462 ret = 0;463 }464 465 if (!ret) {466 sd->s_stream_enabled = enable;467 468 if (enable)469 v4l2_subdev_enable_privacy_led(sd);470 else471 v4l2_subdev_disable_privacy_led(sd);472 }473 474 return ret;475}476 477#ifdef CONFIG_MEDIA_CONTROLLER478/*479 * Create state-management wrapper for pad ops dealing with subdev state. The480 * wrapper handles the case where the caller does not provide the called481 * subdev's state. This should be removed when all the callers are fixed.482 */483#define DEFINE_STATE_WRAPPER(f, arg_type) \484 static int call_##f##_state(struct v4l2_subdev *sd, \485 struct v4l2_subdev_state *_state, \486 arg_type *arg) \487 { \488 struct v4l2_subdev_state *state = _state; \489 int ret; \490 if (!_state) \491 state = v4l2_subdev_lock_and_get_active_state(sd); \492 ret = call_##f(sd, state, arg); \493 if (!_state && state) \494 v4l2_subdev_unlock_state(state); \495 return ret; \496 }497 498#else /* CONFIG_MEDIA_CONTROLLER */499 500#define DEFINE_STATE_WRAPPER(f, arg_type) \501 static int call_##f##_state(struct v4l2_subdev *sd, \502 struct v4l2_subdev_state *state, \503 arg_type *arg) \504 { \505 return call_##f(sd, state, arg); \506 }507 508#endif /* CONFIG_MEDIA_CONTROLLER */509 510DEFINE_STATE_WRAPPER(get_fmt, struct v4l2_subdev_format);511DEFINE_STATE_WRAPPER(set_fmt, struct v4l2_subdev_format);512DEFINE_STATE_WRAPPER(enum_mbus_code, struct v4l2_subdev_mbus_code_enum);513DEFINE_STATE_WRAPPER(enum_frame_size, struct v4l2_subdev_frame_size_enum);514DEFINE_STATE_WRAPPER(enum_frame_interval, struct v4l2_subdev_frame_interval_enum);515DEFINE_STATE_WRAPPER(get_selection, struct v4l2_subdev_selection);516DEFINE_STATE_WRAPPER(set_selection, struct v4l2_subdev_selection);517 518static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers = {519 .get_fmt = call_get_fmt_state,520 .set_fmt = call_set_fmt_state,521 .enum_mbus_code = call_enum_mbus_code_state,522 .enum_frame_size = call_enum_frame_size_state,523 .enum_frame_interval = call_enum_frame_interval_state,524 .get_selection = call_get_selection_state,525 .set_selection = call_set_selection_state,526 .get_frame_interval = call_get_frame_interval,527 .set_frame_interval = call_set_frame_interval,528 .get_edid = call_get_edid,529 .set_edid = call_set_edid,530 .s_dv_timings = call_s_dv_timings,531 .g_dv_timings = call_g_dv_timings,532 .query_dv_timings = call_query_dv_timings,533 .dv_timings_cap = call_dv_timings_cap,534 .enum_dv_timings = call_enum_dv_timings,535 .get_frame_desc = call_get_frame_desc,536 .get_mbus_config = call_get_mbus_config,537};538 539static const struct v4l2_subdev_video_ops v4l2_subdev_call_video_wrappers = {540 .s_stream = call_s_stream,541};542 543const struct v4l2_subdev_ops v4l2_subdev_call_wrappers = {544 .pad = &v4l2_subdev_call_pad_wrappers,545 .video = &v4l2_subdev_call_video_wrappers,546};547EXPORT_SYMBOL(v4l2_subdev_call_wrappers);548 549#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)550 551static struct v4l2_subdev_state *552subdev_ioctl_get_state(struct v4l2_subdev *sd, struct v4l2_subdev_fh *subdev_fh,553 unsigned int cmd, void *arg)554{555 u32 which;556 557 switch (cmd) {558 default:559 return NULL;560 case VIDIOC_SUBDEV_G_FMT:561 case VIDIOC_SUBDEV_S_FMT:562 which = ((struct v4l2_subdev_format *)arg)->which;563 break;564 case VIDIOC_SUBDEV_G_CROP:565 case VIDIOC_SUBDEV_S_CROP:566 which = ((struct v4l2_subdev_crop *)arg)->which;567 break;568 case VIDIOC_SUBDEV_ENUM_MBUS_CODE:569 which = ((struct v4l2_subdev_mbus_code_enum *)arg)->which;570 break;571 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE:572 which = ((struct v4l2_subdev_frame_size_enum *)arg)->which;573 break;574 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL:575 which = ((struct v4l2_subdev_frame_interval_enum *)arg)->which;576 break;577 case VIDIOC_SUBDEV_G_SELECTION:578 case VIDIOC_SUBDEV_S_SELECTION:579 which = ((struct v4l2_subdev_selection *)arg)->which;580 break;581 case VIDIOC_SUBDEV_G_FRAME_INTERVAL:582 case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {583 struct v4l2_subdev_frame_interval *fi = arg;584 585 if (!(subdev_fh->client_caps &586 V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH))587 fi->which = V4L2_SUBDEV_FORMAT_ACTIVE;588 589 which = fi->which;590 break;591 }592 case VIDIOC_SUBDEV_G_ROUTING:593 case VIDIOC_SUBDEV_S_ROUTING:594 which = ((struct v4l2_subdev_routing *)arg)->which;595 break;596 }597 598 return which == V4L2_SUBDEV_FORMAT_TRY ?599 subdev_fh->state :600 v4l2_subdev_get_unlocked_active_state(sd);601}602 603static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,604 struct v4l2_subdev_state *state)605{606 struct video_device *vdev = video_devdata(file);607 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);608 struct v4l2_fh *vfh = file->private_data;609 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);610 bool ro_subdev = test_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags);611 bool streams_subdev = sd->flags & V4L2_SUBDEV_FL_STREAMS;612 bool client_supports_streams = subdev_fh->client_caps &613 V4L2_SUBDEV_CLIENT_CAP_STREAMS;614 int rval;615 616 /*617 * If the streams API is not enabled, remove V4L2_SUBDEV_CAP_STREAMS.618 * Remove this when the API is no longer experimental.619 */620 if (!v4l2_subdev_enable_streams_api)621 streams_subdev = false;622 623 switch (cmd) {624 case VIDIOC_SUBDEV_QUERYCAP: {625 struct v4l2_subdev_capability *cap = arg;626 627 memset(cap->reserved, 0, sizeof(cap->reserved));628 cap->version = LINUX_VERSION_CODE;629 cap->capabilities =630 (ro_subdev ? V4L2_SUBDEV_CAP_RO_SUBDEV : 0) |631 (streams_subdev ? V4L2_SUBDEV_CAP_STREAMS : 0);632 633 return 0;634 }635 636 case VIDIOC_QUERYCTRL:637 /*638 * TODO: this really should be folded into v4l2_queryctrl (this639 * currently returns -EINVAL for NULL control handlers).640 * However, v4l2_queryctrl() is still called directly by641 * drivers as well and until that has been addressed I believe642 * it is safer to do the check here. The same is true for the643 * other control ioctls below.644 */645 if (!vfh->ctrl_handler)646 return -ENOTTY;647 return v4l2_queryctrl(vfh->ctrl_handler, arg);648 649 case VIDIOC_QUERY_EXT_CTRL:650 if (!vfh->ctrl_handler)651 return -ENOTTY;652 return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg);653 654 case VIDIOC_QUERYMENU:655 if (!vfh->ctrl_handler)656 return -ENOTTY;657 return v4l2_querymenu(vfh->ctrl_handler, arg);658 659 case VIDIOC_G_CTRL:660 if (!vfh->ctrl_handler)661 return -ENOTTY;662 return v4l2_g_ctrl(vfh->ctrl_handler, arg);663 664 case VIDIOC_S_CTRL:665 if (!vfh->ctrl_handler)666 return -ENOTTY;667 return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg);668 669 case VIDIOC_G_EXT_CTRLS:670 if (!vfh->ctrl_handler)671 return -ENOTTY;672 return v4l2_g_ext_ctrls(vfh->ctrl_handler,673 vdev, sd->v4l2_dev->mdev, arg);674 675 case VIDIOC_S_EXT_CTRLS:676 if (!vfh->ctrl_handler)677 return -ENOTTY;678 return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,679 vdev, sd->v4l2_dev->mdev, arg);680 681 case VIDIOC_TRY_EXT_CTRLS:682 if (!vfh->ctrl_handler)683 return -ENOTTY;684 return v4l2_try_ext_ctrls(vfh->ctrl_handler,685 vdev, sd->v4l2_dev->mdev, arg);686 687 case VIDIOC_DQEVENT:688 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))689 return -ENOIOCTLCMD;690 691 return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);692 693 case VIDIOC_SUBSCRIBE_EVENT:694 return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);695 696 case VIDIOC_UNSUBSCRIBE_EVENT:697 return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);698 699#ifdef CONFIG_VIDEO_ADV_DEBUG700 case VIDIOC_DBG_G_REGISTER:701 {702 struct v4l2_dbg_register *p = arg;703 704 if (!capable(CAP_SYS_ADMIN))705 return -EPERM;706 return v4l2_subdev_call(sd, core, g_register, p);707 }708 case VIDIOC_DBG_S_REGISTER:709 {710 struct v4l2_dbg_register *p = arg;711 712 if (!capable(CAP_SYS_ADMIN))713 return -EPERM;714 return v4l2_subdev_call(sd, core, s_register, p);715 }716 case VIDIOC_DBG_G_CHIP_INFO:717 {718 struct v4l2_dbg_chip_info *p = arg;719 720 if (p->match.type != V4L2_CHIP_MATCH_SUBDEV || p->match.addr)721 return -EINVAL;722 if (sd->ops->core && sd->ops->core->s_register)723 p->flags |= V4L2_CHIP_FL_WRITABLE;724 if (sd->ops->core && sd->ops->core->g_register)725 p->flags |= V4L2_CHIP_FL_READABLE;726 strscpy(p->name, sd->name, sizeof(p->name));727 return 0;728 }729#endif730 731 case VIDIOC_LOG_STATUS: {732 int ret;733 734 pr_info("%s: ================= START STATUS =================\n",735 sd->name);736 ret = v4l2_subdev_call(sd, core, log_status);737 pr_info("%s: ================== END STATUS ==================\n",738 sd->name);739 return ret;740 }741 742 case VIDIOC_SUBDEV_G_FMT: {743 struct v4l2_subdev_format *format = arg;744 745 if (!client_supports_streams)746 format->stream = 0;747 748 memset(format->reserved, 0, sizeof(format->reserved));749 memset(format->format.reserved, 0, sizeof(format->format.reserved));750 return v4l2_subdev_call(sd, pad, get_fmt, state, format);751 }752 753 case VIDIOC_SUBDEV_S_FMT: {754 struct v4l2_subdev_format *format = arg;755 756 if (format->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)757 return -EPERM;758 759 if (!client_supports_streams)760 format->stream = 0;761 762 memset(format->reserved, 0, sizeof(format->reserved));763 memset(format->format.reserved, 0, sizeof(format->format.reserved));764 return v4l2_subdev_call(sd, pad, set_fmt, state, format);765 }766 767 case VIDIOC_SUBDEV_G_CROP: {768 struct v4l2_subdev_crop *crop = arg;769 struct v4l2_subdev_selection sel;770 771 if (!client_supports_streams)772 crop->stream = 0;773 774 memset(crop->reserved, 0, sizeof(crop->reserved));775 memset(&sel, 0, sizeof(sel));776 sel.which = crop->which;777 sel.pad = crop->pad;778 sel.stream = crop->stream;779 sel.target = V4L2_SEL_TGT_CROP;780 781 rval = v4l2_subdev_call(782 sd, pad, get_selection, state, &sel);783 784 crop->rect = sel.r;785 786 return rval;787 }788 789 case VIDIOC_SUBDEV_S_CROP: {790 struct v4l2_subdev_crop *crop = arg;791 struct v4l2_subdev_selection sel;792 793 if (crop->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)794 return -EPERM;795 796 if (!client_supports_streams)797 crop->stream = 0;798 799 memset(crop->reserved, 0, sizeof(crop->reserved));800 memset(&sel, 0, sizeof(sel));801 sel.which = crop->which;802 sel.pad = crop->pad;803 sel.stream = crop->stream;804 sel.target = V4L2_SEL_TGT_CROP;805 sel.r = crop->rect;806 807 rval = v4l2_subdev_call(808 sd, pad, set_selection, state, &sel);809 810 crop->rect = sel.r;811 812 return rval;813 }814 815 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {816 struct v4l2_subdev_mbus_code_enum *code = arg;817 818 if (!client_supports_streams)819 code->stream = 0;820 821 memset(code->reserved, 0, sizeof(code->reserved));822 return v4l2_subdev_call(sd, pad, enum_mbus_code, state,823 code);824 }825 826 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {827 struct v4l2_subdev_frame_size_enum *fse = arg;828 829 if (!client_supports_streams)830 fse->stream = 0;831 832 memset(fse->reserved, 0, sizeof(fse->reserved));833 return v4l2_subdev_call(sd, pad, enum_frame_size, state,834 fse);835 }836 837 case VIDIOC_SUBDEV_G_FRAME_INTERVAL: {838 struct v4l2_subdev_frame_interval *fi = arg;839 840 if (!client_supports_streams)841 fi->stream = 0;842 843 memset(fi->reserved, 0, sizeof(fi->reserved));844 return v4l2_subdev_call(sd, pad, get_frame_interval, state, fi);845 }846 847 case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {848 struct v4l2_subdev_frame_interval *fi = arg;849 850 if (!client_supports_streams)851 fi->stream = 0;852 853 if (fi->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)854 return -EPERM;855 856 memset(fi->reserved, 0, sizeof(fi->reserved));857 return v4l2_subdev_call(sd, pad, set_frame_interval, state, fi);858 }859 860 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {861 struct v4l2_subdev_frame_interval_enum *fie = arg;862 863 if (!client_supports_streams)864 fie->stream = 0;865 866 memset(fie->reserved, 0, sizeof(fie->reserved));867 return v4l2_subdev_call(sd, pad, enum_frame_interval, state,868 fie);869 }870 871 case VIDIOC_SUBDEV_G_SELECTION: {872 struct v4l2_subdev_selection *sel = arg;873 874 if (!client_supports_streams)875 sel->stream = 0;876 877 memset(sel->reserved, 0, sizeof(sel->reserved));878 return v4l2_subdev_call(879 sd, pad, get_selection, state, sel);880 }881 882 case VIDIOC_SUBDEV_S_SELECTION: {883 struct v4l2_subdev_selection *sel = arg;884 885 if (sel->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)886 return -EPERM;887 888 if (!client_supports_streams)889 sel->stream = 0;890 891 memset(sel->reserved, 0, sizeof(sel->reserved));892 return v4l2_subdev_call(893 sd, pad, set_selection, state, sel);894 }895 896 case VIDIOC_G_EDID: {897 struct v4l2_subdev_edid *edid = arg;898 899 return v4l2_subdev_call(sd, pad, get_edid, edid);900 }901 902 case VIDIOC_S_EDID: {903 struct v4l2_subdev_edid *edid = arg;904 905 return v4l2_subdev_call(sd, pad, set_edid, edid);906 }907 908 case VIDIOC_SUBDEV_DV_TIMINGS_CAP: {909 struct v4l2_dv_timings_cap *cap = arg;910 911 return v4l2_subdev_call(sd, pad, dv_timings_cap, cap);912 }913 914 case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: {915 struct v4l2_enum_dv_timings *dvt = arg;916 917 return v4l2_subdev_call(sd, pad, enum_dv_timings, dvt);918 }919 920 case VIDIOC_SUBDEV_QUERY_DV_TIMINGS:921 return v4l2_subdev_call(sd, pad, query_dv_timings, 0, arg);922 923 case VIDIOC_SUBDEV_G_DV_TIMINGS:924 return v4l2_subdev_call(sd, pad, g_dv_timings, 0, arg);925 926 case VIDIOC_SUBDEV_S_DV_TIMINGS:927 if (ro_subdev)928 return -EPERM;929 930 return v4l2_subdev_call(sd, pad, s_dv_timings, 0, arg);931 932 case VIDIOC_SUBDEV_G_STD:933 return v4l2_subdev_call(sd, video, g_std, arg);934 935 case VIDIOC_SUBDEV_S_STD: {936 v4l2_std_id *std = arg;937 938 if (ro_subdev)939 return -EPERM;940 941 return v4l2_subdev_call(sd, video, s_std, *std);942 }943 944 case VIDIOC_SUBDEV_ENUMSTD: {945 struct v4l2_standard *p = arg;946 v4l2_std_id id;947 948 if (v4l2_subdev_call(sd, video, g_tvnorms, &id))949 return -EINVAL;950 951 return v4l_video_std_enumstd(p, id);952 }953 954 case VIDIOC_SUBDEV_QUERYSTD:955 return v4l2_subdev_call(sd, video, querystd, arg);956 957 case VIDIOC_SUBDEV_G_ROUTING: {958 struct v4l2_subdev_routing *routing = arg;959 struct v4l2_subdev_krouting *krouting;960 961 if (!v4l2_subdev_enable_streams_api)962 return -ENOIOCTLCMD;963 964 if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))965 return -ENOIOCTLCMD;966 967 memset(routing->reserved, 0, sizeof(routing->reserved));968 969 krouting = &state->routing;970 971 memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes,972 krouting->routes,973 min(krouting->num_routes, routing->len_routes) *974 sizeof(*krouting->routes));975 routing->num_routes = krouting->num_routes;976 977 return 0;978 }979 980 case VIDIOC_SUBDEV_S_ROUTING: {981 struct v4l2_subdev_routing *routing = arg;982 struct v4l2_subdev_route *routes =983 (struct v4l2_subdev_route *)(uintptr_t)routing->routes;984 struct v4l2_subdev_krouting krouting = {};985 unsigned int i;986 987 if (!v4l2_subdev_enable_streams_api)988 return -ENOIOCTLCMD;989 990 if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))991 return -ENOIOCTLCMD;992 993 if (routing->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)994 return -EPERM;995 996 if (routing->num_routes > routing->len_routes)997 return -EINVAL;998 999 memset(routing->reserved, 0, sizeof(routing->reserved));1000 1001 for (i = 0; i < routing->num_routes; ++i) {1002 const struct v4l2_subdev_route *route = &routes[i];1003 const struct media_pad *pads = sd->entity.pads;1004 1005 if (route->sink_stream > V4L2_SUBDEV_MAX_STREAM_ID ||1006 route->source_stream > V4L2_SUBDEV_MAX_STREAM_ID)1007 return -EINVAL;1008 1009 if (route->sink_pad >= sd->entity.num_pads)1010 return -EINVAL;1011 1012 if (!(pads[route->sink_pad].flags &1013 MEDIA_PAD_FL_SINK))1014 return -EINVAL;1015 1016 if (route->source_pad >= sd->entity.num_pads)1017 return -EINVAL;1018 1019 if (!(pads[route->source_pad].flags &1020 MEDIA_PAD_FL_SOURCE))1021 return -EINVAL;1022 }1023 1024 /*1025 * If the driver doesn't support setting routing, just return1026 * the routing table.1027 */1028 if (!v4l2_subdev_has_op(sd, pad, set_routing)) {1029 memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes,1030 state->routing.routes,1031 min(state->routing.num_routes, routing->len_routes) *1032 sizeof(*state->routing.routes));1033 routing->num_routes = state->routing.num_routes;1034 1035 return 0;1036 }1037 1038 krouting.num_routes = routing->num_routes;1039 krouting.len_routes = routing->len_routes;1040 krouting.routes = routes;1041 1042 rval = v4l2_subdev_call(sd, pad, set_routing, state,1043 routing->which, &krouting);1044 if (rval < 0)1045 return rval;1046 1047 memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes,1048 state->routing.routes,1049 min(state->routing.num_routes, routing->len_routes) *1050 sizeof(*state->routing.routes));1051 routing->num_routes = state->routing.num_routes;1052 1053 return 0;1054 }1055 1056 case VIDIOC_SUBDEV_G_CLIENT_CAP: {1057 struct v4l2_subdev_client_capability *client_cap = arg;1058 1059 client_cap->capabilities = subdev_fh->client_caps;1060 1061 return 0;1062 }1063 1064 case VIDIOC_SUBDEV_S_CLIENT_CAP: {1065 struct v4l2_subdev_client_capability *client_cap = arg;1066 1067 /*1068 * Clear V4L2_SUBDEV_CLIENT_CAP_STREAMS if streams API is not1069 * enabled. Remove this when streams API is no longer1070 * experimental.1071 */1072 if (!v4l2_subdev_enable_streams_api)1073 client_cap->capabilities &= ~V4L2_SUBDEV_CLIENT_CAP_STREAMS;1074 1075 /* Filter out unsupported capabilities */1076 client_cap->capabilities &= (V4L2_SUBDEV_CLIENT_CAP_STREAMS |1077 V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH);1078 1079 subdev_fh->client_caps = client_cap->capabilities;1080 1081 return 0;1082 }1083 1084 default:1085 return v4l2_subdev_call(sd, core, ioctl, cmd, arg);1086 }1087 1088 return 0;1089}1090 1091static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg)1092{1093 struct video_device *vdev = video_devdata(file);1094 struct mutex *lock = vdev->lock;1095 long ret = -ENODEV;1096 1097 if (lock && mutex_lock_interruptible(lock))1098 return -ERESTARTSYS;1099 1100 if (video_is_registered(vdev)) {1101 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);1102 struct v4l2_fh *vfh = file->private_data;1103 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);1104 struct v4l2_subdev_state *state;1105 1106 state = subdev_ioctl_get_state(sd, subdev_fh, cmd, arg);1107 1108 if (state)1109 v4l2_subdev_lock_state(state);1110 1111 ret = subdev_do_ioctl(file, cmd, arg, state);1112 1113 if (state)1114 v4l2_subdev_unlock_state(state);1115 }1116 1117 if (lock)1118 mutex_unlock(lock);1119 return ret;1120}1121 1122static long subdev_ioctl(struct file *file, unsigned int cmd,1123 unsigned long arg)1124{1125 return video_usercopy(file, cmd, arg, subdev_do_ioctl_lock);1126}1127 1128#ifdef CONFIG_COMPAT1129static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,1130 unsigned long arg)1131{1132 struct video_device *vdev = video_devdata(file);1133 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);1134 1135 return v4l2_subdev_call(sd, core, compat_ioctl32, cmd, arg);1136}1137#endif1138 1139#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */1140static long subdev_ioctl(struct file *file, unsigned int cmd,1141 unsigned long arg)1142{1143 return -ENODEV;1144}1145 1146#ifdef CONFIG_COMPAT1147static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,1148 unsigned long arg)1149{1150 return -ENODEV;1151}1152#endif1153#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */1154 1155static __poll_t subdev_poll(struct file *file, poll_table *wait)1156{1157 struct video_device *vdev = video_devdata(file);1158 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);1159 struct v4l2_fh *fh = file->private_data;1160 1161 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))1162 return EPOLLERR;1163 1164 poll_wait(file, &fh->wait, wait);1165 1166 if (v4l2_event_pending(fh))1167 return EPOLLPRI;1168 1169 return 0;1170}1171 1172const struct v4l2_file_operations v4l2_subdev_fops = {1173 .owner = THIS_MODULE,1174 .open = subdev_open,1175 .unlocked_ioctl = subdev_ioctl,1176#ifdef CONFIG_COMPAT1177 .compat_ioctl32 = subdev_compat_ioctl32,1178#endif1179 .release = subdev_close,1180 .poll = subdev_poll,1181};1182 1183#ifdef CONFIG_MEDIA_CONTROLLER1184 1185int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity,1186 struct fwnode_endpoint *endpoint)1187{1188 struct fwnode_handle *fwnode;1189 struct v4l2_subdev *sd;1190 1191 if (!is_media_entity_v4l2_subdev(entity))1192 return -EINVAL;1193 1194 sd = media_entity_to_v4l2_subdev(entity);1195 1196 fwnode = fwnode_graph_get_port_parent(endpoint->local_fwnode);1197 fwnode_handle_put(fwnode);1198 1199 if (device_match_fwnode(sd->dev, fwnode))1200 return endpoint->port;1201 1202 return -ENXIO;1203}1204EXPORT_SYMBOL_GPL(v4l2_subdev_get_fwnode_pad_1_to_1);1205 1206int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,1207 struct media_link *link,1208 struct v4l2_subdev_format *source_fmt,1209 struct v4l2_subdev_format *sink_fmt)1210{1211 bool pass = true;1212 1213 /* The width, height and code must match. */1214 if (source_fmt->format.width != sink_fmt->format.width) {1215 dev_dbg(sd->entity.graph_obj.mdev->dev,1216 "%s: width does not match (source %u, sink %u)\n",1217 __func__,1218 source_fmt->format.width, sink_fmt->format.width);1219 pass = false;1220 }1221 1222 if (source_fmt->format.height != sink_fmt->format.height) {1223 dev_dbg(sd->entity.graph_obj.mdev->dev,1224 "%s: height does not match (source %u, sink %u)\n",1225 __func__,1226 source_fmt->format.height, sink_fmt->format.height);1227 pass = false;1228 }1229 1230 if (source_fmt->format.code != sink_fmt->format.code) {1231 dev_dbg(sd->entity.graph_obj.mdev->dev,1232 "%s: media bus code does not match (source 0x%8.8x, sink 0x%8.8x)\n",1233 __func__,1234 source_fmt->format.code, sink_fmt->format.code);1235 pass = false;1236 }1237 1238 /* The field order must match, or the sink field order must be NONE1239 * to support interlaced hardware connected to bridges that support1240 * progressive formats only.1241 */1242 if (source_fmt->format.field != sink_fmt->format.field &&1243 sink_fmt->format.field != V4L2_FIELD_NONE) {1244 dev_dbg(sd->entity.graph_obj.mdev->dev,1245 "%s: field does not match (source %u, sink %u)\n",1246 __func__,1247 source_fmt->format.field, sink_fmt->format.field);1248 pass = false;1249 }1250 1251 if (pass)1252 return 0;1253 1254 dev_dbg(sd->entity.graph_obj.mdev->dev,1255 "%s: link was \"%s\":%u -> \"%s\":%u\n", __func__,1256 link->source->entity->name, link->source->index,1257 link->sink->entity->name, link->sink->index);1258 1259 return -EPIPE;1260}1261EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);1262 1263static int1264v4l2_subdev_link_validate_get_format(struct media_pad *pad, u32 stream,1265 struct v4l2_subdev_format *fmt,1266 bool states_locked)1267{1268 struct v4l2_subdev_state *state;1269 struct v4l2_subdev *sd;1270 int ret;1271 1272 sd = media_entity_to_v4l2_subdev(pad->entity);1273 1274 fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;1275 fmt->pad = pad->index;1276 fmt->stream = stream;1277 1278 if (states_locked)1279 state = v4l2_subdev_get_locked_active_state(sd);1280 else1281 state = v4l2_subdev_lock_and_get_active_state(sd);1282 1283 ret = v4l2_subdev_call(sd, pad, get_fmt, state, fmt);1284 1285 if (!states_locked && state)1286 v4l2_subdev_unlock_state(state);1287 1288 return ret;1289}1290 1291#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)1292 1293static void __v4l2_link_validate_get_streams(struct media_pad *pad,1294 u64 *streams_mask,1295 bool states_locked)1296{1297 struct v4l2_subdev_route *route;1298 struct v4l2_subdev_state *state;1299 struct v4l2_subdev *subdev;1300 1301 subdev = media_entity_to_v4l2_subdev(pad->entity);1302 1303 *streams_mask = 0;1304 1305 if (states_locked)1306 state = v4l2_subdev_get_locked_active_state(subdev);1307 else1308 state = v4l2_subdev_lock_and_get_active_state(subdev);1309 1310 if (WARN_ON(!state))1311 return;1312 1313 for_each_active_route(&state->routing, route) {1314 u32 route_pad;1315 u32 route_stream;1316 1317 if (pad->flags & MEDIA_PAD_FL_SOURCE) {1318 route_pad = route->source_pad;1319 route_stream = route->source_stream;1320 } else {1321 route_pad = route->sink_pad;1322 route_stream = route->sink_stream;1323 }1324 1325 if (route_pad != pad->index)1326 continue;1327 1328 *streams_mask |= BIT_ULL(route_stream);1329 }1330 1331 if (!states_locked)1332 v4l2_subdev_unlock_state(state);1333}1334 1335#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */1336 1337static void v4l2_link_validate_get_streams(struct media_pad *pad,1338 u64 *streams_mask,1339 bool states_locked)1340{1341 struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(pad->entity);1342 1343 if (!(subdev->flags & V4L2_SUBDEV_FL_STREAMS)) {1344 /* Non-streams subdevs have an implicit stream 0 */1345 *streams_mask = BIT_ULL(0);1346 return;1347 }1348 1349#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)1350 __v4l2_link_validate_get_streams(pad, streams_mask, states_locked);1351#else1352 /* This shouldn't happen */1353 *streams_mask = 0;1354#endif1355}1356 1357static int v4l2_subdev_link_validate_locked(struct media_link *link, bool states_locked)1358{1359 struct v4l2_subdev *sink_subdev =1360 media_entity_to_v4l2_subdev(link->sink->entity);1361 struct device *dev = sink_subdev->entity.graph_obj.mdev->dev;1362 u64 source_streams_mask;1363 u64 sink_streams_mask;1364 u64 dangling_sink_streams;1365 u32 stream;1366 int ret;1367 1368 dev_dbg(dev, "validating link \"%s\":%u -> \"%s\":%u\n",1369 link->source->entity->name, link->source->index,1370 link->sink->entity->name, link->sink->index);1371 1372 v4l2_link_validate_get_streams(link->source, &source_streams_mask, states_locked);1373 v4l2_link_validate_get_streams(link->sink, &sink_streams_mask, states_locked);1374 1375 /*1376 * It is ok to have more source streams than sink streams as extra1377 * source streams can just be ignored by the receiver, but having extra1378 * sink streams is an error as streams must have a source.1379 */1380 dangling_sink_streams = (source_streams_mask ^ sink_streams_mask) &1381 sink_streams_mask;1382 if (dangling_sink_streams) {1383 dev_err(dev, "Dangling sink streams: mask %#llx\n",1384 dangling_sink_streams);1385 return -EINVAL;1386 }1387 1388 /* Validate source and sink stream formats */1389 1390 for (stream = 0; stream < sizeof(sink_streams_mask) * 8; ++stream) {1391 struct v4l2_subdev_format sink_fmt, source_fmt;1392 1393 if (!(sink_streams_mask & BIT_ULL(stream)))1394 continue;1395 1396 dev_dbg(dev, "validating stream \"%s\":%u:%u -> \"%s\":%u:%u\n",1397 link->source->entity->name, link->source->index, stream,1398 link->sink->entity->name, link->sink->index, stream);1399 1400 ret = v4l2_subdev_link_validate_get_format(link->source, stream,1401 &source_fmt, states_locked);1402 if (ret < 0) {1403 dev_dbg(dev,1404 "Failed to get format for \"%s\":%u:%u (but that's ok)\n",1405 link->source->entity->name, link->source->index,1406 stream);1407 continue;1408 }1409 1410 ret = v4l2_subdev_link_validate_get_format(link->sink, stream,1411 &sink_fmt, states_locked);1412 if (ret < 0) {1413 dev_dbg(dev,1414 "Failed to get format for \"%s\":%u:%u (but that's ok)\n",1415 link->sink->entity->name, link->sink->index,1416 stream);1417 continue;1418 }1419 1420 /* TODO: add stream number to link_validate() */1421 ret = v4l2_subdev_call(sink_subdev, pad, link_validate, link,1422 &source_fmt, &sink_fmt);1423 if (!ret)1424 continue;1425 1426 if (ret != -ENOIOCTLCMD)1427 return ret;1428 1429 ret = v4l2_subdev_link_validate_default(sink_subdev, link,1430 &source_fmt, &sink_fmt);1431 1432 if (ret)1433 return ret;1434 }1435 1436 return 0;1437}1438 1439int v4l2_subdev_link_validate(struct media_link *link)1440{1441 struct v4l2_subdev *source_sd, *sink_sd;1442 struct v4l2_subdev_state *source_state, *sink_state;1443 bool states_locked;1444 int ret;1445 1446 /*1447 * Links are validated in the context of the sink entity. Usage of this1448 * helper on a sink that is not a subdev is a clear driver bug.1449 */1450 if (WARN_ON_ONCE(!is_media_entity_v4l2_subdev(link->sink->entity)))1451 return -EINVAL;1452 1453 /*1454 * If the source is a video device, delegate link validation to it. This1455 * allows usage of this helper for subdev connected to a video output1456 * device, provided that the driver implement the video output device's1457 * .link_validate() operation.1458 */1459 if (is_media_entity_v4l2_video_device(link->source->entity)) {1460 struct media_entity *source = link->source->entity;1461 1462 if (!source->ops || !source->ops->link_validate) {1463 /*1464 * Many existing drivers do not implement the required1465 * .link_validate() operation for their video devices.1466 * Print a warning to get the drivers fixed, and return1467 * 0 to avoid breaking userspace. This should1468 * eventually be turned into a WARN_ON() when all1469 * drivers will have been fixed.1470 */1471 pr_warn_once("video device '%s' does not implement .link_validate(), driver bug!\n",1472 source->name);1473 return 0;1474 }1475 1476 /*1477 * Avoid infinite loops in case a video device incorrectly uses1478 * this helper function as its .link_validate() handler.1479 */1480 if (WARN_ON(source->ops->link_validate == v4l2_subdev_link_validate))1481 return -EINVAL;1482 1483 return source->ops->link_validate(link);1484 }1485 1486 /*1487 * If the source is still not a subdev, usage of this helper is a clear1488 * driver bug.1489 */1490 if (WARN_ON(!is_media_entity_v4l2_subdev(link->source->entity)))1491 return -EINVAL;1492 1493 sink_sd = media_entity_to_v4l2_subdev(link->sink->entity);1494 source_sd = media_entity_to_v4l2_subdev(link->source->entity);1495 1496 sink_state = v4l2_subdev_get_unlocked_active_state(sink_sd);1497 source_state = v4l2_subdev_get_unlocked_active_state(source_sd);1498 1499 states_locked = sink_state && source_state;1500 1501 if (states_locked)1502 v4l2_subdev_lock_states(sink_state, source_state);1503 1504 ret = v4l2_subdev_link_validate_locked(link, states_locked);1505 1506 if (states_locked)1507 v4l2_subdev_unlock_states(sink_state, source_state);1508 1509 return ret;1510}1511EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);1512 1513bool v4l2_subdev_has_pad_interdep(struct media_entity *entity,1514 unsigned int pad0, unsigned int pad1)1515{1516 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);1517 struct v4l2_subdev_krouting *routing;1518 struct v4l2_subdev_state *state;1519 unsigned int i;1520 1521 state = v4l2_subdev_lock_and_get_active_state(sd);1522 1523 routing = &state->routing;1524 1525 for (i = 0; i < routing->num_routes; ++i) {1526 struct v4l2_subdev_route *route = &routing->routes[i];1527 1528 if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))1529 continue;1530 1531 if ((route->sink_pad == pad0 && route->source_pad == pad1) ||1532 (route->source_pad == pad0 && route->sink_pad == pad1)) {1533 v4l2_subdev_unlock_state(state);1534 return true;1535 }1536 }1537 1538 v4l2_subdev_unlock_state(state);1539 1540 return false;1541}1542EXPORT_SYMBOL_GPL(v4l2_subdev_has_pad_interdep);1543 1544struct v4l2_subdev_state *1545__v4l2_subdev_state_alloc(struct v4l2_subdev *sd, const char *lock_name,1546 struct lock_class_key *lock_key)1547{1548 struct v4l2_subdev_state *state;1549 int ret;1550 1551 state = kzalloc(sizeof(*state), GFP_KERNEL);1552 if (!state)1553 return ERR_PTR(-ENOMEM);1554 1555 __mutex_init(&state->_lock, lock_name, lock_key);1556 if (sd->state_lock)1557 state->lock = sd->state_lock;1558 else1559 state->lock = &state->_lock;1560 1561 state->sd = sd;1562 1563 /* Drivers that support streams do not need the legacy pad config */1564 if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS) && sd->entity.num_pads) {1565 state->pads = kvcalloc(sd->entity.num_pads,1566 sizeof(*state->pads), GFP_KERNEL);1567 if (!state->pads) {1568 ret = -ENOMEM;1569 goto err;1570 }1571 }1572 1573 if (sd->internal_ops && sd->internal_ops->init_state) {1574 /*1575 * There can be no race at this point, but we lock the state1576 * anyway to satisfy lockdep checks.1577 */1578 v4l2_subdev_lock_state(state);1579 ret = sd->internal_ops->init_state(sd, state);1580 v4l2_subdev_unlock_state(state);1581 1582 if (ret)1583 goto err;1584 }1585 1586 return state;1587 1588err:1589 if (state && state->pads)1590 kvfree(state->pads);1591 1592 kfree(state);1593 1594 return ERR_PTR(ret);1595}1596EXPORT_SYMBOL_GPL(__v4l2_subdev_state_alloc);1597 1598void __v4l2_subdev_state_free(struct v4l2_subdev_state *state)1599{1600 if (!state)1601 return;1602 1603 mutex_destroy(&state->_lock);1604 1605 kfree(state->routing.routes);1606 kvfree(state->stream_configs.configs);1607 kvfree(state->pads);1608 kfree(state);1609}1610EXPORT_SYMBOL_GPL(__v4l2_subdev_state_free);1611 1612int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name,1613 struct lock_class_key *key)1614{1615 struct v4l2_subdev_state *state;1616 struct device *dev = sd->dev;1617 bool has_disable_streams;1618 bool has_enable_streams;1619 bool has_s_stream;1620 1621 /* Check that the subdevice implements the required features */1622 1623 has_s_stream = v4l2_subdev_has_op(sd, video, s_stream);1624 has_enable_streams = v4l2_subdev_has_op(sd, pad, enable_streams);1625 has_disable_streams = v4l2_subdev_has_op(sd, pad, disable_streams);1626 1627 if (has_enable_streams != has_disable_streams) {1628 dev_err(dev,1629 "subdev '%s' must implement both or neither of .enable_streams() and .disable_streams()\n",1630 sd->name);1631 return -EINVAL;1632 }1633 1634 if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {1635 if (has_s_stream && !has_enable_streams) {1636 dev_err(dev,1637 "subdev '%s' must implement .enable/disable_streams()\n",1638 sd->name);1639 1640 return -EINVAL;1641 }1642 }1643 1644 state = __v4l2_subdev_state_alloc(sd, name, key);1645 if (IS_ERR(state))1646 return PTR_ERR(state);1647 1648 sd->active_state = state;1649 1650 return 0;1651}1652EXPORT_SYMBOL_GPL(__v4l2_subdev_init_finalize);1653 1654void v4l2_subdev_cleanup(struct v4l2_subdev *sd)1655{1656 struct v4l2_async_subdev_endpoint *ase, *ase_tmp;1657 1658 __v4l2_subdev_state_free(sd->active_state);1659 sd->active_state = NULL;1660 1661 /* Uninitialised sub-device, bail out here. */1662 if (!sd->async_subdev_endpoint_list.next)1663 return;1664 1665 list_for_each_entry_safe(ase, ase_tmp, &sd->async_subdev_endpoint_list,1666 async_subdev_endpoint_entry) {1667 list_del(&ase->async_subdev_endpoint_entry);1668 1669 kfree(ase);1670 }1671}1672EXPORT_SYMBOL_GPL(v4l2_subdev_cleanup);1673 1674struct v4l2_mbus_framefmt *1675__v4l2_subdev_state_get_format(struct v4l2_subdev_state *state,1676 unsigned int pad, u32 stream)1677{1678 struct v4l2_subdev_stream_configs *stream_configs;1679 unsigned int i;1680 1681 if (WARN_ON_ONCE(!state))1682 return NULL;1683 1684 if (state->pads) {1685 if (stream)1686 return NULL;1687 1688 if (pad >= state->sd->entity.num_pads)1689 return NULL;1690 1691 return &state->pads[pad].format;1692 }1693 1694 lockdep_assert_held(state->lock);1695 1696 stream_configs = &state->stream_configs;1697 1698 for (i = 0; i < stream_configs->num_configs; ++i) {1699 if (stream_configs->configs[i].pad == pad &&1700 stream_configs->configs[i].stream == stream)1701 return &stream_configs->configs[i].fmt;1702 }1703 1704 return NULL;1705}1706EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_format);1707 1708struct v4l2_rect *1709__v4l2_subdev_state_get_crop(struct v4l2_subdev_state *state, unsigned int pad,1710 u32 stream)1711{1712 struct v4l2_subdev_stream_configs *stream_configs;1713 unsigned int i;1714 1715 if (WARN_ON_ONCE(!state))1716 return NULL;1717 1718 if (state->pads) {1719 if (stream)1720 return NULL;1721 1722 if (pad >= state->sd->entity.num_pads)1723 return NULL;1724 1725 return &state->pads[pad].crop;1726 }1727 1728 lockdep_assert_held(state->lock);1729 1730 stream_configs = &state->stream_configs;1731 1732 for (i = 0; i < stream_configs->num_configs; ++i) {1733 if (stream_configs->configs[i].pad == pad &&1734 stream_configs->configs[i].stream == stream)1735 return &stream_configs->configs[i].crop;1736 }1737 1738 return NULL;1739}1740EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_crop);1741 1742struct v4l2_rect *1743__v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,1744 unsigned int pad, u32 stream)1745{1746 struct v4l2_subdev_stream_configs *stream_configs;1747 unsigned int i;1748 1749 if (WARN_ON_ONCE(!state))1750 return NULL;1751 1752 if (state->pads) {1753 if (stream)1754 return NULL;1755 1756 if (pad >= state->sd->entity.num_pads)1757 return NULL;1758 1759 return &state->pads[pad].compose;1760 }1761 1762 lockdep_assert_held(state->lock);1763 1764 stream_configs = &state->stream_configs;1765 1766 for (i = 0; i < stream_configs->num_configs; ++i) {1767 if (stream_configs->configs[i].pad == pad &&1768 stream_configs->configs[i].stream == stream)1769 return &stream_configs->configs[i].compose;1770 }1771 1772 return NULL;1773}1774EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_compose);1775 1776struct v4l2_fract *1777__v4l2_subdev_state_get_interval(struct v4l2_subdev_state *state,1778 unsigned int pad, u32 stream)1779{1780 struct v4l2_subdev_stream_configs *stream_configs;1781 unsigned int i;1782 1783 if (WARN_ON(!state))1784 return NULL;1785 1786 lockdep_assert_held(state->lock);1787 1788 if (state->pads) {1789 if (stream)1790 return NULL;1791 1792 if (pad >= state->sd->entity.num_pads)1793 return NULL;1794 1795 return &state->pads[pad].interval;1796 }1797 1798 lockdep_assert_held(state->lock);1799 1800 stream_configs = &state->stream_configs;1801 1802 for (i = 0; i < stream_configs->num_configs; ++i) {1803 if (stream_configs->configs[i].pad == pad &&1804 stream_configs->configs[i].stream == stream)1805 return &stream_configs->configs[i].interval;1806 }1807 1808 return NULL;1809}1810EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_interval);1811 1812#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)1813 1814static int1815v4l2_subdev_init_stream_configs(struct v4l2_subdev_stream_configs *stream_configs,1816 const struct v4l2_subdev_krouting *routing)1817{1818 struct v4l2_subdev_stream_configs new_configs = { 0 };1819 struct v4l2_subdev_route *route;1820 u32 idx;1821 1822 /* Count number of formats needed */1823 for_each_active_route(routing, route) {1824 /*1825 * Each route needs a format on both ends of the route.1826 */1827 new_configs.num_configs += 2;1828 }1829 1830 if (new_configs.num_configs) {1831 new_configs.configs = kvcalloc(new_configs.num_configs,1832 sizeof(*new_configs.configs),1833 GFP_KERNEL);1834 1835 if (!new_configs.configs)1836 return -ENOMEM;1837 }1838 1839 /*1840 * Fill in the 'pad' and stream' value for each item in the array from1841 * the routing table1842 */1843 idx = 0;1844 1845 for_each_active_route(routing, route) {1846 new_configs.configs[idx].pad = route->sink_pad;1847 new_configs.configs[idx].stream = route->sink_stream;1848 1849 idx++;1850 1851 new_configs.configs[idx].pad = route->source_pad;1852 new_configs.configs[idx].stream = route->source_stream;1853 1854 idx++;1855 }1856 1857 kvfree(stream_configs->configs);1858 *stream_configs = new_configs;1859 1860 return 0;1861}1862 1863int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,1864 struct v4l2_subdev_format *format)1865{1866 struct v4l2_mbus_framefmt *fmt;1867 1868 fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);1869 if (!fmt)1870 return -EINVAL;1871 1872 format->format = *fmt;1873 1874 return 0;1875}1876EXPORT_SYMBOL_GPL(v4l2_subdev_get_fmt);1877 1878int v4l2_subdev_get_frame_interval(struct v4l2_subdev *sd,1879 struct v4l2_subdev_state *state,1880 struct v4l2_subdev_frame_interval *fi)1881{1882 struct v4l2_fract *interval;1883 1884 interval = v4l2_subdev_state_get_interval(state, fi->pad, fi->stream);1885 if (!interval)1886 return -EINVAL;1887 1888 fi->interval = *interval;1889 1890 return 0;1891}1892EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_interval);1893 1894int v4l2_subdev_set_routing(struct v4l2_subdev *sd,1895 struct v4l2_subdev_state *state,1896 const struct v4l2_subdev_krouting *routing)1897{1898 struct v4l2_subdev_krouting *dst = &state->routing;1899 const struct v4l2_subdev_krouting *src = routing;1900 struct v4l2_subdev_krouting new_routing = { 0 };1901 size_t bytes;1902 int r;1903 1904 if (unlikely(check_mul_overflow((size_t)src->num_routes,1905 sizeof(*src->routes), &bytes)))1906 return -EOVERFLOW;1907 1908 lockdep_assert_held(state->lock);1909 1910 if (src->num_routes > 0) {1911 new_routing.routes = kmemdup(src->routes, bytes, GFP_KERNEL);1912 if (!new_routing.routes)1913 return -ENOMEM;1914 }1915 1916 new_routing.num_routes = src->num_routes;1917 1918 r = v4l2_subdev_init_stream_configs(&state->stream_configs,1919 &new_routing);1920 if (r) {1921 kfree(new_routing.routes);1922 return r;1923 }1924 1925 kfree(dst->routes);1926 *dst = new_routing;1927 1928 return 0;1929}1930EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing);1931 1932struct v4l2_subdev_route *1933__v4l2_subdev_next_active_route(const struct v4l2_subdev_krouting *routing,1934 struct v4l2_subdev_route *route)1935{1936 if (route)1937 ++route;1938 else1939 route = &routing->routes[0];1940 1941 for (; route < routing->routes + routing->num_routes; ++route) {1942 if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))1943 continue;1944 1945 return route;1946 }1947 1948 return NULL;1949}1950EXPORT_SYMBOL_GPL(__v4l2_subdev_next_active_route);1951 1952int v4l2_subdev_set_routing_with_fmt(struct v4l2_subdev *sd,1953 struct v4l2_subdev_state *state,1954 const struct v4l2_subdev_krouting *routing,1955 const struct v4l2_mbus_framefmt *fmt)1956{1957 struct v4l2_subdev_stream_configs *stream_configs;1958 unsigned int i;1959 int ret;1960 1961 ret = v4l2_subdev_set_routing(sd, state, routing);1962 if (ret)1963 return ret;1964 1965 stream_configs = &state->stream_configs;1966 1967 for (i = 0; i < stream_configs->num_configs; ++i)1968 stream_configs->configs[i].fmt = *fmt;1969 1970 return 0;1971}1972EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing_with_fmt);1973 1974int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing,1975 u32 pad, u32 stream, u32 *other_pad,1976 u32 *other_stream)1977{1978 unsigned int i;1979 1980 for (i = 0; i < routing->num_routes; ++i) {1981 struct v4l2_subdev_route *route = &routing->routes[i];1982 1983 if (route->source_pad == pad &&1984 route->source_stream == stream) {1985 if (other_pad)1986 *other_pad = route->sink_pad;1987 if (other_stream)1988 *other_stream = route->sink_stream;1989 return 0;1990 }1991 1992 if (route->sink_pad == pad && route->sink_stream == stream) {1993 if (other_pad)1994 *other_pad = route->source_pad;1995 if (other_stream)1996 *other_stream = route->source_stream;1997 return 0;1998 }1999 }2000 2001 return -EINVAL;2002}2003EXPORT_SYMBOL_GPL(v4l2_subdev_routing_find_opposite_end);2004 2005struct v4l2_mbus_framefmt *2006v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state,2007 u32 pad, u32 stream)2008{2009 u32 other_pad, other_stream;2010 int ret;2011 2012 ret = v4l2_subdev_routing_find_opposite_end(&state->routing,2013 pad, stream,2014 &other_pad, &other_stream);2015 if (ret)2016 return NULL;2017 2018 return v4l2_subdev_state_get_format(state, other_pad, other_stream);2019}2020EXPORT_SYMBOL_GPL(v4l2_subdev_state_get_opposite_stream_format);2021 2022u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,2023 u32 pad0, u32 pad1, u64 *streams)2024{2025 const struct v4l2_subdev_krouting *routing = &state->routing;2026 struct v4l2_subdev_route *route;2027 u64 streams0 = 0;2028 u64 streams1 = 0;2029 2030 for_each_active_route(routing, route) {2031 if (route->sink_pad == pad0 && route->source_pad == pad1 &&2032 (*streams & BIT_ULL(route->sink_stream))) {2033 streams0 |= BIT_ULL(route->sink_stream);2034 streams1 |= BIT_ULL(route->source_stream);2035 }2036 if (route->source_pad == pad0 && route->sink_pad == pad1 &&2037 (*streams & BIT_ULL(route->source_stream))) {2038 streams0 |= BIT_ULL(route->source_stream);2039 streams1 |= BIT_ULL(route->sink_stream);2040 }2041 }2042 2043 *streams = streams0;2044 return streams1;2045}2046EXPORT_SYMBOL_GPL(v4l2_subdev_state_xlate_streams);2047 2048int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,2049 const struct v4l2_subdev_krouting *routing,2050 enum v4l2_subdev_routing_restriction disallow)2051{2052 u32 *remote_pads = NULL;2053 unsigned int i, j;2054 int ret = -EINVAL;2055 2056 if (disallow & (V4L2_SUBDEV_ROUTING_NO_STREAM_MIX |2057 V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING)) {2058 remote_pads = kcalloc(sd->entity.num_pads, sizeof(*remote_pads),2059 GFP_KERNEL);2060 if (!remote_pads)2061 return -ENOMEM;2062 2063 for (i = 0; i < sd->entity.num_pads; ++i)2064 remote_pads[i] = U32_MAX;2065 }2066 2067 for (i = 0; i < routing->num_routes; ++i) {2068 const struct v4l2_subdev_route *route = &routing->routes[i];2069 2070 /* Validate the sink and source pad numbers. */2071 if (route->sink_pad >= sd->entity.num_pads ||2072 !(sd->entity.pads[route->sink_pad].flags & MEDIA_PAD_FL_SINK)) {2073 dev_dbg(sd->dev, "route %u sink (%u) is not a sink pad\n",2074 i, route->sink_pad);2075 goto out;2076 }2077 2078 if (route->source_pad >= sd->entity.num_pads ||2079 !(sd->entity.pads[route->source_pad].flags & MEDIA_PAD_FL_SOURCE)) {2080 dev_dbg(sd->dev, "route %u source (%u) is not a source pad\n",2081 i, route->source_pad);2082 goto out;2083 }2084 2085 /*2086 * V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX: all streams from a2087 * sink pad must be routed to a single source pad.2088 */2089 if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX) {2090 if (remote_pads[route->sink_pad] != U32_MAX &&2091 remote_pads[route->sink_pad] != route->source_pad) {2092 dev_dbg(sd->dev,2093 "route %u attempts to mix %s streams\n",2094 i, "sink");2095 goto out;2096 }2097 }2098 2099 /*2100 * V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX: all streams on a2101 * source pad must originate from a single sink pad.2102 */2103 if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX) {2104 if (remote_pads[route->source_pad] != U32_MAX &&2105 remote_pads[route->source_pad] != route->sink_pad) {2106 dev_dbg(sd->dev,2107 "route %u attempts to mix %s streams\n",2108 i, "source");2109 goto out;2110 }2111 }2112 2113 /*2114 * V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING: Pads on the sink2115 * side can not do stream multiplexing, i.e. there can be only2116 * a single stream in a sink pad.2117 */2118 if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING) {2119 if (remote_pads[route->sink_pad] != U32_MAX) {2120 dev_dbg(sd->dev,2121 "route %u attempts to multiplex on %s pad %u\n",2122 i, "sink", route->sink_pad);2123 goto out;2124 }2125 }2126 2127 /*2128 * V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING: Pads on the2129 * source side can not do stream multiplexing, i.e. there can2130 * be only a single stream in a source pad.2131 */2132 if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING) {2133 if (remote_pads[route->source_pad] != U32_MAX) {2134 dev_dbg(sd->dev,2135 "route %u attempts to multiplex on %s pad %u\n",2136 i, "source", route->source_pad);2137 goto out;2138 }2139 }2140 2141 if (remote_pads) {2142 remote_pads[route->sink_pad] = route->source_pad;2143 remote_pads[route->source_pad] = route->sink_pad;2144 }2145 2146 for (j = i + 1; j < routing->num_routes; ++j) {2147 const struct v4l2_subdev_route *r = &routing->routes[j];2148 2149 /*2150 * V4L2_SUBDEV_ROUTING_NO_1_TO_N: No two routes can2151 * originate from the same (sink) stream.2152 */2153 if ((disallow & V4L2_SUBDEV_ROUTING_NO_1_TO_N) &&2154 route->sink_pad == r->sink_pad &&2155 route->sink_stream == r->sink_stream) {2156 dev_dbg(sd->dev,2157 "routes %u and %u originate from same sink (%u/%u)\n",2158 i, j, route->sink_pad,2159 route->sink_stream);2160 goto out;2161 }2162 2163 /*2164 * V4L2_SUBDEV_ROUTING_NO_N_TO_1: No two routes can end2165 * at the same (source) stream.2166 */2167 if ((disallow & V4L2_SUBDEV_ROUTING_NO_N_TO_1) &&2168 route->source_pad == r->source_pad &&2169 route->source_stream == r->source_stream) {2170 dev_dbg(sd->dev,2171 "routes %u and %u end at same source (%u/%u)\n",2172 i, j, route->source_pad,2173 route->source_stream);2174 goto out;2175 }2176 }2177 }2178 2179 ret = 0;2180 2181out:2182 kfree(remote_pads);2183 return ret;2184}2185EXPORT_SYMBOL_GPL(v4l2_subdev_routing_validate);2186 2187static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd,2188 struct v4l2_subdev_state *state,2189 u32 pad, u64 streams_mask,2190 u64 *found_streams,2191 u64 *enabled_streams)2192{2193 if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS)) {2194 *found_streams = BIT_ULL(0);2195 *enabled_streams =2196 (sd->enabled_pads & BIT_ULL(pad)) ? BIT_ULL(0) : 0;2197 return;2198 }2199 2200 *found_streams = 0;2201 *enabled_streams = 0;2202 2203 for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {2204 const struct v4l2_subdev_stream_config *cfg =2205 &state->stream_configs.configs[i];2206 2207 if (cfg->pad != pad || !(streams_mask & BIT_ULL(cfg->stream)))2208 continue;2209 2210 *found_streams |= BIT_ULL(cfg->stream);2211 if (cfg->enabled)2212 *enabled_streams |= BIT_ULL(cfg->stream);2213 }2214}2215 2216static void v4l2_subdev_set_streams_enabled(struct v4l2_subdev *sd,2217 struct v4l2_subdev_state *state,2218 u32 pad, u64 streams_mask,2219 bool enabled)2220{2221 if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS)) {2222 if (enabled)2223 sd->enabled_pads |= BIT_ULL(pad);2224 else2225 sd->enabled_pads &= ~BIT_ULL(pad);2226 return;2227 }2228 2229 for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {2230 struct v4l2_subdev_stream_config *cfg =2231 &state->stream_configs.configs[i];2232 2233 if (cfg->pad == pad && (streams_mask & BIT_ULL(cfg->stream)))2234 cfg->enabled = enabled;2235 }2236}2237 2238int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,2239 u64 streams_mask)2240{2241 struct device *dev = sd->entity.graph_obj.mdev->dev;2242 struct v4l2_subdev_state *state;2243 bool already_streaming;2244 u64 enabled_streams;2245 u64 found_streams;2246 bool use_s_stream;2247 int ret;2248 2249 /* A few basic sanity checks first. */2250 if (pad >= sd->entity.num_pads)2251 return -EINVAL;2252 2253 if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))2254 return -EOPNOTSUPP;2255 2256 /*2257 * We use a 64-bit bitmask for tracking enabled pads, so only subdevices2258 * with 64 pads or less can be supported.2259 */2260 if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)2261 return -EOPNOTSUPP;2262 2263 if (!streams_mask)2264 return 0;2265 2266 /* Fallback on .s_stream() if .enable_streams() isn't available. */2267 use_s_stream = !v4l2_subdev_has_op(sd, pad, enable_streams);2268 2269 if (!use_s_stream)2270 state = v4l2_subdev_lock_and_get_active_state(sd);2271 else2272 state = NULL;2273 2274 /*2275 * Verify that the requested streams exist and that they are not2276 * already enabled.2277 */2278 2279 v4l2_subdev_collect_streams(sd, state, pad, streams_mask,2280 &found_streams, &enabled_streams);2281 2282 if (found_streams != streams_mask) {2283 dev_dbg(dev, "streams 0x%llx not found on %s:%u\n",2284 streams_mask & ~found_streams, sd->entity.name, pad);2285 ret = -EINVAL;2286 goto done;2287 }2288 2289 if (enabled_streams) {2290 dev_dbg(dev, "streams 0x%llx already enabled on %s:%u\n",2291 enabled_streams, sd->entity.name, pad);2292 ret = -EALREADY;2293 goto done;2294 }2295 2296 dev_dbg(dev, "enable streams %u:%#llx\n", pad, streams_mask);2297 2298 already_streaming = v4l2_subdev_is_streaming(sd);2299 2300 if (!use_s_stream) {2301 /* Call the .enable_streams() operation. */2302 ret = v4l2_subdev_call(sd, pad, enable_streams, state, pad,2303 streams_mask);2304 } else {2305 /* Start streaming when the first pad is enabled. */2306 if (!already_streaming)2307 ret = v4l2_subdev_call(sd, video, s_stream, 1);2308 else2309 ret = 0;2310 }2311 2312 if (ret) {2313 dev_dbg(dev, "enable streams %u:%#llx failed: %d\n", pad,2314 streams_mask, ret);2315 goto done;2316 }2317 2318 /* Mark the streams as enabled. */2319 v4l2_subdev_set_streams_enabled(sd, state, pad, streams_mask, true);2320 2321 /*2322 * TODO: When all the drivers have been changed to use2323 * v4l2_subdev_enable_streams() and v4l2_subdev_disable_streams(),2324 * instead of calling .s_stream() operation directly, we can remove2325 * the privacy LED handling from call_s_stream() and do it here2326 * for all cases.2327 */2328 if (!use_s_stream && !already_streaming)2329 v4l2_subdev_enable_privacy_led(sd);2330 2331done:2332 if (!use_s_stream)2333 v4l2_subdev_unlock_state(state);2334 2335 return ret;2336}2337EXPORT_SYMBOL_GPL(v4l2_subdev_enable_streams);2338 2339int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad,2340 u64 streams_mask)2341{2342 struct device *dev = sd->entity.graph_obj.mdev->dev;2343 struct v4l2_subdev_state *state;2344 u64 enabled_streams;2345 u64 found_streams;2346 bool use_s_stream;2347 int ret;2348 2349 /* A few basic sanity checks first. */2350 if (pad >= sd->entity.num_pads)2351 return -EINVAL;2352 2353 if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))2354 return -EOPNOTSUPP;2355 2356 /*2357 * We use a 64-bit bitmask for tracking enabled pads, so only subdevices2358 * with 64 pads or less can be supported.2359 */2360 if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)2361 return -EOPNOTSUPP;2362 2363 if (!streams_mask)2364 return 0;2365 2366 /* Fallback on .s_stream() if .disable_streams() isn't available. */2367 use_s_stream = !v4l2_subdev_has_op(sd, pad, disable_streams);2368 2369 if (!use_s_stream)2370 state = v4l2_subdev_lock_and_get_active_state(sd);2371 else2372 state = NULL;2373 2374 /*2375 * Verify that the requested streams exist and that they are not2376 * already disabled.2377 */2378 2379 v4l2_subdev_collect_streams(sd, state, pad, streams_mask,2380 &found_streams, &enabled_streams);2381 2382 if (found_streams != streams_mask) {2383 dev_dbg(dev, "streams 0x%llx not found on %s:%u\n",2384 streams_mask & ~found_streams, sd->entity.name, pad);2385 ret = -EINVAL;2386 goto done;2387 }2388 2389 if (enabled_streams != streams_mask) {2390 dev_dbg(dev, "streams 0x%llx already disabled on %s:%u\n",2391 streams_mask & ~enabled_streams, sd->entity.name, pad);2392 ret = -EALREADY;2393 goto done;2394 }2395 2396 dev_dbg(dev, "disable streams %u:%#llx\n", pad, streams_mask);2397 2398 if (!use_s_stream) {2399 /* Call the .disable_streams() operation. */2400 ret = v4l2_subdev_call(sd, pad, disable_streams, state, pad,2401 streams_mask);2402 } else {2403 /* Stop streaming when the last streams are disabled. */2404 2405 if (!(sd->enabled_pads & ~BIT_ULL(pad)))2406 ret = v4l2_subdev_call(sd, video, s_stream, 0);2407 else2408 ret = 0;2409 }2410 2411 if (ret) {2412 dev_dbg(dev, "disable streams %u:%#llx failed: %d\n", pad,2413 streams_mask, ret);2414 goto done;2415 }2416 2417 v4l2_subdev_set_streams_enabled(sd, state, pad, streams_mask, false);2418 2419done:2420 if (!use_s_stream) {2421 if (!v4l2_subdev_is_streaming(sd))2422 v4l2_subdev_disable_privacy_led(sd);2423 2424 v4l2_subdev_unlock_state(state);2425 }2426 2427 return ret;2428}2429EXPORT_SYMBOL_GPL(v4l2_subdev_disable_streams);2430 2431int v4l2_subdev_s_stream_helper(struct v4l2_subdev *sd, int enable)2432{2433 struct v4l2_subdev_state *state;2434 struct v4l2_subdev_route *route;2435 struct media_pad *pad;2436 u64 source_mask = 0;2437 int pad_index = -1;2438 2439 /*2440 * Find the source pad. This helper is meant for subdevs that have a2441 * single source pad, so failures shouldn't happen, but catch them2442 * loudly nonetheless as they indicate a driver bug.2443 */2444 media_entity_for_each_pad(&sd->entity, pad) {2445 if (pad->flags & MEDIA_PAD_FL_SOURCE) {2446 pad_index = pad->index;2447 break;2448 }2449 }2450 2451 if (WARN_ON(pad_index == -1))2452 return -EINVAL;2453 2454 if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {2455 /*2456 * As there's a single source pad, just collect all the source2457 * streams.2458 */2459 state = v4l2_subdev_lock_and_get_active_state(sd);2460 2461 for_each_active_route(&state->routing, route)2462 source_mask |= BIT_ULL(route->source_stream);2463 2464 v4l2_subdev_unlock_state(state);2465 } else {2466 /*2467 * For non-streams subdevices, there's a single implicit stream2468 * per pad.2469 */2470 source_mask = BIT_ULL(0);2471 }2472 2473 if (enable)2474 return v4l2_subdev_enable_streams(sd, pad_index, source_mask);2475 else2476 return v4l2_subdev_disable_streams(sd, pad_index, source_mask);2477}2478EXPORT_SYMBOL_GPL(v4l2_subdev_s_stream_helper);2479 2480#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */2481 2482#endif /* CONFIG_MEDIA_CONTROLLER */2483 2484void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)2485{2486 INIT_LIST_HEAD(&sd->list);2487 BUG_ON(!ops);2488 sd->ops = ops;2489 sd->v4l2_dev = NULL;2490 sd->flags = 0;2491 sd->name[0] = '\0';2492 sd->grp_id = 0;2493 sd->dev_priv = NULL;2494 sd->host_priv = NULL;2495 sd->privacy_led = NULL;2496 INIT_LIST_HEAD(&sd->async_subdev_endpoint_list);2497#if defined(CONFIG_MEDIA_CONTROLLER)2498 sd->entity.name = sd->name;2499 sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;2500 sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;2501#endif2502}2503EXPORT_SYMBOL(v4l2_subdev_init);2504 2505void v4l2_subdev_notify_event(struct v4l2_subdev *sd,2506 const struct v4l2_event *ev)2507{2508 v4l2_event_queue(sd->devnode, ev);2509 v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, (void *)ev);2510}2511EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event);2512 2513bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd)2514{2515 struct v4l2_subdev_state *state;2516 2517 if (!v4l2_subdev_has_op(sd, pad, enable_streams))2518 return sd->s_stream_enabled;2519 2520 if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))2521 return !!sd->enabled_pads;2522 2523 state = v4l2_subdev_get_locked_active_state(sd);2524 2525 for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {2526 const struct v4l2_subdev_stream_config *cfg;2527 2528 cfg = &state->stream_configs.configs[i];2529 2530 if (cfg->enabled)2531 return true;2532 }2533 2534 return false;2535}2536EXPORT_SYMBOL_GPL(v4l2_subdev_is_streaming);2537 2538int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd)2539{2540#if IS_REACHABLE(CONFIG_LEDS_CLASS)2541 sd->privacy_led = led_get(sd->dev, "privacy-led");2542 if (IS_ERR(sd->privacy_led) && PTR_ERR(sd->privacy_led) != -ENOENT)2543 return dev_err_probe(sd->dev, PTR_ERR(sd->privacy_led),2544 "getting privacy LED\n");2545 2546 if (!IS_ERR_OR_NULL(sd->privacy_led)) {2547 mutex_lock(&sd->privacy_led->led_access);2548 led_sysfs_disable(sd->privacy_led);2549 led_trigger_remove(sd->privacy_led);2550 led_set_brightness(sd->privacy_led, 0);2551 mutex_unlock(&sd->privacy_led->led_access);2552 }2553#endif2554 return 0;2555}2556EXPORT_SYMBOL_GPL(v4l2_subdev_get_privacy_led);2557 2558void v4l2_subdev_put_privacy_led(struct v4l2_subdev *sd)2559{2560#if IS_REACHABLE(CONFIG_LEDS_CLASS)2561 if (!IS_ERR_OR_NULL(sd->privacy_led)) {2562 mutex_lock(&sd->privacy_led->led_access);2563 led_sysfs_enable(sd->privacy_led);2564 mutex_unlock(&sd->privacy_led->led_access);2565 led_put(sd->privacy_led);2566 }2567#endif2568}2569EXPORT_SYMBOL_GPL(v4l2_subdev_put_privacy_led);2570