linux/drivers/media/v4l2-core/v4l2-subdev.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * V4L2 sub-device
 *
 * Copyright (C) 2010 Nokia Corporation
 *
 * Contact: Laurent Pinchart <[email protected]>
 *	    Sakari Ailus <[email protected]>
 */

#include <linux/export.h>
#include <linux/ioctl.h>
#include <linux/leds.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/videodev2.h>

#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
/*
 * The Streams API is an experimental feature. To use the Streams API, set
 * 'v4l2_subdev_enable_streams_api' to 1 below.
 */

static bool v4l2_subdev_enable_streams_api;
#endif

/*
 * Maximum stream ID is 63 for now, as we use u64 bitmask to represent a set
 * of streams.
 *
 * Note that V4L2_FRAME_DESC_ENTRY_MAX is related: V4L2_FRAME_DESC_ENTRY_MAX
 * restricts the total number of streams in a pad, although the stream ID is
 * not restricted.
 */
#define V4L2_SUBDEV_MAX_STREAM_ID

#include "v4l2-subdev-priv.h"

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
{}

static void subdev_fh_free(struct v4l2_subdev_fh *fh)
{}

static int subdev_open(struct file *file)
{}

static int subdev_close(struct file *file)
{}
#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */
static int subdev_open(struct file *file)
{
	return -ENODEV;
}

static int subdev_close(struct file *file)
{
	return -ENODEV;
}
#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */

static void v4l2_subdev_enable_privacy_led(struct v4l2_subdev *sd)
{}

static void v4l2_subdev_disable_privacy_led(struct v4l2_subdev *sd)
{}

static inline int check_which(u32 which)
{}

static inline int check_pad(struct v4l2_subdev *sd, u32 pad)
{}

static int check_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,
		       u32 which, u32 pad, u32 stream)
{}

static inline int check_format(struct v4l2_subdev *sd,
			       struct v4l2_subdev_state *state,
			       struct v4l2_subdev_format *format)
{}

static int call_get_fmt(struct v4l2_subdev *sd,
			struct v4l2_subdev_state *state,
			struct v4l2_subdev_format *format)
{}

static int call_set_fmt(struct v4l2_subdev *sd,
			struct v4l2_subdev_state *state,
			struct v4l2_subdev_format *format)
{}

static int call_enum_mbus_code(struct v4l2_subdev *sd,
			       struct v4l2_subdev_state *state,
			       struct v4l2_subdev_mbus_code_enum *code)
{}

static int call_enum_frame_size(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *state,
				struct v4l2_subdev_frame_size_enum *fse)
{}

static int call_enum_frame_interval(struct v4l2_subdev *sd,
				    struct v4l2_subdev_state *state,
				    struct v4l2_subdev_frame_interval_enum *fie)
{}

static inline int check_selection(struct v4l2_subdev *sd,
				  struct v4l2_subdev_state *state,
				  struct v4l2_subdev_selection *sel)
{}

static int call_get_selection(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *state,
			      struct v4l2_subdev_selection *sel)
{}

static int call_set_selection(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *state,
			      struct v4l2_subdev_selection *sel)
{}

static inline int check_frame_interval(struct v4l2_subdev *sd,
				       struct v4l2_subdev_state *state,
				       struct v4l2_subdev_frame_interval *fi)
{}

static int call_get_frame_interval(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *state,
				   struct v4l2_subdev_frame_interval *fi)
{}

static int call_set_frame_interval(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *state,
				   struct v4l2_subdev_frame_interval *fi)
{}

static int call_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
			       struct v4l2_mbus_frame_desc *fd)
{}

static inline int check_edid(struct v4l2_subdev *sd,
			     struct v4l2_subdev_edid *edid)
{}

static int call_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
{}

static int call_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
{}

static int call_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
			     struct v4l2_dv_timings *timings)
{}

static int call_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
			     struct v4l2_dv_timings *timings)
{}

static int call_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,
				 struct v4l2_dv_timings *timings)
{}

static int call_dv_timings_cap(struct v4l2_subdev *sd,
			       struct v4l2_dv_timings_cap *cap)
{}

static int call_enum_dv_timings(struct v4l2_subdev *sd,
				struct v4l2_enum_dv_timings *dvt)
{}

static int call_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_mbus_config *config)
{}

static int call_s_stream(struct v4l2_subdev *sd, int enable)
{}

#ifdef CONFIG_MEDIA_CONTROLLER
/*
 * Create state-management wrapper for pad ops dealing with subdev state. The
 * wrapper handles the case where the caller does not provide the called
 * subdev's state. This should be removed when all the callers are fixed.
 */
#define DEFINE_STATE_WRAPPER(f, arg_type)

#else /* CONFIG_MEDIA_CONTROLLER */

#define DEFINE_STATE_WRAPPER

#endif /* CONFIG_MEDIA_CONTROLLER */

DEFINE_STATE_WRAPPER(get_fmt, struct v4l2_subdev_format);
DEFINE_STATE_WRAPPER(set_fmt, struct v4l2_subdev_format);
DEFINE_STATE_WRAPPER(enum_mbus_code, struct v4l2_subdev_mbus_code_enum);
DEFINE_STATE_WRAPPER(enum_frame_size, struct v4l2_subdev_frame_size_enum);
DEFINE_STATE_WRAPPER(enum_frame_interval, struct v4l2_subdev_frame_interval_enum);
DEFINE_STATE_WRAPPER(get_selection, struct v4l2_subdev_selection);
DEFINE_STATE_WRAPPER(set_selection, struct v4l2_subdev_selection);

static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers =;

static const struct v4l2_subdev_video_ops v4l2_subdev_call_video_wrappers =;

const struct v4l2_subdev_ops v4l2_subdev_call_wrappers =;
EXPORT_SYMBOL();

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)

static struct v4l2_subdev_state *
subdev_ioctl_get_state(struct v4l2_subdev *sd, struct v4l2_subdev_fh *subdev_fh,
		       unsigned int cmd, void *arg)
{}

static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,
			    struct v4l2_subdev_state *state)
{}

static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg)
{}

static long subdev_ioctl(struct file *file, unsigned int cmd,
	unsigned long arg)
{}

#ifdef CONFIG_COMPAT
static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,
	unsigned long arg)
{}
#endif

#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */
static long subdev_ioctl(struct file *file, unsigned int cmd,
			 unsigned long arg)
{
	return -ENODEV;
}

#ifdef CONFIG_COMPAT
static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	return -ENODEV;
}
#endif
#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */

static __poll_t subdev_poll(struct file *file, poll_table *wait)
{}

const struct v4l2_file_operations v4l2_subdev_fops =;

#ifdef CONFIG_MEDIA_CONTROLLER

int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity,
				      struct fwnode_endpoint *endpoint)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
				      struct media_link *link,
				      struct v4l2_subdev_format *source_fmt,
				      struct v4l2_subdev_format *sink_fmt)
{}
EXPORT_SYMBOL_GPL();

static int
v4l2_subdev_link_validate_get_format(struct media_pad *pad, u32 stream,
				     struct v4l2_subdev_format *fmt,
				     bool states_locked)
{}

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)

static void __v4l2_link_validate_get_streams(struct media_pad *pad,
					     u64 *streams_mask,
					     bool states_locked)
{}

#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */

static void v4l2_link_validate_get_streams(struct media_pad *pad,
					   u64 *streams_mask,
					   bool states_locked)
{}

static int v4l2_subdev_link_validate_locked(struct media_link *link, bool states_locked)
{}

int v4l2_subdev_link_validate(struct media_link *link)
{}
EXPORT_SYMBOL_GPL();

bool v4l2_subdev_has_pad_interdep(struct media_entity *entity,
				  unsigned int pad0, unsigned int pad1)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_subdev_state *
__v4l2_subdev_state_alloc(struct v4l2_subdev *sd, const char *lock_name,
			  struct lock_class_key *lock_key)
{}
EXPORT_SYMBOL_GPL();

void __v4l2_subdev_state_free(struct v4l2_subdev_state *state)
{}
EXPORT_SYMBOL_GPL();

int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name,
				struct lock_class_key *key)
{}
EXPORT_SYMBOL_GPL();

void v4l2_subdev_cleanup(struct v4l2_subdev *sd)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_mbus_framefmt *
__v4l2_subdev_state_get_format(struct v4l2_subdev_state *state,
			       unsigned int pad, u32 stream)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_rect *
__v4l2_subdev_state_get_crop(struct v4l2_subdev_state *state, unsigned int pad,
			     u32 stream)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_rect *
__v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,
				unsigned int pad, u32 stream)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_fract *
__v4l2_subdev_state_get_interval(struct v4l2_subdev_state *state,
				 unsigned int pad, u32 stream)
{}
EXPORT_SYMBOL_GPL();

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)

static int
v4l2_subdev_init_stream_configs(struct v4l2_subdev_stream_configs *stream_configs,
				const struct v4l2_subdev_krouting *routing)
{}

int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,
			struct v4l2_subdev_format *format)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_get_frame_interval(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *state,
				   struct v4l2_subdev_frame_interval *fi)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_set_routing(struct v4l2_subdev *sd,
			    struct v4l2_subdev_state *state,
			    const struct v4l2_subdev_krouting *routing)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_subdev_route *
__v4l2_subdev_next_active_route(const struct v4l2_subdev_krouting *routing,
				struct v4l2_subdev_route *route)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_set_routing_with_fmt(struct v4l2_subdev *sd,
				     struct v4l2_subdev_state *state,
				     const struct v4l2_subdev_krouting *routing,
				     const struct v4l2_mbus_framefmt *fmt)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing,
					  u32 pad, u32 stream, u32 *other_pad,
					  u32 *other_stream)
{}
EXPORT_SYMBOL_GPL();

struct v4l2_mbus_framefmt *
v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state,
					     u32 pad, u32 stream)
{}
EXPORT_SYMBOL_GPL();

u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,
				    u32 pad0, u32 pad1, u64 *streams)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
				 const struct v4l2_subdev_krouting *routing,
				 enum v4l2_subdev_routing_restriction disallow)
{}
EXPORT_SYMBOL_GPL();

static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd,
					struct v4l2_subdev_state *state,
					u32 pad, u64 streams_mask,
					u64 *found_streams,
					u64 *enabled_streams)
{}

static void v4l2_subdev_set_streams_enabled(struct v4l2_subdev *sd,
					    struct v4l2_subdev_state *state,
					    u32 pad, u64 streams_mask,
					    bool enabled)
{}

int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,
			       u64 streams_mask)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad,
				u64 streams_mask)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_s_stream_helper(struct v4l2_subdev *sd, int enable)
{}
EXPORT_SYMBOL_GPL();

#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */

#endif /* CONFIG_MEDIA_CONTROLLER */

void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
{}
EXPORT_SYMBOL();

void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
			      const struct v4l2_event *ev)
{}
EXPORT_SYMBOL_GPL();

bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd)
{}
EXPORT_SYMBOL_GPL();

int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd)
{}
EXPORT_SYMBOL_GPL();

void v4l2_subdev_put_privacy_led(struct v4l2_subdev *sd)
{}
EXPORT_SYMBOL_GPL();