v4.19.13 snapshot.
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h
new file mode 100644
index 0000000..814eeef
--- /dev/null
+++ b/include/media/cec-notifier.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * cec-notifier.h - notify CEC drivers of physical address changes
+ *
+ * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk>
+ * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef LINUX_CEC_NOTIFIER_H
+#define LINUX_CEC_NOTIFIER_H
+
+#include <linux/types.h>
+#include <media/cec.h>
+
+struct device;
+struct edid;
+struct cec_adapter;
+struct cec_notifier;
+
+#if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
+
+/**
+ * cec_notifier_get_conn - find or create a new cec_notifier for the given
+ * device and connector tuple.
+ * @dev: device that sends the events.
+ * @conn: the connector name from which the event occurs
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+					   const char *conn);
+
+/**
+ * cec_notifier_put - decrease refcount and delete when the refcount reaches 0.
+ * @n: notifier
+ */
+void cec_notifier_put(struct cec_notifier *n);
+
+/**
+ * cec_notifier_set_phys_addr - set a new physical address.
+ * @n: the CEC notifier
+ * @pa: the CEC physical address
+ *
+ * Set a new CEC physical address.
+ * Does nothing if @n == NULL.
+ */
+void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa);
+
+/**
+ * cec_notifier_set_phys_addr_from_edid - set parse the PA from the EDID.
+ * @n: the CEC notifier
+ * @edid: the struct edid pointer
+ *
+ * Parses the EDID to obtain the new CEC physical address and set it.
+ * Does nothing if @n == NULL.
+ */
+void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
+					  const struct edid *edid);
+
+/**
+ * cec_notifier_register - register a callback with the notifier
+ * @n: the CEC notifier
+ * @adap: the CEC adapter, passed as argument to the callback function
+ * @callback: the callback function
+ */
+void cec_notifier_register(struct cec_notifier *n,
+			   struct cec_adapter *adap,
+			   void (*callback)(struct cec_adapter *adap, u16 pa));
+
+/**
+ * cec_notifier_unregister - unregister the callback from the notifier.
+ * @n: the CEC notifier
+ */
+void cec_notifier_unregister(struct cec_notifier *n);
+
+/**
+ * cec_register_cec_notifier - register the notifier with the cec adapter.
+ * @adap: the CEC adapter
+ * @notifier: the CEC notifier
+ */
+void cec_register_cec_notifier(struct cec_adapter *adap,
+			       struct cec_notifier *notifier);
+
+#else
+static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev,
+							 const char *conn)
+{
+	/* A non-NULL pointer is expected on success */
+	return (struct cec_notifier *)0xdeadfeed;
+}
+
+static inline void cec_notifier_put(struct cec_notifier *n)
+{
+}
+
+static inline void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
+{
+}
+
+static inline void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
+							const struct edid *edid)
+{
+}
+
+static inline void cec_notifier_register(struct cec_notifier *n,
+			 struct cec_adapter *adap,
+			 void (*callback)(struct cec_adapter *adap, u16 pa))
+{
+}
+
+static inline void cec_notifier_unregister(struct cec_notifier *n)
+{
+}
+
+static inline void cec_register_cec_notifier(struct cec_adapter *adap,
+					     struct cec_notifier *notifier)
+{
+}
+#endif
+
+/**
+ * cec_notifier_get - find or create a new cec_notifier for the given device.
+ * @dev: device that sends the events.
+ *
+ * If a notifier for device @dev already exists, then increase the refcount
+ * and return that notifier.
+ *
+ * If it doesn't exist, then allocate a new notifier struct and return a
+ * pointer to that new struct.
+ *
+ * Return NULL if the memory could not be allocated.
+ */
+static inline struct cec_notifier *cec_notifier_get(struct device *dev)
+{
+	return cec_notifier_get_conn(dev, NULL);
+}
+
+/**
+ * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
+ *
+ * @n: the CEC notifier
+ *
+ * This is a simple helper function to invalidate the physical
+ * address. Does nothing if @n == NULL.
+ */
+static inline void cec_notifier_phys_addr_invalidate(struct cec_notifier *n)
+{
+	cec_notifier_set_phys_addr(n, CEC_PHYS_ADDR_INVALID);
+}
+
+#endif
diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h
new file mode 100644
index 0000000..604e79c
--- /dev/null
+++ b/include/media/cec-pin.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * cec-pin.h - low-level CEC pin control
+ *
+ * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef LINUX_CEC_PIN_H
+#define LINUX_CEC_PIN_H
+
+#include <linux/types.h>
+#include <media/cec.h>
+
+/**
+ * struct cec_pin_ops - low-level CEC pin operations
+ * @read:	read the CEC pin. Return true if high, false if low.
+ * @low:	drive the CEC pin low.
+ * @high:	stop driving the CEC pin. The pull-up will drive the pin
+ *		high, unless someone else is driving the pin low.
+ * @enable_irq:	optional, enable the interrupt to detect pin voltage changes.
+ * @disable_irq: optional, disable the interrupt.
+ * @free:	optional. Free any allocated resources. Called when the
+ *		adapter is deleted.
+ * @status:	optional, log status information.
+ * @read_hpd:	read the HPD pin. Return true if high, false if low or
+ *		an error if negative. If NULL or -ENOTTY is returned,
+ *		then this is not supported.
+ * @read_5v:	read the 5V pin. Return true if high, false if low or
+ *		an error if negative. If NULL or -ENOTTY is returned,
+ *		then this is not supported.
+ *
+ * These operations are used by the cec pin framework to manipulate
+ * the CEC pin.
+ */
+struct cec_pin_ops {
+	bool (*read)(struct cec_adapter *adap);
+	void (*low)(struct cec_adapter *adap);
+	void (*high)(struct cec_adapter *adap);
+	bool (*enable_irq)(struct cec_adapter *adap);
+	void (*disable_irq)(struct cec_adapter *adap);
+	void (*free)(struct cec_adapter *adap);
+	void (*status)(struct cec_adapter *adap, struct seq_file *file);
+	int  (*read_hpd)(struct cec_adapter *adap);
+	int  (*read_5v)(struct cec_adapter *adap);
+};
+
+/**
+ * cec_pin_changed() - update pin state from interrupt
+ *
+ * @adap:	pointer to the cec adapter
+ * @value:	when true the pin is high, otherwise it is low
+ *
+ * If changes of the CEC voltage are detected via an interrupt, then
+ * cec_pin_changed is called from the interrupt with the new value.
+ */
+void cec_pin_changed(struct cec_adapter *adap, bool value);
+
+/**
+ * cec_pin_allocate_adapter() - allocate a pin-based cec adapter
+ *
+ * @pin_ops:	low-level pin operations
+ * @priv:	will be stored in adap->priv and can be used by the adapter ops.
+ *		Use cec_get_drvdata(adap) to get the priv pointer.
+ * @name:	the name of the CEC adapter. Note: this name will be copied.
+ * @caps:	capabilities of the CEC adapter. This will be ORed with
+ *		CEC_CAP_MONITOR_ALL and CEC_CAP_MONITOR_PIN.
+ *
+ * Allocate a cec adapter using the cec pin framework.
+ *
+ * Return: a pointer to the cec adapter or an error pointer
+ */
+struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
+					void *priv, const char *name, u32 caps);
+
+#endif
diff --git a/include/media/cec.h b/include/media/cec.h
new file mode 100644
index 0000000..9b7394a
--- /dev/null
+++ b/include/media/cec.h
@@ -0,0 +1,534 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * cec - HDMI Consumer Electronics Control support header
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _MEDIA_CEC_H
+#define _MEDIA_CEC_H
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/kthread.h>
+#include <linux/timer.h>
+#include <linux/cec-funcs.h>
+#include <media/rc-core.h>
+#include <media/cec-notifier.h>
+
+#define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
+			  CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
+
+/**
+ * struct cec_devnode - cec device node
+ * @dev:	cec device
+ * @cdev:	cec character device
+ * @minor:	device node minor number
+ * @registered:	the device was correctly registered
+ * @unregistered: the device was unregistered
+ * @fhs_lock:	lock to control access to the filehandle list
+ * @fhs:	the list of open filehandles (cec_fh)
+ *
+ * This structure represents a cec-related device node.
+ *
+ * The @parent is a physical device. It must be set by core or device drivers
+ * before registering the node.
+ */
+struct cec_devnode {
+	/* sysfs */
+	struct device dev;
+	struct cdev cdev;
+
+	/* device info */
+	int minor;
+	bool registered;
+	bool unregistered;
+	struct list_head fhs;
+	struct mutex lock;
+};
+
+struct cec_adapter;
+struct cec_data;
+struct cec_pin;
+
+struct cec_data {
+	struct list_head list;
+	struct list_head xfer_list;
+	struct cec_adapter *adap;
+	struct cec_msg msg;
+	struct cec_fh *fh;
+	struct delayed_work work;
+	struct completion c;
+	u8 attempts;
+	bool blocking;
+	bool completed;
+};
+
+struct cec_msg_entry {
+	struct list_head	list;
+	struct cec_msg		msg;
+};
+
+struct cec_event_entry {
+	struct list_head	list;
+	struct cec_event	ev;
+};
+
+#define CEC_NUM_CORE_EVENTS 2
+#define CEC_NUM_EVENTS CEC_EVENT_PIN_5V_HIGH
+
+struct cec_fh {
+	struct list_head	list;
+	struct list_head	xfer_list;
+	struct cec_adapter	*adap;
+	u8			mode_initiator;
+	u8			mode_follower;
+
+	/* Events */
+	wait_queue_head_t	wait;
+	struct mutex		lock;
+	struct list_head	events[CEC_NUM_EVENTS]; /* queued events */
+	u16			queued_events[CEC_NUM_EVENTS];
+	unsigned int		total_queued_events;
+	struct cec_event_entry	core_events[CEC_NUM_CORE_EVENTS];
+	struct list_head	msgs; /* queued messages */
+	unsigned int		queued_msgs;
+};
+
+#define CEC_SIGNAL_FREE_TIME_RETRY		3
+#define CEC_SIGNAL_FREE_TIME_NEW_INITIATOR	5
+#define CEC_SIGNAL_FREE_TIME_NEXT_XFER		7
+
+/* The nominal data bit period is 2.4 ms */
+#define CEC_FREE_TIME_TO_USEC(ft)		((ft) * 2400)
+
+struct cec_adap_ops {
+	/* Low-level callbacks */
+	int (*adap_enable)(struct cec_adapter *adap, bool enable);
+	int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+	int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
+	int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
+	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
+			     u32 signal_free_time, struct cec_msg *msg);
+	void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+	void (*adap_free)(struct cec_adapter *adap);
+
+	/* Error injection callbacks */
+	int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
+	bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
+
+	/* High-level CEC message callback */
+	int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
+};
+
+/*
+ * The minimum message length you can receive (excepting poll messages) is 2.
+ * With a transfer rate of at most 36 bytes per second this makes 18 messages
+ * per second worst case.
+ *
+ * We queue at most 3 seconds worth of received messages. The CEC specification
+ * requires that messages are replied to within a second, so 3 seconds should
+ * give more than enough margin. Since most messages are actually more than 2
+ * bytes, this is in practice a lot more than 3 seconds.
+ */
+#define CEC_MAX_MSG_RX_QUEUE_SZ		(18 * 3)
+
+/*
+ * The transmit queue is limited to 1 second worth of messages (worst case).
+ * Messages can be transmitted by userspace and kernel space. But for both it
+ * makes no sense to have a lot of messages queued up. One second seems
+ * reasonable.
+ */
+#define CEC_MAX_MSG_TX_QUEUE_SZ		(18 * 1)
+
+struct cec_adapter {
+	struct module *owner;
+	char name[32];
+	struct cec_devnode devnode;
+	struct mutex lock;
+	struct rc_dev *rc;
+
+	struct list_head transmit_queue;
+	unsigned int transmit_queue_sz;
+	struct list_head wait_queue;
+	struct cec_data *transmitting;
+
+	struct task_struct *kthread_config;
+	struct completion config_completion;
+
+	struct task_struct *kthread;
+	wait_queue_head_t kthread_waitq;
+	wait_queue_head_t waitq;
+
+	const struct cec_adap_ops *ops;
+	void *priv;
+	u32 capabilities;
+	u8 available_log_addrs;
+
+	u16 phys_addr;
+	bool needs_hpd;
+	bool is_configuring;
+	bool is_configured;
+	bool cec_pin_is_high;
+	u8 last_initiator;
+	u32 monitor_all_cnt;
+	u32 monitor_pin_cnt;
+	u32 follower_cnt;
+	struct cec_fh *cec_follower;
+	struct cec_fh *cec_initiator;
+	bool passthrough;
+	struct cec_log_addrs log_addrs;
+
+	u32 tx_timeouts;
+
+#ifdef CONFIG_CEC_NOTIFIER
+	struct cec_notifier *notifier;
+#endif
+#ifdef CONFIG_CEC_PIN
+	struct cec_pin *pin;
+#endif
+
+	struct dentry *cec_dir;
+	struct dentry *status_file;
+	struct dentry *error_inj_file;
+
+	u16 phys_addrs[15];
+	u32 sequence;
+
+	char device_name[32];
+	char input_phys[32];
+	char input_drv[32];
+};
+
+static inline void *cec_get_drvdata(const struct cec_adapter *adap)
+{
+	return adap->priv;
+}
+
+static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr)
+{
+	return adap->log_addrs.log_addr_mask & (1 << log_addr);
+}
+
+static inline bool cec_is_sink(const struct cec_adapter *adap)
+{
+	return adap->phys_addr == 0;
+}
+
+/**
+ * cec_is_registered() - is the CEC adapter registered?
+ *
+ * @adap:	the CEC adapter, may be NULL.
+ *
+ * Return: true if the adapter is registered, false otherwise.
+ */
+static inline bool cec_is_registered(const struct cec_adapter *adap)
+{
+	return adap && adap->devnode.registered;
+}
+
+#define cec_phys_addr_exp(pa) \
+	((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
+
+struct edid;
+
+#if IS_REACHABLE(CONFIG_CEC_CORE)
+struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
+		void *priv, const char *name, u32 caps, u8 available_las);
+int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
+void cec_unregister_adapter(struct cec_adapter *adap);
+void cec_delete_adapter(struct cec_adapter *adap);
+
+int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs,
+		    bool block);
+void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
+		     bool block);
+void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+			       const struct edid *edid);
+int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
+		     bool block);
+
+/* Called by the adapter */
+void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
+			  u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
+			  u8 error_cnt, ktime_t ts);
+
+static inline void cec_transmit_done(struct cec_adapter *adap, u8 status,
+				     u8 arb_lost_cnt, u8 nack_cnt,
+				     u8 low_drive_cnt, u8 error_cnt)
+{
+	cec_transmit_done_ts(adap, status, arb_lost_cnt, nack_cnt,
+			     low_drive_cnt, error_cnt, ktime_get());
+}
+/*
+ * Simplified version of cec_transmit_done for hardware that doesn't retry
+ * failed transmits. So this is always just one attempt in which case
+ * the status is sufficient.
+ */
+void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
+				  u8 status, ktime_t ts);
+
+static inline void cec_transmit_attempt_done(struct cec_adapter *adap,
+					     u8 status)
+{
+	cec_transmit_attempt_done_ts(adap, status, ktime_get());
+}
+
+void cec_received_msg_ts(struct cec_adapter *adap,
+			 struct cec_msg *msg, ktime_t ts);
+
+static inline void cec_received_msg(struct cec_adapter *adap,
+				    struct cec_msg *msg)
+{
+	cec_received_msg_ts(adap, msg, ktime_get());
+}
+
+/**
+ * cec_queue_pin_cec_event() - queue a CEC pin event with a given timestamp.
+ *
+ * @adap:	pointer to the cec adapter
+ * @is_high:	when true the CEC pin is high, otherwise it is low
+ * @dropped_events: when true some events were dropped
+ * @ts:		the timestamp for this event
+ *
+ */
+void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
+			     bool dropped_events, ktime_t ts);
+
+/**
+ * cec_queue_pin_hpd_event() - queue a pin event with a given timestamp.
+ *
+ * @adap:	pointer to the cec adapter
+ * @is_high:	when true the HPD pin is high, otherwise it is low
+ * @ts:		the timestamp for this event
+ *
+ */
+void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
+
+/**
+ * cec_queue_pin_5v_event() - queue a pin event with a given timestamp.
+ *
+ * @adap:	pointer to the cec adapter
+ * @is_high:	when true the 5V pin is high, otherwise it is low
+ * @ts:		the timestamp for this event
+ *
+ */
+void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
+
+/**
+ * cec_get_edid_phys_addr() - find and return the physical address
+ *
+ * @edid:	pointer to the EDID data
+ * @size:	size in bytes of the EDID data
+ * @offset:	If not %NULL then the location of the physical address
+ *		bytes in the EDID will be returned here. This is set to 0
+ *		if there is no physical address found.
+ *
+ * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none.
+ */
+u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
+			   unsigned int *offset);
+
+/**
+ * cec_set_edid_phys_addr() - find and set the physical address
+ *
+ * @edid:	pointer to the EDID data
+ * @size:	size in bytes of the EDID data
+ * @phys_addr:	the new physical address
+ *
+ * This function finds the location of the physical address in the EDID
+ * and fills in the given physical address and updates the checksum
+ * at the end of the EDID block. It does nothing if the EDID doesn't
+ * contain a physical address.
+ */
+void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr);
+
+/**
+ * cec_phys_addr_for_input() - calculate the PA for an input
+ *
+ * @phys_addr:	the physical address of the parent
+ * @input:	the number of the input port, must be between 1 and 15
+ *
+ * This function calculates a new physical address based on the input
+ * port number. For example:
+ *
+ * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0
+ *
+ * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0
+ *
+ * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5
+ *
+ * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth.
+ *
+ * Return: the new physical address or CEC_PHYS_ADDR_INVALID.
+ */
+u16 cec_phys_addr_for_input(u16 phys_addr, u8 input);
+
+/**
+ * cec_phys_addr_validate() - validate a physical address from an EDID
+ *
+ * @phys_addr:	the physical address to validate
+ * @parent:	if not %NULL, then this is filled with the parents PA.
+ * @port:	if not %NULL, then this is filled with the input port.
+ *
+ * This validates a physical address as read from an EDID. If the
+ * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end),
+ * then it will return -EINVAL.
+ *
+ * The parent PA is passed into %parent and the input port is passed into
+ * %port. For example:
+ *
+ * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0.
+ *
+ * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1.
+ *
+ * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2.
+ *
+ * PA = f.f.f.f: has parent f.f.f.f and input port 0.
+ *
+ * Return: 0 if the PA is valid, -EINVAL if not.
+ */
+int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
+
+#else
+
+static inline int cec_register_adapter(struct cec_adapter *adap,
+				       struct device *parent)
+{
+	return 0;
+}
+
+static inline void cec_unregister_adapter(struct cec_adapter *adap)
+{
+}
+
+static inline void cec_delete_adapter(struct cec_adapter *adap)
+{
+}
+
+static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
+				   bool block)
+{
+}
+
+static inline void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+					     const struct edid *edid)
+{
+}
+
+static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
+					 unsigned int *offset)
+{
+	if (offset)
+		*offset = 0;
+	return CEC_PHYS_ADDR_INVALID;
+}
+
+static inline void cec_set_edid_phys_addr(u8 *edid, unsigned int size,
+					  u16 phys_addr)
+{
+}
+
+static inline u16 cec_phys_addr_for_input(u16 phys_addr, u8 input)
+{
+	return CEC_PHYS_ADDR_INVALID;
+}
+
+static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
+{
+	if (parent)
+		*parent = phys_addr;
+	if (port)
+		*port = 0;
+	return 0;
+}
+
+#endif
+
+/**
+ * cec_phys_addr_invalidate() - set the physical address to INVALID
+ *
+ * @adap:	the CEC adapter
+ *
+ * This is a simple helper function to invalidate the physical
+ * address.
+ */
+static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
+{
+	cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
+}
+
+/**
+ * cec_get_edid_spa_location() - find location of the Source Physical Address
+ *
+ * @edid: the EDID
+ * @size: the size of the EDID
+ *
+ * This EDID is expected to be a CEA-861 compliant, which means that there are
+ * at least two blocks and one or more of the extensions blocks are CEA-861
+ * blocks.
+ *
+ * The returned location is guaranteed to be <= size-2.
+ *
+ * This is an inline function since it is used by both CEC and V4L2.
+ * Ideally this would go in a module shared by both, but it is overkill to do
+ * that for just a single function.
+ */
+static inline unsigned int cec_get_edid_spa_location(const u8 *edid,
+						     unsigned int size)
+{
+	unsigned int blocks = size / 128;
+	unsigned int block;
+	u8 d;
+
+	/* Sanity check: at least 2 blocks and a multiple of the block size */
+	if (blocks < 2 || size % 128)
+		return 0;
+
+	/*
+	 * If there are fewer extension blocks than the size, then update
+	 * 'blocks'. It is allowed to have more extension blocks than the size,
+	 * since some hardware can only read e.g. 256 bytes of the EDID, even
+	 * though more blocks are present. The first CEA-861 extension block
+	 * should normally be in block 1 anyway.
+	 */
+	if (edid[0x7e] + 1 < blocks)
+		blocks = edid[0x7e] + 1;
+
+	for (block = 1; block < blocks; block++) {
+		unsigned int offset = block * 128;
+
+		/* Skip any non-CEA-861 extension blocks */
+		if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
+			continue;
+
+		/* search Vendor Specific Data Block (tag 3) */
+		d = edid[offset + 2] & 0x7f;
+		/* Check if there are Data Blocks */
+		if (d <= 4)
+			continue;
+		if (d > 4) {
+			unsigned int i = offset + 4;
+			unsigned int end = offset + d;
+
+			/* Note: 'end' is always < 'size' */
+			do {
+				u8 tag = edid[i] >> 5;
+				u8 len = edid[i] & 0x1f;
+
+				if (tag == 3 && len >= 5 && i + len <= end &&
+				    edid[i + 1] == 0x03 &&
+				    edid[i + 2] == 0x0c &&
+				    edid[i + 3] == 0x00)
+					return i + 4;
+				i += len + 1;
+			} while (i < end);
+		}
+	}
+	return 0;
+}
+
+#endif /* _MEDIA_CEC_H */
diff --git a/include/media/davinci/ccdc_types.h b/include/media/davinci/ccdc_types.h
new file mode 100644
index 0000000..a27defc
--- /dev/null
+++ b/include/media/davinci/ccdc_types.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ **************************************************************************/
+#ifndef _CCDC_TYPES_H
+#define _CCDC_TYPES_H
+enum ccdc_pixfmt {
+	CCDC_PIXFMT_RAW,
+	CCDC_PIXFMT_YCBCR_16BIT,
+	CCDC_PIXFMT_YCBCR_8BIT
+};
+
+enum ccdc_frmfmt {
+	CCDC_FRMFMT_PROGRESSIVE,
+	CCDC_FRMFMT_INTERLACED
+};
+
+/* PIXEL ORDER IN MEMORY from LSB to MSB */
+/* only applicable for 8-bit input mode  */
+enum ccdc_pixorder {
+	CCDC_PIXORDER_YCBYCR,
+	CCDC_PIXORDER_CBYCRY,
+};
+
+enum ccdc_buftype {
+	CCDC_BUFTYPE_FLD_INTERLEAVED,
+	CCDC_BUFTYPE_FLD_SEPARATED
+};
+#endif
diff --git a/include/media/davinci/dm355_ccdc.h b/include/media/davinci/dm355_ccdc.h
new file mode 100644
index 0000000..e6bc72f
--- /dev/null
+++ b/include/media/davinci/dm355_ccdc.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2005-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _DM355_CCDC_H
+#define _DM355_CCDC_H
+#include <media/davinci/ccdc_types.h>
+#include <media/davinci/vpfe_types.h>
+
+/* enum for No of pixel per line to be avg. in Black Clamping */
+enum ccdc_sample_length {
+	CCDC_SAMPLE_1PIXELS,
+	CCDC_SAMPLE_2PIXELS,
+	CCDC_SAMPLE_4PIXELS,
+	CCDC_SAMPLE_8PIXELS,
+	CCDC_SAMPLE_16PIXELS
+};
+
+/* enum for No of lines in Black Clamping */
+enum ccdc_sample_line {
+	CCDC_SAMPLE_1LINES,
+	CCDC_SAMPLE_2LINES,
+	CCDC_SAMPLE_4LINES,
+	CCDC_SAMPLE_8LINES,
+	CCDC_SAMPLE_16LINES
+};
+
+/* enum for Alaw gamma width */
+enum ccdc_gamma_width {
+	CCDC_GAMMA_BITS_13_4,
+	CCDC_GAMMA_BITS_12_3,
+	CCDC_GAMMA_BITS_11_2,
+	CCDC_GAMMA_BITS_10_1,
+	CCDC_GAMMA_BITS_09_0
+};
+
+enum ccdc_colpats {
+	CCDC_RED,
+	CCDC_GREEN_RED,
+	CCDC_GREEN_BLUE,
+	CCDC_BLUE
+};
+
+struct ccdc_col_pat {
+	enum ccdc_colpats olop;
+	enum ccdc_colpats olep;
+	enum ccdc_colpats elop;
+	enum ccdc_colpats elep;
+};
+
+enum ccdc_datasft {
+	CCDC_DATA_NO_SHIFT,
+	CCDC_DATA_SHIFT_1BIT,
+	CCDC_DATA_SHIFT_2BIT,
+	CCDC_DATA_SHIFT_3BIT,
+	CCDC_DATA_SHIFT_4BIT,
+	CCDC_DATA_SHIFT_5BIT,
+	CCDC_DATA_SHIFT_6BIT
+};
+
+enum ccdc_data_size {
+	CCDC_DATA_16BITS,
+	CCDC_DATA_15BITS,
+	CCDC_DATA_14BITS,
+	CCDC_DATA_13BITS,
+	CCDC_DATA_12BITS,
+	CCDC_DATA_11BITS,
+	CCDC_DATA_10BITS,
+	CCDC_DATA_8BITS
+};
+enum ccdc_mfilt1 {
+	CCDC_NO_MEDIAN_FILTER1,
+	CCDC_AVERAGE_FILTER1,
+	CCDC_MEDIAN_FILTER1
+};
+
+enum ccdc_mfilt2 {
+	CCDC_NO_MEDIAN_FILTER2,
+	CCDC_AVERAGE_FILTER2,
+	CCDC_MEDIAN_FILTER2
+};
+
+/* structure for ALaw */
+struct ccdc_a_law {
+	/* Enable/disable A-Law */
+	unsigned char enable;
+	/* Gamma Width Input */
+	enum ccdc_gamma_width gamma_wd;
+};
+
+/* structure for Black Clamping */
+struct ccdc_black_clamp {
+	/* only if bClampEnable is TRUE */
+	unsigned char b_clamp_enable;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_length sample_pixel;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_line sample_ln;
+	/* only if bClampEnable is TRUE */
+	unsigned short start_pixel;
+	/* only if bClampEnable is FALSE */
+	unsigned short sgain;
+	unsigned short dc_sub;
+};
+
+/* structure for Black Level Compensation */
+struct ccdc_black_compensation {
+	/* Constant value to subtract from Red component */
+	unsigned char r;
+	/* Constant value to subtract from Gr component */
+	unsigned char gr;
+	/* Constant value to subtract from Blue component */
+	unsigned char b;
+	/* Constant value to subtract from Gb component */
+	unsigned char gb;
+};
+
+struct ccdc_float {
+	int integer;
+	unsigned int decimal;
+};
+
+#define CCDC_CSC_COEFF_TABLE_SIZE	16
+/* structure for color space converter */
+struct ccdc_csc {
+	unsigned char enable;
+	/*
+	 * S8Q5. Use 2 decimal precision, user values range from -3.00 to 3.99.
+	 * example - to use 1.03, set integer part as 1, and decimal part as 3
+	 * to use -1.03, set integer part as -1 and decimal part as 3
+	 */
+	struct ccdc_float coeff[CCDC_CSC_COEFF_TABLE_SIZE];
+};
+
+/* Structures for Vertical Defect Correction*/
+enum ccdc_vdf_csl {
+	CCDC_VDF_NORMAL,
+	CCDC_VDF_HORZ_INTERPOL_SAT,
+	CCDC_VDF_HORZ_INTERPOL
+};
+
+enum ccdc_vdf_cuda {
+	CCDC_VDF_WHOLE_LINE_CORRECT,
+	CCDC_VDF_UPPER_DISABLE
+};
+
+enum ccdc_dfc_mwr {
+	CCDC_DFC_MWR_WRITE_COMPLETE,
+	CCDC_DFC_WRITE_REG
+};
+
+enum ccdc_dfc_mrd {
+	CCDC_DFC_READ_COMPLETE,
+	CCDC_DFC_READ_REG
+};
+
+enum ccdc_dfc_ma_rst {
+	CCDC_DFC_INCR_ADDR,
+	CCDC_DFC_CLR_ADDR
+};
+
+enum ccdc_dfc_mclr {
+	CCDC_DFC_CLEAR_COMPLETE,
+	CCDC_DFC_CLEAR
+};
+
+struct ccdc_dft_corr_ctl {
+	enum ccdc_vdf_csl vdfcsl;
+	enum ccdc_vdf_cuda vdfcuda;
+	unsigned int vdflsft;
+};
+
+struct ccdc_dft_corr_mem_ctl {
+	enum ccdc_dfc_mwr dfcmwr;
+	enum ccdc_dfc_mrd dfcmrd;
+	enum ccdc_dfc_ma_rst dfcmarst;
+	enum ccdc_dfc_mclr dfcmclr;
+};
+
+#define CCDC_DFT_TABLE_SIZE	16
+/*
+ * Main Structure for vertical defect correction. Vertical defect
+ * correction can correct up to 16 defects if defects less than 16
+ * then pad the rest with 0
+ */
+struct ccdc_vertical_dft {
+	unsigned char ver_dft_en;
+	unsigned char gen_dft_en;
+	unsigned int saturation_ctl;
+	struct ccdc_dft_corr_ctl dft_corr_ctl;
+	struct ccdc_dft_corr_mem_ctl dft_corr_mem_ctl;
+	int table_size;
+	unsigned int dft_corr_horz[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_vert[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_sub1[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_sub2[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_sub3[CCDC_DFT_TABLE_SIZE];
+};
+
+struct ccdc_data_offset {
+	unsigned char horz_offset;
+	unsigned char vert_offset;
+};
+
+/*
+ * Structure for CCDC configuration parameters for raw capture mode passed
+ * by application
+ */
+struct ccdc_config_params_raw {
+	/* data shift to be applied before storing */
+	enum ccdc_datasft datasft;
+	/* data size value from 8 to 16 bits */
+	enum ccdc_data_size data_sz;
+	/* median filter for sdram */
+	enum ccdc_mfilt1 mfilt1;
+	enum ccdc_mfilt2 mfilt2;
+	/* low pass filter enable/disable */
+	unsigned char lpf_enable;
+	/* Threshold of median filter */
+	int med_filt_thres;
+	/*
+	 * horz and vertical data offset. Appliable for defect correction
+	 * and lsc
+	 */
+	struct ccdc_data_offset data_offset;
+	/* Structure for Optional A-Law */
+	struct ccdc_a_law alaw;
+	/* Structure for Optical Black Clamp */
+	struct ccdc_black_clamp blk_clamp;
+	/* Structure for Black Compensation */
+	struct ccdc_black_compensation blk_comp;
+	/* struture for vertical Defect Correction Module Configuration */
+	struct ccdc_vertical_dft vertical_dft;
+	/* structure for color space converter Module Configuration */
+	struct ccdc_csc csc;
+	/* color patters for bayer capture */
+	struct ccdc_col_pat col_pat_field0;
+	struct ccdc_col_pat col_pat_field1;
+};
+
+#ifdef __KERNEL__
+#include <linux/io.h>
+
+#define CCDC_WIN_PAL	{0, 0, 720, 576}
+#define CCDC_WIN_VGA	{0, 0, 640, 480}
+
+struct ccdc_params_ycbcr {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* enable BT.656 embedded sync mode */
+	int bt656_enable;
+	/* cb:y:cr:y or y:cb:y:cr in memory */
+	enum ccdc_pixorder pix_order;
+	/* interleaved or separated fields  */
+	enum ccdc_buftype buf_type;
+};
+
+/* Gain applied to Raw Bayer data */
+struct ccdc_gain {
+	unsigned short r_ye;
+	unsigned short gr_cy;
+	unsigned short gb_g;
+	unsigned short b_mg;
+};
+
+/* Structure for CCDC configuration parameters for raw capture mode */
+struct ccdc_params_raw {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* interleaved or separated fields */
+	enum ccdc_buftype buf_type;
+	/* Gain values */
+	struct ccdc_gain gain;
+	/* offset */
+	unsigned int ccdc_offset;
+	/* horizontal flip enable */
+	unsigned char horz_flip_enable;
+	/*
+	 * enable to store the image in inverse order in memory
+	 * (bottom to top)
+	 */
+	unsigned char image_invert_enable;
+	/* Configurable part of raw data */
+	struct ccdc_config_params_raw config_params;
+};
+
+#endif
+#endif				/* DM355_CCDC_H */
diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h
new file mode 100644
index 0000000..6ea2ce2
--- /dev/null
+++ b/include/media/davinci/dm644x_ccdc.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2006-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _DM644X_CCDC_H
+#define _DM644X_CCDC_H
+#include <media/davinci/ccdc_types.h>
+#include <media/davinci/vpfe_types.h>
+
+/* enum for No of pixel per line to be avg. in Black Clamping*/
+enum ccdc_sample_length {
+	CCDC_SAMPLE_1PIXELS,
+	CCDC_SAMPLE_2PIXELS,
+	CCDC_SAMPLE_4PIXELS,
+	CCDC_SAMPLE_8PIXELS,
+	CCDC_SAMPLE_16PIXELS
+};
+
+/* enum for No of lines in Black Clamping */
+enum ccdc_sample_line {
+	CCDC_SAMPLE_1LINES,
+	CCDC_SAMPLE_2LINES,
+	CCDC_SAMPLE_4LINES,
+	CCDC_SAMPLE_8LINES,
+	CCDC_SAMPLE_16LINES
+};
+
+/* enum for Alaw gamma width */
+enum ccdc_gamma_width {
+	CCDC_GAMMA_BITS_15_6,	/* use bits 15-6 for gamma */
+	CCDC_GAMMA_BITS_14_5,
+	CCDC_GAMMA_BITS_13_4,
+	CCDC_GAMMA_BITS_12_3,
+	CCDC_GAMMA_BITS_11_2,
+	CCDC_GAMMA_BITS_10_1,
+	CCDC_GAMMA_BITS_09_0	/* use bits 9-0 for gamma */
+};
+
+/* returns the highest bit used for the gamma */
+static inline u8 ccdc_gamma_width_max_bit(enum ccdc_gamma_width width)
+{
+	return 15 - width;
+}
+
+enum ccdc_data_size {
+	CCDC_DATA_16BITS,
+	CCDC_DATA_15BITS,
+	CCDC_DATA_14BITS,
+	CCDC_DATA_13BITS,
+	CCDC_DATA_12BITS,
+	CCDC_DATA_11BITS,
+	CCDC_DATA_10BITS,
+	CCDC_DATA_8BITS
+};
+
+/* returns the highest bit used for this data size */
+static inline u8 ccdc_data_size_max_bit(enum ccdc_data_size sz)
+{
+	return sz == CCDC_DATA_8BITS ? 7 : 15 - sz;
+}
+
+/* structure for ALaw */
+struct ccdc_a_law {
+	/* Enable/disable A-Law */
+	unsigned char enable;
+	/* Gamma Width Input */
+	enum ccdc_gamma_width gamma_wd;
+};
+
+/* structure for Black Clamping */
+struct ccdc_black_clamp {
+	unsigned char enable;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_length sample_pixel;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_line sample_ln;
+	/* only if bClampEnable is TRUE */
+	unsigned short start_pixel;
+	/* only if bClampEnable is TRUE */
+	unsigned short sgain;
+	/* only if bClampEnable is FALSE */
+	unsigned short dc_sub;
+};
+
+/* structure for Black Level Compensation */
+struct ccdc_black_compensation {
+	/* Constant value to subtract from Red component */
+	char r;
+	/* Constant value to subtract from Gr component */
+	char gr;
+	/* Constant value to subtract from Blue component */
+	char b;
+	/* Constant value to subtract from Gb component */
+	char gb;
+};
+
+/* Structure for CCDC configuration parameters for raw capture mode passed
+ * by application
+ */
+struct ccdc_config_params_raw {
+	/* data size value from 8 to 16 bits */
+	enum ccdc_data_size data_sz;
+	/* Structure for Optional A-Law */
+	struct ccdc_a_law alaw;
+	/* Structure for Optical Black Clamp */
+	struct ccdc_black_clamp blk_clamp;
+	/* Structure for Black Compensation */
+	struct ccdc_black_compensation blk_comp;
+};
+
+
+#ifdef __KERNEL__
+#include <linux/io.h>
+/* Define to enable/disable video port */
+#define FP_NUM_BYTES		4
+/* Define for extra pixel/line and extra lines/frame */
+#define NUM_EXTRAPIXELS		8
+#define NUM_EXTRALINES		8
+
+/* settings for commonly used video formats */
+#define CCDC_WIN_PAL     {0, 0, 720, 576}
+/* ntsc square pixel */
+#define CCDC_WIN_VGA	{0, 0, (640 + NUM_EXTRAPIXELS), (480 + NUM_EXTRALINES)}
+
+/* Structure for CCDC configuration parameters for raw capture mode */
+struct ccdc_params_raw {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* interleaved or separated fields */
+	enum ccdc_buftype buf_type;
+	/*
+	 * enable to store the image in inverse
+	 * order in memory(bottom to top)
+	 */
+	unsigned char image_invert_enable;
+	/* configurable paramaters */
+	struct ccdc_config_params_raw config_params;
+};
+
+struct ccdc_params_ycbcr {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* enable BT.656 embedded sync mode */
+	int bt656_enable;
+	/* cb:y:cr:y or y:cb:y:cr in memory */
+	enum ccdc_pixorder pix_order;
+	/* interleaved or separated fields  */
+	enum ccdc_buftype buf_type;
+};
+#endif
+#endif				/* _DM644X_CCDC_H */
diff --git a/include/media/davinci/isif.h b/include/media/davinci/isif.h
new file mode 100644
index 0000000..170a7b9
--- /dev/null
+++ b/include/media/davinci/isif.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * isif header file
+ */
+#ifndef _ISIF_H
+#define _ISIF_H
+
+#include <media/davinci/ccdc_types.h>
+#include <media/davinci/vpfe_types.h>
+
+/* isif float type S8Q8/U8Q8 */
+struct isif_float_8 {
+	/* 8 bit integer part */
+	__u8 integer;
+	/* 8 bit decimal part */
+	__u8 decimal;
+};
+
+/* isif float type U16Q16/S16Q16 */
+struct isif_float_16 {
+	/* 16 bit integer part */
+	__u16 integer;
+	/* 16 bit decimal part */
+	__u16 decimal;
+};
+
+/************************************************************************
+ *   Vertical Defect Correction parameters
+ ***********************************************************************/
+/* Defect Correction (DFC) table entry */
+struct isif_vdfc_entry {
+	/* vertical position of defect */
+	__u16 pos_vert;
+	/* horizontal position of defect */
+	__u16 pos_horz;
+	/*
+	 * Defect level of Vertical line defect position. This is subtracted
+	 * from the data at the defect position
+	 */
+	__u8 level_at_pos;
+	/*
+	 * Defect level of the pixels upper than the vertical line defect.
+	 * This is subtracted from the data
+	 */
+	__u8 level_up_pixels;
+	/*
+	 * Defect level of the pixels lower than the vertical line defect.
+	 * This is subtracted from the data
+	 */
+	__u8 level_low_pixels;
+};
+
+#define ISIF_VDFC_TABLE_SIZE		8
+struct isif_dfc {
+	/* enable vertical defect correction */
+	__u8 en;
+	/* Defect level subtraction. Just fed through if saturating */
+#define	ISIF_VDFC_NORMAL		0
+	/*
+	 * Defect level subtraction. Horizontal interpolation ((i-2)+(i+2))/2
+	 * if data saturating
+	 */
+#define ISIF_VDFC_HORZ_INTERPOL_IF_SAT	1
+	/* Horizontal interpolation (((i-2)+(i+2))/2) */
+#define	ISIF_VDFC_HORZ_INTERPOL		2
+	/* one of the vertical defect correction modes above */
+	__u8 corr_mode;
+	/* 0 - whole line corrected, 1 - not pixels upper than the defect */
+	__u8 corr_whole_line;
+#define ISIF_VDFC_NO_SHIFT		0
+#define ISIF_VDFC_SHIFT_1		1
+#define ISIF_VDFC_SHIFT_2		2
+#define ISIF_VDFC_SHIFT_3		3
+#define ISIF_VDFC_SHIFT_4		4
+	/*
+	 * defect level shift value. level_at_pos, level_upper_pos,
+	 * and level_lower_pos can be shifted up by this value. Choose
+	 * one of the values above
+	 */
+	__u8 def_level_shift;
+	/* defect saturation level */
+	__u16 def_sat_level;
+	/* number of vertical defects. Max is ISIF_VDFC_TABLE_SIZE */
+	__u16 num_vdefects;
+	/* VDFC table ptr */
+	struct isif_vdfc_entry table[ISIF_VDFC_TABLE_SIZE];
+};
+
+struct isif_horz_bclamp {
+
+	/* Horizontal clamp disabled. Only vertical clamp value is subtracted */
+#define	ISIF_HORZ_BC_DISABLE		0
+	/*
+	 * Horizontal clamp value is calculated and subtracted from image data
+	 * along with vertical clamp value
+	 */
+#define ISIF_HORZ_BC_CLAMP_CALC_ENABLED	1
+	/*
+	 * Horizontal clamp value calculated from previous image is subtracted
+	 * from image data along with vertical clamp value.
+	 */
+#define ISIF_HORZ_BC_CLAMP_NOT_UPDATED	2
+	/* horizontal clamp mode. One of the values above */
+	__u8 mode;
+	/*
+	 * pixel value limit enable.
+	 *  0 - limit disabled
+	 *  1 - pixel value limited to 1023
+	 */
+	__u8 clamp_pix_limit;
+	/* Select Most left window for bc calculation */
+#define	ISIF_SEL_MOST_LEFT_WIN		0
+	/* Select Most right window for bc calculation */
+#define ISIF_SEL_MOST_RIGHT_WIN		1
+	/* Select most left or right window for clamp val calculation */
+	__u8 base_win_sel_calc;
+	/* Window count per color for calculation. range 1-32 */
+	__u8 win_count_calc;
+	/* Window start position - horizontal for calculation. 0 - 8191 */
+	__u16 win_start_h_calc;
+	/* Window start position - vertical for calculation 0 - 8191 */
+	__u16 win_start_v_calc;
+#define ISIF_HORZ_BC_SZ_H_2PIXELS	0
+#define ISIF_HORZ_BC_SZ_H_4PIXELS	1
+#define ISIF_HORZ_BC_SZ_H_8PIXELS	2
+#define ISIF_HORZ_BC_SZ_H_16PIXELS	3
+	/* Width of the sample window in pixels for calculation */
+	__u8 win_h_sz_calc;
+#define ISIF_HORZ_BC_SZ_V_32PIXELS	0
+#define ISIF_HORZ_BC_SZ_V_64PIXELS	1
+#define	ISIF_HORZ_BC_SZ_V_128PIXELS	2
+#define ISIF_HORZ_BC_SZ_V_256PIXELS	3
+	/* Height of the sample window in pixels for calculation */
+	__u8 win_v_sz_calc;
+};
+
+/************************************************************************
+ *  Black Clamp parameters
+ ***********************************************************************/
+struct isif_vert_bclamp {
+	/* Reset value used is the clamp value calculated */
+#define	ISIF_VERT_BC_USE_HORZ_CLAMP_VAL		0
+	/* Reset value used is reset_clamp_val configured */
+#define	ISIF_VERT_BC_USE_CONFIG_CLAMP_VAL	1
+	/* No update, previous image value is used */
+#define	ISIF_VERT_BC_NO_UPDATE			2
+	/*
+	 * Reset value selector for vertical clamp calculation. Use one of
+	 * the above values
+	 */
+	__u8 reset_val_sel;
+	/* U8Q8. Line average coefficient used in vertical clamp calculation */
+	__u8 line_ave_coef;
+	/* Height of the optical black region for calculation */
+	__u16 ob_v_sz_calc;
+	/* Optical black region start position - horizontal. 0 - 8191 */
+	__u16 ob_start_h;
+	/* Optical black region start position - vertical 0 - 8191 */
+	__u16 ob_start_v;
+};
+
+struct isif_black_clamp {
+	/*
+	 * This offset value is added irrespective of the clamp enable status.
+	 * S13
+	 */
+	__u16 dc_offset;
+	/*
+	 * Enable black/digital clamp value to be subtracted from the image data
+	 */
+	__u8 en;
+	/*
+	 * black clamp mode. same/separate clamp for 4 colors
+	 * 0 - disable - same clamp value for all colors
+	 * 1 - clamp value calculated separately for all colors
+	 */
+	__u8 bc_mode_color;
+	/* Vrtical start position for bc subtraction */
+	__u16 vert_start_sub;
+	/* Black clamp for horizontal direction */
+	struct isif_horz_bclamp horz;
+	/* Black clamp for vertical direction */
+	struct isif_vert_bclamp vert;
+};
+
+/*************************************************************************
+** Color Space Conversion (CSC)
+*************************************************************************/
+#define ISIF_CSC_NUM_COEFF	16
+struct isif_color_space_conv {
+	/* Enable color space conversion */
+	__u8 en;
+	/*
+	 * csc coeffient table. S8Q5, M00 at index 0, M01 at index 1, and
+	 * so forth
+	 */
+	struct isif_float_8 coeff[ISIF_CSC_NUM_COEFF];
+};
+
+
+/*************************************************************************
+**  Black  Compensation parameters
+*************************************************************************/
+struct isif_black_comp {
+	/* Comp for Red */
+	__s8 r_comp;
+	/* Comp for Gr */
+	__s8 gr_comp;
+	/* Comp for Blue */
+	__s8 b_comp;
+	/* Comp for Gb */
+	__s8 gb_comp;
+};
+
+/*************************************************************************
+**  Gain parameters
+*************************************************************************/
+struct isif_gain {
+	/* Gain for Red or ye */
+	struct isif_float_16 r_ye;
+	/* Gain for Gr or cy */
+	struct isif_float_16 gr_cy;
+	/* Gain for Gb or g */
+	struct isif_float_16 gb_g;
+	/* Gain for Blue or mg */
+	struct isif_float_16 b_mg;
+};
+
+#define ISIF_LINEAR_TAB_SIZE	192
+/*************************************************************************
+**  Linearization parameters
+*************************************************************************/
+struct isif_linearize {
+	/* Enable or Disable linearization of data */
+	__u8 en;
+	/* Shift value applied */
+	__u8 corr_shft;
+	/* scale factor applied U11Q10 */
+	struct isif_float_16 scale_fact;
+	/* Size of the linear table */
+	__u16 table[ISIF_LINEAR_TAB_SIZE];
+};
+
+/* Color patterns */
+#define ISIF_RED	0
+#define	ISIF_GREEN_RED	1
+#define ISIF_GREEN_BLUE	2
+#define ISIF_BLUE	3
+struct isif_col_pat {
+	__u8 olop;
+	__u8 olep;
+	__u8 elop;
+	__u8 elep;
+};
+
+/*************************************************************************
+**  Data formatter parameters
+*************************************************************************/
+struct isif_fmtplen {
+	/*
+	 * number of program entries for SET0, range 1 - 16
+	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
+	 * ISIF_COMBINE
+	 */
+	__u16 plen0;
+	/*
+	 * number of program entries for SET1, range 1 - 16
+	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
+	 * ISIF_COMBINE
+	 */
+	__u16 plen1;
+	/**
+	 * number of program entries for SET2, range 1 - 16
+	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
+	 * ISIF_COMBINE
+	 */
+	__u16 plen2;
+	/**
+	 * number of program entries for SET3, range 1 - 16
+	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
+	 * ISIF_COMBINE
+	 */
+	__u16 plen3;
+};
+
+struct isif_fmt_cfg {
+#define ISIF_SPLIT		0
+#define ISIF_COMBINE		1
+	/* Split or combine or line alternate */
+	__u8 fmtmode;
+	/* enable or disable line alternating mode */
+	__u8 ln_alter_en;
+#define ISIF_1LINE		0
+#define	ISIF_2LINES		1
+#define	ISIF_3LINES		2
+#define	ISIF_4LINES		3
+	/* Split/combine line number */
+	__u8 lnum;
+	/* Address increment Range 1 - 16 */
+	__u8 addrinc;
+};
+
+struct isif_fmt_addr_ptr {
+	/* Initial address */
+	__u32 init_addr;
+	/* output line number */
+#define ISIF_1STLINE		0
+#define	ISIF_2NDLINE		1
+#define	ISIF_3RDLINE		2
+#define	ISIF_4THLINE		3
+	__u8 out_line;
+};
+
+struct isif_fmtpgm_ap {
+	/* program address pointer */
+	__u8 pgm_aptr;
+	/* program address increment or decrement */
+	__u8 pgmupdt;
+};
+
+struct isif_data_formatter {
+	/* Enable/Disable data formatter */
+	__u8 en;
+	/* data formatter configuration */
+	struct isif_fmt_cfg cfg;
+	/* Formatter program entries length */
+	struct isif_fmtplen plen;
+	/* first pixel in a line fed to formatter */
+	__u16 fmtrlen;
+	/* HD interval for output line. Only valid when split line */
+	__u16 fmthcnt;
+	/* formatter address pointers */
+	struct isif_fmt_addr_ptr fmtaddr_ptr[16];
+	/* program enable/disable */
+	__u8 pgm_en[32];
+	/* program address pointers */
+	struct isif_fmtpgm_ap fmtpgm_ap[32];
+};
+
+struct isif_df_csc {
+	/* Color Space Conversion confguration, 0 - csc, 1 - df */
+	__u8 df_or_csc;
+	/* csc configuration valid if df_or_csc is 0 */
+	struct isif_color_space_conv csc;
+	/* data formatter configuration valid if df_or_csc is 1 */
+	struct isif_data_formatter df;
+	/* start pixel in a line at the input */
+	__u32 start_pix;
+	/* number of pixels in input line */
+	__u32 num_pixels;
+	/* start line at the input */
+	__u32 start_line;
+	/* number of lines at the input */
+	__u32 num_lines;
+};
+
+struct isif_gain_offsets_adj {
+	/* Gain adjustment per color */
+	struct isif_gain gain;
+	/* Offset adjustment */
+	__u16 offset;
+	/* Enable or Disable Gain adjustment for SDRAM data */
+	__u8 gain_sdram_en;
+	/* Enable or Disable Gain adjustment for IPIPE data */
+	__u8 gain_ipipe_en;
+	/* Enable or Disable Gain adjustment for H3A data */
+	__u8 gain_h3a_en;
+	/* Enable or Disable Gain adjustment for SDRAM data */
+	__u8 offset_sdram_en;
+	/* Enable or Disable Gain adjustment for IPIPE data */
+	__u8 offset_ipipe_en;
+	/* Enable or Disable Gain adjustment for H3A data */
+	__u8 offset_h3a_en;
+};
+
+struct isif_cul {
+	/* Horizontal Cull pattern for odd lines */
+	__u8 hcpat_odd;
+	/* Horizontal Cull pattern for even lines */
+	__u8 hcpat_even;
+	/* Vertical Cull pattern */
+	__u8 vcpat;
+	/* Enable or disable lpf. Apply when cull is enabled */
+	__u8 en_lpf;
+};
+
+struct isif_compress {
+#define ISIF_ALAW		0
+#define ISIF_DPCM		1
+#define ISIF_NO_COMPRESSION	2
+	/* Compression Algorithm used */
+	__u8 alg;
+	/* Choose Predictor1 for DPCM compression */
+#define ISIF_DPCM_PRED1		0
+	/* Choose Predictor2 for DPCM compression */
+#define ISIF_DPCM_PRED2		1
+	/* Predictor for DPCM compression */
+	__u8 pred;
+};
+
+/* all the stuff in this struct will be provided by userland */
+struct isif_config_params_raw {
+	/* Linearization parameters for image sensor data input */
+	struct isif_linearize linearize;
+	/* Data formatter or CSC */
+	struct isif_df_csc df_csc;
+	/* Defect Pixel Correction (DFC) confguration */
+	struct isif_dfc dfc;
+	/* Black/Digital Clamp configuration */
+	struct isif_black_clamp bclamp;
+	/* Gain, offset adjustments */
+	struct isif_gain_offsets_adj gain_offset;
+	/* Culling */
+	struct isif_cul culling;
+	/* A-Law and DPCM compression options */
+	struct isif_compress compress;
+	/* horizontal offset for Gain/LSC/DFC */
+	__u16 horz_offset;
+	/* vertical offset for Gain/LSC/DFC */
+	__u16 vert_offset;
+	/* color pattern for field 0 */
+	struct isif_col_pat col_pat_field0;
+	/* color pattern for field 1 */
+	struct isif_col_pat col_pat_field1;
+#define ISIF_NO_SHIFT		0
+#define	ISIF_1BIT_SHIFT		1
+#define	ISIF_2BIT_SHIFT		2
+#define	ISIF_3BIT_SHIFT		3
+#define	ISIF_4BIT_SHIFT		4
+#define ISIF_5BIT_SHIFT		5
+#define ISIF_6BIT_SHIFT		6
+	/* Data shift applied before storing to SDRAM */
+	__u8 data_shift;
+	/* enable input test pattern generation */
+	__u8 test_pat_gen;
+};
+
+#ifdef __KERNEL__
+struct isif_ycbcr_config {
+	/* isif pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* isif frame format */
+	enum ccdc_frmfmt frm_fmt;
+	/* ISIF crop window */
+	struct v4l2_rect win;
+	/* field polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* interface VD polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* interface HD polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* isif pix order. Only used for ycbcr capture */
+	enum ccdc_pixorder pix_order;
+	/* isif buffer type. Only used for ycbcr capture */
+	enum ccdc_buftype buf_type;
+};
+
+/* MSB of image data connected to sensor port */
+enum isif_data_msb {
+	ISIF_BIT_MSB_15,
+	ISIF_BIT_MSB_14,
+	ISIF_BIT_MSB_13,
+	ISIF_BIT_MSB_12,
+	ISIF_BIT_MSB_11,
+	ISIF_BIT_MSB_10,
+	ISIF_BIT_MSB_9,
+	ISIF_BIT_MSB_8,
+	ISIF_BIT_MSB_7
+};
+
+enum isif_cfa_pattern {
+	ISIF_CFA_PAT_MOSAIC,
+	ISIF_CFA_PAT_STRIPE
+};
+
+struct isif_params_raw {
+	/* isif pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* isif frame format */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* interface VD polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* interface HD polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* buffer type. Applicable for interlaced mode */
+	enum ccdc_buftype buf_type;
+	/* Gain values */
+	struct isif_gain gain;
+	/* cfa pattern */
+	enum isif_cfa_pattern cfa_pat;
+	/* Data MSB position */
+	enum isif_data_msb data_msb;
+	/* Enable horizontal flip */
+	unsigned char horz_flip_en;
+	/* Enable image invert vertically */
+	unsigned char image_invert_en;
+
+	/* all the userland defined stuff*/
+	struct isif_config_params_raw config_params;
+};
+
+enum isif_data_pack {
+	ISIF_PACK_16BIT,
+	ISIF_PACK_12BIT,
+	ISIF_PACK_8BIT
+};
+
+#define ISIF_WIN_NTSC				{0, 0, 720, 480}
+#define ISIF_WIN_VGA				{0, 0, 640, 480}
+
+#endif
+#endif
diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h
new file mode 100644
index 0000000..79a566d
--- /dev/null
+++ b/include/media/davinci/vpbe.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2010 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _VPBE_H
+#define _VPBE_H
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/davinci/vpbe_osd.h>
+#include <media/davinci/vpbe_venc.h>
+#include <media/davinci/vpbe_types.h>
+
+/* OSD configuration info */
+struct osd_config_info {
+	char module_name[32];
+};
+
+struct vpbe_output {
+	struct v4l2_output output;
+	/*
+	 * If output capabilities include dv_timings, list supported timings
+	 * below
+	 */
+	char *subdev_name;
+	/*
+	 * defualt_mode identifies the default timings set at the venc or
+	 * external encoder.
+	 */
+	char *default_mode;
+	/*
+	 * Fields below are used for supporting multiple modes. For example,
+	 * LCD panel might support different modes and they are listed here.
+	 * Similarly for supporting external encoders, lcd controller port
+	 * requires a set of non-standard timing values to be listed here for
+	 * each supported mode since venc is used in non-standard timing mode
+	 * for interfacing with external encoder similar to configuring lcd
+	 * panel timings
+	 */
+	unsigned int num_modes;
+	struct vpbe_enc_mode_info *modes;
+	/*
+	 * Bus configuration goes here for external encoders. Some encoders
+	 * may require multiple interface types for each of the output. For
+	 * example, SD modes would use YCC8 where as HD mode would use YCC16.
+	 * Not sure if this is needed on a per mode basis instead of per
+	 * output basis. If per mode is needed, we may have to move this to
+	 * mode_info structure
+	 */
+	u32 if_params;
+};
+
+/* encoder configuration info */
+struct encoder_config_info {
+	char module_name[32];
+	/* Is this an i2c device ? */
+	unsigned int is_i2c:1;
+	/* i2c subdevice board info */
+	struct i2c_board_info board_info;
+};
+
+/*amplifier configuration info */
+struct amp_config_info {
+	char module_name[32];
+	/* Is this an i2c device ? */
+	unsigned int is_i2c:1;
+	/* i2c subdevice board info */
+	struct i2c_board_info board_info;
+};
+
+/* structure for defining vpbe display subsystem components */
+struct vpbe_config {
+	char module_name[32];
+	/* i2c bus adapter no */
+	int i2c_adapter_id;
+	struct osd_config_info osd;
+	struct encoder_config_info venc;
+	/* external encoder information goes here */
+	int num_ext_encoders;
+	struct encoder_config_info *ext_encoders;
+	/* amplifier information goes here */
+	struct amp_config_info *amp;
+	int num_outputs;
+	/* Order is venc outputs followed by LCD and then external encoders */
+	struct vpbe_output *outputs;
+};
+
+struct vpbe_device;
+
+struct vpbe_device_ops {
+	/* crop cap for the display */
+	int (*g_cropcap)(struct vpbe_device *vpbe_dev,
+			 struct v4l2_cropcap *cropcap);
+
+	/* Enumerate the outputs */
+	int (*enum_outputs)(struct vpbe_device *vpbe_dev,
+			    struct v4l2_output *output);
+
+	/* Set output to the given index */
+	int (*set_output)(struct vpbe_device *vpbe_dev,
+			 int index);
+
+	/* Get current output */
+	unsigned int (*get_output)(struct vpbe_device *vpbe_dev);
+
+	/* Set DV preset at current output */
+	int (*s_dv_timings)(struct vpbe_device *vpbe_dev,
+			   struct v4l2_dv_timings *dv_timings);
+
+	/* Get DV presets supported at the output */
+	int (*g_dv_timings)(struct vpbe_device *vpbe_dev,
+			   struct v4l2_dv_timings *dv_timings);
+
+	/* Enumerate the DV Presets supported at the output */
+	int (*enum_dv_timings)(struct vpbe_device *vpbe_dev,
+			       struct v4l2_enum_dv_timings *timings_info);
+
+	/* Set std at the output */
+	int (*s_std)(struct vpbe_device *vpbe_dev, v4l2_std_id std_id);
+
+	/* Get the current std at the output */
+	int (*g_std)(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id);
+
+	/* initialize the device */
+	int (*initialize)(struct device *dev, struct vpbe_device *vpbe_dev);
+
+	/* De-initialize the device */
+	void (*deinitialize)(struct device *dev, struct vpbe_device *vpbe_dev);
+
+	/* Get the current mode info */
+	int (*get_mode_info)(struct vpbe_device *vpbe_dev,
+			     struct vpbe_enc_mode_info*);
+
+	/*
+	 * Set the current mode in the encoder. Alternate way of setting
+	 * standard or DV preset or custom timings in the encoder
+	 */
+	int (*set_mode)(struct vpbe_device *vpbe_dev,
+			struct vpbe_enc_mode_info*);
+	/* Power management operations */
+	int (*suspend)(struct vpbe_device *vpbe_dev);
+	int (*resume)(struct vpbe_device *vpbe_dev);
+};
+
+/* struct for vpbe device */
+struct vpbe_device {
+	/* V4l2 device */
+	struct v4l2_device v4l2_dev;
+	/* vpbe dispay controller cfg */
+	struct vpbe_config *cfg;
+	/* parent device */
+	struct device *pdev;
+	/* external encoder v4l2 sub devices */
+	struct v4l2_subdev **encoders;
+	/* current encoder index */
+	int current_sd_index;
+	/* external amplifier v4l2 subdevice */
+	struct v4l2_subdev *amp;
+	struct mutex lock;
+	/* device initialized */
+	int initialized;
+	/* vpbe dac clock */
+	struct clk *dac_clk;
+	/* osd_device pointer */
+	struct osd_state *osd_device;
+	/* venc device pointer */
+	struct venc_platform_data *venc_device;
+	/*
+	 * fields below are accessed by users of vpbe_device. Not the
+	 * ones above
+	 */
+
+	/* current output */
+	int current_out_index;
+	/* lock used by caller to do atomic operation on vpbe device */
+	/* current timings set in the controller */
+	struct vpbe_enc_mode_info current_timings;
+	/* venc sub device */
+	struct v4l2_subdev *venc;
+	/* device operations below */
+	struct vpbe_device_ops ops;
+};
+
+#endif
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
new file mode 100644
index 0000000..12783fd
--- /dev/null
+++ b/include/media/davinci/vpbe_display.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef VPBE_DISPLAY_H
+#define VPBE_DISPLAY_H
+
+/* Header files */
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-fh.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/davinci/vpbe_types.h>
+#include <media/davinci/vpbe_osd.h>
+#include <media/davinci/vpbe.h>
+
+#define VPBE_DISPLAY_MAX_DEVICES 2
+
+enum vpbe_display_device_id {
+	VPBE_DISPLAY_DEVICE_0,
+	VPBE_DISPLAY_DEVICE_1
+};
+
+#define VPBE_DISPLAY_DRV_NAME	"vpbe-display"
+
+#define VPBE_DISPLAY_MAJOR_RELEASE              1
+#define VPBE_DISPLAY_MINOR_RELEASE              0
+#define VPBE_DISPLAY_BUILD                      1
+#define VPBE_DISPLAY_VERSION_CODE ((VPBE_DISPLAY_MAJOR_RELEASE << 16) | \
+	(VPBE_DISPLAY_MINOR_RELEASE << 8)  | \
+	VPBE_DISPLAY_BUILD)
+
+#define VPBE_DISPLAY_VALID_FIELD(field)   ((V4L2_FIELD_NONE == field) || \
+	 (V4L2_FIELD_ANY == field) || (V4L2_FIELD_INTERLACED == field))
+
+/* Exp ratio numerator and denominator constants */
+#define VPBE_DISPLAY_H_EXP_RATIO_N	9
+#define VPBE_DISPLAY_H_EXP_RATIO_D	8
+#define VPBE_DISPLAY_V_EXP_RATIO_N	6
+#define VPBE_DISPLAY_V_EXP_RATIO_D	5
+
+/* Zoom multiplication factor */
+#define VPBE_DISPLAY_ZOOM_4X	4
+#define VPBE_DISPLAY_ZOOM_2X	2
+
+/* Structures */
+struct display_layer_info {
+	int enable;
+	/* Layer ID used by Display Manager */
+	enum osd_layer id;
+	struct osd_layer_config config;
+	enum osd_zoom_factor h_zoom;
+	enum osd_zoom_factor v_zoom;
+	enum osd_h_exp_ratio h_exp;
+	enum osd_v_exp_ratio v_exp;
+};
+
+struct vpbe_disp_buffer {
+	struct vb2_v4l2_buffer vb;
+	struct list_head list;
+};
+
+/* vpbe display object structure */
+struct vpbe_layer {
+	/* Pointer to the vpbe_display */
+	struct vpbe_display *disp_dev;
+	/* Pointer pointing to current v4l2_buffer */
+	struct vpbe_disp_buffer *cur_frm;
+	/* Pointer pointing to next v4l2_buffer */
+	struct vpbe_disp_buffer *next_frm;
+	/* videobuf specific parameters
+	 * Buffer queue used in video-buf
+	 */
+	struct vb2_queue buffer_queue;
+	/* Queue of filled frames */
+	struct list_head dma_queue;
+	/* Used in video-buf */
+	spinlock_t irqlock;
+	/* V4l2 specific parameters */
+	/* Identifies video device for this layer */
+	struct video_device video_dev;
+	/* Used to store pixel format */
+	struct v4l2_pix_format pix_fmt;
+	enum v4l2_field buf_field;
+	/* Video layer configuration params */
+	struct display_layer_info layer_info;
+	/* vpbe specific parameters
+	 * enable window for display
+	 */
+	unsigned char window_enable;
+	/* number of open instances of the layer */
+	unsigned int usrs;
+	/* Indicates id of the field which is being displayed */
+	unsigned int field_id;
+	/* Identifies device object */
+	enum vpbe_display_device_id device_id;
+	/* facilitation of ioctl ops lock by v4l2*/
+	struct mutex opslock;
+	u8 layer_first_int;
+};
+
+/* vpbe device structure */
+struct vpbe_display {
+	/* layer specific parameters */
+	/* lock for isr updates to buf layers*/
+	spinlock_t dma_queue_lock;
+	/* C-Plane offset from start of y-plane */
+	unsigned int cbcr_ofst;
+	struct vpbe_layer *dev[VPBE_DISPLAY_MAX_DEVICES];
+	struct vpbe_device *vpbe_dev;
+	struct osd_state *osd_device;
+};
+
+struct buf_config_params {
+	unsigned char min_numbuffers;
+	unsigned char numbuffers[VPBE_DISPLAY_MAX_DEVICES];
+	unsigned int min_bufsize[VPBE_DISPLAY_MAX_DEVICES];
+	unsigned int layer_bufsize[VPBE_DISPLAY_MAX_DEVICES];
+};
+
+#endif	/* VPBE_DISPLAY_H */
diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h
new file mode 100644
index 0000000..32f77bc
--- /dev/null
+++ b/include/media/davinci/vpbe_osd.h
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2007-2009 Texas Instruments Inc
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * Andy Lowe (alowe@mvista.com), MontaVista Software
+ * - Initial version
+ * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd.
+ * - ported to sub device interface
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2..
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _OSD_H
+#define _OSD_H
+
+#include <media/davinci/vpbe_types.h>
+
+#define DM644X_VPBE_OSD_SUBDEV_NAME	"dm644x,vpbe-osd"
+#define DM365_VPBE_OSD_SUBDEV_NAME	"dm365,vpbe-osd"
+#define DM355_VPBE_OSD_SUBDEV_NAME	"dm355,vpbe-osd"
+
+/**
+ * enum osd_layer
+ * @WIN_OSD0: On-Screen Display Window 0
+ * @WIN_VID0: Video Window 0
+ * @WIN_OSD1: On-Screen Display Window 1
+ * @WIN_VID1: Video Window 1
+ *
+ * Description:
+ * An enumeration of the osd display layers.
+ */
+enum osd_layer {
+	WIN_OSD0,
+	WIN_VID0,
+	WIN_OSD1,
+	WIN_VID1,
+};
+
+/**
+ * enum osd_win_layer
+ * @OSDWIN_OSD0: On-Screen Display Window 0
+ * @OSDWIN_OSD1: On-Screen Display Window 1
+ *
+ * Description:
+ * An enumeration of the OSD Window layers.
+ */
+enum osd_win_layer {
+	OSDWIN_OSD0,
+	OSDWIN_OSD1,
+};
+
+/**
+ * enum osd_pix_format
+ * @PIXFMT_1BPP: 1-bit-per-pixel bitmap
+ * @PIXFMT_2BPP: 2-bits-per-pixel bitmap
+ * @PIXFMT_4BPP: 4-bits-per-pixel bitmap
+ * @PIXFMT_8BPP: 8-bits-per-pixel bitmap
+ * @PIXFMT_RGB565: 16-bits-per-pixel RGB565
+ * @PIXFMT_YCbCrI: YUV 4:2:2
+ * @PIXFMT_RGB888: 24-bits-per-pixel RGB888
+ * @PIXFMT_YCrCbI: YUV 4:2:2 with chroma swap
+ * @PIXFMT_NV12: YUV 4:2:0 planar
+ * @PIXFMT_OSD_ATTR: OSD Attribute Window pixel format (4bpp)
+ *
+ * Description:
+ * An enumeration of the DaVinci pixel formats.
+ */
+enum osd_pix_format {
+	PIXFMT_1BPP = 0,
+	PIXFMT_2BPP,
+	PIXFMT_4BPP,
+	PIXFMT_8BPP,
+	PIXFMT_RGB565,
+	PIXFMT_YCBCRI,
+	PIXFMT_RGB888,
+	PIXFMT_YCRCBI,
+	PIXFMT_NV12,
+	PIXFMT_OSD_ATTR,
+};
+
+/**
+ * enum osd_h_exp_ratio
+ * @H_EXP_OFF: no expansion (1/1)
+ * @H_EXP_9_OVER_8: 9/8 expansion ratio
+ * @H_EXP_3_OVER_2: 3/2 expansion ratio
+ *
+ * Description:
+ * An enumeration of the available horizontal expansion ratios.
+ */
+enum osd_h_exp_ratio {
+	H_EXP_OFF,
+	H_EXP_9_OVER_8,
+	H_EXP_3_OVER_2,
+};
+
+/**
+ * enum osd_v_exp_ratio
+ * @V_EXP_OFF: no expansion (1/1)
+ * @V_EXP_6_OVER_5: 6/5 expansion ratio
+ *
+ * Description:
+ * An enumeration of the available vertical expansion ratios.
+ */
+enum osd_v_exp_ratio {
+	V_EXP_OFF,
+	V_EXP_6_OVER_5,
+};
+
+/**
+ * enum osd_zoom_factor
+ * @ZOOM_X1: no zoom (x1)
+ * @ZOOM_X2: x2 zoom
+ * @ZOOM_X4: x4 zoom
+ *
+ * Description:
+ * An enumeration of the available zoom factors.
+ */
+enum osd_zoom_factor {
+	ZOOM_X1,
+	ZOOM_X2,
+	ZOOM_X4,
+};
+
+/**
+ * enum osd_clut
+ * @ROM_CLUT: ROM CLUT
+ * @RAM_CLUT: RAM CLUT
+ *
+ * Description:
+ * An enumeration of the available Color Lookup Tables (CLUTs).
+ */
+enum osd_clut {
+	ROM_CLUT,
+	RAM_CLUT,
+};
+
+/**
+ * enum osd_rom_clut
+ * @ROM_CLUT0: Macintosh CLUT
+ * @ROM_CLUT1: CLUT from DM270 and prior devices
+ *
+ * Description:
+ * An enumeration of the ROM Color Lookup Table (CLUT) options.
+ */
+enum osd_rom_clut {
+	ROM_CLUT0,
+	ROM_CLUT1,
+};
+
+/**
+ * enum osd_blending_factor
+ * @OSD_0_VID_8: OSD pixels are fully transparent
+ * @OSD_1_VID_7: OSD pixels contribute 1/8, video pixels contribute 7/8
+ * @OSD_2_VID_6: OSD pixels contribute 2/8, video pixels contribute 6/8
+ * @OSD_3_VID_5: OSD pixels contribute 3/8, video pixels contribute 5/8
+ * @OSD_4_VID_4: OSD pixels contribute 4/8, video pixels contribute 4/8
+ * @OSD_5_VID_3: OSD pixels contribute 5/8, video pixels contribute 3/8
+ * @OSD_6_VID_2: OSD pixels contribute 6/8, video pixels contribute 2/8
+ * @OSD_8_VID_0: OSD pixels are fully opaque
+ *
+ * Description:
+ * An enumeration of the DaVinci pixel blending factor options.
+ */
+enum osd_blending_factor {
+	OSD_0_VID_8,
+	OSD_1_VID_7,
+	OSD_2_VID_6,
+	OSD_3_VID_5,
+	OSD_4_VID_4,
+	OSD_5_VID_3,
+	OSD_6_VID_2,
+	OSD_8_VID_0,
+};
+
+/**
+ * enum osd_blink_interval
+ * @BLINK_X1: blink interval is 1 vertical refresh cycle
+ * @BLINK_X2: blink interval is 2 vertical refresh cycles
+ * @BLINK_X3: blink interval is 3 vertical refresh cycles
+ * @BLINK_X4: blink interval is 4 vertical refresh cycles
+ *
+ * Description:
+ * An enumeration of the DaVinci pixel blinking interval options.
+ */
+enum osd_blink_interval {
+	BLINK_X1,
+	BLINK_X2,
+	BLINK_X3,
+	BLINK_X4,
+};
+
+/**
+ * enum osd_cursor_h_width
+ * @H_WIDTH_1: horizontal line width is 1 pixel
+ * @H_WIDTH_4: horizontal line width is 4 pixels
+ * @H_WIDTH_8: horizontal line width is 8 pixels
+ * @H_WIDTH_12: horizontal line width is 12 pixels
+ * @H_WIDTH_16: horizontal line width is 16 pixels
+ * @H_WIDTH_20: horizontal line width is 20 pixels
+ * @H_WIDTH_24: horizontal line width is 24 pixels
+ * @H_WIDTH_28: horizontal line width is 28 pixels
+ */
+enum osd_cursor_h_width {
+	H_WIDTH_1,
+	H_WIDTH_4,
+	H_WIDTH_8,
+	H_WIDTH_12,
+	H_WIDTH_16,
+	H_WIDTH_20,
+	H_WIDTH_24,
+	H_WIDTH_28,
+};
+
+/**
+ * enum davinci_cursor_v_width
+ * @V_WIDTH_1: vertical line width is 1 line
+ * @V_WIDTH_2: vertical line width is 2 lines
+ * @V_WIDTH_4: vertical line width is 4 lines
+ * @V_WIDTH_6: vertical line width is 6 lines
+ * @V_WIDTH_8: vertical line width is 8 lines
+ * @V_WIDTH_10: vertical line width is 10 lines
+ * @V_WIDTH_12: vertical line width is 12 lines
+ * @V_WIDTH_14: vertical line width is 14 lines
+ */
+enum osd_cursor_v_width {
+	V_WIDTH_1,
+	V_WIDTH_2,
+	V_WIDTH_4,
+	V_WIDTH_6,
+	V_WIDTH_8,
+	V_WIDTH_10,
+	V_WIDTH_12,
+	V_WIDTH_14,
+};
+
+/**
+ * struct osd_cursor_config
+ * @xsize: horizontal size in pixels
+ * @ysize: vertical size in lines
+ * @xpos: horizontal offset in pixels from the left edge of the display
+ * @ypos: vertical offset in lines from the top of the display
+ * @interlaced: Non-zero if the display is interlaced, or zero otherwise
+ * @h_width: horizontal line width
+ * @v_width: vertical line width
+ * @clut: the CLUT selector (ROM or RAM) for the cursor color
+ * @clut_index: an index into the CLUT for the cursor color
+ *
+ * Description:
+ * A structure describing the configuration parameters of the hardware
+ * rectangular cursor.
+ */
+struct osd_cursor_config {
+	unsigned xsize;
+	unsigned ysize;
+	unsigned xpos;
+	unsigned ypos;
+	int interlaced;
+	enum osd_cursor_h_width h_width;
+	enum osd_cursor_v_width v_width;
+	enum osd_clut clut;
+	unsigned char clut_index;
+};
+
+/**
+ * struct osd_layer_config
+ * @pixfmt: pixel format
+ * @line_length: offset in bytes between start of each line in memory
+ * @xsize: number of horizontal pixels displayed per line
+ * @ysize: number of lines displayed
+ * @xpos: horizontal offset in pixels from the left edge of the display
+ * @ypos: vertical offset in lines from the top of the display
+ * @interlaced: Non-zero if the display is interlaced, or zero otherwise
+ *
+ * Description:
+ * A structure describing the configuration parameters of an On-Screen Display
+ * (OSD) or video layer related to how the image is stored in memory.
+ * @line_length must be a multiple of the cache line size (32 bytes).
+ */
+struct osd_layer_config {
+	enum osd_pix_format pixfmt;
+	unsigned line_length;
+	unsigned xsize;
+	unsigned ysize;
+	unsigned xpos;
+	unsigned ypos;
+	int interlaced;
+};
+
+/* parameters that apply on a per-window (OSD or video) basis */
+struct osd_window_state {
+	int is_allocated;
+	int is_enabled;
+	unsigned long fb_base_phys;
+	enum osd_zoom_factor h_zoom;
+	enum osd_zoom_factor v_zoom;
+	struct osd_layer_config lconfig;
+};
+
+/* parameters that apply on a per-OSD-window basis */
+struct osd_osdwin_state {
+	enum osd_clut clut;
+	enum osd_blending_factor blend;
+	int colorkey_blending;
+	unsigned colorkey;
+	int rec601_attenuation;
+	/* index is pixel value */
+	unsigned char palette_map[16];
+};
+
+/* hardware rectangular cursor parameters */
+struct osd_cursor_state {
+	int is_enabled;
+	struct osd_cursor_config config;
+};
+
+struct osd_state;
+
+struct vpbe_osd_ops {
+	int (*initialize)(struct osd_state *sd);
+	int (*request_layer)(struct osd_state *sd, enum osd_layer layer);
+	void (*release_layer)(struct osd_state *sd, enum osd_layer layer);
+	int (*enable_layer)(struct osd_state *sd, enum osd_layer layer,
+			    int otherwin);
+	void (*disable_layer)(struct osd_state *sd, enum osd_layer layer);
+	int (*set_layer_config)(struct osd_state *sd, enum osd_layer layer,
+				struct osd_layer_config *lconfig);
+	void (*get_layer_config)(struct osd_state *sd, enum osd_layer layer,
+				 struct osd_layer_config *lconfig);
+	void (*start_layer)(struct osd_state *sd, enum osd_layer layer,
+			    unsigned long fb_base_phys,
+			    unsigned long cbcr_ofst);
+	void (*set_left_margin)(struct osd_state *sd, u32 val);
+	void (*set_top_margin)(struct osd_state *sd, u32 val);
+	void (*set_interpolation_filter)(struct osd_state *sd, int filter);
+	int (*set_vid_expansion)(struct osd_state *sd,
+					enum osd_h_exp_ratio h_exp,
+					enum osd_v_exp_ratio v_exp);
+	void (*get_vid_expansion)(struct osd_state *sd,
+					enum osd_h_exp_ratio *h_exp,
+					enum osd_v_exp_ratio *v_exp);
+	void (*set_zoom)(struct osd_state *sd, enum osd_layer layer,
+				enum osd_zoom_factor h_zoom,
+				enum osd_zoom_factor v_zoom);
+};
+
+struct osd_state {
+	enum vpbe_version vpbe_type;
+	spinlock_t lock;
+	struct device *dev;
+	dma_addr_t osd_base_phys;
+	void __iomem *osd_base;
+	unsigned long osd_size;
+	/* 1-->the isr will toggle the VID0 ping-pong buffer */
+	int pingpong;
+	int interpolation_filter;
+	int field_inversion;
+	enum osd_h_exp_ratio osd_h_exp;
+	enum osd_v_exp_ratio osd_v_exp;
+	enum osd_h_exp_ratio vid_h_exp;
+	enum osd_v_exp_ratio vid_v_exp;
+	enum osd_clut backg_clut;
+	unsigned backg_clut_index;
+	enum osd_rom_clut rom_clut;
+	int is_blinking;
+	/* attribute window blinking enabled */
+	enum osd_blink_interval blink;
+	/* YCbCrI or YCrCbI */
+	enum osd_pix_format yc_pixfmt;
+	/* columns are Y, Cb, Cr */
+	unsigned char clut_ram[256][3];
+	struct osd_cursor_state cursor;
+	/* OSD0, VID0, OSD1, VID1 */
+	struct osd_window_state win[4];
+	/* OSD0, OSD1 */
+	struct osd_osdwin_state osdwin[2];
+	/* OSD device Operations */
+	struct vpbe_osd_ops ops;
+};
+
+struct osd_platform_data {
+	int  field_inv_wa_enable;
+};
+
+#endif
diff --git a/include/media/davinci/vpbe_types.h b/include/media/davinci/vpbe_types.h
new file mode 100644
index 0000000..c10690b
--- /dev/null
+++ b/include/media/davinci/vpbe_types.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _VPBE_TYPES_H
+#define _VPBE_TYPES_H
+
+enum vpbe_version {
+	VPBE_VERSION_1 = 1,
+	VPBE_VERSION_2,
+	VPBE_VERSION_3,
+};
+
+/* vpbe_timing_type - Timing types used in vpbe device */
+enum vpbe_enc_timings_type {
+	VPBE_ENC_STD = 0x1,
+	VPBE_ENC_DV_TIMINGS = 0x4,
+	/* Used when set timings through FB device interface */
+	VPBE_ENC_TIMINGS_INVALID = 0x8,
+};
+
+/*
+ * struct vpbe_enc_mode_info
+ * @name: ptr to name string of the standard, "NTSC", "PAL" etc
+ * @std: standard or non-standard mode. 1 - standard, 0 - nonstandard
+ * @interlaced: 1 - interlaced, 0 - non interlaced/progressive
+ * @xres: x or horizontal resolution of the display
+ * @yres: y or vertical resolution of the display
+ * @fps: frame per second
+ * @left_margin: left margin of the display
+ * @right_margin: right margin of the display
+ * @upper_margin: upper margin of the display
+ * @lower_margin: lower margin of the display
+ * @hsync_len: h-sync length
+ * @vsync_len: v-sync length
+ * @flags: bit field: bit usage is documented below
+ *
+ * Description:
+ *  Structure holding timing and resolution information of a standard.
+ * Used by vpbe_device to set required non-standard timing in the
+ * venc when lcd controller output is connected to a external encoder.
+ * A table of timings is maintained in vpbe device to set this in
+ * venc when external encoder is connected to lcd controller output.
+ * Encoder may provide a g_dv_timings() API to override these values
+ * as needed.
+ *
+ *  Notes
+ *  ------
+ *  if_type should be used only by encoder manager and encoder.
+ *  flags usage
+ *     b0 (LSB) - hsync polarity, 0 - negative, 1 - positive
+ *     b1       - vsync polarity, 0 - negative, 1 - positive
+ *     b2       - field id polarity, 0 - negative, 1  - positive
+ */
+struct vpbe_enc_mode_info {
+	unsigned char *name;
+	enum vpbe_enc_timings_type timings_type;
+	v4l2_std_id std_id;
+	struct v4l2_dv_timings dv_timings;
+	unsigned int interlaced;
+	unsigned int xres;
+	unsigned int yres;
+	struct v4l2_fract aspect;
+	struct v4l2_fract fps;
+	unsigned int left_margin;
+	unsigned int right_margin;
+	unsigned int upper_margin;
+	unsigned int lower_margin;
+	unsigned int hsync_len;
+	unsigned int vsync_len;
+	unsigned int flags;
+};
+
+#endif
diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h
new file mode 100644
index 0000000..e32617b
--- /dev/null
+++ b/include/media/davinci/vpbe_venc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _VPBE_VENC_H
+#define _VPBE_VENC_H
+
+#include <media/v4l2-subdev.h>
+#include <media/davinci/vpbe_types.h>
+
+#define DM644X_VPBE_VENC_SUBDEV_NAME	"dm644x,vpbe-venc"
+#define DM365_VPBE_VENC_SUBDEV_NAME	"dm365,vpbe-venc"
+#define DM355_VPBE_VENC_SUBDEV_NAME	"dm355,vpbe-venc"
+
+/* venc events */
+#define VENC_END_OF_FRAME	BIT(0)
+#define VENC_FIRST_FIELD	BIT(1)
+#define VENC_SECOND_FIELD	BIT(2)
+
+struct venc_platform_data {
+	int (*setup_pinmux)(u32 if_type, int field);
+	int (*setup_clock)(enum vpbe_enc_timings_type type,
+			   unsigned int pixclock);
+	int (*setup_if_config)(u32 pixcode);
+	/* Number of LCD outputs supported */
+	int num_lcd_outputs;
+	struct vpbe_if_params *lcd_if_params;
+};
+
+enum venc_ioctls {
+	VENC_GET_FLD = 1,
+};
+
+/* exported functions */
+struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
+		const char *venc_name);
+#endif
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
new file mode 100644
index 0000000..f003533
--- /dev/null
+++ b/include/media/davinci/vpfe_capture.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _VPFE_CAPTURE_H
+#define _VPFE_CAPTURE_H
+
+#ifdef __KERNEL__
+
+/* Header files */
+#include <media/v4l2-dev.h>
+#include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/davinci/vpfe_types.h>
+
+#define VPFE_CAPTURE_NUM_DECODERS        5
+
+/* Macros */
+#define VPFE_MAJOR_RELEASE              0
+#define VPFE_MINOR_RELEASE              0
+#define VPFE_BUILD                      1
+#define VPFE_CAPTURE_VERSION_CODE       ((VPFE_MAJOR_RELEASE << 16) | \
+					(VPFE_MINOR_RELEASE << 8)  | \
+					VPFE_BUILD)
+
+#define CAPTURE_DRV_NAME		"vpfe-capture"
+
+struct vpfe_pixel_format {
+	struct v4l2_fmtdesc fmtdesc;
+	/* bytes per pixel */
+	int bpp;
+};
+
+struct vpfe_std_info {
+	int active_pixels;
+	int active_lines;
+	/* current frame format */
+	int frame_format;
+};
+
+struct vpfe_route {
+	u32 input;
+	u32 output;
+};
+
+struct vpfe_subdev_info {
+	/* Sub device name */
+	char name[32];
+	/* Sub device group id */
+	int grp_id;
+	/* Number of inputs supported */
+	int num_inputs;
+	/* inputs available at the sub device */
+	struct v4l2_input *inputs;
+	/* Sub dev routing information for each input */
+	struct vpfe_route *routes;
+	/* check if sub dev supports routing */
+	int can_route;
+	/* ccdc bus/interface configuration */
+	struct vpfe_hw_if_param ccdc_if_params;
+	/* i2c subdevice board info */
+	struct i2c_board_info board_info;
+};
+
+struct vpfe_config {
+	/* Number of sub devices connected to vpfe */
+	int num_subdevs;
+	/* i2c bus adapter no */
+	int i2c_adapter_id;
+	/* information about each subdev */
+	struct vpfe_subdev_info *sub_devs;
+	/* evm card info */
+	char *card_name;
+	/* ccdc name */
+	char *ccdc;
+	/* vpfe clock */
+	struct clk *vpssclk;
+	struct clk *slaveclk;
+	/* Function for Clearing the interrupt */
+	void (*clr_intr)(int vdint);
+};
+
+struct vpfe_device {
+	/* V4l2 specific parameters */
+	/* Identifies video device for this channel */
+	struct video_device video_dev;
+	/* sub devices */
+	struct v4l2_subdev **sd;
+	/* vpfe cfg */
+	struct vpfe_config *cfg;
+	/* V4l2 device */
+	struct v4l2_device v4l2_dev;
+	/* parent device */
+	struct device *pdev;
+	/* number of open instances of the channel */
+	u32 usrs;
+	/* Indicates id of the field which is being displayed */
+	u32 field_id;
+	/* flag to indicate whether decoder is initialized */
+	u8 initialized;
+	/* current interface type */
+	struct vpfe_hw_if_param vpfe_if_params;
+	/* ptr to currently selected sub device */
+	struct vpfe_subdev_info *current_subdev;
+	/* current input at the sub device */
+	int current_input;
+	/* Keeps track of the information about the standard */
+	struct vpfe_std_info std_info;
+	/* std index into std table */
+	int std_index;
+	/* CCDC IRQs used when CCDC/ISIF output to SDRAM */
+	unsigned int ccdc_irq0;
+	unsigned int ccdc_irq1;
+	/* number of buffers in fbuffers */
+	u32 numbuffers;
+	/* List of buffer pointers for storing frames */
+	u8 *fbuffers[VIDEO_MAX_FRAME];
+	/* Pointer pointing to current v4l2_buffer */
+	struct videobuf_buffer *cur_frm;
+	/* Pointer pointing to next v4l2_buffer */
+	struct videobuf_buffer *next_frm;
+	/*
+	 * This field keeps track of type of buffer exchange mechanism
+	 * user has selected
+	 */
+	enum v4l2_memory memory;
+	/* Used to store pixel format */
+	struct v4l2_format fmt;
+	/*
+	 * used when IMP is chained to store the crop window which
+	 * is different from the image window
+	 */
+	struct v4l2_rect crop;
+	/* Buffer queue used in video-buf */
+	struct videobuf_queue buffer_queue;
+	/* Queue of filled frames */
+	struct list_head dma_queue;
+	/* Used in video-buf */
+	spinlock_t irqlock;
+	/* IRQ lock for DMA queue */
+	spinlock_t dma_queue_lock;
+	/* lock used to access this structure */
+	struct mutex lock;
+	/* number of users performing IO */
+	u32 io_usrs;
+	/* Indicates whether streaming started */
+	u8 started;
+	/*
+	 * offset where second field starts from the starting of the
+	 * buffer for field separated YCbCr formats
+	 */
+	u32 field_off;
+};
+
+/* File handle structure */
+struct vpfe_fh {
+	struct v4l2_fh fh;
+	struct vpfe_device *vpfe_dev;
+	/* Indicates whether this file handle is doing IO */
+	u8 io_allowed;
+};
+
+struct vpfe_config_params {
+	u8 min_numbuffers;
+	u8 numbuffers;
+	u32 min_bufsize;
+	u32 device_bufsize;
+};
+
+#endif				/* End of __KERNEL__ */
+#endif				/* _DAVINCI_VPFE_H */
diff --git a/include/media/davinci/vpfe_types.h b/include/media/davinci/vpfe_types.h
new file mode 100644
index 0000000..498a274
--- /dev/null
+++ b/include/media/davinci/vpfe_types.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option)any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _VPFE_TYPES_H
+#define _VPFE_TYPES_H
+
+#ifdef __KERNEL__
+
+enum vpfe_pin_pol {
+	VPFE_PINPOL_POSITIVE,
+	VPFE_PINPOL_NEGATIVE
+};
+
+enum vpfe_hw_if_type {
+	/* BT656 - 8 bit */
+	VPFE_BT656,
+	/* BT1120 - 16 bit */
+	VPFE_BT1120,
+	/* Raw Bayer */
+	VPFE_RAW_BAYER,
+	/* YCbCr - 8 bit with external sync */
+	VPFE_YCBCR_SYNC_8,
+	/* YCbCr - 16 bit with external sync */
+	VPFE_YCBCR_SYNC_16,
+	/* BT656 - 10 bit */
+	VPFE_BT656_10BIT
+};
+
+/* interface description */
+struct vpfe_hw_if_param {
+	enum vpfe_hw_if_type if_type;
+	enum vpfe_pin_pol hdpol;
+	enum vpfe_pin_pol vdpol;
+};
+
+#endif
+#endif
diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h
new file mode 100644
index 0000000..eae23e4
--- /dev/null
+++ b/include/media/davinci/vpif_types.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef _VPIF_TYPES_H
+#define _VPIF_TYPES_H
+
+#include <linux/i2c.h>
+
+#define VPIF_CAPTURE_MAX_CHANNELS	2
+#define VPIF_DISPLAY_MAX_CHANNELS	2
+
+enum vpif_if_type {
+	VPIF_IF_BT656,
+	VPIF_IF_BT1120,
+	VPIF_IF_RAW_BAYER
+};
+
+struct vpif_interface {
+	enum vpif_if_type if_type;
+	unsigned hd_pol:1;
+	unsigned vd_pol:1;
+	unsigned fid_pol:1;
+};
+
+struct vpif_subdev_info {
+	const char *name;
+	struct i2c_board_info board_info;
+};
+
+struct vpif_output {
+	struct v4l2_output output;
+	const char *subdev_name;
+	u32 input_route;
+	u32 output_route;
+};
+
+struct vpif_display_chan_config {
+	const struct vpif_output *outputs;
+	int output_count;
+	bool clip_en;
+};
+
+struct vpif_display_config {
+	int (*set_clock)(int, int);
+	struct vpif_subdev_info *subdevinfo;
+	int subdev_count;
+	int i2c_adapter_id;
+	struct vpif_display_chan_config chan_config[VPIF_DISPLAY_MAX_CHANNELS];
+	const char *card_name;
+	struct v4l2_async_subdev **asd;	/* Flat array, arranged in groups */
+	int *asd_sizes;		/* 0-terminated array of asd group sizes */
+};
+
+struct vpif_input {
+	struct v4l2_input input;
+	char *subdev_name;
+	u32 input_route;
+	u32 output_route;
+};
+
+struct vpif_capture_chan_config {
+	struct vpif_interface vpif_if;
+	struct vpif_input *inputs;
+	int input_count;
+};
+
+struct vpif_capture_config {
+	int (*setup_input_channel_mode)(int);
+	int (*setup_input_path)(int, const char *);
+	struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS];
+	struct vpif_subdev_info *subdev_info;
+	int subdev_count;
+	int i2c_adapter_id;
+	const char *card_name;
+
+	struct v4l2_async_subdev *asd[VPIF_CAPTURE_MAX_CHANNELS];
+	int asd_sizes[VPIF_CAPTURE_MAX_CHANNELS];
+};
+#endif /* _VPIF_TYPES_H */
diff --git a/include/media/davinci/vpss.h b/include/media/davinci/vpss.h
new file mode 100644
index 0000000..98e7f41
--- /dev/null
+++ b/include/media/davinci/vpss.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * vpss - video processing subsystem module header file.
+ *
+ * Include this header file if a driver needs to configure vpss system
+ * module. It exports a set of library functions  for video drivers to
+ * configure vpss system module functions such as clock enable/disable,
+ * vpss interrupt mux to arm, and other common vpss system module
+ * functions.
+ */
+#ifndef _VPSS_H
+#define _VPSS_H
+
+/* selector for ccdc input selection on DM355 */
+enum vpss_ccdc_source_sel {
+	VPSS_CCDCIN,
+	VPSS_HSSIIN,
+	VPSS_PGLPBK,	/* for DM365 only */
+	VPSS_CCDCPG	/* for DM365 only */
+};
+
+struct vpss_sync_pol {
+	unsigned int ccdpg_hdpol:1;
+	unsigned int ccdpg_vdpol:1;
+};
+
+struct vpss_pg_frame_size {
+	short hlpfr;
+	short pplen;
+};
+
+/* Used for enable/disable VPSS Clock */
+enum vpss_clock_sel {
+	/* DM355/DM365 */
+	VPSS_CCDC_CLOCK,
+	VPSS_IPIPE_CLOCK,
+	VPSS_H3A_CLOCK,
+	VPSS_CFALD_CLOCK,
+	/*
+	 * When using VPSS_VENC_CLOCK_SEL in vpss_enable_clock() api
+	 * following applies:-
+	 * en = 0 selects ENC_CLK
+	 * en = 1 selects ENC_CLK/2
+	 */
+	VPSS_VENC_CLOCK_SEL,
+	VPSS_VPBE_CLOCK,
+	/* DM365 only clocks */
+	VPSS_IPIPEIF_CLOCK,
+	VPSS_RSZ_CLOCK,
+	VPSS_BL_CLOCK,
+	/*
+	 * When using VPSS_PCLK_INTERNAL in vpss_enable_clock() api
+	 * following applies:-
+	 * en = 0 disable internal PCLK
+	 * en = 1 enables internal PCLK
+	 */
+	VPSS_PCLK_INTERNAL,
+	/*
+	 * When using VPSS_PSYNC_CLOCK_SEL in vpss_enable_clock() api
+	 * following applies:-
+	 * en = 0 enables MMR clock
+	 * en = 1 enables VPSS clock
+	 */
+	VPSS_PSYNC_CLOCK_SEL,
+	VPSS_LDC_CLOCK_SEL,
+	VPSS_OSD_CLOCK_SEL,
+	VPSS_FDIF_CLOCK,
+	VPSS_LDC_CLOCK
+};
+
+/* select input to ccdc on dm355 */
+int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel);
+/* enable/disable a vpss clock, 0 - success, -1 - failure */
+int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en);
+/* set sync polarity, only for DM365*/
+void dm365_vpss_set_sync_pol(struct vpss_sync_pol);
+/* set the PG_FRAME_SIZE register, only for DM365 */
+void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size);
+
+/* wbl reset for dm644x */
+enum vpss_wbl_sel {
+	VPSS_PCR_AEW_WBL_0 = 16,
+	VPSS_PCR_AF_WBL_0,
+	VPSS_PCR_RSZ4_WBL_0,
+	VPSS_PCR_RSZ3_WBL_0,
+	VPSS_PCR_RSZ2_WBL_0,
+	VPSS_PCR_RSZ1_WBL_0,
+	VPSS_PCR_PREV_WBL_0,
+	VPSS_PCR_CCDC_WBL_O,
+};
+/* clear wbl overflow flag for DM6446 */
+int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel);
+
+/* set sync polarity*/
+void vpss_set_sync_pol(struct vpss_sync_pol sync);
+/* set the PG_FRAME_SIZE register */
+void vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size);
+/*
+ * vpss_check_and_clear_interrupt - check and clear interrupt
+ * @irq - common enumerator for IRQ
+ *
+ * Following return values used:-
+ * 0 - interrupt occurred and cleared
+ * 1 - interrupt not occurred
+ * 2 - interrupt status not available
+ */
+int vpss_dma_complete_interrupt(void);
+
+#endif
diff --git a/include/media/demux.h b/include/media/demux.h
new file mode 100644
index 0000000..bf00a5a
--- /dev/null
+++ b/include/media/demux.h
@@ -0,0 +1,600 @@
+/*
+ * demux.h
+ *
+ * The Kernel Digital TV Demux kABI defines a driver-internal interface for
+ * registering low-level, hardware specific driver to a hardware independent
+ * demux layer.
+ *
+ * Copyright (c) 2002 Convergence GmbH
+ *
+ * based on code:
+ * Copyright (c) 2000 Nokia Research Center
+ *                    Tampere, FINLAND
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DEMUX_H
+#define __DEMUX_H
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/time.h>
+#include <linux/dvb/dmx.h>
+
+/*
+ * Common definitions
+ */
+
+/*
+ * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
+ */
+
+#ifndef DMX_MAX_FILTER_SIZE
+#define DMX_MAX_FILTER_SIZE 18
+#endif
+
+/*
+ * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed
+ * filter.
+ */
+
+#ifndef DMX_MAX_SECTION_SIZE
+#define DMX_MAX_SECTION_SIZE 4096
+#endif
+#ifndef DMX_MAX_SECFEED_SIZE
+#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
+#endif
+
+/*
+ * TS packet reception
+ */
+
+/**
+ * enum ts_filter_type - filter type bitmap for dmx_ts_feed.set\(\)
+ *
+ * @TS_PACKET:		Send TS packets (188 bytes) to callback (default).
+ * @TS_PAYLOAD_ONLY:	In case TS_PACKET is set, only send the TS payload
+ *			(<=184 bytes per packet) to callback
+ * @TS_DECODER:		Send stream to built-in decoder (if present).
+ * @TS_DEMUX:		In case TS_PACKET is set, send the TS to the demux
+ *			device, not to the dvr device
+ */
+enum ts_filter_type {
+	TS_PACKET = 1,
+	TS_PAYLOAD_ONLY = 2,
+	TS_DECODER = 4,
+	TS_DEMUX = 8,
+};
+
+/**
+ * struct dmx_ts_feed - Structure that contains a TS feed filter
+ *
+ * @is_filtering:	Set to non-zero when filtering in progress
+ * @parent:		pointer to struct dmx_demux
+ * @priv:		pointer to private data of the API client
+ * @set:		sets the TS filter
+ * @start_filtering:	starts TS filtering
+ * @stop_filtering:	stops TS filtering
+ *
+ * A TS feed is typically mapped to a hardware PID filter on the demux chip.
+ * Using this API, the client can set the filtering properties to start/stop
+ * filtering TS packets on a particular TS feed.
+ */
+struct dmx_ts_feed {
+	int is_filtering;
+	struct dmx_demux *parent;
+	void *priv;
+	int (*set)(struct dmx_ts_feed *feed,
+		   u16 pid,
+		   int type,
+		   enum dmx_ts_pes pes_type,
+		   ktime_t timeout);
+	int (*start_filtering)(struct dmx_ts_feed *feed);
+	int (*stop_filtering)(struct dmx_ts_feed *feed);
+};
+
+/*
+ * Section reception
+ */
+
+/**
+ * struct dmx_section_filter - Structure that describes a section filter
+ *
+ * @filter_value: Contains up to 16 bytes (128 bits) of the TS section header
+ *		  that will be matched by the section filter
+ * @filter_mask:  Contains a 16 bytes (128 bits) filter mask with the bits
+ *		  specified by @filter_value that will be used on the filter
+ *		  match logic.
+ * @filter_mode:  Contains a 16 bytes (128 bits) filter mode.
+ * @parent:	  Back-pointer to struct dmx_section_feed.
+ * @priv:	  Pointer to private data of the API client.
+ *
+ *
+ * The @filter_mask controls which bits of @filter_value are compared with
+ * the section headers/payload. On a binary value of 1 in filter_mask, the
+ * corresponding bits are compared. The filter only accepts sections that are
+ * equal to filter_value in all the tested bit positions.
+ */
+struct dmx_section_filter {
+	u8 filter_value[DMX_MAX_FILTER_SIZE];
+	u8 filter_mask[DMX_MAX_FILTER_SIZE];
+	u8 filter_mode[DMX_MAX_FILTER_SIZE];
+	struct dmx_section_feed *parent;
+
+	void *priv;
+};
+
+/**
+ * struct dmx_section_feed - Structure that contains a section feed filter
+ *
+ * @is_filtering:	Set to non-zero when filtering in progress
+ * @parent:		pointer to struct dmx_demux
+ * @priv:		pointer to private data of the API client
+ * @check_crc:		If non-zero, check the CRC values of filtered sections.
+ * @set:		sets the section filter
+ * @allocate_filter:	This function is used to allocate a section filter on
+ *			the demux. It should only be called when no filtering
+ *			is in progress on this section feed. If a filter cannot
+ *			be allocated, the function fails with -ENOSPC.
+ * @release_filter:	This function releases all the resources of a
+ *			previously allocated section filter. The function
+ *			should not be called while filtering is in progress
+ *			on this section feed. After calling this function,
+ *			the caller should not try to dereference the filter
+ *			pointer.
+ * @start_filtering:	starts section filtering
+ * @stop_filtering:	stops section filtering
+ *
+ * A TS feed is typically mapped to a hardware PID filter on the demux chip.
+ * Using this API, the client can set the filtering properties to start/stop
+ * filtering TS packets on a particular TS feed.
+ */
+struct dmx_section_feed {
+	int is_filtering;
+	struct dmx_demux *parent;
+	void *priv;
+
+	int check_crc;
+
+	/* private: Used internally at dvb_demux.c */
+	u32 crc_val;
+
+	u8 *secbuf;
+	u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
+	u16 secbufp, seclen, tsfeedp;
+
+	/* public: */
+	int (*set)(struct dmx_section_feed *feed,
+		   u16 pid,
+		   int check_crc);
+	int (*allocate_filter)(struct dmx_section_feed *feed,
+			       struct dmx_section_filter **filter);
+	int (*release_filter)(struct dmx_section_feed *feed,
+			      struct dmx_section_filter *filter);
+	int (*start_filtering)(struct dmx_section_feed *feed);
+	int (*stop_filtering)(struct dmx_section_feed *feed);
+};
+
+/**
+ * typedef dmx_ts_cb - DVB demux TS filter callback function prototype
+ *
+ * @buffer1:		Pointer to the start of the filtered TS packets.
+ * @buffer1_length:	Length of the TS data in buffer1.
+ * @buffer2:		Pointer to the tail of the filtered TS packets, or NULL.
+ * @buffer2_length:	Length of the TS data in buffer2.
+ * @source:		Indicates which TS feed is the source of the callback.
+ * @buffer_flags:	Address where buffer flags are stored. Those are
+ *			used to report discontinuity users via DVB
+ *			memory mapped API, as defined by
+ *			&enum dmx_buffer_flags.
+ *
+ * This function callback prototype, provided by the client of the demux API,
+ * is called from the demux code. The function is only called when filtering
+ * on a TS feed has been enabled using the start_filtering\(\) function at
+ * the &dmx_demux.
+ * Any TS packets that match the filter settings are copied to a circular
+ * buffer. The filtered TS packets are delivered to the client using this
+ * callback function.
+ * It is expected that the @buffer1 and @buffer2 callback parameters point to
+ * addresses within the circular buffer, but other implementations are also
+ * possible. Note that the called party should not try to free the memory
+ * the @buffer1 and @buffer2 parameters point to.
+ *
+ * When this function is called, the @buffer1 parameter typically points to
+ * the start of the first undelivered TS packet within a circular buffer.
+ * The @buffer2 buffer parameter is normally NULL, except when the received
+ * TS packets have crossed the last address of the circular buffer and
+ * "wrapped" to the beginning of the buffer. In the latter case the @buffer1
+ * parameter would contain an address within the circular buffer, while the
+ * @buffer2 parameter would contain the first address of the circular buffer.
+ * The number of bytes delivered with this function (i.e. @buffer1_length +
+ * @buffer2_length) is usually equal to the value of callback_length parameter
+ * given in the set() function, with one exception: if a timeout occurs before
+ * receiving callback_length bytes of TS data, any undelivered packets are
+ * immediately delivered to the client by calling this function. The timeout
+ * duration is controlled by the set() function in the TS Feed API.
+ *
+ * If a TS packet is received with errors that could not be fixed by the
+ * TS-level forward error correction (FEC), the Transport_error_indicator
+ * flag of the TS packet header should be set. The TS packet should not be
+ * discarded, as the error can possibly be corrected by a higher layer
+ * protocol. If the called party is slow in processing the callback, it
+ * is possible that the circular buffer eventually fills up. If this happens,
+ * the demux driver should discard any TS packets received while the buffer
+ * is full and return -EOVERFLOW.
+ *
+ * The type of data returned to the callback can be selected by the
+ * &dmx_ts_feed.@set function. The type parameter decides if the raw
+ * TS packet (TS_PACKET) or just the payload (TS_PACKET|TS_PAYLOAD_ONLY)
+ * should be returned. If additionally the TS_DECODER bit is set the stream
+ * will also be sent to the hardware MPEG decoder.
+ *
+ * Return:
+ *
+ * - 0, on success;
+ *
+ * - -EOVERFLOW, on buffer overflow.
+ */
+typedef int (*dmx_ts_cb)(const u8 *buffer1,
+			 size_t buffer1_length,
+			 const u8 *buffer2,
+			 size_t buffer2_length,
+			 struct dmx_ts_feed *source,
+			 u32 *buffer_flags);
+
+/**
+ * typedef dmx_section_cb - DVB demux TS filter callback function prototype
+ *
+ * @buffer1:		Pointer to the start of the filtered section, e.g.
+ *			within the circular buffer of the demux driver.
+ * @buffer1_len:	Length of the filtered section data in @buffer1,
+ *			including headers and CRC.
+ * @buffer2:		Pointer to the tail of the filtered section data,
+ *			or NULL. Useful to handle the wrapping of a
+ *			circular buffer.
+ * @buffer2_len:	Length of the filtered section data in @buffer2,
+ *			including headers and CRC.
+ * @source:		Indicates which section feed is the source of the
+ *			callback.
+ * @buffer_flags:	Address where buffer flags are stored. Those are
+ *			used to report discontinuity users via DVB
+ *			memory mapped API, as defined by
+ *			&enum dmx_buffer_flags.
+ *
+ * This function callback prototype, provided by the client of the demux API,
+ * is called from the demux code. The function is only called when
+ * filtering of sections has been enabled using the function
+ * &dmx_ts_feed.@start_filtering. When the demux driver has received a
+ * complete section that matches at least one section filter, the client
+ * is notified via this callback function. Normally this function is called
+ * for each received section; however, it is also possible to deliver
+ * multiple sections with one callback, for example when the system load
+ * is high. If an error occurs while receiving a section, this
+ * function should be called with the corresponding error type set in the
+ * success field, whether or not there is data to deliver. The Section Feed
+ * implementation should maintain a circular buffer for received sections.
+ * However, this is not necessary if the Section Feed API is implemented as
+ * a client of the TS Feed API, because the TS Feed implementation then
+ * buffers the received data. The size of the circular buffer can be
+ * configured using the &dmx_ts_feed.@set function in the Section Feed API.
+ * If there is no room in the circular buffer when a new section is received,
+ * the section must be discarded. If this happens, the value of the success
+ * parameter should be DMX_OVERRUN_ERROR on the next callback.
+ */
+typedef int (*dmx_section_cb)(const u8 *buffer1,
+			      size_t buffer1_len,
+			      const u8 *buffer2,
+			      size_t buffer2_len,
+			      struct dmx_section_filter *source,
+			      u32 *buffer_flags);
+
+/*
+ * DVB Front-End
+ */
+
+/**
+ * enum dmx_frontend_source - Used to identify the type of frontend
+ *
+ * @DMX_MEMORY_FE:	The source of the demux is memory. It means that
+ *			the MPEG-TS to be filtered comes from userspace,
+ *			via write() syscall.
+ *
+ * @DMX_FRONTEND_0:	The source of the demux is a frontend connected
+ *			to the demux.
+ */
+enum dmx_frontend_source {
+	DMX_MEMORY_FE,
+	DMX_FRONTEND_0,
+};
+
+/**
+ * struct dmx_frontend - Structure that lists the frontends associated with
+ *			 a demux
+ *
+ * @connectivity_list:	List of front-ends that can be connected to a
+ *			particular demux;
+ * @source:		Type of the frontend.
+ *
+ * FIXME: this structure should likely be replaced soon by some
+ *	media-controller based logic.
+ */
+struct dmx_frontend {
+	struct list_head connectivity_list;
+	enum dmx_frontend_source source;
+};
+
+/*
+ * MPEG-2 TS Demux
+ */
+
+/**
+ * enum dmx_demux_caps - MPEG-2 TS Demux capabilities bitmap
+ *
+ * @DMX_TS_FILTERING:		set if TS filtering is supported;
+ * @DMX_SECTION_FILTERING:	set if section filtering is supported;
+ * @DMX_MEMORY_BASED_FILTERING:	set if write() available.
+ *
+ * Those flags are OR'ed in the &dmx_demux.capabilities field
+ */
+enum dmx_demux_caps {
+	DMX_TS_FILTERING = 1,
+	DMX_SECTION_FILTERING = 4,
+	DMX_MEMORY_BASED_FILTERING = 8,
+};
+
+/*
+ * Demux resource type identifier.
+ */
+
+/**
+ * DMX_FE_ENTRY - Casts elements in the list of registered
+ *		  front-ends from the generic type struct list_head
+ *		  to the type * struct dmx_frontend
+ *
+ * @list: list of struct dmx_frontend
+ */
+#define DMX_FE_ENTRY(list) \
+	list_entry(list, struct dmx_frontend, connectivity_list)
+
+/**
+ * struct dmx_demux - Structure that contains the demux capabilities and
+ *		      callbacks.
+ *
+ * @capabilities: Bitfield of capability flags.
+ *
+ * @frontend: Front-end connected to the demux
+ *
+ * @priv: Pointer to private data of the API client
+ *
+ * @open: This function reserves the demux for use by the caller and, if
+ *	necessary, initializes the demux. When the demux is no longer needed,
+ *	the function @close should be called. It should be possible for
+ *	multiple clients to access the demux at the same time. Thus, the
+ *	function implementation should increment the demux usage count when
+ *	@open is called and decrement it when @close is called.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-EUSERS, if maximum usage count was reached;
+ *	-EINVAL, on bad parameter.
+ *
+ * @close: This function reserves the demux for use by the caller and, if
+ *	necessary, initializes the demux. When the demux is no longer needed,
+ *	the function @close should be called. It should be possible for
+ *	multiple clients to access the demux at the same time. Thus, the
+ *	function implementation should increment the demux usage count when
+ *	@open is called and decrement it when @close is called.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-ENODEV, if demux was not in use (e. g. no users);
+ *	-EINVAL, on bad parameter.
+ *
+ * @write: This function provides the demux driver with a memory buffer
+ *	containing TS packets. Instead of receiving TS packets from the DVB
+ *	front-end, the demux driver software will read packets from memory.
+ *	Any clients of this demux with active TS, PES or Section filters will
+ *	receive filtered data via the Demux callback API (see 0). The function
+ *	returns when all the data in the buffer has been consumed by the demux.
+ *	Demux hardware typically cannot read TS from memory. If this is the
+ *	case, memory-based filtering has to be implemented entirely in software.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @buf function parameter contains a pointer to the TS data in
+ *	kernel-space memory.
+ *	The @count function parameter contains the length of the TS data.
+ *	It returns:
+ *	0 on success;
+ *	-ERESTARTSYS, if mutex lock was interrupted;
+ *	-EINTR, if a signal handling is pending;
+ *	-ENODEV, if demux was removed;
+ *	-EINVAL, on bad parameter.
+ *
+ * @allocate_ts_feed: Allocates a new TS feed, which is used to filter the TS
+ *	packets carrying a certain PID. The TS feed normally corresponds to a
+ *	hardware PID filter on the demux chip.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @feed function parameter contains a pointer to the TS feed API and
+ *	instance data.
+ *	The @callback function parameter contains a pointer to the callback
+ *	function for passing received TS packet.
+ *	It returns:
+ *	0 on success;
+ *	-ERESTARTSYS, if mutex lock was interrupted;
+ *	-EBUSY, if no more TS feeds is available;
+ *	-EINVAL, on bad parameter.
+ *
+ * @release_ts_feed: Releases the resources allocated with @allocate_ts_feed.
+ *	Any filtering in progress on the TS feed should be stopped before
+ *	calling this function.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @feed function parameter contains a pointer to the TS feed API and
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-EINVAL on bad parameter.
+ *
+ * @allocate_section_feed: Allocates a new section feed, i.e. a demux resource
+ *	for filtering and receiving sections. On platforms with hardware
+ *	support for section filtering, a section feed is directly mapped to
+ *	the demux HW. On other platforms, TS packets are first PID filtered in
+ *	hardware and a hardware section filter then emulated in software. The
+ *	caller obtains an API pointer of type dmx_section_feed_t as an out
+ *	parameter. Using this API the caller can set filtering parameters and
+ *	start receiving sections.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @feed function parameter contains a pointer to the TS feed API and
+ *	instance data.
+ *	The @callback function parameter contains a pointer to the callback
+ *	function for passing received TS packet.
+ *	It returns:
+ *	0 on success;
+ *	-EBUSY, if no more TS feeds is available;
+ *	-EINVAL, on bad parameter.
+ *
+ * @release_section_feed: Releases the resources allocated with
+ *	@allocate_section_feed, including allocated filters. Any filtering in
+ *	progress on the section feed should be stopped before calling this
+ *	function.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @feed function parameter contains a pointer to the TS feed API and
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-EINVAL, on bad parameter.
+ *
+ * @add_frontend: Registers a connectivity between a demux and a front-end,
+ *	i.e., indicates that the demux can be connected via a call to
+ *	@connect_frontend to use the given front-end as a TS source. The
+ *	client of this function has to allocate dynamic or static memory for
+ *	the frontend structure and initialize its fields before calling this
+ *	function. This function is normally called during the driver
+ *	initialization. The caller must not free the memory of the frontend
+ *	struct before successfully calling @remove_frontend.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @frontend function parameter contains a pointer to the front-end
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-EINVAL, on bad parameter.
+ *
+ * @remove_frontend: Indicates that the given front-end, registered by a call
+ *	to @add_frontend, can no longer be connected as a TS source by this
+ *	demux. The function should be called when a front-end driver or a demux
+ *	driver is removed from the system. If the front-end is in use, the
+ *	function fails with the return value of -EBUSY. After successfully
+ *	calling this function, the caller can free the memory of the frontend
+ *	struct if it was dynamically allocated before the @add_frontend
+ *	operation.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @frontend function parameter contains a pointer to the front-end
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-ENODEV, if the front-end was not found,
+ *	-EINVAL, on bad parameter.
+ *
+ * @get_frontends: Provides the APIs of the front-ends that have been
+ *	registered for this demux. Any of the front-ends obtained with this
+ *	call can be used as a parameter for @connect_frontend. The include
+ *	file demux.h contains the macro DMX_FE_ENTRY() for converting an
+ *	element of the generic type struct &list_head * to the type
+ *	struct &dmx_frontend *. The caller must not free the memory of any of
+ *	the elements obtained via this function call.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	It returns a struct list_head pointer to the list of front-end
+ *	interfaces, or NULL in the case of an empty list.
+ *
+ * @connect_frontend: Connects the TS output of the front-end to the input of
+ *	the demux. A demux can only be connected to a front-end registered to
+ *	the demux with the function @add_frontend. It may or may not be
+ *	possible to connect multiple demuxes to the same front-end, depending
+ *	on the capabilities of the HW platform. When not used, the front-end
+ *	should be released by calling @disconnect_frontend.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @frontend function parameter contains a pointer to the front-end
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-EINVAL, on bad parameter.
+ *
+ * @disconnect_frontend: Disconnects the demux and a front-end previously
+ *	connected by a @connect_frontend call.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	It returns:
+ *	0 on success;
+ *	-EINVAL on bad parameter.
+ *
+ * @get_pes_pids: Get the PIDs for DMX_PES_AUDIO0, DMX_PES_VIDEO0,
+ *	DMX_PES_TELETEXT0, DMX_PES_SUBTITLE0 and DMX_PES_PCR0.
+ *	The @demux function parameter contains a pointer to the demux API and
+ *	instance data.
+ *	The @pids function parameter contains an array with five u16 elements
+ *	where the PIDs will be stored.
+ *	It returns:
+ *	0 on success;
+ *	-EINVAL on bad parameter.
+ */
+struct dmx_demux {
+	enum dmx_demux_caps capabilities;
+	struct dmx_frontend *frontend;
+	void *priv;
+	int (*open)(struct dmx_demux *demux);
+	int (*close)(struct dmx_demux *demux);
+	int (*write)(struct dmx_demux *demux, const char __user *buf,
+		     size_t count);
+	int (*allocate_ts_feed)(struct dmx_demux *demux,
+				struct dmx_ts_feed **feed,
+				dmx_ts_cb callback);
+	int (*release_ts_feed)(struct dmx_demux *demux,
+			       struct dmx_ts_feed *feed);
+	int (*allocate_section_feed)(struct dmx_demux *demux,
+				     struct dmx_section_feed **feed,
+				     dmx_section_cb callback);
+	int (*release_section_feed)(struct dmx_demux *demux,
+				    struct dmx_section_feed *feed);
+	int (*add_frontend)(struct dmx_demux *demux,
+			    struct dmx_frontend *frontend);
+	int (*remove_frontend)(struct dmx_demux *demux,
+			       struct dmx_frontend *frontend);
+	struct list_head *(*get_frontends)(struct dmx_demux *demux);
+	int (*connect_frontend)(struct dmx_demux *demux,
+				struct dmx_frontend *frontend);
+	int (*disconnect_frontend)(struct dmx_demux *demux);
+
+	int (*get_pes_pids)(struct dmx_demux *demux, u16 *pids);
+
+	/* private: */
+
+	/*
+	 * Only used at av7110, to read some data from firmware.
+	 * As this was never documented, we have no clue about what's
+	 * there, and its usage on other drivers aren't encouraged.
+	 */
+	int (*get_stc)(struct dmx_demux *demux, unsigned int num,
+		       u64 *stc, unsigned int *base);
+};
+
+#endif /* #ifndef __DEMUX_H */
diff --git a/include/media/dmxdev.h b/include/media/dmxdev.h
new file mode 100644
index 0000000..baafa3b
--- /dev/null
+++ b/include/media/dmxdev.h
@@ -0,0 +1,214 @@
+/*
+ * dmxdev.h
+ *
+ * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
+ *                    for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DMXDEV_H_
+#define _DMXDEV_H_
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include <linux/dvb/dmx.h>
+
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_vb2.h>
+
+/**
+ * enum dmxdev_type - type of demux filter type.
+ *
+ * @DMXDEV_TYPE_NONE:	no filter set.
+ * @DMXDEV_TYPE_SEC:	section filter.
+ * @DMXDEV_TYPE_PES:	Program Elementary Stream (PES) filter.
+ */
+enum dmxdev_type {
+	DMXDEV_TYPE_NONE,
+	DMXDEV_TYPE_SEC,
+	DMXDEV_TYPE_PES,
+};
+
+/**
+ * enum dmxdev_state - state machine for the dmxdev.
+ *
+ * @DMXDEV_STATE_FREE:		indicates that the filter is freed.
+ * @DMXDEV_STATE_ALLOCATED:	indicates that the filter was allocated
+ *				to be used.
+ * @DMXDEV_STATE_SET:		indicates that the filter parameters are set.
+ * @DMXDEV_STATE_GO:		indicates that the filter is running.
+ * @DMXDEV_STATE_DONE:		indicates that a packet was already filtered
+ *				and the filter is now disabled.
+ *				Set only if %DMX_ONESHOT. See
+ *				&dmx_sct_filter_params.
+ * @DMXDEV_STATE_TIMEDOUT:	Indicates a timeout condition.
+ */
+enum dmxdev_state {
+	DMXDEV_STATE_FREE,
+	DMXDEV_STATE_ALLOCATED,
+	DMXDEV_STATE_SET,
+	DMXDEV_STATE_GO,
+	DMXDEV_STATE_DONE,
+	DMXDEV_STATE_TIMEDOUT
+};
+
+/**
+ * struct dmxdev_feed - digital TV dmxdev feed
+ *
+ * @pid:	Program ID to be filtered
+ * @ts:		pointer to &struct dmx_ts_feed
+ * @next:	&struct list_head pointing to the next feed.
+ */
+
+struct dmxdev_feed {
+	u16 pid;
+	struct dmx_ts_feed *ts;
+	struct list_head next;
+};
+
+/**
+ * struct dmxdev_filter - digital TV dmxdev filter
+ *
+ * @filter:	a union describing a dmxdev filter.
+ *		Currently used only for section filters.
+ * @filter.sec: a &struct dmx_section_filter pointer.
+ *		For section filter only.
+ * @feed:	a union describing a dmxdev feed.
+ *		Depending on the filter type, it can be either
+ *		@feed.ts or @feed.sec.
+ * @feed.ts:	a &struct list_head list.
+ *		For TS and PES feeds.
+ * @feed.sec:	a &struct dmx_section_feed pointer.
+ *		For section feed only.
+ * @params:	a union describing dmxdev filter parameters.
+ *		Depending on the filter type, it can be either
+ *		@params.sec or @params.pes.
+ * @params.sec:	a &struct dmx_sct_filter_params embedded struct.
+ *		For section filter only.
+ * @params.pes:	a &struct dmx_pes_filter_params embedded struct.
+ *		For PES filter only.
+ * @type:	type of the dmxdev filter, as defined by &enum dmxdev_type.
+ * @state:	state of the dmxdev filter, as defined by &enum dmxdev_state.
+ * @dev:	pointer to &struct dmxdev.
+ * @buffer:	an embedded &struct dvb_ringbuffer buffer.
+ * @vb2_ctx:	control struct for VB2 handler
+ * @mutex:	protects the access to &struct dmxdev_filter.
+ * @timer:	&struct timer_list embedded timer, used to check for
+ *		feed timeouts.
+ *		Only for section filter.
+ * @todo:	index for the @secheader.
+ *		Only for section filter.
+ * @secheader:	buffer cache to parse the section header.
+ *		Only for section filter.
+ */
+struct dmxdev_filter {
+	union {
+		struct dmx_section_filter *sec;
+	} filter;
+
+	union {
+		/* list of TS and PES feeds (struct dmxdev_feed) */
+		struct list_head ts;
+		struct dmx_section_feed *sec;
+	} feed;
+
+	union {
+		struct dmx_sct_filter_params sec;
+		struct dmx_pes_filter_params pes;
+	} params;
+
+	enum dmxdev_type type;
+	enum dmxdev_state state;
+	struct dmxdev *dev;
+	struct dvb_ringbuffer buffer;
+	struct dvb_vb2_ctx vb2_ctx;
+
+	struct mutex mutex;
+
+	/* only for sections */
+	struct timer_list timer;
+	int todo;
+	u8 secheader[3];
+};
+
+/**
+ * struct dmxdev - Describes a digital TV demux device.
+ *
+ * @dvbdev:		pointer to &struct dvb_device associated with
+ *			the demux device node.
+ * @dvr_dvbdev:		pointer to &struct dvb_device associated with
+ *			the dvr device node.
+ * @filter:		pointer to &struct dmxdev_filter.
+ * @demux:		pointer to &struct dmx_demux.
+ * @filternum:		number of filters.
+ * @capabilities:	demux capabilities as defined by &enum dmx_demux_caps.
+ * @may_do_mmap:	flag used to indicate if the device may do mmap.
+ * @exit:		flag to indicate that the demux is being released.
+ * @dvr_orig_fe:	pointer to &struct dmx_frontend.
+ * @dvr_buffer:		embedded &struct dvb_ringbuffer for DVB output.
+ * @dvr_vb2_ctx:	control struct for VB2 handler
+ * @mutex:		protects the usage of this structure.
+ * @lock:		protects access to &dmxdev->filter->data.
+ */
+struct dmxdev {
+	struct dvb_device *dvbdev;
+	struct dvb_device *dvr_dvbdev;
+
+	struct dmxdev_filter *filter;
+	struct dmx_demux *demux;
+
+	int filternum;
+	int capabilities;
+
+	unsigned int may_do_mmap:1;
+	unsigned int exit:1;
+#define DMXDEV_CAP_DUPLEX 1
+	struct dmx_frontend *dvr_orig_fe;
+
+	struct dvb_ringbuffer dvr_buffer;
+#define DVR_BUFFER_SIZE (10*188*1024)
+
+	struct dvb_vb2_ctx dvr_vb2_ctx;
+
+	struct mutex mutex;
+	spinlock_t lock;
+};
+
+/**
+ * dvb_dmxdev_init - initializes a digital TV demux and registers both demux
+ *	and DVR devices.
+ *
+ * @dmxdev: pointer to &struct dmxdev.
+ * @adap: pointer to &struct dvb_adapter.
+ */
+int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *adap);
+
+/**
+ * dvb_dmxdev_release - releases a digital TV demux and unregisters it.
+ *
+ * @dmxdev: pointer to &struct dmxdev.
+ */
+void dvb_dmxdev_release(struct dmxdev *dmxdev);
+
+#endif /* _DMXDEV_H_ */
diff --git a/include/media/drv-intf/cx2341x.h b/include/media/drv-intf/cx2341x.h
new file mode 100644
index 0000000..33a97bf
--- /dev/null
+++ b/include/media/drv-intf/cx2341x.h
@@ -0,0 +1,295 @@
+/*
+    cx23415/6/8 header containing common defines.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef CX2341X_H
+#define CX2341X_H
+
+#include <media/v4l2-ctrls.h>
+
+enum cx2341x_port {
+	CX2341X_PORT_MEMORY    = 0,
+	CX2341X_PORT_STREAMING = 1,
+	CX2341X_PORT_SERIAL    = 2
+};
+
+enum cx2341x_cap {
+	CX2341X_CAP_HAS_SLICED_VBI = 1 << 0,
+	CX2341X_CAP_HAS_TS	   = 1 << 1,
+	CX2341X_CAP_HAS_AC3	   = 1 << 2,
+};
+
+struct cx2341x_mpeg_params {
+	/* misc */
+	u32 capabilities;
+	enum cx2341x_port port;
+	u16 width;
+	u16 height;
+	u16 is_50hz;
+
+	/* stream */
+	enum v4l2_mpeg_stream_type stream_type;
+	enum v4l2_mpeg_stream_vbi_fmt stream_vbi_fmt;
+	u16 stream_insert_nav_packets;
+
+	/* audio */
+	enum v4l2_mpeg_audio_sampling_freq audio_sampling_freq;
+	enum v4l2_mpeg_audio_encoding audio_encoding;
+	enum v4l2_mpeg_audio_l2_bitrate audio_l2_bitrate;
+	enum v4l2_mpeg_audio_ac3_bitrate audio_ac3_bitrate;
+	enum v4l2_mpeg_audio_mode audio_mode;
+	enum v4l2_mpeg_audio_mode_extension audio_mode_extension;
+	enum v4l2_mpeg_audio_emphasis audio_emphasis;
+	enum v4l2_mpeg_audio_crc audio_crc;
+	u32 audio_properties;
+	u16 audio_mute;
+
+	/* video */
+	enum v4l2_mpeg_video_encoding video_encoding;
+	enum v4l2_mpeg_video_aspect video_aspect;
+	u16 video_b_frames;
+	u16 video_gop_size;
+	u16 video_gop_closure;
+	enum v4l2_mpeg_video_bitrate_mode video_bitrate_mode;
+	u32 video_bitrate;
+	u32 video_bitrate_peak;
+	u16 video_temporal_decimation;
+	u16 video_mute;
+	u32 video_mute_yuv;
+
+	/* encoding filters */
+	enum v4l2_mpeg_cx2341x_video_spatial_filter_mode video_spatial_filter_mode;
+	u16 video_spatial_filter;
+	enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type video_luma_spatial_filter_type;
+	enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type video_chroma_spatial_filter_type;
+	enum v4l2_mpeg_cx2341x_video_temporal_filter_mode video_temporal_filter_mode;
+	u16 video_temporal_filter;
+	enum v4l2_mpeg_cx2341x_video_median_filter_type video_median_filter_type;
+	u16 video_luma_median_filter_top;
+	u16 video_luma_median_filter_bottom;
+	u16 video_chroma_median_filter_top;
+	u16 video_chroma_median_filter_bottom;
+};
+
+#define CX2341X_MBOX_MAX_DATA 16
+
+extern const u32 cx2341x_mpeg_ctrls[];
+typedef int (*cx2341x_mbox_func)(void *priv, u32 cmd, int in, int out,
+		u32 data[CX2341X_MBOX_MAX_DATA]);
+int cx2341x_update(void *priv, cx2341x_mbox_func func,
+		const struct cx2341x_mpeg_params *old,
+		const struct cx2341x_mpeg_params *new);
+int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
+		struct v4l2_queryctrl *qctrl);
+const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id);
+int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
+		struct v4l2_ext_controls *ctrls, unsigned int cmd);
+void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p);
+void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix);
+
+struct cx2341x_handler;
+
+struct cx2341x_handler_ops {
+	/* needed for the video clock freq */
+	int (*s_audio_sampling_freq)(struct cx2341x_handler *hdl, u32 val);
+	/* needed for dualwatch */
+	int (*s_audio_mode)(struct cx2341x_handler *hdl, u32 val);
+	/* needed for setting up the video resolution */
+	int (*s_video_encoding)(struct cx2341x_handler *hdl, u32 val);
+	/* needed for setting up the sliced vbi insertion data structures */
+	int (*s_stream_vbi_fmt)(struct cx2341x_handler *hdl, u32 val);
+};
+
+struct cx2341x_handler {
+	u32 capabilities;
+	enum cx2341x_port port;
+	u16 width;
+	u16 height;
+	u16 is_50hz;
+	u32 audio_properties;
+
+	struct v4l2_ctrl_handler hdl;
+	void *priv;
+	cx2341x_mbox_func func;
+	const struct cx2341x_handler_ops *ops;
+
+	struct v4l2_ctrl *stream_vbi_fmt;
+
+	struct {
+		/* audio cluster */
+		struct v4l2_ctrl *audio_sampling_freq;
+		struct v4l2_ctrl *audio_encoding;
+		struct v4l2_ctrl *audio_l2_bitrate;
+		struct v4l2_ctrl *audio_mode;
+		struct v4l2_ctrl *audio_mode_extension;
+		struct v4l2_ctrl *audio_emphasis;
+		struct v4l2_ctrl *audio_crc;
+		struct v4l2_ctrl *audio_ac3_bitrate;
+	};
+
+	struct {
+		/* video gop cluster */
+		struct v4l2_ctrl *video_b_frames;
+		struct v4l2_ctrl *video_gop_size;
+	};
+
+	struct {
+		/* stream type cluster */
+		struct v4l2_ctrl *stream_type;
+		struct v4l2_ctrl *video_encoding;
+		struct v4l2_ctrl *video_bitrate_mode;
+		struct v4l2_ctrl *video_bitrate;
+		struct v4l2_ctrl *video_bitrate_peak;
+	};
+
+	struct {
+		/* video mute cluster */
+		struct v4l2_ctrl *video_mute;
+		struct v4l2_ctrl *video_mute_yuv;
+	};
+
+	struct {
+		/* video filter mode cluster */
+		struct v4l2_ctrl *video_spatial_filter_mode;
+		struct v4l2_ctrl *video_temporal_filter_mode;
+		struct v4l2_ctrl *video_median_filter_type;
+	};
+
+	struct {
+		/* video filter type cluster */
+		struct v4l2_ctrl *video_luma_spatial_filter_type;
+		struct v4l2_ctrl *video_chroma_spatial_filter_type;
+	};
+
+	struct  {
+		/* video filter cluster */
+		struct v4l2_ctrl *video_spatial_filter;
+		struct v4l2_ctrl *video_temporal_filter;
+	};
+
+	struct {
+		/* video median cluster */
+		struct v4l2_ctrl *video_luma_median_filter_top;
+		struct v4l2_ctrl *video_luma_median_filter_bottom;
+		struct v4l2_ctrl *video_chroma_median_filter_top;
+		struct v4l2_ctrl *video_chroma_median_filter_bottom;
+	};
+};
+
+int cx2341x_handler_init(struct cx2341x_handler *cxhdl,
+			 unsigned nr_of_controls_hint);
+void cx2341x_handler_set_50hz(struct cx2341x_handler *cxhdl, int is_50hz);
+int cx2341x_handler_setup(struct cx2341x_handler *cxhdl);
+void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy);
+
+/* Firmware names */
+#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw"
+/* Decoder firmware for the cx23415 only */
+#define CX2341X_FIRM_DEC_FILENAME "v4l-cx2341x-dec.fw"
+
+/* Firmware API commands */
+
+/* MPEG decoder API, specific to the cx23415 */
+#define CX2341X_DEC_PING_FW			0x00
+#define CX2341X_DEC_START_PLAYBACK		0x01
+#define CX2341X_DEC_STOP_PLAYBACK		0x02
+#define CX2341X_DEC_SET_PLAYBACK_SPEED		0x03
+#define CX2341X_DEC_STEP_VIDEO			0x05
+#define CX2341X_DEC_SET_DMA_BLOCK_SIZE		0x08
+#define CX2341X_DEC_GET_XFER_INFO		0x09
+#define CX2341X_DEC_GET_DMA_STATUS		0x0a
+#define CX2341X_DEC_SCHED_DMA_FROM_HOST		0x0b
+#define CX2341X_DEC_PAUSE_PLAYBACK		0x0d
+#define CX2341X_DEC_HALT_FW			0x0e
+#define CX2341X_DEC_SET_STANDARD		0x10
+#define CX2341X_DEC_GET_VERSION			0x11
+#define CX2341X_DEC_SET_STREAM_INPUT		0x14
+#define CX2341X_DEC_GET_TIMING_INFO		0x15
+#define CX2341X_DEC_SET_AUDIO_MODE		0x16
+#define CX2341X_DEC_SET_EVENT_NOTIFICATION	0x17
+#define CX2341X_DEC_SET_DISPLAY_BUFFERS		0x18
+#define CX2341X_DEC_EXTRACT_VBI			0x19
+#define CX2341X_DEC_SET_DECODER_SOURCE		0x1a
+#define CX2341X_DEC_SET_PREBUFFERING		0x1e
+
+/* MPEG encoder API */
+#define CX2341X_ENC_PING_FW			0x80
+#define CX2341X_ENC_START_CAPTURE		0x81
+#define CX2341X_ENC_STOP_CAPTURE		0x82
+#define CX2341X_ENC_SET_AUDIO_ID		0x89
+#define CX2341X_ENC_SET_VIDEO_ID		0x8b
+#define CX2341X_ENC_SET_PCR_ID			0x8d
+#define CX2341X_ENC_SET_FRAME_RATE		0x8f
+#define CX2341X_ENC_SET_FRAME_SIZE		0x91
+#define CX2341X_ENC_SET_BIT_RATE		0x95
+#define CX2341X_ENC_SET_GOP_PROPERTIES		0x97
+#define CX2341X_ENC_SET_ASPECT_RATIO		0x99
+#define CX2341X_ENC_SET_DNR_FILTER_MODE		0x9b
+#define CX2341X_ENC_SET_DNR_FILTER_PROPS	0x9d
+#define CX2341X_ENC_SET_CORING_LEVELS		0x9f
+#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE	0xa1
+#define CX2341X_ENC_SET_VBI_LINE		0xb7
+#define CX2341X_ENC_SET_STREAM_TYPE		0xb9
+#define CX2341X_ENC_SET_OUTPUT_PORT		0xbb
+#define CX2341X_ENC_SET_AUDIO_PROPERTIES	0xbd
+#define CX2341X_ENC_HALT_FW			0xc3
+#define CX2341X_ENC_GET_VERSION			0xc4
+#define CX2341X_ENC_SET_GOP_CLOSURE		0xc5
+#define CX2341X_ENC_GET_SEQ_END			0xc6
+#define CX2341X_ENC_SET_PGM_INDEX_INFO		0xc7
+#define CX2341X_ENC_SET_VBI_CONFIG		0xc8
+#define CX2341X_ENC_SET_DMA_BLOCK_SIZE		0xc9
+#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10	0xca
+#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9	0xcb
+#define CX2341X_ENC_SCHED_DMA_TO_HOST		0xcc
+#define CX2341X_ENC_INITIALIZE_INPUT		0xcd
+#define CX2341X_ENC_SET_FRAME_DROP_RATE		0xd0
+#define CX2341X_ENC_PAUSE_ENCODER		0xd2
+#define CX2341X_ENC_REFRESH_INPUT		0xd3
+#define CX2341X_ENC_SET_COPYRIGHT		0xd4
+#define CX2341X_ENC_SET_EVENT_NOTIFICATION	0xd5
+#define CX2341X_ENC_SET_NUM_VSYNC_LINES		0xd6
+#define CX2341X_ENC_SET_PLACEHOLDER		0xd7
+#define CX2341X_ENC_MUTE_VIDEO			0xd9
+#define CX2341X_ENC_MUTE_AUDIO			0xda
+#define CX2341X_ENC_SET_VERT_CROP_LINE		0xdb
+#define CX2341X_ENC_MISC			0xdc
+
+/* OSD API, specific to the cx23415 */
+#define CX2341X_OSD_GET_FRAMEBUFFER		0x41
+#define CX2341X_OSD_GET_PIXEL_FORMAT		0x42
+#define CX2341X_OSD_SET_PIXEL_FORMAT		0x43
+#define CX2341X_OSD_GET_STATE			0x44
+#define CX2341X_OSD_SET_STATE			0x45
+#define CX2341X_OSD_GET_OSD_COORDS		0x46
+#define CX2341X_OSD_SET_OSD_COORDS		0x47
+#define CX2341X_OSD_GET_SCREEN_COORDS		0x48
+#define CX2341X_OSD_SET_SCREEN_COORDS		0x49
+#define CX2341X_OSD_GET_GLOBAL_ALPHA		0x4a
+#define CX2341X_OSD_SET_GLOBAL_ALPHA		0x4b
+#define CX2341X_OSD_SET_BLEND_COORDS		0x4c
+#define CX2341X_OSD_GET_FLICKER_STATE		0x4f
+#define CX2341X_OSD_SET_FLICKER_STATE		0x50
+#define CX2341X_OSD_BLT_COPY			0x52
+#define CX2341X_OSD_BLT_FILL			0x53
+#define CX2341X_OSD_BLT_TEXT			0x54
+#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW	0x56
+#define CX2341X_OSD_SET_CHROMA_KEY		0x60
+#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX	0x61
+#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX	0x62
+
+#endif /* CX2341X_H */
diff --git a/include/media/drv-intf/cx25840.h b/include/media/drv-intf/cx25840.h
new file mode 100644
index 0000000..783c5bd
--- /dev/null
+++ b/include/media/drv-intf/cx25840.h
@@ -0,0 +1,188 @@
+/*
+    cx25840.h - definition for cx25840/1/2/3 inputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _CX25840_H_
+#define _CX25840_H_
+
+/* Note that the cx25840 driver requires that the bridge driver calls the
+   v4l2_subdev's init operation in order to load the driver's firmware.
+   Without this the audio standard detection will fail and you will
+   only get mono.
+
+   Since loading the firmware is often problematic when the driver is
+   compiled into the kernel I recommend postponing calling this function
+   until the first open of the video device. Another reason for
+   postponing it is that loading this firmware takes a long time (seconds)
+   due to the slow i2c bus speed. So it will speed up the boot process if
+   you can avoid loading the fw as long as the video device isn't used. */
+
+enum cx25840_video_input {
+	/* Composite video inputs In1-In8 */
+	CX25840_COMPOSITE1 = 1,
+	CX25840_COMPOSITE2,
+	CX25840_COMPOSITE3,
+	CX25840_COMPOSITE4,
+	CX25840_COMPOSITE5,
+	CX25840_COMPOSITE6,
+	CX25840_COMPOSITE7,
+	CX25840_COMPOSITE8,
+
+	/* S-Video inputs consist of one luma input (In1-In8) ORed with one
+	   chroma input (In5-In8) */
+	CX25840_SVIDEO_LUMA1 = 0x10,
+	CX25840_SVIDEO_LUMA2 = 0x20,
+	CX25840_SVIDEO_LUMA3 = 0x30,
+	CX25840_SVIDEO_LUMA4 = 0x40,
+	CX25840_SVIDEO_LUMA5 = 0x50,
+	CX25840_SVIDEO_LUMA6 = 0x60,
+	CX25840_SVIDEO_LUMA7 = 0x70,
+	CX25840_SVIDEO_LUMA8 = 0x80,
+	CX25840_SVIDEO_CHROMA4 = 0x400,
+	CX25840_SVIDEO_CHROMA5 = 0x500,
+	CX25840_SVIDEO_CHROMA6 = 0x600,
+	CX25840_SVIDEO_CHROMA7 = 0x700,
+	CX25840_SVIDEO_CHROMA8 = 0x800,
+
+	/* S-Video aliases for common luma/chroma combinations */
+	CX25840_SVIDEO1 = 0x510,
+	CX25840_SVIDEO2 = 0x620,
+	CX25840_SVIDEO3 = 0x730,
+	CX25840_SVIDEO4 = 0x840,
+
+	/* Allow frames to specify specific input configurations */
+	CX25840_VIN1_CH1  = 0x80000000,
+	CX25840_VIN2_CH1  = 0x80000001,
+	CX25840_VIN3_CH1  = 0x80000002,
+	CX25840_VIN4_CH1  = 0x80000003,
+	CX25840_VIN5_CH1  = 0x80000004,
+	CX25840_VIN6_CH1  = 0x80000005,
+	CX25840_VIN7_CH1  = 0x80000006,
+	CX25840_VIN8_CH1  = 0x80000007,
+	CX25840_VIN4_CH2  = 0x80000000,
+	CX25840_VIN5_CH2  = 0x80000010,
+	CX25840_VIN6_CH2  = 0x80000020,
+	CX25840_NONE_CH2  = 0x80000030,
+	CX25840_VIN7_CH3  = 0x80000000,
+	CX25840_VIN8_CH3  = 0x80000040,
+	CX25840_NONE0_CH3 = 0x80000080,
+	CX25840_NONE1_CH3 = 0x800000c0,
+	CX25840_SVIDEO_ON = 0x80000100,
+	CX25840_COMPONENT_ON = 0x80000200,
+	CX25840_DIF_ON = 0x80000400,
+};
+
+enum cx25840_audio_input {
+	/* Audio inputs: serial or In4-In8 */
+	CX25840_AUDIO_SERIAL,
+	CX25840_AUDIO4 = 4,
+	CX25840_AUDIO5,
+	CX25840_AUDIO6,
+	CX25840_AUDIO7,
+	CX25840_AUDIO8,
+};
+
+enum cx25840_io_pin {
+	CX25840_PIN_DVALID_PRGM0 = 0,
+	CX25840_PIN_FIELD_PRGM1,
+	CX25840_PIN_HRESET_PRGM2,
+	CX25840_PIN_VRESET_HCTL_PRGM3,
+	CX25840_PIN_IRQ_N_PRGM4,
+	CX25840_PIN_IR_TX_PRGM6,
+	CX25840_PIN_IR_RX_PRGM5,
+	CX25840_PIN_GPIO0_PRGM8,
+	CX25840_PIN_GPIO1_PRGM9,
+	CX25840_PIN_SA_SDIN,		/* Alternate GP Input only */
+	CX25840_PIN_SA_SDOUT,		/* Alternate GP Input only */
+	CX25840_PIN_PLL_CLK_PRGM7,
+	CX25840_PIN_CHIP_SEL_VIPCLK,	/* Output only */
+};
+
+enum cx25840_io_pad {
+	/* Output pads */
+	CX25840_PAD_DEFAULT = 0,
+	CX25840_PAD_ACTIVE,
+	CX25840_PAD_VACTIVE,
+	CX25840_PAD_CBFLAG,
+	CX25840_PAD_VID_DATA_EXT0,
+	CX25840_PAD_VID_DATA_EXT1,
+	CX25840_PAD_GPO0,
+	CX25840_PAD_GPO1,
+	CX25840_PAD_GPO2,
+	CX25840_PAD_GPO3,
+	CX25840_PAD_IRQ_N,
+	CX25840_PAD_AC_SYNC,
+	CX25840_PAD_AC_SDOUT,
+	CX25840_PAD_PLL_CLK,
+	CX25840_PAD_VRESET,
+	CX25840_PAD_RESERVED,
+	/* Pads for PLL_CLK output only */
+	CX25840_PAD_XTI_X5_DLL,
+	CX25840_PAD_AUX_PLL,
+	CX25840_PAD_VID_PLL,
+	CX25840_PAD_XTI,
+	/* Input Pads */
+	CX25840_PAD_GPI0,
+	CX25840_PAD_GPI1,
+	CX25840_PAD_GPI2,
+	CX25840_PAD_GPI3,
+};
+
+enum cx25840_io_pin_strength {
+	CX25840_PIN_DRIVE_MEDIUM = 0,
+	CX25840_PIN_DRIVE_SLOW,
+	CX25840_PIN_DRIVE_FAST,
+};
+
+enum cx23885_io_pin {
+	CX23885_PIN_IR_RX_GPIO19,
+	CX23885_PIN_IR_TX_GPIO20,
+	CX23885_PIN_I2S_SDAT_GPIO21,
+	CX23885_PIN_I2S_WCLK_GPIO22,
+	CX23885_PIN_I2S_BCLK_GPIO23,
+	CX23885_PIN_IRQ_N_GPIO16,
+};
+
+enum cx23885_io_pad {
+	CX23885_PAD_IR_RX,
+	CX23885_PAD_GPIO19,
+	CX23885_PAD_IR_TX,
+	CX23885_PAD_GPIO20,
+	CX23885_PAD_I2S_SDAT,
+	CX23885_PAD_GPIO21,
+	CX23885_PAD_I2S_WCLK,
+	CX23885_PAD_GPIO22,
+	CX23885_PAD_I2S_BCLK,
+	CX23885_PAD_GPIO23,
+	CX23885_PAD_IRQ_N,
+	CX23885_PAD_GPIO16,
+};
+
+/* pvr150_workaround activates a workaround for a hardware bug that is
+   present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
+   certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
+   audio autodetect fails on some channels for these models and the workaround
+   is to select the audio standard explicitly. Many thanks to Hauppauge for
+   providing this information.
+   This platform data only needs to be supplied by the ivtv driver. */
+struct cx25840_platform_data {
+	int pvr150_workaround;
+};
+
+#endif
diff --git a/include/media/drv-intf/exynos-fimc.h b/include/media/drv-intf/exynos-fimc.h
new file mode 100644
index 0000000..f9c6433
--- /dev/null
+++ b/include/media/drv-intf/exynos-fimc.h
@@ -0,0 +1,162 @@
+/*
+ * Samsung S5P/Exynos4 SoC series camera interface driver header
+ *
+ * Copyright (C) 2010 - 2013 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef S5P_FIMC_H_
+#define S5P_FIMC_H_
+
+#include <media/media-entity.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-mediabus.h>
+
+/*
+ * Enumeration of data inputs to the camera subsystem.
+ */
+enum fimc_input {
+	FIMC_INPUT_PARALLEL_0	= 1,
+	FIMC_INPUT_PARALLEL_1,
+	FIMC_INPUT_MIPI_CSI2_0	= 3,
+	FIMC_INPUT_MIPI_CSI2_1,
+	FIMC_INPUT_WRITEBACK_A	= 5,
+	FIMC_INPUT_WRITEBACK_B,
+	FIMC_INPUT_WRITEBACK_ISP = 5,
+};
+
+/*
+ * Enumeration of the FIMC data bus types.
+ */
+enum fimc_bus_type {
+	/* Camera parallel bus */
+	FIMC_BUS_TYPE_ITU_601 = 1,
+	/* Camera parallel bus with embedded synchronization */
+	FIMC_BUS_TYPE_ITU_656,
+	/* Camera MIPI-CSI2 serial bus */
+	FIMC_BUS_TYPE_MIPI_CSI2,
+	/* FIFO link from LCD controller (WriteBack A) */
+	FIMC_BUS_TYPE_LCD_WRITEBACK_A,
+	/* FIFO link from LCD controller (WriteBack B) */
+	FIMC_BUS_TYPE_LCD_WRITEBACK_B,
+	/* FIFO link from FIMC-IS */
+	FIMC_BUS_TYPE_ISP_WRITEBACK = FIMC_BUS_TYPE_LCD_WRITEBACK_B,
+};
+
+#define fimc_input_is_parallel(x) ((x) == 1 || (x) == 2)
+#define fimc_input_is_mipi_csi(x) ((x) == 3 || (x) == 4)
+
+/*
+ * The subdevices' group IDs.
+ */
+#define GRP_ID_SENSOR		(1 << 8)
+#define GRP_ID_FIMC_IS_SENSOR	(1 << 9)
+#define GRP_ID_WRITEBACK	(1 << 10)
+#define GRP_ID_CSIS		(1 << 11)
+#define GRP_ID_FIMC		(1 << 12)
+#define GRP_ID_FLITE		(1 << 13)
+#define GRP_ID_FIMC_IS		(1 << 14)
+
+/**
+ * struct fimc_source_info - video source description required for the host
+ *			     interface configuration
+ *
+ * @fimc_bus_type: FIMC camera input type
+ * @sensor_bus_type: image sensor bus type, MIPI, ITU-R BT.601 etc.
+ * @flags: the parallel sensor bus flags defining signals polarity (V4L2_MBUS_*)
+ * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU)
+ */
+struct fimc_source_info {
+	enum fimc_bus_type fimc_bus_type;
+	enum fimc_bus_type sensor_bus_type;
+	u16 flags;
+	u16 mux_id;
+};
+
+/*
+ * v4l2_device notification id. This is only for internal use in the kernel.
+ * Sensor subdevs should issue S5P_FIMC_TX_END_NOTIFY notification in single
+ * frame capture mode when there is only one VSYNC pulse issued by the sensor
+ * at begining of the frame transmission.
+ */
+#define S5P_FIMC_TX_END_NOTIFY _IO('e', 0)
+
+#define FIMC_MAX_PLANES	3
+
+/**
+ * struct fimc_fmt - color format data structure
+ * @mbus_code: media bus pixel code, -1 if not applicable
+ * @name: format description
+ * @fourcc: fourcc code for this format, 0 if not applicable
+ * @color: the driver's private color format id
+ * @memplanes: number of physically non-contiguous data planes
+ * @colplanes: number of physically contiguous data planes
+ * @colorspace: v4l2 colorspace (V4L2_COLORSPACE_*)
+ * @depth: per plane driver's private 'number of bits per pixel'
+ * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no)
+ * @flags: flags indicating which operation mode format applies to
+ */
+struct fimc_fmt {
+	u32 mbus_code;
+	char	*name;
+	u32	fourcc;
+	u32	color;
+	u16	memplanes;
+	u16	colplanes;
+	u8	colorspace;
+	u8	depth[FIMC_MAX_PLANES];
+	u16	mdataplanes;
+	u16	flags;
+#define FMT_FLAGS_CAM		(1 << 0)
+#define FMT_FLAGS_M2M_IN	(1 << 1)
+#define FMT_FLAGS_M2M_OUT	(1 << 2)
+#define FMT_FLAGS_M2M		(1 << 1 | 1 << 2)
+#define FMT_HAS_ALPHA		(1 << 3)
+#define FMT_FLAGS_COMPRESSED	(1 << 4)
+#define FMT_FLAGS_WRITEBACK	(1 << 5)
+#define FMT_FLAGS_RAW_BAYER	(1 << 6)
+#define FMT_FLAGS_YUV		(1 << 7)
+};
+
+struct exynos_media_pipeline;
+
+/*
+ * Media pipeline operations to be called from within a video node,  i.e. the
+ * last entity within the pipeline. Implemented by related media device driver.
+ */
+struct exynos_media_pipeline_ops {
+	int (*prepare)(struct exynos_media_pipeline *p,
+						struct media_entity *me);
+	int (*unprepare)(struct exynos_media_pipeline *p);
+	int (*open)(struct exynos_media_pipeline *p, struct media_entity *me,
+							bool resume);
+	int (*close)(struct exynos_media_pipeline *p);
+	int (*set_stream)(struct exynos_media_pipeline *p, bool state);
+};
+
+struct exynos_video_entity {
+	struct video_device vdev;
+	struct exynos_media_pipeline *pipe;
+};
+
+struct exynos_media_pipeline {
+	struct media_pipeline mp;
+	const struct exynos_media_pipeline_ops *ops;
+};
+
+static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
+					struct video_device *vdev)
+{
+	return container_of(vdev, struct exynos_video_entity, vdev);
+}
+
+#define fimc_pipeline_call(ent, op, args...)				  \
+	((!(ent) || !(ent)->pipe) ? -ENOENT : \
+	(((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
+	(ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))	  \
+
+#endif /* S5P_FIMC_H_ */
diff --git a/include/media/drv-intf/msp3400.h b/include/media/drv-intf/msp3400.h
new file mode 100644
index 0000000..db98ce4
--- /dev/null
+++ b/include/media/drv-intf/msp3400.h
@@ -0,0 +1,225 @@
+/*
+    msp3400.h - definition for msp3400 inputs and outputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _MSP3400_H_
+#define _MSP3400_H_
+
+/* msp3400 routing
+   ===============
+
+   The msp3400 has a complicated routing scheme with many possible
+   combinations. The details are all in the datasheets but I will try
+   to give a short description here.
+
+   Inputs
+   ======
+
+   There are 1) tuner inputs, 2) I2S inputs, 3) SCART inputs. You will have
+   to select which tuner input to use and which SCART input to use. The
+   selected tuner input, the selected SCART input and all I2S inputs go to
+   the DSP (the tuner input first goes through the demodulator).
+
+   The DSP handles things like volume, bass/treble, balance, and some chips
+   have support for surround sound. It has several outputs: MAIN, AUX, I2S
+   and SCART1/2. Each output can select which DSP input to use. So the MAIN
+   output can select the tuner input while at the same time the SCART1 output
+   uses the I2S input.
+
+   Outputs
+   =======
+
+   Most DSP outputs are also the outputs of the msp3400. However, the SCART
+   outputs of the msp3400 can select which input to use: either the SCART1 or
+   SCART2 output from the DSP, or the msp3400 SCART inputs, thus completely
+   bypassing the DSP.
+
+   Summary
+   =======
+
+   So to specify a complete routing scheme for the msp3400 you will have to
+   specify in the 'input' arg of the s_routing function:
+
+   1) which tuner input to use
+   2) which SCART input to use
+   3) which DSP input to use for each DSP output
+
+   And in the 'output' arg of the s_routing function you specify:
+
+   1) which SCART input to use for each SCART output
+
+   Depending on how the msp is wired to the other components you can
+   ignore or mute certain inputs or outputs.
+
+   Also, depending on the msp version only a subset of the inputs or
+   outputs may be present. At the end of this header some tables are
+   added containing a list of what is available for each msp version.
+ */
+
+/* Inputs to the DSP unit: two independent selections have to be made:
+   1) the tuner (SIF) input
+   2) the SCART input
+   Bits 0-2 are used for the SCART input select, bit 3 is used for the tuner
+   input, bits 4-7 are reserved.
+ */
+
+/* SCART input to DSP selection */
+#define MSP_IN_SCART1		0  /* Pin SC1_IN */
+#define MSP_IN_SCART2		1  /* Pin SC2_IN */
+#define MSP_IN_SCART3		2  /* Pin SC3_IN */
+#define MSP_IN_SCART4		3  /* Pin SC4_IN */
+#define MSP_IN_MONO		6  /* Pin MONO_IN */
+#define MSP_IN_MUTE		7  /* Mute DSP input */
+#define MSP_SCART_TO_DSP(in)	(in)
+/* Tuner input to demodulator and DSP selection */
+#define MSP_IN_TUNER1		0  /* Analog Sound IF input pin ANA_IN1 */
+#define MSP_IN_TUNER2		1  /* Analog Sound IF input pin ANA_IN2 */
+#define MSP_TUNER_TO_DSP(in)	((in) << 3)
+
+/* The msp has up to 5 DSP outputs, each output can independently select
+   a DSP input.
+
+   The DSP outputs are: loudspeaker output (aka MAIN), headphones output
+   (aka AUX), SCART1 DA output, SCART2 DA output and an I2S output.
+   There also is a quasi-peak detector output, but that is not used by
+   this driver and is set to the same input as the loudspeaker output.
+   Not all outputs are supported by all msp models. Setting the input
+   of an unsupported output will be ignored by the driver.
+
+   There are up to 16 DSP inputs to choose from, so each output is
+   assigned 4 bits.
+
+   Note: the 44x8G can mix two inputs and feed the result back to the
+   DSP. This is currently not implemented. Also not implemented is the
+   multi-channel capable I2S3 input of the 44x0G. If someone can demonstrate
+   a need for one of those features then additional support can be added. */
+#define MSP_DSP_IN_TUNER	0  /* Tuner DSP input */
+#define MSP_DSP_IN_SCART	2  /* SCART DSP input */
+#define MSP_DSP_IN_I2S1		5  /* I2S1 DSP input */
+#define MSP_DSP_IN_I2S2		6  /* I2S2 DSP input */
+#define MSP_DSP_IN_I2S3		7  /* I2S3 DSP input */
+#define MSP_DSP_IN_MAIN_AVC	11 /* MAIN AVC processed DSP input */
+#define MSP_DSP_IN_MAIN		12 /* MAIN DSP input */
+#define MSP_DSP_IN_AUX		13 /* AUX DSP input */
+#define MSP_DSP_TO_MAIN(in)	((in) << 4)
+#define MSP_DSP_TO_AUX(in)	((in) << 8)
+#define MSP_DSP_TO_SCART1(in)	((in) << 12)
+#define MSP_DSP_TO_SCART2(in)	((in) << 16)
+#define MSP_DSP_TO_I2S(in)	((in) << 20)
+
+/* Output SCART select: the SCART outputs can select which input
+   to use. */
+#define MSP_SC_IN_SCART1	0  /* SCART1 input, bypassing the DSP */
+#define MSP_SC_IN_SCART2	1  /* SCART2 input, bypassing the DSP */
+#define MSP_SC_IN_SCART3	2  /* SCART3 input, bypassing the DSP */
+#define MSP_SC_IN_SCART4	3  /* SCART4 input, bypassing the DSP */
+#define MSP_SC_IN_DSP_SCART1	4  /* DSP SCART1 input */
+#define MSP_SC_IN_DSP_SCART2	5  /* DSP SCART2 input */
+#define MSP_SC_IN_MONO		6  /* MONO input, bypassing the DSP */
+#define MSP_SC_IN_MUTE		7  /* MUTE output */
+#define MSP_SC_TO_SCART1(in)	(in)
+#define MSP_SC_TO_SCART2(in)	((in) << 4)
+
+/* Shortcut macros */
+#define MSP_INPUT(sc, t, main_aux_src, sc_i2s_src) \
+	(MSP_SCART_TO_DSP(sc) | \
+	 MSP_TUNER_TO_DSP(t) | \
+	 MSP_DSP_TO_MAIN(main_aux_src) | \
+	 MSP_DSP_TO_AUX(main_aux_src) | \
+	 MSP_DSP_TO_SCART1(sc_i2s_src) | \
+	 MSP_DSP_TO_SCART2(sc_i2s_src) | \
+	 MSP_DSP_TO_I2S(sc_i2s_src))
+#define MSP_INPUT_DEFAULT MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
+				    MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER)
+#define MSP_OUTPUT(sc) \
+	(MSP_SC_TO_SCART1(sc) | \
+	 MSP_SC_TO_SCART2(sc))
+/* This equals the RESET position of the msp3400 ACB register */
+#define MSP_OUTPUT_DEFAULT (MSP_SC_TO_SCART1(MSP_SC_IN_SCART3) | \
+			    MSP_SC_TO_SCART2(MSP_SC_IN_DSP_SCART1))
+
+/* Tuner inputs vs. msp version */
+/* Chip      TUNER_1   TUNER_2
+   -------------------------
+   msp34x0b  y         y
+   msp34x0c  y         y
+   msp34x0d  y         y
+   msp34x5d  y         n
+   msp34x7d  y         n
+   msp34x0g  y         y
+   msp34x1g  y         y
+   msp34x2g  y         y
+   msp34x5g  y         n
+   msp34x7g  y         n
+   msp44x0g  y         y
+   msp44x8g  y         y
+ */
+
+/* SCART inputs vs. msp version */
+/* Chip      SC1 SC2 SC3 SC4
+   -------------------------
+   msp34x0b  y   y   y   n
+   msp34x0c  y   y   y   n
+   msp34x0d  y   y   y   y
+   msp34x5d  y   y   n   n
+   msp34x7d  y   n   n   n
+   msp34x0g  y   y   y   y
+   msp34x1g  y   y   y   y
+   msp34x2g  y   y   y   y
+   msp34x5g  y   y   n   n
+   msp34x7g  y   n   n   n
+   msp44x0g  y   y   y   y
+   msp44x8g  y   y   y   y
+ */
+
+/* DSP inputs vs. msp version (tuner and SCART inputs are always available) */
+/* Chip      I2S1 I2S2 I2S3 MAIN_AVC MAIN AUX
+   ------------------------------------------
+   msp34x0b  y    n    n    n        n    n
+   msp34x0c  y    y    n    n        n    n
+   msp34x0d  y    y    n    n        n    n
+   msp34x5d  y    y    n    n        n    n
+   msp34x7d  n    n    n    n        n    n
+   msp34x0g  y    y    n    n        n    n
+   msp34x1g  y    y    n    n        n    n
+   msp34x2g  y    y    n    y        y    y
+   msp34x5g  y    y    n    n        n    n
+   msp34x7g  n    n    n    n        n    n
+   msp44x0g  y    y    y    y        y    y
+   msp44x8g  y    y    y    n        n    n
+ */
+
+/* DSP outputs vs. msp version */
+/* Chip      MAIN AUX SCART1 SCART2 I2S
+   ------------------------------------
+   msp34x0b  y    y   y      n      y
+   msp34x0c  y    y   y      n      y
+   msp34x0d  y    y   y      y      y
+   msp34x5d  y    n   y      n      y
+   msp34x7d  y    n   y      n      n
+   msp34x0g  y    y   y      y      y
+   msp34x1g  y    y   y      y      y
+   msp34x2g  y    y   y      y      y
+   msp34x5g  y    n   y      n      y
+   msp34x7g  y    n   y      n      n
+   msp44x0g  y    y   y      y      y
+   msp44x8g  y    y   y      y      y
+ */
+
+#endif /* MSP3400_H */
diff --git a/include/media/drv-intf/renesas-ceu.h b/include/media/drv-intf/renesas-ceu.h
new file mode 100644
index 0000000..52841d1
--- /dev/null
+++ b/include/media/drv-intf/renesas-ceu.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * renesas-ceu.h - Renesas CEU driver interface
+ *
+ * Copyright 2017-2018 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ */
+
+#ifndef __MEDIA_DRV_INTF_RENESAS_CEU_H__
+#define __MEDIA_DRV_INTF_RENESAS_CEU_H__
+
+#define CEU_MAX_SUBDEVS		2
+
+struct ceu_async_subdev {
+	unsigned long flags;
+	unsigned char bus_width;
+	unsigned char bus_shift;
+	unsigned int i2c_adapter_id;
+	unsigned int i2c_address;
+};
+
+struct ceu_platform_data {
+	unsigned int num_subdevs;
+	struct ceu_async_subdev subdevs[CEU_MAX_SUBDEVS];
+};
+
+#endif /* ___MEDIA_DRV_INTF_RENESAS_CEU_H__ */
diff --git a/include/media/drv-intf/s3c_camif.h b/include/media/drv-intf/s3c_camif.h
new file mode 100644
index 0000000..df96c2c
--- /dev/null
+++ b/include/media/drv-intf/s3c_camif.h
@@ -0,0 +1,45 @@
+/*
+ * s3c24xx/s3c64xx SoC series Camera Interface (CAMIF) driver
+ *
+ * Copyright (C) 2012 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef MEDIA_S3C_CAMIF_
+#define MEDIA_S3C_CAMIF_
+
+#include <linux/i2c.h>
+#include <media/v4l2-mediabus.h>
+
+/**
+ * struct s3c_camif_sensor_info - an image sensor description
+ * @i2c_board_info: pointer to an I2C sensor subdevice board info
+ * @clock_frequency: frequency of the clock the host provides to a sensor
+ * @mbus_type: media bus type
+ * @i2c_bus_num: i2c control bus id the sensor is attached to
+ * @flags: the parallel bus flags defining signals polarity (V4L2_MBUS_*)
+ * @use_field: 1 if parallel bus FIELD signal is used (only s3c64xx)
+ */
+struct s3c_camif_sensor_info {
+	struct i2c_board_info i2c_board_info;
+	unsigned long clock_frequency;
+	enum v4l2_mbus_type mbus_type;
+	u16 i2c_bus_num;
+	u16 flags;
+	u8 use_field;
+};
+
+struct s3c_camif_plat_data {
+	struct s3c_camif_sensor_info sensor;
+	int (*gpio_get)(void);
+	int (*gpio_put)(void);
+};
+
+/* Platform default helper functions */
+int s3c_camif_gpio_get(void);
+int s3c_camif_gpio_put(void);
+
+#endif /* MEDIA_S3C_CAMIF_ */
diff --git a/include/media/drv-intf/saa7146.h b/include/media/drv-intf/saa7146.h
new file mode 100644
index 0000000..a7bf2c4
--- /dev/null
+++ b/include/media/drv-intf/saa7146.h
@@ -0,0 +1,472 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SAA7146__
+#define __SAA7146__
+
+#include <linux/delay.h>	/* for delay-stuff */
+#include <linux/slab.h>		/* for kmalloc/kfree */
+#include <linux/pci.h>		/* for pci-config-stuff, vendor ids etc. */
+#include <linux/init.h>		/* for "__init" */
+#include <linux/interrupt.h>	/* for IMMEDIATE_BH */
+#include <linux/kmod.h>		/* for kernel module loader */
+#include <linux/i2c.h>		/* for i2c subsystem */
+#include <asm/io.h>		/* for accessing devices */
+#include <linux/stringify.h>
+#include <linux/mutex.h>
+#include <linux/scatterlist.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#include <linux/vmalloc.h>	/* for vmalloc() */
+#include <linux/mm.h>		/* for vmalloc_to_page() */
+
+#define saa7146_write(sxy,adr,dat)    writel((dat),(sxy->mem+(adr)))
+#define saa7146_read(sxy,adr)         readl(sxy->mem+(adr))
+
+extern unsigned int saa7146_debug;
+
+#ifndef DEBUG_VARIABLE
+	#define DEBUG_VARIABLE saa7146_debug
+#endif
+
+#define ERR(fmt, ...)	pr_err("%s: " fmt, __func__, ##__VA_ARGS__)
+
+#define _DBG(mask, fmt, ...)						\
+do {									\
+	if (DEBUG_VARIABLE & mask)					\
+		pr_debug("%s(): " fmt, __func__, ##__VA_ARGS__);	\
+} while (0)
+
+/* simple debug messages */
+#define DEB_S(fmt, ...)		_DBG(0x01, fmt, ##__VA_ARGS__)
+/* more detailed debug messages */
+#define DEB_D(fmt, ...)		_DBG(0x02, fmt, ##__VA_ARGS__)
+/* print enter and exit of functions */
+#define DEB_EE(fmt, ...)	_DBG(0x04, fmt, ##__VA_ARGS__)
+/* i2c debug messages */
+#define DEB_I2C(fmt, ...)	_DBG(0x08, fmt, ##__VA_ARGS__)
+/* vbi debug messages */
+#define DEB_VBI(fmt, ...)	_DBG(0x10, fmt, ##__VA_ARGS__)
+/* interrupt debug messages */
+#define DEB_INT(fmt, ...)	_DBG(0x20, fmt, ##__VA_ARGS__)
+/* capture debug messages */
+#define DEB_CAP(fmt, ...)	_DBG(0x40, fmt, ##__VA_ARGS__)
+
+#define SAA7146_ISR_CLEAR(x,y) \
+	saa7146_write(x, ISR, (y));
+
+struct module;
+
+struct saa7146_dev;
+struct saa7146_extension;
+struct saa7146_vv;
+
+/* saa7146 page table */
+struct saa7146_pgtable {
+	unsigned int	size;
+	__le32		*cpu;
+	dma_addr_t	dma;
+	/* used for offsets for u,v planes for planar capture modes */
+	unsigned long	offset;
+	/* used for custom pagetables (used for example by budget dvb cards) */
+	struct scatterlist *slist;
+	int		nents;
+};
+
+struct saa7146_pci_extension_data {
+	struct saa7146_extension *ext;
+	void *ext_priv;			/* most likely a name string */
+};
+
+#define MAKE_EXTENSION_PCI(x_var, x_vendor, x_device)		\
+	{							\
+		.vendor    = PCI_VENDOR_ID_PHILIPS,		\
+		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,	\
+		.subvendor = x_vendor,				\
+		.subdevice = x_device,				\
+		.driver_data = (unsigned long)& x_var,		\
+	}
+
+struct saa7146_extension
+{
+	char	name[32];		/* name of the device */
+#define SAA7146_USE_I2C_IRQ	0x1
+#define SAA7146_I2C_SHORT_DELAY	0x2
+	int	flags;
+
+	/* pairs of subvendor and subdevice ids for
+	   supported devices, last entry 0xffff, 0xfff */
+	struct module *module;
+	struct pci_driver driver;
+	const struct pci_device_id *pci_tbl;
+
+	/* extension functions */
+	int (*probe)(struct saa7146_dev *);
+	int (*attach)(struct saa7146_dev *, struct saa7146_pci_extension_data *);
+	int (*detach)(struct saa7146_dev*);
+
+	u32	irq_mask;	/* mask to indicate, which irq-events are handled by the extension */
+	void	(*irq_func)(struct saa7146_dev*, u32* irq_mask);
+};
+
+struct saa7146_dma
+{
+	dma_addr_t	dma_handle;
+	__le32		*cpu_addr;
+};
+
+struct saa7146_dev
+{
+	struct module			*module;
+
+	struct v4l2_device		v4l2_dev;
+	struct v4l2_ctrl_handler	ctrl_handler;
+
+	/* different device locks */
+	spinlock_t			slock;
+	struct mutex			v4l2_lock;
+
+	unsigned char			__iomem *mem;		/* pointer to mapped IO memory */
+	u32				revision;	/* chip revision; needed for bug-workarounds*/
+
+	/* pci-device & irq stuff*/
+	char				name[32];
+	struct pci_dev			*pci;
+	u32				int_todo;
+	spinlock_t			int_slock;
+
+	/* extension handling */
+	struct saa7146_extension	*ext;		/* indicates if handled by extension */
+	void				*ext_priv;	/* pointer for extension private use (most likely some private data) */
+	struct saa7146_ext_vv		*ext_vv_data;
+
+	/* per device video/vbi informations (if available) */
+	struct saa7146_vv	*vv_data;
+	void (*vv_callback)(struct saa7146_dev *dev, unsigned long status);
+
+	/* i2c-stuff */
+	struct mutex			i2c_lock;
+
+	u32				i2c_bitrate;
+	struct saa7146_dma		d_i2c;	/* pointer to i2c memory */
+	wait_queue_head_t		i2c_wq;
+	int				i2c_op;
+
+	/* memories */
+	struct saa7146_dma		d_rps0;
+	struct saa7146_dma		d_rps1;
+};
+
+static inline struct saa7146_dev *to_saa7146_dev(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct saa7146_dev, v4l2_dev);
+}
+
+/* from saa7146_i2c.c */
+int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate);
+
+/* from saa7146_core.c */
+int saa7146_register_extension(struct saa7146_extension*);
+int saa7146_unregister_extension(struct saa7146_extension*);
+struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc);
+int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
+void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
+int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
+void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt);
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt);
+void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
+int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop);
+
+/* some memory sizes */
+#define SAA7146_I2C_MEM		( 1*PAGE_SIZE)
+#define SAA7146_RPS_MEM		( 1*PAGE_SIZE)
+
+/* some i2c constants */
+#define SAA7146_I2C_TIMEOUT	100	/* i2c-timeout-value in ms */
+#define SAA7146_I2C_RETRIES	3	/* how many times shall we retry an i2c-operation? */
+#define SAA7146_I2C_DELAY	5	/* time we wait after certain i2c-operations */
+
+/* unsorted defines */
+#define ME1    0x0000000800
+#define PV1    0x0000000008
+
+/* gpio defines */
+#define SAA7146_GPIO_INPUT 0x00
+#define SAA7146_GPIO_IRQHI 0x10
+#define SAA7146_GPIO_IRQLO 0x20
+#define SAA7146_GPIO_IRQHL 0x30
+#define SAA7146_GPIO_OUTLO 0x40
+#define SAA7146_GPIO_OUTHI 0x50
+
+/* debi defines */
+#define DEBINOSWAP 0x000e0000
+
+/* define for the register programming sequencer (rps) */
+#define CMD_NOP		0x00000000  /* No operation */
+#define CMD_CLR_EVENT	0x00000000  /* Clear event */
+#define CMD_SET_EVENT	0x10000000  /* Set signal event */
+#define CMD_PAUSE	0x20000000  /* Pause */
+#define CMD_CHECK_LATE	0x30000000  /* Check late */
+#define CMD_UPLOAD	0x40000000  /* Upload */
+#define CMD_STOP	0x50000000  /* Stop */
+#define CMD_INTERRUPT	0x60000000  /* Interrupt */
+#define CMD_JUMP	0x80000000  /* Jump */
+#define CMD_WR_REG	0x90000000  /* Write (load) register */
+#define CMD_RD_REG	0xa0000000  /* Read (store) register */
+#define CMD_WR_REG_MASK	0xc0000000  /* Write register with mask */
+
+#define CMD_OAN		MASK_27
+#define CMD_INV		MASK_26
+#define CMD_SIG4	MASK_25
+#define CMD_SIG3	MASK_24
+#define CMD_SIG2	MASK_23
+#define CMD_SIG1	MASK_22
+#define CMD_SIG0	MASK_21
+#define CMD_O_FID_B	MASK_14
+#define CMD_E_FID_B	MASK_13
+#define CMD_O_FID_A	MASK_12
+#define CMD_E_FID_A	MASK_11
+
+/* some events and command modifiers for rps1 squarewave generator */
+#define EVT_HS          (1<<15)     // Source Line Threshold reached
+#define EVT_VBI_B       (1<<9)      // VSYNC Event
+#define RPS_OAN         (1<<27)     // 1: OR events, 0: AND events
+#define RPS_INV         (1<<26)     // Invert (compound) event
+#define GPIO3_MSK       0xFF000000  // GPIO #3 control bits
+
+/* Bit mask constants */
+#define MASK_00   0x00000001    /* Mask value for bit 0 */
+#define MASK_01   0x00000002    /* Mask value for bit 1 */
+#define MASK_02   0x00000004    /* Mask value for bit 2 */
+#define MASK_03   0x00000008    /* Mask value for bit 3 */
+#define MASK_04   0x00000010    /* Mask value for bit 4 */
+#define MASK_05   0x00000020    /* Mask value for bit 5 */
+#define MASK_06   0x00000040    /* Mask value for bit 6 */
+#define MASK_07   0x00000080    /* Mask value for bit 7 */
+#define MASK_08   0x00000100    /* Mask value for bit 8 */
+#define MASK_09   0x00000200    /* Mask value for bit 9 */
+#define MASK_10   0x00000400    /* Mask value for bit 10 */
+#define MASK_11   0x00000800    /* Mask value for bit 11 */
+#define MASK_12   0x00001000    /* Mask value for bit 12 */
+#define MASK_13   0x00002000    /* Mask value for bit 13 */
+#define MASK_14   0x00004000    /* Mask value for bit 14 */
+#define MASK_15   0x00008000    /* Mask value for bit 15 */
+#define MASK_16   0x00010000    /* Mask value for bit 16 */
+#define MASK_17   0x00020000    /* Mask value for bit 17 */
+#define MASK_18   0x00040000    /* Mask value for bit 18 */
+#define MASK_19   0x00080000    /* Mask value for bit 19 */
+#define MASK_20   0x00100000    /* Mask value for bit 20 */
+#define MASK_21   0x00200000    /* Mask value for bit 21 */
+#define MASK_22   0x00400000    /* Mask value for bit 22 */
+#define MASK_23   0x00800000    /* Mask value for bit 23 */
+#define MASK_24   0x01000000    /* Mask value for bit 24 */
+#define MASK_25   0x02000000    /* Mask value for bit 25 */
+#define MASK_26   0x04000000    /* Mask value for bit 26 */
+#define MASK_27   0x08000000    /* Mask value for bit 27 */
+#define MASK_28   0x10000000    /* Mask value for bit 28 */
+#define MASK_29   0x20000000    /* Mask value for bit 29 */
+#define MASK_30   0x40000000    /* Mask value for bit 30 */
+#define MASK_31   0x80000000    /* Mask value for bit 31 */
+
+#define MASK_B0   0x000000ff    /* Mask value for byte 0 */
+#define MASK_B1   0x0000ff00    /* Mask value for byte 1 */
+#define MASK_B2   0x00ff0000    /* Mask value for byte 2 */
+#define MASK_B3   0xff000000    /* Mask value for byte 3 */
+
+#define MASK_W0   0x0000ffff    /* Mask value for word 0 */
+#define MASK_W1   0xffff0000    /* Mask value for word 1 */
+
+#define MASK_PA   0xfffffffc    /* Mask value for physical address */
+#define MASK_PR   0xfffffffe	/* Mask value for protection register */
+#define MASK_ER   0xffffffff    /* Mask value for the entire register */
+
+#define MASK_NONE 0x00000000    /* No mask */
+
+/* register aliases */
+#define BASE_ODD1         0x00  /* Video DMA 1 registers  */
+#define BASE_EVEN1        0x04
+#define PROT_ADDR1        0x08
+#define PITCH1            0x0C
+#define BASE_PAGE1        0x10  /* Video DMA 1 base page */
+#define NUM_LINE_BYTE1    0x14
+
+#define BASE_ODD2         0x18  /* Video DMA 2 registers */
+#define BASE_EVEN2        0x1C
+#define PROT_ADDR2        0x20
+#define PITCH2            0x24
+#define BASE_PAGE2        0x28  /* Video DMA 2 base page */
+#define NUM_LINE_BYTE2    0x2C
+
+#define BASE_ODD3         0x30  /* Video DMA 3 registers */
+#define BASE_EVEN3        0x34
+#define PROT_ADDR3        0x38
+#define PITCH3            0x3C
+#define BASE_PAGE3        0x40  /* Video DMA 3 base page */
+#define NUM_LINE_BYTE3    0x44
+
+#define PCI_BT_V1         0x48  /* Video/FIFO 1 */
+#define PCI_BT_V2         0x49  /* Video/FIFO 2 */
+#define PCI_BT_V3         0x4A  /* Video/FIFO 3 */
+#define PCI_BT_DEBI       0x4B  /* DEBI */
+#define PCI_BT_A          0x4C  /* Audio */
+
+#define DD1_INIT          0x50  /* Init setting of DD1 interface */
+
+#define DD1_STREAM_B      0x54  /* DD1 B video data stream handling */
+#define DD1_STREAM_A      0x56  /* DD1 A video data stream handling */
+
+#define BRS_CTRL          0x58  /* BRS control register */
+#define HPS_CTRL          0x5C  /* HPS control register */
+#define HPS_V_SCALE       0x60  /* HPS vertical scale */
+#define HPS_V_GAIN        0x64  /* HPS vertical ACL and gain */
+#define HPS_H_PRESCALE    0x68  /* HPS horizontal prescale   */
+#define HPS_H_SCALE       0x6C  /* HPS horizontal scale */
+#define BCS_CTRL          0x70  /* BCS control */
+#define CHROMA_KEY_RANGE  0x74
+#define CLIP_FORMAT_CTRL  0x78  /* HPS outputs formats & clipping */
+
+#define DEBI_CONFIG       0x7C
+#define DEBI_COMMAND      0x80
+#define DEBI_PAGE         0x84
+#define DEBI_AD           0x88
+
+#define I2C_TRANSFER      0x8C
+#define I2C_STATUS        0x90
+
+#define BASE_A1_IN        0x94	/* Audio 1 input DMA */
+#define PROT_A1_IN        0x98
+#define PAGE_A1_IN        0x9C
+
+#define BASE_A1_OUT       0xA0  /* Audio 1 output DMA */
+#define PROT_A1_OUT       0xA4
+#define PAGE_A1_OUT       0xA8
+
+#define BASE_A2_IN        0xAC  /* Audio 2 input DMA */
+#define PROT_A2_IN        0xB0
+#define PAGE_A2_IN        0xB4
+
+#define BASE_A2_OUT       0xB8  /* Audio 2 output DMA */
+#define PROT_A2_OUT       0xBC
+#define PAGE_A2_OUT       0xC0
+
+#define RPS_PAGE0         0xC4  /* RPS task 0 page register */
+#define RPS_PAGE1         0xC8  /* RPS task 1 page register */
+
+#define RPS_THRESH0       0xCC  /* HBI threshold for task 0 */
+#define RPS_THRESH1       0xD0  /* HBI threshold for task 1 */
+
+#define RPS_TOV0          0xD4  /* RPS timeout for task 0 */
+#define RPS_TOV1          0xD8  /* RPS timeout for task 1 */
+
+#define IER               0xDC  /* Interrupt enable register */
+
+#define GPIO_CTRL         0xE0  /* GPIO 0-3 register */
+
+#define EC1SSR            0xE4  /* Event cnt set 1 source select */
+#define EC2SSR            0xE8  /* Event cnt set 2 source select */
+#define ECT1R             0xEC  /* Event cnt set 1 thresholds */
+#define ECT2R             0xF0  /* Event cnt set 2 thresholds */
+
+#define ACON1             0xF4
+#define ACON2             0xF8
+
+#define MC1               0xFC   /* Main control register 1 */
+#define MC2               0x100  /* Main control register 2  */
+
+#define RPS_ADDR0         0x104  /* RPS task 0 address register */
+#define RPS_ADDR1         0x108  /* RPS task 1 address register */
+
+#define ISR               0x10C  /* Interrupt status register */
+#define PSR               0x110  /* Primary status register */
+#define SSR               0x114  /* Secondary status register */
+
+#define EC1R              0x118  /* Event counter set 1 register */
+#define EC2R              0x11C  /* Event counter set 2 register */
+
+#define PCI_VDP1          0x120  /* Video DMA pointer of FIFO 1 */
+#define PCI_VDP2          0x124  /* Video DMA pointer of FIFO 2 */
+#define PCI_VDP3          0x128  /* Video DMA pointer of FIFO 3 */
+#define PCI_ADP1          0x12C  /* Audio DMA pointer of audio out 1 */
+#define PCI_ADP2          0x130  /* Audio DMA pointer of audio in 1 */
+#define PCI_ADP3          0x134  /* Audio DMA pointer of audio out 2 */
+#define PCI_ADP4          0x138  /* Audio DMA pointer of audio in 2 */
+#define PCI_DMA_DDP       0x13C  /* DEBI DMA pointer */
+
+#define LEVEL_REP         0x140,
+#define A_TIME_SLOT1      0x180,  /* from 180 - 1BC */
+#define A_TIME_SLOT2      0x1C0,  /* from 1C0 - 1FC */
+
+/* isr masks */
+#define SPCI_PPEF       0x80000000  /* PCI parity error */
+#define SPCI_PABO       0x40000000  /* PCI access error (target or master abort) */
+#define SPCI_PPED       0x20000000  /* PCI parity error on 'real time data' */
+#define SPCI_RPS_I1     0x10000000  /* Interrupt issued by RPS1 */
+#define SPCI_RPS_I0     0x08000000  /* Interrupt issued by RPS0 */
+#define SPCI_RPS_LATE1  0x04000000  /* RPS task 1 is late */
+#define SPCI_RPS_LATE0  0x02000000  /* RPS task 0 is late */
+#define SPCI_RPS_E1     0x01000000  /* RPS error from task 1 */
+#define SPCI_RPS_E0     0x00800000  /* RPS error from task 0 */
+#define SPCI_RPS_TO1    0x00400000  /* RPS timeout task 1 */
+#define SPCI_RPS_TO0    0x00200000  /* RPS timeout task 0 */
+#define SPCI_UPLD       0x00100000  /* RPS in upload */
+#define SPCI_DEBI_S     0x00080000  /* DEBI status */
+#define SPCI_DEBI_E     0x00040000  /* DEBI error */
+#define SPCI_IIC_S      0x00020000  /* I2C status */
+#define SPCI_IIC_E      0x00010000  /* I2C error */
+#define SPCI_A2_IN      0x00008000  /* Audio 2 input DMA protection / limit */
+#define SPCI_A2_OUT     0x00004000  /* Audio 2 output DMA protection / limit */
+#define SPCI_A1_IN      0x00002000  /* Audio 1 input DMA protection / limit */
+#define SPCI_A1_OUT     0x00001000  /* Audio 1 output DMA protection / limit */
+#define SPCI_AFOU       0x00000800  /* Audio FIFO over- / underflow */
+#define SPCI_V_PE       0x00000400  /* Video protection address */
+#define SPCI_VFOU       0x00000200  /* Video FIFO over- / underflow */
+#define SPCI_FIDA       0x00000100  /* Field ID video port A */
+#define SPCI_FIDB       0x00000080  /* Field ID video port B */
+#define SPCI_PIN3       0x00000040  /* GPIO pin 3 */
+#define SPCI_PIN2       0x00000020  /* GPIO pin 2 */
+#define SPCI_PIN1       0x00000010  /* GPIO pin 1 */
+#define SPCI_PIN0       0x00000008  /* GPIO pin 0 */
+#define SPCI_ECS        0x00000004  /* Event counter 1, 2, 4, 5 */
+#define SPCI_EC3S       0x00000002  /* Event counter 3 */
+#define SPCI_EC0S       0x00000001  /* Event counter 0 */
+
+/* i2c */
+#define	SAA7146_I2C_ABORT	(1<<7)
+#define	SAA7146_I2C_SPERR	(1<<6)
+#define	SAA7146_I2C_APERR	(1<<5)
+#define	SAA7146_I2C_DTERR	(1<<4)
+#define	SAA7146_I2C_DRERR	(1<<3)
+#define	SAA7146_I2C_AL		(1<<2)
+#define	SAA7146_I2C_ERR		(1<<1)
+#define	SAA7146_I2C_BUSY	(1<<0)
+
+#define	SAA7146_I2C_START	(0x3)
+#define	SAA7146_I2C_CONT	(0x2)
+#define	SAA7146_I2C_STOP	(0x1)
+#define	SAA7146_I2C_NOP		(0x0)
+
+#define SAA7146_I2C_BUS_BIT_RATE_6400	(0x500)
+#define SAA7146_I2C_BUS_BIT_RATE_3200	(0x100)
+#define SAA7146_I2C_BUS_BIT_RATE_480	(0x400)
+#define SAA7146_I2C_BUS_BIT_RATE_320	(0x600)
+#define SAA7146_I2C_BUS_BIT_RATE_240	(0x700)
+#define SAA7146_I2C_BUS_BIT_RATE_120	(0x000)
+#define SAA7146_I2C_BUS_BIT_RATE_80	(0x200)
+#define SAA7146_I2C_BUS_BIT_RATE_60	(0x300)
+
+static inline void SAA7146_IER_DISABLE(struct saa7146_dev *x, unsigned y)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&x->int_slock, flags);
+	saa7146_write(x, IER, saa7146_read(x, IER) & ~y);
+	spin_unlock_irqrestore(&x->int_slock, flags);
+}
+
+static inline void SAA7146_IER_ENABLE(struct saa7146_dev *x, unsigned y)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&x->int_slock, flags);
+	saa7146_write(x, IER, saa7146_read(x, IER) | y);
+	spin_unlock_irqrestore(&x->int_slock, flags);
+}
+
+#endif
diff --git a/include/media/drv-intf/saa7146_vv.h b/include/media/drv-intf/saa7146_vv.h
new file mode 100644
index 0000000..6f80fb7
--- /dev/null
+++ b/include/media/drv-intf/saa7146_vv.h
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __SAA7146_VV__
+#define __SAA7146_VV__
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/drv-intf/saa7146.h>
+#include <media/videobuf-dma-sg.h>
+
+#define MAX_SAA7146_CAPTURE_BUFFERS	32	/* arbitrary */
+#define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
+
+#define WRITE_RPS0(x) do { \
+	dev->d_rps0.cpu_addr[ count++ ] = cpu_to_le32(x); \
+	} while (0);
+
+#define WRITE_RPS1(x) do { \
+	dev->d_rps1.cpu_addr[ count++ ] = cpu_to_le32(x); \
+	} while (0);
+
+struct	saa7146_video_dma {
+	u32 base_odd;
+	u32 base_even;
+	u32 prot_addr;
+	u32 pitch;
+	u32 base_page;
+	u32 num_line_byte;
+};
+
+#define FORMAT_BYTE_SWAP	0x1
+#define FORMAT_IS_PLANAR	0x2
+
+struct saa7146_format {
+	char	*name;
+	u32	pixelformat;
+	u32	trans;
+	u8	depth;
+	u8	flags;
+	u8	swap;
+};
+
+struct saa7146_standard
+{
+	char          *name;
+	v4l2_std_id   id;
+
+	int v_offset;	/* number of lines of vertical offset before processing */
+	int v_field;	/* number of lines in a field for HPS to process */
+
+	int h_offset;	/* horizontal offset of processing window */
+	int h_pixels;	/* number of horizontal pixels to process */
+
+	int v_max_out;
+	int h_max_out;
+};
+
+/* buffer for one video/vbi frame */
+struct saa7146_buf {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer vb;
+
+	/* saa7146 specific */
+	struct v4l2_pix_format  *fmt;
+	int (*activate)(struct saa7146_dev *dev,
+			struct saa7146_buf *buf,
+			struct saa7146_buf *next);
+
+	/* page tables */
+	struct saa7146_pgtable  pt[3];
+};
+
+struct saa7146_dmaqueue {
+	struct saa7146_dev	*dev;
+	struct saa7146_buf	*curr;
+	struct list_head	queue;
+	struct timer_list	timeout;
+};
+
+struct saa7146_overlay {
+	struct saa7146_fh	*fh;
+	struct v4l2_window	win;
+	struct v4l2_clip	clips[16];
+	int			nclips;
+};
+
+/* per open data */
+struct saa7146_fh {
+	/* Must be the first field! */
+	struct v4l2_fh		fh;
+	struct saa7146_dev	*dev;
+
+	/* video capture */
+	struct videobuf_queue	video_q;
+
+	/* vbi capture */
+	struct videobuf_queue	vbi_q;
+
+	unsigned int resources;	/* resource management for device open */
+};
+
+#define STATUS_OVERLAY	0x01
+#define STATUS_CAPTURE	0x02
+
+struct saa7146_vv
+{
+	/* vbi capture */
+	struct saa7146_dmaqueue		vbi_dmaq;
+	struct v4l2_vbi_format		vbi_fmt;
+	struct timer_list		vbi_read_timeout;
+	struct file			*vbi_read_timeout_file;
+	/* vbi workaround interrupt queue */
+	wait_queue_head_t		vbi_wq;
+	int				vbi_fieldcount;
+	struct saa7146_fh		*vbi_streaming;
+
+	int				video_status;
+	struct saa7146_fh		*video_fh;
+
+	/* video overlay */
+	struct saa7146_overlay		ov;
+	struct v4l2_framebuffer		ov_fb;
+	struct saa7146_format		*ov_fmt;
+	struct saa7146_fh		*ov_suspend;
+
+	/* video capture */
+	struct saa7146_dmaqueue		video_dmaq;
+	struct v4l2_pix_format		video_fmt;
+	enum v4l2_field			last_field;
+
+	/* common: fixme? shouldn't this be in saa7146_fh?
+	   (this leads to a more complicated question: shall the driver
+	   store the different settings (for example S_INPUT) for every open
+	   and restore it appropriately, or should all settings be common for
+	   all opens? currently, we do the latter, like all other
+	   drivers do... */
+	struct saa7146_standard	*standard;
+
+	int	vflip;
+	int	hflip;
+	int	current_hps_source;
+	int	current_hps_sync;
+
+	struct saa7146_dma	d_clipping;	/* pointer to clipping memory */
+
+	unsigned int resources;	/* resource management for device */
+};
+
+/* flags */
+#define SAA7146_USE_PORT_B_FOR_VBI	0x2     /* use input port b for vbi hardware bug workaround */
+
+struct saa7146_ext_vv
+{
+	/* informations about the video capabilities of the device */
+	int	inputs;
+	int	audios;
+	u32	capabilities;
+	int	flags;
+
+	/* additionally supported transmission standards */
+	struct saa7146_standard *stds;
+	int num_stds;
+	int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *);
+
+	/* the extension can override this */
+	struct v4l2_ioctl_ops vid_ops;
+	struct v4l2_ioctl_ops vbi_ops;
+	/* pointer to the saa7146 core ops */
+	const struct v4l2_ioctl_ops *core_ops;
+
+	struct v4l2_file_operations vbi_fops;
+};
+
+struct saa7146_use_ops  {
+	void (*init)(struct saa7146_dev *, struct saa7146_vv *);
+	int(*open)(struct saa7146_dev *, struct file *);
+	void (*release)(struct saa7146_dev *, struct file *);
+	void (*irq_done)(struct saa7146_dev *, unsigned long status);
+	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
+};
+
+/* from saa7146_fops.c */
+int saa7146_register_device(struct video_device *vid, struct saa7146_dev *dev, char *name, int type);
+int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev *dev);
+void saa7146_buffer_finish(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, int state);
+void saa7146_buffer_next(struct saa7146_dev *dev, struct saa7146_dmaqueue *q,int vbi);
+int saa7146_buffer_queue(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, struct saa7146_buf *buf);
+void saa7146_buffer_timeout(struct timer_list *t);
+void saa7146_dma_free(struct saa7146_dev* dev,struct videobuf_queue *q,
+						struct saa7146_buf *buf);
+
+int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv);
+int saa7146_vv_release(struct saa7146_dev* dev);
+
+/* from saa7146_hlp.c */
+int saa7146_enable_overlay(struct saa7146_fh *fh);
+void saa7146_disable_overlay(struct saa7146_fh *fh);
+
+void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next);
+void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma) ;
+void saa7146_set_hps_source_and_sync(struct saa7146_dev *saa, int source, int sync);
+void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
+
+/* from saa7146_video.c */
+extern const struct v4l2_ioctl_ops saa7146_video_ioctl_ops;
+extern const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops;
+extern const struct saa7146_use_ops saa7146_video_uops;
+int saa7146_start_preview(struct saa7146_fh *fh);
+int saa7146_stop_preview(struct saa7146_fh *fh);
+long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
+int saa7146_s_ctrl(struct v4l2_ctrl *ctrl);
+
+/* from saa7146_vbi.c */
+extern const struct saa7146_use_ops saa7146_vbi_uops;
+
+/* resource management functions */
+int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit);
+void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits);
+
+#define RESOURCE_DMA1_HPS	0x1
+#define RESOURCE_DMA2_CLP	0x2
+#define RESOURCE_DMA3_BRS	0x4
+
+/* saa7146 source inputs */
+#define SAA7146_HPS_SOURCE_PORT_A	0x00
+#define SAA7146_HPS_SOURCE_PORT_B	0x01
+#define SAA7146_HPS_SOURCE_YPB_CPA	0x02
+#define SAA7146_HPS_SOURCE_YPA_CPB	0x03
+
+/* sync inputs */
+#define SAA7146_HPS_SYNC_PORT_A		0x00
+#define SAA7146_HPS_SYNC_PORT_B		0x01
+
+/* some memory sizes */
+/* max. 16 clipping rectangles */
+#define SAA7146_CLIPPING_MEM	(16 * 4 * sizeof(u32))
+
+/* some defines for the various clipping-modes */
+#define SAA7146_CLIPPING_RECT		0x4
+#define SAA7146_CLIPPING_RECT_INVERTED	0x5
+#define SAA7146_CLIPPING_MASK		0x6
+#define SAA7146_CLIPPING_MASK_INVERTED	0x7
+
+/* output formats: each entry holds four informations */
+#define RGB08_COMPOSED	0x0217 /* composed is used in the sense of "not-planar" */
+/* this means: planar?=0, yuv2rgb-conversation-mode=2, dither=yes(=1), format-mode = 7 */
+#define RGB15_COMPOSED	0x0213
+#define RGB16_COMPOSED	0x0210
+#define RGB24_COMPOSED	0x0201
+#define RGB32_COMPOSED	0x0202
+
+#define Y8			0x0006
+#define YUV411_COMPOSED		0x0003
+#define YUV422_COMPOSED		0x0000
+/* this means: planar?=1, yuv2rgb-conversion-mode=0, dither=no(=0), format-mode = b */
+#define YUV411_DECOMPOSED	0x100b
+#define YUV422_DECOMPOSED	0x1009
+#define YUV420_DECOMPOSED	0x100a
+
+#define IS_PLANAR(x) (x & 0xf000)
+
+/* misc defines */
+#define SAA7146_NO_SWAP		(0x0)
+#define SAA7146_TWO_BYTE_SWAP	(0x1)
+#define SAA7146_FOUR_BYTE_SWAP	(0x2)
+
+#endif
diff --git a/include/media/drv-intf/sh_mobile_ceu.h b/include/media/drv-intf/sh_mobile_ceu.h
new file mode 100644
index 0000000..555f0ec
--- /dev/null
+++ b/include/media/drv-intf/sh_mobile_ceu.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_SH_MOBILE_CEU_H__
+#define __ASM_SH_MOBILE_CEU_H__
+
+#define SH_CEU_FLAG_USE_8BIT_BUS	(1 << 0) /* use  8bit bus width */
+#define SH_CEU_FLAG_USE_16BIT_BUS	(1 << 1) /* use 16bit bus width */
+#define SH_CEU_FLAG_HSYNC_LOW		(1 << 2) /* default High if possible */
+#define SH_CEU_FLAG_VSYNC_LOW		(1 << 3) /* default High if possible */
+#define SH_CEU_FLAG_LOWER_8BIT		(1 << 4) /* default upper 8bit */
+
+struct device;
+struct resource;
+
+struct sh_mobile_ceu_companion {
+	u32		num_resources;
+	struct resource	*resource;
+	int		id;
+	void		*platform_data;
+};
+
+struct sh_mobile_ceu_info {
+	unsigned long flags;
+	int max_width;
+	int max_height;
+	struct v4l2_async_subdev **asd;	/* Flat array, arranged in groups */
+	unsigned int *asd_sizes;	/* 0-terminated array pf asd group sizes */
+};
+
+#endif /* __ASM_SH_MOBILE_CEU_H__ */
diff --git a/include/media/drv-intf/sh_vou.h b/include/media/drv-intf/sh_vou.h
new file mode 100644
index 0000000..ec3ba9a
--- /dev/null
+++ b/include/media/drv-intf/sh_vou.h
@@ -0,0 +1,33 @@
+/*
+ * SuperH Video Output Unit (VOU) driver header
+ *
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef SH_VOU_H
+#define SH_VOU_H
+
+#include <linux/i2c.h>
+
+/* Bus flags */
+#define SH_VOU_PCLK_FALLING	(1 << 0)
+#define SH_VOU_HSYNC_LOW	(1 << 1)
+#define SH_VOU_VSYNC_LOW	(1 << 2)
+
+enum sh_vou_bus_fmt {
+	SH_VOU_BUS_8BIT,
+	SH_VOU_BUS_16BIT,
+	SH_VOU_BUS_BT656,
+};
+
+struct sh_vou_pdata {
+	enum sh_vou_bus_fmt bus_fmt;
+	int i2c_adap;
+	struct i2c_board_info *board_info;
+	unsigned long flags;
+};
+
+#endif
diff --git a/include/media/drv-intf/si476x.h b/include/media/drv-intf/si476x.h
new file mode 100644
index 0000000..ad87fa8
--- /dev/null
+++ b/include/media/drv-intf/si476x.h
@@ -0,0 +1,37 @@
+/*
+ * include/media/drv-intf/si476x.h -- Common definitions for si476x driver
+ *
+ * Copyright (C) 2012 Innovative Converged Devices(ICD)
+ * Copyright (C) 2013 Andrey Smirnov
+ *
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef SI476X_H
+#define SI476X_H
+
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#include <linux/mfd/si476x-reports.h>
+
+enum si476x_ctrl_id {
+	V4L2_CID_SI476X_RSSI_THRESHOLD	= (V4L2_CID_USER_SI476X_BASE + 1),
+	V4L2_CID_SI476X_SNR_THRESHOLD	= (V4L2_CID_USER_SI476X_BASE + 2),
+	V4L2_CID_SI476X_MAX_TUNE_ERROR	= (V4L2_CID_USER_SI476X_BASE + 3),
+	V4L2_CID_SI476X_HARMONICS_COUNT	= (V4L2_CID_USER_SI476X_BASE + 4),
+	V4L2_CID_SI476X_DIVERSITY_MODE	= (V4L2_CID_USER_SI476X_BASE + 5),
+	V4L2_CID_SI476X_INTERCHIP_LINK	= (V4L2_CID_USER_SI476X_BASE + 6),
+};
+
+#endif /* SI476X_H*/
diff --git a/include/media/drv-intf/soc_mediabus.h b/include/media/drv-intf/soc_mediabus.h
new file mode 100644
index 0000000..2ff7737
--- /dev/null
+++ b/include/media/drv-intf/soc_mediabus.h
@@ -0,0 +1,112 @@
+/*
+ * SoC-camera Media Bus API extensions
+ *
+ * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef SOC_MEDIABUS_H
+#define SOC_MEDIABUS_H
+
+#include <linux/videodev2.h>
+#include <linux/v4l2-mediabus.h>
+
+/**
+ * enum soc_mbus_packing - data packing types on the media-bus
+ * @SOC_MBUS_PACKING_NONE:	no packing, bit-for-bit transfer to RAM, one
+ *				sample represents one pixel
+ * @SOC_MBUS_PACKING_2X8_PADHI:	16 bits transferred in 2 8-bit samples, in the
+ *				possibly incomplete byte high bits are padding
+ * @SOC_MBUS_PACKING_2X8_PADLO:	as above, but low bits are padding
+ * @SOC_MBUS_PACKING_EXTEND16:	sample width (e.g., 10 bits) has to be extended
+ *				to 16 bits
+ * @SOC_MBUS_PACKING_VARIABLE:	compressed formats with variable packing
+ * @SOC_MBUS_PACKING_1_5X8:	used for packed YUV 4:2:0 formats, where 4
+ *				pixels occupy 6 bytes in RAM
+ * @SOC_MBUS_PACKING_EXTEND32:	sample width (e.g., 24 bits) has to be extended
+ *				to 32 bits
+ */
+enum soc_mbus_packing {
+	SOC_MBUS_PACKING_NONE,
+	SOC_MBUS_PACKING_2X8_PADHI,
+	SOC_MBUS_PACKING_2X8_PADLO,
+	SOC_MBUS_PACKING_EXTEND16,
+	SOC_MBUS_PACKING_VARIABLE,
+	SOC_MBUS_PACKING_1_5X8,
+	SOC_MBUS_PACKING_EXTEND32,
+};
+
+/**
+ * enum soc_mbus_order - sample order on the media bus
+ * @SOC_MBUS_ORDER_LE:		least significant sample first
+ * @SOC_MBUS_ORDER_BE:		most significant sample first
+ */
+enum soc_mbus_order {
+	SOC_MBUS_ORDER_LE,
+	SOC_MBUS_ORDER_BE,
+};
+
+/**
+ * enum soc_mbus_layout - planes layout in memory
+ * @SOC_MBUS_LAYOUT_PACKED:		color components packed
+ * @SOC_MBUS_LAYOUT_PLANAR_2Y_U_V:	YUV components stored in 3 planes (4:2:2)
+ * @SOC_MBUS_LAYOUT_PLANAR_2Y_C:	YUV components stored in a luma and a
+ *					chroma plane (C plane is half the size
+ *					of Y plane)
+ * @SOC_MBUS_LAYOUT_PLANAR_Y_C:		YUV components stored in a luma and a
+ *					chroma plane (C plane is the same size
+ *					as Y plane)
+ */
+enum soc_mbus_layout {
+	SOC_MBUS_LAYOUT_PACKED = 0,
+	SOC_MBUS_LAYOUT_PLANAR_2Y_U_V,
+	SOC_MBUS_LAYOUT_PLANAR_2Y_C,
+	SOC_MBUS_LAYOUT_PLANAR_Y_C,
+};
+
+/**
+ * struct soc_mbus_pixelfmt - Data format on the media bus
+ * @name:		Name of the format
+ * @fourcc:		Fourcc code, that will be obtained if the data is
+ *			stored in memory in the following way:
+ * @packing:		Type of sample-packing, that has to be used
+ * @order:		Sample order when storing in memory
+ * @bits_per_sample:	How many bits the bridge has to sample
+ */
+struct soc_mbus_pixelfmt {
+	const char		*name;
+	u32			fourcc;
+	enum soc_mbus_packing	packing;
+	enum soc_mbus_order	order;
+	enum soc_mbus_layout	layout;
+	u8			bits_per_sample;
+};
+
+/**
+ * struct soc_mbus_lookup - Lookup FOURCC IDs by mediabus codes for pass-through
+ * @code:	mediabus pixel-code
+ * @fmt:	pixel format description
+ */
+struct soc_mbus_lookup {
+	u32	code;
+	struct soc_mbus_pixelfmt	fmt;
+};
+
+const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
+	u32 code,
+	const struct soc_mbus_lookup *lookup,
+	int n);
+const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
+	u32 code);
+s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf);
+s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
+			u32 bytes_per_line, u32 height);
+int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
+			unsigned int *numerator, unsigned int *denominator);
+unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
+					unsigned int flags);
+
+#endif
diff --git a/include/media/drv-intf/tea575x.h b/include/media/drv-intf/tea575x.h
new file mode 100644
index 0000000..ba49238
--- /dev/null
+++ b/include/media/drv-intf/tea575x.h
@@ -0,0 +1,80 @@
+#ifndef __SOUND_TEA575X_TUNER_H
+#define __SOUND_TEA575X_TUNER_H
+
+/*
+ *   ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
+ *
+ *	Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ */
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+
+#define TEA575X_FMIF	10700
+#define TEA575X_AMIF	  450
+
+#define TEA575X_DATA	(1 << 0)
+#define TEA575X_CLK	(1 << 1)
+#define TEA575X_WREN	(1 << 2)
+#define TEA575X_MOST	(1 << 3)
+
+struct snd_tea575x;
+
+struct snd_tea575x_ops {
+	/* Drivers using snd_tea575x must either define read_ and write_val */
+	void (*write_val)(struct snd_tea575x *tea, u32 val);
+	u32 (*read_val)(struct snd_tea575x *tea);
+	/* Or define the 3 pin functions */
+	void (*set_pins)(struct snd_tea575x *tea, u8 pins);
+	u8 (*get_pins)(struct snd_tea575x *tea);
+	void (*set_direction)(struct snd_tea575x *tea, bool output);
+};
+
+struct snd_tea575x {
+	struct v4l2_device *v4l2_dev;
+	struct v4l2_file_operations fops;
+	struct video_device vd;		/* video device */
+	int radio_nr;			/* radio_nr */
+	bool tea5759;			/* 5759 chip is present */
+	bool has_am;			/* Device can tune to AM freqs */
+	bool cannot_read_data;		/* Device cannot read the data pin */
+	bool cannot_mute;		/* Device cannot mute */
+	bool mute;			/* Device is muted? */
+	bool stereo;			/* receiving stereo */
+	bool tuned;			/* tuned to a station */
+	unsigned int val;		/* hw value */
+	u32 band;			/* 0: FM, 1: FM-Japan, 2: AM */
+	u32 freq;			/* frequency */
+	struct mutex mutex;
+	const struct snd_tea575x_ops *ops;
+	void *private_data;
+	u8 card[32];
+	u8 bus_info[32];
+	struct v4l2_ctrl_handler ctrl_handler;
+	int (*ext_init)(struct snd_tea575x *tea);
+};
+
+int snd_tea575x_enum_freq_bands(struct snd_tea575x *tea,
+					struct v4l2_frequency_band *band);
+int snd_tea575x_g_tuner(struct snd_tea575x *tea, struct v4l2_tuner *v);
+int snd_tea575x_s_hw_freq_seek(struct file *file, struct snd_tea575x *tea,
+				const struct v4l2_hw_freq_seek *a);
+int snd_tea575x_hw_init(struct snd_tea575x *tea);
+int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner);
+void snd_tea575x_exit(struct snd_tea575x *tea);
+void snd_tea575x_set_freq(struct snd_tea575x *tea);
+
+#endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h
new file mode 100644
index 0000000..f9e73b4
--- /dev/null
+++ b/include/media/dvb-usb-ids.h
@@ -0,0 +1,425 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* dvb-usb-ids.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de) see
+ * dvb-usb-init.c for copyright information.
+ *
+ * a header file containing define's for the USB device supported by the
+ * various drivers.
+ */
+#ifndef _DVB_USB_IDS_H_
+#define _DVB_USB_IDS_H_
+
+/* Vendor IDs */
+#define USB_VID_ADSTECH				0x06e1
+#define USB_VID_AFATECH				0x15a4
+#define USB_VID_ALCOR_MICRO			0x058f
+#define USB_VID_ALINK				0x05e3
+#define USB_VID_AMT				0x1c73
+#define USB_VID_ANCHOR				0x0547
+#define USB_VID_ANSONIC				0x10b9
+#define USB_VID_ANUBIS_ELECTRONIC		0x10fd
+#define USB_VID_ASUS				0x0b05
+#define USB_VID_AVERMEDIA			0x07ca
+#define USB_VID_COMPRO				0x185b
+#define USB_VID_COMPRO_UNK			0x145f
+#define USB_VID_CONEXANT			0x0572
+#define USB_VID_CYPRESS				0x04b4
+#define USB_VID_DEXATEK				0x1d19
+#define USB_VID_DIBCOM				0x10b8
+#define USB_VID_DPOSH				0x1498
+#define USB_VID_DVICO				0x0fe9
+#define USB_VID_E3C				0x18b4
+#define USB_VID_ELGATO				0x0fd9
+#define USB_VID_EMPIA				0xeb1a
+#define USB_VID_GENPIX				0x09c0
+#define USB_VID_GRANDTEC			0x5032
+#define USB_VID_GTEK				0x1f4d
+#define USB_VID_HANFTEK				0x15f4
+#define USB_VID_HAUPPAUGE			0x2040
+#define USB_VID_HYPER_PALTEK			0x1025
+#define USB_VID_INTEL				0x8086
+#define USB_VID_ITETECH				0x048d
+#define USB_VID_KWORLD				0xeb2a
+#define USB_VID_KWORLD_2			0x1b80
+#define USB_VID_KYE				0x0458
+#define USB_VID_LEADTEK				0x0413
+#define USB_VID_LITEON				0x04ca
+#define USB_VID_MEDION				0x1660
+#define USB_VID_MIGLIA				0x18f3
+#define USB_VID_MSI				0x0db0
+#define USB_VID_MSI_2				0x1462
+#define USB_VID_OPERA1				0x695c
+#define USB_VID_PINNACLE			0x2304
+#define USB_VID_PCTV				0x2013
+#define USB_VID_PIXELVIEW			0x1554
+#define USB_VID_REALTEK				0x0bda
+#define USB_VID_TECHNOTREND			0x0b48
+#define USB_VID_TERRATEC			0x0ccd
+#define USB_VID_TELESTAR			0x10b9
+#define USB_VID_VISIONPLUS			0x13d3
+#define USB_VID_SONY				0x1415
+#define USB_PID_TEVII_S421			0xd421
+#define USB_PID_TEVII_S480_1			0xd481
+#define USB_PID_TEVII_S480_2			0xd482
+#define USB_PID_TEVII_S630			0xd630
+#define USB_PID_TEVII_S632			0xd632
+#define USB_PID_TEVII_S650			0xd650
+#define USB_PID_TEVII_S660			0xd660
+#define USB_PID_TEVII_S662			0xd662
+#define USB_VID_TWINHAN				0x1822
+#define USB_VID_ULTIMA_ELECTRONIC		0x05d8
+#define USB_VID_UNIWILL				0x1584
+#define USB_VID_WIDEVIEW			0x14aa
+#define USB_VID_GIGABYTE			0x1044
+#define USB_VID_YUAN				0x1164
+#define USB_VID_XTENSIONS			0x1ae7
+#define USB_VID_ZYDAS				0x0ace
+#define USB_VID_HUMAX_COEX			0x10b9
+#define USB_VID_774				0x7a69
+#define USB_VID_EVOLUTEPC			0x1e59
+#define USB_VID_AZUREWAVE			0x13d3
+#define USB_VID_TECHNISAT			0x14f7
+#define USB_VID_HAMA				0x147f
+#define USB_VID_MICROSOFT			0x045e
+
+/* Product IDs */
+#define USB_PID_ADSTECH_USB2_COLD			0xa333
+#define USB_PID_ADSTECH_USB2_WARM			0xa334
+#define USB_PID_AFATECH_AF9005				0x9020
+#define USB_PID_AFATECH_AF9015_9015			0x9015
+#define USB_PID_AFATECH_AF9015_9016			0x9016
+#define USB_PID_AFATECH_AF9035_1000			0x1000
+#define USB_PID_AFATECH_AF9035_1001			0x1001
+#define USB_PID_AFATECH_AF9035_1002			0x1002
+#define USB_PID_AFATECH_AF9035_1003			0x1003
+#define USB_PID_AFATECH_AF9035_9035			0x9035
+#define USB_PID_TREKSTOR_DVBT				0x901b
+#define USB_PID_TREKSTOR_TERRES_2_0			0xC803
+#define USB_VID_ALINK_DTU				0xf170
+#define USB_PID_ANSONIC_DVBT_USB			0x6000
+#define USB_PID_ANYSEE					0x861f
+#define USB_PID_AZUREWAVE_AD_TU700			0x3237
+#define USB_PID_AZUREWAVE_6007				0x0ccd
+#define USB_PID_AVERMEDIA_DVBT_USB_COLD			0x0001
+#define USB_PID_AVERMEDIA_DVBT_USB_WARM			0x0002
+#define USB_PID_AVERMEDIA_DVBT_USB2_COLD		0xa800
+#define USB_PID_AVERMEDIA_DVBT_USB2_WARM		0xa801
+#define USB_PID_COMPRO_DVBU2000_COLD			0xd000
+#define USB_PID_COMPRO_DVBU2000_WARM			0xd001
+#define USB_PID_COMPRO_DVBU2000_UNK_COLD		0x010c
+#define USB_PID_COMPRO_DVBU2000_UNK_WARM		0x010d
+#define USB_PID_COMPRO_VIDEOMATE_U500			0x1e78
+#define USB_PID_COMPRO_VIDEOMATE_U500_PC		0x1e80
+#define USB_PID_CONCEPTRONIC_CTVDIGRCU			0xe397
+#define USB_PID_CONEXANT_D680_DMB			0x86d6
+#define USB_PID_CREATIX_CTX1921				0x1921
+#define USB_PID_DELOCK_USB2_DVBT			0xb803
+#define USB_PID_DIBCOM_HOOK_DEFAULT			0x0064
+#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM		0x0065
+#define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
+#define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
+#define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
+#define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
+#define USB_PID_DIBCOM_STK7700P				0x1e14
+#define USB_PID_DIBCOM_STK7700P_PC			0x1e78
+#define USB_PID_DIBCOM_STK7700D				0x1ef0
+#define USB_PID_DIBCOM_STK7700_U7000			0x7001
+#define USB_PID_DIBCOM_STK7070P				0x1ebc
+#define USB_PID_DIBCOM_STK7070PD			0x1ebe
+#define USB_PID_DIBCOM_STK807XP				0x1f90
+#define USB_PID_DIBCOM_STK807XPVR			0x1f98
+#define USB_PID_DIBCOM_STK8096GP                        0x1fa0
+#define USB_PID_DIBCOM_STK8096PVR                       0x1faa
+#define USB_PID_DIBCOM_NIM8096MD                        0x1fa8
+#define USB_PID_DIBCOM_TFE8096P				0x1f9C
+#define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131
+#define USB_PID_DIBCOM_STK7770P				0x1e80
+#define USB_PID_DIBCOM_NIM7090				0x1bb2
+#define USB_PID_DIBCOM_TFE7090PVR			0x1bb4
+#define USB_PID_DIBCOM_TFE7790P				0x1e6e
+#define USB_PID_DIBCOM_NIM9090M				0x2383
+#define USB_PID_DIBCOM_NIM9090MD			0x2384
+#define USB_PID_DPOSH_M9206_COLD			0x9206
+#define USB_PID_DPOSH_M9206_WARM			0xa090
+#define USB_PID_E3C_EC168				0x1689
+#define USB_PID_E3C_EC168_2				0xfffa
+#define USB_PID_E3C_EC168_3				0xfffb
+#define USB_PID_E3C_EC168_4				0x1001
+#define USB_PID_E3C_EC168_5				0x1002
+#define USB_PID_FREECOM_DVBT				0x0160
+#define USB_PID_FREECOM_DVBT_2				0x0161
+#define USB_PID_UNIWILL_STK7700P			0x6003
+#define USB_PID_GENIUS_TVGO_DVB_T03			0x4012
+#define USB_PID_GRANDTEC_DVBT_USB_COLD			0x0fa0
+#define USB_PID_GRANDTEC_DVBT_USB_WARM			0x0fa1
+#define USB_PID_GOTVIEW_SAT_HD				0x5456
+#define USB_PID_INTEL_CE9500				0x9500
+#define USB_PID_ITETECH_IT9135				0x9135
+#define USB_PID_ITETECH_IT9135_9005			0x9005
+#define USB_PID_ITETECH_IT9135_9006			0x9006
+#define USB_PID_ITETECH_IT9303				0x9306
+#define USB_PID_KWORLD_399U				0xe399
+#define USB_PID_KWORLD_399U_2				0xe400
+#define USB_PID_KWORLD_395U				0xe396
+#define USB_PID_KWORLD_395U_2				0xe39b
+#define USB_PID_KWORLD_395U_3				0xe395
+#define USB_PID_KWORLD_395U_4				0xe39a
+#define USB_PID_KWORLD_MC810				0xc810
+#define USB_PID_KWORLD_PC160_2T				0xc160
+#define USB_PID_KWORLD_PC160_T				0xc161
+#define USB_PID_KWORLD_UB383_T				0xe383
+#define USB_PID_KWORLD_UB499_2T_T09			0xe409
+#define USB_PID_KWORLD_VSTREAM_COLD			0x17de
+#define USB_PID_KWORLD_VSTREAM_WARM			0x17df
+#define USB_PID_PROF_1100				0xb012
+#define USB_PID_TERRATEC_CINERGY_S			0x0064
+#define USB_PID_TERRATEC_CINERGY_T_USB_XE		0x0055
+#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2		0x0069
+#define USB_PID_TERRATEC_CINERGY_T_STICK		0x0093
+#define USB_PID_TERRATEC_CINERGY_T_STICK_RC		0x0097
+#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC	0x0099
+#define USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1	0x00a9
+#define USB_PID_TWINHAN_VP7041_COLD			0x3201
+#define USB_PID_TWINHAN_VP7041_WARM			0x3202
+#define USB_PID_TWINHAN_VP7020_COLD			0x3203
+#define USB_PID_TWINHAN_VP7020_WARM			0x3204
+#define USB_PID_TWINHAN_VP7045_COLD			0x3205
+#define USB_PID_TWINHAN_VP7045_WARM			0x3206
+#define USB_PID_TWINHAN_VP7021_COLD			0x3207
+#define USB_PID_TWINHAN_VP7021_WARM			0x3208
+#define USB_PID_TWINHAN_VP7049				0x3219
+#define USB_PID_TINYTWIN				0x3226
+#define USB_PID_TINYTWIN_2				0xe402
+#define USB_PID_TINYTWIN_3				0x9016
+#define USB_PID_DNTV_TINYUSB2_COLD			0x3223
+#define USB_PID_DNTV_TINYUSB2_WARM			0x3224
+#define USB_PID_ULTIMA_TVBOX_COLD			0x8105
+#define USB_PID_ULTIMA_TVBOX_WARM			0x8106
+#define USB_PID_ULTIMA_TVBOX_AN2235_COLD		0x8107
+#define USB_PID_ULTIMA_TVBOX_AN2235_WARM		0x8108
+#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD		0x2235
+#define USB_PID_ULTIMA_TVBOX_USB2_COLD			0x8109
+#define USB_PID_ULTIMA_TVBOX_USB2_WARM			0x810a
+#define USB_PID_ARTEC_T14_COLD				0x810b
+#define USB_PID_ARTEC_T14_WARM				0x810c
+#define USB_PID_ARTEC_T14BR				0x810f
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD		0x8613
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM		0x1002
+#define USB_PID_UNK_HYPER_PALTEK_COLD			0x005e
+#define USB_PID_UNK_HYPER_PALTEK_WARM			0x005f
+#define USB_PID_HANFTEK_UMT_010_COLD			0x0001
+#define USB_PID_HANFTEK_UMT_010_WARM			0x0015
+#define USB_PID_DTT200U_COLD				0x0201
+#define USB_PID_DTT200U_WARM				0x0301
+#define USB_PID_WT220U_ZAP250_COLD			0x0220
+#define USB_PID_WT220U_COLD				0x0222
+#define USB_PID_WT220U_WARM				0x0221
+#define USB_PID_WT220U_FC_COLD				0x0225
+#define USB_PID_WT220U_FC_WARM				0x0226
+#define USB_PID_WT220U_ZL0353_COLD			0x022a
+#define USB_PID_WT220U_ZL0353_WARM			0x022b
+#define USB_PID_WINTV_NOVA_T_USB2_COLD			0x9300
+#define USB_PID_WINTV_NOVA_T_USB2_WARM			0x9301
+#define USB_PID_HAUPPAUGE_NOVA_T_500			0x9941
+#define USB_PID_HAUPPAUGE_NOVA_T_500_2			0x9950
+#define USB_PID_HAUPPAUGE_NOVA_T_500_3			0x8400
+#define USB_PID_HAUPPAUGE_NOVA_T_STICK			0x7050
+#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2		0x7060
+#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3		0x7070
+#define USB_PID_HAUPPAUGE_MYTV_T			0x7080
+#define USB_PID_HAUPPAUGE_NOVA_TD_STICK			0x9580
+#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009		0x5200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC			0xb200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210		0xb210
+#define USB_PID_AVERMEDIA_EXPRESS			0xb568
+#define USB_PID_AVERMEDIA_VOLAR				0xa807
+#define USB_PID_AVERMEDIA_VOLAR_2			0xb808
+#define USB_PID_AVERMEDIA_VOLAR_A868R			0xa868
+#define USB_PID_AVERMEDIA_MCE_USB_M038			0x1228
+#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R	0x0039
+#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC	0x1039
+#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT	0x2039
+#define USB_PID_AVERMEDIA_VOLAR_X			0xa815
+#define USB_PID_AVERMEDIA_VOLAR_X_2			0x8150
+#define USB_PID_AVERMEDIA_A309				0xa309
+#define USB_PID_AVERMEDIA_A310				0xa310
+#define USB_PID_AVERMEDIA_A850				0x850a
+#define USB_PID_AVERMEDIA_A850T				0x850b
+#define USB_PID_AVERMEDIA_A805				0xa805
+#define USB_PID_AVERMEDIA_A815M				0x815a
+#define USB_PID_AVERMEDIA_A835				0xa835
+#define USB_PID_AVERMEDIA_B835				0xb835
+#define USB_PID_AVERMEDIA_A835B_1835			0x1835
+#define USB_PID_AVERMEDIA_A835B_2835			0x2835
+#define USB_PID_AVERMEDIA_A835B_3835			0x3835
+#define USB_PID_AVERMEDIA_A835B_4835			0x4835
+#define USB_PID_AVERMEDIA_1867				0x1867
+#define USB_PID_AVERMEDIA_A867				0xa867
+#define USB_PID_AVERMEDIA_H335				0x0335
+#define USB_PID_AVERMEDIA_TD110				0xa110
+#define USB_PID_AVERMEDIA_TWINSTAR			0x0825
+#define USB_PID_TECHNOTREND_CONNECT_S2400               0x3006
+#define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM	0x3009
+#define USB_PID_TECHNOTREND_CONNECT_CT3650		0x300d
+#define USB_PID_TECHNOTREND_CONNECT_S2_4600             0x3011
+#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI		0x3012
+#define USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI_2	0x3015
+#define USB_PID_TECHNOTREND_TVSTICK_CT2_4400		0x3014
+#define USB_PID_TECHNOTREND_CONNECT_S2_4650_CI		0x3017
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2	0x0081
+#define USB_PID_TERRATEC_CINERGY_HT_USB_XE		0x0058
+#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS		0x0060
+#define USB_PID_TERRATEC_CINERGY_T_EXPRESS		0x0062
+#define USB_PID_TERRATEC_CINERGY_T_XXS			0x0078
+#define USB_PID_TERRATEC_CINERGY_T_XXS_2		0x00ab
+#define USB_PID_TERRATEC_CINERGY_S2_R1			0x00a8
+#define USB_PID_TERRATEC_CINERGY_S2_R2			0x00b0
+#define USB_PID_TERRATEC_CINERGY_S2_R3			0x0102
+#define USB_PID_TERRATEC_CINERGY_S2_R4			0x0105
+#define USB_PID_TERRATEC_H7				0x10b4
+#define USB_PID_TERRATEC_H7_2				0x10a3
+#define USB_PID_TERRATEC_H7_3				0x10a5
+#define USB_PID_TERRATEC_T1				0x10ae
+#define USB_PID_TERRATEC_T3				0x10a0
+#define USB_PID_TERRATEC_T5				0x10a1
+#define USB_PID_NOXON_DAB_STICK				0x00b3
+#define USB_PID_NOXON_DAB_STICK_REV2			0x00e0
+#define USB_PID_NOXON_DAB_STICK_REV3			0x00b4
+#define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
+#define USB_PID_PINNACLE_PCTV2000E			0x022c
+#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH		0x0228
+#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T	0x0229
+#define USB_PID_PINNACLE_PCTV71E			0x022b
+#define USB_PID_PINNACLE_PCTV72E			0x0236
+#define USB_PID_PINNACLE_PCTV73E			0x0237
+#define USB_PID_PINNACLE_PCTV310E			0x3211
+#define USB_PID_PINNACLE_PCTV801E			0x023a
+#define USB_PID_PINNACLE_PCTV801E_SE			0x023b
+#define USB_PID_PINNACLE_PCTV340E			0x023d
+#define USB_PID_PINNACLE_PCTV340E_SE			0x023e
+#define USB_PID_PINNACLE_PCTV73A			0x0243
+#define USB_PID_PINNACLE_PCTV73ESE			0x0245
+#define USB_PID_PINNACLE_PCTV74E			0x0246
+#define USB_PID_PINNACLE_PCTV282E			0x0248
+#define USB_PID_PIXELVIEW_SBTVD				0x5010
+#define USB_PID_PCTV_200E				0x020e
+#define USB_PID_PCTV_400E				0x020f
+#define USB_PID_PCTV_450E				0x0222
+#define USB_PID_PCTV_452E				0x021f
+#define USB_PID_PCTV_78E				0x025a
+#define USB_PID_PCTV_79E				0x0262
+#define USB_PID_REALTEK_RTL2831U			0x2831
+#define USB_PID_REALTEK_RTL2832U			0x2832
+#define USB_PID_TECHNOTREND_CONNECT_S2_3600		0x3007
+#define USB_PID_TECHNOTREND_CONNECT_S2_3650_CI		0x300a
+#define USB_PID_NEBULA_DIGITV				0x0201
+#define USB_PID_DVICO_BLUEBIRD_LGDT			0xd820
+#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD		0xd500
+#define USB_PID_DVICO_BLUEBIRD_LG064F_WARM		0xd501
+#define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD		0xdb00
+#define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM		0xdb01
+#define USB_PID_DVICO_BLUEBIRD_TH7579_COLD		0xdb10
+#define USB_PID_DVICO_BLUEBIRD_TH7579_WARM		0xdb11
+#define USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD		0xdb50
+#define USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM		0xdb51
+#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD		0xdb58
+#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM		0xdb59
+#define USB_PID_DVICO_BLUEBIRD_DUAL_4			0xdb78
+#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2		0xdb98
+#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2		0xdb70
+#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM	0xdb71
+#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD		0xdb54
+#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM		0xdb55
+#define USB_PID_MEDION_MD95700				0x0932
+#define USB_PID_MSI_MEGASKY580				0x5580
+#define USB_PID_MSI_MEGASKY580_55801			0x5581
+#define USB_PID_KYE_DVB_T_COLD				0x701e
+#define USB_PID_KYE_DVB_T_WARM				0x701f
+#define USB_PID_LITEON_DVB_T_COLD			0xf000
+#define USB_PID_LITEON_DVB_T_WARM			0xf001
+#define USB_PID_DIGIVOX_MINI_SL_COLD			0xe360
+#define USB_PID_DIGIVOX_MINI_SL_WARM			0xe361
+#define USB_PID_GRANDTEC_DVBT_USB2_COLD			0x0bc6
+#define USB_PID_GRANDTEC_DVBT_USB2_WARM			0x0bc7
+#define USB_PID_WINFAST_DTV2000DS			0x6a04
+#define USB_PID_WINFAST_DTV2000DS_PLUS			0x6f12
+#define USB_PID_WINFAST_DTV_DONGLE_COLD			0x6025
+#define USB_PID_WINFAST_DTV_DONGLE_WARM			0x6026
+#define USB_PID_WINFAST_DTV_DONGLE_STK7700P		0x6f00
+#define USB_PID_WINFAST_DTV_DONGLE_H			0x60f6
+#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2		0x6f01
+#define USB_PID_WINFAST_DTV_DONGLE_GOLD			0x6029
+#define USB_PID_WINFAST_DTV_DONGLE_MINID		0x6f0f
+#define USB_PID_GENPIX_8PSK_REV_1_COLD			0x0200
+#define USB_PID_GENPIX_8PSK_REV_1_WARM			0x0201
+#define USB_PID_GENPIX_8PSK_REV_2			0x0202
+#define USB_PID_GENPIX_SKYWALKER_1			0x0203
+#define USB_PID_GENPIX_SKYWALKER_CW3K			0x0204
+#define USB_PID_GENPIX_SKYWALKER_2			0x0206
+#define USB_PID_SIGMATEK_DVB_110			0x6610
+#define USB_PID_MSI_DIGI_VOX_MINI_II			0x1513
+#define USB_PID_MSI_DIGIVOX_DUO				0x8801
+#define USB_PID_OPERA1_COLD				0x2830
+#define USB_PID_OPERA1_WARM				0x3829
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD		0x0514
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM		0x0513
+#define USB_PID_GIGABYTE_U7000				0x7001
+#define USB_PID_GIGABYTE_U8000				0x7002
+#define USB_PID_ASUS_U3000				0x171f
+#define USB_PID_ASUS_U3000H				0x1736
+#define USB_PID_ASUS_U3100				0x173f
+#define USB_PID_ASUS_U3100MINI_PLUS			0x1779
+#define USB_PID_YUAN_EC372S				0x1edc
+#define USB_PID_YUAN_STK7700PH				0x1f08
+#define USB_PID_YUAN_PD378S				0x2edc
+#define USB_PID_YUAN_MC770				0x0871
+#define USB_PID_YUAN_STK7700D				0x1efc
+#define USB_PID_YUAN_STK7700D_2				0x1e8c
+#define USB_PID_DW2102					0x2102
+#define USB_PID_DW2104					0x2104
+#define USB_PID_DW3101					0x3101
+#define USB_PID_XTENSIONS_XD_380			0x0381
+#define USB_PID_TELESTAR_STARSTICK_2			0x8000
+#define USB_PID_MSI_DIGI_VOX_MINI_III                   0x8807
+#define USB_PID_SONY_PLAYTV				0x0003
+#define USB_PID_MYGICA_D689				0xd811
+#define USB_PID_MYGICA_T230				0xc688
+#define USB_PID_MYGICA_T230C				0xc689
+#define USB_PID_ELGATO_EYETV_DIVERSITY			0x0011
+#define USB_PID_ELGATO_EYETV_DTT			0x0021
+#define USB_PID_ELGATO_EYETV_DTT_2			0x003f
+#define USB_PID_ELGATO_EYETV_DTT_Dlx			0x0020
+#define USB_PID_ELGATO_EYETV_SAT			0x002a
+#define USB_PID_ELGATO_EYETV_SAT_V2			0x0025
+#define USB_PID_ELGATO_EYETV_SAT_V3			0x0036
+#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD		0x5000
+#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM		0x5001
+#define USB_PID_FRIIO_WHITE				0x0001
+#define USB_PID_TVWAY_PLUS				0x0002
+#define USB_PID_SVEON_STV20				0xe39d
+#define USB_PID_SVEON_STV20_RTL2832U			0xd39d
+#define USB_PID_SVEON_STV21				0xd3b0
+#define USB_PID_SVEON_STV22				0xe401
+#define USB_PID_SVEON_STV22_IT9137			0xe411
+#define USB_PID_AZUREWAVE_AZ6027			0x3275
+#define USB_PID_TERRATEC_DVBS2CI_V1			0x10a4
+#define USB_PID_TERRATEC_DVBS2CI_V2			0x10ac
+#define USB_PID_TECHNISAT_USB2_HDCI_V1			0x0001
+#define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002
+#define USB_PID_TECHNISAT_USB2_CABLESTAR_HDCI		0x0003
+#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004
+#define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
+#define USB_PID_CPYTO_REDI_PC50A			0xa803
+#define USB_PID_CTVDIGDUAL_V2				0xe410
+#define USB_PID_PCTV_2002E                              0x025c
+#define USB_PID_PCTV_2002E_SE                           0x025d
+#define USB_PID_SVEON_STV27                             0xd3af
+#define USB_PID_TURBOX_DTT_2000                         0xd3a4
+#define USB_PID_WINTV_SOLOHD                            0x0264
+#define USB_PID_WINTV_SOLOHD_2                          0x8268
+#define USB_PID_EVOLVEO_XTRATV_STICK			0xa115
+#define USB_PID_HAMA_DVBT_HYBRID			0x2758
+#define USB_PID_XBOX_ONE_TUNER                          0x02d5
+#endif
diff --git a/include/media/dvb_ca_en50221.h b/include/media/dvb_ca_en50221.h
new file mode 100644
index 0000000..a1c014b
--- /dev/null
+++ b/include/media/dvb_ca_en50221.h
@@ -0,0 +1,142 @@
+/*
+ * dvb_ca.h: generic DVB functions for EN50221 CA interfaces
+ *
+ * Copyright (C) 2004 Andrew de Quincey
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DVB_CA_EN50221_H_
+#define _DVB_CA_EN50221_H_
+
+#include <linux/list.h>
+#include <linux/dvb/ca.h>
+
+#include <media/dvbdev.h>
+
+#define DVB_CA_EN50221_POLL_CAM_PRESENT	1
+#define DVB_CA_EN50221_POLL_CAM_CHANGED	2
+#define DVB_CA_EN50221_POLL_CAM_READY		4
+
+#define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE	1
+#define DVB_CA_EN50221_FLAG_IRQ_FR		2
+#define DVB_CA_EN50221_FLAG_IRQ_DA		4
+
+#define DVB_CA_EN50221_CAMCHANGE_REMOVED		0
+#define DVB_CA_EN50221_CAMCHANGE_INSERTED		1
+
+/**
+ * struct dvb_ca_en50221- Structure describing a CA interface
+ *
+ * @owner:		the module owning this structure
+ * @read_attribute_mem:	function for reading attribute memory on the CAM
+ * @write_attribute_mem: function for writing attribute memory on the CAM
+ * @read_cam_control:	function for reading the control interface on the CAM
+ * @write_cam_control:	function for reading the control interface on the CAM
+ * @read_data:		function for reading data (block mode)
+ * @write_data:		function for writing data (block mode)
+ * @slot_reset:		function to reset the CAM slot
+ * @slot_shutdown:	function to shutdown a CAM slot
+ * @slot_ts_enable:	function to enable the Transport Stream on a CAM slot
+ * @poll_slot_status:	function to poll slot status. Only necessary if
+ *			DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set.
+ * @data:		private data, used by caller.
+ * @private:		Opaque data used by the dvb_ca core. Do not modify!
+ *
+ * NOTE: the read_*, write_* and poll_slot_status functions will be
+ * called for different slots concurrently and need to use locks where
+ * and if appropriate. There will be no concurrent access to one slot.
+ */
+struct dvb_ca_en50221 {
+	struct module *owner;
+
+	int (*read_attribute_mem)(struct dvb_ca_en50221 *ca,
+				  int slot, int address);
+	int (*write_attribute_mem)(struct dvb_ca_en50221 *ca,
+				   int slot, int address, u8 value);
+
+	int (*read_cam_control)(struct dvb_ca_en50221 *ca,
+				int slot, u8 address);
+	int (*write_cam_control)(struct dvb_ca_en50221 *ca,
+				 int slot, u8 address, u8 value);
+
+	int (*read_data)(struct dvb_ca_en50221 *ca,
+			 int slot, u8 *ebuf, int ecount);
+	int (*write_data)(struct dvb_ca_en50221 *ca,
+			  int slot, u8 *ebuf, int ecount);
+
+	int (*slot_reset)(struct dvb_ca_en50221 *ca, int slot);
+	int (*slot_shutdown)(struct dvb_ca_en50221 *ca, int slot);
+	int (*slot_ts_enable)(struct dvb_ca_en50221 *ca, int slot);
+
+	int (*poll_slot_status)(struct dvb_ca_en50221 *ca, int slot, int open);
+
+	void *data;
+
+	void *private;
+};
+
+/*
+ * Functions for reporting IRQ events
+ */
+
+/**
+ * dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
+ *
+ * @pubca: CA instance.
+ * @slot: Slot concerned.
+ * @change_type: One of the DVB_CA_CAMCHANGE_* values
+ */
+void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot,
+				  int change_type);
+
+/**
+ * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
+ *
+ * @pubca: CA instance.
+ * @slot: Slot concerned.
+ */
+void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot);
+
+/**
+ * dvb_ca_en50221_frda_irq - An FR or a DA IRQ has occurred.
+ *
+ * @ca: CA instance.
+ * @slot: Slot concerned.
+ */
+void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *ca, int slot);
+
+/*
+ * Initialisation/shutdown functions
+ */
+
+/**
+ * dvb_ca_en50221_init - Initialise a new DVB CA device.
+ *
+ * @dvb_adapter: DVB adapter to attach the new CA device to.
+ * @ca: The dvb_ca instance.
+ * @flags: Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
+ * @slot_count: Number of slots supported.
+ *
+ * @return 0 on success, nonzero on failure
+ */
+int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
+			struct dvb_ca_en50221 *ca, int flags,
+			       int slot_count);
+
+/**
+ * dvb_ca_en50221_release - Release a DVB CA device.
+ *
+ * @ca: The associated dvb_ca instance.
+ */
+void dvb_ca_en50221_release(struct dvb_ca_en50221 *ca);
+
+#endif
diff --git a/include/media/dvb_demux.h b/include/media/dvb_demux.h
new file mode 100644
index 0000000..3b6aeca
--- /dev/null
+++ b/include/media/dvb_demux.h
@@ -0,0 +1,354 @@
+/*
+ * dvb_demux.h: DVB kernel demux API
+ *
+ * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler
+ *                         for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DVB_DEMUX_H_
+#define _DVB_DEMUX_H_
+
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
+#include <media/demux.h>
+
+/**
+ * enum dvb_dmx_filter_type - type of demux feed.
+ *
+ * @DMX_TYPE_TS:	feed is in TS mode.
+ * @DMX_TYPE_SEC:	feed is in Section mode.
+ */
+enum dvb_dmx_filter_type {
+	DMX_TYPE_TS,
+	DMX_TYPE_SEC,
+};
+
+/**
+ * enum dvb_dmx_state - state machine for a demux filter.
+ *
+ * @DMX_STATE_FREE:		indicates that the filter is freed.
+ * @DMX_STATE_ALLOCATED:	indicates that the filter was allocated
+ *				to be used.
+ * @DMX_STATE_READY:		indicates that the filter is ready
+ *				to be used.
+ * @DMX_STATE_GO:		indicates that the filter is running.
+ */
+enum dvb_dmx_state {
+	DMX_STATE_FREE,
+	DMX_STATE_ALLOCATED,
+	DMX_STATE_READY,
+	DMX_STATE_GO,
+};
+
+#define DVB_DEMUX_MASK_MAX 18
+
+#define MAX_PID 0x1fff
+
+#define SPEED_PKTS_INTERVAL 50000
+
+/**
+ * struct dvb_demux_filter - Describes a DVB demux section filter.
+ *
+ * @filter:		Section filter as defined by &struct dmx_section_filter.
+ * @maskandmode:	logical ``and`` bit mask.
+ * @maskandnotmode:	logical ``and not`` bit mask.
+ * @doneq:		flag that indicates when a filter is ready.
+ * @next:		pointer to the next section filter.
+ * @feed:		&struct dvb_demux_feed pointer.
+ * @index:		index of the used demux filter.
+ * @state:		state of the filter as described by &enum dvb_dmx_state.
+ * @type:		type of the filter as described
+ *			by &enum dvb_dmx_filter_type.
+ */
+
+struct dvb_demux_filter {
+	struct dmx_section_filter filter;
+	u8 maskandmode[DMX_MAX_FILTER_SIZE];
+	u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
+	bool doneq;
+
+	struct dvb_demux_filter *next;
+	struct dvb_demux_feed *feed;
+	int index;
+	enum dvb_dmx_state state;
+	enum dvb_dmx_filter_type type;
+
+	/* private: used only by av7110 */
+	u16 hw_handle;
+};
+
+/**
+ * struct dvb_demux_feed - describes a DVB field
+ *
+ * @feed:	a union describing a digital TV feed.
+ *		Depending on the feed type, it can be either
+ *		@feed.ts or @feed.sec.
+ * @feed.ts:	a &struct dmx_ts_feed pointer.
+ *		For TS feed only.
+ * @feed.sec:	a &struct dmx_section_feed pointer.
+ *		For section feed only.
+ * @cb:		a union describing digital TV callbacks.
+ *		Depending on the feed type, it can be either
+ *		@cb.ts or @cb.sec.
+ * @cb.ts:	a dmx_ts_cb() calback function pointer.
+ *		For TS feed only.
+ * @cb.sec:	a dmx_section_cb() callback function pointer.
+ *		For section feed only.
+ * @demux:	pointer to &struct dvb_demux.
+ * @priv:	private data that can optionally be used by a DVB driver.
+ * @type:	type of the filter, as defined by &enum dvb_dmx_filter_type.
+ * @state:	state of the filter as defined by &enum dvb_dmx_state.
+ * @pid:	PID to be filtered.
+ * @timeout:	feed timeout.
+ * @filter:	pointer to &struct dvb_demux_filter.
+ * @buffer_flags: Buffer flags used to report discontinuity users via DVB
+ *		  memory mapped API, as defined by &enum dmx_buffer_flags.
+ * @ts_type:	type of TS, as defined by &enum ts_filter_type.
+ * @pes_type:	type of PES, as defined by &enum dmx_ts_pes.
+ * @cc:		MPEG-TS packet continuity counter
+ * @pusi_seen:	if true, indicates that a discontinuity was detected.
+ *		it is used to prevent feeding of garbage from previous section.
+ * @peslen:	length of the PES (Packet Elementary Stream).
+ * @list_head:	head for the list of digital TV demux feeds.
+ * @index:	a unique index for each feed. Can be used as hardware
+ *		pid filter index.
+ */
+struct dvb_demux_feed {
+	union {
+		struct dmx_ts_feed ts;
+		struct dmx_section_feed sec;
+	} feed;
+
+	union {
+		dmx_ts_cb ts;
+		dmx_section_cb sec;
+	} cb;
+
+	struct dvb_demux *demux;
+	void *priv;
+	enum dvb_dmx_filter_type type;
+	enum dvb_dmx_state state;
+	u16 pid;
+
+	ktime_t timeout;
+	struct dvb_demux_filter *filter;
+
+	u32 buffer_flags;
+
+	enum ts_filter_type ts_type;
+	enum dmx_ts_pes pes_type;
+
+	int cc;
+	bool pusi_seen;
+
+	u16 peslen;
+
+	struct list_head list_head;
+	unsigned int index;
+};
+
+/**
+ * struct dvb_demux - represents a digital TV demux
+ * @dmx:		embedded &struct dmx_demux with demux capabilities
+ *			and callbacks.
+ * @priv:		private data that can optionally be used by
+ *			a DVB driver.
+ * @filternum:		maximum amount of DVB filters.
+ * @feednum:		maximum amount of DVB feeds.
+ * @start_feed:		callback routine to be called in order to start
+ *			a DVB feed.
+ * @stop_feed:		callback routine to be called in order to stop
+ *			a DVB feed.
+ * @write_to_decoder:	callback routine to be called if the feed is TS and
+ *			it is routed to an A/V decoder, when a new TS packet
+ *			is received.
+ *			Used only on av7110-av.c.
+ * @check_crc32:	callback routine to check CRC. If not initialized,
+ *			dvb_demux will use an internal one.
+ * @memcopy:		callback routine to memcopy received data.
+ *			If not initialized, dvb_demux will default to memcpy().
+ * @users:		counter for the number of demux opened file descriptors.
+ *			Currently, it is limited to 10 users.
+ * @filter:		pointer to &struct dvb_demux_filter.
+ * @feed:		pointer to &struct dvb_demux_feed.
+ * @frontend_list:	&struct list_head with frontends used by the demux.
+ * @pesfilter:		array of &struct dvb_demux_feed with the PES types
+ *			that will be filtered.
+ * @pids:		list of filtered program IDs.
+ * @feed_list:		&struct list_head with feeds.
+ * @tsbuf:		temporary buffer used internally to store TS packets.
+ * @tsbufp:		temporary buffer index used internally.
+ * @mutex:		pointer to &struct mutex used to protect feed set
+ *			logic.
+ * @lock:		pointer to &spinlock_t, used to protect buffer handling.
+ * @cnt_storage:	buffer used for TS/TEI continuity check.
+ * @speed_last_time:	&ktime_t used for TS speed check.
+ * @speed_pkts_cnt:	packets count used for TS speed check.
+ */
+struct dvb_demux {
+	struct dmx_demux dmx;
+	void *priv;
+	int filternum;
+	int feednum;
+	int (*start_feed)(struct dvb_demux_feed *feed);
+	int (*stop_feed)(struct dvb_demux_feed *feed);
+	int (*write_to_decoder)(struct dvb_demux_feed *feed,
+				 const u8 *buf, size_t len);
+	u32 (*check_crc32)(struct dvb_demux_feed *feed,
+			    const u8 *buf, size_t len);
+	void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
+			 const u8 *src, size_t len);
+
+	int users;
+#define MAX_DVB_DEMUX_USERS 10
+	struct dvb_demux_filter *filter;
+	struct dvb_demux_feed *feed;
+
+	struct list_head frontend_list;
+
+	struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
+	u16 pids[DMX_PES_OTHER];
+
+#define DMX_MAX_PID 0x2000
+	struct list_head feed_list;
+	u8 tsbuf[204];
+	int tsbufp;
+
+	struct mutex mutex;
+	spinlock_t lock;
+
+	uint8_t *cnt_storage; /* for TS continuity check */
+
+	ktime_t speed_last_time; /* for TS speed check */
+	uint32_t speed_pkts_cnt; /* for TS speed check */
+
+	/* private: used only on av7110 */
+	int playing;
+	int recording;
+};
+
+/**
+ * dvb_dmx_init - initialize a digital TV demux struct.
+ *
+ * @demux: &struct dvb_demux to be initialized.
+ *
+ * Before being able to register a digital TV demux struct, drivers
+ * should call this routine. On its typical usage, some fields should
+ * be initialized at the driver before calling it.
+ *
+ * A typical usecase is::
+ *
+ *	dvb->demux.dmx.capabilities =
+ *		DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+ *		DMX_MEMORY_BASED_FILTERING;
+ *	dvb->demux.priv       = dvb;
+ *	dvb->demux.filternum  = 256;
+ *	dvb->demux.feednum    = 256;
+ *	dvb->demux.start_feed = driver_start_feed;
+ *	dvb->demux.stop_feed  = driver_stop_feed;
+ *	ret = dvb_dmx_init(&dvb->demux);
+ *	if (ret < 0)
+ *		return ret;
+ */
+int dvb_dmx_init(struct dvb_demux *demux);
+
+/**
+ * dvb_dmx_release - releases a digital TV demux internal buffers.
+ *
+ * @demux: &struct dvb_demux to be released.
+ *
+ * The DVB core internally allocates data at @demux. This routine
+ * releases those data. Please notice that the struct itelf is not
+ * released, as it can be embedded on other structs.
+ */
+void dvb_dmx_release(struct dvb_demux *demux);
+
+/**
+ * dvb_dmx_swfilter_packets - use dvb software filter for a buffer with
+ *	multiple MPEG-TS packets with 188 bytes each.
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data to be filtered
+ * @count: number of MPEG-TS packets with size of 188.
+ *
+ * The routine will discard a DVB packet that don't start with 0x47.
+ *
+ * Use this routine if the DVB demux fills MPEG-TS buffers that are
+ * already aligned.
+ *
+ * NOTE: The @buf size should have size equal to ``count * 188``.
+ */
+void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
+			      size_t count);
+
+/**
+ * dvb_dmx_swfilter -  use dvb software filter for a buffer with
+ *	multiple MPEG-TS packets with 188 bytes each.
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data to be filtered
+ * @count: number of MPEG-TS packets with size of 188.
+ *
+ * If a DVB packet doesn't start with 0x47, it will seek for the first
+ * byte that starts with 0x47.
+ *
+ * Use this routine if the DVB demux fill buffers that may not start with
+ * a packet start mark (0x47).
+ *
+ * NOTE: The @buf size should have size equal to ``count * 188``.
+ */
+void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
+
+/**
+ * dvb_dmx_swfilter_204 -  use dvb software filter for a buffer with
+ *	multiple MPEG-TS packets with 204 bytes each.
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data to be filtered
+ * @count: number of MPEG-TS packets with size of 204.
+ *
+ * If a DVB packet doesn't start with 0x47, it will seek for the first
+ * byte that starts with 0x47.
+ *
+ * Use this routine if the DVB demux fill buffers that may not start with
+ * a packet start mark (0x47).
+ *
+ * NOTE: The @buf size should have size equal to ``count * 204``.
+ */
+void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
+			  size_t count);
+
+/**
+ * dvb_dmx_swfilter_raw -  make the raw data available to userspace without
+ *	filtering
+ *
+ * @demux: pointer to &struct dvb_demux
+ * @buf: buffer with data
+ * @count: number of packets to be passed. The actual size of each packet
+ *	depends on the &dvb_demux->feed->cb.ts logic.
+ *
+ * Use it if the driver needs to deliver the raw payload to userspace without
+ * passing through the kernel demux. That is meant to support some
+ * delivery systems that aren't based on MPEG-TS.
+ *
+ * This function relies on &dvb_demux->feed->cb.ts to actually handle the
+ * buffer.
+ */
+void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
+			  size_t count);
+
+#endif /* _DVB_DEMUX_H_ */
diff --git a/include/media/dvb_frontend.h b/include/media/dvb_frontend.h
new file mode 100644
index 0000000..6f7a85a
--- /dev/null
+++ b/include/media/dvb_frontend.h
@@ -0,0 +1,824 @@
+/*
+ * dvb_frontend.h
+ *
+ * The Digital TV Frontend kABI defines a driver-internal interface for
+ * registering low-level, hardware specific driver to a hardware independent
+ * frontend layer.
+ *
+ * Copyright (C) 2001 convergence integrated media GmbH
+ * Copyright (C) 2004 convergence GmbH
+ *
+ * Written by Ralph Metzler
+ * Overhauled by Holger Waechtler
+ * Kernel I2C stuff by Michael Hunold <hunold@convergence.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _DVB_FRONTEND_H_
+#define _DVB_FRONTEND_H_
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/ioctl.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include <linux/dvb/frontend.h>
+
+#include <media/dvbdev.h>
+
+/*
+ * Maximum number of Delivery systems per frontend. It
+ * should be smaller or equal to 32
+ */
+#define MAX_DELSYS	8
+
+/* Helper definitions to be used at frontend drivers */
+#define kHz 1000UL
+#define MHz 1000000UL
+
+/**
+ * struct dvb_frontend_tune_settings - parameters to adjust frontend tuning
+ *
+ * @min_delay_ms:	minimum delay for tuning, in ms
+ * @step_size:		step size between two consecutive frequencies
+ * @max_drift:		maximum drift
+ *
+ * NOTE: step_size is in Hz, for terrestrial/cable or kHz for satellite
+ */
+struct dvb_frontend_tune_settings {
+	int min_delay_ms;
+	int step_size;
+	int max_drift;
+};
+
+struct dvb_frontend;
+
+/**
+ * struct dvb_tuner_info - Frontend name and min/max ranges/bandwidths
+ *
+ * @name:		name of the Frontend
+ * @frequency_min_hz:	minimal frequency supported in Hz
+ * @frequency_max_hz:	maximum frequency supported in Hz
+ * @frequency_step_hz:	frequency step in Hz
+ * @bandwidth_min:	minimal frontend bandwidth supported
+ * @bandwidth_max:	maximum frontend bandwidth supported
+ * @bandwidth_step:	frontend bandwidth step
+ */
+struct dvb_tuner_info {
+	char name[128];
+
+	u32 frequency_min_hz;
+	u32 frequency_max_hz;
+	u32 frequency_step_hz;
+
+	u32 bandwidth_min;
+	u32 bandwidth_max;
+	u32 bandwidth_step;
+};
+
+/**
+ * struct analog_parameters - Parameters to tune into an analog/radio channel
+ *
+ * @frequency:	Frequency used by analog TV tuner (either in 62.5 kHz step,
+ *		for TV, or 62.5 Hz for radio)
+ * @mode:	Tuner mode, as defined on enum v4l2_tuner_type
+ * @audmode:	Audio mode as defined for the rxsubchans field at videodev2.h,
+ *		e. g. V4L2_TUNER_MODE_*
+ * @std:	TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_*
+ *
+ * Hybrid tuners should be supported by both V4L2 and DVB APIs. This
+ * struct contains the data that are used by the V4L2 side. To avoid
+ * dependencies from V4L2 headers, all enums here are declared as integers.
+ */
+struct analog_parameters {
+	unsigned int frequency;
+	unsigned int mode;
+	unsigned int audmode;
+	u64 std;
+};
+
+/**
+ * enum dvbfe_algo - defines the algorithm used to tune into a channel
+ *
+ * @DVBFE_ALGO_HW: Hardware Algorithm -
+ *	Devices that support this algorithm do everything in hardware
+ *	and no software support is needed to handle them.
+ *	Requesting these devices to LOCK is the only thing required,
+ *	device is supposed to do everything in the hardware.
+ *
+ * @DVBFE_ALGO_SW: Software Algorithm -
+ * These are dumb devices, that require software to do everything
+ *
+ * @DVBFE_ALGO_CUSTOM: Customizable Agorithm -
+ *	Devices having this algorithm can be customized to have specific
+ *	algorithms in the frontend driver, rather than simply doing a
+ *	software zig-zag. In this case the zigzag maybe hardware assisted
+ *	or it maybe completely done in hardware. In all cases, usage of
+ *	this algorithm, in conjunction with the search and track
+ *	callbacks, utilizes the driver specific algorithm.
+ *
+ * @DVBFE_ALGO_RECOVERY: Recovery Algorithm -
+ *	These devices have AUTO recovery capabilities from LOCK failure
+ */
+enum dvbfe_algo {
+	DVBFE_ALGO_HW			= (1 <<  0),
+	DVBFE_ALGO_SW			= (1 <<  1),
+	DVBFE_ALGO_CUSTOM		= (1 <<  2),
+	DVBFE_ALGO_RECOVERY		= (1 << 31)
+};
+
+/**
+ * enum dvbfe_search - search callback possible return status
+ *
+ * @DVBFE_ALGO_SEARCH_SUCCESS:
+ *	The frontend search algorithm completed and returned successfully
+ *
+ * @DVBFE_ALGO_SEARCH_ASLEEP:
+ *	The frontend search algorithm is sleeping
+ *
+ * @DVBFE_ALGO_SEARCH_FAILED:
+ *	The frontend search for a signal failed
+ *
+ * @DVBFE_ALGO_SEARCH_INVALID:
+ *	The frontend search algorith was probably supplied with invalid
+ *	parameters and the search is an invalid one
+ *
+ * @DVBFE_ALGO_SEARCH_ERROR:
+ *	The frontend search algorithm failed due to some error
+ *
+ * @DVBFE_ALGO_SEARCH_AGAIN:
+ *	The frontend search algorithm was requested to search again
+ */
+enum dvbfe_search {
+	DVBFE_ALGO_SEARCH_SUCCESS	= (1 <<  0),
+	DVBFE_ALGO_SEARCH_ASLEEP	= (1 <<  1),
+	DVBFE_ALGO_SEARCH_FAILED	= (1 <<  2),
+	DVBFE_ALGO_SEARCH_INVALID	= (1 <<  3),
+	DVBFE_ALGO_SEARCH_AGAIN		= (1 <<  4),
+	DVBFE_ALGO_SEARCH_ERROR		= (1 << 31),
+};
+
+/**
+ * struct dvb_tuner_ops - Tuner information and callbacks
+ *
+ * @info:		embedded &struct dvb_tuner_info with tuner properties
+ * @release:		callback function called when frontend is detached.
+ *			drivers should free any allocated memory.
+ * @init:		callback function used to initialize the tuner device.
+ * @sleep:		callback function used to put the tuner to sleep.
+ * @suspend:		callback function used to inform that the Kernel will
+ *			suspend.
+ * @resume:		callback function used to inform that the Kernel is
+ *			resuming from suspend.
+ * @set_params:		callback function used to inform the tuner to tune
+ *			into a digital TV channel. The properties to be used
+ *			are stored at &struct dvb_frontend.dtv_property_cache.
+ *			The tuner demod can change the parameters to reflect
+ *			the changes needed for the channel to be tuned, and
+ *			update statistics. This is the recommended way to set
+ *			the tuner parameters and should be used on newer
+ *			drivers.
+ * @set_analog_params:	callback function used to tune into an analog TV
+ *			channel on hybrid tuners. It passes @analog_parameters
+ *			to the driver.
+ * @set_config:		callback function used to send some tuner-specific
+ *			parameters.
+ * @get_frequency:	get the actual tuned frequency
+ * @get_bandwidth:	get the bandwitdh used by the low pass filters
+ * @get_if_frequency:	get the Intermediate Frequency, in Hz. For baseband,
+ *			should return 0.
+ * @get_status:		returns the frontend lock status
+ * @get_rf_strength:	returns the RF signal strength. Used mostly to support
+ *			analog TV and radio. Digital TV should report, instead,
+ *			via DVBv5 API (&struct dvb_frontend.dtv_property_cache).
+ * @get_afc:		Used only by analog TV core. Reports the frequency
+ *			drift due to AFC.
+ * @calc_regs:		callback function used to pass register data settings
+ *			for simple tuners.  Shouldn't be used on newer drivers.
+ * @set_frequency:	Set a new frequency. Shouldn't be used on newer drivers.
+ * @set_bandwidth:	Set a new frequency. Shouldn't be used on newer drivers.
+ *
+ * NOTE: frequencies used on @get_frequency and @set_frequency are in Hz for
+ * terrestrial/cable or kHz for satellite.
+ *
+ */
+struct dvb_tuner_ops {
+
+	struct dvb_tuner_info info;
+
+	void (*release)(struct dvb_frontend *fe);
+	int (*init)(struct dvb_frontend *fe);
+	int (*sleep)(struct dvb_frontend *fe);
+	int (*suspend)(struct dvb_frontend *fe);
+	int (*resume)(struct dvb_frontend *fe);
+
+	/* This is the recomended way to set the tuner */
+	int (*set_params)(struct dvb_frontend *fe);
+	int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
+
+	int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
+
+	int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
+	int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+	int (*get_if_frequency)(struct dvb_frontend *fe, u32 *frequency);
+
+#define TUNER_STATUS_LOCKED 1
+#define TUNER_STATUS_STEREO 2
+	int (*get_status)(struct dvb_frontend *fe, u32 *status);
+	int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
+	int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
+
+	/*
+	 * This is support for demods like the mt352 - fills out the supplied
+	 * buffer with what to write.
+	 *
+	 * Don't use on newer drivers.
+	 */
+	int (*calc_regs)(struct dvb_frontend *fe, u8 *buf, int buf_len);
+
+	/*
+	 * These are provided separately from set_params in order to
+	 * facilitate silicon tuners which require sophisticated tuning loops,
+	 * controlling each parameter separately.
+	 *
+	 * Don't use on newer drivers.
+	 */
+	int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
+	int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+};
+
+/**
+ * struct analog_demod_info - Information struct for analog TV part of the demod
+ *
+ * @name:	Name of the analog TV demodulator
+ */
+struct analog_demod_info {
+	char *name;
+};
+
+/**
+ * struct analog_demod_ops  - Demodulation information and callbacks for
+ *			      analog TV and radio
+ *
+ * @info:		pointer to struct analog_demod_info
+ * @set_params:		callback function used to inform the demod to set the
+ *			demodulator parameters needed to decode an analog or
+ *			radio channel. The properties are passed via
+ *			&struct analog_params.
+ * @has_signal:		returns 0xffff if has signal, or 0 if it doesn't.
+ * @get_afc:		Used only by analog TV core. Reports the frequency
+ *			drift due to AFC.
+ * @tuner_status:	callback function that returns tuner status bits, e. g.
+ *			%TUNER_STATUS_LOCKED and %TUNER_STATUS_STEREO.
+ * @standby:		set the tuner to standby mode.
+ * @release:		callback function called when frontend is detached.
+ *			drivers should free any allocated memory.
+ * @i2c_gate_ctrl:	controls the I2C gate. Newer drivers should use I2C
+ *			mux support instead.
+ * @set_config:		callback function used to send some tuner-specific
+ *			parameters.
+ */
+struct analog_demod_ops {
+
+	struct analog_demod_info info;
+
+	void (*set_params)(struct dvb_frontend *fe,
+			   struct analog_parameters *params);
+	int  (*has_signal)(struct dvb_frontend *fe, u16 *signal);
+	int  (*get_afc)(struct dvb_frontend *fe, s32 *afc);
+	void (*tuner_status)(struct dvb_frontend *fe);
+	void (*standby)(struct dvb_frontend *fe);
+	void (*release)(struct dvb_frontend *fe);
+	int  (*i2c_gate_ctrl)(struct dvb_frontend *fe, int enable);
+
+	/** This is to allow setting tuner-specific configuration */
+	int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
+};
+
+struct dtv_frontend_properties;
+
+/**
+ * struct dvb_frontend_internal_info - Frontend properties and capabilities
+ *
+ * @name:			Name of the frontend
+ * @frequency_min_hz:		Minimal frequency supported by the frontend.
+ * @frequency_max_hz:		Minimal frequency supported by the frontend.
+ * @frequency_stepsize_hz:	All frequencies are multiple of this value.
+ * @frequency_tolerance_hz:	Frequency tolerance.
+ * @symbol_rate_min:		Minimal symbol rate, in bauds
+ *				(for Cable/Satellite systems).
+ * @symbol_rate_max:		Maximal symbol rate, in bauds
+ *				(for Cable/Satellite systems).
+ * @symbol_rate_tolerance:	Maximal symbol rate tolerance, in ppm
+ *				(for Cable/Satellite systems).
+ * @caps:			Capabilities supported by the frontend,
+ *				as specified in &enum fe_caps.
+ */
+struct dvb_frontend_internal_info {
+	char	name[128];
+	u32	frequency_min_hz;
+	u32	frequency_max_hz;
+	u32	frequency_stepsize_hz;
+	u32	frequency_tolerance_hz;
+	u32	symbol_rate_min;
+	u32	symbol_rate_max;
+	u32	symbol_rate_tolerance;
+	enum fe_caps caps;
+};
+
+/**
+ * struct dvb_frontend_ops - Demodulation information and callbacks for
+ *			      ditialt TV
+ *
+ * @info:		embedded &struct dvb_tuner_info with tuner properties
+ * @delsys:		Delivery systems supported by the frontend
+ * @detach:		callback function called when frontend is detached.
+ *			drivers should clean up, but not yet free the &struct
+ *			dvb_frontend allocation.
+ * @release:		callback function called when frontend is ready to be
+ *			freed.
+ *			drivers should free any allocated memory.
+ * @release_sec:	callback function requesting that the Satelite Equipment
+ *			Control (SEC) driver to release and free any memory
+ *			allocated by the driver.
+ * @init:		callback function used to initialize the tuner device.
+ * @sleep:		callback function used to put the tuner to sleep.
+ * @write:		callback function used by some demod legacy drivers to
+ *			allow other drivers to write data into their registers.
+ *			Should not be used on new drivers.
+ * @tune:		callback function used by demod drivers that use
+ *			@DVBFE_ALGO_HW to tune into a frequency.
+ * @get_frontend_algo:	returns the desired hardware algorithm.
+ * @set_frontend:	callback function used to inform the demod to set the
+ *			parameters for demodulating a digital TV channel.
+ *			The properties to be used are stored at &struct
+ *			dvb_frontend.dtv_property_cache. The demod can change
+ *			the parameters to reflect the changes needed for the
+ *			channel to be decoded, and update statistics.
+ * @get_tune_settings:	callback function
+ * @get_frontend:	callback function used to inform the parameters
+ *			actuall in use. The properties to be used are stored at
+ *			&struct dvb_frontend.dtv_property_cache and update
+ *			statistics. Please notice that it should not return
+ *			an error code if the statistics are not available
+ *			because the demog is not locked.
+ * @read_status:	returns the locking status of the frontend.
+ * @read_ber:		legacy callback function to return the bit error rate.
+ *			Newer drivers should provide such info via DVBv5 API,
+ *			e. g. @set_frontend;/@get_frontend, implementing this
+ *			callback only if DVBv3 API compatibility is wanted.
+ * @read_signal_strength: legacy callback function to return the signal
+ *			strength. Newer drivers should provide such info via
+ *			DVBv5 API, e. g. @set_frontend/@get_frontend,
+ *			implementing this callback only if DVBv3 API
+ *			compatibility is wanted.
+ * @read_snr:		legacy callback function to return the Signal/Noise
+ *			rate. Newer drivers should provide such info via
+ *			DVBv5 API, e. g. @set_frontend/@get_frontend,
+ *			implementing this callback only if DVBv3 API
+ *			compatibility is wanted.
+ * @read_ucblocks:	legacy callback function to return the Uncorrected Error
+ *			Blocks. Newer drivers should provide such info via
+ *			DVBv5 API, e. g. @set_frontend/@get_frontend,
+ *			implementing this callback only if DVBv3 API
+ *			compatibility is wanted.
+ * @diseqc_reset_overload: callback function to implement the
+ *			FE_DISEQC_RESET_OVERLOAD() ioctl (only Satellite)
+ * @diseqc_send_master_cmd: callback function to implement the
+ *			FE_DISEQC_SEND_MASTER_CMD() ioctl (only Satellite).
+ * @diseqc_recv_slave_reply: callback function to implement the
+ *			FE_DISEQC_RECV_SLAVE_REPLY() ioctl (only Satellite)
+ * @diseqc_send_burst:	callback function to implement the
+ *			FE_DISEQC_SEND_BURST() ioctl (only Satellite).
+ * @set_tone:		callback function to implement the
+ *			FE_SET_TONE() ioctl (only Satellite).
+ * @set_voltage:	callback function to implement the
+ *			FE_SET_VOLTAGE() ioctl (only Satellite).
+ * @enable_high_lnb_voltage: callback function to implement the
+ *			FE_ENABLE_HIGH_LNB_VOLTAGE() ioctl (only Satellite).
+ * @dishnetwork_send_legacy_command: callback function to implement the
+ *			FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl (only Satellite).
+ *			Drivers should not use this, except when the DVB
+ *			core emulation fails to provide proper support (e.g.
+ *			if @set_voltage takes more than 8ms to work), and
+ *			when backward compatibility with this legacy API is
+ *			required.
+ * @i2c_gate_ctrl:	controls the I2C gate. Newer drivers should use I2C
+ *			mux support instead.
+ * @ts_bus_ctrl:	callback function used to take control of the TS bus.
+ * @set_lna:		callback function to power on/off/auto the LNA.
+ * @search:		callback function used on some custom algo search algos.
+ * @tuner_ops:		pointer to &struct dvb_tuner_ops
+ * @analog_ops:		pointer to &struct analog_demod_ops
+ */
+struct dvb_frontend_ops {
+	struct dvb_frontend_internal_info info;
+
+	u8 delsys[MAX_DELSYS];
+
+	void (*detach)(struct dvb_frontend *fe);
+	void (*release)(struct dvb_frontend* fe);
+	void (*release_sec)(struct dvb_frontend* fe);
+
+	int (*init)(struct dvb_frontend* fe);
+	int (*sleep)(struct dvb_frontend* fe);
+
+	int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
+
+	/* if this is set, it overrides the default swzigzag */
+	int (*tune)(struct dvb_frontend* fe,
+		    bool re_tune,
+		    unsigned int mode_flags,
+		    unsigned int *delay,
+		    enum fe_status *status);
+
+	/* get frontend tuning algorithm from the module */
+	enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
+
+	/* these two are only used for the swzigzag code */
+	int (*set_frontend)(struct dvb_frontend *fe);
+	int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
+
+	int (*get_frontend)(struct dvb_frontend *fe,
+			    struct dtv_frontend_properties *props);
+
+	int (*read_status)(struct dvb_frontend *fe, enum fe_status *status);
+	int (*read_ber)(struct dvb_frontend* fe, u32* ber);
+	int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
+	int (*read_snr)(struct dvb_frontend* fe, u16* snr);
+	int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks);
+
+	int (*diseqc_reset_overload)(struct dvb_frontend* fe);
+	int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
+	int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply);
+	int (*diseqc_send_burst)(struct dvb_frontend *fe,
+				 enum fe_sec_mini_cmd minicmd);
+	int (*set_tone)(struct dvb_frontend *fe, enum fe_sec_tone_mode tone);
+	int (*set_voltage)(struct dvb_frontend *fe,
+			   enum fe_sec_voltage voltage);
+	int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
+	int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
+	int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+	int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
+	int (*set_lna)(struct dvb_frontend *);
+
+	/*
+	 * These callbacks are for devices that implement their own
+	 * tuning algorithms, rather than a simple swzigzag
+	 */
+	enum dvbfe_search (*search)(struct dvb_frontend *fe);
+
+	struct dvb_tuner_ops tuner_ops;
+	struct analog_demod_ops analog_ops;
+};
+
+#ifdef __DVB_CORE__
+#define MAX_EVENT 8
+
+/* Used only internally at dvb_frontend.c */
+struct dvb_fe_events {
+	struct dvb_frontend_event events[MAX_EVENT];
+	int			  eventw;
+	int			  eventr;
+	int			  overflow;
+	wait_queue_head_t	  wait_queue;
+	struct mutex		  mtx;
+};
+#endif
+
+/**
+ * struct dtv_frontend_properties - contains a list of properties that are
+ *				    specific to a digital TV standard.
+ *
+ * @frequency:		frequency in Hz for terrestrial/cable or in kHz for
+ *			Satellite
+ * @modulation:		Frontend modulation type
+ * @voltage:		SEC voltage (only Satellite)
+ * @sectone:		SEC tone mode (only Satellite)
+ * @inversion:		Spectral inversion
+ * @fec_inner:		Forward error correction inner Code Rate
+ * @transmission_mode:	Transmission Mode
+ * @bandwidth_hz:	Bandwidth, in Hz. A zero value means that userspace
+ *			wants to autodetect.
+ * @guard_interval:	Guard Interval
+ * @hierarchy:		Hierarchy
+ * @symbol_rate:	Symbol Rate
+ * @code_rate_HP:	high priority stream code rate
+ * @code_rate_LP:	low priority stream code rate
+ * @pilot:		Enable/disable/autodetect pilot tones
+ * @rolloff:		Rolloff factor (alpha)
+ * @delivery_system:	FE delivery system (e. g. digital TV standard)
+ * @interleaving:	interleaving
+ * @isdbt_partial_reception: ISDB-T partial reception (only ISDB standard)
+ * @isdbt_sb_mode:	ISDB-T Sound Broadcast (SB) mode (only ISDB standard)
+ * @isdbt_sb_subchannel:	ISDB-T SB subchannel (only ISDB standard)
+ * @isdbt_sb_segment_idx:	ISDB-T SB segment index (only ISDB standard)
+ * @isdbt_sb_segment_count:	ISDB-T SB segment count (only ISDB standard)
+ * @isdbt_layer_enabled:	ISDB Layer enabled (only ISDB standard)
+ * @layer:		ISDB per-layer data (only ISDB standard)
+ * @layer.segment_count: Segment Count;
+ * @layer.fec:		per layer code rate;
+ * @layer.modulation:	per layer modulation;
+ * @layer.interleaving:	 per layer interleaving.
+ * @stream_id:		If different than zero, enable substream filtering, if
+ *			hardware supports (DVB-S2 and DVB-T2).
+ * @scrambling_sequence_index:	Carries the index of the DVB-S2 physical layer
+ *				scrambling sequence.
+ * @atscmh_fic_ver:	Version number of the FIC (Fast Information Channel)
+ *			signaling data (only ATSC-M/H)
+ * @atscmh_parade_id:	Parade identification number (only ATSC-M/H)
+ * @atscmh_nog:		Number of MH groups per MH subframe for a designated
+ *			parade (only ATSC-M/H)
+ * @atscmh_tnog:	Total number of MH groups including all MH groups
+ *			belonging to all MH parades in one MH subframe
+ *			(only ATSC-M/H)
+ * @atscmh_sgn:		Start group number (only ATSC-M/H)
+ * @atscmh_prc:		Parade repetition cycle (only ATSC-M/H)
+ * @atscmh_rs_frame_mode:	Reed Solomon (RS) frame mode (only ATSC-M/H)
+ * @atscmh_rs_frame_ensemble:	RS frame ensemble (only ATSC-M/H)
+ * @atscmh_rs_code_mode_pri:	RS code mode pri (only ATSC-M/H)
+ * @atscmh_rs_code_mode_sec:	RS code mode sec (only ATSC-M/H)
+ * @atscmh_sccc_block_mode:	Series Concatenated Convolutional Code (SCCC)
+ *				Block Mode (only ATSC-M/H)
+ * @atscmh_sccc_code_mode_a:	SCCC code mode A (only ATSC-M/H)
+ * @atscmh_sccc_code_mode_b:	SCCC code mode B (only ATSC-M/H)
+ * @atscmh_sccc_code_mode_c:	SCCC code mode C (only ATSC-M/H)
+ * @atscmh_sccc_code_mode_d:	SCCC code mode D (only ATSC-M/H)
+ * @lna:		Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA)
+ * @strength:		DVBv5 API statistics: Signal Strength
+ * @cnr:		DVBv5 API statistics: Signal to Noise ratio of the
+ *			(main) carrier
+ * @pre_bit_error:	DVBv5 API statistics: pre-Viterbi bit error count
+ * @pre_bit_count:	DVBv5 API statistics: pre-Viterbi bit count
+ * @post_bit_error:	DVBv5 API statistics: post-Viterbi bit error count
+ * @post_bit_count:	DVBv5 API statistics: post-Viterbi bit count
+ * @block_error:	DVBv5 API statistics: block error count
+ * @block_count:	DVBv5 API statistics: block count
+ *
+ * NOTE: derivated statistics like Uncorrected Error blocks (UCE) are
+ * calculated on userspace.
+ *
+ * Only a subset of the properties are needed for a given delivery system.
+ * For more info, consult the media_api.html with the documentation of the
+ * Userspace API.
+ */
+struct dtv_frontend_properties {
+	u32			frequency;
+	enum fe_modulation	modulation;
+
+	enum fe_sec_voltage	voltage;
+	enum fe_sec_tone_mode	sectone;
+	enum fe_spectral_inversion inversion;
+	enum fe_code_rate	fec_inner;
+	enum fe_transmit_mode	transmission_mode;
+	u32			bandwidth_hz;	/* 0 = AUTO */
+	enum fe_guard_interval	guard_interval;
+	enum fe_hierarchy	hierarchy;
+	u32			symbol_rate;
+	enum fe_code_rate	code_rate_HP;
+	enum fe_code_rate	code_rate_LP;
+
+	enum fe_pilot		pilot;
+	enum fe_rolloff		rolloff;
+
+	enum fe_delivery_system	delivery_system;
+
+	enum fe_interleaving	interleaving;
+
+	/* ISDB-T specifics */
+	u8			isdbt_partial_reception;
+	u8			isdbt_sb_mode;
+	u8			isdbt_sb_subchannel;
+	u32			isdbt_sb_segment_idx;
+	u32			isdbt_sb_segment_count;
+	u8			isdbt_layer_enabled;
+	struct {
+	    u8			segment_count;
+	    enum fe_code_rate	fec;
+	    enum fe_modulation	modulation;
+	    u8			interleaving;
+	} layer[3];
+
+	/* Multistream specifics */
+	u32			stream_id;
+
+	/* Physical Layer Scrambling specifics */
+	u32			scrambling_sequence_index;
+
+	/* ATSC-MH specifics */
+	u8			atscmh_fic_ver;
+	u8			atscmh_parade_id;
+	u8			atscmh_nog;
+	u8			atscmh_tnog;
+	u8			atscmh_sgn;
+	u8			atscmh_prc;
+
+	u8			atscmh_rs_frame_mode;
+	u8			atscmh_rs_frame_ensemble;
+	u8			atscmh_rs_code_mode_pri;
+	u8			atscmh_rs_code_mode_sec;
+	u8			atscmh_sccc_block_mode;
+	u8			atscmh_sccc_code_mode_a;
+	u8			atscmh_sccc_code_mode_b;
+	u8			atscmh_sccc_code_mode_c;
+	u8			atscmh_sccc_code_mode_d;
+
+	u32			lna;
+
+	/* statistics data */
+	struct dtv_fe_stats	strength;
+	struct dtv_fe_stats	cnr;
+	struct dtv_fe_stats	pre_bit_error;
+	struct dtv_fe_stats	pre_bit_count;
+	struct dtv_fe_stats	post_bit_error;
+	struct dtv_fe_stats	post_bit_count;
+	struct dtv_fe_stats	block_error;
+	struct dtv_fe_stats	block_count;
+};
+
+#define DVB_FE_NO_EXIT  0
+#define DVB_FE_NORMAL_EXIT      1
+#define DVB_FE_DEVICE_REMOVED   2
+#define DVB_FE_DEVICE_RESUME    3
+
+/**
+ * struct dvb_frontend - Frontend structure to be used on drivers.
+ *
+ * @refcount:		refcount to keep track of &struct dvb_frontend
+ *			references
+ * @ops:		embedded &struct dvb_frontend_ops
+ * @dvb:		pointer to &struct dvb_adapter
+ * @demodulator_priv:	demod private data
+ * @tuner_priv:		tuner private data
+ * @frontend_priv:	frontend private data
+ * @sec_priv:		SEC private data
+ * @analog_demod_priv:	Analog demod private data
+ * @dtv_property_cache:	embedded &struct dtv_frontend_properties
+ * @callback:		callback function used on some drivers to call
+ *			either the tuner or the demodulator.
+ * @id:			Frontend ID
+ * @exit:		Used to inform the DVB core that the frontend
+ *			thread should exit (usually, means that the hardware
+ *			got disconnected.
+ */
+
+struct dvb_frontend {
+	struct kref refcount;
+	struct dvb_frontend_ops ops;
+	struct dvb_adapter *dvb;
+	void *demodulator_priv;
+	void *tuner_priv;
+	void *frontend_priv;
+	void *sec_priv;
+	void *analog_demod_priv;
+	struct dtv_frontend_properties dtv_property_cache;
+#define DVB_FRONTEND_COMPONENT_TUNER 0
+#define DVB_FRONTEND_COMPONENT_DEMOD 1
+	int (*callback)(void *adapter_priv, int component, int cmd, int arg);
+	int id;
+	unsigned int exit;
+};
+
+/**
+ * dvb_register_frontend() - Registers a DVB frontend at the adapter
+ *
+ * @dvb: pointer to &struct dvb_adapter
+ * @fe: pointer to &struct dvb_frontend
+ *
+ * Allocate and initialize the private data needed by the frontend core to
+ * manage the frontend and calls dvb_register_device() to register a new
+ * frontend. It also cleans the property cache that stores the frontend
+ * parameters and selects the first available delivery system.
+ */
+int dvb_register_frontend(struct dvb_adapter *dvb,
+				 struct dvb_frontend *fe);
+
+/**
+ * dvb_unregister_frontend() - Unregisters a DVB frontend
+ *
+ * @fe: pointer to &struct dvb_frontend
+ *
+ * Stops the frontend kthread, calls dvb_unregister_device() and frees the
+ * private frontend data allocated by dvb_register_frontend().
+ *
+ * NOTE: This function doesn't frees the memory allocated by the demod,
+ * by the SEC driver and by the tuner. In order to free it, an explicit call to
+ * dvb_frontend_detach() is needed, after calling this function.
+ */
+int dvb_unregister_frontend(struct dvb_frontend *fe);
+
+/**
+ * dvb_frontend_detach() - Detaches and frees frontend specific data
+ *
+ * @fe: pointer to &struct dvb_frontend
+ *
+ * This function should be called after dvb_unregister_frontend(). It
+ * calls the SEC, tuner and demod release functions:
+ * &dvb_frontend_ops.release_sec, &dvb_frontend_ops.tuner_ops.release,
+ * &dvb_frontend_ops.analog_ops.release and &dvb_frontend_ops.release.
+ *
+ * If the driver is compiled with %CONFIG_MEDIA_ATTACH, it also decreases
+ * the module reference count, needed to allow userspace to remove the
+ * previously used DVB frontend modules.
+ */
+void dvb_frontend_detach(struct dvb_frontend *fe);
+
+/**
+ * dvb_frontend_suspend() - Suspends a Digital TV frontend
+ *
+ * @fe: pointer to &struct dvb_frontend
+ *
+ * This function prepares a Digital TV frontend to suspend.
+ *
+ * In order to prepare the tuner to suspend, if
+ * &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise,
+ * it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available.
+ *
+ * It will also call &dvb_frontend_ops.sleep\(\) to put the demod to suspend.
+ *
+ * The drivers should also call dvb_frontend_suspend\(\) as part of their
+ * handler for the &device_driver.suspend\(\).
+ */
+int dvb_frontend_suspend(struct dvb_frontend *fe);
+
+/**
+ * dvb_frontend_resume() - Resumes a Digital TV frontend
+ *
+ * @fe: pointer to &struct dvb_frontend
+ *
+ * This function resumes the usual operation of the tuner after resume.
+ *
+ * In order to resume the frontend, it calls the demod &dvb_frontend_ops.init\(\).
+ *
+ * If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it.
+ * Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.
+ *
+ * Once tuner and demods are resumed, it will enforce that the SEC voltage and
+ * tone are restored to their previous values and wake up the frontend's
+ * kthread in order to retune the frontend.
+ *
+ * The drivers should also call dvb_frontend_resume() as part of their
+ * handler for the &device_driver.resume\(\).
+ */
+int dvb_frontend_resume(struct dvb_frontend *fe);
+
+/**
+ * dvb_frontend_reinitialise() - forces a reinitialisation at the frontend
+ *
+ * @fe: pointer to &struct dvb_frontend
+ *
+ * Calls &dvb_frontend_ops.init\(\) and &dvb_frontend_ops.tuner_ops.init\(\),
+ * and resets SEC tone and voltage (for Satellite systems).
+ *
+ * NOTE: Currently, this function is used only by one driver (budget-av).
+ * It seems to be due to address some special issue with that specific
+ * frontend.
+ */
+void dvb_frontend_reinitialise(struct dvb_frontend *fe);
+
+/**
+ * dvb_frontend_sleep_until() - Sleep for the amount of time given by
+ *                      add_usec parameter
+ *
+ * @waketime: pointer to &struct ktime_t
+ * @add_usec: time to sleep, in microseconds
+ *
+ * This function is used to measure the time required for the
+ * FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl to work. It needs to be as precise
+ * as possible, as it affects the detection of the dish tone command at the
+ * satellite subsystem.
+ *
+ * Its used internally by the DVB frontend core, in order to emulate
+ * FE_DISHNETWORK_SEND_LEGACY_CMD() using the &dvb_frontend_ops.set_voltage\(\)
+ * callback.
+ *
+ * NOTE: it should not be used at the drivers, as the emulation for the
+ * legacy callback is provided by the Kernel. The only situation where this
+ * should be at the drivers is when there are some bugs at the hardware that
+ * would prevent the core emulation to work. On such cases, the driver would
+ * be writing a &dvb_frontend_ops.dishnetwork_send_legacy_command\(\) and
+ * calling this function directly.
+ */
+void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec);
+
+#endif
diff --git a/include/media/dvb_math.h b/include/media/dvb_math.h
new file mode 100644
index 0000000..8690ec4
--- /dev/null
+++ b/include/media/dvb_math.h
@@ -0,0 +1,66 @@
+/*
+ * dvb-math provides some complex fixed-point math
+ * operations shared between the dvb related stuff
+ *
+ * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#ifndef __DVB_MATH_H
+#define __DVB_MATH_H
+
+#include <linux/types.h>
+
+/**
+ * intlog2 - computes log2 of a value; the result is shifted left by 24 bits
+ *
+ * @value: The value (must be != 0)
+ *
+ * to use rational values you can use the following method:
+ *
+ *   intlog2(value) = intlog2(value * 2^x) - x * 2^24
+ *
+ * Some usecase examples:
+ *
+ *	intlog2(8) will give 3 << 24 = 3 * 2^24
+ *
+ *	intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
+ *
+ *	intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
+ *
+ *
+ * return: log2(value) * 2^24
+ */
+extern unsigned int intlog2(u32 value);
+
+/**
+ * intlog10 - computes log10 of a value; the result is shifted left by 24 bits
+ *
+ * @value: The value (must be != 0)
+ *
+ * to use rational values you can use the following method:
+ *
+ *   intlog10(value) = intlog10(value * 10^x) - x * 2^24
+ *
+ * An usecase example:
+ *
+ *	intlog10(1000) will give 3 << 24 = 3 * 2^24
+ *
+ *   due to the implementation intlog10(1000) might be not exactly 3 * 2^24
+ *
+ * look at intlog2 for similar examples
+ *
+ * return: log10(value) * 2^24
+ */
+extern unsigned int intlog10(u32 value);
+
+#endif
diff --git a/include/media/dvb_net.h b/include/media/dvb_net.h
new file mode 100644
index 0000000..5e31d37
--- /dev/null
+++ b/include/media/dvb_net.h
@@ -0,0 +1,93 @@
+/*
+ * dvb_net.h
+ *
+ * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DVB_NET_H_
+#define _DVB_NET_H_
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <media/dvbdev.h>
+
+#define DVB_NET_DEVICES_MAX 10
+
+#ifdef CONFIG_DVB_NET
+
+/**
+ * struct dvb_net - describes a DVB network interface
+ *
+ * @dvbdev:		pointer to &struct dvb_device.
+ * @device:		array of pointers to &struct net_device.
+ * @state:		array of integers to each net device. A value
+ *			different than zero means that the interface is
+ *			in usage.
+ * @exit:		flag to indicate when the device is being removed.
+ * @demux:		pointer to &struct dmx_demux.
+ * @ioctl_mutex:	protect access to this struct.
+ *
+ * Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
+ * devices.
+ */
+
+struct dvb_net {
+	struct dvb_device *dvbdev;
+	struct net_device *device[DVB_NET_DEVICES_MAX];
+	int state[DVB_NET_DEVICES_MAX];
+	unsigned int exit:1;
+	struct dmx_demux *demux;
+	struct mutex ioctl_mutex;
+};
+
+/**
+ * dvb_net_init - nitializes a digital TV network device and registers it.
+ *
+ * @adap:	pointer to &struct dvb_adapter.
+ * @dvbnet:	pointer to &struct dvb_net.
+ * @dmxdemux:	pointer to &struct dmx_demux.
+ */
+int dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet,
+		  struct dmx_demux *dmxdemux);
+
+/**
+ * dvb_net_release - releases a digital TV network device and unregisters it.
+ *
+ * @dvbnet:	pointer to &struct dvb_net.
+ */
+void dvb_net_release(struct dvb_net *dvbnet);
+
+#else
+
+struct dvb_net {
+	struct dvb_device *dvbdev;
+};
+
+static inline void dvb_net_release(struct dvb_net *dvbnet)
+{
+}
+
+static inline int dvb_net_init(struct dvb_adapter *adap,
+			       struct dvb_net *dvbnet, struct dmx_demux *dmx)
+{
+	return 0;
+}
+
+#endif /* ifdef CONFIG_DVB_NET */
+
+#endif
diff --git a/include/media/dvb_ringbuffer.h b/include/media/dvb_ringbuffer.h
new file mode 100644
index 0000000..8ed6bcc
--- /dev/null
+++ b/include/media/dvb_ringbuffer.h
@@ -0,0 +1,280 @@
+/*
+ *
+ * dvb_ringbuffer.h: ring buffer implementation for the dvb driver
+ *
+ * Copyright (C) 2003 Oliver Endriss
+ * Copyright (C) 2004 Andrew de Quincey
+ *
+ * based on code originally found in av7110.c & dvb_ci.c:
+ * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler
+ *                         for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#ifndef _DVB_RINGBUFFER_H_
+#define _DVB_RINGBUFFER_H_
+
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+/**
+ * struct dvb_ringbuffer - Describes a ring buffer used at DVB framework
+ *
+ * @data: Area were the ringbuffer data is written
+ * @size: size of the ringbuffer
+ * @pread: next position to read
+ * @pwrite: next position to write
+ * @error: used by ringbuffer clients to indicate that an error happened.
+ * @queue: Wait queue used by ringbuffer clients to indicate when buffer
+ *         was filled
+ * @lock: Spinlock used to protect the ringbuffer
+ */
+struct dvb_ringbuffer {
+	u8               *data;
+	ssize_t           size;
+	ssize_t           pread;
+	ssize_t           pwrite;
+	int               error;
+
+	wait_queue_head_t queue;
+	spinlock_t        lock;
+};
+
+#define DVB_RINGBUFFER_PKTHDRSIZE 3
+
+/**
+ * dvb_ringbuffer_init - initialize ring buffer, lock and queue
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @data: pointer to the buffer where the data will be stored
+ * @len: bytes from ring buffer into @buf
+ */
+extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data,
+				size_t len);
+
+/**
+ * dvb_ringbuffer_empty - test whether buffer is empty
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ */
+extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);
+
+/**
+ * dvb_ringbuffer_free - returns the number of free bytes in the buffer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ *
+ * Return: number of free bytes in the buffer
+ */
+extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
+
+/**
+ * dvb_ringbuffer_avail - returns the number of bytes waiting in the buffer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ *
+ * Return: number of bytes waiting in the buffer
+ */
+extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
+
+/**
+ * dvb_ringbuffer_reset - resets the ringbuffer to initial state
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ *
+ * Resets the read and write pointers to zero and flush the buffer.
+ *
+ * This counts as a read and write operation
+ */
+extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);
+
+/*
+ * read routines & macros
+ */
+
+/**
+ * dvb_ringbuffer_flush - flush buffer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ */
+extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
+
+/**
+ * dvb_ringbuffer_flush_spinlock_wakeup- flush buffer protected by spinlock
+ *      and wake-up waiting task(s)
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ */
+extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
+
+/**
+ * DVB_RINGBUFFER_PEEK - peek at byte @offs in the buffer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @offs: offset inside the ringbuffer
+ */
+#define DVB_RINGBUFFER_PEEK(rbuf, offs)	\
+			((rbuf)->data[((rbuf)->pread + (offs)) % (rbuf)->size])
+
+/**
+ * DVB_RINGBUFFER_SKIP - advance read ptr by @num bytes
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @num: number of bytes to advance
+ */
+#define DVB_RINGBUFFER_SKIP(rbuf, num)	{\
+			(rbuf)->pread = ((rbuf)->pread + (num)) % (rbuf)->size;\
+}
+
+/**
+ * dvb_ringbuffer_read_user - Reads a buffer into a user pointer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @buf: pointer to the buffer where the data will be stored
+ * @len: bytes from ring buffer into @buf
+ *
+ * This variant assumes that the buffer is a memory at the userspace. So,
+ * it will internally call copy_to_user().
+ *
+ * Return: number of bytes transferred or -EFAULT
+ */
+extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
+				   u8 __user *buf, size_t len);
+
+/**
+ * dvb_ringbuffer_read - Reads a buffer into a pointer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @buf: pointer to the buffer where the data will be stored
+ * @len: bytes from ring buffer into @buf
+ *
+ * This variant assumes that the buffer is a memory at the Kernel space
+ *
+ * Return: number of bytes transferred or -EFAULT
+ */
+extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
+				   u8 *buf, size_t len);
+
+/*
+ * write routines & macros
+ */
+
+/**
+ * DVB_RINGBUFFER_WRITE_BYTE - write single byte to ring buffer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @byte: byte to write
+ */
+#define DVB_RINGBUFFER_WRITE_BYTE(rbuf, byte)	\
+			{ (rbuf)->data[(rbuf)->pwrite] = (byte); \
+			(rbuf)->pwrite = ((rbuf)->pwrite + 1) % (rbuf)->size; }
+
+/**
+ * dvb_ringbuffer_write - Writes a buffer into the ringbuffer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @buf: pointer to the buffer where the data will be read
+ * @len: bytes from ring buffer into @buf
+ *
+ * This variant assumes that the buffer is a memory at the Kernel space
+ *
+ * return: number of bytes transferred or -EFAULT
+ */
+extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
+				    size_t len);
+
+/**
+ * dvb_ringbuffer_write_user - Writes a buffer received via a user pointer
+ *
+ * @rbuf: pointer to struct dvb_ringbuffer
+ * @buf: pointer to the buffer where the data will be read
+ * @len: bytes from ring buffer into @buf
+ *
+ * This variant assumes that the buffer is a memory at the userspace. So,
+ * it will internally call copy_from_user().
+ *
+ * Return: number of bytes transferred or -EFAULT
+ */
+extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+					 const u8 __user *buf, size_t len);
+
+/**
+ * dvb_ringbuffer_pkt_write - Write a packet into the ringbuffer.
+ *
+ * @rbuf: Ringbuffer to write to.
+ * @buf: Buffer to write.
+ * @len: Length of buffer (currently limited to 65535 bytes max).
+ *
+ * Return: Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
+ */
+extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf,
+					size_t len);
+
+/**
+ * dvb_ringbuffer_pkt_read_user - Read from a packet in the ringbuffer.
+ *
+ * @rbuf: Ringbuffer concerned.
+ * @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
+ * @offset: Offset into packet to read from.
+ * @buf: Destination buffer for data.
+ * @len: Size of destination buffer.
+ *
+ * Return: Number of bytes read, or -EFAULT.
+ *
+ * .. note::
+ *
+ *    unlike dvb_ringbuffer_read(), this does **NOT** update the read pointer
+ *    in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a
+ *    packet as no longer required.
+ */
+extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf,
+					    size_t idx,
+					    int offset, u8 __user *buf,
+					    size_t len);
+
+/**
+ * dvb_ringbuffer_pkt_read - Read from a packet in the ringbuffer.
+ * Note: unlike dvb_ringbuffer_read_user(), this DOES update the read pointer
+ * in the ringbuffer.
+ *
+ * @rbuf: Ringbuffer concerned.
+ * @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
+ * @offset: Offset into packet to read from.
+ * @buf: Destination buffer for data.
+ * @len: Size of destination buffer.
+ *
+ * Return: Number of bytes read, or -EFAULT.
+ */
+extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
+				       int offset, u8 *buf, size_t len);
+
+/**
+ * dvb_ringbuffer_pkt_dispose - Dispose of a packet in the ring buffer.
+ *
+ * @rbuf: Ring buffer concerned.
+ * @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
+ */
+extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
+
+/**
+ * dvb_ringbuffer_pkt_next - Get the index of the next packet in a ringbuffer.
+ *
+ * @rbuf: Ringbuffer concerned.
+ * @idx: Previous packet index, or -1 to return the first packet index.
+ * @pktlen: On success, will be updated to contain the length of the packet
+ *          in bytes.
+ * returns Packet index (if >=0), or -1 if no packets available.
+ */
+extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf,
+				       size_t idx, size_t *pktlen);
+
+#endif /* _DVB_RINGBUFFER_H_ */
diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h
new file mode 100644
index 0000000..8cb8845
--- /dev/null
+++ b/include/media/dvb_vb2.h
@@ -0,0 +1,280 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * dvb-vb2.h - DVB driver helper framework for streaming I/O
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ *
+ * Author: jh1009.sung@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _DVB_VB2_H
+#define _DVB_VB2_H
+
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/dvb/dmx.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+
+/**
+ * enum dvb_buf_type - types of Digital TV memory-mapped buffers
+ *
+ * @DVB_BUF_TYPE_CAPTURE: buffer is filled by the Kernel,
+ *			  with a received Digital TV stream
+ */
+enum dvb_buf_type {
+	DVB_BUF_TYPE_CAPTURE        = 1,
+};
+
+/**
+ * enum dvb_vb2_states - states to control VB2 state machine
+ * @DVB_VB2_STATE_NONE:
+ *	VB2 engine not initialized yet, init failed or VB2 was released.
+ * @DVB_VB2_STATE_INIT:
+ *	VB2 engine initialized.
+ * @DVB_VB2_STATE_REQBUFS:
+ *	Buffers were requested
+ * @DVB_VB2_STATE_STREAMON:
+ *	VB2 is streaming. Callers should not check it directly. Instead,
+ *	they should use dvb_vb2_is_streaming().
+ *
+ * Note:
+ *
+ * Callers should not touch at the state machine directly. This
+ * is handled inside dvb_vb2.c.
+ */
+enum dvb_vb2_states {
+	DVB_VB2_STATE_NONE	= 0x0,
+	DVB_VB2_STATE_INIT	= 0x1,
+	DVB_VB2_STATE_REQBUFS	= 0x2,
+	DVB_VB2_STATE_STREAMON	= 0x4,
+};
+
+#define DVB_VB2_NAME_MAX (20)
+
+/**
+ * struct dvb_buffer - video buffer information for v4l2.
+ *
+ * @vb:		embedded struct &vb2_buffer.
+ * @list:	list of &struct dvb_buffer.
+ */
+struct dvb_buffer {
+	struct vb2_buffer	vb;
+	struct list_head	list;
+};
+
+/**
+ * struct dvb_vb2_ctx - control struct for VB2 handler
+ * @vb_q:	pointer to &struct vb2_queue with videobuf2 queue.
+ * @mutex:	mutex to serialize vb2 operations. Used by
+ *		vb2 core %wait_prepare and %wait_finish operations.
+ * @slock:	spin lock used to protect buffer filling at dvb_vb2.c.
+ * @dvb_q:	List of buffers that are not filled yet.
+ * @buf:	Pointer to the buffer that are currently being filled.
+ * @offset:	index to the next position at the @buf to be filled.
+ * @remain:	How many bytes are left to be filled at @buf.
+ * @state:	bitmask of buffer states as defined by &enum dvb_vb2_states.
+ * @buf_siz:	size of each VB2 buffer.
+ * @buf_cnt:	number of VB2 buffers.
+ * @nonblocking:
+ *		If different than zero, device is operating on non-blocking
+ *		mode.
+ * @flags:	buffer flags as defined by &enum dmx_buffer_flags.
+ *		Filled only at &DMX_DQBUF. &DMX_QBUF should zero this field.
+ * @count:	monotonic counter for filled buffers. Helps to identify
+ *		data stream loses. Filled only at &DMX_DQBUF. &DMX_QBUF should
+ *		zero this field.
+ *
+ * @name:	name of the device type. Currently, it can either be
+ *		"dvr" or "demux_filter".
+ */
+struct dvb_vb2_ctx {
+	struct vb2_queue	vb_q;
+	struct mutex		mutex;
+	spinlock_t		slock;
+	struct list_head	dvb_q;
+	struct dvb_buffer	*buf;
+	int	offset;
+	int	remain;
+	int	state;
+	int	buf_siz;
+	int	buf_cnt;
+	int	nonblocking;
+
+	enum dmx_buffer_flags flags;
+	u32	count;
+
+	char	name[DVB_VB2_NAME_MAX + 1];
+};
+
+#ifndef CONFIG_DVB_MMAP
+static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
+			       const char *name, int non_blocking)
+{
+	return 0;
+};
+static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
+{
+	return 0;
+};
+#define dvb_vb2_is_streaming(ctx) (0)
+#define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0)
+
+static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
+				    struct file *file,
+				    poll_table *wait)
+{
+	return 0;
+}
+#else
+/**
+ * dvb_vb2_init - initializes VB2 handler
+ *
+ * @ctx:	control struct for VB2 handler
+ * @name:	name for the VB2 handler
+ * @non_blocking:
+ *		if not zero, it means that the device is at non-blocking mode
+ */
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking);
+
+/**
+ * dvb_vb2_release - Releases the VB2 handler allocated resources and
+ *	put @ctx at DVB_VB2_STATE_NONE state.
+ * @ctx:	control struct for VB2 handler
+ */
+int dvb_vb2_release(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_is_streaming - checks if the VB2 handler is streaming
+ * @ctx:	control struct for VB2 handler
+ *
+ * Return: 0 if not streaming, 1 otherwise.
+ */
+int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_fill_buffer - fills a VB2 buffer
+ * @ctx:	control struct for VB2 handler
+ * @src:	place where the data is stored
+ * @len:	number of bytes to be copied from @src
+ * @buffer_flags:
+ *		pointer to buffer flags as defined by &enum dmx_buffer_flags.
+ *		can be NULL.
+ */
+int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
+			const unsigned char *src, int len,
+			enum dmx_buffer_flags *buffer_flags);
+
+/**
+ * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV
+ *      buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @file:	&struct file argument passed to the poll
+ *		file operation handler.
+ * @wait:	&poll_table wait argument passed to the poll
+ *		file operation handler.
+ *
+ * Implements poll syscall() logic.
+ */
+__poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
+		      poll_table *wait);
+#endif
+
+/**
+ * dvb_vb2_stream_on() - Wrapper to vb2_core_streamon() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ *
+ * Starts dvb streaming
+ */
+int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx);
+/**
+ * dvb_vb2_stream_off() - Wrapper to vb2_core_streamoff() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ *
+ * Stops dvb streaming
+ */
+int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_reqbufs() - Wrapper to vb2_core_reqbufs() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @req:	&struct dmx_requestbuffers passed from userspace in
+ *		order to handle &DMX_REQBUFS.
+ *
+ * Initiate streaming by requesting a number of buffers. Also used to
+ * free previously requested buffers, is ``req->count`` is zero.
+ */
+int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req);
+
+/**
+ * dvb_vb2_querybuf() - Wrapper to vb2_core_querybuf() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @b:		&struct dmx_buffer passed from userspace in
+ *		order to handle &DMX_QUERYBUF.
+ *
+ *
+ */
+int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_expbuf() - Wrapper to vb2_core_expbuf() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @exp:	&struct dmx_exportbuffer passed from userspace in
+ *		order to handle &DMX_EXPBUF.
+ *
+ * Export a buffer as a file descriptor.
+ */
+int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp);
+
+/**
+ * dvb_vb2_qbuf() - Wrapper to vb2_core_qbuf() for Digital TV buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @b:		&struct dmx_buffer passed from userspace in
+ *		order to handle &DMX_QBUF.
+ *
+ * Queue a Digital TV buffer as requested by userspace
+ */
+int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_dqbuf() - Wrapper to vb2_core_dqbuf() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @b:		&struct dmx_buffer passed from userspace in
+ *		order to handle &DMX_DQBUF.
+ *
+ * Dequeue a Digital TV buffer to the userspace
+ */
+int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_mmap() - Wrapper to vb2_mmap() for Digital TV buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @vma:        pointer to &struct vm_area_struct with the vma passed
+ *              to the mmap file operation handler in the driver.
+ *
+ * map Digital TV video buffers into application address space.
+ */
+int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma);
+
+#endif /* _DVB_VB2_H */
diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h
new file mode 100644
index 0000000..881ca46
--- /dev/null
+++ b/include/media/dvbdev.h
@@ -0,0 +1,470 @@
+/*
+ * dvbdev.h
+ *
+ * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
+ *                    for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DVBDEV_H_
+#define _DVBDEV_H_
+
+#include <linux/types.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <media/media-device.h>
+
+#define DVB_MAJOR 212
+
+#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
+  #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
+#else
+  #define DVB_MAX_ADAPTERS 16
+#endif
+
+#define DVB_UNSET (-1)
+
+/* List of DVB device types */
+
+/**
+ * enum dvb_device_type - type of the Digital TV device
+ *
+ * @DVB_DEVICE_SEC:		Digital TV standalone Common Interface (CI)
+ * @DVB_DEVICE_FRONTEND:	Digital TV frontend.
+ * @DVB_DEVICE_DEMUX:		Digital TV demux.
+ * @DVB_DEVICE_DVR:		Digital TV digital video record (DVR).
+ * @DVB_DEVICE_CA:		Digital TV Conditional Access (CA).
+ * @DVB_DEVICE_NET:		Digital TV network.
+ *
+ * @DVB_DEVICE_VIDEO:		Digital TV video decoder.
+ *				Deprecated. Used only on av7110-av.
+ * @DVB_DEVICE_AUDIO:		Digital TV audio decoder.
+ *				Deprecated. Used only on av7110-av.
+ * @DVB_DEVICE_OSD:		Digital TV On Screen Display (OSD).
+ *				Deprecated. Used only on av7110.
+ */
+enum dvb_device_type {
+	DVB_DEVICE_SEC,
+	DVB_DEVICE_FRONTEND,
+	DVB_DEVICE_DEMUX,
+	DVB_DEVICE_DVR,
+	DVB_DEVICE_CA,
+	DVB_DEVICE_NET,
+
+	DVB_DEVICE_VIDEO,
+	DVB_DEVICE_AUDIO,
+	DVB_DEVICE_OSD,
+};
+
+#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
+	static short adapter_nr[] = \
+		{[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \
+	module_param_array(adapter_nr, short, NULL, 0444); \
+	MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
+
+struct dvb_frontend;
+
+/**
+ * struct dvb_adapter - represents a Digital TV adapter using Linux DVB API
+ *
+ * @num:		Number of the adapter
+ * @list_head:		List with the DVB adapters
+ * @device_list:	List with the DVB devices
+ * @name:		Name of the adapter
+ * @proposed_mac:	proposed MAC address for the adapter
+ * @priv:		private data
+ * @device:		pointer to struct device
+ * @module:		pointer to struct module
+ * @mfe_shared:		mfe shared: indicates mutually exclusive frontends
+ *			Thie usage of this flag is currently deprecated
+ * @mfe_dvbdev:		Frontend device in use, in the case of MFE
+ * @mfe_lock:		Lock to prevent using the other frontends when MFE is
+ *			used.
+ * @mdev_lock:          Protect access to the mdev pointer.
+ * @mdev:		pointer to struct media_device, used when the media
+ *			controller is used.
+ * @conn:		RF connector. Used only if the device has no separate
+ *			tuner.
+ * @conn_pads:		pointer to struct media_pad associated with @conn;
+ */
+struct dvb_adapter {
+	int num;
+	struct list_head list_head;
+	struct list_head device_list;
+	const char *name;
+	u8 proposed_mac [6];
+	void* priv;
+
+	struct device *device;
+
+	struct module *module;
+
+	int mfe_shared;			/* indicates mutually exclusive frontends */
+	struct dvb_device *mfe_dvbdev;	/* frontend device in use */
+	struct mutex mfe_lock;		/* access lock for thread creation */
+
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	struct mutex mdev_lock;
+	struct media_device *mdev;
+	struct media_entity *conn;
+	struct media_pad *conn_pads;
+#endif
+};
+
+/**
+ * struct dvb_device - represents a DVB device node
+ *
+ * @list_head:	List head with all DVB devices
+ * @fops:	pointer to struct file_operations
+ * @adapter:	pointer to the adapter that holds this device node
+ * @type:	type of the device, as defined by &enum dvb_device_type.
+ * @minor:	devnode minor number. Major number is always DVB_MAJOR.
+ * @id:		device ID number, inside the adapter
+ * @readers:	Initialized by the caller. Each call to open() in Read Only mode
+ *		decreases this counter by one.
+ * @writers:	Initialized by the caller. Each call to open() in Read/Write
+ *		mode decreases this counter by one.
+ * @users:	Initialized by the caller. Each call to open() in any mode
+ *		decreases this counter by one.
+ * @wait_queue:	wait queue, used to wait for certain events inside one of
+ *		the DVB API callers
+ * @kernel_ioctl: callback function used to handle ioctl calls from userspace.
+ * @name:	Name to be used for the device at the Media Controller
+ * @entity:	pointer to struct media_entity associated with the device node
+ * @pads:	pointer to struct media_pad associated with @entity;
+ * @priv:	private data
+ * @intf_devnode: Pointer to media_intf_devnode. Used by the dvbdev core to
+ *		store the MC device node interface
+ * @tsout_num_entities: Number of Transport Stream output entities
+ * @tsout_entity: array with MC entities associated to each TS output node
+ * @tsout_pads: array with the source pads for each @tsout_entity
+ *
+ * This structure is used by the DVB core (frontend, CA, net, demux) in
+ * order to create the device nodes. Usually, driver should not initialize
+ * this struct diretly.
+ */
+struct dvb_device {
+	struct list_head list_head;
+	const struct file_operations *fops;
+	struct dvb_adapter *adapter;
+	enum dvb_device_type type;
+	int minor;
+	u32 id;
+
+	/* in theory, 'users' can vanish now,
+	   but I don't want to change too much now... */
+	int readers;
+	int writers;
+	int users;
+
+	wait_queue_head_t	  wait_queue;
+	/* don't really need those !? -- FIXME: use video_usercopy  */
+	int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
+
+	/* Needed for media controller register/unregister */
+#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
+	const char *name;
+
+	/* Allocated and filled inside dvbdev.c */
+	struct media_intf_devnode *intf_devnode;
+
+	unsigned tsout_num_entities;
+	struct media_entity *entity, *tsout_entity;
+	struct media_pad *pads, *tsout_pads;
+#endif
+
+	void *priv;
+};
+
+/**
+ * dvb_register_adapter - Registers a new DVB adapter
+ *
+ * @adap:	pointer to struct dvb_adapter
+ * @name:	Adapter's name
+ * @module:	initialized with THIS_MODULE at the caller
+ * @device:	pointer to struct device that corresponds to the device driver
+ * @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
+ *		to select among them. Typically, initialized with:
+ *		DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
+ */
+int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
+			 struct module *module, struct device *device,
+			 short *adapter_nums);
+
+/**
+ * dvb_unregister_adapter - Unregisters a DVB adapter
+ *
+ * @adap:	pointer to struct dvb_adapter
+ */
+int dvb_unregister_adapter(struct dvb_adapter *adap);
+
+/**
+ * dvb_register_device - Registers a new DVB device
+ *
+ * @adap:	pointer to struct dvb_adapter
+ * @pdvbdev:	pointer to the place where the new struct dvb_device will be
+ *		stored
+ * @template:	Template used to create &pdvbdev;
+ * @priv:	private data
+ * @type:	type of the device, as defined by &enum dvb_device_type.
+ * @demux_sink_pads: Number of demux outputs, to be used to create the TS
+ *		outputs via the Media Controller.
+ */
+int dvb_register_device(struct dvb_adapter *adap,
+			struct dvb_device **pdvbdev,
+			const struct dvb_device *template,
+			void *priv,
+			enum dvb_device_type type,
+			int demux_sink_pads);
+
+/**
+ * dvb_remove_device - Remove a registered DVB device
+ *
+ * This does not free memory.  To do that, call dvb_free_device().
+ *
+ * @dvbdev:	pointer to struct dvb_device
+ */
+void dvb_remove_device(struct dvb_device *dvbdev);
+
+/**
+ * dvb_free_device - Free memory occupied by a DVB device.
+ *
+ * Call dvb_unregister_device() before calling this function.
+ *
+ * @dvbdev:	pointer to struct dvb_device
+ */
+void dvb_free_device(struct dvb_device *dvbdev);
+
+/**
+ * dvb_unregister_device - Unregisters a DVB device
+ *
+ * This is a combination of dvb_remove_device() and dvb_free_device().
+ * Using this function is usually a mistake, and is often an indicator
+ * for a use-after-free bug (when a userspace process keeps a file
+ * handle to a detached device).
+ *
+ * @dvbdev:	pointer to struct dvb_device
+ */
+void dvb_unregister_device(struct dvb_device *dvbdev);
+
+#ifdef CONFIG_MEDIA_CONTROLLER_DVB
+/**
+ * dvb_create_media_graph - Creates media graph for the Digital TV part of the
+ *				device.
+ *
+ * @adap:			pointer to &struct dvb_adapter
+ * @create_rf_connector:	if true, it creates the RF connector too
+ *
+ * This function checks all DVB-related functions at the media controller
+ * entities and creates the needed links for the media graph. It is
+ * capable of working with multiple tuners or multiple frontends, but it
+ * won't create links if the device has multiple tuners and multiple frontends
+ * or if the device has multiple muxes. In such case, the caller driver should
+ * manually create the remaining links.
+ */
+__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
+					bool create_rf_connector);
+
+/**
+ * dvb_register_media_controller - registers a media controller at DVB adapter
+ *
+ * @adap:			pointer to &struct dvb_adapter
+ * @mdev:			pointer to &struct media_device
+ */
+static inline void dvb_register_media_controller(struct dvb_adapter *adap,
+						 struct media_device *mdev)
+{
+	adap->mdev = mdev;
+}
+
+/**
+ * dvb_get_media_controller - gets the associated media controller
+ *
+ * @adap:			pointer to &struct dvb_adapter
+ */
+static inline struct media_device
+*dvb_get_media_controller(struct dvb_adapter *adap)
+{
+	return adap->mdev;
+}
+#else
+static inline
+int dvb_create_media_graph(struct dvb_adapter *adap,
+			   bool create_rf_connector)
+{
+	return 0;
+};
+#define dvb_register_media_controller(a, b) {}
+#define dvb_get_media_controller(a) NULL
+#endif
+
+/**
+ * dvb_generic_open - Digital TV open function, used by DVB devices
+ *
+ * @inode: pointer to &struct inode.
+ * @file: pointer to &struct file.
+ *
+ * Checks if a DVB devnode is still valid, and if the permissions are
+ * OK and increment negative use count.
+ */
+int dvb_generic_open(struct inode *inode, struct file *file);
+
+/**
+ * dvb_generic_close - Digital TV close function, used by DVB devices
+ *
+ * @inode: pointer to &struct inode.
+ * @file: pointer to &struct file.
+ *
+ * Checks if a DVB devnode is still valid, and if the permissions are
+ * OK and decrement negative use count.
+ */
+int dvb_generic_release(struct inode *inode, struct file *file);
+
+/**
+ * dvb_generic_ioctl - Digital TV close function, used by DVB devices
+ *
+ * @file: pointer to &struct file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ *
+ * Checks if a DVB devnode and struct dvbdev.kernel_ioctl is still valid.
+ * If so, calls dvb_usercopy().
+ */
+long dvb_generic_ioctl(struct file *file,
+		       unsigned int cmd, unsigned long arg);
+
+/**
+ * dvb_usercopy - copies data from/to userspace memory when an ioctl is
+ *      issued.
+ *
+ * @file: Pointer to struct &file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ * @func: function that will actually handle the ioctl
+ *
+ * Ancillary function that uses ioctl direction and size to copy from
+ * userspace. Then, it calls @func, and, if needed, data is copied back
+ * to userspace.
+ */
+int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
+		 int (*func)(struct file *file, unsigned int cmd, void *arg));
+
+#if IS_ENABLED(CONFIG_I2C)
+
+struct i2c_adapter;
+struct i2c_client;
+/**
+ * dvb_module_probe - helper routine to probe an I2C module
+ *
+ * @module_name:
+ *	Name of the I2C module to be probed
+ * @name:
+ *	Optional name for the I2C module. Used for debug purposes.
+ * 	If %NULL, defaults to @module_name.
+ * @adap:
+ *	pointer to &struct i2c_adapter that describes the I2C adapter where
+ *	the module will be bound.
+ * @addr:
+ *	I2C address of the adapter, in 7-bit notation.
+ * @platform_data:
+ *	Platform data to be passed to the I2C module probed.
+ *
+ * This function binds an I2C device into the DVB core. Should be used by
+ * all drivers that use I2C bus to control the hardware. A module bound
+ * with dvb_module_probe() should use dvb_module_release() to unbind.
+ *
+ * Return:
+ *	On success, return an &struct i2c_client, pointing the the bound
+ *	I2C device. %NULL otherwise.
+ *
+ * .. note::
+ *
+ *    In the past, DVB modules (mainly, frontends) were bound via dvb_attach()
+ *    macro, with does an ugly hack, using I2C low level functions. Such
+ *    usage is deprecated and will be removed soon. Instead, use this routine.
+ */
+struct i2c_client *dvb_module_probe(const char *module_name,
+				    const char *name,
+				    struct i2c_adapter *adap,
+				    unsigned char addr,
+				    void *platform_data);
+
+/**
+ * dvb_module_release - releases an I2C device allocated with
+ *	 dvb_module_probe().
+ *
+ * @client: pointer to &struct i2c_client with the I2C client to be released.
+ *	    can be %NULL.
+ *
+ * This function should be used to free all resources reserved by
+ * dvb_module_probe() and unbinding the I2C hardware.
+ */
+void dvb_module_release(struct i2c_client *client);
+
+#endif /* CONFIG_I2C */
+
+/* Legacy generic DVB attach function. */
+#ifdef CONFIG_MEDIA_ATTACH
+
+/**
+ * dvb_attach - attaches a DVB frontend into the DVB core.
+ *
+ * @FUNCTION:	function on a frontend module to be called.
+ * @ARGS...:	@FUNCTION arguments.
+ *
+ * This ancillary function loads a frontend module in runtime and runs
+ * the @FUNCTION function there, with @ARGS.
+ * As it increments symbol usage cont, at unregister, dvb_detach()
+ * should be called.
+ *
+ * .. note::
+ *
+ *    In the past, DVB modules (mainly, frontends) were bound via dvb_attach()
+ *    macro, with does an ugly hack, using I2C low level functions. Such
+ *    usage is deprecated and will be removed soon. Instead, you should use
+ *    dvb_module_probe().
+ */
+#define dvb_attach(FUNCTION, ARGS...) ({ \
+	void *__r = NULL; \
+	typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
+	if (__a) { \
+		__r = (void *) __a(ARGS); \
+		if (__r == NULL) \
+			symbol_put(FUNCTION); \
+	} else { \
+		printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \
+	} \
+	__r; \
+})
+
+/**
+ * dvb_detach - detaches a DVB frontend loaded via dvb_attach()
+ *
+ * @FUNC:	attach function
+ *
+ * Decrements usage count for a function previously called via dvb_attach().
+ */
+
+#define dvb_detach(FUNC)	symbol_put_addr(FUNC)
+
+#else
+#define dvb_attach(FUNCTION, ARGS...) ({ \
+	FUNCTION(ARGS); \
+})
+
+#define dvb_detach(FUNC)	{}
+
+#endif	/* CONFIG_MEDIA_ATTACH */
+
+#endif /* #ifndef _DVBDEV_H_ */
diff --git a/include/media/i2c/ad9389b.h b/include/media/i2c/ad9389b.h
new file mode 100644
index 0000000..30f9ea9
--- /dev/null
+++ b/include/media/i2c/ad9389b.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Analog Devices AD9389B/AD9889B video encoder driver header
+ *
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef AD9389B_H
+#define AD9389B_H
+
+enum ad9389b_tmds_pll_gear {
+	AD9389B_TMDS_PLL_GEAR_AUTOMATIC,
+	AD9389B_TMDS_PLL_GEAR_SEMI_AUTOMATIC,
+};
+
+/* Platform dependent definitions */
+struct ad9389b_platform_data {
+	enum ad9389b_tmds_pll_gear tmds_pll_gear ;
+	/* Differential Data/Clock Output Drive Strength (reg. 0xa2/0xa3) */
+	u8 diff_data_drive_strength;
+	u8 diff_clk_drive_strength;
+};
+
+/* notify events */
+#define AD9389B_MONITOR_DETECT 0
+#define AD9389B_EDID_DETECT 1
+
+struct ad9389b_monitor_detect {
+	int present;
+};
+
+struct ad9389b_edid_detect {
+	int present;
+	int segment;
+};
+
+#endif
diff --git a/include/media/i2c/adp1653.h b/include/media/i2c/adp1653.h
new file mode 100644
index 0000000..8a79f72
--- /dev/null
+++ b/include/media/i2c/adp1653.h
@@ -0,0 +1,123 @@
+/*
+ * include/media/i2c/adp1653.h
+ *
+ * Copyright (C) 2008--2011 Nokia Corporation
+ *
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * Contributors:
+ *	Sakari Ailus <sakari.ailus@iki.fi>
+ *	Tuukka Toivonen <tuukkat76@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef ADP1653_H
+#define ADP1653_H
+
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+
+#define ADP1653_NAME				"adp1653"
+#define ADP1653_I2C_ADDR			(0x60 >> 1)
+
+/* Register definitions */
+#define ADP1653_REG_OUT_SEL			0x00
+#define ADP1653_REG_OUT_SEL_HPLED_TORCH_MIN	0x01
+#define ADP1653_REG_OUT_SEL_HPLED_TORCH_MAX	0x0b
+#define ADP1653_REG_OUT_SEL_HPLED_FLASH_MIN	0x0c
+#define ADP1653_REG_OUT_SEL_HPLED_FLASH_MAX	0x1f
+#define ADP1653_REG_OUT_SEL_HPLED_SHIFT		3
+#define ADP1653_REG_OUT_SEL_ILED_MAX		0x07
+#define ADP1653_REG_OUT_SEL_ILED_SHIFT		0
+
+#define ADP1653_REG_CONFIG			0x01
+#define ADP1653_REG_CONFIG_TMR_CFG		(1 << 4)
+#define ADP1653_REG_CONFIG_TMR_SET_MAX		0x0f
+#define ADP1653_REG_CONFIG_TMR_SET_SHIFT	0
+
+#define ADP1653_REG_SW_STROBE			0x02
+#define ADP1653_REG_SW_STROBE_SW_STROBE		(1 << 0)
+
+#define ADP1653_REG_FAULT			0x03
+#define ADP1653_REG_FAULT_FLT_SCP		(1 << 3)
+#define ADP1653_REG_FAULT_FLT_OT		(1 << 2)
+#define ADP1653_REG_FAULT_FLT_TMR		(1 << 1)
+#define ADP1653_REG_FAULT_FLT_OV		(1 << 0)
+
+#define ADP1653_INDICATOR_INTENSITY_MIN		0
+#define ADP1653_INDICATOR_INTENSITY_STEP	2500
+#define ADP1653_INDICATOR_INTENSITY_MAX		\
+	(ADP1653_REG_OUT_SEL_ILED_MAX * ADP1653_INDICATOR_INTENSITY_STEP)
+#define ADP1653_INDICATOR_INTENSITY_uA_TO_REG(a) \
+	((a) / ADP1653_INDICATOR_INTENSITY_STEP)
+#define ADP1653_INDICATOR_INTENSITY_REG_TO_uA(a) \
+	((a) * ADP1653_INDICATOR_INTENSITY_STEP)
+
+#define ADP1653_FLASH_INTENSITY_BASE		35
+#define ADP1653_FLASH_INTENSITY_STEP		15
+#define ADP1653_FLASH_INTENSITY_MIN					\
+	(ADP1653_FLASH_INTENSITY_BASE					\
+	 + ADP1653_REG_OUT_SEL_HPLED_FLASH_MIN * ADP1653_FLASH_INTENSITY_STEP)
+#define ADP1653_FLASH_INTENSITY_MAX			\
+	(ADP1653_FLASH_INTENSITY_MIN +			\
+	 (ADP1653_REG_OUT_SEL_HPLED_FLASH_MAX -		\
+	  ADP1653_REG_OUT_SEL_HPLED_FLASH_MIN + 1) *	\
+	 ADP1653_FLASH_INTENSITY_STEP)
+
+#define ADP1653_FLASH_INTENSITY_mA_TO_REG(a)				\
+	((a) < ADP1653_FLASH_INTENSITY_BASE ? 0 :			\
+	 (((a) - ADP1653_FLASH_INTENSITY_BASE) / ADP1653_FLASH_INTENSITY_STEP))
+#define ADP1653_FLASH_INTENSITY_REG_TO_mA(a)		\
+	((a) * ADP1653_FLASH_INTENSITY_STEP + ADP1653_FLASH_INTENSITY_BASE)
+
+#define ADP1653_TORCH_INTENSITY_MIN					\
+	(ADP1653_FLASH_INTENSITY_BASE					\
+	 + ADP1653_REG_OUT_SEL_HPLED_TORCH_MIN * ADP1653_FLASH_INTENSITY_STEP)
+#define ADP1653_TORCH_INTENSITY_MAX			\
+	(ADP1653_TORCH_INTENSITY_MIN +			\
+	 (ADP1653_REG_OUT_SEL_HPLED_TORCH_MAX -		\
+	  ADP1653_REG_OUT_SEL_HPLED_TORCH_MIN + 1) *	\
+	 ADP1653_FLASH_INTENSITY_STEP)
+
+struct adp1653_platform_data {
+	int (*power)(struct v4l2_subdev *sd, int on);
+
+	u32 max_flash_timeout;		/* flash light timeout in us */
+	u32 max_flash_intensity;	/* led intensity, flash mode, mA */
+	u32 max_torch_intensity;	/* led intensity, torch mode, mA */
+	u32 max_indicator_intensity;	/* indicator led intensity, uA */
+
+	struct gpio_desc *enable_gpio;	/* for device-tree based boot */
+};
+
+#define to_adp1653_flash(sd)	container_of(sd, struct adp1653_flash, subdev)
+
+struct adp1653_flash {
+	struct v4l2_subdev subdev;
+	struct adp1653_platform_data *platform_data;
+
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *led_mode;
+	struct v4l2_ctrl *flash_timeout;
+	struct v4l2_ctrl *flash_intensity;
+	struct v4l2_ctrl *torch_intensity;
+	struct v4l2_ctrl *indicator_intensity;
+
+	struct mutex power_lock;
+	int power_count;
+	int fault;
+};
+
+#endif /* ADP1653_H */
diff --git a/include/media/i2c/adv7183.h b/include/media/i2c/adv7183.h
new file mode 100644
index 0000000..2ad8c3d
--- /dev/null
+++ b/include/media/i2c/adv7183.h
@@ -0,0 +1,43 @@
+/*
+ * adv7183.h - definition for adv7183 inputs and outputs
+ *
+ * Copyright (c) 2011 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ADV7183_H_
+#define _ADV7183_H_
+
+/* ADV7183 HW inputs */
+#define ADV7183_COMPOSITE0  0  /* CVBS in on AIN1 */
+#define ADV7183_COMPOSITE1  1  /* CVBS in on AIN2 */
+#define ADV7183_COMPOSITE2  2  /* CVBS in on AIN3 */
+#define ADV7183_COMPOSITE3  3  /* CVBS in on AIN4 */
+#define ADV7183_COMPOSITE4  4  /* CVBS in on AIN5 */
+#define ADV7183_COMPOSITE5  5  /* CVBS in on AIN6 */
+#define ADV7183_COMPOSITE6  6  /* CVBS in on AIN7 */
+#define ADV7183_COMPOSITE7  7  /* CVBS in on AIN8 */
+#define ADV7183_COMPOSITE8  8  /* CVBS in on AIN9 */
+#define ADV7183_COMPOSITE9  9  /* CVBS in on AIN10 */
+#define ADV7183_COMPOSITE10 10 /* CVBS in on AIN11 */
+
+#define ADV7183_SVIDEO0     11 /* Y on AIN1, C on AIN4 */
+#define ADV7183_SVIDEO1     12 /* Y on AIN2, C on AIN5 */
+#define ADV7183_SVIDEO2     13 /* Y on AIN3, C on AIN6 */
+
+#define ADV7183_COMPONENT0  14 /* Y on AIN1, Pr on AIN4, Pb on AIN5 */
+#define ADV7183_COMPONENT1  15 /* Y on AIN2, Pr on AIN3, Pb on AIN6 */
+
+/* ADV7183 HW outputs */
+#define ADV7183_8BIT_OUT    0
+#define ADV7183_16BIT_OUT   1
+
+#endif
diff --git a/include/media/i2c/adv7343.h b/include/media/i2c/adv7343.h
new file mode 100644
index 0000000..e4142b1
--- /dev/null
+++ b/include/media/i2c/adv7343.h
@@ -0,0 +1,63 @@
+/*
+ * ADV7343 header file
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef ADV7343_H
+#define ADV7343_H
+
+#define ADV7343_COMPOSITE_ID	(0)
+#define ADV7343_COMPONENT_ID	(1)
+#define ADV7343_SVIDEO_ID	(2)
+
+/**
+ * adv7343_power_mode - power mode configuration.
+ * @sleep_mode: on enable the current consumption is reduced to micro ampere
+ *		level. All DACs and the internal PLL circuit are disabled.
+ *		Registers can be read from and written in sleep mode.
+ * @pll_control: PLL and oversampling control. This control allows internal
+ *		 PLL 1 circuit to be powered down and the oversampling to be
+ *		 switched off.
+ * @dac: array to configure power on/off DAC's 1..6
+ *
+ * Power mode register (Register 0x0), for more info refer REGISTER MAP ACCESS
+ * section of datasheet[1], table 17 page no 30.
+ *
+ * [1] http://www.analog.com/static/imported-files/data_sheets/ADV7342_7343.pdf
+ */
+struct adv7343_power_mode {
+	bool sleep_mode;
+	bool pll_control;
+	u32 dac[6];
+};
+
+/**
+ * struct adv7343_sd_config - SD Only Output Configuration.
+ * @sd_dac_out: array configuring SD DAC Outputs 1 and 2
+ */
+struct adv7343_sd_config {
+	/* SD only Output Configuration */
+	u32 sd_dac_out[2];
+};
+
+/**
+ * struct adv7343_platform_data - Platform data values and access functions.
+ * @mode_config: Configuration for power mode.
+ * @sd_config: SD Only Configuration.
+ */
+struct adv7343_platform_data {
+	struct adv7343_power_mode mode_config;
+	struct adv7343_sd_config sd_config;
+};
+
+#endif				/* End of #ifndef ADV7343_H */
diff --git a/include/media/i2c/adv7393.h b/include/media/i2c/adv7393.h
new file mode 100644
index 0000000..b28edf3
--- /dev/null
+++ b/include/media/i2c/adv7393.h
@@ -0,0 +1,28 @@
+/*
+ * ADV7393 header file
+ *
+ * Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/
+ * Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
+ *
+ * Based on ADV7343 driver,
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef ADV7393_H
+#define ADV7393_H
+
+#define ADV7393_COMPOSITE_ID	(0)
+#define ADV7393_COMPONENT_ID	(1)
+#define ADV7393_SVIDEO_ID	(2)
+
+#endif				/* End of #ifndef ADV7393_H */
diff --git a/include/media/i2c/adv7511.h b/include/media/i2c/adv7511.h
new file mode 100644
index 0000000..1874c05
--- /dev/null
+++ b/include/media/i2c/adv7511.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Analog Devices ADV7511 HDMI Transmitter Device Driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef ADV7511_H
+#define ADV7511_H
+
+/* notify events */
+#define ADV7511_MONITOR_DETECT 0
+#define ADV7511_EDID_DETECT 1
+
+
+struct adv7511_monitor_detect {
+	int present;
+};
+
+struct adv7511_edid_detect {
+	int present;
+	int segment;
+	uint16_t phys_addr;
+};
+
+struct adv7511_platform_data {
+	u8 i2c_edid;
+	u8 i2c_cec;
+	u8 i2c_pktmem;
+	u32 cec_clk;
+};
+
+#endif
diff --git a/include/media/i2c/adv7604.h b/include/media/i2c/adv7604.h
new file mode 100644
index 0000000..77a9799
--- /dev/null
+++ b/include/media/i2c/adv7604.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * adv7604 - Analog Devices ADV7604 video decoder driver
+ *
+ * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _ADV7604_
+#define _ADV7604_
+
+#include <linux/types.h>
+
+/* Analog input muxing modes (AFE register 0x02, [2:0]) */
+enum adv7604_ain_sel {
+	ADV7604_AIN1_2_3_NC_SYNC_1_2 = 0,
+	ADV7604_AIN4_5_6_NC_SYNC_2_1 = 1,
+	ADV7604_AIN7_8_9_NC_SYNC_3_1 = 2,
+	ADV7604_AIN10_11_12_NC_SYNC_4_1 = 3,
+	ADV7604_AIN9_4_5_6_SYNC_2_1 = 4,
+};
+
+/*
+ * Bus rotation and reordering. This is used to specify component reordering on
+ * the board and describes the components order on the bus when the ADV7604
+ * outputs RGB.
+ */
+enum adv7604_bus_order {
+	ADV7604_BUS_ORDER_RGB,		/* No operation	*/
+	ADV7604_BUS_ORDER_GRB,		/* Swap 1-2	*/
+	ADV7604_BUS_ORDER_RBG,		/* Swap 2-3	*/
+	ADV7604_BUS_ORDER_BGR,		/* Swap 1-3	*/
+	ADV7604_BUS_ORDER_BRG,		/* Rotate right	*/
+	ADV7604_BUS_ORDER_GBR,		/* Rotate left	*/
+};
+
+/* Input Color Space (IO register 0x02, [7:4]) */
+enum adv76xx_inp_color_space {
+	ADV76XX_INP_COLOR_SPACE_LIM_RGB = 0,
+	ADV76XX_INP_COLOR_SPACE_FULL_RGB = 1,
+	ADV76XX_INP_COLOR_SPACE_LIM_YCbCr_601 = 2,
+	ADV76XX_INP_COLOR_SPACE_LIM_YCbCr_709 = 3,
+	ADV76XX_INP_COLOR_SPACE_XVYCC_601 = 4,
+	ADV76XX_INP_COLOR_SPACE_XVYCC_709 = 5,
+	ADV76XX_INP_COLOR_SPACE_FULL_YCbCr_601 = 6,
+	ADV76XX_INP_COLOR_SPACE_FULL_YCbCr_709 = 7,
+	ADV76XX_INP_COLOR_SPACE_AUTO = 0xf,
+};
+
+/* Select output format (IO register 0x03, [4:2]) */
+enum adv7604_op_format_mode_sel {
+	ADV7604_OP_FORMAT_MODE0 = 0x00,
+	ADV7604_OP_FORMAT_MODE1 = 0x04,
+	ADV7604_OP_FORMAT_MODE2 = 0x08,
+};
+
+enum adv76xx_drive_strength {
+	ADV76XX_DR_STR_MEDIUM_LOW = 1,
+	ADV76XX_DR_STR_MEDIUM_HIGH = 2,
+	ADV76XX_DR_STR_HIGH = 3,
+};
+
+/* INT1 Configuration (IO register 0x40, [1:0]) */
+enum adv76xx_int1_config {
+	ADV76XX_INT1_CONFIG_OPEN_DRAIN,
+	ADV76XX_INT1_CONFIG_ACTIVE_LOW,
+	ADV76XX_INT1_CONFIG_ACTIVE_HIGH,
+	ADV76XX_INT1_CONFIG_DISABLED,
+};
+
+enum adv76xx_page {
+	ADV76XX_PAGE_IO,
+	ADV7604_PAGE_AVLINK,
+	ADV76XX_PAGE_CEC,
+	ADV76XX_PAGE_INFOFRAME,
+	ADV7604_PAGE_ESDP,
+	ADV7604_PAGE_DPP,
+	ADV76XX_PAGE_AFE,
+	ADV76XX_PAGE_REP,
+	ADV76XX_PAGE_EDID,
+	ADV76XX_PAGE_HDMI,
+	ADV76XX_PAGE_TEST,
+	ADV76XX_PAGE_CP,
+	ADV7604_PAGE_VDP,
+	ADV76XX_PAGE_MAX,
+};
+
+/* Platform dependent definition */
+struct adv76xx_platform_data {
+	/* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */
+	unsigned disable_pwrdnb:1;
+
+	/* DIS_CABLE_DET_RST: 1 if the 5V pins are unused and unconnected */
+	unsigned disable_cable_det_rst:1;
+
+	int default_input;
+
+	/* Analog input muxing mode */
+	enum adv7604_ain_sel ain_sel;
+
+	/* Bus rotation and reordering */
+	enum adv7604_bus_order bus_order;
+
+	/* Select output format mode */
+	enum adv7604_op_format_mode_sel op_format_mode_sel;
+
+	/* Configuration of the INT1 pin */
+	enum adv76xx_int1_config int1_config;
+
+	/* IO register 0x02 */
+	unsigned alt_gamma:1;
+
+	/* IO register 0x05 */
+	unsigned blank_data:1;
+	unsigned insert_av_codes:1;
+	unsigned replicate_av_codes:1;
+
+	/* IO register 0x06 */
+	unsigned inv_vs_pol:1;
+	unsigned inv_hs_pol:1;
+	unsigned inv_llc_pol:1;
+
+	/* IO register 0x14 */
+	enum adv76xx_drive_strength dr_str_data;
+	enum adv76xx_drive_strength dr_str_clk;
+	enum adv76xx_drive_strength dr_str_sync;
+
+	/* IO register 0x30 */
+	unsigned output_bus_lsb_to_msb:1;
+
+	/* Free run */
+	unsigned hdmi_free_run_mode;
+
+	/* i2c addresses: 0 == use default */
+	u8 i2c_addresses[ADV76XX_PAGE_MAX];
+};
+
+enum adv76xx_pad {
+	ADV76XX_PAD_HDMI_PORT_A = 0,
+	ADV7604_PAD_HDMI_PORT_B = 1,
+	ADV7604_PAD_HDMI_PORT_C = 2,
+	ADV7604_PAD_HDMI_PORT_D = 3,
+	ADV7604_PAD_VGA_RGB = 4,
+	ADV7604_PAD_VGA_COMP = 5,
+	/* The source pad is either 1 (ADV7611) or 6 (ADV7604) */
+	ADV7604_PAD_SOURCE = 6,
+	ADV7611_PAD_SOURCE = 1,
+	ADV76XX_PAD_MAX = 7,
+};
+
+#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE	(V4L2_CID_DV_CLASS_BASE + 0x1000)
+#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL	(V4L2_CID_DV_CLASS_BASE + 0x1001)
+#define V4L2_CID_ADV_RX_FREE_RUN_COLOR		(V4L2_CID_DV_CLASS_BASE + 0x1002)
+
+/* notify events */
+#define ADV76XX_HOTPLUG		1
+
+#endif
diff --git a/include/media/i2c/adv7842.h b/include/media/i2c/adv7842.h
new file mode 100644
index 0000000..05e01f0
--- /dev/null
+++ b/include/media/i2c/adv7842.h
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * adv7842 - Analog Devices ADV7842 video decoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _ADV7842_
+#define _ADV7842_
+
+/* Analog input muxing modes (AFE register 0x02, [2:0]) */
+enum adv7842_ain_sel {
+	ADV7842_AIN1_2_3_NC_SYNC_1_2 = 0,
+	ADV7842_AIN4_5_6_NC_SYNC_2_1 = 1,
+	ADV7842_AIN7_8_9_NC_SYNC_3_1 = 2,
+	ADV7842_AIN10_11_12_NC_SYNC_4_1 = 3,
+	ADV7842_AIN9_4_5_6_SYNC_2_1 = 4,
+};
+
+/*
+ * Bus rotation and reordering. This is used to specify component reordering on
+ * the board and describes the components order on the bus when the ADV7842
+ * outputs RGB.
+ */
+enum adv7842_bus_order {
+	ADV7842_BUS_ORDER_RGB,		/* No operation	*/
+	ADV7842_BUS_ORDER_GRB,		/* Swap 1-2	*/
+	ADV7842_BUS_ORDER_RBG,		/* Swap 2-3	*/
+	ADV7842_BUS_ORDER_BGR,		/* Swap 1-3	*/
+	ADV7842_BUS_ORDER_BRG,		/* Rotate right	*/
+	ADV7842_BUS_ORDER_GBR,		/* Rotate left	*/
+};
+
+/* Input Color Space (IO register 0x02, [7:4]) */
+enum adv7842_inp_color_space {
+	ADV7842_INP_COLOR_SPACE_LIM_RGB = 0,
+	ADV7842_INP_COLOR_SPACE_FULL_RGB = 1,
+	ADV7842_INP_COLOR_SPACE_LIM_YCbCr_601 = 2,
+	ADV7842_INP_COLOR_SPACE_LIM_YCbCr_709 = 3,
+	ADV7842_INP_COLOR_SPACE_XVYCC_601 = 4,
+	ADV7842_INP_COLOR_SPACE_XVYCC_709 = 5,
+	ADV7842_INP_COLOR_SPACE_FULL_YCbCr_601 = 6,
+	ADV7842_INP_COLOR_SPACE_FULL_YCbCr_709 = 7,
+	ADV7842_INP_COLOR_SPACE_AUTO = 0xf,
+};
+
+/* Select output format (IO register 0x03, [4:2]) */
+enum adv7842_op_format_mode_sel {
+	ADV7842_OP_FORMAT_MODE0 = 0x00,
+	ADV7842_OP_FORMAT_MODE1 = 0x04,
+	ADV7842_OP_FORMAT_MODE2 = 0x08,
+};
+
+/* Mode of operation */
+enum adv7842_mode {
+	ADV7842_MODE_SDP,
+	ADV7842_MODE_COMP,
+	ADV7842_MODE_RGB,
+	ADV7842_MODE_HDMI
+};
+
+/* Video standard select (IO register 0x00, [5:0]) */
+enum adv7842_vid_std_select {
+	/* SDP */
+	ADV7842_SDP_VID_STD_CVBS_SD_4x1 = 0x01,
+	ADV7842_SDP_VID_STD_YC_SD4_x1 = 0x09,
+	/* RGB */
+	ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE = 0x07,
+	/* HDMI GR */
+	ADV7842_HDMI_GR_VID_STD_AUTO_GRAPH_MODE = 0x02,
+	/* HDMI COMP */
+	ADV7842_HDMI_COMP_VID_STD_HD_1250P = 0x1e,
+};
+
+enum adv7842_select_input {
+	ADV7842_SELECT_HDMI_PORT_A,
+	ADV7842_SELECT_HDMI_PORT_B,
+	ADV7842_SELECT_VGA_RGB,
+	ADV7842_SELECT_VGA_COMP,
+	ADV7842_SELECT_SDP_CVBS,
+	ADV7842_SELECT_SDP_YC,
+};
+
+enum adv7842_drive_strength {
+	ADV7842_DR_STR_LOW = 0,
+	ADV7842_DR_STR_MEDIUM_LOW = 1,
+	ADV7842_DR_STR_MEDIUM_HIGH = 2,
+	ADV7842_DR_STR_HIGH = 3,
+};
+
+struct adv7842_sdp_csc_coeff {
+	bool manual;
+	u16 scaling;
+	u16 A1;
+	u16 A2;
+	u16 A3;
+	u16 A4;
+	u16 B1;
+	u16 B2;
+	u16 B3;
+	u16 B4;
+	u16 C1;
+	u16 C2;
+	u16 C3;
+	u16 C4;
+};
+
+struct adv7842_sdp_io_sync_adjustment {
+	bool adjust;
+	u16 hs_beg;
+	u16 hs_width;
+	u16 de_beg;
+	u16 de_end;
+	u8 vs_beg_o;
+	u8 vs_beg_e;
+	u8 vs_end_o;
+	u8 vs_end_e;
+	u8 de_v_beg_o;
+	u8 de_v_beg_e;
+	u8 de_v_end_o;
+	u8 de_v_end_e;
+};
+
+/* Platform dependent definition */
+struct adv7842_platform_data {
+	/* chip reset during probe */
+	unsigned chip_reset:1;
+
+	/* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */
+	unsigned disable_pwrdnb:1;
+
+	/* DIS_CABLE_DET_RST: 1 if the 5V pins are unused and unconnected */
+	unsigned disable_cable_det_rst:1;
+
+	/* Analog input muxing mode */
+	enum adv7842_ain_sel ain_sel;
+
+	/* Bus rotation and reordering */
+	enum adv7842_bus_order bus_order;
+
+	/* Select output format mode */
+	enum adv7842_op_format_mode_sel op_format_mode_sel;
+
+	/* Default mode */
+	enum adv7842_mode mode;
+
+	/* Default input */
+	unsigned input;
+
+	/* Video standard */
+	enum adv7842_vid_std_select vid_std_select;
+
+	/* IO register 0x02 */
+	unsigned alt_gamma:1;
+
+	/* IO register 0x05 */
+	unsigned blank_data:1;
+	unsigned insert_av_codes:1;
+	unsigned replicate_av_codes:1;
+
+	/* IO register 0x30 */
+	unsigned output_bus_lsb_to_msb:1;
+
+	/* IO register 0x14 */
+	enum adv7842_drive_strength dr_str_data;
+	enum adv7842_drive_strength dr_str_clk;
+	enum adv7842_drive_strength dr_str_sync;
+
+	/*
+	 * IO register 0x19: Adjustment to the LLC DLL phase in
+	 * increments of 1/32 of a clock period.
+	 */
+	unsigned llc_dll_phase:5;
+
+	/* External RAM for 3-D comb or frame synchronizer */
+	unsigned sd_ram_size; /* ram size in MB */
+	unsigned sd_ram_ddr:1; /* ddr or sdr sdram */
+
+	/* HDMI free run, CP-reg 0xBA */
+	unsigned hdmi_free_run_enable:1;
+	/* 0 = Mode 0: run when there is no TMDS clock
+	   1 = Mode 1: run when there is no TMDS clock or the
+	       video resolution does not match programmed one. */
+	unsigned hdmi_free_run_mode:1;
+
+	/* SDP free run, CP-reg 0xDD */
+	unsigned sdp_free_run_auto:1;
+	unsigned sdp_free_run_man_col_en:1;
+	unsigned sdp_free_run_cbar_en:1;
+	unsigned sdp_free_run_force:1;
+
+	/* HPA manual (0) or auto (1), affects HDMI register 0x69 */
+	unsigned hpa_auto:1;
+
+	struct adv7842_sdp_csc_coeff sdp_csc_coeff;
+
+	struct adv7842_sdp_io_sync_adjustment sdp_io_sync_625;
+	struct adv7842_sdp_io_sync_adjustment sdp_io_sync_525;
+
+	/* i2c addresses */
+	u8 i2c_sdp_io;
+	u8 i2c_sdp;
+	u8 i2c_cp;
+	u8 i2c_vdp;
+	u8 i2c_afe;
+	u8 i2c_hdmi;
+	u8 i2c_repeater;
+	u8 i2c_edid;
+	u8 i2c_infoframe;
+	u8 i2c_cec;
+	u8 i2c_avlink;
+};
+
+#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE	(V4L2_CID_DV_CLASS_BASE + 0x1000)
+#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL	(V4L2_CID_DV_CLASS_BASE + 0x1001)
+#define V4L2_CID_ADV_RX_FREE_RUN_COLOR		(V4L2_CID_DV_CLASS_BASE + 0x1002)
+
+/* custom ioctl, used to test the external RAM that's used by the
+ * deinterlacer. */
+#define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE)
+
+#define ADV7842_EDID_PORT_A   0
+#define ADV7842_EDID_PORT_B   1
+#define ADV7842_EDID_PORT_VGA 2
+#define ADV7842_PAD_SOURCE    3
+
+#endif
diff --git a/include/media/i2c/ak881x.h b/include/media/i2c/ak881x.h
new file mode 100644
index 0000000..b7f2add
--- /dev/null
+++ b/include/media/i2c/ak881x.h
@@ -0,0 +1,25 @@
+/*
+ * Header for AK8813 / AK8814 TV-ecoders from Asahi Kasei Microsystems Co., Ltd. (AKM)
+ *
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef AK881X_H
+#define AK881X_H
+
+#define AK881X_IF_MODE_MASK	(3 << 0)
+#define AK881X_IF_MODE_BT656	(0 << 0)
+#define AK881X_IF_MODE_MASTER	(1 << 0)
+#define AK881X_IF_MODE_SLAVE	(2 << 0)
+#define AK881X_FIELD		(1 << 2)
+#define AK881X_COMPONENT	(1 << 3)
+
+struct ak881x_pdata {
+	unsigned long flags;
+};
+
+#endif
diff --git a/include/media/i2c/bt819.h b/include/media/i2c/bt819.h
new file mode 100644
index 0000000..1bcf0db
--- /dev/null
+++ b/include/media/i2c/bt819.h
@@ -0,0 +1,36 @@
+/*
+    bt819.h - bt819 notifications
+
+    Copyright (C) 2009 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _BT819_H_
+#define _BT819_H_
+
+#include <linux/ioctl.h>
+
+/* v4l2_device notifications. */
+
+/* Needed to reset the FIFO buffer when changing the input
+   or the video standard.
+
+   Note: these ioctls that internal to the kernel and are never called
+   from userspace. */
+#define BT819_FIFO_RESET_LOW	_IO('b', 0)
+#define BT819_FIFO_RESET_HIGH	_IO('b', 1)
+
+#endif
diff --git a/include/media/i2c/cs5345.h b/include/media/i2c/cs5345.h
new file mode 100644
index 0000000..6ccae24
--- /dev/null
+++ b/include/media/i2c/cs5345.h
@@ -0,0 +1,39 @@
+/*
+    cs5345.h - definition for cs5345 inputs and outputs
+
+    Copyright (C) 2007 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _CS5345_H_
+#define _CS5345_H_
+
+/* CS5345 HW inputs */
+#define CS5345_IN_MIC 0
+#define CS5345_IN_1   1
+#define CS5345_IN_2   2
+#define CS5345_IN_3   3
+#define CS5345_IN_4   4
+#define CS5345_IN_5   5
+#define CS5345_IN_6   6
+
+#define CS5345_MCLK_1   0x00
+#define CS5345_MCLK_1_5 0x10
+#define CS5345_MCLK_2   0x20
+#define CS5345_MCLK_3   0x30
+#define CS5345_MCLK_4   0x40
+
+#endif
diff --git a/include/media/i2c/cs53l32a.h b/include/media/i2c/cs53l32a.h
new file mode 100644
index 0000000..bf76197
--- /dev/null
+++ b/include/media/i2c/cs53l32a.h
@@ -0,0 +1,34 @@
+/*
+    cs53l32a.h - definition for cs53l32a inputs and outputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _CS53L32A_H_
+#define _CS53L32A_H_
+
+/* There are 2 physical inputs, but the second input can be
+   placed in two modes, the first mode bypasses the PGA (gain),
+   the second goes through the PGA. Hence there are three
+   possible inputs to choose from. */
+
+/* CS53L32A HW inputs */
+#define CS53L32A_IN0 0
+#define CS53L32A_IN1 1
+#define CS53L32A_IN2 2
+
+#endif
diff --git a/include/media/i2c/ir-kbd-i2c.h b/include/media/i2c/ir-kbd-i2c.h
new file mode 100644
index 0000000..9f47d6a
--- /dev/null
+++ b/include/media/i2c/ir-kbd-i2c.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _IR_I2C
+#define _IR_I2C
+
+#include <media/rc-core.h>
+
+#define DEFAULT_POLLING_INTERVAL	100	/* ms */
+
+struct IR_i2c;
+
+struct IR_i2c {
+	char		       *ir_codes;
+	struct i2c_client      *c;
+	struct rc_dev          *rc;
+
+	/* Used to avoid fast repeating */
+	unsigned char          old;
+
+	u32                    polling_interval; /* in ms */
+
+	struct delayed_work    work;
+	char                   phys[32];
+	int                    (*get_key)(struct IR_i2c *ir,
+					  enum rc_proto *protocol,
+					  u32 *scancode, u8 *toggle);
+	/* tx */
+	struct i2c_client      *tx_c;
+	struct mutex	       lock;	/* do not poll Rx during Tx */
+	unsigned int	       carrier;
+	unsigned int	       duty_cycle;
+};
+
+enum ir_kbd_get_key_fn {
+	IR_KBD_GET_KEY_CUSTOM = 0,
+	IR_KBD_GET_KEY_PIXELVIEW,
+	IR_KBD_GET_KEY_HAUP,
+	IR_KBD_GET_KEY_KNC1,
+	IR_KBD_GET_KEY_FUSIONHDTV,
+	IR_KBD_GET_KEY_HAUP_XVR,
+	IR_KBD_GET_KEY_AVERMEDIA_CARDBUS,
+};
+
+/* Can be passed when instantiating an ir_video i2c device */
+struct IR_i2c_init_data {
+	char			*ir_codes;
+	const char		*name;
+	u64			type; /* RC_PROTO_BIT_RC5, etc */
+	u32			polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */
+
+	/*
+	 * Specify either a function pointer or a value indicating one of
+	 * ir_kbd_i2c's internal get_key functions
+	 */
+	int                    (*get_key)(struct IR_i2c *ir,
+					  enum rc_proto *protocol,
+					  u32 *scancode, u8 *toggle);
+	enum ir_kbd_get_key_fn internal_get_key_func;
+
+	struct rc_dev		*rc_dev;
+};
+#endif
diff --git a/include/media/i2c/lm3560.h b/include/media/i2c/lm3560.h
new file mode 100644
index 0000000..0e2b1c7
--- /dev/null
+++ b/include/media/i2c/lm3560.h
@@ -0,0 +1,93 @@
+/*
+ * include/media/i2c/lm3560.h
+ *
+ * Copyright (C) 2013 Texas Instruments
+ *
+ * Contact: Daniel Jeong <gshark.jeong@gmail.com>
+ *			Ldd-Mlp <ldd-mlp@list.ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef __LM3560_H__
+#define __LM3560_H__
+
+#include <media/v4l2-subdev.h>
+
+#define LM3559_NAME	"lm3559"
+#define LM3560_NAME	"lm3560"
+#define LM3560_I2C_ADDR	(0x53)
+
+/*  FLASH Brightness
+ *	min 62500uA, step 62500uA, max 1000000uA
+ */
+#define LM3560_FLASH_BRT_MIN 62500
+#define LM3560_FLASH_BRT_STEP 62500
+#define LM3560_FLASH_BRT_MAX 1000000
+#define LM3560_FLASH_BRT_uA_TO_REG(a)	\
+	((a) < LM3560_FLASH_BRT_MIN ? 0 :	\
+	 (((a) - LM3560_FLASH_BRT_MIN) / LM3560_FLASH_BRT_STEP))
+#define LM3560_FLASH_BRT_REG_TO_uA(a)		\
+	((a) * LM3560_FLASH_BRT_STEP + LM3560_FLASH_BRT_MIN)
+
+/*  FLASH TIMEOUT DURATION
+ *	min 32ms, step 32ms, max 1024ms
+ */
+#define LM3560_FLASH_TOUT_MIN 32
+#define LM3560_FLASH_TOUT_STEP 32
+#define LM3560_FLASH_TOUT_MAX 1024
+#define LM3560_FLASH_TOUT_ms_TO_REG(a)	\
+	((a) < LM3560_FLASH_TOUT_MIN ? 0 :	\
+	 (((a) - LM3560_FLASH_TOUT_MIN) / LM3560_FLASH_TOUT_STEP))
+#define LM3560_FLASH_TOUT_REG_TO_ms(a)		\
+	((a) * LM3560_FLASH_TOUT_STEP + LM3560_FLASH_TOUT_MIN)
+
+/*  TORCH BRT
+ *	min 31250uA, step 31250uA, max 250000uA
+ */
+#define LM3560_TORCH_BRT_MIN 31250
+#define LM3560_TORCH_BRT_STEP 31250
+#define LM3560_TORCH_BRT_MAX 250000
+#define LM3560_TORCH_BRT_uA_TO_REG(a)	\
+	((a) < LM3560_TORCH_BRT_MIN ? 0 :	\
+	 (((a) - LM3560_TORCH_BRT_MIN) / LM3560_TORCH_BRT_STEP))
+#define LM3560_TORCH_BRT_REG_TO_uA(a)		\
+	((a) * LM3560_TORCH_BRT_STEP + LM3560_TORCH_BRT_MIN)
+
+enum lm3560_led_id {
+	LM3560_LED0 = 0,
+	LM3560_LED1,
+	LM3560_LED_MAX
+};
+
+enum lm3560_peak_current {
+	LM3560_PEAK_1600mA = 0x00,
+	LM3560_PEAK_2300mA = 0x20,
+	LM3560_PEAK_3000mA = 0x40,
+	LM3560_PEAK_3600mA = 0x60
+};
+
+/* struct lm3560_platform_data
+ *
+ * @peak :  peak current
+ * @max_flash_timeout: flash timeout
+ * @max_flash_brt: flash mode led brightness
+ * @max_torch_brt: torch mode led brightness
+ */
+struct lm3560_platform_data {
+	enum lm3560_peak_current peak;
+
+	u32 max_flash_timeout;
+	u32 max_flash_brt[LM3560_LED_MAX];
+	u32 max_torch_brt[LM3560_LED_MAX];
+};
+
+#endif /* __LM3560_H__ */
diff --git a/include/media/i2c/lm3646.h b/include/media/i2c/lm3646.h
new file mode 100644
index 0000000..724c100
--- /dev/null
+++ b/include/media/i2c/lm3646.h
@@ -0,0 +1,87 @@
+/*
+ * include/media/i2c/lm3646.h
+ *
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * Contact: Daniel Jeong <gshark.jeong@gmail.com>
+ *			Ldd-Mlp <ldd-mlp@list.ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef __LM3646_H__
+#define __LM3646_H__
+
+#include <media/v4l2-subdev.h>
+
+#define LM3646_NAME	"lm3646"
+#define LM3646_I2C_ADDR_REV1	(0x67)
+#define LM3646_I2C_ADDR_REV0	(0x63)
+
+/*  TOTAL FLASH Brightness Max
+ *	min 93350uA, step 93750uA, max 1499600uA
+ */
+#define LM3646_TOTAL_FLASH_BRT_MIN 93350
+#define LM3646_TOTAL_FLASH_BRT_STEP 93750
+#define LM3646_TOTAL_FLASH_BRT_MAX 1499600
+#define LM3646_TOTAL_FLASH_BRT_uA_TO_REG(a)	\
+	((a) < LM3646_TOTAL_FLASH_BRT_MIN ? 0 :	\
+	 ((((a) - LM3646_TOTAL_FLASH_BRT_MIN) / LM3646_TOTAL_FLASH_BRT_STEP)))
+
+/*  TOTAL TORCH Brightness Max
+ *	min 23040uA, step 23430uA, max 187100uA
+ */
+#define LM3646_TOTAL_TORCH_BRT_MIN 23040
+#define LM3646_TOTAL_TORCH_BRT_STEP 23430
+#define LM3646_TOTAL_TORCH_BRT_MAX 187100
+#define LM3646_TOTAL_TORCH_BRT_uA_TO_REG(a)	\
+	((a) < LM3646_TOTAL_TORCH_BRT_MIN ? 0 :	\
+	 ((((a) - LM3646_TOTAL_TORCH_BRT_MIN) / LM3646_TOTAL_TORCH_BRT_STEP)))
+
+/*  LED1 FLASH Brightness
+ *	min 23040uA, step 11718uA, max 1499600uA
+ */
+#define LM3646_LED1_FLASH_BRT_MIN 23040
+#define LM3646_LED1_FLASH_BRT_STEP 11718
+#define LM3646_LED1_FLASH_BRT_MAX 1499600
+#define LM3646_LED1_FLASH_BRT_uA_TO_REG(a)	\
+	((a) <= LM3646_LED1_FLASH_BRT_MIN ? 0 :	\
+	 ((((a) - LM3646_LED1_FLASH_BRT_MIN) / LM3646_LED1_FLASH_BRT_STEP))+1)
+
+/*  LED1 TORCH Brightness
+ *	min 2530uA, step 1460uA, max 187100uA
+ */
+#define LM3646_LED1_TORCH_BRT_MIN 2530
+#define LM3646_LED1_TORCH_BRT_STEP 1460
+#define LM3646_LED1_TORCH_BRT_MAX 187100
+#define LM3646_LED1_TORCH_BRT_uA_TO_REG(a)	\
+	((a) <= LM3646_LED1_TORCH_BRT_MIN ? 0 :	\
+	 ((((a) - LM3646_LED1_TORCH_BRT_MIN) / LM3646_LED1_TORCH_BRT_STEP))+1)
+
+/*  FLASH TIMEOUT DURATION
+ *	min 50ms, step 50ms, max 400ms
+ */
+#define LM3646_FLASH_TOUT_MIN 50
+#define LM3646_FLASH_TOUT_STEP 50
+#define LM3646_FLASH_TOUT_MAX 400
+#define LM3646_FLASH_TOUT_ms_TO_REG(a)	\
+	((a) <= LM3646_FLASH_TOUT_MIN ? 0 :	\
+	 (((a) - LM3646_FLASH_TOUT_MIN) / LM3646_FLASH_TOUT_STEP))
+
+/* struct lm3646_platform_data
+ *
+ * @flash_timeout: flash timeout
+ * @led1_flash_brt: led1 flash mode brightness, uA
+ * @led1_torch_brt: led1 torch mode brightness, uA
+ */
+struct lm3646_platform_data {
+
+	u32 flash_timeout;
+
+	u32 led1_flash_brt;
+	u32 led1_torch_brt;
+};
+
+#endif /* __LM3646_H__ */
diff --git a/include/media/i2c/m52790.h b/include/media/i2c/m52790.h
new file mode 100644
index 0000000..8d9db3c
--- /dev/null
+++ b/include/media/i2c/m52790.h
@@ -0,0 +1,93 @@
+/*
+    m52790.h - definition for m52790 inputs and outputs
+
+    Copyright (C) 2007 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _M52790_H_
+#define _M52790_H_
+
+/* Input routing switch 1 */
+
+#define M52790_SW1_IN_MASK	0x0003
+#define M52790_SW1_IN_TUNER	0x0000
+#define M52790_SW1_IN_V2	0x0001
+#define M52790_SW1_IN_V3	0x0002
+#define M52790_SW1_IN_V4	0x0003
+
+/* Selects component input instead of composite */
+#define M52790_SW1_YCMIX	0x0004
+
+
+/* Input routing switch 2 */
+
+#define M52790_SW2_IN_MASK	0x0300
+#define M52790_SW2_IN_TUNER	0x0000
+#define M52790_SW2_IN_V2	0x0100
+#define M52790_SW2_IN_V3	0x0200
+#define M52790_SW2_IN_V4	0x0300
+
+/* Selects component input instead of composite */
+#define M52790_SW2_YCMIX	0x0400
+
+
+/* Output routing switch 1 */
+
+/* Enable 6dB amplifier for composite out */
+#define M52790_SW1_V_AMP	0x0008
+
+/* Enable 6dB amplifier for component out */
+#define M52790_SW1_YC_AMP	0x0010
+
+/* Audio output mode */
+#define M52790_SW1_AUDIO_MASK	0x00c0
+#define M52790_SW1_AUDIO_MUTE	0x0000
+#define M52790_SW1_AUDIO_R	0x0040
+#define M52790_SW1_AUDIO_L	0x0080
+#define M52790_SW1_AUDIO_STEREO 0x00c0
+
+
+/* Output routing switch 2 */
+
+/* Enable 6dB amplifier for composite out */
+#define M52790_SW2_V_AMP	0x0800
+
+/* Enable 6dB amplifier for component out */
+#define M52790_SW2_YC_AMP	0x1000
+
+/* Audio output mode */
+#define M52790_SW2_AUDIO_MASK	0xc000
+#define M52790_SW2_AUDIO_MUTE	0x0000
+#define M52790_SW2_AUDIO_R	0x4000
+#define M52790_SW2_AUDIO_L	0x8000
+#define M52790_SW2_AUDIO_STEREO 0xc000
+
+
+/* Common values */
+#define M52790_IN_TUNER (M52790_SW1_IN_TUNER | M52790_SW2_IN_TUNER)
+#define M52790_IN_V2    (M52790_SW1_IN_V2 | M52790_SW2_IN_V2)
+#define M52790_IN_V3    (M52790_SW1_IN_V3 | M52790_SW2_IN_V3)
+#define M52790_IN_V4    (M52790_SW1_IN_V4 | M52790_SW2_IN_V4)
+
+#define M52790_OUT_STEREO	(M52790_SW1_AUDIO_STEREO | \
+				 M52790_SW2_AUDIO_STEREO)
+#define M52790_OUT_AMP_STEREO	(M52790_SW1_AUDIO_STEREO | \
+				 M52790_SW1_V_AMP | \
+				 M52790_SW2_AUDIO_STEREO | \
+				 M52790_SW2_V_AMP)
+
+#endif
diff --git a/include/media/i2c/m5mols.h b/include/media/i2c/m5mols.h
new file mode 100644
index 0000000..4a825ae
--- /dev/null
+++ b/include/media/i2c/m5mols.h
@@ -0,0 +1,33 @@
+/*
+ * Driver header for M-5MOLS 8M Pixel camera sensor with ISP
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ * Copyright (C) 2009 Samsung Electronics Co., Ltd.
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef MEDIA_M5MOLS_H
+#define MEDIA_M5MOLS_H
+
+/**
+ * struct m5mols_platform_data - platform data for M-5MOLS driver
+ * @gpio_reset:	GPIO driving the reset pin of M-5MOLS
+ * @reset_polarity: active state for gpio_reset pin, 0 or 1
+ * @set_power:	an additional callback to the board setup code
+ *		to be called after enabling and before disabling
+ *		the sensor's supply regulators
+ */
+struct m5mols_platform_data {
+	int gpio_reset;
+	u8 reset_polarity;
+	int (*set_power)(struct device *dev, int on);
+};
+
+#endif	/* MEDIA_M5MOLS_H */
diff --git a/include/media/i2c/mt9m032.h b/include/media/i2c/mt9m032.h
new file mode 100644
index 0000000..30d02a1
--- /dev/null
+++ b/include/media/i2c/mt9m032.h
@@ -0,0 +1,31 @@
+/*
+ * Driver for MT9M032 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2010-2011 Lund Engineering
+ * Contact: Gil Lund <gwlund@lundeng.com>
+ * Author: Martin Hostettler <martin@neutronstar.dyndns.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef MT9M032_H
+#define MT9M032_H
+
+#define MT9M032_NAME		"mt9m032"
+#define MT9M032_I2C_ADDR	(0xb8 >> 1)
+
+struct mt9m032_platform_data {
+	u32 ext_clock;
+	u32 pix_clock;
+	bool invert_pixclock;
+
+};
+#endif /* MT9M032_H */
diff --git a/include/media/i2c/mt9p031.h b/include/media/i2c/mt9p031.h
new file mode 100644
index 0000000..7c29c53
--- /dev/null
+++ b/include/media/i2c/mt9p031.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef MT9P031_H
+#define MT9P031_H
+
+struct v4l2_subdev;
+
+/*
+ * struct mt9p031_platform_data - MT9P031 platform data
+ * @ext_freq: Input clock frequency
+ * @target_freq: Pixel clock frequency
+ */
+struct mt9p031_platform_data {
+	int ext_freq;
+	int target_freq;
+};
+
+#endif
diff --git a/include/media/i2c/mt9t001.h b/include/media/i2c/mt9t001.h
new file mode 100644
index 0000000..4b10905
--- /dev/null
+++ b/include/media/i2c/mt9t001.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _MEDIA_MT9T001_H
+#define _MEDIA_MT9T001_H
+
+struct mt9t001_platform_data {
+	unsigned int clk_pol:1;
+	unsigned int ext_clk;
+};
+
+#endif
diff --git a/include/media/i2c/mt9t112.h b/include/media/i2c/mt9t112.h
new file mode 100644
index 0000000..cc80d5c
--- /dev/null
+++ b/include/media/i2c/mt9t112.h
@@ -0,0 +1,27 @@
+/*  SPDX-License-Identifier: GPL-2.0 */
+/* mt9t112 Camera
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ */
+
+#ifndef __MT9T112_H__
+#define __MT9T112_H__
+
+struct mt9t112_pll_divider {
+	u8 m, n;
+	u8 p1, p2, p3, p4, p5, p6, p7;
+};
+
+/**
+ * mt9t112_platform_data -	mt9t112 driver interface
+ * @flags:			Sensor media bus configuration.
+ * @divider:			Sensor PLL configuration
+ */
+struct mt9t112_platform_data {
+#define MT9T112_FLAG_PCLK_RISING_EDGE	BIT(0)
+	u32 flags;
+	struct mt9t112_pll_divider divider;
+};
+
+#endif /* __MT9T112_H__ */
diff --git a/include/media/i2c/mt9v011.h b/include/media/i2c/mt9v011.h
new file mode 100644
index 0000000..ea29fc7
--- /dev/null
+++ b/include/media/i2c/mt9v011.h
@@ -0,0 +1,17 @@
+/* mt9v011 sensor
+ *
+ * Copyright (C) 2011 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MT9V011_H__
+#define __MT9V011_H__
+
+struct mt9v011_platform_data {
+	unsigned xtal;	/* Hz */
+};
+
+#endif
diff --git a/include/media/i2c/mt9v022.h b/include/media/i2c/mt9v022.h
new file mode 100644
index 0000000..4056180
--- /dev/null
+++ b/include/media/i2c/mt9v022.h
@@ -0,0 +1,16 @@
+/*
+ * mt9v022 sensor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MT9V022_H__
+#define __MT9V022_H__
+
+struct mt9v022_platform_data {
+	unsigned short y_skip_top;	/* Lines to skip at the top */
+};
+
+#endif
diff --git a/include/media/i2c/mt9v032.h b/include/media/i2c/mt9v032.h
new file mode 100644
index 0000000..83a37cc
--- /dev/null
+++ b/include/media/i2c/mt9v032.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _MEDIA_MT9V032_H
+#define _MEDIA_MT9V032_H
+
+struct mt9v032_platform_data {
+	unsigned int clk_pol:1;
+
+	const s64 *link_freqs;
+	s64 link_def_freq;
+};
+
+#endif
diff --git a/include/media/i2c/noon010pc30.h b/include/media/i2c/noon010pc30.h
new file mode 100644
index 0000000..58eafee
--- /dev/null
+++ b/include/media/i2c/noon010pc30.h
@@ -0,0 +1,28 @@
+/*
+ * Driver header for NOON010PC30L camera sensor chip.
+ *
+ * Copyright (c) 2010 Samsung Electronics, Co. Ltd
+ * Contact: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef NOON010PC30_H
+#define NOON010PC30_H
+
+/**
+ * @clk_rate: the clock frequency in Hz
+ * @gpio_nreset: GPIO driving nRESET pin
+ * @gpio_nstby: GPIO driving nSTBY pin
+ */
+
+struct noon010pc30_platform_data {
+	unsigned long clk_rate;
+	int gpio_nreset;
+	int gpio_nstby;
+};
+
+#endif /* NOON010PC30_H */
diff --git a/include/media/i2c/ov2659.h b/include/media/i2c/ov2659.h
new file mode 100644
index 0000000..4216adc
--- /dev/null
+++ b/include/media/i2c/ov2659.h
@@ -0,0 +1,34 @@
+/*
+ * Omnivision OV2659 CMOS Image Sensor driver
+ *
+ * Copyright (C) 2015 Texas Instruments, Inc.
+ *
+ * Benoit Parrot <bparrot@ti.com>
+ * Lad, Prabhakar <prabhakar.csengg@gmail.com>
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef OV2659_H
+#define OV2659_H
+
+/**
+ * struct ov2659_platform_data - ov2659 driver platform data
+ * @link_frequency: target pixel clock frequency
+ */
+struct ov2659_platform_data {
+	s64 link_frequency;
+};
+
+#endif /* OV2659_H */
diff --git a/include/media/i2c/ov7670.h b/include/media/i2c/ov7670.h
new file mode 100644
index 0000000..1913d51
--- /dev/null
+++ b/include/media/i2c/ov7670.h
@@ -0,0 +1,22 @@
+/*
+ * A V4L2 driver for OmniVision OV7670 cameras.
+ *
+ * Copyright 2010 One Laptop Per Child
+ *
+ * This file may be distributed under the terms of the GNU General
+ * Public License, version 2.
+ */
+
+#ifndef __OV7670_H
+#define __OV7670_H
+
+struct ov7670_config {
+	int min_width;			/* Filter out smaller sizes */
+	int min_height;			/* Filter out smaller sizes */
+	int clock_speed;		/* External clock speed (MHz) */
+	bool use_smbus;			/* Use smbus I/O instead of I2C */
+	bool pll_bypass;		/* Choose whether to bypass the PLL */
+	bool pclk_hb_disable;		/* Disable toggling pixclk during horizontal blanking */
+};
+
+#endif
diff --git a/include/media/i2c/ov772x.h b/include/media/i2c/ov772x.h
new file mode 100644
index 0000000..27d087b
--- /dev/null
+++ b/include/media/i2c/ov772x.h
@@ -0,0 +1,61 @@
+/*
+ * ov772x Camera
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __OV772X_H__
+#define __OV772X_H__
+
+/* for flags */
+#define OV772X_FLAG_VFLIP	(1 << 0) /* Vertical flip image */
+#define OV772X_FLAG_HFLIP	(1 << 1) /* Horizontal flip image */
+
+/*
+ * for Edge ctrl
+ *
+ * strength also control Auto or Manual Edge Control Mode
+ * see also OV772X_MANUAL_EDGE_CTRL
+ */
+struct ov772x_edge_ctrl {
+	unsigned char strength;
+	unsigned char threshold;
+	unsigned char upper;
+	unsigned char lower;
+};
+
+#define OV772X_MANUAL_EDGE_CTRL		0x80 /* un-used bit of strength */
+#define OV772X_EDGE_STRENGTH_MASK	0x1F
+#define OV772X_EDGE_THRESHOLD_MASK	0x0F
+#define OV772X_EDGE_UPPER_MASK		0xFF
+#define OV772X_EDGE_LOWER_MASK		0xFF
+
+#define OV772X_AUTO_EDGECTRL(u, l)	\
+{					\
+	.upper = (u & OV772X_EDGE_UPPER_MASK),	\
+	.lower = (l & OV772X_EDGE_LOWER_MASK),	\
+}
+
+#define OV772X_MANUAL_EDGECTRL(s, t)			\
+{							\
+	.strength  = (s & OV772X_EDGE_STRENGTH_MASK) |	\
+			OV772X_MANUAL_EDGE_CTRL,	\
+	.threshold = (t & OV772X_EDGE_THRESHOLD_MASK),	\
+}
+
+/**
+ * ov772x_camera_info -	ov772x driver interface structure
+ * @flags:		Sensor configuration flags
+ * @edgectrl:		Sensor edge control
+ */
+struct ov772x_camera_info {
+	unsigned long		flags;
+	struct ov772x_edge_ctrl	edgectrl;
+};
+
+#endif /* __OV772X_H__ */
diff --git a/include/media/i2c/ov9650.h b/include/media/i2c/ov9650.h
new file mode 100644
index 0000000..d630cf9
--- /dev/null
+++ b/include/media/i2c/ov9650.h
@@ -0,0 +1,27 @@
+/*
+ * OV9650/OV9652 camera sensors driver
+ *
+ * Copyright (C) 2013 Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef OV9650_H_
+#define OV9650_H_
+
+/**
+ * struct ov9650_platform_data - ov9650 driver platform data
+ * @mclk_frequency: the sensor's master clock frequency in Hz
+ * @gpio_pwdn:	    number of a GPIO connected to OV965X PWDN pin
+ * @gpio_reset:     number of a GPIO connected to OV965X RESET pin
+ *
+ * If any of @gpio_pwdn or @gpio_reset are unused then they should be
+ * set to a negative value. @mclk_frequency must always be specified.
+ */
+struct ov9650_platform_data {
+	unsigned long mclk_frequency;
+	int gpio_pwdn;
+	int gpio_reset;
+};
+#endif /* OV9650_H_ */
diff --git a/include/media/i2c/rj54n1cb0c.h b/include/media/i2c/rj54n1cb0c.h
new file mode 100644
index 0000000..8ae3288
--- /dev/null
+++ b/include/media/i2c/rj54n1cb0c.h
@@ -0,0 +1,19 @@
+/*
+ * RJ54N1CB0C Private data
+ *
+ * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RJ54N1CB0C_H__
+#define __RJ54N1CB0C_H__
+
+struct rj54n1_pdata {
+	unsigned int	mclk_freq;
+	bool		ioctl_high;
+};
+
+#endif
diff --git a/include/media/i2c/s5c73m3.h b/include/media/i2c/s5c73m3.h
new file mode 100644
index 0000000..ccb9e54
--- /dev/null
+++ b/include/media/i2c/s5c73m3.h
@@ -0,0 +1,55 @@
+/*
+ * Samsung LSI S5C73M3 8M pixel camera driver
+ *
+ * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Andrzej Hajda <a.hajda@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef MEDIA_S5C73M3__
+#define MEDIA_S5C73M3__
+
+#include <linux/videodev2.h>
+#include <media/v4l2-mediabus.h>
+
+/**
+ * struct s5c73m3_gpio - data structure describing a GPIO
+ * @gpio:  GPIO number
+ * @level: indicates active state of the @gpio
+ */
+struct s5c73m3_gpio {
+	int gpio;
+	int level;
+};
+
+/**
+ * struct s5c73m3_platform_data - s5c73m3 driver platform data
+ * @mclk_frequency: sensor's master clock frequency in Hz
+ * @gpio_reset:  GPIO driving RESET pin
+ * @gpio_stby:   GPIO driving STBY pin
+ * @nlanes:      maximum number of MIPI-CSI lanes used
+ * @horiz_flip:  default horizontal image flip value, non zero to enable
+ * @vert_flip:   default vertical image flip value, non zero to enable
+ */
+
+struct s5c73m3_platform_data {
+	unsigned long mclk_frequency;
+
+	struct s5c73m3_gpio gpio_reset;
+	struct s5c73m3_gpio gpio_stby;
+
+	enum v4l2_mbus_type bus_type;
+	u8 nlanes;
+	u8 horiz_flip;
+	u8 vert_flip;
+};
+
+#endif /* MEDIA_S5C73M3__ */
diff --git a/include/media/i2c/s5k4ecgx.h b/include/media/i2c/s5k4ecgx.h
new file mode 100644
index 0000000..90c1be7
--- /dev/null
+++ b/include/media/i2c/s5k4ecgx.h
@@ -0,0 +1,37 @@
+/*
+ * S5K4ECGX image sensor header file
+ *
+ * Copyright (C) 2012, Linaro
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5K4ECGX_H
+#define S5K4ECGX_H
+
+/**
+ * struct s5k4ecgx_gpio - data structure describing a GPIO
+ * @gpio : GPIO number
+ * @level: indicates active state of the @gpio
+ */
+struct s5k4ecgx_gpio {
+	int gpio;
+	int level;
+};
+
+/**
+ * struct ss5k4ecgx_platform_data- s5k4ecgx driver platform data
+ * @gpio_reset:	 GPIO driving RESET pin
+ * @gpio_stby :	 GPIO driving STBY pin
+ */
+
+struct s5k4ecgx_platform_data {
+	struct s5k4ecgx_gpio gpio_reset;
+	struct s5k4ecgx_gpio gpio_stby;
+};
+
+#endif /* S5K4ECGX_H */
diff --git a/include/media/i2c/s5k6aa.h b/include/media/i2c/s5k6aa.h
new file mode 100644
index 0000000..ba34f70
--- /dev/null
+++ b/include/media/i2c/s5k6aa.h
@@ -0,0 +1,51 @@
+/*
+ * S5K6AAFX camera sensor driver header
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef S5K6AA_H
+#define S5K6AA_H
+
+#include <media/v4l2-mediabus.h>
+
+/**
+ * struct s5k6aa_gpio - data structure describing a GPIO
+ * @gpio:  GPIO number
+ * @level: indicates active state of the @gpio
+ */
+struct s5k6aa_gpio {
+	int gpio;
+	int level;
+};
+
+/**
+ * struct s5k6aa_platform_data - s5k6aa driver platform data
+ * @set_power:   an additional callback to the board code, called
+ *               after enabling the regulators and before switching
+ *               the sensor off
+ * @mclk_frequency: sensor's master clock frequency in Hz
+ * @gpio_reset:  GPIO driving RESET pin
+ * @gpio_stby:   GPIO driving STBY pin
+ * @nlanes:      maximum number of MIPI-CSI lanes used
+ * @horiz_flip:  default horizontal image flip value, non zero to enable
+ * @vert_flip:   default vertical image flip value, non zero to enable
+ */
+
+struct s5k6aa_platform_data {
+	int (*set_power)(int enable);
+	unsigned long mclk_frequency;
+	struct s5k6aa_gpio gpio_reset;
+	struct s5k6aa_gpio gpio_stby;
+	enum v4l2_mbus_type bus_type;
+	u8 nlanes;
+	u8 horiz_flip;
+	u8 vert_flip;
+};
+
+#endif /* S5K6AA_H */
diff --git a/include/media/i2c/saa6588.h b/include/media/i2c/saa6588.h
new file mode 100644
index 0000000..a0825f5
--- /dev/null
+++ b/include/media/i2c/saa6588.h
@@ -0,0 +1,43 @@
+/*
+
+    Types and defines needed for RDS. This is included by
+    saa6588.c and every driver (e.g. bttv-driver.c) that wants
+    to use the saa6588 module.
+
+    (c) 2005 by Hans J. Koch
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _SAA6588_H
+#define _SAA6588_H
+
+struct saa6588_command {
+	unsigned int  block_count;
+	bool          nonblocking;
+	int           result;
+	unsigned char __user *buffer;
+	struct file   *instance;
+	poll_table    *event_list;
+	__poll_t      poll_mask;
+};
+
+/* These ioctls are internal to the kernel */
+#define SAA6588_CMD_CLOSE	_IOW('R', 2, int)
+#define SAA6588_CMD_READ	_IOR('R', 3, int)
+#define SAA6588_CMD_POLL	_IOR('R', 4, int)
+
+#endif
diff --git a/include/media/i2c/saa7115.h b/include/media/i2c/saa7115.h
new file mode 100644
index 0000000..a0cda42
--- /dev/null
+++ b/include/media/i2c/saa7115.h
@@ -0,0 +1,140 @@
+/*
+    saa7115.h - definition for saa7111/3/4/5 inputs and frequency flags
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SAA7115_H_
+#define _SAA7115_H_
+
+/* s_routing inputs, outputs, and config */
+
+/* SAA7111/3/4/5 HW inputs */
+#define SAA7115_COMPOSITE0 0
+#define SAA7115_COMPOSITE1 1
+#define SAA7115_COMPOSITE2 2
+#define SAA7115_COMPOSITE3 3
+#define SAA7115_COMPOSITE4 4 /* not available for the saa7111/3 */
+#define SAA7115_COMPOSITE5 5 /* not available for the saa7111/3 */
+#define SAA7115_SVIDEO0    6
+#define SAA7115_SVIDEO1    7
+#define SAA7115_SVIDEO2    8
+#define SAA7115_SVIDEO3    9
+
+/* outputs */
+#define SAA7115_IPORT_ON	1
+#define SAA7115_IPORT_OFF	0
+
+/* SAA7111 specific outputs. */
+#define SAA7111_VBI_BYPASS	2
+#define SAA7111_FMT_YUV422      0x00
+#define SAA7111_FMT_RGB		0x40
+#define SAA7111_FMT_CCIR	0x80
+#define SAA7111_FMT_YUV411	0xc0
+
+/* config flags */
+/*
+ * Register 0x85 should set bit 0 to 0 (it's 1 by default). This bit
+ * controls the IDQ signal polarity which is set to 'inverted' if the bit
+ * it 1 and to 'default' if it is 0.
+ */
+#define SAA7115_IDQ_IS_DEFAULT  (1 << 0)
+
+/* s_crystal_freq values and flags */
+
+/* SAA7115 v4l2_crystal_freq frequency values */
+#define SAA7115_FREQ_32_11_MHZ  32110000   /* 32.11 MHz crystal, SAA7114/5 only */
+#define SAA7115_FREQ_24_576_MHZ 24576000   /* 24.576 MHz crystal */
+
+/* SAA7115 v4l2_crystal_freq audio clock control flags */
+#define SAA7115_FREQ_FL_UCGC         (1 << 0) /* SA 3A[7], UCGC, SAA7115 only */
+#define SAA7115_FREQ_FL_CGCDIV       (1 << 1) /* SA 3A[6], CGCDIV, SAA7115 only */
+#define SAA7115_FREQ_FL_APLL         (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */
+#define SAA7115_FREQ_FL_DOUBLE_ASCLK (1 << 3) /* SA 39, LRDIV, SAA7114/5 only */
+
+/* ===== SAA7113 Config enums ===== */
+
+/* Register 0x08 "Horizontal time constant" [Bit 3..4]:
+ * Should be set to "Fast Locking Mode" according to the datasheet,
+ * and that is the default setting in the gm7113c_init table.
+ * saa7113_init sets this value to "VTR Mode". */
+enum saa7113_r08_htc {
+	SAA7113_HTC_TV_MODE = 0x00,
+	SAA7113_HTC_VTR_MODE,			/* Default for saa7113_init */
+	SAA7113_HTC_FAST_LOCKING_MODE = 0x03	/* Default for gm7113c_init */
+};
+
+/* Register 0x10 "Output format selection" [Bit 6..7]:
+ * Defaults to ITU_656 as specified in datasheet. */
+enum saa7113_r10_ofts {
+	SAA7113_OFTS_ITU_656 = 0x0,	/* Default */
+	SAA7113_OFTS_VFLAG_BY_VREF,
+	SAA7113_OFTS_VFLAG_BY_DATA_TYPE
+};
+
+/*
+ * Register 0x12 "Output control" [Bit 0..3 Or Bit 4..7]:
+ * This is used to select what data is output on the RTS0 and RTS1 pins.
+ * RTS1 [Bit 4..7] Defaults to DOT_IN. (This value can not be set for RTS0)
+ * RTS0 [Bit 0..3] Defaults to VIPB in gm7113c_init as specified
+ * in the datasheet, but is set to HREF_HS in the saa7113_init table.
+ */
+enum saa7113_r12_rts {
+	SAA7113_RTS_DOT_IN = 0,		/* OBS: Only for RTS1 (Default RTS1) */
+	SAA7113_RTS_VIPB,		/* Default RTS0 For gm7113c_init */
+	SAA7113_RTS_GPSW,
+	SAA7115_RTS_HL,
+	SAA7113_RTS_VL,
+	SAA7113_RTS_DL,
+	SAA7113_RTS_PLIN,
+	SAA7113_RTS_HREF_HS,		/* Default RTS0 For saa7113_init */
+	SAA7113_RTS_HS,
+	SAA7113_RTS_HQ,
+	SAA7113_RTS_ODD,
+	SAA7113_RTS_VS,
+	SAA7113_RTS_V123,
+	SAA7113_RTS_VGATE,
+	SAA7113_RTS_VREF,
+	SAA7113_RTS_FID
+};
+
+/**
+ * struct saa7115_platform_data - Allow overriding default initialization
+ *
+ * @saa7113_force_gm7113c_init:	Force the use of the gm7113c_init table
+ *				instead of saa7113_init table
+ *				(saa7113 only)
+ * @saa7113_r08_htc:		[R_08 - Bit 3..4]
+ * @saa7113_r10_vrln:		[R_10 - Bit 3]
+ *				default: Disabled for gm7113c_init
+ *					 Enabled for saa7113c_init
+ * @saa7113_r10_ofts:		[R_10 - Bit 6..7]
+ * @saa7113_r12_rts0:		[R_12 - Bit 0..3]
+ * @saa7113_r12_rts1:		[R_12 - Bit 4..7]
+ * @saa7113_r13_adlsb:		[R_13 - Bit 7] - default: disabled
+ */
+struct saa7115_platform_data {
+	bool saa7113_force_gm7113c_init;
+	enum saa7113_r08_htc *saa7113_r08_htc;
+	bool *saa7113_r10_vrln;
+	enum saa7113_r10_ofts *saa7113_r10_ofts;
+	enum saa7113_r12_rts *saa7113_r12_rts0;
+	enum saa7113_r12_rts *saa7113_r12_rts1;
+	bool *saa7113_r13_adlsb;
+};
+
+#endif
diff --git a/include/media/i2c/saa7127.h b/include/media/i2c/saa7127.h
new file mode 100644
index 0000000..7005ba7
--- /dev/null
+++ b/include/media/i2c/saa7127.h
@@ -0,0 +1,40 @@
+/*
+    saa7127.h - definition for saa7126/7/8/9 inputs/outputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SAA7127_H_
+#define _SAA7127_H_
+
+/* Enumeration for the supported input types */
+enum saa7127_input_type {
+	SAA7127_INPUT_TYPE_NORMAL,
+	SAA7127_INPUT_TYPE_TEST_IMAGE
+};
+
+/* Enumeration for the supported output signal types */
+enum saa7127_output_type {
+	SAA7127_OUTPUT_TYPE_BOTH,
+	SAA7127_OUTPUT_TYPE_COMPOSITE,
+	SAA7127_OUTPUT_TYPE_SVIDEO,
+	SAA7127_OUTPUT_TYPE_RGB,
+	SAA7127_OUTPUT_TYPE_YUV_C,
+	SAA7127_OUTPUT_TYPE_YUV_V
+};
+
+#endif
diff --git a/include/media/i2c/smiapp.h b/include/media/i2c/smiapp.h
new file mode 100644
index 0000000..525d55b
--- /dev/null
+++ b/include/media/i2c/smiapp.h
@@ -0,0 +1,73 @@
+/*
+ * include/media/i2c/smiapp.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011--2012 Nokia Corporation
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef __SMIAPP_H_
+#define __SMIAPP_H_
+
+#include <media/v4l2-subdev.h>
+
+#define SMIAPP_NAME		"smiapp"
+
+#define SMIAPP_DFL_I2C_ADDR	(0x20 >> 1) /* Default I2C Address */
+#define SMIAPP_ALT_I2C_ADDR	(0x6e >> 1) /* Alternate I2C Address */
+
+#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK	0
+#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE	1
+#define SMIAPP_CSI_SIGNALLING_MODE_CSI2			2
+
+/*
+ * Sometimes due to board layout considerations the camera module can be
+ * mounted rotated. The typical rotation used is 180 degrees which can be
+ * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
+ * FIXME: rotation also changes the bayer pattern.
+ */
+enum smiapp_module_board_orient {
+	SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
+	SMIAPP_MODULE_BOARD_ORIENT_180,
+};
+
+struct smiapp_flash_strobe_parms {
+	u8 mode;
+	u32 strobe_width_high_us;
+	u16 strobe_delay;
+	u16 stobe_start_point;
+	u8 trigger;
+};
+
+struct smiapp_hwconfig {
+	/*
+	 * Change the cci address if i2c_addr_alt is set.
+	 * Both default and alternate cci addr need to be present
+	 */
+	unsigned short i2c_addr_dfl;	/* Default i2c addr */
+	unsigned short i2c_addr_alt;	/* Alternate i2c addr */
+
+	uint32_t nvm_size;		/* bytes */
+	uint32_t ext_clk;		/* sensor external clk */
+
+	unsigned int lanes;		/* Number of CSI-2 lanes */
+	uint32_t csi_signalling_mode;	/* SMIAPP_CSI_SIGNALLING_MODE_* */
+	uint64_t *op_sys_clock;
+
+	enum smiapp_module_board_orient module_board_orient;
+
+	struct smiapp_flash_strobe_parms *strobe_setup;
+};
+
+#endif /* __SMIAPP_H_  */
diff --git a/include/media/i2c/sr030pc30.h b/include/media/i2c/sr030pc30.h
new file mode 100644
index 0000000..6f901a6
--- /dev/null
+++ b/include/media/i2c/sr030pc30.h
@@ -0,0 +1,21 @@
+/*
+ * Driver header for SR030PC30 camera sensor
+ *
+ * Copyright (c) 2010 Samsung Electronics, Co. Ltd
+ * Contact: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef SR030PC30_H
+#define SR030PC30_H
+
+struct sr030pc30_platform_data {
+	unsigned long clk_rate;	/* master clock frequency in Hz */
+	int (*set_power)(struct device *dev, int on);
+};
+
+#endif /* SR030PC30_H */
diff --git a/include/media/i2c/tc358743.h b/include/media/i2c/tc358743.h
new file mode 100644
index 0000000..b343650
--- /dev/null
+++ b/include/media/i2c/tc358743.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tc358743 - Toshiba HDMI to CSI-2 bridge
+ *
+ * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * References (c = chapter, p = page):
+ * REF_01 - Toshiba, TC358743XBG (H2C), Functional Specification, Rev 0.60
+ * REF_02 - Toshiba, TC358743XBG_HDMI-CSI_Tv11p_nm.xls
+ */
+
+#ifndef _TC358743_
+#define _TC358743_
+
+enum tc358743_ddc5v_delays {
+	DDC5V_DELAY_0_MS,
+	DDC5V_DELAY_50_MS,
+	DDC5V_DELAY_100_MS,
+	DDC5V_DELAY_200_MS,
+};
+
+enum tc358743_hdmi_detection_delay {
+	HDMI_MODE_DELAY_0_MS,
+	HDMI_MODE_DELAY_25_MS,
+	HDMI_MODE_DELAY_50_MS,
+	HDMI_MODE_DELAY_100_MS,
+};
+
+struct tc358743_platform_data {
+	/* System clock connected to REFCLK (pin H5) */
+	u32 refclk_hz; /* 26 MHz, 27 MHz or 42 MHz */
+
+	/* DDC +5V debounce delay to avoid spurious interrupts when the cable
+	 * is connected.
+	 * Sets DDC5V_MODE in register DDC_CTL.
+	 * Default: DDC5V_DELAY_0_MS
+	 */
+	enum tc358743_ddc5v_delays ddc5v_delay;
+
+	bool enable_hdcp;
+
+	/*
+	 * The FIFO size is 512x32, so Toshiba recommend to set the default FIFO
+	 * level to somewhere in the middle (e.g. 300), so it can cover speed
+	 * mismatches in input and output ports.
+	 */
+	u16 fifo_level;
+
+	/* Bps pr lane is (refclk_hz / pll_prd) * pll_fbd */
+	u16 pll_prd;
+	u16 pll_fbd;
+
+	/* CSI
+	 * Calculate CSI parameters with REF_02 for the highest resolution your
+	 * CSI interface can handle. The driver will adjust the number of CSI
+	 * lanes in use according to the pixel clock.
+	 *
+	 * The values in brackets are calculated with REF_02 when the number of
+	 * bps pr lane is 823.5 MHz, and can serve as a starting point.
+	 */
+	u32 lineinitcnt;	/* (0x00001770) */
+	u32 lptxtimecnt;	/* (0x00000005) */
+	u32 tclk_headercnt;	/* (0x00001d04) */
+	u32 tclk_trailcnt;	/* (0x00000000) */
+	u32 ths_headercnt;	/* (0x00000505) */
+	u32 twakeup;		/* (0x00004650) */
+	u32 tclk_postcnt;	/* (0x00000000) */
+	u32 ths_trailcnt;	/* (0x00000004) */
+	u32 hstxvregcnt;	/* (0x00000005) */
+
+	/* DVI->HDMI detection delay to avoid unnecessary switching between DVI
+	 * and HDMI mode.
+	 * Sets HDMI_DET_V in register HDMI_DET.
+	 * Default: HDMI_MODE_DELAY_0_MS
+	 */
+	enum tc358743_hdmi_detection_delay hdmi_detection_delay;
+
+	/* Reset PHY automatically when TMDS clock goes from DC to AC.
+	 * Sets PHY_AUTO_RST2 in register PHY_CTL2.
+	 * Default: false
+	 */
+	bool hdmi_phy_auto_reset_tmds_detected;
+
+	/* Reset PHY automatically when TMDS clock passes 21 MHz.
+	 * Sets PHY_AUTO_RST3 in register PHY_CTL2.
+	 * Default: false
+	 */
+	bool hdmi_phy_auto_reset_tmds_in_range;
+
+	/* Reset PHY automatically when TMDS clock is detected.
+	 * Sets PHY_AUTO_RST4 in register PHY_CTL2.
+	 * Default: false
+	 */
+	bool hdmi_phy_auto_reset_tmds_valid;
+
+	/* Reset HDMI PHY automatically when hsync period is out of range.
+	 * Sets H_PI_RST in register HV_RST.
+	 * Default: false
+	 */
+	bool hdmi_phy_auto_reset_hsync_out_of_range;
+
+	/* Reset HDMI PHY automatically when vsync period is out of range.
+	 * Sets V_PI_RST in register HV_RST.
+	 * Default: false
+	 */
+	bool hdmi_phy_auto_reset_vsync_out_of_range;
+};
+
+/* custom controls */
+/* Audio sample rate in Hz */
+#define TC358743_CID_AUDIO_SAMPLING_RATE (V4L2_CID_USER_TC358743_BASE + 0)
+/* Audio present status */
+#define TC358743_CID_AUDIO_PRESENT       (V4L2_CID_USER_TC358743_BASE + 1)
+
+#endif
diff --git a/include/media/i2c/tda1997x.h b/include/media/i2c/tda1997x.h
new file mode 100644
index 0000000..c6c2a8a
--- /dev/null
+++ b/include/media/i2c/tda1997x.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * tda1997x - NXP HDMI receiver
+ *
+ * Copyright 2017 Tim Harvey <tharvey@gateworks.com>
+ *
+ */
+
+#ifndef _TDA1997X_
+#define _TDA1997X_
+
+/* Platform Data */
+struct tda1997x_platform_data {
+	enum v4l2_mbus_type vidout_bus_type;
+	u32 vidout_bus_width;
+	u8 vidout_port_cfg[9];
+	/* pin polarity (1=invert) */
+	bool vidout_inv_de;
+	bool vidout_inv_hs;
+	bool vidout_inv_vs;
+	bool vidout_inv_pclk;
+	/* clock delays (0=-8, 1=-7 ... 15=+7 pixels) */
+	u8 vidout_delay_hs;
+	u8 vidout_delay_vs;
+	u8 vidout_delay_de;
+	u8 vidout_delay_pclk;
+	/* sync selections (controls how sync pins are derived) */
+	u8 vidout_sel_hs;
+	u8 vidout_sel_vs;
+	u8 vidout_sel_de;
+
+	/* Audio Port Output */
+	int audout_format;
+	u32 audout_mclk_fs;	/* clock multiplier */
+	u32 audout_width;	/* 13 or 32 bit */
+	u32 audout_layout;	/* layout0=AP0 layout1=AP0,AP1,AP2,AP3 */
+	bool audout_layoutauto;	/* audio layout dictated by pkt header */
+	bool audout_invert_clk;	/* data valid on rising edge of BCLK */
+	bool audio_auto_mute;	/* enable hardware audio auto-mute */
+};
+
+#endif
diff --git a/include/media/i2c/ths7303.h b/include/media/i2c/ths7303.h
new file mode 100644
index 0000000..95492d1
--- /dev/null
+++ b/include/media/i2c/ths7303.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Texas Instruments Inc
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * Contributors:
+ *     Hans Verkuil <hans.verkuil@cisco.com>
+ *     Lad, Prabhakar <prabhakar.lad@ti.com>
+ *     Martin Bugge <marbugge@cisco.com>
+ */
+
+#ifndef THS7353_H
+#define THS7353_H
+
+/**
+ * struct ths7303_platform_data - Platform dependent data
+ * @ch_1: Bias value for channel one.
+ * @ch_2: Bias value for channel two.
+ * @ch_3: Bias value for channel three.
+ */
+struct ths7303_platform_data {
+	u8 ch_1;
+	u8 ch_2;
+	u8 ch_3;
+};
+
+#endif
diff --git a/include/media/i2c/tvaudio.h b/include/media/i2c/tvaudio.h
new file mode 100644
index 0000000..f13e1a3
--- /dev/null
+++ b/include/media/i2c/tvaudio.h
@@ -0,0 +1,64 @@
+/*
+    tvaudio.h - definition for tvaudio inputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _TVAUDIO_H
+#define _TVAUDIO_H
+
+/*
+ * i2c bus addresses for the chips supported by tvaudio.c
+ */
+
+#define I2C_ADDR_TDA8425	0x82
+#define I2C_ADDR_TDA9840	0x84
+#define I2C_ADDR_TDA9874	0xb0 /* also used by 9875 */
+#define I2C_ADDR_TDA9875	0xb0
+#define I2C_ADDR_TDA8425	0x82
+#define I2C_ADDR_TDA9840	0x84 /* also used by TA8874Z */
+#define I2C_ADDR_TDA985x_L	0xb4 /* also used by 9873 */
+#define I2C_ADDR_TDA985x_H	0xb6
+#define I2C_ADDR_TDA9874	0xb0 /* also used by 9875 */
+#define I2C_ADDR_TEA6300	0x80 /* also used by 6320 */
+#define I2C_ADDR_TEA6420	0x98
+#define I2C_ADDR_PIC16C54	0x96 /* PV951 */
+
+/* The tvaudio module accepts the following inputs: */
+#define TVAUDIO_INPUT_TUNER  0
+#define TVAUDIO_INPUT_RADIO  1
+#define TVAUDIO_INPUT_EXTERN 2
+#define TVAUDIO_INPUT_INTERN 3
+
+static inline const unsigned short *tvaudio_addrs(void)
+{
+	static const unsigned short addrs[] = {
+		I2C_ADDR_TDA8425   >> 1,
+		I2C_ADDR_TEA6300   >> 1,
+		I2C_ADDR_TEA6420   >> 1,
+		I2C_ADDR_TDA9840   >> 1,
+		I2C_ADDR_TDA985x_L >> 1,
+		I2C_ADDR_TDA985x_H >> 1,
+		I2C_ADDR_TDA9874   >> 1,
+		I2C_ADDR_PIC16C54  >> 1,
+		I2C_CLIENT_END
+	};
+
+	return addrs;
+}
+
+#endif
diff --git a/include/media/i2c/tvp514x.h b/include/media/i2c/tvp514x.h
new file mode 100644
index 0000000..c489670
--- /dev/null
+++ b/include/media/i2c/tvp514x.h
@@ -0,0 +1,107 @@
+/*
+ * drivers/media/video/tvp514x.h
+ *
+ * Copyright (C) 2008 Texas Instruments Inc
+ * Author: Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Contributors:
+ *     Sivaraj R <sivaraj@ti.com>
+ *     Brijesh R Jadav <brijesh.j@ti.com>
+ *     Hardik Shah <hardik.shah@ti.com>
+ *     Manjunath Hadli <mrh@ti.com>
+ *     Karicheri Muralidharan <m-karicheri2@ti.com>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _TVP514X_H
+#define _TVP514X_H
+
+/*
+ * Other macros
+ */
+#define TVP514X_MODULE_NAME		"tvp514x"
+
+#define TVP514X_XCLK_BT656		(27000000)
+
+/* Number of pixels and number of lines per frame for different standards */
+#define NTSC_NUM_ACTIVE_PIXELS		(720)
+#define NTSC_NUM_ACTIVE_LINES		(480)
+#define PAL_NUM_ACTIVE_PIXELS		(720)
+#define PAL_NUM_ACTIVE_LINES		(576)
+
+/**
+ * enum tvp514x_input - enum for different decoder input pin
+ *		configuration.
+ */
+enum tvp514x_input {
+	/*
+	 * CVBS input selection
+	 */
+	INPUT_CVBS_VI1A = 0x0,
+	INPUT_CVBS_VI1B,
+	INPUT_CVBS_VI1C,
+	INPUT_CVBS_VI2A = 0x04,
+	INPUT_CVBS_VI2B,
+	INPUT_CVBS_VI2C,
+	INPUT_CVBS_VI3A = 0x08,
+	INPUT_CVBS_VI3B,
+	INPUT_CVBS_VI3C,
+	INPUT_CVBS_VI4A = 0x0C,
+	/*
+	 * S-Video input selection
+	 */
+	INPUT_SVIDEO_VI2A_VI1A = 0x44,
+	INPUT_SVIDEO_VI2B_VI1B,
+	INPUT_SVIDEO_VI2C_VI1C,
+	INPUT_SVIDEO_VI2A_VI3A = 0x54,
+	INPUT_SVIDEO_VI2B_VI3B,
+	INPUT_SVIDEO_VI2C_VI3C,
+	INPUT_SVIDEO_VI4A_VI1A = 0x4C,
+	INPUT_SVIDEO_VI4A_VI1B,
+	INPUT_SVIDEO_VI4A_VI1C,
+	INPUT_SVIDEO_VI4A_VI3A = 0x5C,
+	INPUT_SVIDEO_VI4A_VI3B,
+	INPUT_SVIDEO_VI4A_VI3C,
+
+	/* Need to add entries for
+	 * RGB, YPbPr and SCART.
+	 */
+	INPUT_INVALID
+};
+
+/**
+ * enum tvp514x_output - enum for output format
+ *			supported.
+ *
+ */
+enum tvp514x_output {
+	OUTPUT_10BIT_422_EMBEDDED_SYNC = 0,
+	OUTPUT_20BIT_422_SEPERATE_SYNC,
+	OUTPUT_10BIT_422_SEPERATE_SYNC = 3,
+	OUTPUT_INVALID
+};
+
+/**
+ * struct tvp514x_platform_data - Platform data values and access functions.
+ * @clk_polarity: Clock polarity of the current interface.
+ * @hs_polarity: HSYNC Polarity configuration for current interface.
+ * @vs_polarity: VSYNC Polarity configuration for current interface.
+ */
+struct tvp514x_platform_data {
+	/* Interface control params */
+	bool clk_polarity;
+	bool hs_polarity;
+	bool vs_polarity;
+};
+
+
+#endif				/* ifndef _TVP514X_H */
diff --git a/include/media/i2c/tvp7002.h b/include/media/i2c/tvp7002.h
new file mode 100644
index 0000000..cb213c1
--- /dev/null
+++ b/include/media/i2c/tvp7002.h
@@ -0,0 +1,50 @@
+/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
+ * Digitizer with Horizontal PLL registers
+ *
+ * Copyright (C) 2009 Texas Instruments Inc
+ * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
+ *
+ * This code is partially based upon the TVP5150 driver
+ * written by Mauro Carvalho Chehab <mchehab@kernel.org>,
+ * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
+ * and the TVP7002 driver in the TI LSP 2.10.00.14
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef _TVP7002_H_
+#define _TVP7002_H_
+
+#define TVP7002_MODULE_NAME "tvp7002"
+
+/**
+ * struct tvp7002_config - Platform dependent data
+ *@clk_polarity: Clock polarity
+ *		0 - Data clocked out on rising edge of DATACLK signal
+ *		1 - Data clocked out on falling edge of DATACLK signal
+ *@hs_polarity:  HSYNC polarity
+ *		0 - Active low HSYNC output, 1 - Active high HSYNC output
+ *@vs_polarity: VSYNC Polarity
+ *		0 - Active low VSYNC output, 1 - Active high VSYNC output
+ *@fid_polarity: Active-high Field ID polarity.
+ *		0 - The field ID output is set to logic 1 for an odd field
+ *		    (field 1) and set to logic 0 for an even field (field 0).
+ *		1 - Operation with polarity inverted.
+ *@sog_polarity: Active high Sync on Green output polarity.
+ *		0 - Normal operation, 1 - Operation with polarity inverted
+ */
+struct tvp7002_config {
+	bool clk_polarity;
+	bool hs_polarity;
+	bool vs_polarity;
+	bool fid_polarity;
+	bool sog_polarity;
+};
+#endif
diff --git a/include/media/i2c/tw9910.h b/include/media/i2c/tw9910.h
new file mode 100644
index 0000000..bec8f7b
--- /dev/null
+++ b/include/media/i2c/tw9910.h
@@ -0,0 +1,47 @@
+/*
+ * tw9910 Driver header
+ *
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on ov772x.h
+ *
+ * Copyright (C) Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __TW9910_H__
+#define __TW9910_H__
+
+#include <media/soc_camera.h>
+
+/**
+ * tw9910_mpout_pin - MPOUT (multi-purpose output) pin functions
+ */
+enum tw9910_mpout_pin {
+	TW9910_MPO_VLOSS,
+	TW9910_MPO_HLOCK,
+	TW9910_MPO_SLOCK,
+	TW9910_MPO_VLOCK,
+	TW9910_MPO_MONO,
+	TW9910_MPO_DET50,
+	TW9910_MPO_FIELD,
+	TW9910_MPO_RTCO,
+};
+
+/**
+ * tw9910_video_info -	tw9910 driver interface structure
+ * @buswidth:		Parallel data bus width (8 or 16).
+ * @mpout:		Selected function of MPOUT (multi-purpose output) pin.
+ *			See &enum tw9910_mpout_pin
+ */
+struct tw9910_video_info {
+	unsigned long		buswidth;
+	enum tw9910_mpout_pin	mpout;
+};
+
+
+#endif /* __TW9910_H__ */
diff --git a/include/media/i2c/uda1342.h b/include/media/i2c/uda1342.h
new file mode 100644
index 0000000..cb412d4
--- /dev/null
+++ b/include/media/i2c/uda1342.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * uda1342.h - definition for uda1342 inputs
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _UDA1342_H_
+#define _UDA1342_H_
+
+/* The UDA1342 has 2 inputs */
+
+#define UDA1342_IN1 1
+#define UDA1342_IN2 2
+
+#endif
diff --git a/include/media/i2c/upd64031a.h b/include/media/i2c/upd64031a.h
new file mode 100644
index 0000000..1eba24d
--- /dev/null
+++ b/include/media/i2c/upd64031a.h
@@ -0,0 +1,36 @@
+/*
+ * upd64031a - NEC Electronics Ghost Reduction input defines
+ *
+ * 2006 by Hans Verkuil (hverkuil@xs4all.nl)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _UPD64031A_H_
+#define _UPD64031A_H_
+
+/* Ghost reduction modes */
+#define UPD64031A_GR_ON		0
+#define UPD64031A_GR_OFF	1
+#define UPD64031A_GR_THROUGH	3
+
+/* Direct 3D/YCS Connection */
+#define UPD64031A_3DYCS_DISABLE   (0 << 2)
+#define UPD64031A_3DYCS_COMPOSITE (2 << 2)
+#define UPD64031A_3DYCS_SVIDEO    (3 << 2)
+
+/* Composite sync digital separation circuit */
+#define UPD64031A_COMPOSITE_EXTERNAL (1 << 4)
+
+/* Vertical sync digital separation circuit */
+#define UPD64031A_VERTICAL_EXTERNAL (1 << 5)
+
+#endif
diff --git a/include/media/i2c/upd64083.h b/include/media/i2c/upd64083.h
new file mode 100644
index 0000000..4bed737
--- /dev/null
+++ b/include/media/i2c/upd64083.h
@@ -0,0 +1,54 @@
+/*
+ * upd6408x - NEC Electronics 3-Dimensional Y/C separation input defines
+ *
+ * 2006 by Hans Verkuil (hverkuil@xs4all.nl)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _UPD64083_H_
+#define _UPD64083_H_
+
+/* There are two bits of information that the driver needs in order
+   to select the correct routing: the operating mode and the selection
+   of the Y input (external or internal).
+
+   The first two operating modes expect a composite signal on the Y input,
+   the second two operating modes use both the Y and C inputs.
+
+   Normally YCS_MODE is used for tuner and composite inputs, and the
+   YCNR mode is used for S-Video inputs.
+
+   The external Y-ADC is selected when the composite input comes from a
+   upd64031a ghost reduction device. If this device is not present, or
+   the input is a S-Video signal, then the internal Y-ADC input should
+   be used. */
+
+/* Operating modes: */
+
+/* YCS mode: Y/C separation (burst locked clocking) */
+#define UPD64083_YCS_MODE      0
+/* YCS+ mode: 2D Y/C separation and YCNR (burst locked clocking) */
+#define UPD64083_YCS_PLUS_MODE 1
+
+/* Note: the following two modes cannot be used in combination with the
+   external Y-ADC. */
+/* MNNR mode: frame comb type YNR+C delay (line locked clocking) */
+#define UPD64083_MNNR_MODE     2
+/* YCNR mode: frame recursive YCNR (burst locked clocking) */
+#define UPD64083_YCNR_MODE     3
+
+/* Select external Y-ADC: this should be set if this device is used in
+   combination with the upd64031a ghost reduction device.
+   Otherwise leave at 0 (use internal Y-ADC). */
+#define UPD64083_EXT_Y_ADC     (1 << 2)
+
+#endif
diff --git a/include/media/i2c/wm8775.h b/include/media/i2c/wm8775.h
new file mode 100644
index 0000000..d0e801a
--- /dev/null
+++ b/include/media/i2c/wm8775.h
@@ -0,0 +1,44 @@
+/*
+    wm8775.h - definition for wm8775 inputs and outputs
+
+    Copyright (C) 2006 Hans Verkuil (hverkuil@xs4all.nl)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _WM8775_H_
+#define _WM8775_H_
+
+/* The WM8775 has 4 inputs and one output. Zero or more inputs
+   are multiplexed together to the output. Hence there are
+   16 combinations.
+   If only one input is active (the normal case) then the
+   input values 1, 2, 4 or 8 should be used. */
+
+#define WM8775_AIN1 1
+#define WM8775_AIN2 2
+#define WM8775_AIN3 4
+#define WM8775_AIN4 8
+
+
+struct wm8775_platform_data {
+	/*
+	 * FIXME: Instead, we should parametrize the params
+	 * that need different settings between ivtv, pvrusb2, and Nova-S
+	 */
+	bool is_nova_s;
+};
+
+#endif
diff --git a/include/media/imx.h b/include/media/imx.h
new file mode 100644
index 0000000..6e5f50d
--- /dev/null
+++ b/include/media/imx.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2014-2017 Mentor Graphics Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+#ifndef __MEDIA_IMX_H__
+#define __MEDIA_IMX_H__
+
+#include <linux/imx-media.h>
+
+#endif
diff --git a/include/media/media-device.h b/include/media/media-device.h
new file mode 100644
index 0000000..bcc6ec4
--- /dev/null
+++ b/include/media/media-device.h
@@ -0,0 +1,478 @@
+/*
+ * Media device
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *	     Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MEDIA_DEVICE_H
+#define _MEDIA_DEVICE_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+#include <media/media-devnode.h>
+#include <media/media-entity.h>
+
+struct ida;
+struct device;
+
+/**
+ * struct media_entity_notify - Media Entity Notify
+ *
+ * @list: List head
+ * @notify_data: Input data to invoke the callback
+ * @notify: Callback function pointer
+ *
+ * Drivers may register a callback to take action when new entities get
+ * registered with the media device. This handler is intended for creating
+ * links between existing entities and should not create entities and register
+ * them.
+ */
+struct media_entity_notify {
+	struct list_head list;
+	void *notify_data;
+	void (*notify)(struct media_entity *entity, void *notify_data);
+};
+
+/**
+ * struct media_device_ops - Media device operations
+ * @link_notify: Link state change notification callback. This callback is
+ *		 called with the graph_mutex held.
+ */
+struct media_device_ops {
+	int (*link_notify)(struct media_link *link, u32 flags,
+			   unsigned int notification);
+};
+
+/**
+ * struct media_device - Media device
+ * @dev:	Parent device
+ * @devnode:	Media device node
+ * @driver_name: Optional device driver name. If not set, calls to
+ *		%MEDIA_IOC_DEVICE_INFO will return ``dev->driver->name``.
+ *		This is needed for USB drivers for example, as otherwise
+ *		they'll all appear as if the driver name was "usb".
+ * @model:	Device model name
+ * @serial:	Device serial number (optional)
+ * @bus_info:	Unique and stable device location identifier
+ * @hw_revision: Hardware device revision
+ * @topology_version: Monotonic counter for storing the version of the graph
+ *		topology. Should be incremented each time the topology changes.
+ * @id:		Unique ID used on the last registered graph object
+ * @entity_internal_idx: Unique internal entity ID used by the graph traversal
+ *		algorithms
+ * @entity_internal_idx_max: Allocated internal entity indices
+ * @entities:	List of registered entities
+ * @interfaces:	List of registered interfaces
+ * @pads:	List of registered pads
+ * @links:	List of registered links
+ * @entity_notify: List of registered entity_notify callbacks
+ * @graph_mutex: Protects access to struct media_device data
+ * @pm_count_walk: Graph walk for power state walk. Access serialised using
+ *		   graph_mutex.
+ *
+ * @source_priv: Driver Private data for enable/disable source handlers
+ * @enable_source: Enable Source Handler function pointer
+ * @disable_source: Disable Source Handler function pointer
+ *
+ * @ops:	Operation handler callbacks
+ *
+ * This structure represents an abstract high-level media device. It allows easy
+ * access to entities and provides basic media device-level support. The
+ * structure can be allocated directly or embedded in a larger structure.
+ *
+ * The parent @dev is a physical device. It must be set before registering the
+ * media device.
+ *
+ * @model is a descriptive model name exported through sysfs. It doesn't have to
+ * be unique.
+ *
+ * @enable_source is a handler to find source entity for the
+ * sink entity  and activate the link between them if source
+ * entity is free. Drivers should call this handler before
+ * accessing the source.
+ *
+ * @disable_source is a handler to find source entity for the
+ * sink entity  and deactivate the link between them. Drivers
+ * should call this handler to release the source.
+ *
+ * Use-case: find tuner entity connected to the decoder
+ * entity and check if it is available, and activate the
+ * the link between them from @enable_source and deactivate
+ * from @disable_source.
+ *
+ * .. note::
+ *
+ *    Bridge driver is expected to implement and set the
+ *    handler when &media_device is registered or when
+ *    bridge driver finds the media_device during probe.
+ *    Bridge driver sets source_priv with information
+ *    necessary to run @enable_source and @disable_source handlers.
+ *    Callers should hold graph_mutex to access and call @enable_source
+ *    and @disable_source handlers.
+ */
+struct media_device {
+	/* dev->driver_data points to this struct. */
+	struct device *dev;
+	struct media_devnode *devnode;
+
+	char model[32];
+	char driver_name[32];
+	char serial[40];
+	char bus_info[32];
+	u32 hw_revision;
+
+	u64 topology_version;
+
+	u32 id;
+	struct ida entity_internal_idx;
+	int entity_internal_idx_max;
+
+	struct list_head entities;
+	struct list_head interfaces;
+	struct list_head pads;
+	struct list_head links;
+
+	/* notify callback list invoked when a new entity is registered */
+	struct list_head entity_notify;
+
+	/* Serializes graph operations. */
+	struct mutex graph_mutex;
+	struct media_graph pm_count_walk;
+
+	void *source_priv;
+	int (*enable_source)(struct media_entity *entity,
+			     struct media_pipeline *pipe);
+	void (*disable_source)(struct media_entity *entity);
+
+	const struct media_device_ops *ops;
+};
+
+/* We don't need to include pci.h or usb.h here */
+struct pci_dev;
+struct usb_device;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+
+/* Supported link_notify @notification values. */
+#define MEDIA_DEV_NOTIFY_PRE_LINK_CH	0
+#define MEDIA_DEV_NOTIFY_POST_LINK_CH	1
+
+/**
+ * media_entity_enum_init - Initialise an entity enumeration
+ *
+ * @ent_enum: Entity enumeration to be initialised
+ * @mdev: The related media device
+ *
+ * Return: zero on success or a negative error code.
+ */
+static inline __must_check int media_entity_enum_init(
+	struct media_entity_enum *ent_enum, struct media_device *mdev)
+{
+	return __media_entity_enum_init(ent_enum,
+					mdev->entity_internal_idx_max + 1);
+}
+
+/**
+ * media_device_init() - Initializes a media device element
+ *
+ * @mdev:	pointer to struct &media_device
+ *
+ * This function initializes the media device prior to its registration.
+ * The media device initialization and registration is split in two functions
+ * to avoid race conditions and make the media device available to user-space
+ * before the media graph has been completed.
+ *
+ * So drivers need to first initialize the media device, register any entity
+ * within the media device, create pad to pad links and then finally register
+ * the media device by calling media_device_register() as a final step.
+ */
+void media_device_init(struct media_device *mdev);
+
+/**
+ * media_device_cleanup() - Cleanups a media device element
+ *
+ * @mdev:	pointer to struct &media_device
+ *
+ * This function that will destroy the graph_mutex that is
+ * initialized in media_device_init().
+ */
+void media_device_cleanup(struct media_device *mdev);
+
+/**
+ * __media_device_register() - Registers a media device element
+ *
+ * @mdev:	pointer to struct &media_device
+ * @owner:	should be filled with %THIS_MODULE
+ *
+ * Users, should, instead, call the media_device_register() macro.
+ *
+ * The caller is responsible for initializing the &media_device structure
+ * before registration. The following fields of &media_device must be set:
+ *
+ *  - &media_entity.dev must point to the parent device (usually a &pci_dev,
+ *    &usb_interface or &platform_device instance).
+ *
+ *  - &media_entity.model must be filled with the device model name as a
+ *    NUL-terminated UTF-8 string. The device/model revision must not be
+ *    stored in this field.
+ *
+ * The following fields are optional:
+ *
+ *  - &media_entity.serial is a unique serial number stored as a
+ *    NUL-terminated ASCII string. The field is big enough to store a GUID
+ *    in text form. If the hardware doesn't provide a unique serial number
+ *    this field must be left empty.
+ *
+ *  - &media_entity.bus_info represents the location of the device in the
+ *    system as a NUL-terminated ASCII string. For PCI/PCIe devices
+ *    &media_entity.bus_info must be set to "PCI:" (or "PCIe:") followed by
+ *    the value of pci_name(). For USB devices,the usb_make_path() function
+ *    must be used. This field is used by applications to distinguish between
+ *    otherwise identical devices that don't provide a serial number.
+ *
+ *  - &media_entity.hw_revision is the hardware device revision in a
+ *    driver-specific format. When possible the revision should be formatted
+ *    with the KERNEL_VERSION() macro.
+ *
+ * .. note::
+ *
+ *    #) Upon successful registration a character device named media[0-9]+ is created. The device major and minor numbers are dynamic. The model name is exported as a sysfs attribute.
+ *
+ *    #) Unregistering a media device that hasn't been registered is **NOT** safe.
+ *
+ * Return: returns zero on success or a negative error code.
+ */
+int __must_check __media_device_register(struct media_device *mdev,
+					 struct module *owner);
+
+
+/**
+ * media_device_register() - Registers a media device element
+ *
+ * @mdev:	pointer to struct &media_device
+ *
+ * This macro calls __media_device_register() passing %THIS_MODULE as
+ * the __media_device_register() second argument (**owner**).
+ */
+#define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE)
+
+/**
+ * media_device_unregister() - Unregisters a media device element
+ *
+ * @mdev:	pointer to struct &media_device
+ *
+ * It is safe to call this function on an unregistered (but initialised)
+ * media device.
+ */
+void media_device_unregister(struct media_device *mdev);
+
+/**
+ * media_device_register_entity() - registers a media entity inside a
+ *	previously registered media device.
+ *
+ * @mdev:	pointer to struct &media_device
+ * @entity:	pointer to struct &media_entity to be registered
+ *
+ * Entities are identified by a unique positive integer ID. The media
+ * controller framework will such ID automatically. IDs are not guaranteed
+ * to be contiguous, and the ID number can change on newer Kernel versions.
+ * So, neither the driver nor userspace should hardcode ID numbers to refer
+ * to the entities, but, instead, use the framework to find the ID, when
+ * needed.
+ *
+ * The media_entity name, type and flags fields should be initialized before
+ * calling media_device_register_entity(). Entities embedded in higher-level
+ * standard structures can have some of those fields set by the higher-level
+ * framework.
+ *
+ * If the device has pads, media_entity_pads_init() should be called before
+ * this function. Otherwise, the &media_entity.pad and &media_entity.num_pads
+ * should be zeroed before calling this function.
+ *
+ * Entities have flags that describe the entity capabilities and state:
+ *
+ * %MEDIA_ENT_FL_DEFAULT
+ *    indicates the default entity for a given type.
+ *    This can be used to report the default audio and video devices or the
+ *    default camera sensor.
+ *
+ * .. note::
+ *
+ *    Drivers should set the entity function before calling this function.
+ *    Please notice that the values %MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN and
+ *    %MEDIA_ENT_F_UNKNOWN should not be used by the drivers.
+ */
+int __must_check media_device_register_entity(struct media_device *mdev,
+					      struct media_entity *entity);
+
+/**
+ * media_device_unregister_entity() - unregisters a media entity.
+ *
+ * @entity:	pointer to struct &media_entity to be unregistered
+ *
+ * All links associated with the entity and all PADs are automatically
+ * unregistered from the media_device when this function is called.
+ *
+ * Unregistering an entity will not change the IDs of the other entities and
+ * the previoully used ID will never be reused for a newly registered entities.
+ *
+ * When a media device is unregistered, all its entities are unregistered
+ * automatically. No manual entities unregistration is then required.
+ *
+ * .. note::
+ *
+ *    The media_entity instance itself must be freed explicitly by
+ *    the driver if required.
+ */
+void media_device_unregister_entity(struct media_entity *entity);
+
+/**
+ * media_device_register_entity_notify() - Registers a media entity_notify
+ *					   callback
+ *
+ * @mdev:      The media device
+ * @nptr:      The media_entity_notify
+ *
+ * .. note::
+ *
+ *    When a new entity is registered, all the registered
+ *    media_entity_notify callbacks are invoked.
+ */
+
+int __must_check media_device_register_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr);
+
+/**
+ * media_device_unregister_entity_notify() - Unregister a media entity notify
+ *					     callback
+ *
+ * @mdev:      The media device
+ * @nptr:      The media_entity_notify
+ *
+ */
+void media_device_unregister_entity_notify(struct media_device *mdev,
+					struct media_entity_notify *nptr);
+
+/* Iterate over all entities. */
+#define media_device_for_each_entity(entity, mdev)			\
+	list_for_each_entry(entity, &(mdev)->entities, graph_obj.list)
+
+/* Iterate over all interfaces. */
+#define media_device_for_each_intf(intf, mdev)			\
+	list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
+
+/* Iterate over all pads. */
+#define media_device_for_each_pad(pad, mdev)			\
+	list_for_each_entry(pad, &(mdev)->pads, graph_obj.list)
+
+/* Iterate over all links. */
+#define media_device_for_each_link(link, mdev)			\
+	list_for_each_entry(link, &(mdev)->links, graph_obj.list)
+
+/**
+ * media_device_pci_init() - create and initialize a
+ *	struct &media_device from a PCI device.
+ *
+ * @mdev:	pointer to struct &media_device
+ * @pci_dev:	pointer to struct pci_dev
+ * @name:	media device name. If %NULL, the routine will use the default
+ *		name for the pci device, given by pci_name() macro.
+ */
+void media_device_pci_init(struct media_device *mdev,
+			   struct pci_dev *pci_dev,
+			   const char *name);
+/**
+ * __media_device_usb_init() - create and initialize a
+ *	struct &media_device from a PCI device.
+ *
+ * @mdev:	pointer to struct &media_device
+ * @udev:	pointer to struct usb_device
+ * @board_name:	media device name. If %NULL, the routine will use the usb
+ *		product name, if available.
+ * @driver_name: name of the driver. if %NULL, the routine will use the name
+ *		given by ``udev->dev->driver->name``, with is usually the wrong
+ *		thing to do.
+ *
+ * .. note::
+ *
+ *    It is better to call media_device_usb_init() instead, as
+ *    such macro fills driver_name with %KBUILD_MODNAME.
+ */
+void __media_device_usb_init(struct media_device *mdev,
+			     struct usb_device *udev,
+			     const char *board_name,
+			     const char *driver_name);
+
+#else
+static inline int media_device_register(struct media_device *mdev)
+{
+	return 0;
+}
+static inline void media_device_unregister(struct media_device *mdev)
+{
+}
+static inline int media_device_register_entity(struct media_device *mdev,
+						struct media_entity *entity)
+{
+	return 0;
+}
+static inline void media_device_unregister_entity(struct media_entity *entity)
+{
+}
+static inline int media_device_register_entity_notify(
+					struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+	return 0;
+}
+static inline void media_device_unregister_entity_notify(
+					struct media_device *mdev,
+					struct media_entity_notify *nptr)
+{
+}
+
+static inline void media_device_pci_init(struct media_device *mdev,
+					 struct pci_dev *pci_dev,
+					 char *name)
+{
+}
+
+static inline void __media_device_usb_init(struct media_device *mdev,
+					   struct usb_device *udev,
+					   char *board_name,
+					   char *driver_name)
+{
+}
+
+#endif /* CONFIG_MEDIA_CONTROLLER */
+
+/**
+ * media_device_usb_init() - create and initialize a
+ *	struct &media_device from a PCI device.
+ *
+ * @mdev:	pointer to struct &media_device
+ * @udev:	pointer to struct usb_device
+ * @name:	media device name. If %NULL, the routine will use the usb
+ *		product name, if available.
+ *
+ * This macro calls media_device_usb_init() passing the
+ * media_device_usb_init() **driver_name** parameter filled with
+ * %KBUILD_MODNAME.
+ */
+#define media_device_usb_init(mdev, udev, name) \
+	__media_device_usb_init(mdev, udev, name, KBUILD_MODNAME)
+
+#endif
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h
new file mode 100644
index 0000000..dc2f64e
--- /dev/null
+++ b/include/media/media-devnode.h
@@ -0,0 +1,176 @@
+/*
+ * Media device node
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *	     Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * --
+ *
+ * Common functions for media-related drivers to register and unregister media
+ * device nodes.
+ */
+
+#ifndef _MEDIA_DEVNODE_H
+#define _MEDIA_DEVNODE_H
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+
+struct media_device;
+
+/*
+ * Flag to mark the media_devnode struct as registered. Drivers must not touch
+ * this flag directly, it will be set and cleared by media_devnode_register and
+ * media_devnode_unregister.
+ */
+#define MEDIA_FLAG_REGISTERED	0
+
+/**
+ * struct media_file_operations - Media device file operations
+ *
+ * @owner: should be filled with %THIS_MODULE
+ * @read: pointer to the function that implements read() syscall
+ * @write: pointer to the function that implements write() syscall
+ * @poll: pointer to the function that implements poll() syscall
+ * @ioctl: pointer to the function that implements ioctl() syscall
+ * @compat_ioctl: pointer to the function that will handle 32 bits userspace
+ *	calls to the the ioctl() syscall on a Kernel compiled with 64 bits.
+ * @open: pointer to the function that implements open() syscall
+ * @release: pointer to the function that will release the resources allocated
+ *	by the @open function.
+ */
+struct media_file_operations {
+	struct module *owner;
+	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
+	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
+	__poll_t (*poll) (struct file *, struct poll_table_struct *);
+	long (*ioctl) (struct file *, unsigned int, unsigned long);
+	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
+	int (*open) (struct file *);
+	int (*release) (struct file *);
+};
+
+/**
+ * struct media_devnode - Media device node
+ * @media_dev:	pointer to struct &media_device
+ * @fops:	pointer to struct &media_file_operations with media device ops
+ * @dev:	pointer to struct &device containing the media controller device
+ * @cdev:	struct cdev pointer character device
+ * @parent:	parent device
+ * @minor:	device node minor number
+ * @flags:	flags, combination of the ``MEDIA_FLAG_*`` constants
+ * @release:	release callback called at the end of ``media_devnode_release()``
+ *		routine at media-device.c.
+ *
+ * This structure represents a media-related device node.
+ *
+ * The @parent is a physical device. It must be set by core or device drivers
+ * before registering the node.
+ */
+struct media_devnode {
+	struct media_device *media_dev;
+
+	/* device ops */
+	const struct media_file_operations *fops;
+
+	/* sysfs */
+	struct device dev;		/* media device */
+	struct cdev cdev;		/* character device */
+	struct device *parent;		/* device parent */
+
+	/* device info */
+	int minor;
+	unsigned long flags;		/* Use bitops to access flags */
+
+	/* callbacks */
+	void (*release)(struct media_devnode *devnode);
+};
+
+/* dev to media_devnode */
+#define to_media_devnode(cd) container_of(cd, struct media_devnode, dev)
+
+/**
+ * media_devnode_register - register a media device node
+ *
+ * @mdev: struct media_device we want to register a device node
+ * @devnode: media device node structure we want to register
+ * @owner: should be filled with %THIS_MODULE
+ *
+ * The registration code assigns minor numbers and registers the new device node
+ * with the kernel. An error is returned if no free minor number can be found,
+ * or if the registration of the device node fails.
+ *
+ * Zero is returned on success.
+ *
+ * Note that if the media_devnode_register call fails, the release() callback of
+ * the media_devnode structure is *not* called, so the caller is responsible for
+ * freeing any data.
+ */
+int __must_check media_devnode_register(struct media_device *mdev,
+					struct media_devnode *devnode,
+					struct module *owner);
+
+/**
+ * media_devnode_unregister_prepare - clear the media device node register bit
+ * @devnode: the device node to prepare for unregister
+ *
+ * This clears the passed device register bit. Future open calls will be met
+ * with errors. Should be called before media_devnode_unregister() to avoid
+ * races with unregister and device file open calls.
+ *
+ * This function can safely be called if the device node has never been
+ * registered or has already been unregistered.
+ */
+void media_devnode_unregister_prepare(struct media_devnode *devnode);
+
+/**
+ * media_devnode_unregister - unregister a media device node
+ * @devnode: the device node to unregister
+ *
+ * This unregisters the passed device. Future open calls will be met with
+ * errors.
+ *
+ * Should be called after media_devnode_unregister_prepare()
+ */
+void media_devnode_unregister(struct media_devnode *devnode);
+
+/**
+ * media_devnode_data - returns a pointer to the &media_devnode
+ *
+ * @filp: pointer to struct &file
+ */
+static inline struct media_devnode *media_devnode_data(struct file *filp)
+{
+	return filp->private_data;
+}
+
+/**
+ * media_devnode_is_registered - returns true if &media_devnode is registered;
+ *	false otherwise.
+ *
+ * @devnode: pointer to struct &media_devnode.
+ *
+ * Note: If mdev is NULL, it also returns false.
+ */
+static inline int media_devnode_is_registered(struct media_devnode *devnode)
+{
+	if (!devnode)
+		return false;
+
+	return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
+}
+
+#endif /* _MEDIA_DEVNODE_H */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
new file mode 100644
index 0000000..3aa3d58
--- /dev/null
+++ b/include/media/media-entity.h
@@ -0,0 +1,1088 @@
+/*
+ * Media entity
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *	     Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MEDIA_ENTITY_H
+#define _MEDIA_ENTITY_H
+
+#include <linux/bitmap.h>
+#include <linux/bug.h>
+#include <linux/fwnode.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/media.h>
+
+/* Enums used internally at the media controller to represent graphs */
+
+/**
+ * enum media_gobj_type - type of a graph object
+ *
+ * @MEDIA_GRAPH_ENTITY:		Identify a media entity
+ * @MEDIA_GRAPH_PAD:		Identify a media pad
+ * @MEDIA_GRAPH_LINK:		Identify a media link
+ * @MEDIA_GRAPH_INTF_DEVNODE:	Identify a media Kernel API interface via
+ *				a device node
+ */
+enum media_gobj_type {
+	MEDIA_GRAPH_ENTITY,
+	MEDIA_GRAPH_PAD,
+	MEDIA_GRAPH_LINK,
+	MEDIA_GRAPH_INTF_DEVNODE,
+};
+
+#define MEDIA_BITS_PER_TYPE		8
+#define MEDIA_BITS_PER_ID		(32 - MEDIA_BITS_PER_TYPE)
+#define MEDIA_ID_MASK			 GENMASK_ULL(MEDIA_BITS_PER_ID - 1, 0)
+
+/* Structs to represent the objects that belong to a media graph */
+
+/**
+ * struct media_gobj - Define a graph object.
+ *
+ * @mdev:	Pointer to the struct &media_device that owns the object
+ * @id:		Non-zero object ID identifier. The ID should be unique
+ *		inside a media_device, as it is composed by
+ *		%MEDIA_BITS_PER_TYPE to store the type plus
+ *		%MEDIA_BITS_PER_ID to store the ID
+ * @list:	List entry stored in one of the per-type mdev object lists
+ *
+ * All objects on the media graph should have this struct embedded
+ */
+struct media_gobj {
+	struct media_device	*mdev;
+	u32			id;
+	struct list_head	list;
+};
+
+#define MEDIA_ENTITY_ENUM_MAX_DEPTH	16
+
+/**
+ * struct media_entity_enum - An enumeration of media entities.
+ *
+ * @bmap:	Bit map in which each bit represents one entity at struct
+ *		media_entity->internal_idx.
+ * @idx_max:	Number of bits in bmap
+ */
+struct media_entity_enum {
+	unsigned long *bmap;
+	int idx_max;
+};
+
+/**
+ * struct media_graph - Media graph traversal state
+ *
+ * @stack:		Graph traversal stack; the stack contains information
+ *			on the path the media entities to be walked and the
+ *			links through which they were reached.
+ * @stack.entity:	pointer to &struct media_entity at the graph.
+ * @stack.link:		pointer to &struct list_head.
+ * @ent_enum:		Visited entities
+ * @top:		The top of the stack
+ */
+struct media_graph {
+	struct {
+		struct media_entity *entity;
+		struct list_head *link;
+	} stack[MEDIA_ENTITY_ENUM_MAX_DEPTH];
+
+	struct media_entity_enum ent_enum;
+	int top;
+};
+
+/**
+ * struct media_pipeline - Media pipeline related information
+ *
+ * @streaming_count:	Streaming start count - streaming stop count
+ * @graph:		Media graph walk during pipeline start / stop
+ */
+struct media_pipeline {
+	int streaming_count;
+	struct media_graph graph;
+};
+
+/**
+ * struct media_link - A link object part of a media graph.
+ *
+ * @graph_obj:	Embedded structure containing the media object common data
+ * @list:	Linked list associated with an entity or an interface that
+ *		owns the link.
+ * @gobj0:	Part of a union. Used to get the pointer for the first
+ *		graph_object of the link.
+ * @source:	Part of a union. Used only if the first object (gobj0) is
+ *		a pad. In that case, it represents the source pad.
+ * @intf:	Part of a union. Used only if the first object (gobj0) is
+ *		an interface.
+ * @gobj1:	Part of a union. Used to get the pointer for the second
+ *		graph_object of the link.
+ * @sink:	Part of a union. Used only if the second object (gobj1) is
+ *		a pad. In that case, it represents the sink pad.
+ * @entity:	Part of a union. Used only if the second object (gobj1) is
+ *		an entity.
+ * @reverse:	Pointer to the link for the reverse direction of a pad to pad
+ *		link.
+ * @flags:	Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*)
+ * @is_backlink: Indicate if the link is a backlink.
+ */
+struct media_link {
+	struct media_gobj graph_obj;
+	struct list_head list;
+	union {
+		struct media_gobj *gobj0;
+		struct media_pad *source;
+		struct media_interface *intf;
+	};
+	union {
+		struct media_gobj *gobj1;
+		struct media_pad *sink;
+		struct media_entity *entity;
+	};
+	struct media_link *reverse;
+	unsigned long flags;
+	bool is_backlink;
+};
+
+/**
+ * struct media_pad - A media pad graph object.
+ *
+ * @graph_obj:	Embedded structure containing the media object common data
+ * @entity:	Entity this pad belongs to
+ * @index:	Pad index in the entity pads array, numbered from 0 to n
+ * @flags:	Pad flags, as defined in
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		(seek for ``MEDIA_PAD_FL_*``)
+ */
+struct media_pad {
+	struct media_gobj graph_obj;	/* must be first field in struct */
+	struct media_entity *entity;
+	u16 index;
+	unsigned long flags;
+};
+
+/**
+ * struct media_entity_operations - Media entity operations
+ * @get_fwnode_pad:	Return the pad number based on a fwnode endpoint or
+ *			a negative value on error. This operation can be used
+ *			to map a fwnode to a media pad number. Optional.
+ * @link_setup:		Notify the entity of link changes. The operation can
+ *			return an error, in which case link setup will be
+ *			cancelled. Optional.
+ * @link_validate:	Return whether a link is valid from the entity point of
+ *			view. The media_pipeline_start() function
+ *			validates all links by calling this operation. Optional.
+ *
+ * .. note::
+ *
+ *    Those these callbacks are called with struct &media_device.graph_mutex
+ *    mutex held.
+ */
+struct media_entity_operations {
+	int (*get_fwnode_pad)(struct fwnode_endpoint *endpoint);
+	int (*link_setup)(struct media_entity *entity,
+			  const struct media_pad *local,
+			  const struct media_pad *remote, u32 flags);
+	int (*link_validate)(struct media_link *link);
+};
+
+/**
+ * enum media_entity_type - Media entity type
+ *
+ * @MEDIA_ENTITY_TYPE_BASE:
+ *	The entity isn't embedded in another subsystem structure.
+ * @MEDIA_ENTITY_TYPE_VIDEO_DEVICE:
+ *	The entity is embedded in a struct video_device instance.
+ * @MEDIA_ENTITY_TYPE_V4L2_SUBDEV:
+ *	The entity is embedded in a struct v4l2_subdev instance.
+ *
+ * Media entity objects are often not instantiated directly, but the media
+ * entity structure is inherited by (through embedding) other subsystem-specific
+ * structures. The media entity type identifies the type of the subclass
+ * structure that implements a media entity instance.
+ *
+ * This allows runtime type identification of media entities and safe casting to
+ * the correct object type. For instance, a media entity structure instance
+ * embedded in a v4l2_subdev structure instance will have the type
+ * %MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a &v4l2_subdev
+ * structure using the container_of() macro.
+ */
+enum media_entity_type {
+	MEDIA_ENTITY_TYPE_BASE,
+	MEDIA_ENTITY_TYPE_VIDEO_DEVICE,
+	MEDIA_ENTITY_TYPE_V4L2_SUBDEV,
+};
+
+/**
+ * struct media_entity - A media entity graph object.
+ *
+ * @graph_obj:	Embedded structure containing the media object common data.
+ * @name:	Entity name.
+ * @obj_type:	Type of the object that implements the media_entity.
+ * @function:	Entity main function, as defined in
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		(seek for ``MEDIA_ENT_F_*``)
+ * @flags:	Entity flags, as defined in
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		(seek for ``MEDIA_ENT_FL_*``)
+ * @num_pads:	Number of sink and source pads.
+ * @num_links:	Total number of links, forward and back, enabled and disabled.
+ * @num_backlinks: Number of backlinks
+ * @internal_idx: An unique internal entity specific number. The numbers are
+ *		re-used if entities are unregistered or registered again.
+ * @pads:	Pads array with the size defined by @num_pads.
+ * @links:	List of data links.
+ * @ops:	Entity operations.
+ * @stream_count: Stream count for the entity.
+ * @use_count:	Use count for the entity.
+ * @pipe:	Pipeline this entity belongs to.
+ * @info:	Union with devnode information.  Kept just for backward
+ *		compatibility.
+ * @info.dev:	Contains device major and minor info.
+ * @info.dev.major: device node major, if the device is a devnode.
+ * @info.dev.minor: device node minor, if the device is a devnode.
+ * @major:	Devnode major number (zero if not applicable). Kept just
+ *		for backward compatibility.
+ * @minor:	Devnode minor number (zero if not applicable). Kept just
+ *		for backward compatibility.
+ *
+ * .. note::
+ *
+ *    @stream_count and @use_count reference counts must never be
+ *    negative, but are signed integers on purpose: a simple ``WARN_ON(<0)``
+ *    check can be used to detect reference count bugs that would make them
+ *    negative.
+ */
+struct media_entity {
+	struct media_gobj graph_obj;	/* must be first field in struct */
+	const char *name;
+	enum media_entity_type obj_type;
+	u32 function;
+	unsigned long flags;
+
+	u16 num_pads;
+	u16 num_links;
+	u16 num_backlinks;
+	int internal_idx;
+
+	struct media_pad *pads;
+	struct list_head links;
+
+	const struct media_entity_operations *ops;
+
+	int stream_count;
+	int use_count;
+
+	struct media_pipeline *pipe;
+
+	union {
+		struct {
+			u32 major;
+			u32 minor;
+		} dev;
+	} info;
+};
+
+/**
+ * struct media_interface - A media interface graph object.
+ *
+ * @graph_obj:		embedded graph object
+ * @links:		List of links pointing to graph entities
+ * @type:		Type of the interface as defined in
+ *			:ref:`include/uapi/linux/media.h <media_header>`
+ *			(seek for ``MEDIA_INTF_T_*``)
+ * @flags:		Interface flags as defined in
+ *			:ref:`include/uapi/linux/media.h <media_header>`
+ *			(seek for ``MEDIA_INTF_FL_*``)
+ *
+ * .. note::
+ *
+ *    Currently, no flags for &media_interface is defined.
+ */
+struct media_interface {
+	struct media_gobj		graph_obj;
+	struct list_head		links;
+	u32				type;
+	u32				flags;
+};
+
+/**
+ * struct media_intf_devnode - A media interface via a device node.
+ *
+ * @intf:	embedded interface object
+ * @major:	Major number of a device node
+ * @minor:	Minor number of a device node
+ */
+struct media_intf_devnode {
+	struct media_interface		intf;
+
+	/* Should match the fields at media_v2_intf_devnode */
+	u32				major;
+	u32				minor;
+};
+
+/**
+ * media_entity_id() - return the media entity graph object id
+ *
+ * @entity:	pointer to &media_entity
+ */
+static inline u32 media_entity_id(struct media_entity *entity)
+{
+	return entity->graph_obj.id;
+}
+
+/**
+ * media_type() - return the media object type
+ *
+ * @gobj:	Pointer to the struct &media_gobj graph object
+ */
+static inline enum media_gobj_type media_type(struct media_gobj *gobj)
+{
+	return gobj->id >> MEDIA_BITS_PER_ID;
+}
+
+/**
+ * media_id() - return the media object ID
+ *
+ * @gobj:	Pointer to the struct &media_gobj graph object
+ */
+static inline u32 media_id(struct media_gobj *gobj)
+{
+	return gobj->id & MEDIA_ID_MASK;
+}
+
+/**
+ * media_gobj_gen_id() - encapsulates type and ID on at the object ID
+ *
+ * @type:	object type as define at enum &media_gobj_type.
+ * @local_id:	next ID, from struct &media_device.id.
+ */
+static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id)
+{
+	u32 id;
+
+	id = type << MEDIA_BITS_PER_ID;
+	id |= local_id & MEDIA_ID_MASK;
+
+	return id;
+}
+
+/**
+ * is_media_entity_v4l2_video_device() - Check if the entity is a video_device
+ * @entity:	pointer to entity
+ *
+ * Return: %true if the entity is an instance of a video_device object and can
+ * safely be cast to a struct video_device using the container_of() macro, or
+ * %false otherwise.
+ */
+static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity)
+{
+	return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE;
+}
+
+/**
+ * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev
+ * @entity:	pointer to entity
+ *
+ * Return: %true if the entity is an instance of a &v4l2_subdev object and can
+ * safely be cast to a struct &v4l2_subdev using the container_of() macro, or
+ * %false otherwise.
+ */
+static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)
+{
+	return entity && entity->obj_type == MEDIA_ENTITY_TYPE_V4L2_SUBDEV;
+}
+
+/**
+ * __media_entity_enum_init - Initialise an entity enumeration
+ *
+ * @ent_enum: Entity enumeration to be initialised
+ * @idx_max: Maximum number of entities in the enumeration
+ *
+ * Return: Returns zero on success or a negative error code.
+ */
+__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum,
+					  int idx_max);
+
+/**
+ * media_entity_enum_cleanup - Release resources of an entity enumeration
+ *
+ * @ent_enum: Entity enumeration to be released
+ */
+void media_entity_enum_cleanup(struct media_entity_enum *ent_enum);
+
+/**
+ * media_entity_enum_zero - Clear the entire enum
+ *
+ * @ent_enum: Entity enumeration to be cleared
+ */
+static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum)
+{
+	bitmap_zero(ent_enum->bmap, ent_enum->idx_max);
+}
+
+/**
+ * media_entity_enum_set - Mark a single entity in the enum
+ *
+ * @ent_enum: Entity enumeration
+ * @entity: Entity to be marked
+ */
+static inline void media_entity_enum_set(struct media_entity_enum *ent_enum,
+					 struct media_entity *entity)
+{
+	if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
+		return;
+
+	__set_bit(entity->internal_idx, ent_enum->bmap);
+}
+
+/**
+ * media_entity_enum_clear - Unmark a single entity in the enum
+ *
+ * @ent_enum: Entity enumeration
+ * @entity: Entity to be unmarked
+ */
+static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum,
+					   struct media_entity *entity)
+{
+	if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
+		return;
+
+	__clear_bit(entity->internal_idx, ent_enum->bmap);
+}
+
+/**
+ * media_entity_enum_test - Test whether the entity is marked
+ *
+ * @ent_enum: Entity enumeration
+ * @entity: Entity to be tested
+ *
+ * Returns %true if the entity was marked.
+ */
+static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum,
+					  struct media_entity *entity)
+{
+	if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
+		return true;
+
+	return test_bit(entity->internal_idx, ent_enum->bmap);
+}
+
+/**
+ * media_entity_enum_test_and_set - Test whether the entity is marked,
+ *	and mark it
+ *
+ * @ent_enum: Entity enumeration
+ * @entity: Entity to be tested
+ *
+ * Returns %true if the entity was marked, and mark it before doing so.
+ */
+static inline bool
+media_entity_enum_test_and_set(struct media_entity_enum *ent_enum,
+			       struct media_entity *entity)
+{
+	if (WARN_ON(entity->internal_idx >= ent_enum->idx_max))
+		return true;
+
+	return __test_and_set_bit(entity->internal_idx, ent_enum->bmap);
+}
+
+/**
+ * media_entity_enum_empty - Test whether the entire enum is empty
+ *
+ * @ent_enum: Entity enumeration
+ *
+ * Return: %true if the entity was empty.
+ */
+static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum)
+{
+	return bitmap_empty(ent_enum->bmap, ent_enum->idx_max);
+}
+
+/**
+ * media_entity_enum_intersects - Test whether two enums intersect
+ *
+ * @ent_enum1: First entity enumeration
+ * @ent_enum2: Second entity enumeration
+ *
+ * Return: %true if entity enumerations @ent_enum1 and @ent_enum2 intersect,
+ * otherwise %false.
+ */
+static inline bool media_entity_enum_intersects(
+	struct media_entity_enum *ent_enum1,
+	struct media_entity_enum *ent_enum2)
+{
+	WARN_ON(ent_enum1->idx_max != ent_enum2->idx_max);
+
+	return bitmap_intersects(ent_enum1->bmap, ent_enum2->bmap,
+				 min(ent_enum1->idx_max, ent_enum2->idx_max));
+}
+
+/**
+ * gobj_to_entity - returns the struct &media_entity pointer from the
+ *	@gobj contained on it.
+ *
+ * @gobj: Pointer to the struct &media_gobj graph object
+ */
+#define gobj_to_entity(gobj) \
+		container_of(gobj, struct media_entity, graph_obj)
+
+/**
+ * gobj_to_pad - returns the struct &media_pad pointer from the
+ *	@gobj contained on it.
+ *
+ * @gobj: Pointer to the struct &media_gobj graph object
+ */
+#define gobj_to_pad(gobj) \
+		container_of(gobj, struct media_pad, graph_obj)
+
+/**
+ * gobj_to_link - returns the struct &media_link pointer from the
+ *	@gobj contained on it.
+ *
+ * @gobj: Pointer to the struct &media_gobj graph object
+ */
+#define gobj_to_link(gobj) \
+		container_of(gobj, struct media_link, graph_obj)
+
+/**
+ * gobj_to_intf - returns the struct &media_interface pointer from the
+ *	@gobj contained on it.
+ *
+ * @gobj: Pointer to the struct &media_gobj graph object
+ */
+#define gobj_to_intf(gobj) \
+		container_of(gobj, struct media_interface, graph_obj)
+
+/**
+ * intf_to_devnode - returns the struct media_intf_devnode pointer from the
+ *	@intf contained on it.
+ *
+ * @intf: Pointer to struct &media_intf_devnode
+ */
+#define intf_to_devnode(intf) \
+		container_of(intf, struct media_intf_devnode, intf)
+
+/**
+ *  media_gobj_create - Initialize a graph object
+ *
+ * @mdev:	Pointer to the &media_device that contains the object
+ * @type:	Type of the object
+ * @gobj:	Pointer to the struct &media_gobj graph object
+ *
+ * This routine initializes the embedded struct &media_gobj inside a
+ * media graph object. It is called automatically if ``media_*_create``
+ * function calls are used. However, if the object (entity, link, pad,
+ * interface) is embedded on some other object, this function should be
+ * called before registering the object at the media controller.
+ */
+void media_gobj_create(struct media_device *mdev,
+		    enum media_gobj_type type,
+		    struct media_gobj *gobj);
+
+/**
+ *  media_gobj_destroy - Stop using a graph object on a media device
+ *
+ * @gobj:	Pointer to the struct &media_gobj graph object
+ *
+ * This should be called by all routines like media_device_unregister()
+ * that remove/destroy media graph objects.
+ */
+void media_gobj_destroy(struct media_gobj *gobj);
+
+/**
+ * media_entity_pads_init() - Initialize the entity pads
+ *
+ * @entity:	entity where the pads belong
+ * @num_pads:	total number of sink and source pads
+ * @pads:	Array of @num_pads pads.
+ *
+ * The pads array is managed by the entity driver and passed to
+ * media_entity_pads_init() where its pointer will be stored in the
+ * &media_entity structure.
+ *
+ * If no pads are needed, drivers could either directly fill
+ * &media_entity->num_pads with 0 and &media_entity->pads with %NULL or call
+ * this function that will do the same.
+ *
+ * As the number of pads is known in advance, the pads array is not allocated
+ * dynamically but is managed by the entity driver. Most drivers will embed the
+ * pads array in a driver-specific structure, avoiding dynamic allocation.
+ *
+ * Drivers must set the direction of every pad in the pads array before calling
+ * media_entity_pads_init(). The function will initialize the other pads fields.
+ */
+int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
+		      struct media_pad *pads);
+
+/**
+ * media_entity_cleanup() - free resources associated with an entity
+ *
+ * @entity:	entity where the pads belong
+ *
+ * This function must be called during the cleanup phase after unregistering
+ * the entity (currently, it does nothing).
+ */
+#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
+static inline void media_entity_cleanup(struct media_entity *entity) {}
+#else
+#define media_entity_cleanup(entity) do { } while (false)
+#endif
+
+/**
+ * media_create_pad_link() - creates a link between two entities.
+ *
+ * @source:	pointer to &media_entity of the source pad.
+ * @source_pad:	number of the source pad in the pads array
+ * @sink:	pointer to &media_entity of the sink pad.
+ * @sink_pad:	number of the sink pad in the pads array.
+ * @flags:	Link flags, as defined in
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		( seek for ``MEDIA_LNK_FL_*``)
+ *
+ * Valid values for flags:
+ *
+ * %MEDIA_LNK_FL_ENABLED
+ *   Indicates that the link is enabled and can be used to transfer media data.
+ *   When two or more links target a sink pad, only one of them can be
+ *   enabled at a time.
+ *
+ * %MEDIA_LNK_FL_IMMUTABLE
+ *   Indicates that the link enabled state can't be modified at runtime. If
+ *   %MEDIA_LNK_FL_IMMUTABLE is set, then %MEDIA_LNK_FL_ENABLED must also be
+ *   set, since an immutable link is always enabled.
+ *
+ * .. note::
+ *
+ *    Before calling this function, media_entity_pads_init() and
+ *    media_device_register_entity() should be called previously for both ends.
+ */
+__must_check int media_create_pad_link(struct media_entity *source,
+			u16 source_pad, struct media_entity *sink,
+			u16 sink_pad, u32 flags);
+
+/**
+ * media_create_pad_links() - creates a link between two entities.
+ *
+ * @mdev: Pointer to the media_device that contains the object
+ * @source_function: Function of the source entities. Used only if @source is
+ *	NULL.
+ * @source: pointer to &media_entity of the source pad. If NULL, it will use
+ *	all entities that matches the @sink_function.
+ * @source_pad: number of the source pad in the pads array
+ * @sink_function: Function of the sink entities. Used only if @sink is NULL.
+ * @sink: pointer to &media_entity of the sink pad. If NULL, it will use
+ *	all entities that matches the @sink_function.
+ * @sink_pad: number of the sink pad in the pads array.
+ * @flags: Link flags, as defined in include/uapi/linux/media.h.
+ * @allow_both_undefined: if %true, then both @source and @sink can be NULL.
+ *	In such case, it will create a crossbar between all entities that
+ *	matches @source_function to all entities that matches @sink_function.
+ *	If %false, it will return 0 and won't create any link if both @source
+ *	and @sink are NULL.
+ *
+ * Valid values for flags:
+ *
+ * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be
+ *	used to transfer media data. If multiple links are created and this
+ *	flag is passed as an argument, only the first created link will have
+ *	this flag.
+ *
+ * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't
+ *	be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then
+ *	%MEDIA_LNK_FL_ENABLED must also be set since an immutable link is
+ *	always enabled.
+ *
+ * It is common for some devices to have multiple source and/or sink entities
+ * of the same type that should be linked. While media_create_pad_link()
+ * creates link by link, this function is meant to allow 1:n, n:1 and even
+ * cross-bar (n:n) links.
+ *
+ * .. note::
+ *
+ *    Before calling this function, media_entity_pads_init() and
+ *    media_device_register_entity() should be called previously for the
+ *    entities to be linked.
+ */
+int media_create_pad_links(const struct media_device *mdev,
+			   const u32 source_function,
+			   struct media_entity *source,
+			   const u16 source_pad,
+			   const u32 sink_function,
+			   struct media_entity *sink,
+			   const u16 sink_pad,
+			   u32 flags,
+			   const bool allow_both_undefined);
+
+void __media_entity_remove_links(struct media_entity *entity);
+
+/**
+ * media_entity_remove_links() - remove all links associated with an entity
+ *
+ * @entity:	pointer to &media_entity
+ *
+ * .. note::
+ *
+ *    This is called automatically when an entity is unregistered via
+ *    media_device_register_entity().
+ */
+void media_entity_remove_links(struct media_entity *entity);
+
+/**
+ * __media_entity_setup_link - Configure a media link without locking
+ * @link: The link being configured
+ * @flags: Link configuration flags
+ *
+ * The bulk of link setup is handled by the two entities connected through the
+ * link. This function notifies both entities of the link configuration change.
+ *
+ * If the link is immutable or if the current and new configuration are
+ * identical, return immediately.
+ *
+ * The user is expected to hold link->source->parent->mutex. If not,
+ * media_entity_setup_link() should be used instead.
+ */
+int __media_entity_setup_link(struct media_link *link, u32 flags);
+
+/**
+ * media_entity_setup_link() - changes the link flags properties in runtime
+ *
+ * @link:	pointer to &media_link
+ * @flags:	the requested new link flags
+ *
+ * The only configurable property is the %MEDIA_LNK_FL_ENABLED link flag
+ * flag to enable/disable a link. Links marked with the
+ * %MEDIA_LNK_FL_IMMUTABLE link flag can not be enabled or disabled.
+ *
+ * When a link is enabled or disabled, the media framework calls the
+ * link_setup operation for the two entities at the source and sink of the
+ * link, in that order. If the second link_setup call fails, another
+ * link_setup call is made on the first entity to restore the original link
+ * flags.
+ *
+ * Media device drivers can be notified of link setup operations by setting the
+ * &media_device.link_notify pointer to a callback function. If provided, the
+ * notification callback will be called before enabling and after disabling
+ * links.
+ *
+ * Entity drivers must implement the link_setup operation if any of their links
+ * is non-immutable. The operation must either configure the hardware or store
+ * the configuration information to be applied later.
+ *
+ * Link configuration must not have any side effect on other links. If an
+ * enabled link at a sink pad prevents another link at the same pad from
+ * being enabled, the link_setup operation must return %-EBUSY and can't
+ * implicitly disable the first enabled link.
+ *
+ * .. note::
+ *
+ *    The valid values of the flags for the link is the same as described
+ *    on media_create_pad_link(), for pad to pad links or the same as described
+ *    on media_create_intf_link(), for interface to entity links.
+ */
+int media_entity_setup_link(struct media_link *link, u32 flags);
+
+/**
+ * media_entity_find_link - Find a link between two pads
+ * @source: Source pad
+ * @sink: Sink pad
+ *
+ * Return: returns a pointer to the link between the two entities. If no
+ * such link exists, return %NULL.
+ */
+struct media_link *media_entity_find_link(struct media_pad *source,
+		struct media_pad *sink);
+
+/**
+ * media_entity_remote_pad - Find the pad at the remote end of a link
+ * @pad: Pad at the local end of the link
+ *
+ * Search for a remote pad connected to the given pad by iterating over all
+ * links originating or terminating at that pad until an enabled link is found.
+ *
+ * Return: returns a pointer to the pad at the remote end of the first found
+ * enabled link, or %NULL if no enabled link has been found.
+ */
+struct media_pad *media_entity_remote_pad(const struct media_pad *pad);
+
+/**
+ * media_entity_get - Get a reference to the parent module
+ *
+ * @entity: The entity
+ *
+ * Get a reference to the parent media device module.
+ *
+ * The function will return immediately if @entity is %NULL.
+ *
+ * Return: returns a pointer to the entity on success or %NULL on failure.
+ */
+struct media_entity *media_entity_get(struct media_entity *entity);
+
+/**
+ * media_entity_get_fwnode_pad - Get pad number from fwnode
+ *
+ * @entity: The entity
+ * @fwnode: Pointer to the fwnode_handle which should be used to find the pad
+ * @direction_flags: Expected direction of the pad, as defined in
+ *		     :ref:`include/uapi/linux/media.h <media_header>`
+ *		     (seek for ``MEDIA_PAD_FL_*``)
+ *
+ * This function can be used to resolve the media pad number from
+ * a fwnode. This is useful for devices which use more complex
+ * mappings of media pads.
+ *
+ * If the entity does not implement the get_fwnode_pad() operation
+ * then this function searches the entity for the first pad that
+ * matches the @direction_flags.
+ *
+ * Return: returns the pad number on success or a negative error code.
+ */
+int media_entity_get_fwnode_pad(struct media_entity *entity,
+				struct fwnode_handle *fwnode,
+				unsigned long direction_flags);
+
+/**
+ * media_graph_walk_init - Allocate resources used by graph walk.
+ *
+ * @graph: Media graph structure that will be used to walk the graph
+ * @mdev: Pointer to the &media_device that contains the object
+ */
+__must_check int media_graph_walk_init(
+	struct media_graph *graph, struct media_device *mdev);
+
+/**
+ * media_graph_walk_cleanup - Release resources used by graph walk.
+ *
+ * @graph: Media graph structure that will be used to walk the graph
+ */
+void media_graph_walk_cleanup(struct media_graph *graph);
+
+/**
+ * media_entity_put - Release the reference to the parent module
+ *
+ * @entity: The entity
+ *
+ * Release the reference count acquired by media_entity_get().
+ *
+ * The function will return immediately if @entity is %NULL.
+ */
+void media_entity_put(struct media_entity *entity);
+
+/**
+ * media_graph_walk_start - Start walking the media graph at a
+ *	given entity
+ *
+ * @graph: Media graph structure that will be used to walk the graph
+ * @entity: Starting entity
+ *
+ * Before using this function, media_graph_walk_init() must be
+ * used to allocate resources used for walking the graph. This
+ * function initializes the graph traversal structure to walk the
+ * entities graph starting at the given entity. The traversal
+ * structure must not be modified by the caller during graph
+ * traversal. After the graph walk, the resources must be released
+ * using media_graph_walk_cleanup().
+ */
+void media_graph_walk_start(struct media_graph *graph,
+			    struct media_entity *entity);
+
+/**
+ * media_graph_walk_next - Get the next entity in the graph
+ * @graph: Media graph structure
+ *
+ * Perform a depth-first traversal of the given media entities graph.
+ *
+ * The graph structure must have been previously initialized with a call to
+ * media_graph_walk_start().
+ *
+ * Return: returns the next entity in the graph or %NULL if the whole graph
+ * have been traversed.
+ */
+struct media_entity *media_graph_walk_next(struct media_graph *graph);
+
+/**
+ * media_pipeline_start - Mark a pipeline as streaming
+ * @entity: Starting entity
+ * @pipe: Media pipeline to be assigned to all entities in the pipeline.
+ *
+ * Mark all entities connected to a given entity through enabled links, either
+ * directly or indirectly, as streaming. The given pipeline object is assigned
+ * to every entity in the pipeline and stored in the media_entity pipe field.
+ *
+ * Calls to this function can be nested, in which case the same number of
+ * media_pipeline_stop() calls will be required to stop streaming. The
+ * pipeline pointer must be identical for all nested calls to
+ * media_pipeline_start().
+ */
+__must_check int media_pipeline_start(struct media_entity *entity,
+				      struct media_pipeline *pipe);
+/**
+ * __media_pipeline_start - Mark a pipeline as streaming
+ *
+ * @entity: Starting entity
+ * @pipe: Media pipeline to be assigned to all entities in the pipeline.
+ *
+ * ..note:: This is the non-locking version of media_pipeline_start()
+ */
+__must_check int __media_pipeline_start(struct media_entity *entity,
+					struct media_pipeline *pipe);
+
+/**
+ * media_pipeline_stop - Mark a pipeline as not streaming
+ * @entity: Starting entity
+ *
+ * Mark all entities connected to a given entity through enabled links, either
+ * directly or indirectly, as not streaming. The media_entity pipe field is
+ * reset to %NULL.
+ *
+ * If multiple calls to media_pipeline_start() have been made, the same
+ * number of calls to this function are required to mark the pipeline as not
+ * streaming.
+ */
+void media_pipeline_stop(struct media_entity *entity);
+
+/**
+ * __media_pipeline_stop - Mark a pipeline as not streaming
+ *
+ * @entity: Starting entity
+ *
+ * .. note:: This is the non-locking version of media_pipeline_stop()
+ */
+void __media_pipeline_stop(struct media_entity *entity);
+
+/**
+ * media_devnode_create() - creates and initializes a device node interface
+ *
+ * @mdev:	pointer to struct &media_device
+ * @type:	type of the interface, as given by
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		( seek for ``MEDIA_INTF_T_*``) macros.
+ * @flags:	Interface flags, as defined in
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		( seek for ``MEDIA_INTF_FL_*``)
+ * @major:	Device node major number.
+ * @minor:	Device node minor number.
+ *
+ * Return: if succeeded, returns a pointer to the newly allocated
+ *	&media_intf_devnode pointer.
+ *
+ * .. note::
+ *
+ *    Currently, no flags for &media_interface is defined.
+ */
+struct media_intf_devnode *
+__must_check media_devnode_create(struct media_device *mdev,
+				  u32 type, u32 flags,
+				  u32 major, u32 minor);
+/**
+ * media_devnode_remove() - removes a device node interface
+ *
+ * @devnode:	pointer to &media_intf_devnode to be freed.
+ *
+ * When a device node interface is removed, all links to it are automatically
+ * removed.
+ */
+void media_devnode_remove(struct media_intf_devnode *devnode);
+struct media_link *
+
+/**
+ * media_create_intf_link() - creates a link between an entity and an interface
+ *
+ * @entity:	pointer to %media_entity
+ * @intf:	pointer to %media_interface
+ * @flags:	Link flags, as defined in
+ *		:ref:`include/uapi/linux/media.h <media_header>`
+ *		( seek for ``MEDIA_LNK_FL_*``)
+ *
+ *
+ * Valid values for flags:
+ *
+ * %MEDIA_LNK_FL_ENABLED
+ *   Indicates that the interface is connected to the entity hardware.
+ *   That's the default value for interfaces. An interface may be disabled if
+ *   the hardware is busy due to the usage of some other interface that it is
+ *   currently controlling the hardware.
+ *
+ *   A typical example is an hybrid TV device that handle only one type of
+ *   stream on a given time. So, when the digital TV is streaming,
+ *   the V4L2 interfaces won't be enabled, as such device is not able to
+ *   also stream analog TV or radio.
+ *
+ * .. note::
+ *
+ *    Before calling this function, media_devnode_create() should be called for
+ *    the interface and media_device_register_entity() should be called for the
+ *    interface that will be part of the link.
+ */
+__must_check media_create_intf_link(struct media_entity *entity,
+				    struct media_interface *intf,
+				    u32 flags);
+/**
+ * __media_remove_intf_link() - remove a single interface link
+ *
+ * @link:	pointer to &media_link.
+ *
+ * .. note:: This is an unlocked version of media_remove_intf_link()
+ */
+void __media_remove_intf_link(struct media_link *link);
+
+/**
+ * media_remove_intf_link() - remove a single interface link
+ *
+ * @link:	pointer to &media_link.
+ *
+ * .. note:: Prefer to use this one, instead of __media_remove_intf_link()
+ */
+void media_remove_intf_link(struct media_link *link);
+
+/**
+ * __media_remove_intf_links() - remove all links associated with an interface
+ *
+ * @intf:	pointer to &media_interface
+ *
+ * .. note:: This is an unlocked version of media_remove_intf_links().
+ */
+void __media_remove_intf_links(struct media_interface *intf);
+
+/**
+ * media_remove_intf_links() - remove all links associated with an interface
+ *
+ * @intf:	pointer to &media_interface
+ *
+ * .. note::
+ *
+ *   #) This is called automatically when an entity is unregistered via
+ *      media_device_register_entity() and by media_devnode_remove().
+ *
+ *   #) Prefer to use this one, instead of __media_remove_intf_links().
+ */
+void media_remove_intf_links(struct media_interface *intf);
+
+/**
+ * media_entity_call - Calls a struct media_entity_operations operation on
+ *	an entity
+ *
+ * @entity: entity where the @operation will be called
+ * @operation: type of the operation. Should be the name of a member of
+ *	struct &media_entity_operations.
+ *
+ * This helper function will check if @operation is not %NULL. On such case,
+ * it will issue a call to @operation\(@entity, @args\).
+ */
+
+#define media_entity_call(entity, operation, args...)			\
+	(((entity)->ops && (entity)->ops->operation) ?			\
+	 (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
+
+#endif
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
new file mode 100644
index 0000000..6157177
--- /dev/null
+++ b/include/media/rc-core.h
@@ -0,0 +1,402 @@
+/*
+ * Remote Controller core header
+ *
+ * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
+ *
+ * This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _RC_CORE
+#define _RC_CORE
+
+#include <linux/spinlock.h>
+#include <linux/cdev.h>
+#include <linux/kfifo.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <media/rc-map.h>
+
+/**
+ * enum rc_driver_type - type of the RC driver.
+ *
+ * @RC_DRIVER_SCANCODE:	 Driver or hardware generates a scancode.
+ * @RC_DRIVER_IR_RAW:	 Driver or hardware generates pulse/space sequences.
+ *			 It needs a Infra-Red pulse/space decoder
+ * @RC_DRIVER_IR_RAW_TX: Device transmitter only,
+ *			 driver requires pulse/space data sequence.
+ */
+enum rc_driver_type {
+	RC_DRIVER_SCANCODE = 0,
+	RC_DRIVER_IR_RAW,
+	RC_DRIVER_IR_RAW_TX,
+};
+
+/**
+ * struct rc_scancode_filter - Filter scan codes.
+ * @data:	Scancode data to match.
+ * @mask:	Mask of bits of scancode to compare.
+ */
+struct rc_scancode_filter {
+	u32 data;
+	u32 mask;
+};
+
+/**
+ * enum rc_filter_type - Filter type constants.
+ * @RC_FILTER_NORMAL:	Filter for normal operation.
+ * @RC_FILTER_WAKEUP:	Filter for waking from suspend.
+ * @RC_FILTER_MAX:	Number of filter types.
+ */
+enum rc_filter_type {
+	RC_FILTER_NORMAL = 0,
+	RC_FILTER_WAKEUP,
+
+	RC_FILTER_MAX
+};
+
+/**
+ * struct lirc_fh - represents an open lirc file
+ * @list: list of open file handles
+ * @rc: rcdev for this lirc chardev
+ * @carrier_low: when setting the carrier range, first the low end must be
+ *	set with an ioctl and then the high end with another ioctl
+ * @send_timeout_reports: report timeouts in lirc raw IR.
+ * @rawir: queue for incoming raw IR
+ * @scancodes: queue for incoming decoded scancodes
+ * @wait_poll: poll struct for lirc device
+ * @send_mode: lirc mode for sending, either LIRC_MODE_SCANCODE or
+ *	LIRC_MODE_PULSE
+ * @rec_mode: lirc mode for receiving, either LIRC_MODE_SCANCODE or
+ *	LIRC_MODE_MODE2
+ */
+struct lirc_fh {
+	struct list_head list;
+	struct rc_dev *rc;
+	int				carrier_low;
+	bool				send_timeout_reports;
+	DECLARE_KFIFO_PTR(rawir, unsigned int);
+	DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode);
+	wait_queue_head_t		wait_poll;
+	u8				send_mode;
+	u8				rec_mode;
+};
+
+/**
+ * struct rc_dev - represents a remote control device
+ * @dev: driver model's view of this device
+ * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
+ * @sysfs_groups: sysfs attribute groups
+ * @device_name: name of the rc child device
+ * @input_phys: physical path to the input child device
+ * @input_id: id of the input child device (struct input_id)
+ * @driver_name: name of the hardware driver which registered this device
+ * @map_name: name of the default keymap
+ * @rc_map: current scan/key table
+ * @lock: used to ensure we've filled in all protocol details before
+ *	anyone can call show_protocols or store_protocols
+ * @minor: unique minor remote control device number
+ * @raw: additional data for raw pulse/space devices
+ * @input_dev: the input child device used to communicate events to userspace
+ * @driver_type: specifies if protocol decoding is done in hardware or software
+ * @idle: used to keep track of RX state
+ * @encode_wakeup: wakeup filtering uses IR encode API, therefore the allowed
+ *	wakeup protocols is the set of all raw encoders
+ * @allowed_protocols: bitmask with the supported RC_PROTO_BIT_* protocols
+ * @enabled_protocols: bitmask with the enabled RC_PROTO_BIT_* protocols
+ * @allowed_wakeup_protocols: bitmask with the supported RC_PROTO_BIT_* wakeup
+ *	protocols
+ * @wakeup_protocol: the enabled RC_PROTO_* wakeup protocol or
+ *	RC_PROTO_UNKNOWN if disabled.
+ * @scancode_filter: scancode filter
+ * @scancode_wakeup_filter: scancode wakeup filters
+ * @scancode_mask: some hardware decoders are not capable of providing the full
+ *	scancode to the application. As this is a hardware limit, we can't do
+ *	anything with it. Yet, as the same keycode table can be used with other
+ *	devices, a mask is provided to allow its usage. Drivers should generally
+ *	leave this field in blank
+ * @users: number of current users of the device
+ * @priv: driver-specific data
+ * @keylock: protects the remaining members of the struct
+ * @keypressed: whether a key is currently pressed
+ * @keyup_jiffies: time (in jiffies) when the current keypress should be released
+ * @timer_keyup: timer for releasing a keypress
+ * @timer_repeat: timer for autorepeat events. This is needed for CEC, which
+ *	has non-standard repeats.
+ * @last_keycode: keycode of last keypress
+ * @last_protocol: protocol of last keypress
+ * @last_scancode: scancode of last keypress
+ * @last_toggle: toggle value of last command
+ * @timeout: optional time after which device stops sending data
+ * @min_timeout: minimum timeout supported by device
+ * @max_timeout: maximum timeout supported by device
+ * @rx_resolution : resolution (in ns) of input sampler
+ * @tx_resolution: resolution (in ns) of output sampler
+ * @lirc_dev: lirc device
+ * @lirc_cdev: lirc char cdev
+ * @gap_start: time when gap starts
+ * @gap_duration: duration of initial gap
+ * @gap: true if we're in a gap
+ * @lirc_fh_lock: protects lirc_fh list
+ * @lirc_fh: list of open files
+ * @registered: set to true by rc_register_device(), false by
+ *	rc_unregister_device
+ * @change_protocol: allow changing the protocol used on hardware decoders
+ * @open: callback to allow drivers to enable polling/irq when IR input device
+ *	is opened.
+ * @close: callback to allow drivers to disable polling/irq when IR input device
+ *	is opened.
+ * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
+ * @s_tx_carrier: set transmit carrier frequency
+ * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
+ * @s_rx_carrier_range: inform driver about carrier it is expected to handle
+ * @tx_ir: transmit IR
+ * @s_idle: enable/disable hardware idle mode, upon which,
+ *	device doesn't interrupt host until it sees IR pulses
+ * @s_learning_mode: enable wide band receiver used for learning
+ * @s_carrier_report: enable carrier reports
+ * @s_filter: set the scancode filter
+ * @s_wakeup_filter: set the wakeup scancode filter. If the mask is zero
+ *	then wakeup should be disabled. wakeup_protocol will be set to
+ *	a valid protocol if mask is nonzero.
+ * @s_timeout: set hardware timeout in ns
+ */
+struct rc_dev {
+	struct device			dev;
+	bool				managed_alloc;
+	const struct attribute_group	*sysfs_groups[5];
+	const char			*device_name;
+	const char			*input_phys;
+	struct input_id			input_id;
+	const char			*driver_name;
+	const char			*map_name;
+	struct rc_map			rc_map;
+	struct mutex			lock;
+	unsigned int			minor;
+	struct ir_raw_event_ctrl	*raw;
+	struct input_dev		*input_dev;
+	enum rc_driver_type		driver_type;
+	bool				idle;
+	bool				encode_wakeup;
+	u64				allowed_protocols;
+	u64				enabled_protocols;
+	u64				allowed_wakeup_protocols;
+	enum rc_proto			wakeup_protocol;
+	struct rc_scancode_filter	scancode_filter;
+	struct rc_scancode_filter	scancode_wakeup_filter;
+	u32				scancode_mask;
+	u32				users;
+	void				*priv;
+	spinlock_t			keylock;
+	bool				keypressed;
+	unsigned long			keyup_jiffies;
+	struct timer_list		timer_keyup;
+	struct timer_list		timer_repeat;
+	u32				last_keycode;
+	enum rc_proto			last_protocol;
+	u32				last_scancode;
+	u8				last_toggle;
+	u32				timeout;
+	u32				min_timeout;
+	u32				max_timeout;
+	u32				rx_resolution;
+	u32				tx_resolution;
+#ifdef CONFIG_LIRC
+	struct device			lirc_dev;
+	struct cdev			lirc_cdev;
+	ktime_t				gap_start;
+	u64				gap_duration;
+	bool				gap;
+	spinlock_t			lirc_fh_lock;
+	struct list_head		lirc_fh;
+#endif
+	bool				registered;
+	int				(*change_protocol)(struct rc_dev *dev, u64 *rc_proto);
+	int				(*open)(struct rc_dev *dev);
+	void				(*close)(struct rc_dev *dev);
+	int				(*s_tx_mask)(struct rc_dev *dev, u32 mask);
+	int				(*s_tx_carrier)(struct rc_dev *dev, u32 carrier);
+	int				(*s_tx_duty_cycle)(struct rc_dev *dev, u32 duty_cycle);
+	int				(*s_rx_carrier_range)(struct rc_dev *dev, u32 min, u32 max);
+	int				(*tx_ir)(struct rc_dev *dev, unsigned *txbuf, unsigned n);
+	void				(*s_idle)(struct rc_dev *dev, bool enable);
+	int				(*s_learning_mode)(struct rc_dev *dev, int enable);
+	int				(*s_carrier_report) (struct rc_dev *dev, int enable);
+	int				(*s_filter)(struct rc_dev *dev,
+						    struct rc_scancode_filter *filter);
+	int				(*s_wakeup_filter)(struct rc_dev *dev,
+							   struct rc_scancode_filter *filter);
+	int				(*s_timeout)(struct rc_dev *dev,
+						     unsigned int timeout);
+};
+
+#define to_rc_dev(d) container_of(d, struct rc_dev, dev)
+
+/*
+ * From rc-main.c
+ * Those functions can be used on any type of Remote Controller. They
+ * basically creates an input_dev and properly reports the device as a
+ * Remote Controller, at sys/class/rc.
+ */
+
+/**
+ * rc_allocate_device - Allocates a RC device
+ *
+ * @rc_driver_type: specifies the type of the RC output to be allocated
+ * returns a pointer to struct rc_dev.
+ */
+struct rc_dev *rc_allocate_device(enum rc_driver_type);
+
+/**
+ * devm_rc_allocate_device - Managed RC device allocation
+ *
+ * @dev: pointer to struct device
+ * @rc_driver_type: specifies the type of the RC output to be allocated
+ * returns a pointer to struct rc_dev.
+ */
+struct rc_dev *devm_rc_allocate_device(struct device *dev, enum rc_driver_type);
+
+/**
+ * rc_free_device - Frees a RC device
+ *
+ * @dev: pointer to struct rc_dev.
+ */
+void rc_free_device(struct rc_dev *dev);
+
+/**
+ * rc_register_device - Registers a RC device
+ *
+ * @dev: pointer to struct rc_dev.
+ */
+int rc_register_device(struct rc_dev *dev);
+
+/**
+ * devm_rc_register_device - Manageded registering of a RC device
+ *
+ * @parent: pointer to struct device.
+ * @dev: pointer to struct rc_dev.
+ */
+int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
+
+/**
+ * rc_unregister_device - Unregisters a RC device
+ *
+ * @dev: pointer to struct rc_dev.
+ */
+void rc_unregister_device(struct rc_dev *dev);
+
+void rc_repeat(struct rc_dev *dev);
+void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
+		u8 toggle);
+void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
+			  u32 scancode, u8 toggle);
+void rc_keyup(struct rc_dev *dev);
+u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode);
+
+/*
+ * From rc-raw.c
+ * The Raw interface is specific to InfraRed. It may be a good idea to
+ * split it later into a separate header.
+ */
+struct ir_raw_event {
+	union {
+		u32             duration;
+		u32             carrier;
+	};
+	u8                      duty_cycle;
+
+	unsigned                pulse:1;
+	unsigned                reset:1;
+	unsigned                timeout:1;
+	unsigned                carrier_report:1;
+};
+
+#define DEFINE_IR_RAW_EVENT(event) struct ir_raw_event event = {}
+
+static inline void init_ir_raw_event(struct ir_raw_event *ev)
+{
+	memset(ev, 0, sizeof(*ev));
+}
+
+#define IR_DEFAULT_TIMEOUT	MS_TO_NS(125)
+#define IR_MAX_DURATION         500000000	/* 500 ms */
+#define US_TO_NS(usec)		((usec) * 1000)
+#define MS_TO_US(msec)		((msec) * 1000)
+#define MS_TO_NS(msec)		((msec) * 1000 * 1000)
+
+void ir_raw_event_handle(struct rc_dev *dev);
+int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev);
+int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse);
+int ir_raw_event_store_with_filter(struct rc_dev *dev,
+				   struct ir_raw_event *ev);
+int ir_raw_event_store_with_timeout(struct rc_dev *dev,
+				    struct ir_raw_event *ev);
+void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
+int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
+			   struct ir_raw_event *events, unsigned int max);
+int ir_raw_encode_carrier(enum rc_proto protocol);
+
+static inline void ir_raw_event_reset(struct rc_dev *dev)
+{
+	struct ir_raw_event ev = { .reset = true };
+
+	ir_raw_event_store(dev, &ev);
+	dev->idle = true;
+	ir_raw_event_handle(dev);
+}
+
+/* extract mask bits out of data and pack them into the result */
+static inline u32 ir_extract_bits(u32 data, u32 mask)
+{
+	u32 vbit = 1, value = 0;
+
+	do {
+		if (mask & 1) {
+			if (data & 1)
+				value |= vbit;
+			vbit <<= 1;
+		}
+		data >>= 1;
+	} while (mask >>= 1);
+
+	return value;
+}
+
+/* Get NEC scancode and protocol type from address and command bytes */
+static inline u32 ir_nec_bytes_to_scancode(u8 address, u8 not_address,
+					   u8 command, u8 not_command,
+					   enum rc_proto *protocol)
+{
+	u32 scancode;
+
+	if ((command ^ not_command) != 0xff) {
+		/* NEC transport, but modified protocol, used by at
+		 * least Apple and TiVo remotes
+		 */
+		scancode = not_address << 24 |
+			address     << 16 |
+			not_command <<  8 |
+			command;
+		*protocol = RC_PROTO_NEC32;
+	} else if ((address ^ not_address) != 0xff) {
+		/* Extended NEC */
+		scancode = address     << 16 |
+			   not_address <<  8 |
+			   command;
+		*protocol = RC_PROTO_NECX;
+	} else {
+		/* Normal NEC */
+		scancode = address << 8 | command;
+		*protocol = RC_PROTO_NEC;
+	}
+
+	return scancode;
+}
+
+#endif /* _RC_CORE */
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
new file mode 100644
index 0000000..bfa3017
--- /dev/null
+++ b/include/media/rc-map.h
@@ -0,0 +1,285 @@
+/*
+ * rc-map.h - define RC map names used by RC drivers
+ *
+ * Copyright (c) 2010 by Mauro Carvalho Chehab
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/input.h>
+#include <uapi/linux/lirc.h>
+
+#define RC_PROTO_BIT_NONE		0ULL
+#define RC_PROTO_BIT_UNKNOWN		BIT_ULL(RC_PROTO_UNKNOWN)
+#define RC_PROTO_BIT_OTHER		BIT_ULL(RC_PROTO_OTHER)
+#define RC_PROTO_BIT_RC5		BIT_ULL(RC_PROTO_RC5)
+#define RC_PROTO_BIT_RC5X_20		BIT_ULL(RC_PROTO_RC5X_20)
+#define RC_PROTO_BIT_RC5_SZ		BIT_ULL(RC_PROTO_RC5_SZ)
+#define RC_PROTO_BIT_JVC		BIT_ULL(RC_PROTO_JVC)
+#define RC_PROTO_BIT_SONY12		BIT_ULL(RC_PROTO_SONY12)
+#define RC_PROTO_BIT_SONY15		BIT_ULL(RC_PROTO_SONY15)
+#define RC_PROTO_BIT_SONY20		BIT_ULL(RC_PROTO_SONY20)
+#define RC_PROTO_BIT_NEC		BIT_ULL(RC_PROTO_NEC)
+#define RC_PROTO_BIT_NECX		BIT_ULL(RC_PROTO_NECX)
+#define RC_PROTO_BIT_NEC32		BIT_ULL(RC_PROTO_NEC32)
+#define RC_PROTO_BIT_SANYO		BIT_ULL(RC_PROTO_SANYO)
+#define RC_PROTO_BIT_MCIR2_KBD		BIT_ULL(RC_PROTO_MCIR2_KBD)
+#define RC_PROTO_BIT_MCIR2_MSE		BIT_ULL(RC_PROTO_MCIR2_MSE)
+#define RC_PROTO_BIT_RC6_0		BIT_ULL(RC_PROTO_RC6_0)
+#define RC_PROTO_BIT_RC6_6A_20		BIT_ULL(RC_PROTO_RC6_6A_20)
+#define RC_PROTO_BIT_RC6_6A_24		BIT_ULL(RC_PROTO_RC6_6A_24)
+#define RC_PROTO_BIT_RC6_6A_32		BIT_ULL(RC_PROTO_RC6_6A_32)
+#define RC_PROTO_BIT_RC6_MCE		BIT_ULL(RC_PROTO_RC6_MCE)
+#define RC_PROTO_BIT_SHARP		BIT_ULL(RC_PROTO_SHARP)
+#define RC_PROTO_BIT_XMP		BIT_ULL(RC_PROTO_XMP)
+#define RC_PROTO_BIT_CEC		BIT_ULL(RC_PROTO_CEC)
+#define RC_PROTO_BIT_IMON		BIT_ULL(RC_PROTO_IMON)
+
+#define RC_PROTO_BIT_ALL \
+			(RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \
+			 RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
+			 RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \
+			 RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \
+			 RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \
+			 RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \
+			 RC_PROTO_BIT_SANYO | \
+			 RC_PROTO_BIT_MCIR2_KBD | RC_PROTO_BIT_MCIR2_MSE | \
+			 RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \
+			 RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \
+			 RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \
+			 RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \
+			 RC_PROTO_BIT_IMON)
+/* All rc protocols for which we have decoders */
+#define RC_PROTO_BIT_ALL_IR_DECODER \
+			(RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
+			 RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \
+			 RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \
+			 RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \
+			 RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \
+			 RC_PROTO_BIT_SANYO | RC_PROTO_BIT_MCIR2_KBD | \
+			 RC_PROTO_BIT_MCIR2_MSE | \
+			 RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \
+			 RC_PROTO_BIT_RC6_6A_24 |  RC_PROTO_BIT_RC6_6A_32 | \
+			 RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \
+			 RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON)
+
+#define RC_PROTO_BIT_ALL_IR_ENCODER \
+			(RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
+			 RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \
+			 RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \
+			 RC_PROTO_BIT_SONY20 |  RC_PROTO_BIT_NEC | \
+			 RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \
+			 RC_PROTO_BIT_SANYO | RC_PROTO_BIT_MCIR2_KBD | \
+			 RC_PROTO_BIT_MCIR2_MSE | \
+			 RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \
+			 RC_PROTO_BIT_RC6_6A_24 | \
+			 RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \
+			 RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON)
+
+#define RC_SCANCODE_UNKNOWN(x)			(x)
+#define RC_SCANCODE_OTHER(x)			(x)
+#define RC_SCANCODE_NEC(addr, cmd)		(((addr) << 8) | (cmd))
+#define RC_SCANCODE_NECX(addr, cmd)		(((addr) << 8) | (cmd))
+#define RC_SCANCODE_NEC32(data)			((data) & 0xffffffff)
+#define RC_SCANCODE_RC5(sys, cmd)		(((sys) << 8) | (cmd))
+#define RC_SCANCODE_RC5_SZ(sys, cmd)		(((sys) << 8) | (cmd))
+#define RC_SCANCODE_RC6_0(sys, cmd)		(((sys) << 8) | (cmd))
+#define RC_SCANCODE_RC6_6A(vendor, sys, cmd)	(((vendor) << 16) | ((sys) << 8) | (cmd))
+
+/**
+ * struct rc_map_table - represents a scancode/keycode pair
+ *
+ * @scancode: scan code (u32)
+ * @keycode: Linux input keycode
+ */
+struct rc_map_table {
+	u32	scancode;
+	u32	keycode;
+};
+
+/**
+ * struct rc_map - represents a keycode map table
+ *
+ * @scan: pointer to struct &rc_map_table
+ * @size: Max number of entries
+ * @len: Number of entries that are in use
+ * @alloc: size of \*scan, in bytes
+ * @rc_proto: type of the remote controller protocol, as defined at
+ *	     enum &rc_proto
+ * @name: name of the key map table
+ * @lock: lock to protect access to this structure
+ */
+struct rc_map {
+	struct rc_map_table	*scan;
+	unsigned int		size;
+	unsigned int		len;
+	unsigned int		alloc;
+	enum rc_proto		rc_proto;
+	const char		*name;
+	spinlock_t		lock;
+};
+
+/**
+ * struct rc_map_list - list of the registered &rc_map maps
+ *
+ * @list: pointer to struct &list_head
+ * @map: pointer to struct &rc_map
+ */
+struct rc_map_list {
+	struct list_head	 list;
+	struct rc_map map;
+};
+
+/* Routines from rc-map.c */
+
+/**
+ * rc_map_register() - Registers a Remote Controler scancode map
+ *
+ * @map:	pointer to struct rc_map_list
+ */
+int rc_map_register(struct rc_map_list *map);
+
+/**
+ * rc_map_unregister() - Unregisters a Remote Controler scancode map
+ *
+ * @map:	pointer to struct rc_map_list
+ */
+void rc_map_unregister(struct rc_map_list *map);
+
+/**
+ * rc_map_get - gets an RC map from its name
+ * @name: name of the RC scancode map
+ */
+struct rc_map *rc_map_get(const char *name);
+
+/* Names of the several keytables defined in-kernel */
+
+#define RC_MAP_ADSTECH_DVB_T_PCI         "rc-adstech-dvb-t-pci"
+#define RC_MAP_ALINK_DTU_M               "rc-alink-dtu-m"
+#define RC_MAP_ANYSEE                    "rc-anysee"
+#define RC_MAP_APAC_VIEWCOMP             "rc-apac-viewcomp"
+#define RC_MAP_ASTROMETA_T2HYBRID        "rc-astrometa-t2hybrid"
+#define RC_MAP_ASUS_PC39                 "rc-asus-pc39"
+#define RC_MAP_ASUS_PS3_100              "rc-asus-ps3-100"
+#define RC_MAP_ATI_TV_WONDER_HD_600      "rc-ati-tv-wonder-hd-600"
+#define RC_MAP_ATI_X10                   "rc-ati-x10"
+#define RC_MAP_AVERMEDIA_A16D            "rc-avermedia-a16d"
+#define RC_MAP_AVERMEDIA_CARDBUS         "rc-avermedia-cardbus"
+#define RC_MAP_AVERMEDIA_DVBT            "rc-avermedia-dvbt"
+#define RC_MAP_AVERMEDIA_M135A           "rc-avermedia-m135a"
+#define RC_MAP_AVERMEDIA_M733A_RM_K6     "rc-avermedia-m733a-rm-k6"
+#define RC_MAP_AVERMEDIA_RM_KS           "rc-avermedia-rm-ks"
+#define RC_MAP_AVERMEDIA                 "rc-avermedia"
+#define RC_MAP_AVERTV_303                "rc-avertv-303"
+#define RC_MAP_AZUREWAVE_AD_TU700        "rc-azurewave-ad-tu700"
+#define RC_MAP_BEHOLD_COLUMBUS           "rc-behold-columbus"
+#define RC_MAP_BEHOLD                    "rc-behold"
+#define RC_MAP_BUDGET_CI_OLD             "rc-budget-ci-old"
+#define RC_MAP_CEC                       "rc-cec"
+#define RC_MAP_CINERGY_1400              "rc-cinergy-1400"
+#define RC_MAP_CINERGY                   "rc-cinergy"
+#define RC_MAP_D680_DMB                  "rc-d680-dmb"
+#define RC_MAP_DELOCK_61959              "rc-delock-61959"
+#define RC_MAP_DIB0700_NEC_TABLE         "rc-dib0700-nec"
+#define RC_MAP_DIB0700_RC5_TABLE         "rc-dib0700-rc5"
+#define RC_MAP_DIGITALNOW_TINYTWIN       "rc-digitalnow-tinytwin"
+#define RC_MAP_DIGITTRADE                "rc-digittrade"
+#define RC_MAP_DM1105_NEC                "rc-dm1105-nec"
+#define RC_MAP_DNTV_LIVE_DVBT_PRO        "rc-dntv-live-dvbt-pro"
+#define RC_MAP_DNTV_LIVE_DVB_T           "rc-dntv-live-dvb-t"
+#define RC_MAP_DTT200U                   "rc-dtt200u"
+#define RC_MAP_DVBSKY                    "rc-dvbsky"
+#define RC_MAP_DVICO_MCE		 "rc-dvico-mce"
+#define RC_MAP_DVICO_PORTABLE		 "rc-dvico-portable"
+#define RC_MAP_EMPTY                     "rc-empty"
+#define RC_MAP_EM_TERRATEC               "rc-em-terratec"
+#define RC_MAP_ENCORE_ENLTV2             "rc-encore-enltv2"
+#define RC_MAP_ENCORE_ENLTV_FM53         "rc-encore-enltv-fm53"
+#define RC_MAP_ENCORE_ENLTV              "rc-encore-enltv"
+#define RC_MAP_EVGA_INDTUBE              "rc-evga-indtube"
+#define RC_MAP_EZTV                      "rc-eztv"
+#define RC_MAP_FLYDVB                    "rc-flydvb"
+#define RC_MAP_FLYVIDEO                  "rc-flyvideo"
+#define RC_MAP_FUSIONHDTV_MCE            "rc-fusionhdtv-mce"
+#define RC_MAP_GADMEI_RM008Z             "rc-gadmei-rm008z"
+#define RC_MAP_GEEKBOX                   "rc-geekbox"
+#define RC_MAP_GENIUS_TVGO_A11MCE        "rc-genius-tvgo-a11mce"
+#define RC_MAP_GOTVIEW7135               "rc-gotview7135"
+#define RC_MAP_HAUPPAUGE_NEW             "rc-hauppauge"
+#define RC_MAP_HISI_POPLAR               "rc-hisi-poplar"
+#define RC_MAP_HISI_TV_DEMO              "rc-hisi-tv-demo"
+#define RC_MAP_IMON_MCE                  "rc-imon-mce"
+#define RC_MAP_IMON_PAD                  "rc-imon-pad"
+#define RC_MAP_IMON_RSC                  "rc-imon-rsc"
+#define RC_MAP_IODATA_BCTV7E             "rc-iodata-bctv7e"
+#define RC_MAP_IT913X_V1                 "rc-it913x-v1"
+#define RC_MAP_IT913X_V2                 "rc-it913x-v2"
+#define RC_MAP_KAIOMY                    "rc-kaiomy"
+#define RC_MAP_KWORLD_315U               "rc-kworld-315u"
+#define RC_MAP_KWORLD_PC150U             "rc-kworld-pc150u"
+#define RC_MAP_KWORLD_PLUS_TV_ANALOG     "rc-kworld-plus-tv-analog"
+#define RC_MAP_LEADTEK_Y04G0051          "rc-leadtek-y04g0051"
+#define RC_MAP_LME2510                   "rc-lme2510"
+#define RC_MAP_MANLI                     "rc-manli"
+#define RC_MAP_MEDION_X10                "rc-medion-x10"
+#define RC_MAP_MEDION_X10_DIGITAINER     "rc-medion-x10-digitainer"
+#define RC_MAP_MEDION_X10_OR2X           "rc-medion-x10-or2x"
+#define RC_MAP_MSI_DIGIVOX_II            "rc-msi-digivox-ii"
+#define RC_MAP_MSI_DIGIVOX_III           "rc-msi-digivox-iii"
+#define RC_MAP_MSI_TVANYWHERE_PLUS       "rc-msi-tvanywhere-plus"
+#define RC_MAP_MSI_TVANYWHERE            "rc-msi-tvanywhere"
+#define RC_MAP_NEBULA                    "rc-nebula"
+#define RC_MAP_NEC_TERRATEC_CINERGY_XS   "rc-nec-terratec-cinergy-xs"
+#define RC_MAP_NORWOOD                   "rc-norwood"
+#define RC_MAP_NPGTECH                   "rc-npgtech"
+#define RC_MAP_PCTV_SEDNA                "rc-pctv-sedna"
+#define RC_MAP_PINNACLE_COLOR            "rc-pinnacle-color"
+#define RC_MAP_PINNACLE_GREY             "rc-pinnacle-grey"
+#define RC_MAP_PINNACLE_PCTV_HD          "rc-pinnacle-pctv-hd"
+#define RC_MAP_PIXELVIEW_NEW             "rc-pixelview-new"
+#define RC_MAP_PIXELVIEW                 "rc-pixelview"
+#define RC_MAP_PIXELVIEW_002T		 "rc-pixelview-002t"
+#define RC_MAP_PIXELVIEW_MK12            "rc-pixelview-mk12"
+#define RC_MAP_POWERCOLOR_REAL_ANGEL     "rc-powercolor-real-angel"
+#define RC_MAP_PROTEUS_2309              "rc-proteus-2309"
+#define RC_MAP_PURPLETV                  "rc-purpletv"
+#define RC_MAP_PV951                     "rc-pv951"
+#define RC_MAP_HAUPPAUGE                 "rc-hauppauge"
+#define RC_MAP_RC5_TV                    "rc-rc5-tv"
+#define RC_MAP_RC6_MCE                   "rc-rc6-mce"
+#define RC_MAP_REAL_AUDIO_220_32_KEYS    "rc-real-audio-220-32-keys"
+#define RC_MAP_REDDO                     "rc-reddo"
+#define RC_MAP_SNAPSTREAM_FIREFLY        "rc-snapstream-firefly"
+#define RC_MAP_STREAMZAP                 "rc-streamzap"
+#define RC_MAP_TANGO                     "rc-tango"
+#define RC_MAP_TBS_NEC                   "rc-tbs-nec"
+#define RC_MAP_TECHNISAT_TS35            "rc-technisat-ts35"
+#define RC_MAP_TECHNISAT_USB2            "rc-technisat-usb2"
+#define RC_MAP_TERRATEC_CINERGY_C_PCI    "rc-terratec-cinergy-c-pci"
+#define RC_MAP_TERRATEC_CINERGY_S2_HD    "rc-terratec-cinergy-s2-hd"
+#define RC_MAP_TERRATEC_CINERGY_XS       "rc-terratec-cinergy-xs"
+#define RC_MAP_TERRATEC_SLIM             "rc-terratec-slim"
+#define RC_MAP_TERRATEC_SLIM_2           "rc-terratec-slim-2"
+#define RC_MAP_TEVII_NEC                 "rc-tevii-nec"
+#define RC_MAP_TIVO                      "rc-tivo"
+#define RC_MAP_TOTAL_MEDIA_IN_HAND       "rc-total-media-in-hand"
+#define RC_MAP_TOTAL_MEDIA_IN_HAND_02    "rc-total-media-in-hand-02"
+#define RC_MAP_TREKSTOR                  "rc-trekstor"
+#define RC_MAP_TT_1500                   "rc-tt-1500"
+#define RC_MAP_TWINHAN_DTV_CAB_CI        "rc-twinhan-dtv-cab-ci"
+#define RC_MAP_TWINHAN_VP1027_DVBS       "rc-twinhan1027"
+#define RC_MAP_VIDEOMATE_K100            "rc-videomate-k100"
+#define RC_MAP_VIDEOMATE_S350            "rc-videomate-s350"
+#define RC_MAP_VIDEOMATE_TV_PVR          "rc-videomate-tv-pvr"
+#define RC_MAP_WINFAST                   "rc-winfast"
+#define RC_MAP_WINFAST_USBII_DELUXE      "rc-winfast-usbii-deluxe"
+#define RC_MAP_SU3000                    "rc-su3000"
+#define RC_MAP_ZX_IRDEC                  "rc-zx-irdec"
+
+/*
+ * Please, do not just append newer Remote Controller names at the end.
+ * The names should be ordered in alphabetical order
+ */
diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
new file mode 100644
index 0000000..b60a7b1
--- /dev/null
+++ b/include/media/rcar-fcp.h
@@ -0,0 +1,42 @@
+/*
+ * rcar-fcp.h  --  R-Car Frame Compression Processor Driver
+ *
+ * Copyright (C) 2016 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MEDIA_RCAR_FCP_H__
+#define __MEDIA_RCAR_FCP_H__
+
+struct device_node;
+struct rcar_fcp_device;
+
+#if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
+struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
+void rcar_fcp_put(struct rcar_fcp_device *fcp);
+struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp);
+int rcar_fcp_enable(struct rcar_fcp_device *fcp);
+void rcar_fcp_disable(struct rcar_fcp_device *fcp);
+#else
+static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
+{
+	return ERR_PTR(-ENOENT);
+}
+static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
+static inline struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
+{
+	return NULL;
+}
+static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
+{
+	return 0;
+}
+static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { }
+#endif
+
+#endif /* __MEDIA_RCAR_FCP_H__ */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
new file mode 100644
index 0000000..b7e42a1
--- /dev/null
+++ b/include/media/soc_camera.h
@@ -0,0 +1,400 @@
+/*
+ * camera image capture (abstract) bus driver header
+ *
+ * Copyright (C) 2006, Sascha Hauer, Pengutronix
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef SOC_CAMERA_H
+#define SOC_CAMERA_H
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/pm.h>
+#include <linux/videodev2.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+
+struct file;
+struct soc_camera_desc;
+struct soc_camera_async_client;
+
+struct soc_camera_device {
+	struct list_head list;		/* list of all registered devices */
+	struct soc_camera_desc *sdesc;
+	struct device *pdev;		/* Platform device */
+	struct device *parent;		/* Camera host device */
+	struct device *control;		/* E.g., the i2c client */
+	s32 user_width;
+	s32 user_height;
+	u32 bytesperline;		/* for padding, zero if unused */
+	u32 sizeimage;
+	enum v4l2_colorspace colorspace;
+	unsigned char iface;		/* Host number */
+	unsigned char devnum;		/* Device number per host */
+	struct soc_camera_sense *sense;	/* See comment in struct definition */
+	struct video_device *vdev;
+	struct v4l2_ctrl_handler ctrl_handler;
+	const struct soc_camera_format_xlate *current_fmt;
+	struct soc_camera_format_xlate *user_formats;
+	int num_user_formats;
+	enum v4l2_field field;		/* Preserve field over close() */
+	void *host_priv;		/* Per-device host private data */
+	/* soc_camera.c private count. Only accessed with .host_lock held */
+	int use_count;
+	struct file *streamer;		/* stream owner */
+	struct v4l2_clk *clk;
+	/* Asynchronous subdevice management */
+	struct soc_camera_async_client *sasc;
+	/* video buffer queue */
+	struct vb2_queue vb2_vidq;
+};
+
+/* Host supports programmable stride */
+#define SOCAM_HOST_CAP_STRIDE		(1 << 0)
+
+enum soc_camera_subdev_role {
+	SOCAM_SUBDEV_DATA_SOURCE = 1,
+	SOCAM_SUBDEV_DATA_SINK,
+	SOCAM_SUBDEV_DATA_PROCESSOR,
+};
+
+struct soc_camera_async_subdev {
+	struct v4l2_async_subdev asd;
+	enum soc_camera_subdev_role role;
+};
+
+struct soc_camera_host {
+	struct v4l2_device v4l2_dev;
+	struct list_head list;
+	struct mutex host_lock;		/* Main synchronisation lock */
+	struct mutex clk_lock;		/* Protect pipeline modifications */
+	unsigned char nr;		/* Host number */
+	u32 capabilities;
+	struct soc_camera_device *icd;	/* Currently attached client */
+	void *priv;
+	const char *drv_name;
+	struct soc_camera_host_ops *ops;
+	struct v4l2_async_subdev **asd;	/* Flat array, arranged in groups */
+	unsigned int *asd_sizes;	/* 0-terminated array of asd group sizes */
+};
+
+struct soc_camera_host_ops {
+	struct module *owner;
+	int (*add)(struct soc_camera_device *);
+	void (*remove)(struct soc_camera_device *);
+	int (*clock_start)(struct soc_camera_host *);
+	void (*clock_stop)(struct soc_camera_host *);
+	/*
+	 * .get_formats() is called for each client device format, but
+	 * .put_formats() is only called once. Further, if any of the calls to
+	 * .get_formats() fail, .put_formats() will not be called at all, the
+	 * failing .get_formats() must then clean up internally.
+	 */
+	int (*get_formats)(struct soc_camera_device *, unsigned int,
+			   struct soc_camera_format_xlate *);
+	void (*put_formats)(struct soc_camera_device *);
+	int (*get_selection)(struct soc_camera_device *, struct v4l2_selection *);
+	int (*set_selection)(struct soc_camera_device *, struct v4l2_selection *);
+	/*
+	 * The difference to .set_selection() is, that .set_liveselection is not allowed
+	 * to change the output sizes
+	 */
+	int (*set_liveselection)(struct soc_camera_device *, struct v4l2_selection *);
+	int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
+	int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
+	int (*init_videobuf2)(struct vb2_queue *,
+			      struct soc_camera_device *);
+	int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
+	int (*set_bus_param)(struct soc_camera_device *);
+	int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
+	int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
+	int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
+	__poll_t (*poll)(struct file *, poll_table *);
+};
+
+#define SOCAM_SENSOR_INVERT_PCLK	(1 << 0)
+#define SOCAM_SENSOR_INVERT_MCLK	(1 << 1)
+#define SOCAM_SENSOR_INVERT_HSYNC	(1 << 2)
+#define SOCAM_SENSOR_INVERT_VSYNC	(1 << 3)
+#define SOCAM_SENSOR_INVERT_DATA	(1 << 4)
+
+struct i2c_board_info;
+struct regulator_bulk_data;
+
+struct soc_camera_subdev_desc {
+	/* Per camera SOCAM_SENSOR_* bus flags */
+	unsigned long flags;
+
+	/* sensor driver private platform data */
+	void *drv_priv;
+
+	/*
+	 * Set unbalanced_power to true to deal with legacy drivers, failing to
+	 * balance their calls to subdevice's .s_power() method. clock_state is
+	 * then used internally by helper functions, it shouldn't be touched by
+	 * drivers or the platform code.
+	 */
+	bool unbalanced_power;
+	unsigned long clock_state;
+
+	/* Optional callbacks to power on or off and reset the sensor */
+	int (*power)(struct device *, int);
+	int (*reset)(struct device *);
+
+	/*
+	 * some platforms may support different data widths than the sensors
+	 * native ones due to different data line routing. Let the board code
+	 * overwrite the width flags.
+	 */
+	int (*set_bus_param)(struct soc_camera_subdev_desc *, unsigned long flags);
+	unsigned long (*query_bus_param)(struct soc_camera_subdev_desc *);
+	void (*free_bus)(struct soc_camera_subdev_desc *);
+
+	/* Optional regulators that have to be managed on power on/off events */
+	struct v4l2_subdev_platform_data sd_pdata;
+};
+
+struct soc_camera_host_desc {
+	/* Camera bus id, used to match a camera and a bus */
+	int bus_id;
+	int i2c_adapter_id;
+	struct i2c_board_info *board_info;
+	const char *module_name;
+
+	/*
+	 * For non-I2C devices platform has to provide methods to add a device
+	 * to the system and to remove it
+	 */
+	int (*add_device)(struct soc_camera_device *);
+	void (*del_device)(struct soc_camera_device *);
+};
+
+/*
+ * Platform data for "soc-camera-pdrv"
+ * This MUST be kept binary-identical to struct soc_camera_link below, until
+ * it is completely replaced by this one, after which we can split it into its
+ * two components.
+ */
+struct soc_camera_desc {
+	struct soc_camera_subdev_desc subdev_desc;
+	struct soc_camera_host_desc host_desc;
+};
+
+/* Prepare to replace this struct: don't change its layout any more! */
+struct soc_camera_link {
+	/*
+	 * Subdevice part - keep at top and compatible to
+	 * struct soc_camera_subdev_desc
+	 */
+
+	/* Per camera SOCAM_SENSOR_* bus flags */
+	unsigned long flags;
+
+	void *priv;
+
+	/* Set by platforms to handle misbehaving drivers */
+	bool unbalanced_power;
+	/* Used by soc-camera helper functions */
+	unsigned long clock_state;
+
+	/* Optional callbacks to power on or off and reset the sensor */
+	int (*power)(struct device *, int);
+	int (*reset)(struct device *);
+	/*
+	 * some platforms may support different data widths than the sensors
+	 * native ones due to different data line routing. Let the board code
+	 * overwrite the width flags.
+	 */
+	int (*set_bus_param)(struct soc_camera_link *, unsigned long flags);
+	unsigned long (*query_bus_param)(struct soc_camera_link *);
+	void (*free_bus)(struct soc_camera_link *);
+
+	/* Optional regulators that have to be managed on power on/off events */
+	struct regulator_bulk_data *regulators;
+	int num_regulators;
+
+	void *host_priv;
+
+	/*
+	 * Host part - keep at bottom and compatible to
+	 * struct soc_camera_host_desc
+	 */
+
+	/* Camera bus id, used to match a camera and a bus */
+	int bus_id;
+	int i2c_adapter_id;
+	struct i2c_board_info *board_info;
+	const char *module_name;
+
+	/*
+	 * For non-I2C devices platform has to provide methods to add a device
+	 * to the system and to remove it
+	 */
+	int (*add_device)(struct soc_camera_device *);
+	void (*del_device)(struct soc_camera_device *);
+};
+
+static inline struct soc_camera_host *to_soc_camera_host(
+	const struct device *dev)
+{
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+
+	return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev);
+}
+
+static inline struct soc_camera_desc *to_soc_camera_desc(
+	const struct soc_camera_device *icd)
+{
+	return icd->sdesc;
+}
+
+static inline struct device *to_soc_camera_control(
+	const struct soc_camera_device *icd)
+{
+	return icd->control;
+}
+
+static inline struct v4l2_subdev *soc_camera_to_subdev(
+	const struct soc_camera_device *icd)
+{
+	struct device *control = to_soc_camera_control(icd);
+	return dev_get_drvdata(control);
+}
+
+int soc_camera_host_register(struct soc_camera_host *ici);
+void soc_camera_host_unregister(struct soc_camera_host *ici);
+
+const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
+	struct soc_camera_device *icd, unsigned int fourcc);
+
+/**
+ * struct soc_camera_format_xlate - match between host and sensor formats
+ * @code: code of a sensor provided format
+ * @host_fmt: host format after host translation from code
+ *
+ * Host and sensor translation structure. Used in table of host and sensor
+ * formats matchings in soc_camera_device. A host can override the generic list
+ * generation by implementing get_formats(), and use it for format checks and
+ * format setup.
+ */
+struct soc_camera_format_xlate {
+	u32 code;
+	const struct soc_mbus_pixelfmt *host_fmt;
+};
+
+#define SOCAM_SENSE_PCLK_CHANGED	(1 << 0)
+
+/**
+ * This struct can be attached to struct soc_camera_device by the host driver
+ * to request sense from the camera, for example, when calling .set_fmt(). The
+ * host then can check which flags are set and verify respective values if any.
+ * For example, if SOCAM_SENSE_PCLK_CHANGED is set, it means, pixclock has
+ * changed during this operation. After completion the host should detach sense.
+ *
+ * @flags		ored SOCAM_SENSE_* flags
+ * @master_clock	if the host wants to be informed about pixel-clock
+ *			change, it better set master_clock.
+ * @pixel_clock_max	maximum pixel clock frequency supported by the host,
+ *			camera is not allowed to exceed this.
+ * @pixel_clock		if the camera driver changed pixel clock during this
+ *			operation, it sets SOCAM_SENSE_PCLK_CHANGED, uses
+ *			master_clock to calculate the new pixel-clock and
+ *			sets this field.
+ */
+struct soc_camera_sense {
+	unsigned long flags;
+	unsigned long master_clock;
+	unsigned long pixel_clock_max;
+	unsigned long pixel_clock;
+};
+
+#define SOCAM_DATAWIDTH(x)	BIT((x) - 1)
+#define SOCAM_DATAWIDTH_4	SOCAM_DATAWIDTH(4)
+#define SOCAM_DATAWIDTH_8	SOCAM_DATAWIDTH(8)
+#define SOCAM_DATAWIDTH_9	SOCAM_DATAWIDTH(9)
+#define SOCAM_DATAWIDTH_10	SOCAM_DATAWIDTH(10)
+#define SOCAM_DATAWIDTH_12	SOCAM_DATAWIDTH(12)
+#define SOCAM_DATAWIDTH_15	SOCAM_DATAWIDTH(15)
+#define SOCAM_DATAWIDTH_16	SOCAM_DATAWIDTH(16)
+#define SOCAM_DATAWIDTH_18	SOCAM_DATAWIDTH(18)
+#define SOCAM_DATAWIDTH_24	SOCAM_DATAWIDTH(24)
+
+#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \
+			      SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \
+			      SOCAM_DATAWIDTH_12 | SOCAM_DATAWIDTH_15 | \
+			      SOCAM_DATAWIDTH_16 | SOCAM_DATAWIDTH_18 | \
+			      SOCAM_DATAWIDTH_24)
+
+static inline void soc_camera_limit_side(int *start, int *length,
+		unsigned int start_min,
+		unsigned int length_min, unsigned int length_max)
+{
+	if (*length < length_min)
+		*length = length_min;
+	else if (*length > length_max)
+		*length = length_max;
+
+	if (*start < start_min)
+		*start = start_min;
+	else if (*start > start_min + length_max - *length)
+		*start = start_min + length_max - *length;
+}
+
+unsigned long soc_camera_apply_board_flags(struct soc_camera_subdev_desc *ssdd,
+					   const struct v4l2_mbus_config *cfg);
+
+int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd);
+int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			struct v4l2_clk *clk);
+int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			 struct v4l2_clk *clk);
+
+static inline int soc_camera_set_power(struct device *dev,
+		struct soc_camera_subdev_desc *ssdd, struct v4l2_clk *clk, bool on)
+{
+	return on ? soc_camera_power_on(dev, ssdd, clk)
+		  : soc_camera_power_off(dev, ssdd, clk);
+}
+
+/* This is only temporary here - until v4l2-subdev begins to link to video_device */
+#include <linux/i2c.h>
+static inline struct video_device *soc_camera_i2c_to_vdev(const struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
+	return icd ? icd->vdev : NULL;
+}
+
+static inline struct soc_camera_subdev_desc *soc_camera_i2c_to_desc(const struct i2c_client *client)
+{
+	return client->dev.platform_data;
+}
+
+static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(struct video_device *vdev)
+{
+	struct soc_camera_device *icd = video_get_drvdata(vdev);
+	return soc_camera_to_subdev(icd);
+}
+
+static inline struct soc_camera_device *soc_camera_from_vb2q(const struct vb2_queue *vq)
+{
+	return container_of(vq, struct soc_camera_device, vb2_vidq);
+}
+
+static inline u32 soc_camera_grp_id(const struct soc_camera_device *icd)
+{
+	return (icd->iface << 8) | (icd->devnum + 1);
+}
+
+void soc_camera_lock(struct vb2_queue *vq);
+void soc_camera_unlock(struct vb2_queue *vq);
+
+#endif
diff --git a/include/media/tpg/v4l2-tpg.h b/include/media/tpg/v4l2-tpg.h
new file mode 100644
index 0000000..eb191e8
--- /dev/null
+++ b/include/media/tpg/v4l2-tpg.h
@@ -0,0 +1,650 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * v4l2-tpg.h - Test Pattern Generator
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _V4L2_TPG_H_
+#define _V4L2_TPG_H_
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/videodev2.h>
+
+struct tpg_rbg_color8 {
+	unsigned char r, g, b;
+};
+
+struct tpg_rbg_color16 {
+	__u16 r, g, b;
+};
+
+enum tpg_color {
+	TPG_COLOR_CSC_WHITE,
+	TPG_COLOR_CSC_YELLOW,
+	TPG_COLOR_CSC_CYAN,
+	TPG_COLOR_CSC_GREEN,
+	TPG_COLOR_CSC_MAGENTA,
+	TPG_COLOR_CSC_RED,
+	TPG_COLOR_CSC_BLUE,
+	TPG_COLOR_CSC_BLACK,
+	TPG_COLOR_75_YELLOW,
+	TPG_COLOR_75_CYAN,
+	TPG_COLOR_75_GREEN,
+	TPG_COLOR_75_MAGENTA,
+	TPG_COLOR_75_RED,
+	TPG_COLOR_75_BLUE,
+	TPG_COLOR_100_WHITE,
+	TPG_COLOR_100_YELLOW,
+	TPG_COLOR_100_CYAN,
+	TPG_COLOR_100_GREEN,
+	TPG_COLOR_100_MAGENTA,
+	TPG_COLOR_100_RED,
+	TPG_COLOR_100_BLUE,
+	TPG_COLOR_100_BLACK,
+	TPG_COLOR_TEXTFG,
+	TPG_COLOR_TEXTBG,
+	TPG_COLOR_RANDOM,
+	TPG_COLOR_RAMP,
+	TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
+};
+
+extern const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX];
+extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
+extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
+extern const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
+					  [V4L2_XFER_FUNC_SMPTE2084 + 1]
+					  [TPG_COLOR_CSC_BLACK + 1];
+enum tpg_pattern {
+	TPG_PAT_75_COLORBAR,
+	TPG_PAT_100_COLORBAR,
+	TPG_PAT_CSC_COLORBAR,
+	TPG_PAT_100_HCOLORBAR,
+	TPG_PAT_100_COLORSQUARES,
+	TPG_PAT_BLACK,
+	TPG_PAT_WHITE,
+	TPG_PAT_RED,
+	TPG_PAT_GREEN,
+	TPG_PAT_BLUE,
+	TPG_PAT_CHECKERS_16X16,
+	TPG_PAT_CHECKERS_2X2,
+	TPG_PAT_CHECKERS_1X1,
+	TPG_PAT_COLOR_CHECKERS_2X2,
+	TPG_PAT_COLOR_CHECKERS_1X1,
+	TPG_PAT_ALTERNATING_HLINES,
+	TPG_PAT_ALTERNATING_VLINES,
+	TPG_PAT_CROSS_1_PIXEL,
+	TPG_PAT_CROSS_2_PIXELS,
+	TPG_PAT_CROSS_10_PIXELS,
+	TPG_PAT_GRAY_RAMP,
+
+	/* Must be the last pattern */
+	TPG_PAT_NOISE,
+};
+
+extern const char * const tpg_pattern_strings[];
+
+enum tpg_quality {
+	TPG_QUAL_COLOR,
+	TPG_QUAL_GRAY,
+	TPG_QUAL_NOISE
+};
+
+enum tpg_video_aspect {
+	TPG_VIDEO_ASPECT_IMAGE,
+	TPG_VIDEO_ASPECT_4X3,
+	TPG_VIDEO_ASPECT_14X9_CENTRE,
+	TPG_VIDEO_ASPECT_16X9_CENTRE,
+	TPG_VIDEO_ASPECT_16X9_ANAMORPHIC,
+};
+
+enum tpg_pixel_aspect {
+	TPG_PIXEL_ASPECT_SQUARE,
+	TPG_PIXEL_ASPECT_NTSC,
+	TPG_PIXEL_ASPECT_PAL,
+};
+
+enum tpg_move_mode {
+	TPG_MOVE_NEG_FAST,
+	TPG_MOVE_NEG,
+	TPG_MOVE_NEG_SLOW,
+	TPG_MOVE_NONE,
+	TPG_MOVE_POS_SLOW,
+	TPG_MOVE_POS,
+	TPG_MOVE_POS_FAST,
+};
+
+enum tgp_color_enc {
+	TGP_COLOR_ENC_RGB,
+	TGP_COLOR_ENC_YCBCR,
+	TGP_COLOR_ENC_HSV,
+	TGP_COLOR_ENC_LUMA,
+};
+
+extern const char * const tpg_aspect_strings[];
+
+#define TPG_MAX_PLANES 3
+#define TPG_MAX_PAT_LINES 8
+
+struct tpg_data {
+	/* Source frame size */
+	unsigned			src_width, src_height;
+	/* Buffer height */
+	unsigned			buf_height;
+	/* Scaled output frame size */
+	unsigned			scaled_width;
+	u32				field;
+	bool				field_alternate;
+	/* crop coordinates are frame-based */
+	struct v4l2_rect		crop;
+	/* compose coordinates are format-based */
+	struct v4l2_rect		compose;
+	/* border and square coordinates are frame-based */
+	struct v4l2_rect		border;
+	struct v4l2_rect		square;
+
+	/* Color-related fields */
+	enum tpg_quality		qual;
+	unsigned			qual_offset;
+	u8				alpha_component;
+	bool				alpha_red_only;
+	u8				brightness;
+	u8				contrast;
+	u8				saturation;
+	s16				hue;
+	u32				fourcc;
+	enum tgp_color_enc		color_enc;
+	u32				colorspace;
+	u32				xfer_func;
+	u32				ycbcr_enc;
+	u32				hsv_enc;
+	/*
+	 * Stores the actual transfer function, i.e. will never be
+	 * V4L2_XFER_FUNC_DEFAULT.
+	 */
+	u32				real_xfer_func;
+	/*
+	 * Stores the actual Y'CbCr encoding, i.e. will never be
+	 * V4L2_YCBCR_ENC_DEFAULT.
+	 */
+	u32				real_hsv_enc;
+	u32				real_ycbcr_enc;
+	u32				quantization;
+	/*
+	 * Stores the actual quantization, i.e. will never be
+	 * V4L2_QUANTIZATION_DEFAULT.
+	 */
+	u32				real_quantization;
+	enum tpg_video_aspect		vid_aspect;
+	enum tpg_pixel_aspect		pix_aspect;
+	unsigned			rgb_range;
+	unsigned			real_rgb_range;
+	unsigned			buffers;
+	unsigned			planes;
+	bool				interleaved;
+	u8				vdownsampling[TPG_MAX_PLANES];
+	u8				hdownsampling[TPG_MAX_PLANES];
+	/*
+	 * horizontal positions must be ANDed with this value to enforce
+	 * correct boundaries for packed YUYV values.
+	 */
+	unsigned			hmask[TPG_MAX_PLANES];
+	/* Used to store the colors in native format, either RGB or YUV */
+	u8				colors[TPG_COLOR_MAX][3];
+	u8				textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8];
+	/* size in bytes for two pixels in each plane */
+	unsigned			twopixelsize[TPG_MAX_PLANES];
+	unsigned			bytesperline[TPG_MAX_PLANES];
+
+	/* Configuration */
+	enum tpg_pattern		pattern;
+	bool				hflip;
+	bool				vflip;
+	unsigned			perc_fill;
+	bool				perc_fill_blank;
+	bool				show_border;
+	bool				show_square;
+	bool				insert_sav;
+	bool				insert_eav;
+
+	/* Test pattern movement */
+	enum tpg_move_mode		mv_hor_mode;
+	int				mv_hor_count;
+	int				mv_hor_step;
+	enum tpg_move_mode		mv_vert_mode;
+	int				mv_vert_count;
+	int				mv_vert_step;
+
+	bool				recalc_colors;
+	bool				recalc_lines;
+	bool				recalc_square_border;
+
+	/* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
+	unsigned			max_line_width;
+	u8				*lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
+	u8				*downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
+	u8				*random_line[TPG_MAX_PLANES];
+	u8				*contrast_line[TPG_MAX_PLANES];
+	u8				*black_line[TPG_MAX_PLANES];
+};
+
+void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h);
+int tpg_alloc(struct tpg_data *tpg, unsigned max_w);
+void tpg_free(struct tpg_data *tpg);
+void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
+		       u32 field);
+void tpg_log_status(struct tpg_data *tpg);
+
+void tpg_set_font(const u8 *f);
+void tpg_gen_text(const struct tpg_data *tpg,
+		u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text);
+void tpg_calc_text_basep(struct tpg_data *tpg,
+		u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf);
+unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line);
+void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
+			   unsigned p, u8 *vbuf);
+void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std,
+		    unsigned p, u8 *vbuf);
+bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc);
+void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
+		const struct v4l2_rect *compose);
+
+static inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern)
+{
+	if (tpg->pattern == pattern)
+		return;
+	tpg->pattern = pattern;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_quality(struct tpg_data *tpg,
+				    enum tpg_quality qual, unsigned qual_offset)
+{
+	if (tpg->qual == qual && tpg->qual_offset == qual_offset)
+		return;
+	tpg->qual = qual;
+	tpg->qual_offset = qual_offset;
+	tpg->recalc_colors = true;
+}
+
+static inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg)
+{
+	return tpg->qual;
+}
+
+static inline void tpg_s_alpha_component(struct tpg_data *tpg,
+					    u8 alpha_component)
+{
+	if (tpg->alpha_component == alpha_component)
+		return;
+	tpg->alpha_component = alpha_component;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_alpha_mode(struct tpg_data *tpg,
+					    bool red_only)
+{
+	if (tpg->alpha_red_only == red_only)
+		return;
+	tpg->alpha_red_only = red_only;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_brightness(struct tpg_data *tpg,
+					u8 brightness)
+{
+	if (tpg->brightness == brightness)
+		return;
+	tpg->brightness = brightness;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_contrast(struct tpg_data *tpg,
+					u8 contrast)
+{
+	if (tpg->contrast == contrast)
+		return;
+	tpg->contrast = contrast;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_saturation(struct tpg_data *tpg,
+					u8 saturation)
+{
+	if (tpg->saturation == saturation)
+		return;
+	tpg->saturation = saturation;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_hue(struct tpg_data *tpg,
+					s16 hue)
+{
+	if (tpg->hue == hue)
+		return;
+	tpg->hue = hue;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_rgb_range(struct tpg_data *tpg,
+					unsigned rgb_range)
+{
+	if (tpg->rgb_range == rgb_range)
+		return;
+	tpg->rgb_range = rgb_range;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_real_rgb_range(struct tpg_data *tpg,
+					unsigned rgb_range)
+{
+	if (tpg->real_rgb_range == rgb_range)
+		return;
+	tpg->real_rgb_range = rgb_range;
+	tpg->recalc_colors = true;
+}
+
+static inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace)
+{
+	if (tpg->colorspace == colorspace)
+		return;
+	tpg->colorspace = colorspace;
+	tpg->recalc_colors = true;
+}
+
+static inline u32 tpg_g_colorspace(const struct tpg_data *tpg)
+{
+	return tpg->colorspace;
+}
+
+static inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc)
+{
+	if (tpg->ycbcr_enc == ycbcr_enc)
+		return;
+	tpg->ycbcr_enc = ycbcr_enc;
+	tpg->recalc_colors = true;
+}
+
+static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg)
+{
+	return tpg->ycbcr_enc;
+}
+
+static inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc)
+{
+	if (tpg->hsv_enc == hsv_enc)
+		return;
+	tpg->hsv_enc = hsv_enc;
+	tpg->recalc_colors = true;
+}
+
+static inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg)
+{
+	return tpg->hsv_enc;
+}
+
+static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func)
+{
+	if (tpg->xfer_func == xfer_func)
+		return;
+	tpg->xfer_func = xfer_func;
+	tpg->recalc_colors = true;
+}
+
+static inline u32 tpg_g_xfer_func(const struct tpg_data *tpg)
+{
+	return tpg->xfer_func;
+}
+
+static inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization)
+{
+	if (tpg->quantization == quantization)
+		return;
+	tpg->quantization = quantization;
+	tpg->recalc_colors = true;
+}
+
+static inline u32 tpg_g_quantization(const struct tpg_data *tpg)
+{
+	return tpg->quantization;
+}
+
+static inline unsigned tpg_g_buffers(const struct tpg_data *tpg)
+{
+	return tpg->buffers;
+}
+
+static inline unsigned tpg_g_planes(const struct tpg_data *tpg)
+{
+	return tpg->interleaved ? 1 : tpg->planes;
+}
+
+static inline bool tpg_g_interleaved(const struct tpg_data *tpg)
+{
+	return tpg->interleaved;
+}
+
+static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane)
+{
+	return tpg->twopixelsize[plane];
+}
+
+static inline unsigned tpg_hdiv(const struct tpg_data *tpg,
+				  unsigned plane, unsigned x)
+{
+	return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) *
+		tpg->twopixelsize[plane] / 2;
+}
+
+static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x)
+{
+	return (x * tpg->scaled_width) / tpg->src_width;
+}
+
+static inline unsigned tpg_hscale_div(const struct tpg_data *tpg,
+				      unsigned plane, unsigned x)
+{
+	return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x));
+}
+
+static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane)
+{
+	return tpg->bytesperline[plane];
+}
+
+static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl)
+{
+	unsigned p;
+
+	if (tpg->buffers > 1) {
+		tpg->bytesperline[plane] = bpl;
+		return;
+	}
+
+	for (p = 0; p < tpg_g_planes(tpg); p++) {
+		unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
+
+		tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
+	}
+	if (tpg_g_interleaved(tpg))
+		tpg->bytesperline[1] = tpg->bytesperline[0];
+}
+
+
+static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane)
+{
+	unsigned w = 0;
+	unsigned p;
+
+	if (tpg->buffers > 1)
+		return tpg_g_bytesperline(tpg, plane);
+	for (p = 0; p < tpg_g_planes(tpg); p++) {
+		unsigned plane_w = tpg_g_bytesperline(tpg, p);
+
+		w += plane_w / tpg->vdownsampling[p];
+	}
+	return w;
+}
+
+static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
+					   unsigned plane, unsigned bpl)
+{
+	unsigned w = 0;
+	unsigned p;
+
+	if (tpg->buffers > 1)
+		return bpl;
+	for (p = 0; p < tpg_g_planes(tpg); p++) {
+		unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
+
+		plane_w /= tpg->hdownsampling[p];
+		w += plane_w / tpg->vdownsampling[p];
+	}
+	return w;
+}
+
+static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane)
+{
+	if (plane >= tpg_g_planes(tpg))
+		return 0;
+
+	return tpg_g_bytesperline(tpg, plane) * tpg->buf_height /
+	       tpg->vdownsampling[plane];
+}
+
+static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h)
+{
+	tpg->buf_height = h;
+}
+
+static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate)
+{
+	tpg->field = field;
+	tpg->field_alternate = alternate;
+}
+
+static inline void tpg_s_perc_fill(struct tpg_data *tpg,
+				      unsigned perc_fill)
+{
+	tpg->perc_fill = perc_fill;
+}
+
+static inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg)
+{
+	return tpg->perc_fill;
+}
+
+static inline void tpg_s_perc_fill_blank(struct tpg_data *tpg,
+					 bool perc_fill_blank)
+{
+	tpg->perc_fill_blank = perc_fill_blank;
+}
+
+static inline void tpg_s_video_aspect(struct tpg_data *tpg,
+					enum tpg_video_aspect vid_aspect)
+{
+	if (tpg->vid_aspect == vid_aspect)
+		return;
+	tpg->vid_aspect = vid_aspect;
+	tpg->recalc_square_border = true;
+}
+
+static inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg)
+{
+	return tpg->vid_aspect;
+}
+
+static inline void tpg_s_pixel_aspect(struct tpg_data *tpg,
+					enum tpg_pixel_aspect pix_aspect)
+{
+	if (tpg->pix_aspect == pix_aspect)
+		return;
+	tpg->pix_aspect = pix_aspect;
+	tpg->recalc_square_border = true;
+}
+
+static inline void tpg_s_show_border(struct tpg_data *tpg,
+					bool show_border)
+{
+	tpg->show_border = show_border;
+}
+
+static inline void tpg_s_show_square(struct tpg_data *tpg,
+					bool show_square)
+{
+	tpg->show_square = show_square;
+}
+
+static inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav)
+{
+	tpg->insert_sav = insert_sav;
+}
+
+static inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav)
+{
+	tpg->insert_eav = insert_eav;
+}
+
+void tpg_update_mv_step(struct tpg_data *tpg);
+
+static inline void tpg_s_mv_hor_mode(struct tpg_data *tpg,
+				enum tpg_move_mode mv_hor_mode)
+{
+	tpg->mv_hor_mode = mv_hor_mode;
+	tpg_update_mv_step(tpg);
+}
+
+static inline void tpg_s_mv_vert_mode(struct tpg_data *tpg,
+				enum tpg_move_mode mv_vert_mode)
+{
+	tpg->mv_vert_mode = mv_vert_mode;
+	tpg_update_mv_step(tpg);
+}
+
+static inline void tpg_init_mv_count(struct tpg_data *tpg)
+{
+	tpg->mv_hor_count = tpg->mv_vert_count = 0;
+}
+
+static inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field)
+{
+	tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2);
+	tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2);
+}
+
+static inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip)
+{
+	if (tpg->hflip == hflip)
+		return;
+	tpg->hflip = hflip;
+	tpg_update_mv_step(tpg);
+	tpg->recalc_lines = true;
+}
+
+static inline bool tpg_g_hflip(const struct tpg_data *tpg)
+{
+	return tpg->hflip;
+}
+
+static inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip)
+{
+	tpg->vflip = vflip;
+}
+
+static inline bool tpg_g_vflip(const struct tpg_data *tpg)
+{
+	return tpg->vflip;
+}
+
+static inline bool tpg_pattern_is_static(const struct tpg_data *tpg)
+{
+	return tpg->pattern != TPG_PAT_NOISE &&
+	       tpg->mv_hor_mode == TPG_MOVE_NONE &&
+	       tpg->mv_vert_mode == TPG_MOVE_NONE;
+}
+
+#endif
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h
new file mode 100644
index 0000000..df76ac8
--- /dev/null
+++ b/include/media/tuner-types.h
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * descriptions for simple tuners.
+ */
+
+#ifndef __TUNER_TYPES_H__
+#define __TUNER_TYPES_H__
+
+/**
+ * enum param_type - type of the tuner pameters
+ *
+ * @TUNER_PARAM_TYPE_RADIO:	Tuner params are for FM and/or AM radio
+ * @TUNER_PARAM_TYPE_PAL:	Tuner params are for PAL color TV standard
+ * @TUNER_PARAM_TYPE_SECAM:	Tuner params are for SECAM color TV standard
+ * @TUNER_PARAM_TYPE_NTSC:	Tuner params are for NTSC color TV standard
+ * @TUNER_PARAM_TYPE_DIGITAL:	Tuner params are for digital TV
+ */
+enum param_type {
+	TUNER_PARAM_TYPE_RADIO,
+	TUNER_PARAM_TYPE_PAL,
+	TUNER_PARAM_TYPE_SECAM,
+	TUNER_PARAM_TYPE_NTSC,
+	TUNER_PARAM_TYPE_DIGITAL,
+};
+
+/**
+ * struct tuner_range - define the frequencies supported by the tuner
+ *
+ * @limit:		Max frequency supported by that range, in 62.5 kHz
+ *			(TV) or 62.5 Hz (Radio), as defined by
+ *			V4L2_TUNER_CAP_LOW.
+ * @config:		Value of the band switch byte (BB) to setup this mode.
+ * @cb:			Value of the CB byte to setup this mode.
+ *
+ * Please notice that digital tuners like xc3028/xc4000/xc5000 don't use
+ * those ranges, as they're defined inside the driver. This is used by
+ * analog tuners that are compatible with the "Philips way" to setup the
+ * tuners. On those devices, the tuner set is done via 4 bytes:
+ *
+ *	#) divider byte1 (DB1)
+ *	#) divider byte 2 (DB2)
+ *	#) Control byte (CB)
+ *	#) band switch byte (BB)
+ *
+ * Some tuners also have an additional optional Auxiliary byte (AB).
+ */
+struct tuner_range {
+	unsigned short limit;
+	unsigned char config;
+	unsigned char cb;
+};
+
+/**
+ * struct tuner_params - Parameters to be used to setup the tuner. Those
+ *			 are used by drivers/media/tuners/tuner-types.c in
+ *			 order to specify the tuner properties. Most of
+ *			 the parameters are for tuners based on tda9887 IF-PLL
+ *			 multi-standard analog TV/Radio demodulator, with is
+ *			 very common on legacy analog tuners.
+ *
+ * @type:			Type of the tuner parameters, as defined at
+ *				enum param_type. If the tuner supports multiple
+ *				standards, an array should be used, with one
+ *				row per different standard.
+ * @cb_first_if_lower_freq:	Many Philips-based tuners have a comment in
+ *				their datasheet like
+ *				"For channel selection involving band
+ *				switching, and to ensure smooth tuning to the
+ *				desired channel without causing unnecessary
+ *				charge pump action, it is recommended to
+ *				consider the difference between wanted channel
+ *				frequency and the current channel frequency.
+ *				Unnecessary charge pump action will result
+ *				in very low tuning voltage which may drive the
+ *				oscillator to extreme conditions".
+ *				Set cb_first_if_lower_freq to 1, if this check
+ *				is required for this tuner. I tested this for
+ *				PAL by first setting the TV frequency to
+ *				203 MHz and then switching to 96.6 MHz FM
+ *				radio. The result was static unless the
+ *				control byte was sent first.
+ * @has_tda9887:		Set to 1 if this tuner uses a tda9887
+ * @port1_fm_high_sensitivity:	Many Philips tuners use tda9887 PORT1 to select
+ *				the FM radio sensitivity. If this setting is 1,
+ *				then set PORT1 to 1 to get proper FM reception.
+ * @port2_fm_high_sensitivity:	Some Philips tuners use tda9887 PORT2 to select
+ *				the FM radio sensitivity. If this setting is 1,
+ *				then set PORT2 to 1 to get proper FM reception.
+ * @fm_gain_normal:		Some Philips tuners use tda9887 cGainNormal to
+ *				select the FM radio sensitivity. If this
+ *				setting is 1, e register will use cGainNormal
+ *				instead of cGainLow.
+ * @intercarrier_mode:		Most tuners with a tda9887 use QSS mode.
+ *				Some (cheaper) tuners use Intercarrier mode.
+ *				If this setting is 1, then the tuner needs to
+ *				be set to intercarrier mode.
+ * @port1_active:		This setting sets the default value for PORT1.
+ *				0 means inactive, 1 means active. Note: the
+ *				actual bit value written to the tda9887 is
+ *				inverted. So a 0 here means a 1 in the B6 bit.
+ * @port2_active:		This setting sets the default value for PORT2.
+ *				0 means inactive, 1 means active. Note: the
+ *				actual bit value written to the tda9887 is
+ *				inverted. So a 0 here means a 1 in the B7 bit.
+ * @port1_invert_for_secam_lc:	Sometimes PORT1 is inverted when the SECAM-L'
+ *				standard is selected. Set this bit to 1 if this
+ *				is needed.
+ * @port2_invert_for_secam_lc:	Sometimes PORT2 is inverted when the SECAM-L'
+ *				standard is selected. Set this bit to 1 if this
+ *				is needed.
+ * @port1_set_for_fm_mono:	Some cards require PORT1 to be 1 for mono Radio
+ *				FM and 0 for stereo.
+ * @default_pll_gating_18:	Select 18% (or according to datasheet 0%)
+ *				L standard PLL gating, vs the driver default
+ *				of 36%.
+ * @radio_if:			IF to use in radio mode.  Tuners with a
+ *				separate radio IF filter seem to use 10.7,
+ *				while those without use 33.3 for PAL/SECAM
+ *				tuners and 41.3 for NTSC tuners.
+ *				0 = 10.7, 1 = 33.3, 2 = 41.3
+ * @default_top_low:		Default tda9887 TOP value in dB for the low
+ *				band. Default is 0. Range: -16:+15
+ * @default_top_mid:		Default tda9887 TOP value in dB for the mid
+ *				band. Default is 0. Range: -16:+15
+ * @default_top_high:		Default tda9887 TOP value in dB for the high
+ *				band. Default is 0. Range: -16:+15
+ * @default_top_secam_low:	Default tda9887 TOP value in dB for SECAM-L/L'
+ *				for the low band. Default is 0. Several tuners
+ *				require a different TOP value for the
+ *				SECAM-L/L' standards. Range: -16:+15
+ * @default_top_secam_mid:	Default tda9887 TOP value in dB for SECAM-L/L'
+ *				for the mid band. Default is 0. Several tuners
+ *				require a different TOP value for the
+ *				SECAM-L/L' standards. Range: -16:+15
+ * @default_top_secam_high:	Default tda9887 TOP value in dB for SECAM-L/L'
+ *				for the high band. Default is 0. Several tuners
+ *				require a different TOP value for the
+ *				SECAM-L/L' standards. Range: -16:+15
+ * @iffreq:			Intermediate frequency (IF) used by the tuner
+ *				on digital mode.
+ * @count:			Size of the ranges array.
+ * @ranges:			Array with the frequency ranges supported by
+ *				the tuner.
+ */
+struct tuner_params {
+	enum param_type type;
+
+	unsigned int cb_first_if_lower_freq:1;
+	unsigned int has_tda9887:1;
+	unsigned int port1_fm_high_sensitivity:1;
+	unsigned int port2_fm_high_sensitivity:1;
+	unsigned int fm_gain_normal:1;
+	unsigned int intercarrier_mode:1;
+	unsigned int port1_active:1;
+	unsigned int port2_active:1;
+	unsigned int port1_invert_for_secam_lc:1;
+	unsigned int port2_invert_for_secam_lc:1;
+	unsigned int port1_set_for_fm_mono:1;
+	unsigned int default_pll_gating_18:1;
+	unsigned int radio_if:2;
+	signed int default_top_low:5;
+	signed int default_top_mid:5;
+	signed int default_top_high:5;
+	signed int default_top_secam_low:5;
+	signed int default_top_secam_mid:5;
+	signed int default_top_secam_high:5;
+
+	u16 iffreq;
+
+	unsigned int count;
+	struct tuner_range *ranges;
+};
+
+/**
+ * struct tunertype - describes the known tuners.
+ *
+ * @name:	string with the tuner's name.
+ * @count:	size of &struct tuner_params array.
+ * @params:	pointer to &struct tuner_params array.
+ *
+ * @min:	minimal tuner frequency, in 62.5 kHz step.
+ *		should be multiplied to 16 to convert to MHz.
+ * @max:	minimal tuner frequency, in 62.5 kHz step.
+ *		Should be multiplied to 16 to convert to MHz.
+ * @stepsize:	frequency step, in Hz.
+ * @initdata:	optional byte sequence to initialize the tuner.
+ * @sleepdata:	optional byte sequence to power down the tuner.
+ */
+struct tunertype {
+	char *name;
+	unsigned int count;
+	struct tuner_params *params;
+
+	u16 min;
+	u16 max;
+	u32 stepsize;
+
+	u8 *initdata;
+	u8 *sleepdata;
+};
+
+extern struct tunertype tuners[];
+extern unsigned const int tuner_count;
+
+#endif
diff --git a/include/media/tuner.h b/include/media/tuner.h
new file mode 100644
index 0000000..b3edc14
--- /dev/null
+++ b/include/media/tuner.h
@@ -0,0 +1,236 @@
+/*
+ * tuner.h - definition for different tuners
+ *
+ * Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
+ * minor modifications by Ralph Metzler (rjkm@thp.uni-koeln.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _TUNER_H
+#define _TUNER_H
+#ifdef __KERNEL__
+
+#include <linux/videodev2.h>
+#include <media/v4l2-mc.h>
+
+#define ADDR_UNSET (255)
+
+#define TUNER_TEMIC_PAL			0        /* 4002 FH5 (3X 7756, 9483) */
+#define TUNER_PHILIPS_PAL_I		1
+#define TUNER_PHILIPS_NTSC		2
+#define TUNER_PHILIPS_SECAM		3	/* you must actively select B/G, L, L` */
+
+#define TUNER_ABSENT			4
+#define TUNER_PHILIPS_PAL		5
+#define TUNER_TEMIC_NTSC		6	/* 4032 FY5 (3X 7004, 9498, 9789)  */
+#define TUNER_TEMIC_PAL_I		7	/* 4062 FY5 (3X 8501, 9957) */
+
+#define TUNER_TEMIC_4036FY5_NTSC	8	/* 4036 FY5 (3X 1223, 1981, 7686) */
+#define TUNER_ALPS_TSBH1_NTSC		9
+#define TUNER_ALPS_TSBE1_PAL		10
+#define TUNER_ALPS_TSBB5_PAL_I		11
+
+#define TUNER_ALPS_TSBE5_PAL		12
+#define TUNER_ALPS_TSBC5_PAL		13
+#define TUNER_TEMIC_4006FH5_PAL		14	/* 4006 FH5 (3X 9500, 9501, 7291) */
+#define TUNER_ALPS_TSHC6_NTSC		15
+
+#define TUNER_TEMIC_PAL_DK		16	/* 4016 FY5 (3X 1392, 1393) */
+#define TUNER_PHILIPS_NTSC_M		17
+#define TUNER_TEMIC_4066FY5_PAL_I	18	/* 4066 FY5 (3X 7032, 7035) */
+#define TUNER_TEMIC_4006FN5_MULTI_PAL	19	/* B/G, I and D/K autodetected (3X 7595, 7606, 7657) */
+
+#define TUNER_TEMIC_4009FR5_PAL		20	/* incl. FM radio (3X 7607, 7488, 7711) */
+#define TUNER_TEMIC_4039FR5_NTSC	21	/* incl. FM radio (3X 7246, 7578, 7732) */
+#define TUNER_TEMIC_4046FM5		22	/* you must actively select B/G, D/K, I, L, L` !  (3X 7804, 7806, 8103, 8104) */
+#define TUNER_PHILIPS_PAL_DK		23
+
+#define TUNER_PHILIPS_FQ1216ME		24	/* you must actively select B/G/D/K, I, L, L` */
+#define TUNER_LG_PAL_I_FM		25
+#define TUNER_LG_PAL_I			26
+#define TUNER_LG_NTSC_FM		27
+
+#define TUNER_LG_PAL_FM			28
+#define TUNER_LG_PAL			29
+#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM 30	/* B/G, I and D/K autodetected (3X 8155, 8160, 8163) */
+#define TUNER_SHARP_2U5JF5540_NTSC	31
+
+#define TUNER_Samsung_PAL_TCPM9091PD27	32
+#define TUNER_MT2032			33
+#define TUNER_TEMIC_4106FH5		34	/* 4106 FH5 (3X 7808, 7865) */
+#define TUNER_TEMIC_4012FY5		35	/* 4012 FY5 (3X 0971, 1099) */
+
+#define TUNER_TEMIC_4136FY5		36	/* 4136 FY5 (3X 7708, 7746) */
+#define TUNER_LG_PAL_NEW_TAPC		37
+#define TUNER_PHILIPS_FM1216ME_MK3	38
+#define TUNER_LG_NTSC_NEW_TAPC		39
+
+#define TUNER_HITACHI_NTSC		40
+#define TUNER_PHILIPS_PAL_MK		41
+#define TUNER_PHILIPS_FCV1236D		42
+#define TUNER_PHILIPS_FM1236_MK3	43
+
+#define TUNER_PHILIPS_4IN1		44	/* ATI TV Wonder Pro - Conexant */
+	/*
+	 * Microtune merged with Temic 12/31/1999 partially financed by Alps.
+	 * these may be similar to Temic
+	 */
+#define TUNER_MICROTUNE_4049FM5		45
+#define TUNER_PANASONIC_VP27		46
+#define TUNER_LG_NTSC_TAPE		47
+
+#define TUNER_TNF_8831BGFF		48
+#define TUNER_MICROTUNE_4042FI5		49	/* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
+#define TUNER_TCL_2002N			50
+#define TUNER_PHILIPS_FM1256_IH3	51
+
+#define TUNER_THOMSON_DTT7610		52
+#define TUNER_PHILIPS_FQ1286		53
+#define TUNER_PHILIPS_TDA8290		54
+#define TUNER_TCL_2002MB		55	/* Hauppauge PVR-150 PAL */
+
+#define TUNER_PHILIPS_FQ1216AME_MK4	56	/* Hauppauge PVR-150 PAL */
+#define TUNER_PHILIPS_FQ1236A_MK4	57	/* Hauppauge PVR-500MCE NTSC */
+#define TUNER_YMEC_TVF_8531MF		58
+#define TUNER_YMEC_TVF_5533MF		59	/* Pixelview Pro Ultra NTSC */
+
+#define TUNER_THOMSON_DTT761X		60	/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
+#define TUNER_TENA_9533_DI		61
+#define TUNER_TEA5767			62	/* Only FM Radio Tuner */
+#define TUNER_PHILIPS_FMD1216ME_MK3	63
+
+#define TUNER_LG_TDVS_H06XF		64	/* TDVS H061F, H062F, H064F */
+#define TUNER_YMEC_TVF66T5_B_DFF	65	/* Acorp Y878F */
+#define TUNER_LG_TALN			66
+#define TUNER_PHILIPS_TD1316		67
+
+#define TUNER_PHILIPS_TUV1236D		68	/* ATI HDTV Wonder */
+#define TUNER_TNF_5335MF                69	/* Sabrent Bt848   */
+#define TUNER_SAMSUNG_TCPN_2121P30A     70	/* Hauppauge PVR-500MCE NTSC */
+#define TUNER_XC2028			71
+
+#define TUNER_THOMSON_FE6600		72	/* DViCO FusionHDTV DVB-T Hybrid */
+#define TUNER_SAMSUNG_TCPG_6121P30A     73	/* Hauppauge PVR-500 PAL */
+#define TUNER_TDA9887                   74      /* This tuner should be used only internally */
+#define TUNER_TEA5761			75	/* Only FM Radio Tuner */
+#define TUNER_XC5000			76	/* Xceive Silicon Tuner */
+#define TUNER_TCL_MF02GIP_5N		77	/* TCL MF02GIP_5N */
+#define TUNER_PHILIPS_FMD1216MEX_MK3	78
+#define TUNER_PHILIPS_FM1216MK5		79
+#define TUNER_PHILIPS_FQ1216LME_MK3	80	/* Active loopthrough, no FM */
+
+#define TUNER_PARTSNIC_PTI_5NF05	81
+#define TUNER_PHILIPS_CU1216L           82
+#define TUNER_NXP_TDA18271		83
+#define TUNER_SONY_BTF_PXN01Z		84
+#define TUNER_PHILIPS_FQ1236_MK5	85	/* NTSC, TDA9885, no FM radio */
+#define TUNER_TENA_TNF_5337		86
+
+#define TUNER_XC4000			87	/* Xceive Silicon Tuner */
+#define TUNER_XC5000C			88	/* Xceive Silicon Tuner */
+
+#define TUNER_SONY_BTF_PG472Z		89	/* PAL+SECAM */
+#define TUNER_SONY_BTF_PK467Z		90	/* NTSC_JP */
+#define TUNER_SONY_BTF_PB463Z		91	/* NTSC */
+
+/* tv card specific */
+#define TDA9887_PRESENT			(1<<0)
+#define TDA9887_PORT1_INACTIVE		(1<<1)
+#define TDA9887_PORT2_INACTIVE		(1<<2)
+#define TDA9887_QSS			(1<<3)
+#define TDA9887_INTERCARRIER		(1<<4)
+#define TDA9887_PORT1_ACTIVE		(1<<5)
+#define TDA9887_PORT2_ACTIVE		(1<<6)
+#define TDA9887_INTERCARRIER_NTSC	(1<<7)
+/* Tuner takeover point adjustment, in dB, -16 <= top <= 15 */
+#define TDA9887_TOP_MASK		(0x3f << 8)
+#define TDA9887_TOP_SET			(1 << 13)
+#define TDA9887_TOP(top)		(TDA9887_TOP_SET | \
+					 (((16 + (top)) & 0x1f) << 8))
+
+/* config options */
+#define TDA9887_DEEMPHASIS_MASK		(3<<16)
+#define TDA9887_DEEMPHASIS_NONE		(1<<16)
+#define TDA9887_DEEMPHASIS_50		(2<<16)
+#define TDA9887_DEEMPHASIS_75		(3<<16)
+#define TDA9887_AUTOMUTE		(1<<18)
+#define TDA9887_GATING_18		(1<<19)
+#define TDA9887_GAIN_NORMAL		(1<<20)
+#define TDA9887_RIF_41_3		(1<<21)  /* radio IF1 41.3 vs 33.3 */
+
+/**
+ * enum tuner_mode      - Mode of the tuner
+ *
+ * @T_RADIO:        Tuner core will work in radio mode
+ * @T_ANALOG_TV:    Tuner core will work in analog TV mode
+ *
+ * Older boards only had a single tuner device, but some devices have a
+ * separate tuner for radio. In any case, the tuner-core needs to know if
+ * the tuner chip(s) will be used in radio mode or analog TV mode, as, on
+ * radio mode, frequencies are specified on a different range than on TV
+ * mode. This enum is used by the tuner core in order to work with the
+ * proper tuner range and eventually use a different tuner chip while in
+ * radio mode.
+ */
+enum tuner_mode {
+	T_RADIO		= 1 << V4L2_TUNER_RADIO,
+	T_ANALOG_TV     = 1 << V4L2_TUNER_ANALOG_TV,
+	/* Don't map V4L2_TUNER_DIGITAL_TV, as tuner-core won't use it */
+};
+
+/**
+ * struct tuner_setup   - setup the tuner chipsets
+ *
+ * @addr:		I2C address used to control the tuner device/chipset
+ * @type:		Type of the tuner, as defined at the TUNER_* macros.
+ *			Each different tuner model should have an unique
+ *			identifier.
+ * @mode_mask:		Mask with the allowed tuner modes: V4L2_TUNER_RADIO,
+ *			V4L2_TUNER_ANALOG_TV and/or V4L2_TUNER_DIGITAL_TV,
+ *			describing if the tuner should be used to support
+ *			Radio, analog TV and/or digital TV.
+ * @config:		Used to send tuner-specific configuration for complex
+ *			tuners that require extra parameters to be set.
+ *			Only a very few tuners require it and its usage on
+ *			newer tuners should be avoided.
+ * @tuner_callback:	Some tuners require to call back the bridge driver,
+ *			in order to do some tasks like rising a GPIO at the
+ *			bridge chipset, in order to do things like resetting
+ *			the device.
+ *
+ * Older boards only had a single tuner device. Nowadays multiple tuner
+ * devices may be present on a single board. Using TUNER_SET_TYPE_ADDR
+ * to pass the tuner_setup structure it is possible to setup each tuner
+ * device in turn.
+ *
+ * Since multiple devices may be present it is no longer sufficient to
+ * send a command to a single i2c device. Instead you should broadcast
+ * the command to all i2c devices.
+ *
+ * By setting the mode_mask correctly you can select which commands are
+ * accepted by a specific tuner device. For example, set mode_mask to
+ * T_RADIO if the device is a radio-only tuner. That specific tuner will
+ * only accept commands when the tuner is in radio mode and ignore them
+ * when the tuner is set to TV mode.
+ */
+
+struct tuner_setup {
+	unsigned short	addr;
+	unsigned int	type;
+	unsigned int	mode_mask;
+	void		*config;
+	int (*tuner_callback)(void *dev, int component, int cmd, int arg);
+};
+
+#endif /* __KERNEL__ */
+
+#endif /* _TUNER_H */
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
new file mode 100644
index 0000000..b56eaee
--- /dev/null
+++ b/include/media/tveeprom.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * tveeprom - Contains structures and functions to work with Hauppauge
+ *	      eeproms.
+ */
+
+#include <linux/if_ether.h>
+
+/**
+ * enum tveeprom_audio_processor - Specifies the type of audio processor
+ *				   used on a Hauppauge device.
+ *
+ * @TVEEPROM_AUDPROC_NONE:	No audio processor present
+ * @TVEEPROM_AUDPROC_INTERNAL:	The audio processor is internal to the
+ *				video processor
+ * @TVEEPROM_AUDPROC_MSP:	The audio processor is a MSPXXXX device
+ * @TVEEPROM_AUDPROC_OTHER:	The audio processor is another device
+ */
+enum tveeprom_audio_processor {
+	TVEEPROM_AUDPROC_NONE,
+	TVEEPROM_AUDPROC_INTERNAL,
+	TVEEPROM_AUDPROC_MSP,
+	TVEEPROM_AUDPROC_OTHER,
+};
+
+/**
+ * struct tveeprom - Contains the fields parsed from Hauppauge eeproms
+ *
+ * @has_radio:			1 if the device has radio; 0 otherwise.
+ *
+ * @has_ir:			If has_ir == 0, then it is unknown what the IR
+ *				capabilities are. Otherwise:
+ *				bit 0) 1 (= IR capabilities are known);
+ *				bit 1) IR receiver present;
+ *				bit 2) IR transmitter (blaster) present.
+ *
+ * @has_MAC_address:		0: no MAC, 1: MAC present, 2: unknown.
+ * @tuner_type:			type of the tuner (TUNER_*, as defined at
+ *				include/media/tuner.h).
+ *
+ * @tuner_formats:		Supported analog TV standards (V4L2_STD_*).
+ * @tuner_hauppauge_model:	Hauppauge's code for the device model number.
+ * @tuner2_type:		type of the second tuner (TUNER_*, as defined
+ *				at include/media/tuner.h).
+ *
+ * @tuner2_formats:		Tuner 2 supported analog TV standards
+ *				(V4L2_STD_*).
+ *
+ * @tuner2_hauppauge_model:	tuner 2 Hauppauge's code for the device model
+ *				number.
+ *
+ * @audio_processor:		analog audio decoder, as defined by enum
+ *				tveeprom_audio_processor.
+ *
+ * @decoder_processor:		Hauppauge's code for the decoder chipset.
+ *				Unused by the drivers, as they probe the
+ *				decoder based on the PCI or USB ID.
+ *
+ * @model:			Hauppauge's model number
+ *
+ * @revision:			Card revision number
+ *
+ * @serial_number:		Card's serial number
+ *
+ * @rev_str:			Card revision converted to number
+ *
+ * @MAC_address:		MAC address for the network interface
+ */
+struct tveeprom {
+	u32 has_radio;
+	u32 has_ir;
+	u32 has_MAC_address;
+
+	u32 tuner_type;
+	u32 tuner_formats;
+	u32 tuner_hauppauge_model;
+
+	u32 tuner2_type;
+	u32 tuner2_formats;
+	u32 tuner2_hauppauge_model;
+
+	u32 audio_processor;
+	u32 decoder_processor;
+
+	u32 model;
+	u32 revision;
+	u32 serial_number;
+	char rev_str[5];
+	u8 MAC_address[ETH_ALEN];
+};
+
+/**
+ * tveeprom_hauppauge_analog - Fill struct tveeprom using the contents
+ *			       of the eeprom previously filled at
+ *			       @eeprom_data field.
+ *
+ * @tvee:		Struct to where the eeprom parsed data will be filled;
+ * @eeprom_data:	Array with the contents of the eeprom_data. It should
+ *			contain 256 bytes filled with the contents of the
+ *			eeprom read from the Hauppauge device.
+ */
+void tveeprom_hauppauge_analog(struct tveeprom *tvee,
+			       unsigned char *eeprom_data);
+
+/**
+ * tveeprom_read - Reads the contents of the eeprom found at the Hauppauge
+ *		   devices.
+ *
+ * @c:		I2C client struct
+ * @eedata:	Array where the eeprom content will be stored.
+ * @len:	Size of @eedata array. If the eeprom content will be latter
+ *		be parsed by tveeprom_hauppauge_analog(), len should be, at
+ *		least, 256.
+ */
+int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len);
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
new file mode 100644
index 0000000..1592d32
--- /dev/null
+++ b/include/media/v4l2-async.h
@@ -0,0 +1,226 @@
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef V4L2_ASYNC_H
+#define V4L2_ASYNC_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+struct device;
+struct device_node;
+struct v4l2_device;
+struct v4l2_subdev;
+struct v4l2_async_notifier;
+
+/* A random max subdevice number, used to allocate an array on stack */
+#define V4L2_MAX_SUBDEVS 128U
+
+/**
+ * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used
+ *	in order to identify a match
+ *
+ * @V4L2_ASYNC_MATCH_CUSTOM: Match will use the logic provided by &struct
+ *	v4l2_async_subdev.match ops
+ * @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
+ * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
+ * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
+ *
+ * This enum is used by the asyncrhronous sub-device logic to define the
+ * algorithm that will be used to match an asynchronous device.
+ */
+enum v4l2_async_match_type {
+	V4L2_ASYNC_MATCH_CUSTOM,
+	V4L2_ASYNC_MATCH_DEVNAME,
+	V4L2_ASYNC_MATCH_I2C,
+	V4L2_ASYNC_MATCH_FWNODE,
+};
+
+/**
+ * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
+ *
+ * @match_type:	type of match that will be used
+ * @match:	union of per-bus type matching data sets
+ * @match.fwnode:
+ *		pointer to &struct fwnode_handle to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
+ * @match.device_name:
+ *		string containing the device name to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
+ * @match.i2c:	embedded struct with I2C parameters to be matched.
+ *		Both @match.i2c.adapter_id and @match.i2c.address
+ *		should be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.adapter_id:
+ *		I2C adapter ID to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.address:
+ *		I2C address to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.custom:
+ *		Driver-specific match criteria.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.match:
+ *		Driver-specific match function to be used if
+ *		%V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.priv:
+ *		Driver-specific private struct with match parameters
+ *		to be used if %V4L2_ASYNC_MATCH_CUSTOM.
+ * @list:	used to link struct v4l2_async_subdev objects, waiting to be
+ *		probed, to a notifier->waiting list
+ *
+ * When this struct is used as a member in a driver specific struct,
+ * the driver specific struct shall contain the &struct
+ * v4l2_async_subdev as its first member.
+ */
+struct v4l2_async_subdev {
+	enum v4l2_async_match_type match_type;
+	union {
+		struct fwnode_handle *fwnode;
+		const char *device_name;
+		struct {
+			int adapter_id;
+			unsigned short address;
+		} i2c;
+		struct {
+			bool (*match)(struct device *,
+				      struct v4l2_async_subdev *);
+			void *priv;
+		} custom;
+	} match;
+
+	/* v4l2-async core private: not to be used by drivers */
+	struct list_head list;
+};
+
+/**
+ * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations
+ * @bound:	a subdevice driver has successfully probed one of the subdevices
+ * @complete:	All subdevices have been probed successfully. The complete
+ *		callback is only executed for the root notifier.
+ * @unbind:	a subdevice is leaving
+ */
+struct v4l2_async_notifier_operations {
+	int (*bound)(struct v4l2_async_notifier *notifier,
+		     struct v4l2_subdev *subdev,
+		     struct v4l2_async_subdev *asd);
+	int (*complete)(struct v4l2_async_notifier *notifier);
+	void (*unbind)(struct v4l2_async_notifier *notifier,
+		       struct v4l2_subdev *subdev,
+		       struct v4l2_async_subdev *asd);
+};
+
+/**
+ * struct v4l2_async_notifier - v4l2_device notifier data
+ *
+ * @ops:	notifier operations
+ * @num_subdevs: number of subdevices used in the subdevs array
+ * @max_subdevs: number of subdevices allocated in the subdevs array
+ * @subdevs:	array of pointers to subdevice descriptors
+ * @v4l2_dev:	v4l2_device of the root notifier, NULL otherwise
+ * @sd:		sub-device that registered the notifier, NULL otherwise
+ * @parent:	parent notifier
+ * @waiting:	list of struct v4l2_async_subdev, waiting for their drivers
+ * @done:	list of struct v4l2_subdev, already probed
+ * @list:	member in a global list of notifiers
+ */
+struct v4l2_async_notifier {
+	const struct v4l2_async_notifier_operations *ops;
+	unsigned int num_subdevs;
+	unsigned int max_subdevs;
+	struct v4l2_async_subdev **subdevs;
+	struct v4l2_device *v4l2_dev;
+	struct v4l2_subdev *sd;
+	struct v4l2_async_notifier *parent;
+	struct list_head waiting;
+	struct list_head done;
+	struct list_head list;
+};
+
+/**
+ * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @notifier: pointer to &struct v4l2_async_notifier
+ */
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+				 struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous
+ *					 notifier for a sub-device
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @notifier: pointer to &struct v4l2_async_notifier
+ */
+int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
+					struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ */
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_notifier_cleanup - clean up notifier resources
+ * @notifier: the notifier the resources of which are to be cleaned up
+ *
+ * Release memory resources related to a notifier, including the async
+ * sub-devices allocated for the purposes of the notifier but not the notifier
+ * itself. The user is responsible for calling this function to clean up the
+ * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
+ * @v4l2_fwnode_reference_parse_sensor_common.
+ *
+ * There is no harm from calling v4l2_async_notifier_cleanup in other
+ * cases as long as its memory has been zeroed after it has been
+ * allocated.
+ */
+void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_register_subdev - registers a sub-device to the asynchronous
+ *	subdevice framework
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
+int v4l2_async_register_subdev(struct v4l2_subdev *sd);
+
+/**
+ * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to
+ *					      the asynchronous sub-device
+ *					      framework and parse set up common
+ *					      sensor related devices
+ *
+ * @sd: pointer to struct &v4l2_subdev
+ *
+ * This function is just like v4l2_async_register_subdev() with the exception
+ * that calling it will also parse firmware interfaces for remote references
+ * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the
+ * async sub-devices. The sub-device is similarly unregistered by calling
+ * v4l2_async_unregister_subdev().
+ *
+ * While registered, the subdev module is marked as in-use.
+ *
+ * An error is returned if the module is no longer loaded on any attempts
+ * to register it.
+ */
+int __must_check v4l2_async_register_subdev_sensor_common(
+	struct v4l2_subdev *sd);
+
+/**
+ * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
+ *	subdevice framework
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
+#endif
diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h
new file mode 100644
index 0000000..7ec857f
--- /dev/null
+++ b/include/media/v4l2-clk.h
@@ -0,0 +1,76 @@
+/*
+ * V4L2 clock service
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ATTENTION: This is a temporary API and it shall be replaced by the generic
+ * clock API, when the latter becomes widely available.
+ */
+
+#ifndef MEDIA_V4L2_CLK_H
+#define MEDIA_V4L2_CLK_H
+
+#include <linux/atomic.h>
+#include <linux/export.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+struct module;
+struct device;
+
+struct clk;
+struct v4l2_clk {
+	struct list_head list;
+	const struct v4l2_clk_ops *ops;
+	const char *dev_id;
+	int enable;
+	struct mutex lock; /* Protect the enable count */
+	atomic_t use_count;
+	struct clk *clk;
+	void *priv;
+};
+
+struct v4l2_clk_ops {
+	struct module	*owner;
+	int		(*enable)(struct v4l2_clk *clk);
+	void		(*disable)(struct v4l2_clk *clk);
+	unsigned long	(*get_rate)(struct v4l2_clk *clk);
+	int		(*set_rate)(struct v4l2_clk *clk, unsigned long);
+};
+
+struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
+				   const char *dev_name,
+				   void *priv);
+void v4l2_clk_unregister(struct v4l2_clk *clk);
+struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id);
+void v4l2_clk_put(struct v4l2_clk *clk);
+int v4l2_clk_enable(struct v4l2_clk *clk);
+void v4l2_clk_disable(struct v4l2_clk *clk);
+unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk);
+int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate);
+
+struct module;
+
+struct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id,
+			unsigned long rate, struct module *owner);
+void v4l2_clk_unregister_fixed(struct v4l2_clk *clk);
+
+static inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id,
+							unsigned long rate)
+{
+	return __v4l2_clk_register_fixed(dev_id, rate, THIS_MODULE);
+}
+
+#define V4L2_CLK_NAME_SIZE 64
+
+#define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \
+			  "%d-%04x", adap, client)
+
+#define v4l2_clk_name_of(name, size, node) snprintf(name, size, \
+			  "of-%pOF", node)
+
+#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
new file mode 100644
index 0000000..cdc87ec
--- /dev/null
+++ b/include/media/v4l2-common.h
@@ -0,0 +1,387 @@
+/*
+    v4l2 common internal API header
+
+    This header contains internal shared ioctl definitions for use by the
+    internal low-level v4l2 drivers.
+    Each ioctl begins with VIDIOC_INT_ to clearly mark that it is an internal
+    define,
+
+    Copyright (C) 2005  Hans Verkuil <hverkuil@xs4all.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef V4L2_COMMON_H_
+#define V4L2_COMMON_H_
+
+#include <media/v4l2-dev.h>
+
+/* Common printk constructs for v4l-i2c drivers. These macros create a unique
+   prefix consisting of the driver name, the adapter number and the i2c
+   address. */
+#define v4l_printk(level, name, adapter, addr, fmt, arg...) \
+	printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg)
+
+#define v4l_client_printk(level, client, fmt, arg...)			    \
+	v4l_printk(level, (client)->dev.driver->name, (client)->adapter, \
+		   (client)->addr, fmt , ## arg)
+
+#define v4l_err(client, fmt, arg...) \
+	v4l_client_printk(KERN_ERR, client, fmt , ## arg)
+
+#define v4l_warn(client, fmt, arg...) \
+	v4l_client_printk(KERN_WARNING, client, fmt , ## arg)
+
+#define v4l_info(client, fmt, arg...) \
+	v4l_client_printk(KERN_INFO, client, fmt , ## arg)
+
+/* These three macros assume that the debug level is set with a module
+   parameter called 'debug'. */
+#define v4l_dbg(level, debug, client, fmt, arg...)			     \
+	do {								     \
+		if (debug >= (level))					     \
+			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
+	} while (0)
+
+/* Add a version of v4l_dbg to be used on drivers using dev_foo() macros */
+#define dev_dbg_lvl(__dev, __level, __debug, __fmt, __arg...)		\
+	do {								\
+		if (__debug >= (__level))				\
+			dev_printk(KERN_DEBUG, __dev, __fmt, ##__arg);	\
+	} while (0)
+
+/* ------------------------------------------------------------------------- */
+
+/* These printk constructs can be used with v4l2_device and v4l2_subdev */
+#define v4l2_printk(level, dev, fmt, arg...) \
+	printk(level "%s: " fmt, (dev)->name , ## arg)
+
+#define v4l2_err(dev, fmt, arg...) \
+	v4l2_printk(KERN_ERR, dev, fmt , ## arg)
+
+#define v4l2_warn(dev, fmt, arg...) \
+	v4l2_printk(KERN_WARNING, dev, fmt , ## arg)
+
+#define v4l2_info(dev, fmt, arg...) \
+	v4l2_printk(KERN_INFO, dev, fmt , ## arg)
+
+/* These three macros assume that the debug level is set with a module
+   parameter called 'debug'. */
+#define v4l2_dbg(level, debug, dev, fmt, arg...)			\
+	do {								\
+		if (debug >= (level))					\
+			v4l2_printk(KERN_DEBUG, dev, fmt , ## arg);	\
+	} while (0)
+
+/**
+ * v4l2_ctrl_query_fill- Fill in a struct v4l2_queryctrl
+ *
+ * @qctrl: pointer to the &struct v4l2_queryctrl to be filled
+ * @min: minimum value for the control
+ * @max: maximum value for the control
+ * @step: control step
+ * @def: default value for the control
+ *
+ * Fills the &struct v4l2_queryctrl fields for the query control.
+ *
+ * .. note::
+ *
+ *    This function assumes that the @qctrl->id field is filled.
+ *
+ * Returns -EINVAL if the control is not known by the V4L2 core, 0 on success.
+ */
+
+int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
+			 s32 min, s32 max, s32 step, s32 def);
+
+/* ------------------------------------------------------------------------- */
+
+/* I2C Helper functions */
+
+struct i2c_driver;
+struct i2c_adapter;
+struct i2c_client;
+struct i2c_device_id;
+struct v4l2_device;
+struct v4l2_subdev;
+struct v4l2_subdev_ops;
+
+/**
+ * v4l2_i2c_new_subdev - Load an i2c module and return an initialized
+ *	&struct v4l2_subdev.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @adapter: pointer to struct i2c_adapter
+ * @client_type:  name of the chip that's on the adapter.
+ * @addr: I2C address. If zero, it will use @probe_addrs
+ * @probe_addrs: array with a list of address. The last entry at such
+ *	array should be %I2C_CLIENT_END.
+ *
+ * returns a &struct v4l2_subdev pointer.
+ */
+struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter, const char *client_type,
+		u8 addr, const unsigned short *probe_addrs);
+
+struct i2c_board_info;
+
+/**
+ * v4l2_i2c_new_subdev_board - Load an i2c module and return an initialized
+ *	&struct v4l2_subdev.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @adapter: pointer to struct i2c_adapter
+ * @info: pointer to struct i2c_board_info used to replace the irq,
+ *	 platform_data and addr arguments.
+ * @probe_addrs: array with a list of address. The last entry at such
+ *	array should be %I2C_CLIENT_END.
+ *
+ * returns a &struct v4l2_subdev pointer.
+ */
+struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
+		struct i2c_adapter *adapter, struct i2c_board_info *info,
+		const unsigned short *probe_addrs);
+
+/**
+ * v4l2_i2c_subdev_init - Initializes a &struct v4l2_subdev with data from
+ *	an i2c_client struct.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @client: pointer to struct i2c_client
+ * @ops: pointer to &struct v4l2_subdev_ops
+ */
+void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
+		const struct v4l2_subdev_ops *ops);
+
+/**
+ * v4l2_i2c_subdev_addr - returns i2c client address of &struct v4l2_subdev.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * Returns the address of an I2C sub-device
+ */
+unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);
+
+/**
+ * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
+ *	should be used when seeking for I2C devices.
+ *
+ * @ADDRS_RADIO:		Radio tuner addresses.
+ *				Represent the following I2C addresses:
+ *				0x10 (if compiled with tea5761 support)
+ *				and 0x60.
+ * @ADDRS_DEMOD:		Demod tuner addresses.
+ *				Represent the following I2C addresses:
+ *				0x42, 0x43, 0x4a and 0x4b.
+ * @ADDRS_TV:			TV tuner addresses.
+ *				Represent the following I2C addresses:
+ *				0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
+ *				0x63 and 0x64.
+ * @ADDRS_TV_WITH_DEMOD:	TV tuner addresses if demod is present, this
+ *				excludes addresses used by the demodulator
+ *				from the list of candidates.
+ *				Represent the following I2C addresses:
+ *				0x60, 0x61, 0x62, 0x63 and 0x64.
+ *
+ * NOTE: All I2C addresses above use the 7-bit notation.
+ */
+enum v4l2_i2c_tuner_type {
+	ADDRS_RADIO,
+	ADDRS_DEMOD,
+	ADDRS_TV,
+	ADDRS_TV_WITH_DEMOD,
+};
+/**
+ * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
+ *
+ * @type: type of the tuner to seek, as defined by
+ *	  &enum v4l2_i2c_tuner_type.
+ *
+ * NOTE: Use only if the tuner addresses are unknown.
+ */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
+
+/* ------------------------------------------------------------------------- */
+
+/* SPI Helper functions */
+#if defined(CONFIG_SPI)
+
+#include <linux/spi/spi.h>
+
+struct spi_device;
+
+/**
+ *  v4l2_spi_new_subdev - Load an spi module and return an initialized
+ *	&struct v4l2_subdev.
+ *
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device.
+ * @master: pointer to struct spi_master.
+ * @info: pointer to struct spi_board_info.
+ *
+ * returns a &struct v4l2_subdev pointer.
+ */
+struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
+		struct spi_master *master, struct spi_board_info *info);
+
+/**
+ * v4l2_spi_subdev_init - Initialize a v4l2_subdev with data from an
+ *	spi_device struct.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @spi: pointer to struct spi_device.
+ * @ops: pointer to &struct v4l2_subdev_ops
+ */
+void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
+		const struct v4l2_subdev_ops *ops);
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * FIXME: these remaining ioctls/structs should be removed as well, but they
+ * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
+ * To remove these ioctls some more cleanup is needed in those modules.
+ *
+ * It doesn't make much sense on documenting them, as what we really want is
+ * to get rid of them.
+ */
+
+/* s_config */
+struct v4l2_priv_tun_config {
+	int tuner;
+	void *priv;
+};
+#define TUNER_SET_CONFIG           _IOW('d', 92, struct v4l2_priv_tun_config)
+
+#define VIDIOC_INT_RESET		_IOW ('d', 102, u32)
+
+/* ------------------------------------------------------------------------- */
+
+/* Miscellaneous helper functions */
+
+/**
+ * v4l_bound_align_image - adjust video dimensions according to
+ *	a given constraints.
+ *
+ * @width:	pointer to width that will be adjusted if needed.
+ * @wmin:	minimum width.
+ * @wmax:	maximum width.
+ * @walign:	least significant bit on width.
+ * @height:	pointer to height that will be adjusted if needed.
+ * @hmin:	minimum height.
+ * @hmax:	maximum height.
+ * @halign:	least significant bit on width.
+ * @salign:	least significant bit for the image size (e. g.
+ *		:math:`width * height`).
+ *
+ * Clip an image to have @width between @wmin and @wmax, and @height between
+ * @hmin and @hmax, inclusive.
+ *
+ * Additionally, the @width will be a multiple of :math:`2^{walign}`,
+ * the @height will be a multiple of :math:`2^{halign}`, and the overall
+ * size :math:`width * height` will be a multiple of :math:`2^{salign}`.
+ *
+ * .. note::
+ *
+ *    #. The clipping rectangle may be shrunk or enlarged to fit the alignment
+ *       constraints.
+ *    #. @wmax must not be smaller than @wmin.
+ *    #. @hmax must not be smaller than @hmin.
+ *    #. The alignments must not be so high there are no possible image
+ *       sizes within the allowed bounds.
+ *    #. @wmin and @hmin must be at least 1 (don't use 0).
+ *    #. For @walign, @halign and @salign, if you don't care about a certain
+ *       alignment, specify ``0``, as :math:`2^0 = 1` and one byte alignment
+ *       is equivalent to no alignment.
+ *    #. If you only want to adjust downward, specify a maximum that's the
+ *       same as the initial value.
+ */
+void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
+			   unsigned int wmax, unsigned int walign,
+			   unsigned int *height, unsigned int hmin,
+			   unsigned int hmax, unsigned int halign,
+			   unsigned int salign);
+
+/**
+ * v4l2_find_nearest_size - Find the nearest size among a discrete
+ *	set of resolutions contained in an array of a driver specific struct.
+ *
+ * @array: a driver specific array of image sizes
+ * @array_size: the length of the driver specific array of image sizes
+ * @width_field: the name of the width field in the driver specific struct
+ * @height_field: the name of the height field in the driver specific struct
+ * @width: desired width.
+ * @height: desired height.
+ *
+ * Finds the closest resolution to minimize the width and height differences
+ * between what requested and the supported resolutions. The size of the width
+ * and height fields in the driver specific must equal to that of u32, i.e. four
+ * bytes.
+ *
+ * Returns the best match or NULL if the length of the array is zero.
+ */
+#define v4l2_find_nearest_size(array, array_size, width_field, height_field, \
+			       width, height)				\
+	({								\
+		BUILD_BUG_ON(sizeof((array)->width_field) != sizeof(u32) || \
+			     sizeof((array)->height_field) != sizeof(u32)); \
+		(typeof(&(array)[0]))__v4l2_find_nearest_size(		\
+			(array), array_size, sizeof(*(array)),		\
+			offsetof(typeof(*(array)), width_field),	\
+			offsetof(typeof(*(array)), height_field),	\
+			width, height);					\
+	})
+const void *
+__v4l2_find_nearest_size(const void *array, size_t array_size,
+			 size_t entry_size, size_t width_offset,
+			 size_t height_offset, s32 width, s32 height);
+
+/**
+ * v4l2_get_timestamp - helper routine to get a timestamp to be used when
+ *	filling streaming metadata. Internally, it uses ktime_get_ts(),
+ *	which is the recommended way to get it.
+ *
+ * @tv: pointer to &struct timeval to be filled.
+ */
+void v4l2_get_timestamp(struct timeval *tv);
+
+/**
+ * v4l2_g_parm_cap - helper routine for vidioc_g_parm to fill this in by
+ *      calling the g_frame_interval op of the given subdev. It only works
+ *      for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the
+ *      function name.
+ *
+ * @vdev: the struct video_device pointer. Used to determine the device caps.
+ * @sd: the sub-device pointer.
+ * @a: the VIDIOC_G_PARM argument.
+ */
+int v4l2_g_parm_cap(struct video_device *vdev,
+		    struct v4l2_subdev *sd, struct v4l2_streamparm *a);
+
+/**
+ * v4l2_s_parm_cap - helper routine for vidioc_s_parm to fill this in by
+ *      calling the s_frame_interval op of the given subdev. It only works
+ *      for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the
+ *      function name.
+ *
+ * @vdev: the struct video_device pointer. Used to determine the device caps.
+ * @sd: the sub-device pointer.
+ * @a: the VIDIOC_S_PARM argument.
+ */
+int v4l2_s_parm_cap(struct video_device *vdev,
+		    struct v4l2_subdev *sd, struct v4l2_streamparm *a);
+
+#endif /* V4L2_COMMON_H_ */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
new file mode 100644
index 0000000..f615ba1
--- /dev/null
+++ b/include/media/v4l2-ctrls.h
@@ -0,0 +1,1167 @@
+/*
+ *  V4L2 controls support header.
+ *
+ *  Copyright (C) 2010  Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _V4L2_CTRLS_H
+#define _V4L2_CTRLS_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+
+/* forward references */
+struct file;
+struct v4l2_ctrl_handler;
+struct v4l2_ctrl_helper;
+struct v4l2_ctrl;
+struct video_device;
+struct v4l2_subdev;
+struct v4l2_subscribed_event;
+struct v4l2_fh;
+struct poll_table_struct;
+
+/**
+ * union v4l2_ctrl_ptr - A pointer to a control value.
+ * @p_s32:	Pointer to a 32-bit signed value.
+ * @p_s64:	Pointer to a 64-bit signed value.
+ * @p_u8:	Pointer to a 8-bit unsigned value.
+ * @p_u16:	Pointer to a 16-bit unsigned value.
+ * @p_u32:	Pointer to a 32-bit unsigned value.
+ * @p_char:	Pointer to a string.
+ * @p:		Pointer to a compound value.
+ */
+union v4l2_ctrl_ptr {
+	s32 *p_s32;
+	s64 *p_s64;
+	u8 *p_u8;
+	u16 *p_u16;
+	u32 *p_u32;
+	char *p_char;
+	void *p;
+};
+
+/**
+ * struct v4l2_ctrl_ops - The control operations that the driver has to provide.
+ *
+ * @g_volatile_ctrl: Get a new value for this control. Generally only relevant
+ *		for volatile (and usually read-only) controls such as a control
+ *		that returns the current signal strength which changes
+ *		continuously.
+ *		If not set, then the currently cached value will be returned.
+ * @try_ctrl:	Test whether the control's value is valid. Only relevant when
+ *		the usual min/max/step checks are not sufficient.
+ * @s_ctrl:	Actually set the new control value. s_ctrl is compulsory. The
+ *		ctrl->handler->lock is held when these ops are called, so no
+ *		one else can access controls owned by that handler.
+ */
+struct v4l2_ctrl_ops {
+	int (*g_volatile_ctrl)(struct v4l2_ctrl *ctrl);
+	int (*try_ctrl)(struct v4l2_ctrl *ctrl);
+	int (*s_ctrl)(struct v4l2_ctrl *ctrl);
+};
+
+/**
+ * struct v4l2_ctrl_type_ops - The control type operations that the driver
+ *			       has to provide.
+ *
+ * @equal: return true if both values are equal.
+ * @init: initialize the value.
+ * @log: log the value.
+ * @validate: validate the value. Return 0 on success and a negative value
+ *	otherwise.
+ */
+struct v4l2_ctrl_type_ops {
+	bool (*equal)(const struct v4l2_ctrl *ctrl, u32 idx,
+		      union v4l2_ctrl_ptr ptr1,
+		      union v4l2_ctrl_ptr ptr2);
+	void (*init)(const struct v4l2_ctrl *ctrl, u32 idx,
+		     union v4l2_ctrl_ptr ptr);
+	void (*log)(const struct v4l2_ctrl *ctrl);
+	int (*validate)(const struct v4l2_ctrl *ctrl, u32 idx,
+			union v4l2_ctrl_ptr ptr);
+};
+
+/**
+ * typedef v4l2_ctrl_notify_fnc - typedef for a notify argument with a function
+ *	that should be called when a control value has changed.
+ *
+ * @ctrl: pointer to struct &v4l2_ctrl
+ * @priv: control private data
+ *
+ * This typedef definition is used as an argument to v4l2_ctrl_notify()
+ * and as an argument at struct &v4l2_ctrl_handler.
+ */
+typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
+
+/**
+ * struct v4l2_ctrl - The control structure.
+ *
+ * @node:	The list node.
+ * @ev_subs:	The list of control event subscriptions.
+ * @handler:	The handler that owns the control.
+ * @cluster:	Point to start of cluster array.
+ * @ncontrols:	Number of controls in cluster array.
+ * @done:	Internal flag: set for each processed control.
+ * @is_new:	Set when the user specified a new value for this control. It
+ *		is also set when called from v4l2_ctrl_handler_setup(). Drivers
+ *		should never set this flag.
+ * @has_changed: Set when the current value differs from the new value. Drivers
+ *		should never use this flag.
+ * @is_private: If set, then this control is private to its handler and it
+ *		will not be added to any other handlers. Drivers can set
+ *		this flag.
+ * @is_auto:   If set, then this control selects whether the other cluster
+ *		members are in 'automatic' mode or 'manual' mode. This is
+ *		used for autogain/gain type clusters. Drivers should never
+ *		set this flag directly.
+ * @is_int:    If set, then this control has a simple integer value (i.e. it
+ *		uses ctrl->val).
+ * @is_string: If set, then this control has type %V4L2_CTRL_TYPE_STRING.
+ * @is_ptr:	If set, then this control is an array and/or has type >=
+ *		%V4L2_CTRL_COMPOUND_TYPES
+ *		and/or has type %V4L2_CTRL_TYPE_STRING. In other words, &struct
+ *		v4l2_ext_control uses field p to point to the data.
+ * @is_array: If set, then this control contains an N-dimensional array.
+ * @has_volatiles: If set, then one or more members of the cluster are volatile.
+ *		Drivers should never touch this flag.
+ * @call_notify: If set, then call the handler's notify function whenever the
+ *		control's value changes.
+ * @manual_mode_value: If the is_auto flag is set, then this is the value
+ *		of the auto control that determines if that control is in
+ *		manual mode. So if the value of the auto control equals this
+ *		value, then the whole cluster is in manual mode. Drivers should
+ *		never set this flag directly.
+ * @ops:	The control ops.
+ * @type_ops:	The control type ops.
+ * @id:	The control ID.
+ * @name:	The control name.
+ * @type:	The control type.
+ * @minimum:	The control's minimum value.
+ * @maximum:	The control's maximum value.
+ * @default_value: The control's default value.
+ * @step:	The control's step value for non-menu controls.
+ * @elems:	The number of elements in the N-dimensional array.
+ * @elem_size:	The size in bytes of the control.
+ * @dims:	The size of each dimension.
+ * @nr_of_dims:The number of dimensions in @dims.
+ * @menu_skip_mask: The control's skip mask for menu controls. This makes it
+ *		easy to skip menu items that are not valid. If bit X is set,
+ *		then menu item X is skipped. Of course, this only works for
+ *		menus with <= 32 menu items. There are no menus that come
+ *		close to that number, so this is OK. Should we ever need more,
+ *		then this will have to be extended to a u64 or a bit array.
+ * @qmenu:	A const char * array for all menu items. Array entries that are
+ *		empty strings ("") correspond to non-existing menu items (this
+ *		is in addition to the menu_skip_mask above). The last entry
+ *		must be NULL.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_MENU.
+ * @qmenu_int:	A 64-bit integer array for with integer menu items.
+ *		The size of array must be equal to the menu size, e. g.:
+ *		:math:`ceil(\frac{maximum - minimum}{step}) + 1`.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_INTEGER_MENU.
+ * @flags:	The control's flags.
+ * @cur:	Structure to store the current value.
+ * @cur.val:	The control's current value, if the @type is represented via
+ *		a u32 integer (see &enum v4l2_ctrl_type).
+ * @val:	The control's new s32 value.
+ * @priv:	The control's private pointer. For use by the driver. It is
+ *		untouched by the control framework. Note that this pointer is
+ *		not freed when the control is deleted. Should this be needed
+ *		then a new internal bitfield can be added to tell the framework
+ *		to free this pointer.
+ * @p_cur:	The control's current value represented via a union which
+ *		provides a standard way of accessing control types
+ *		through a pointer.
+ * @p_new:	The control's new value represented via a union which provides
+ *		a standard way of accessing control types
+ *		through a pointer.
+ */
+struct v4l2_ctrl {
+	/* Administrative fields */
+	struct list_head node;
+	struct list_head ev_subs;
+	struct v4l2_ctrl_handler *handler;
+	struct v4l2_ctrl **cluster;
+	unsigned int ncontrols;
+
+	unsigned int done:1;
+
+	unsigned int is_new:1;
+	unsigned int has_changed:1;
+	unsigned int is_private:1;
+	unsigned int is_auto:1;
+	unsigned int is_int:1;
+	unsigned int is_string:1;
+	unsigned int is_ptr:1;
+	unsigned int is_array:1;
+	unsigned int has_volatiles:1;
+	unsigned int call_notify:1;
+	unsigned int manual_mode_value:8;
+
+	const struct v4l2_ctrl_ops *ops;
+	const struct v4l2_ctrl_type_ops *type_ops;
+	u32 id;
+	const char *name;
+	enum v4l2_ctrl_type type;
+	s64 minimum, maximum, default_value;
+	u32 elems;
+	u32 elem_size;
+	u32 dims[V4L2_CTRL_MAX_DIMS];
+	u32 nr_of_dims;
+	union {
+		u64 step;
+		u64 menu_skip_mask;
+	};
+	union {
+		const char * const *qmenu;
+		const s64 *qmenu_int;
+	};
+	unsigned long flags;
+	void *priv;
+	s32 val;
+	struct {
+		s32 val;
+	} cur;
+
+	union v4l2_ctrl_ptr p_new;
+	union v4l2_ctrl_ptr p_cur;
+};
+
+/**
+ * struct v4l2_ctrl_ref - The control reference.
+ *
+ * @node:	List node for the sorted list.
+ * @next:	Single-link list node for the hash.
+ * @ctrl:	The actual control information.
+ * @helper:	Pointer to helper struct. Used internally in
+ *		``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``.
+ *
+ * Each control handler has a list of these refs. The list_head is used to
+ * keep a sorted-by-control-ID list of all controls, while the next pointer
+ * is used to link the control in the hash's bucket.
+ */
+struct v4l2_ctrl_ref {
+	struct list_head node;
+	struct v4l2_ctrl_ref *next;
+	struct v4l2_ctrl *ctrl;
+	struct v4l2_ctrl_helper *helper;
+};
+
+/**
+ * struct v4l2_ctrl_handler - The control handler keeps track of all the
+ *	controls: both the controls owned by the handler and those inherited
+ *	from other handlers.
+ *
+ * @_lock:	Default for "lock".
+ * @lock:	Lock to control access to this handler and its controls.
+ *		May be replaced by the user right after init.
+ * @ctrls:	The list of controls owned by this handler.
+ * @ctrl_refs:	The list of control references.
+ * @cached:	The last found control reference. It is common that the same
+ *		control is needed multiple times, so this is a simple
+ *		optimization.
+ * @buckets:	Buckets for the hashing. Allows for quick control lookup.
+ * @notify:	A notify callback that is called whenever the control changes
+ *		value.
+ *		Note that the handler's lock is held when the notify function
+ *		is called!
+ * @notify_priv: Passed as argument to the v4l2_ctrl notify callback.
+ * @nr_of_buckets: Total number of buckets in the array.
+ * @error:	The error code of the first failed control addition.
+ */
+struct v4l2_ctrl_handler {
+	struct mutex _lock;
+	struct mutex *lock;
+	struct list_head ctrls;
+	struct list_head ctrl_refs;
+	struct v4l2_ctrl_ref *cached;
+	struct v4l2_ctrl_ref **buckets;
+	v4l2_ctrl_notify_fnc notify;
+	void *notify_priv;
+	u16 nr_of_buckets;
+	int error;
+};
+
+/**
+ * struct v4l2_ctrl_config - Control configuration structure.
+ *
+ * @ops:	The control ops.
+ * @type_ops:	The control type ops. Only needed for compound controls.
+ * @id:	The control ID.
+ * @name:	The control name.
+ * @type:	The control type.
+ * @min:	The control's minimum value.
+ * @max:	The control's maximum value.
+ * @step:	The control's step value for non-menu controls.
+ * @def:	The control's default value.
+ * @dims:	The size of each dimension.
+ * @elem_size:	The size in bytes of the control.
+ * @flags:	The control's flags.
+ * @menu_skip_mask: The control's skip mask for menu controls. This makes it
+ *		easy to skip menu items that are not valid. If bit X is set,
+ *		then menu item X is skipped. Of course, this only works for
+ *		menus with <= 64 menu items. There are no menus that come
+ *		close to that number, so this is OK. Should we ever need more,
+ *		then this will have to be extended to a bit array.
+ * @qmenu:	A const char * array for all menu items. Array entries that are
+ *		empty strings ("") correspond to non-existing menu items (this
+ *		is in addition to the menu_skip_mask above). The last entry
+ *		must be NULL.
+ * @qmenu_int:	A const s64 integer array for all menu items of the type
+ *		V4L2_CTRL_TYPE_INTEGER_MENU.
+ * @is_private: If set, then this control is private to its handler and it
+ *		will not be added to any other handlers.
+ */
+struct v4l2_ctrl_config {
+	const struct v4l2_ctrl_ops *ops;
+	const struct v4l2_ctrl_type_ops *type_ops;
+	u32 id;
+	const char *name;
+	enum v4l2_ctrl_type type;
+	s64 min;
+	s64 max;
+	u64 step;
+	s64 def;
+	u32 dims[V4L2_CTRL_MAX_DIMS];
+	u32 elem_size;
+	u32 flags;
+	u64 menu_skip_mask;
+	const char * const *qmenu;
+	const s64 *qmenu_int;
+	unsigned int is_private:1;
+};
+
+/**
+ * v4l2_ctrl_fill - Fill in the control fields based on the control ID.
+ *
+ * @id: ID of the control
+ * @name: pointer to be filled with a string with the name of the control
+ * @type: pointer for storing the type of the control
+ * @min: pointer for storing the minimum value for the control
+ * @max: pointer for storing the maximum value for the control
+ * @step: pointer for storing the control step
+ * @def: pointer for storing the default value for the control
+ * @flags: pointer for storing the flags to be used on the control
+ *
+ * This works for all standard V4L2 controls.
+ * For non-standard controls it will only fill in the given arguments
+ * and @name content will be set to %NULL.
+ *
+ * This function will overwrite the contents of @name, @type and @flags.
+ * The contents of @min, @max, @step and @def may be modified depending on
+ * the type.
+ *
+ * .. note::
+ *
+ *    Do not use in drivers! It is used internally for backwards compatibility
+ *    control handling only. Once all drivers are converted to use the new
+ *    control framework this function will no longer be exported.
+ */
+void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
+		    s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags);
+
+
+/**
+ * v4l2_ctrl_handler_init_class() - Initialize the control handler.
+ * @hdl:	The control handler.
+ * @nr_of_controls_hint: A hint of how many controls this handler is
+ *		expected to refer to. This is the total number, so including
+ *		any inherited controls. It doesn't have to be precise, but if
+ *		it is way off, then you either waste memory (too many buckets
+ *		are allocated) or the control lookup becomes slower (not enough
+ *		buckets are allocated, so there are more slow list lookups).
+ *		It will always work, though.
+ * @key:	Used by the lock validator if CONFIG_LOCKDEP is set.
+ * @name:	Used by the lock validator if CONFIG_LOCKDEP is set.
+ *
+ * .. attention::
+ *
+ *    Never use this call directly, always use the v4l2_ctrl_handler_init()
+ *    macro that hides the @key and @name arguments.
+ *
+ * Return: returns an error if the buckets could not be allocated. This
+ * error will also be stored in @hdl->error.
+ */
+int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
+				 unsigned int nr_of_controls_hint,
+				 struct lock_class_key *key, const char *name);
+
+#ifdef CONFIG_LOCKDEP
+
+/**
+ * v4l2_ctrl_handler_init - helper function to create a static struct
+ *	 &lock_class_key and calls v4l2_ctrl_handler_init_class()
+ *
+ * @hdl:	The control handler.
+ * @nr_of_controls_hint: A hint of how many controls this handler is
+ *		expected to refer to. This is the total number, so including
+ *		any inherited controls. It doesn't have to be precise, but if
+ *		it is way off, then you either waste memory (too many buckets
+ *		are allocated) or the control lookup becomes slower (not enough
+ *		buckets are allocated, so there are more slow list lookups).
+ *		It will always work, though.
+ *
+ * This helper function creates a static struct &lock_class_key and
+ * calls v4l2_ctrl_handler_init_class(), providing a proper name for the lock
+ * validador.
+ *
+ * Use this helper function to initialize a control handler.
+ */
+#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint)		\
+(									\
+	({								\
+		static struct lock_class_key _key;			\
+		v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint,	\
+					&_key,				\
+					KBUILD_BASENAME ":"		\
+					__stringify(__LINE__) ":"	\
+					"(" #hdl ")->_lock");		\
+	})								\
+)
+#else
+#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint)		\
+	v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint, NULL, NULL)
+#endif
+
+/**
+ * v4l2_ctrl_handler_free() - Free all controls owned by the handler and free
+ * the control list.
+ * @hdl:	The control handler.
+ *
+ * Does nothing if @hdl == NULL.
+ */
+void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl);
+
+/**
+ * v4l2_ctrl_lock() - Helper function to lock the handler
+ * associated with the control.
+ * @ctrl:	The control to lock.
+ */
+static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
+{
+	mutex_lock(ctrl->handler->lock);
+}
+
+/**
+ * v4l2_ctrl_unlock() - Helper function to unlock the handler
+ * associated with the control.
+ * @ctrl:	The control to unlock.
+ */
+static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
+{
+	mutex_unlock(ctrl->handler->lock);
+}
+
+/**
+ * __v4l2_ctrl_handler_setup() - Call the s_ctrl op for all controls belonging
+ * to the handler to initialize the hardware to the current control values. The
+ * caller is responsible for acquiring the control handler mutex on behalf of
+ * __v4l2_ctrl_handler_setup().
+ * @hdl:	The control handler.
+ *
+ * Button controls will be skipped, as are read-only controls.
+ *
+ * If @hdl == NULL, then this just returns 0.
+ */
+int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl);
+
+/**
+ * v4l2_ctrl_handler_setup() - Call the s_ctrl op for all controls belonging
+ * to the handler to initialize the hardware to the current control values.
+ * @hdl:	The control handler.
+ *
+ * Button controls will be skipped, as are read-only controls.
+ *
+ * If @hdl == NULL, then this just returns 0.
+ */
+int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl);
+
+/**
+ * v4l2_ctrl_handler_log_status() - Log all controls owned by the handler.
+ * @hdl:	The control handler.
+ * @prefix:	The prefix to use when logging the control values. If the
+ *		prefix does not end with a space, then ": " will be added
+ *		after the prefix. If @prefix == NULL, then no prefix will be
+ *		used.
+ *
+ * For use with VIDIOC_LOG_STATUS.
+ *
+ * Does nothing if @hdl == NULL.
+ */
+void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
+				  const char *prefix);
+
+/**
+ * v4l2_ctrl_new_custom() - Allocate and initialize a new custom V4L2
+ *	control.
+ *
+ * @hdl:	The control handler.
+ * @cfg:	The control's configuration data.
+ * @priv:	The control's driver-specific private data.
+ *
+ * If the &v4l2_ctrl struct could not be allocated then NULL is returned
+ * and @hdl->error is set to the error code (if it wasn't set already).
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
+				       const struct v4l2_ctrl_config *cfg,
+				       void *priv);
+
+/**
+ * v4l2_ctrl_new_std() - Allocate and initialize a new standard V4L2 non-menu
+ *	control.
+ *
+ * @hdl:	The control handler.
+ * @ops:	The control ops.
+ * @id:		The control ID.
+ * @min:	The control's minimum value.
+ * @max:	The control's maximum value.
+ * @step:	The control's step value
+ * @def:	The control's default value.
+ *
+ * If the &v4l2_ctrl struct could not be allocated, or the control
+ * ID is not known, then NULL is returned and @hdl->error is set to the
+ * appropriate error code (if it wasn't set already).
+ *
+ * If @id refers to a menu control, then this function will return NULL.
+ *
+ * Use v4l2_ctrl_new_std_menu() when adding menu controls.
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
+				    const struct v4l2_ctrl_ops *ops,
+				    u32 id, s64 min, s64 max, u64 step,
+				    s64 def);
+
+/**
+ * v4l2_ctrl_new_std_menu() - Allocate and initialize a new standard V4L2
+ *	menu control.
+ *
+ * @hdl:	The control handler.
+ * @ops:	The control ops.
+ * @id:		The control ID.
+ * @max:	The control's maximum value.
+ * @mask:	The control's skip mask for menu controls. This makes it
+ *		easy to skip menu items that are not valid. If bit X is set,
+ *		then menu item X is skipped. Of course, this only works for
+ *		menus with <= 64 menu items. There are no menus that come
+ *		close to that number, so this is OK. Should we ever need more,
+ *		then this will have to be extended to a bit array.
+ * @def:	The control's default value.
+ *
+ * Same as v4l2_ctrl_new_std(), but @min is set to 0 and the @mask value
+ * determines which menu items are to be skipped.
+ *
+ * If @id refers to a non-menu control, then this function will return NULL.
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
+					 const struct v4l2_ctrl_ops *ops,
+					 u32 id, u8 max, u64 mask, u8 def);
+
+/**
+ * v4l2_ctrl_new_std_menu_items() - Create a new standard V4L2 menu control
+ *	with driver specific menu.
+ *
+ * @hdl:	The control handler.
+ * @ops:	The control ops.
+ * @id:	The control ID.
+ * @max:	The control's maximum value.
+ * @mask:	The control's skip mask for menu controls. This makes it
+ *		easy to skip menu items that are not valid. If bit X is set,
+ *		then menu item X is skipped. Of course, this only works for
+ *		menus with <= 64 menu items. There are no menus that come
+ *		close to that number, so this is OK. Should we ever need more,
+ *		then this will have to be extended to a bit array.
+ * @def:	The control's default value.
+ * @qmenu:	The new menu.
+ *
+ * Same as v4l2_ctrl_new_std_menu(), but @qmenu will be the driver specific
+ * menu of this control.
+ *
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
+					       const struct v4l2_ctrl_ops *ops,
+					       u32 id, u8 max,
+					       u64 mask, u8 def,
+					       const char * const *qmenu);
+
+/**
+ * v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control.
+ *
+ * @hdl:	The control handler.
+ * @ops:	The control ops.
+ * @id:	The control ID.
+ * @max:	The control's maximum value.
+ * @def:	The control's default value.
+ * @qmenu_int:	The control's menu entries.
+ *
+ * Same as v4l2_ctrl_new_std_menu(), but @mask is set to 0 and it additionaly
+ * takes as an argument an array of integers determining the menu items.
+ *
+ * If @id refers to a non-integer-menu control, then this function will
+ * return %NULL.
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
+					 const struct v4l2_ctrl_ops *ops,
+					 u32 id, u8 max, u8 def,
+					 const s64 *qmenu_int);
+
+/**
+ * typedef v4l2_ctrl_filter - Typedef to define the filter function to be
+ *	used when adding a control handler.
+ *
+ * @ctrl: pointer to struct &v4l2_ctrl.
+ */
+
+typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl);
+
+/**
+ * v4l2_ctrl_add_handler() - Add all controls from handler @add to
+ *	handler @hdl.
+ *
+ * @hdl:	The control handler.
+ * @add:	The control handler whose controls you want to add to
+ *		the @hdl control handler.
+ * @filter:	This function will filter which controls should be added.
+ *
+ * Does nothing if either of the two handlers is a NULL pointer.
+ * If @filter is NULL, then all controls are added. Otherwise only those
+ * controls for which @filter returns true will be added.
+ * In case of an error @hdl->error will be set to the error code (if it
+ * wasn't set already).
+ */
+int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
+			  struct v4l2_ctrl_handler *add,
+			  v4l2_ctrl_filter filter);
+
+/**
+ * v4l2_ctrl_radio_filter() - Standard filter for radio controls.
+ *
+ * @ctrl:	The control that is filtered.
+ *
+ * This will return true for any controls that are valid for radio device
+ * nodes. Those are all of the V4L2_CID_AUDIO_* user controls and all FM
+ * transmitter class controls.
+ *
+ * This function is to be used with v4l2_ctrl_add_handler().
+ */
+bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl);
+
+/**
+ * v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging
+ *	to that cluster.
+ *
+ * @ncontrols:	The number of controls in this cluster.
+ * @controls:	The cluster control array of size @ncontrols.
+ */
+void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls);
+
+
+/**
+ * v4l2_ctrl_auto_cluster() - Mark all controls in the cluster as belonging
+ *	to that cluster and set it up for autofoo/foo-type handling.
+ *
+ * @ncontrols:	The number of controls in this cluster.
+ * @controls:	The cluster control array of size @ncontrols. The first control
+ *		must be the 'auto' control (e.g. autogain, autoexposure, etc.)
+ * @manual_val: The value for the first control in the cluster that equals the
+ *		manual setting.
+ * @set_volatile: If true, then all controls except the first auto control will
+ *		be volatile.
+ *
+ * Use for control groups where one control selects some automatic feature and
+ * the other controls are only active whenever the automatic feature is turned
+ * off (manual mode). Typical examples: autogain vs gain, auto-whitebalance vs
+ * red and blue balance, etc.
+ *
+ * The behavior of such controls is as follows:
+ *
+ * When the autofoo control is set to automatic, then any manual controls
+ * are set to inactive and any reads will call g_volatile_ctrl (if the control
+ * was marked volatile).
+ *
+ * When the autofoo control is set to manual, then any manual controls will
+ * be marked active, and any reads will just return the current value without
+ * going through g_volatile_ctrl.
+ *
+ * In addition, this function will set the %V4L2_CTRL_FLAG_UPDATE flag
+ * on the autofoo control and %V4L2_CTRL_FLAG_INACTIVE on the foo control(s)
+ * if autofoo is in auto mode.
+ */
+void v4l2_ctrl_auto_cluster(unsigned int ncontrols,
+			    struct v4l2_ctrl **controls,
+			    u8 manual_val, bool set_volatile);
+
+
+/**
+ * v4l2_ctrl_find() - Find a control with the given ID.
+ *
+ * @hdl:	The control handler.
+ * @id:	The control ID to find.
+ *
+ * If @hdl == NULL this will return NULL as well. Will lock the handler so
+ * do not use from inside &v4l2_ctrl_ops.
+ */
+struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id);
+
+/**
+ * v4l2_ctrl_activate() - Make the control active or inactive.
+ * @ctrl:	The control to (de)activate.
+ * @active:	True if the control should become active.
+ *
+ * This sets or clears the V4L2_CTRL_FLAG_INACTIVE flag atomically.
+ * Does nothing if @ctrl == NULL.
+ * This will usually be called from within the s_ctrl op.
+ * The V4L2_EVENT_CTRL event will be generated afterwards.
+ *
+ * This function assumes that the control handler is locked.
+ */
+void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
+
+/**
+ * v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed.
+ *
+ * @ctrl:	The control to (de)activate.
+ * @grabbed:	True if the control should become grabbed.
+ *
+ * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically.
+ * Does nothing if @ctrl == NULL.
+ * The V4L2_EVENT_CTRL event will be generated afterwards.
+ * This will usually be called when starting or stopping streaming in the
+ * driver.
+ *
+ * This function assumes that the control handler is not locked and will
+ * take the lock itself.
+ */
+void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
+
+/**
+ *__v4l2_ctrl_modify_range() - Unlocked variant of v4l2_ctrl_modify_range()
+ *
+ * @ctrl:	The control to update.
+ * @min:	The control's minimum value.
+ * @max:	The control's maximum value.
+ * @step:	The control's step value
+ * @def:	The control's default value.
+ *
+ * Update the range of a control on the fly. This works for control types
+ * INTEGER, BOOLEAN, MENU, INTEGER MENU and BITMASK. For menu controls the
+ * @step value is interpreted as a menu_skip_mask.
+ *
+ * An error is returned if one of the range arguments is invalid for this
+ * control type.
+ *
+ * The caller is responsible for acquiring the control handler mutex on behalf
+ * of __v4l2_ctrl_modify_range().
+ */
+int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
+			     s64 min, s64 max, u64 step, s64 def);
+
+/**
+ * v4l2_ctrl_modify_range() - Update the range of a control.
+ *
+ * @ctrl:	The control to update.
+ * @min:	The control's minimum value.
+ * @max:	The control's maximum value.
+ * @step:	The control's step value
+ * @def:	The control's default value.
+ *
+ * Update the range of a control on the fly. This works for control types
+ * INTEGER, BOOLEAN, MENU, INTEGER MENU and BITMASK. For menu controls the
+ * @step value is interpreted as a menu_skip_mask.
+ *
+ * An error is returned if one of the range arguments is invalid for this
+ * control type.
+ *
+ * This function assumes that the control handler is not locked and will
+ * take the lock itself.
+ */
+static inline int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
+					 s64 min, s64 max, u64 step, s64 def)
+{
+	int rval;
+
+	v4l2_ctrl_lock(ctrl);
+	rval = __v4l2_ctrl_modify_range(ctrl, min, max, step, def);
+	v4l2_ctrl_unlock(ctrl);
+
+	return rval;
+}
+
+/**
+ * v4l2_ctrl_notify() - Function to set a notify callback for a control.
+ *
+ * @ctrl:	The control.
+ * @notify:	The callback function.
+ * @priv:	The callback private handle, passed as argument to the callback.
+ *
+ * This function sets a callback function for the control. If @ctrl is NULL,
+ * then it will do nothing. If @notify is NULL, then the notify callback will
+ * be removed.
+ *
+ * There can be only one notify. If another already exists, then a WARN_ON
+ * will be issued and the function will do nothing.
+ */
+void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify,
+		      void *priv);
+
+/**
+ * v4l2_ctrl_get_name() - Get the name of the control
+ *
+ * @id:		The control ID.
+ *
+ * This function returns the name of the given control ID or NULL if it isn't
+ * a known control.
+ */
+const char *v4l2_ctrl_get_name(u32 id);
+
+/**
+ * v4l2_ctrl_get_menu() - Get the menu string array of the control
+ *
+ * @id:		The control ID.
+ *
+ * This function returns the NULL-terminated menu string array name of the
+ * given control ID or NULL if it isn't a known menu control.
+ */
+const char * const *v4l2_ctrl_get_menu(u32 id);
+
+/**
+ * v4l2_ctrl_get_int_menu() - Get the integer menu array of the control
+ *
+ * @id:		The control ID.
+ * @len:	The size of the integer array.
+ *
+ * This function returns the integer array of the given control ID or NULL if it
+ * if it isn't a known integer menu control.
+ */
+const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len);
+
+/**
+ * v4l2_ctrl_g_ctrl() - Helper function to get the control's value from
+ *	within a driver.
+ *
+ * @ctrl:	The control.
+ *
+ * This returns the control's value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for integer type controls only.
+ */
+s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
+
+/**
+ * __v4l2_ctrl_s_ctrl() - Unlocked variant of v4l2_ctrl_s_ctrl().
+ *
+ * @ctrl:	The control.
+ * @val:	TheControls name new value.
+ *
+ * This sets the control's new value safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for integer type controls only.
+ */
+int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
+
+/**
+ * v4l2_ctrl_s_ctrl() - Helper function to set the control's value from
+ *	within a driver.
+ * @ctrl:	The control.
+ * @val:	The new value.
+ *
+ * This sets the control's new value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for integer type controls only.
+ */
+static inline int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
+{
+	int rval;
+
+	v4l2_ctrl_lock(ctrl);
+	rval = __v4l2_ctrl_s_ctrl(ctrl, val);
+	v4l2_ctrl_unlock(ctrl);
+
+	return rval;
+}
+
+/**
+ * v4l2_ctrl_g_ctrl_int64() - Helper function to get a 64-bit control's value
+ *	from within a driver.
+ *
+ * @ctrl:	The control.
+ *
+ * This returns the control's value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for 64-bit integer type controls only.
+ */
+s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl);
+
+/**
+ * __v4l2_ctrl_s_ctrl_int64() - Unlocked variant of v4l2_ctrl_s_ctrl_int64().
+ *
+ * @ctrl:	The control.
+ * @val:	The new value.
+ *
+ * This sets the control's new value safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for 64-bit integer type controls only.
+ */
+int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val);
+
+/**
+ * v4l2_ctrl_s_ctrl_int64() - Helper function to set a 64-bit control's value
+ *	from within a driver.
+ *
+ * @ctrl:	The control.
+ * @val:	The new value.
+ *
+ * This sets the control's new value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for 64-bit integer type controls only.
+ */
+static inline int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
+{
+	int rval;
+
+	v4l2_ctrl_lock(ctrl);
+	rval = __v4l2_ctrl_s_ctrl_int64(ctrl, val);
+	v4l2_ctrl_unlock(ctrl);
+
+	return rval;
+}
+
+/**
+ * __v4l2_ctrl_s_ctrl_string() - Unlocked variant of v4l2_ctrl_s_ctrl_string().
+ *
+ * @ctrl:	The control.
+ * @s:		The new string.
+ *
+ * This sets the control's new string safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for string type controls only.
+ */
+int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s);
+
+/**
+ * v4l2_ctrl_s_ctrl_string() - Helper function to set a control's string value
+ *	 from within a driver.
+ *
+ * @ctrl:	The control.
+ * @s:		The new string.
+ *Controls name
+ * This sets the control's new string safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for string type controls only.
+ */
+static inline int v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
+{
+	int rval;
+
+	v4l2_ctrl_lock(ctrl);
+	rval = __v4l2_ctrl_s_ctrl_string(ctrl, s);
+	v4l2_ctrl_unlock(ctrl);
+
+	return rval;
+}
+
+/* Internal helper functions that deal with control events. */
+extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
+
+/**
+ * v4l2_ctrl_replace - Function to be used as a callback to
+ *	&struct v4l2_subscribed_event_ops replace\(\)
+ *
+ * @old: pointer to struct &v4l2_event with the reported
+ *	 event;
+ * @new: pointer to struct &v4l2_event with the modified
+ *	 event;
+ */
+void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);
+
+/**
+ * v4l2_ctrl_merge - Function to be used as a callback to
+ *	&struct v4l2_subscribed_event_ops merge(\)
+ *
+ * @old: pointer to struct &v4l2_event with the reported
+ *	 event;
+ * @new: pointer to struct &v4l2_event with the merged
+ *	 event;
+ */
+void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new);
+
+/**
+ * v4l2_ctrl_log_status - helper function to implement %VIDIOC_LOG_STATUS ioctl
+ *
+ * @file: pointer to struct file
+ * @fh: unused. Kept just to be compatible to the arguments expected by
+ *	&struct v4l2_ioctl_ops.vidioc_log_status.
+ *
+ * Can be used as a vidioc_log_status function that just dumps all controls
+ * associated with the filehandle.
+ */
+int v4l2_ctrl_log_status(struct file *file, void *fh);
+
+/**
+ * v4l2_ctrl_subscribe_event - Subscribes to an event
+ *
+ *
+ * @fh: pointer to struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ *
+ * Can be used as a vidioc_subscribe_event function that just subscribes
+ * control events.
+ */
+int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
+				const struct v4l2_event_subscription *sub);
+
+/**
+ * v4l2_ctrl_poll - function to be used as a callback to the poll()
+ *	That just polls for control events.
+ *
+ * @file: pointer to struct file
+ * @wait: pointer to struct poll_table_struct
+ */
+__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait);
+
+/* Helpers for ioctl_ops */
+
+/**
+ * v4l2_queryctrl - Helper function to implement
+ *	:ref:`VIDIOC_QUERYCTRL <vidioc_queryctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @qc: pointer to &struct v4l2_queryctrl
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc);
+
+/**
+ * v4l2_query_ext_ctrl - Helper function to implement
+ *	 :ref:`VIDIOC_QUERY_EXT_CTRL <vidioc_queryctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @qc: pointer to &struct v4l2_query_ext_ctrl
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl,
+			struct v4l2_query_ext_ctrl *qc);
+
+/**
+ * v4l2_querymenu - Helper function to implement
+ *	:ref:`VIDIOC_QUERYMENU <vidioc_queryctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @qm: pointer to &struct v4l2_querymenu
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm);
+
+/**
+ * v4l2_g_ctrl - Helper function to implement
+ *	:ref:`VIDIOC_G_CTRL <vidioc_g_ctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @ctrl: pointer to &struct v4l2_control
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl);
+
+/**
+ * v4l2_s_ctrl - Helper function to implement
+ *	:ref:`VIDIOC_S_CTRL <vidioc_g_ctrl>` ioctl
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ *
+ * @ctrl: pointer to &struct v4l2_control
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+		struct v4l2_control *ctrl);
+
+/**
+ * v4l2_g_ext_ctrls - Helper function to implement
+ *	:ref:`VIDIOC_G_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @c: pointer to &struct v4l2_ext_controls
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+		     struct v4l2_ext_controls *c);
+
+/**
+ * v4l2_try_ext_ctrls - Helper function to implement
+ *	:ref:`VIDIOC_TRY_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @c: pointer to &struct v4l2_ext_controls
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+		       struct v4l2_ext_controls *c);
+
+/**
+ * v4l2_s_ext_ctrls - Helper function to implement
+ *	:ref:`VIDIOC_S_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @c: pointer to &struct v4l2_ext_controls
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+		     struct v4l2_ext_controls *c);
+
+/**
+ * v4l2_ctrl_subdev_subscribe_event - Helper function to implement
+ *	as a &struct v4l2_subdev_core_ops subscribe_event function
+ *	that just subscribes control events.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
+int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+				     struct v4l2_event_subscription *sub);
+
+/**
+ * v4l2_ctrl_subdev_log_status - Log all controls owned by subdev's control
+ *	 handler.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
+int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd);
+
+#endif
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
new file mode 100644
index 0000000..456ac13
--- /dev/null
+++ b/include/media/v4l2-dev.h
@@ -0,0 +1,527 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ * Moved from videodev2.h
+ *
+ *	Some commonly needed functions for drivers (v4l2-common.o module)
+ */
+#ifndef _V4L2_DEV_H
+#define _V4L2_DEV_H
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+
+#include <media/media-entity.h>
+
+#define VIDEO_MAJOR	81
+
+/**
+ * enum vfl_devnode_type - type of V4L2 device node
+ *
+ * @VFL_TYPE_GRABBER:	for video input/output devices
+ * @VFL_TYPE_VBI:	for vertical blank data (i.e. closed captions, teletext)
+ * @VFL_TYPE_RADIO:	for radio tuners
+ * @VFL_TYPE_SUBDEV:	for V4L2 subdevices
+ * @VFL_TYPE_SDR:	for Software Defined Radio tuners
+ * @VFL_TYPE_TOUCH:	for touch sensors
+ * @VFL_TYPE_MAX:	number of VFL types, must always be last in the enum
+ */
+enum vfl_devnode_type {
+	VFL_TYPE_GRABBER	= 0,
+	VFL_TYPE_VBI,
+	VFL_TYPE_RADIO,
+	VFL_TYPE_SUBDEV,
+	VFL_TYPE_SDR,
+	VFL_TYPE_TOUCH,
+	VFL_TYPE_MAX /* Shall be the last one */
+};
+
+/**
+ * enum  vfl_direction - Identifies if a &struct video_device corresponds
+ *	to a receiver, a transmitter or a mem-to-mem device.
+ *
+ * @VFL_DIR_RX:		device is a receiver.
+ * @VFL_DIR_TX:		device is a transmitter.
+ * @VFL_DIR_M2M:	device is a memory to memory device.
+ *
+ * Note: Ignored if &enum vfl_devnode_type is %VFL_TYPE_SUBDEV.
+ */
+enum vfl_devnode_direction {
+	VFL_DIR_RX,
+	VFL_DIR_TX,
+	VFL_DIR_M2M,
+};
+
+struct v4l2_ioctl_callbacks;
+struct video_device;
+struct v4l2_device;
+struct v4l2_ctrl_handler;
+
+/**
+ * enum v4l2_video_device_flags - Flags used by &struct video_device
+ *
+ * @V4L2_FL_REGISTERED:
+ *	indicates that a &struct video_device is registered.
+ *	Drivers can clear this flag if they want to block all future
+ *	device access. It is cleared by video_unregister_device.
+ * @V4L2_FL_USES_V4L2_FH:
+ *	indicates that file->private_data points to &struct v4l2_fh.
+ *	This flag is set by the core when v4l2_fh_init() is called.
+ *	All new drivers should use it.
+ */
+enum v4l2_video_device_flags {
+	V4L2_FL_REGISTERED	= 0,
+	V4L2_FL_USES_V4L2_FH	= 1,
+};
+
+/* Priority helper functions */
+
+/**
+ * struct v4l2_prio_state - stores the priority states
+ *
+ * @prios: array with elements to store the array priorities
+ *
+ *
+ * .. note::
+ *    The size of @prios array matches the number of priority types defined
+ *    by enum &v4l2_priority.
+ */
+struct v4l2_prio_state {
+	atomic_t prios[4];
+};
+
+/**
+ * v4l2_prio_init - initializes a struct v4l2_prio_state
+ *
+ * @global: pointer to &struct v4l2_prio_state
+ */
+void v4l2_prio_init(struct v4l2_prio_state *global);
+
+/**
+ * v4l2_prio_change - changes the v4l2 file handler priority
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: pointer to the desired priority, as defined by enum &v4l2_priority
+ * @new: Priority type requested, as defined by enum &v4l2_priority.
+ *
+ * .. note::
+ *	This function should be used only by the V4L2 core.
+ */
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+		     enum v4l2_priority new);
+
+/**
+ * v4l2_prio_open - Implements the priority logic for a file handler open
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: pointer to the desired priority, as defined by enum &v4l2_priority
+ *
+ * .. note::
+ *	This function should be used only by the V4L2 core.
+ */
+void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
+
+/**
+ * v4l2_prio_close - Implements the priority logic for a file handler close
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: priority to be released, as defined by enum &v4l2_priority
+ *
+ * .. note::
+ *	This function should be used only by the V4L2 core.
+ */
+void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
+
+/**
+ * v4l2_prio_max - Return the maximum priority, as stored at the @global array.
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ *
+ * .. note::
+ *	This function should be used only by the V4L2 core.
+ */
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
+
+/**
+ * v4l2_prio_check - Implements the priority logic for a file handler close
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: desired priority, as defined by enum &v4l2_priority local
+ *
+ * .. note::
+ *	This function should be used only by the V4L2 core.
+ */
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
+
+/**
+ * struct v4l2_file_operations - fs operations used by a V4L2 device
+ *
+ * @owner: pointer to struct module
+ * @read: operations needed to implement the read() syscall
+ * @write: operations needed to implement the write() syscall
+ * @poll: operations needed to implement the poll() syscall
+ * @unlocked_ioctl: operations needed to implement the ioctl() syscall
+ * @compat_ioctl32: operations needed to implement the ioctl() syscall for
+ *	the special case where the Kernel uses 64 bits instructions, but
+ *	the userspace uses 32 bits.
+ * @get_unmapped_area: called by the mmap() syscall, used when %!CONFIG_MMU
+ * @mmap: operations needed to implement the mmap() syscall
+ * @open: operations needed to implement the open() syscall
+ * @release: operations needed to implement the release() syscall
+ *
+ * .. note::
+ *
+ *	Those operations are used to implemente the fs struct file_operations
+ *	at the V4L2 drivers. The V4L2 core overrides the fs ops with some
+ *	extra logic needed by the subsystem.
+ */
+struct v4l2_file_operations {
+	struct module *owner;
+	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
+	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
+	__poll_t (*poll) (struct file *, struct poll_table_struct *);
+	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+#ifdef CONFIG_COMPAT
+	long (*compat_ioctl32) (struct file *, unsigned int, unsigned long);
+#endif
+	unsigned long (*get_unmapped_area) (struct file *, unsigned long,
+				unsigned long, unsigned long, unsigned long);
+	int (*mmap) (struct file *, struct vm_area_struct *);
+	int (*open) (struct file *);
+	int (*release) (struct file *);
+};
+
+/*
+ * Newer version of video_device, handled by videodev2.c
+ *	This version moves redundant code from video device code to
+ *	the common handler
+ */
+
+/**
+ * struct video_device - Structure used to create and manage the V4L2 device
+ *	nodes.
+ *
+ * @entity: &struct media_entity
+ * @intf_devnode: pointer to &struct media_intf_devnode
+ * @pipe: &struct media_pipeline
+ * @fops: pointer to &struct v4l2_file_operations for the video device
+ * @device_caps: device capabilities as used in v4l2_capabilities
+ * @dev: &struct device for the video device
+ * @cdev: character device
+ * @v4l2_dev: pointer to &struct v4l2_device parent
+ * @dev_parent: pointer to &struct device parent
+ * @ctrl_handler: Control handler associated with this device node.
+ *	 May be NULL.
+ * @queue: &struct vb2_queue associated with this device node. May be NULL.
+ * @prio: pointer to &struct v4l2_prio_state with device's Priority state.
+ *	 If NULL, then v4l2_dev->prio will be used.
+ * @name: video device name
+ * @vfl_type: V4L device type, as defined by &enum vfl_devnode_type
+ * @vfl_dir: V4L receiver, transmitter or m2m
+ * @minor: device node 'minor'. It is set to -1 if the registration failed
+ * @num: number of the video device node
+ * @flags: video device flags. Use bitops to set/clear/test flags.
+ *	   Contains a set of &enum v4l2_video_device_flags.
+ * @index: attribute to differentiate multiple indices on one physical device
+ * @fh_lock: Lock for all v4l2_fhs
+ * @fh_list: List of &struct v4l2_fh
+ * @dev_debug: Internal device debug flags, not for use by drivers
+ * @tvnorms: Supported tv norms
+ *
+ * @release: video device release() callback
+ * @ioctl_ops: pointer to &struct v4l2_ioctl_ops with ioctl callbacks
+ *
+ * @valid_ioctls: bitmap with the valid ioctls for this device
+ * @lock: pointer to &struct mutex serialization lock
+ *
+ * .. note::
+ *	Only set @dev_parent if that can't be deduced from @v4l2_dev.
+ */
+
+struct video_device
+{
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	struct media_entity entity;
+	struct media_intf_devnode *intf_devnode;
+	struct media_pipeline pipe;
+#endif
+	const struct v4l2_file_operations *fops;
+
+	u32 device_caps;
+
+	/* sysfs */
+	struct device dev;
+	struct cdev *cdev;
+
+	struct v4l2_device *v4l2_dev;
+	struct device *dev_parent;
+
+	struct v4l2_ctrl_handler *ctrl_handler;
+
+	struct vb2_queue *queue;
+
+	struct v4l2_prio_state *prio;
+
+	/* device info */
+	char name[32];
+	enum vfl_devnode_type vfl_type;
+	enum vfl_devnode_direction vfl_dir;
+	int minor;
+	u16 num;
+	unsigned long flags;
+	int index;
+
+	/* V4L2 file handles */
+	spinlock_t		fh_lock;
+	struct list_head	fh_list;
+
+	int dev_debug;
+
+	v4l2_std_id tvnorms;
+
+	/* callbacks */
+	void (*release)(struct video_device *vdev);
+	const struct v4l2_ioctl_ops *ioctl_ops;
+	DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
+
+	struct mutex *lock;
+};
+
+/**
+ * media_entity_to_video_device - Returns a &struct video_device from
+ *	the &struct media_entity embedded on it.
+ *
+ * @__entity: pointer to &struct media_entity
+ */
+#define media_entity_to_video_device(__entity) \
+	container_of(__entity, struct video_device, entity)
+
+/**
+ * to_video_device - Returns a &struct video_device from the
+ *	&struct device embedded on it.
+ *
+ * @cd: pointer to &struct device
+ */
+#define to_video_device(cd) container_of(cd, struct video_device, dev)
+
+/**
+ * __video_register_device - register video4linux devices
+ *
+ * @vdev: struct video_device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
+ * @nr:   which device node number is desired:
+ *	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ * @warn_if_nr_in_use: warn if the desired device node number
+ *        was already in use and another number was chosen instead.
+ * @owner: module that owns the video device node
+ *
+ * The registration code assigns minor numbers and device node numbers
+ * based on the requested type and registers the new device node with
+ * the kernel.
+ *
+ * This function assumes that struct video_device was zeroed when it
+ * was allocated and does not contain any stale date.
+ *
+ * An error is returned if no free minor or device node number could be
+ * found, or if the registration of the device node failed.
+ *
+ * Returns 0 on success.
+ *
+ * .. note::
+ *
+ *	This function is meant to be used only inside the V4L2 core.
+ *	Drivers should use video_register_device() or
+ *	video_register_device_no_warn().
+ */
+int __must_check __video_register_device(struct video_device *vdev,
+					 enum vfl_devnode_type type,
+					 int nr, int warn_if_nr_in_use,
+					 struct module *owner);
+
+/**
+ *  video_register_device - register video4linux devices
+ *
+ * @vdev: struct video_device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
+ * @nr:   which device node number is desired:
+ *	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *
+ * Internally, it calls __video_register_device(). Please see its
+ * documentation for more details.
+ *
+ * .. note::
+ *	if video_register_device fails, the release() callback of
+ *	&struct video_device structure is *not* called, so the caller
+ *	is responsible for freeing any data. Usually that means that
+ *	you video_device_release() should be called on failure.
+ */
+static inline int __must_check video_register_device(struct video_device *vdev,
+						     enum vfl_devnode_type type,
+						     int nr)
+{
+	return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
+}
+
+/**
+ *  video_register_device_no_warn - register video4linux devices
+ *
+ * @vdev: struct video_device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
+ * @nr:   which device node number is desired:
+ *	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *
+ * This function is identical to video_register_device() except that no
+ * warning is issued if the desired device node number was already in use.
+ *
+ * Internally, it calls __video_register_device(). Please see its
+ * documentation for more details.
+ *
+ * .. note::
+ *	if video_register_device fails, the release() callback of
+ *	&struct video_device structure is *not* called, so the caller
+ *	is responsible for freeing any data. Usually that means that
+ *	you video_device_release() should be called on failure.
+ */
+static inline int __must_check
+video_register_device_no_warn(struct video_device *vdev,
+			      enum vfl_devnode_type type, int nr)
+{
+	return __video_register_device(vdev, type, nr, 0, vdev->fops->owner);
+}
+
+/**
+ * video_unregister_device - Unregister video devices.
+ *
+ * @vdev: &struct video_device to register
+ *
+ * Does nothing if vdev == NULL or if video_is_registered() returns false.
+ */
+void video_unregister_device(struct video_device *vdev);
+
+/**
+ * video_device_alloc - helper function to alloc &struct video_device
+ *
+ * Returns NULL if %-ENOMEM or a &struct video_device on success.
+ */
+struct video_device * __must_check video_device_alloc(void);
+
+/**
+ * video_device_release - helper function to release &struct video_device
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * Can also be used for video_device->release\(\).
+ */
+void video_device_release(struct video_device *vdev);
+
+/**
+ * video_device_release_empty - helper function to implement the
+ *	video_device->release\(\) callback.
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * This release function does nothing.
+ *
+ * It should be used when the video_device is a static global struct.
+ *
+ * .. note::
+ *	Having a static video_device is a dubious construction at best.
+ */
+void video_device_release_empty(struct video_device *vdev);
+
+/**
+ * v4l2_disable_ioctl- mark that a given command isn't implemented.
+ *	shouldn't use core locking
+ *
+ * @vdev: pointer to &struct video_device
+ * @cmd: ioctl command
+ *
+ * This function allows drivers to provide just one v4l2_ioctl_ops struct, but
+ * disable ioctls based on the specific card that is actually found.
+ *
+ * .. note::
+ *
+ *    This must be called before video_register_device.
+ *    See also the comments for determine_valid_ioctls().
+ */
+static inline void v4l2_disable_ioctl(struct video_device *vdev,
+				      unsigned int cmd)
+{
+	if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
+		set_bit(_IOC_NR(cmd), vdev->valid_ioctls);
+}
+
+/**
+ * video_get_drvdata - gets private data from &struct video_device.
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * returns a pointer to the private data
+ */
+static inline void *video_get_drvdata(struct video_device *vdev)
+{
+	return dev_get_drvdata(&vdev->dev);
+}
+
+/**
+ * video_set_drvdata - sets private data from &struct video_device.
+ *
+ * @vdev: pointer to &struct video_device
+ * @data: private data pointer
+ */
+static inline void video_set_drvdata(struct video_device *vdev, void *data)
+{
+	dev_set_drvdata(&vdev->dev, data);
+}
+
+/**
+ * video_devdata - gets &struct video_device from struct file.
+ *
+ * @file: pointer to struct file
+ */
+struct video_device *video_devdata(struct file *file);
+
+/**
+ * video_drvdata - gets private data from &struct video_device using the
+ *	struct file.
+ *
+ * @file: pointer to struct file
+ *
+ * This is function combines both video_get_drvdata() and video_devdata()
+ * as this is used very often.
+ */
+static inline void *video_drvdata(struct file *file)
+{
+	return video_get_drvdata(video_devdata(file));
+}
+
+/**
+ * video_device_node_name - returns the video device name
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * Returns the device name string
+ */
+static inline const char *video_device_node_name(struct video_device *vdev)
+{
+	return dev_name(&vdev->dev);
+}
+
+/**
+ * video_is_registered - returns true if the &struct video_device is registered.
+ *
+ *
+ * @vdev: pointer to &struct video_device
+ */
+static inline int video_is_registered(struct video_device *vdev)
+{
+	return test_bit(V4L2_FL_REGISTERED, &vdev->flags);
+}
+
+#endif /* _V4L2_DEV_H */
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
new file mode 100644
index 0000000..b330e4a
--- /dev/null
+++ b/include/media/v4l2-device.h
@@ -0,0 +1,527 @@
+/*
+    V4L2 device support header.
+
+    Copyright (C) 2008  Hans Verkuil <hverkuil@xs4all.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _V4L2_DEVICE_H
+#define _V4L2_DEVICE_H
+
+#include <media/media-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-dev.h>
+
+#define V4L2_DEVICE_NAME_SIZE (20 + 16)
+
+struct v4l2_ctrl_handler;
+
+/**
+ * struct v4l2_device - main struct to for V4L2 device drivers
+ *
+ * @dev: pointer to struct device.
+ * @mdev: pointer to struct media_device, may be NULL.
+ * @subdevs: used to keep track of the registered subdevs
+ * @lock: lock this struct; can be used by the driver as well
+ *	if this struct is embedded into a larger struct.
+ * @name: unique device name, by default the driver name + bus ID
+ * @notify: notify operation called by some sub-devices.
+ * @ctrl_handler: The control handler. May be %NULL.
+ * @prio: Device's priority state
+ * @ref: Keep track of the references to this struct.
+ * @release: Release function that is called when the ref count
+ *	goes to 0.
+ *
+ * Each instance of a V4L2 device should create the v4l2_device struct,
+ * either stand-alone or embedded in a larger struct.
+ *
+ * It allows easy access to sub-devices (see v4l2-subdev.h) and provides
+ * basic V4L2 device-level support.
+ *
+ * .. note::
+ *
+ *    #) @dev->driver_data points to this struct.
+ *    #) @dev might be %NULL if there is no parent device
+ */
+struct v4l2_device {
+	struct device *dev;
+	struct media_device *mdev;
+	struct list_head subdevs;
+	spinlock_t lock;
+	char name[V4L2_DEVICE_NAME_SIZE];
+	void (*notify)(struct v4l2_subdev *sd,
+			unsigned int notification, void *arg);
+	struct v4l2_ctrl_handler *ctrl_handler;
+	struct v4l2_prio_state prio;
+	struct kref ref;
+	void (*release)(struct v4l2_device *v4l2_dev);
+};
+
+/**
+ * v4l2_device_get - gets a V4L2 device reference
+ *
+ * @v4l2_dev: pointer to struct &v4l2_device
+ *
+ * This is an ancillary routine meant to increment the usage for the
+ * struct &v4l2_device pointed by @v4l2_dev.
+ */
+static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
+{
+	kref_get(&v4l2_dev->ref);
+}
+
+/**
+ * v4l2_device_put - putss a V4L2 device reference
+ *
+ * @v4l2_dev: pointer to struct &v4l2_device
+ *
+ * This is an ancillary routine meant to decrement the usage for the
+ * struct &v4l2_device pointed by @v4l2_dev.
+ */
+int v4l2_device_put(struct v4l2_device *v4l2_dev);
+
+/**
+ * v4l2_device_register - Initialize v4l2_dev and make @dev->driver_data
+ *	point to @v4l2_dev.
+ *
+ * @dev: pointer to struct &device
+ * @v4l2_dev: pointer to struct &v4l2_device
+ *
+ * .. note::
+ *	@dev may be %NULL in rare cases (ISA devices).
+ *	In such case the caller must fill in the @v4l2_dev->name field
+ *	before calling this function.
+ */
+int __must_check v4l2_device_register(struct device *dev,
+				      struct v4l2_device *v4l2_dev);
+
+/**
+ * v4l2_device_set_name - Optional function to initialize the
+ *	name field of struct &v4l2_device
+ *
+ * @v4l2_dev: pointer to struct &v4l2_device
+ * @basename: base name for the device name
+ * @instance: pointer to a static atomic_t var with the instance usage for
+ *	the device driver.
+ *
+ * v4l2_device_set_name() initializes the name field of struct &v4l2_device
+ * using the driver name and a driver-global atomic_t instance.
+ *
+ * This function will increment the instance counter and returns the
+ * instance value used in the name.
+ *
+ * Example:
+ *
+ *   static atomic_t drv_instance = ATOMIC_INIT(0);
+ *
+ *   ...
+ *
+ *   instance = v4l2_device_set_name(&\ v4l2_dev, "foo", &\ drv_instance);
+ *
+ * The first time this is called the name field will be set to foo0 and
+ * this function returns 0. If the name ends with a digit (e.g. cx18),
+ * then the name will be set to cx18-0 since cx180 would look really odd.
+ */
+int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
+			 atomic_t *instance);
+
+/**
+ * v4l2_device_disconnect - Change V4L2 device state to disconnected.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ *
+ * Should be called when the USB parent disconnects.
+ * Since the parent disappears, this ensures that @v4l2_dev doesn't have
+ * an invalid parent pointer.
+ *
+ * .. note:: This function sets @v4l2_dev->dev to NULL.
+ */
+void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
+
+/**
+ *  v4l2_device_unregister - Unregister all sub-devices and any other
+ *	 resources related to @v4l2_dev.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ */
+void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
+
+/**
+ * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
+ *
+ * @v4l2_dev: pointer to struct &v4l2_device
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * While registered, the subdev module is marked as in-use.
+ *
+ * An error is returned if the module is no longer loaded on any attempts
+ * to register it.
+ */
+int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
+					     struct v4l2_subdev *sd);
+
+/**
+ * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * .. note ::
+ *
+ *	Can also be called if the subdev wasn't registered. In such
+ *	case, it will do nothing.
+ */
+void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
+
+/**
+ * v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs
+ *	of the v4l2 device that are marked with
+ *	the %V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ */
+int __must_check
+v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
+
+/**
+ * v4l2_subdev_notify - Sends a notification to v4l2_device.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @notification: type of notification. Please notice that the notification
+ *	type is driver-specific.
+ * @arg: arguments for the notification. Those are specific to each
+ *	notification type.
+ */
+static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
+				      unsigned int notification, void *arg)
+{
+	if (sd && sd->v4l2_dev && sd->v4l2_dev->notify)
+		sd->v4l2_dev->notify(sd, notification, arg);
+}
+
+/* Helper macros to iterate over all subdevs. */
+
+/**
+ * v4l2_device_for_each_subdev - Helper macro that interates over all
+ *	sub-devices of a given &v4l2_device.
+ *
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev pointer used as an iterator by the loop.
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ *
+ * This macro iterates over all sub-devices owned by the @v4l2_dev device.
+ * It acts as a for loop iterator and executes the next statement with
+ * the @sd variable pointing to each sub-device in turn.
+ */
+#define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
+	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
+
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev pointer used as an iterator by the loop.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
+	do {								\
+		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
+			if ((cond) && (sd)->ops->o && (sd)->ops->o->f)	\
+				(sd)->ops->o->f((sd) , ##args);		\
+	} while (0)
+
+/**
+ * __v4l2_device_call_subdevs - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
+	do {								\
+		struct v4l2_subdev *__sd;				\
+									\
+		__v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o,	\
+						f , ##args);		\
+	} while (0)
+
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code, zero
+ * otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
+({									\
+	long __err = 0;							\
+									\
+	list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) {		\
+		if ((cond) && (sd)->ops->o && (sd)->ops->o->f)		\
+			__err = (sd)->ops->o->f((sd) , ##args);		\
+		if (__err && __err != -ENOIOCTLCMD)			\
+			break;						\
+	}								\
+	(__err == -ENOIOCTLCMD) ? 0 : __err;				\
+})
+
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
+({									\
+	struct v4l2_subdev *__sd;					\
+	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o,	\
+						f , ##args);		\
+})
+
+/**
+ * v4l2_device_call_all - Calls the specified operation for
+ *	all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ *	by the bridge driver.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ *	    Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
+	do {								\
+		struct v4l2_subdev *__sd;				\
+									\
+		__v4l2_device_call_subdevs_p(v4l2_dev, __sd,		\
+			!(grpid) || __sd->grp_id == (grpid), o, f ,	\
+			##args);					\
+	} while (0)
+
+/**
+ * v4l2_device_call_until_err - Calls the specified operation for
+ *	all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ *	by the bridge driver, until an error occurs.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ *	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)	\
+({									\
+	struct v4l2_subdev *__sd;					\
+	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,		\
+			!(grpid) || __sd->grp_id == (grpid), o, f ,	\
+			##args);					\
+})
+
+/**
+ * v4l2_device_mask_call_all - Calls the specified operation for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)	\
+	do {								\
+		struct v4l2_subdev *__sd;				\
+									\
+		__v4l2_device_call_subdevs_p(v4l2_dev, __sd,		\
+			!(grpmsk) || (__sd->grp_id & (grpmsk)), o, f ,	\
+			##args);					\
+	} while (0)
+
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified operation for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
+#define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
+({									\
+	struct v4l2_subdev *__sd;					\
+	__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd,		\
+			!(grpmsk) || (__sd->grp_id & (grpmsk)), o, f ,	\
+			##args);					\
+})
+
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ *	given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ *	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ */
+#define v4l2_device_has_op(v4l2_dev, grpid, o, f)			\
+({									\
+	struct v4l2_subdev *__sd;					\
+	bool __result = false;						\
+	list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) {		\
+		if ((grpid) && __sd->grp_id != (grpid))			\
+			continue;					\
+		if (v4l2_subdev_has_op(__sd, o, f)) {			\
+			__result = true;				\
+			break;						\
+		}							\
+	}								\
+	__result;							\
+})
+
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ *	mask has a given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ */
+#define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f)			\
+({									\
+	struct v4l2_subdev *__sd;					\
+	bool __result = false;						\
+	list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) {		\
+		if ((grpmsk) && !(__sd->grp_id & (grpmsk)))		\
+			continue;					\
+		if (v4l2_subdev_has_op(__sd, o, f)) {			\
+			__result = true;				\
+			break;						\
+		}							\
+	}								\
+	__result;							\
+})
+
+#endif
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
new file mode 100644
index 0000000..17cb27d
--- /dev/null
+++ b/include/media/v4l2-dv-timings.h
@@ -0,0 +1,237 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * v4l2-dv-timings - Internal header with dv-timings helper functions
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef __V4L2_DV_TIMINGS_H
+#define __V4L2_DV_TIMINGS_H
+
+#include <linux/videodev2.h>
+
+/*
+ * v4l2_dv_timings_presets: list of all dv_timings presets.
+ */
+extern const struct v4l2_dv_timings v4l2_dv_timings_presets[];
+
+/**
+ * typedef v4l2_check_dv_timings_fnc - timings check callback
+ *
+ * @t: the v4l2_dv_timings struct.
+ * @handle: a handle from the driver.
+ *
+ * Returns true if the given timings are valid.
+ */
+typedef bool v4l2_check_dv_timings_fnc(const struct v4l2_dv_timings *t, void *handle);
+
+/**
+ * v4l2_valid_dv_timings() - are these timings valid?
+ *
+ * @t:	  the v4l2_dv_timings struct.
+ * @cap: the v4l2_dv_timings_cap capabilities.
+ * @fnc: callback to check if this timing is OK. May be NULL.
+ * @fnc_handle: a handle that is passed on to @fnc.
+ *
+ * Returns true if the given dv_timings struct is supported by the
+ * hardware capabilities and the callback function (if non-NULL), returns
+ * false otherwise.
+ */
+bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+			   const struct v4l2_dv_timings_cap *cap,
+			   v4l2_check_dv_timings_fnc fnc,
+			   void *fnc_handle);
+
+/**
+ * v4l2_enum_dv_timings_cap() - Helper function to enumerate possible DV
+ *	 timings based on capabilities
+ *
+ * @t:	  the v4l2_enum_dv_timings struct.
+ * @cap: the v4l2_dv_timings_cap capabilities.
+ * @fnc: callback to check if this timing is OK. May be NULL.
+ * @fnc_handle: a handle that is passed on to @fnc.
+ *
+ * This enumerates dv_timings using the full list of possible CEA-861 and DMT
+ * timings, filtering out any timings that are not supported based on the
+ * hardware capabilities and the callback function (if non-NULL).
+ *
+ * If a valid timing for the given index is found, it will fill in @t and
+ * return 0, otherwise it returns -EINVAL.
+ */
+int v4l2_enum_dv_timings_cap(struct v4l2_enum_dv_timings *t,
+			     const struct v4l2_dv_timings_cap *cap,
+			     v4l2_check_dv_timings_fnc fnc,
+			     void *fnc_handle);
+
+/**
+ * v4l2_find_dv_timings_cap() - Find the closest timings struct
+ *
+ * @t:	  the v4l2_enum_dv_timings struct.
+ * @cap: the v4l2_dv_timings_cap capabilities.
+ * @pclock_delta: maximum delta between t->pixelclock and the timing struct
+ *		under consideration.
+ * @fnc: callback to check if a given timings struct is OK. May be NULL.
+ * @fnc_handle: a handle that is passed on to @fnc.
+ *
+ * This function tries to map the given timings to an entry in the
+ * full list of possible CEA-861 and DMT timings, filtering out any timings
+ * that are not supported based on the hardware capabilities and the callback
+ * function (if non-NULL).
+ *
+ * On success it will fill in @t with the found timings and it returns true.
+ * On failure it will return false.
+ */
+bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t,
+			      const struct v4l2_dv_timings_cap *cap,
+			      unsigned pclock_delta,
+			      v4l2_check_dv_timings_fnc fnc,
+			      void *fnc_handle);
+
+/**
+ * v4l2_find_dv_timings_cea861_vic() - find timings based on CEA-861 VIC
+ * @t:		the timings data.
+ * @vic:	CEA-861 VIC code
+ *
+ * On success it will fill in @t with the found timings and it returns true.
+ * On failure it will return false.
+ */
+bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic);
+
+/**
+ * v4l2_match_dv_timings() - do two timings match?
+ *
+ * @measured:	  the measured timings data.
+ * @standard:	  the timings according to the standard.
+ * @pclock_delta: maximum delta in Hz between standard->pixelclock and
+ *		the measured timings.
+ * @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
+ * match.
+ *
+ * Returns true if the two timings match, returns false otherwise.
+ */
+bool v4l2_match_dv_timings(const struct v4l2_dv_timings *measured,
+			   const struct v4l2_dv_timings *standard,
+			   unsigned pclock_delta, bool match_reduced_fps);
+
+/**
+ * v4l2_print_dv_timings() - log the contents of a dv_timings struct
+ * @dev_prefix:device prefix for each log line.
+ * @prefix:	additional prefix for each log line, may be NULL.
+ * @t:		the timings data.
+ * @detailed:	if true, give a detailed log.
+ */
+void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
+			   const struct v4l2_dv_timings *t, bool detailed);
+
+/**
+ * v4l2_detect_cvt - detect if the given timings follow the CVT standard
+ *
+ * @frame_height: the total height of the frame (including blanking) in lines.
+ * @hfreq: the horizontal frequency in Hz.
+ * @vsync: the height of the vertical sync in lines.
+ * @active_width: active width of image (does not include blanking). This
+ * information is needed only in case of version 2 of reduced blanking.
+ * In other cases, this parameter does not have any effect on timings.
+ * @polarities: the horizontal and vertical polarities (same as struct
+ *		v4l2_bt_timings polarities).
+ * @interlaced: if this flag is true, it indicates interlaced format
+ * @fmt: the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid CVT format. If so, then it will return true, and fmt will be filled
+ * in with the found CVT timings.
+ */
+bool v4l2_detect_cvt(unsigned frame_height, unsigned hfreq, unsigned vsync,
+		unsigned active_width, u32 polarities, bool interlaced,
+		struct v4l2_dv_timings *fmt);
+
+/**
+ * v4l2_detect_gtf - detect if the given timings follow the GTF standard
+ *
+ * @frame_height: the total height of the frame (including blanking) in lines.
+ * @hfreq: the horizontal frequency in Hz.
+ * @vsync: the height of the vertical sync in lines.
+ * @polarities: the horizontal and vertical polarities (same as struct
+ *		v4l2_bt_timings polarities).
+ * @interlaced: if this flag is true, it indicates interlaced format
+ * @aspect: preferred aspect ratio. GTF has no method of determining the
+ *		aspect ratio in order to derive the image width from the
+ *		image height, so it has to be passed explicitly. Usually
+ *		the native screen aspect ratio is used for this. If it
+ *		is not filled in correctly, then 16:9 will be assumed.
+ * @fmt: the resulting timings.
+ *
+ * This function will attempt to detect if the given values correspond to a
+ * valid GTF format. If so, then it will return true, and fmt will be filled
+ * in with the found GTF timings.
+ */
+bool v4l2_detect_gtf(unsigned frame_height, unsigned hfreq, unsigned vsync,
+		u32 polarities, bool interlaced, struct v4l2_fract aspect,
+		struct v4l2_dv_timings *fmt);
+
+/**
+ * v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
+ *	0x15 and 0x16 from the EDID.
+ *
+ * @hor_landscape: byte 0x15 from the EDID.
+ * @vert_portrait: byte 0x16 from the EDID.
+ *
+ * Determines the aspect ratio from the EDID.
+ * See VESA Enhanced EDID standard, release A, rev 2, section 3.6.2:
+ * "Horizontal and Vertical Screen Size or Aspect Ratio"
+ */
+struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
+
+/**
+ * v4l2_dv_timings_aspect_ratio - calculate the aspect ratio based on the
+ *	v4l2_dv_timings information.
+ *
+ * @t: the timings data.
+ */
+struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t);
+
+/**
+ * can_reduce_fps - check if conditions for reduced fps are true.
+ * @bt: v4l2 timing structure
+ *
+ * For different timings reduced fps is allowed if the following conditions
+ * are met:
+ *
+ *   - For CVT timings: if reduced blanking v2 (vsync == 8) is true.
+ *   - For CEA861 timings: if %V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
+ */
+static inline  bool can_reduce_fps(struct v4l2_bt_timings *bt)
+{
+	if ((bt->standards & V4L2_DV_BT_STD_CVT) && (bt->vsync == 8))
+		return true;
+
+	if ((bt->standards & V4L2_DV_BT_STD_CEA861) &&
+	    (bt->flags & V4L2_DV_FL_CAN_REDUCE_FPS))
+		return true;
+
+	return false;
+}
+
+/**
+ * struct v4l2_hdmi_rx_colorimetry - describes the HDMI colorimetry information
+ * @colorspace:		enum v4l2_colorspace, the colorspace
+ * @ycbcr_enc:		enum v4l2_ycbcr_encoding, Y'CbCr encoding
+ * @quantization:	enum v4l2_quantization, colorspace quantization
+ * @xfer_func:		enum v4l2_xfer_func, colorspace transfer function
+ */
+struct v4l2_hdmi_colorimetry {
+	enum v4l2_colorspace colorspace;
+	enum v4l2_ycbcr_encoding ycbcr_enc;
+	enum v4l2_quantization quantization;
+	enum v4l2_xfer_func xfer_func;
+};
+
+struct hdmi_avi_infoframe;
+struct hdmi_vendor_infoframe;
+
+struct v4l2_hdmi_colorimetry
+v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
+			 const struct hdmi_vendor_infoframe *hdmi,
+			 unsigned int height);
+
+#endif
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
new file mode 100644
index 0000000..17833e8
--- /dev/null
+++ b/include/media/v4l2-event.h
@@ -0,0 +1,205 @@
+/*
+ * v4l2-event.h
+ *
+ * V4L2 events.
+ *
+ * Copyright (C) 2009--2010 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef V4L2_EVENT_H
+#define V4L2_EVENT_H
+
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/wait.h>
+
+struct v4l2_fh;
+struct v4l2_subdev;
+struct v4l2_subscribed_event;
+struct video_device;
+
+/**
+ * struct v4l2_kevent - Internal kernel event struct.
+ * @list:	List node for the v4l2_fh->available list.
+ * @sev:	Pointer to parent v4l2_subscribed_event.
+ * @event:	The event itself.
+ */
+struct v4l2_kevent {
+	struct list_head	list;
+	struct v4l2_subscribed_event *sev;
+	struct v4l2_event	event;
+};
+
+/**
+ * struct v4l2_subscribed_event_ops - Subscribed event operations.
+ *
+ * @add:	Optional callback, called when a new listener is added
+ * @del:	Optional callback, called when a listener stops listening
+ * @replace:	Optional callback that can replace event 'old' with event 'new'.
+ * @merge:	Optional callback that can merge event 'old' into event 'new'.
+ */
+struct v4l2_subscribed_event_ops {
+	int  (*add)(struct v4l2_subscribed_event *sev, unsigned int elems);
+	void (*del)(struct v4l2_subscribed_event *sev);
+	void (*replace)(struct v4l2_event *old, const struct v4l2_event *new);
+	void (*merge)(const struct v4l2_event *old, struct v4l2_event *new);
+};
+
+/**
+ * struct v4l2_subscribed_event - Internal struct representing a subscribed
+ *		event.
+ *
+ * @list:	List node for the v4l2_fh->subscribed list.
+ * @type:	Event type.
+ * @id:	Associated object ID (e.g. control ID). 0 if there isn't any.
+ * @flags:	Copy of v4l2_event_subscription->flags.
+ * @fh:	Filehandle that subscribed to this event.
+ * @node:	List node that hooks into the object's event list
+ *		(if there is one).
+ * @ops:	v4l2_subscribed_event_ops
+ * @elems:	The number of elements in the events array.
+ * @first:	The index of the events containing the oldest available event.
+ * @in_use:	The number of queued events.
+ * @events:	An array of @elems events.
+ */
+struct v4l2_subscribed_event {
+	struct list_head	list;
+	u32			type;
+	u32			id;
+	u32			flags;
+	struct v4l2_fh		*fh;
+	struct list_head	node;
+	const struct v4l2_subscribed_event_ops *ops;
+	unsigned int		elems;
+	unsigned int		first;
+	unsigned int		in_use;
+	struct v4l2_kevent	events[];
+};
+
+/**
+ * v4l2_event_dequeue - Dequeue events from video device.
+ *
+ * @fh: pointer to struct v4l2_fh
+ * @event: pointer to struct v4l2_event
+ * @nonblocking: if not zero, waits for an event to arrive
+ */
+int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
+		       int nonblocking);
+
+/**
+ * v4l2_event_queue - Queue events to video device.
+ *
+ * @vdev: pointer to &struct video_device
+ * @ev: pointer to &struct v4l2_event
+ *
+ * The event will be queued for all &struct v4l2_fh file handlers.
+ *
+ * .. note::
+ *    The driver's only responsibility is to fill in the type and the data
+ *    fields.The other fields will be filled in by  V4L2.
+ */
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
+
+/**
+ * v4l2_event_queue_fh - Queue events to video device.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @ev: pointer to &struct v4l2_event
+ *
+ *
+ * The event will be queued only for the specified &struct v4l2_fh file handler.
+ *
+ * .. note::
+ *    The driver's only responsibility is to fill in the type and the data
+ *    fields.The other fields will be filled in by  V4L2.
+ */
+void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev);
+
+/**
+ * v4l2_event_pending - Check if an event is available
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * Returns the number of pending events.
+ */
+int v4l2_event_pending(struct v4l2_fh *fh);
+
+/**
+ * v4l2_event_subscribe - Subscribes to an event
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ * @elems: size of the events queue
+ * @ops: pointer to &v4l2_subscribed_event_ops
+ *
+ * .. note::
+ *
+ *    if @elems is zero, the framework will fill in a default value,
+ *    with is currently 1 element.
+ */
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+			 const struct v4l2_event_subscription *sub,
+			 unsigned int elems,
+			 const struct v4l2_subscribed_event_ops *ops);
+/**
+ * v4l2_event_unsubscribe - Unsubscribes to an event
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+			   const struct v4l2_event_subscription *sub);
+/**
+ * v4l2_event_unsubscribe_all - Unsubscribes to all events
+ *
+ * @fh: pointer to &struct v4l2_fh
+ */
+void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
+
+/**
+ * v4l2_event_subdev_unsubscribe - Subdev variant of v4l2_event_unsubscribe()
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ *
+ * .. note::
+ *
+ *	This function should be used for the &struct v4l2_subdev_core_ops
+ *	%unsubscribe_event field.
+ */
+int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd,
+				  struct v4l2_fh *fh,
+				  struct v4l2_event_subscription *sub);
+/**
+ * v4l2_src_change_event_subscribe - helper function that calls
+ *	v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE.
+ *
+ * @fh: pointer to struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
+int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
+				    const struct v4l2_event_subscription *sub);
+/**
+ * v4l2_src_change_event_subdev_subscribe - Variant of v4l2_event_subscribe(),
+ *	meant to subscribe only events of the type %V4L2_EVENT_SOURCE_CHANGE.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
+int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
+					   struct v4l2_fh *fh,
+					   struct v4l2_event_subscription *sub);
+#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
new file mode 100644
index 0000000..8586cfb
--- /dev/null
+++ b/include/media/v4l2-fh.h
@@ -0,0 +1,171 @@
+/*
+ * v4l2-fh.h
+ *
+ * V4L2 file handle. Store per file handle data for the V4L2
+ * framework. Using file handles is optional for the drivers.
+ *
+ * Copyright (C) 2009--2010 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef V4L2_FH_H
+#define V4L2_FH_H
+
+#include <linux/fs.h>
+#include <linux/kconfig.h>
+#include <linux/list.h>
+#include <linux/videodev2.h>
+
+struct video_device;
+struct v4l2_ctrl_handler;
+
+/**
+ * struct v4l2_fh - Describes a V4L2 file handler
+ *
+ * @list: list of file handlers
+ * @vdev: pointer to &struct video_device
+ * @ctrl_handler: pointer to &struct v4l2_ctrl_handler
+ * @prio: priority of the file handler, as defined by &enum v4l2_priority
+ *
+ * @wait: event' s wait queue
+ * @subscribe_lock: serialise changes to the subscribed list; guarantee that
+ *		    the add and del event callbacks are orderly called
+ * @subscribed: list of subscribed events
+ * @available: list of events waiting to be dequeued
+ * @navailable: number of available events at @available list
+ * @sequence: event sequence number
+ *
+ * @m2m_ctx: pointer to &struct v4l2_m2m_ctx
+ */
+struct v4l2_fh {
+	struct list_head	list;
+	struct video_device	*vdev;
+	struct v4l2_ctrl_handler *ctrl_handler;
+	enum v4l2_priority	prio;
+
+	/* Events */
+	wait_queue_head_t	wait;
+	struct mutex		subscribe_lock;
+	struct list_head	subscribed;
+	struct list_head	available;
+	unsigned int		navailable;
+	u32			sequence;
+
+#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
+	struct v4l2_m2m_ctx	*m2m_ctx;
+#endif
+};
+
+/**
+ * v4l2_fh_init - Initialise the file handle.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @vdev: pointer to &struct video_device
+ *
+ * Parts of the V4L2 framework using the
+ * file handles should be initialised in this function. Must be called
+ * from driver's v4l2_file_operations->open\(\) handler if the driver
+ * uses &struct v4l2_fh.
+ */
+void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev);
+
+/**
+ * v4l2_fh_add - Add the fh to the list of file handles on a video_device.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * .. note::
+ *    The @fh file handle must be initialised first.
+ */
+void v4l2_fh_add(struct v4l2_fh *fh);
+
+/**
+ * v4l2_fh_open - Ancillary routine that can be used as the open\(\) op
+ *	of v4l2_file_operations.
+ *
+ * @filp: pointer to struct file
+ *
+ * It allocates a v4l2_fh and inits and adds it to the &struct video_device
+ * associated with the file pointer.
+ */
+int v4l2_fh_open(struct file *filp);
+
+/**
+ * v4l2_fh_del - Remove file handle from the list of file handles.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * On error filp->private_data will be %NULL, otherwise it will point to
+ * the &struct v4l2_fh.
+ *
+ * .. note::
+ *    Must be called in v4l2_file_operations->release\(\) handler if the driver
+ *    uses &struct v4l2_fh.
+ */
+void v4l2_fh_del(struct v4l2_fh *fh);
+
+/**
+ * v4l2_fh_exit - Release resources related to a file handle.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * Parts of the V4L2 framework using the v4l2_fh must release their
+ * resources here, too.
+ *
+ * .. note::
+ *    Must be called in v4l2_file_operations->release\(\) handler if the
+ *    driver uses &struct v4l2_fh.
+ */
+void v4l2_fh_exit(struct v4l2_fh *fh);
+
+/**
+ * v4l2_fh_release - Ancillary routine that can be used as the release\(\) op
+ *	of v4l2_file_operations.
+ *
+ * @filp: pointer to struct file
+ *
+ * It deletes and exits the v4l2_fh associated with the file pointer and
+ * frees it. It will do nothing if filp->private_data (the pointer to the
+ * v4l2_fh struct) is %NULL.
+ *
+ * This function always returns 0.
+ */
+int v4l2_fh_release(struct file *filp);
+
+/**
+ * v4l2_fh_is_singular - Returns 1 if this filehandle is the only filehandle
+ *	 opened for the associated video_device.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * If @fh is NULL, then it returns 0.
+ */
+int v4l2_fh_is_singular(struct v4l2_fh *fh);
+
+/**
+ * v4l2_fh_is_singular_file - Returns 1 if this filehandle is the only
+ *	filehandle opened for the associated video_device.
+ *
+ * @filp: pointer to struct file
+ *
+ * This is a helper function variant of v4l2_fh_is_singular() with uses
+ * struct file as argument.
+ *
+ * If filp->private_data is %NULL, then it will return 0.
+ */
+static inline int v4l2_fh_is_singular_file(struct file *filp)
+{
+	return v4l2_fh_is_singular(filp->private_data);
+}
+
+#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h
new file mode 100644
index 0000000..0a5e451
--- /dev/null
+++ b/include/media/v4l2-flash-led-class.h
@@ -0,0 +1,189 @@
+/*
+ * V4L2 flash LED sub-device registration helpers.
+ *
+ *	Copyright (C) 2015 Samsung Electronics Co., Ltd
+ *	Author: Jacek Anaszewski <j.anaszewski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _V4L2_FLASH_H
+#define _V4L2_FLASH_H
+
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+
+struct led_classdev_flash;
+struct led_classdev;
+struct v4l2_flash;
+enum led_brightness;
+
+/**
+ * struct v4l2_flash_ctrl_data - flash control initialization data, filled
+ *				basing on the features declared by the LED flash
+ *				class driver in the v4l2_flash_config
+ * @config:	initialization data for a control
+ * @cid:	contains v4l2 flash control id if the config
+ *		field was initialized, 0 otherwise
+ */
+struct v4l2_flash_ctrl_data {
+	struct v4l2_ctrl_config config;
+	u32 cid;
+};
+
+/**
+ * struct v4l2_flash_ops - V4L2 flash operations
+ *
+ * @external_strobe_set: Setup strobing the flash by hardware pin state
+ *	assertion.
+ * @intensity_to_led_brightness: Convert intensity to brightness in a device
+ *	specific manner
+ * @led_brightness_to_intensity: convert brightness to intensity in a device
+ *	specific manner.
+ */
+struct v4l2_flash_ops {
+	int (*external_strobe_set)(struct v4l2_flash *v4l2_flash,
+					bool enable);
+	enum led_brightness (*intensity_to_led_brightness)
+		(struct v4l2_flash *v4l2_flash, s32 intensity);
+	s32 (*led_brightness_to_intensity)
+		(struct v4l2_flash *v4l2_flash, enum led_brightness);
+};
+
+/**
+ * struct v4l2_flash_config - V4L2 Flash sub-device initialization data
+ * @dev_name:			the name of the media entity,
+ *				unique in the system
+ * @intensity:			non-flash strobe constraints for the LED
+ * @flash_faults:		bitmask of flash faults that the LED flash class
+ *				device can report; corresponding LED_FAULT* bit
+ *				definitions are available in the header file
+ *				<linux/led-class-flash.h>
+ * @has_external_strobe:	external strobe capability
+ */
+struct v4l2_flash_config {
+	char dev_name[32];
+	struct led_flash_setting intensity;
+	u32 flash_faults;
+	unsigned int has_external_strobe:1;
+};
+
+/**
+ * struct v4l2_flash - Flash sub-device context
+ * @fled_cdev:		LED flash class device controlled by this sub-device
+ * @iled_cdev:		LED class device representing indicator LED associated
+ *			with the LED flash class device
+ * @ops:		V4L2 specific flash ops
+ * @sd:			V4L2 sub-device
+ * @hdl:		flash controls handler
+ * @ctrls:		array of pointers to controls, whose values define
+ *			the sub-device state
+ */
+struct v4l2_flash {
+	struct led_classdev_flash *fled_cdev;
+	struct led_classdev *iled_cdev;
+	const struct v4l2_flash_ops *ops;
+
+	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
+	struct v4l2_ctrl **ctrls;
+};
+
+/**
+ * v4l2_subdev_to_v4l2_flash - Returns a &struct v4l2_flash from the
+ * &struct v4l2_subdev embedded on it.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
+static inline struct v4l2_flash *v4l2_subdev_to_v4l2_flash(
+							struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct v4l2_flash, sd);
+}
+
+/**
+ * v4l2_ctrl_to_v4l2_flash - Returns a &struct v4l2_flash from the
+ * &struct v4l2_ctrl embedded on it.
+ *
+ * @c: pointer to &struct v4l2_ctrl
+ */
+static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
+{
+	return container_of(c->handler, struct v4l2_flash, hdl);
+}
+
+#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
+/**
+ * v4l2_flash_init - initialize V4L2 flash led sub-device
+ * @dev:	flash device, e.g. an I2C device
+ * @fwn:	fwnode_handle of the LED, may be NULL if the same as device's
+ * @fled_cdev:	LED flash class device to wrap
+ * @ops:	V4L2 Flash device ops
+ * @config:	initialization data for V4L2 Flash sub-device
+ *
+ * Create V4L2 Flash sub-device wrapping given LED subsystem device.
+ * The ops pointer is stored by the V4L2 flash framework. No
+ * references are held to config nor its contents once this function
+ * has returned.
+ *
+ * Returns: A valid pointer, or, when an error occurs, the return
+ * value is encoded using ERR_PTR(). Use IS_ERR() to check and
+ * PTR_ERR() to obtain the numeric return value.
+ */
+struct v4l2_flash *v4l2_flash_init(
+	struct device *dev, struct fwnode_handle *fwn,
+	struct led_classdev_flash *fled_cdev,
+	const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config);
+
+/**
+ * v4l2_flash_indicator_init - initialize V4L2 indicator sub-device
+ * @dev:	flash device, e.g. an I2C device
+ * @fwn:	fwnode_handle of the LED, may be NULL if the same as device's
+ * @iled_cdev:	LED flash class device representing the indicator LED
+ * @config:	initialization data for V4L2 Flash sub-device
+ *
+ * Create V4L2 Flash sub-device wrapping given LED subsystem device.
+ * The ops pointer is stored by the V4L2 flash framework. No
+ * references are held to config nor its contents once this function
+ * has returned.
+ *
+ * Returns: A valid pointer, or, when an error occurs, the return
+ * value is encoded using ERR_PTR(). Use IS_ERR() to check and
+ * PTR_ERR() to obtain the numeric return value.
+ */
+struct v4l2_flash *v4l2_flash_indicator_init(
+	struct device *dev, struct fwnode_handle *fwn,
+	struct led_classdev *iled_cdev, struct v4l2_flash_config *config);
+
+/**
+ * v4l2_flash_release - release V4L2 Flash sub-device
+ * @v4l2_flash: the V4L2 Flash sub-device to release
+ *
+ * Release V4L2 Flash sub-device.
+ */
+void v4l2_flash_release(struct v4l2_flash *v4l2_flash);
+
+#else
+static inline struct v4l2_flash *v4l2_flash_init(
+	struct device *dev, struct fwnode_handle *fwn,
+	struct led_classdev_flash *fled_cdev,
+	const struct v4l2_flash_ops *ops, struct v4l2_flash_config *config)
+{
+	return NULL;
+}
+
+static inline struct v4l2_flash *v4l2_flash_indicator_init(
+	struct device *dev, struct fwnode_handle *fwn,
+	struct led_classdev *iled_cdev, struct v4l2_flash_config *config)
+{
+	return NULL;
+}
+
+static inline void v4l2_flash_release(struct v4l2_flash *v4l2_flash)
+{
+}
+#endif /* CONFIG_V4L2_FLASH_LED_CLASS */
+
+#endif /* _V4L2_FLASH_H */
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
new file mode 100644
index 0000000..9cccab6
--- /dev/null
+++ b/include/media/v4l2-fwnode.h
@@ -0,0 +1,361 @@
+/*
+ * V4L2 fwnode binding parsing library
+ *
+ * Copyright (c) 2016 Intel Corporation.
+ * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
+ *
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Copyright (C) 2012 Renesas Electronics Corp.
+ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+#ifndef _V4L2_FWNODE_H
+#define _V4L2_FWNODE_H
+
+#include <linux/errno.h>
+#include <linux/fwnode.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+#include <media/v4l2-mediabus.h>
+
+struct fwnode_handle;
+struct v4l2_async_notifier;
+struct v4l2_async_subdev;
+
+#define V4L2_FWNODE_CSI2_MAX_DATA_LANES	4
+
+/**
+ * struct v4l2_fwnode_bus_mipi_csi2 - MIPI CSI-2 bus data structure
+ * @flags: media bus (V4L2_MBUS_*) flags
+ * @data_lanes: an array of physical data lane indexes
+ * @clock_lane: physical lane index of the clock lane
+ * @num_data_lanes: number of data lanes
+ * @lane_polarities: polarity of the lanes. The order is the same of
+ *		   the physical lanes.
+ */
+struct v4l2_fwnode_bus_mipi_csi2 {
+	unsigned int flags;
+	unsigned char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES];
+	unsigned char clock_lane;
+	unsigned short num_data_lanes;
+	bool lane_polarities[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES];
+};
+
+/**
+ * struct v4l2_fwnode_bus_parallel - parallel data bus data structure
+ * @flags: media bus (V4L2_MBUS_*) flags
+ * @bus_width: bus width in bits
+ * @data_shift: data shift in bits
+ */
+struct v4l2_fwnode_bus_parallel {
+	unsigned int flags;
+	unsigned char bus_width;
+	unsigned char data_shift;
+};
+
+/**
+ * struct v4l2_fwnode_bus_mipi_csi1 - CSI-1/CCP2 data bus structure
+ * @clock_inv: polarity of clock/strobe signal
+ *	       false - not inverted, true - inverted
+ * @strobe: false - data/clock, true - data/strobe
+ * @lane_polarity: the polarities of the clock (index 0) and data lanes
+ *		   index (1)
+ * @data_lane: the number of the data lane
+ * @clock_lane: the number of the clock lane
+ */
+struct v4l2_fwnode_bus_mipi_csi1 {
+	bool clock_inv;
+	bool strobe;
+	bool lane_polarity[2];
+	unsigned char data_lane;
+	unsigned char clock_lane;
+};
+
+/**
+ * struct v4l2_fwnode_endpoint - the endpoint data structure
+ * @base: fwnode endpoint of the v4l2_fwnode
+ * @bus_type: bus type
+ * @bus: union with bus configuration data structure
+ * @bus.parallel: embedded &struct v4l2_fwnode_bus_parallel.
+ *		  Used if the bus is parallel.
+ * @bus.mipi_csi1: embedded &struct v4l2_fwnode_bus_mipi_csi1.
+ *		   Used if the bus is MIPI Alliance's Camera Serial
+ *		   Interface version 1 (MIPI CSI1) or Standard
+ *		   Mobile Imaging Architecture's Compact Camera Port 2
+ *		   (SMIA CCP2).
+ * @bus.mipi_csi2: embedded &struct v4l2_fwnode_bus_mipi_csi2.
+ *		   Used if the bus is MIPI Alliance's Camera Serial
+ *		   Interface version 2 (MIPI CSI2).
+ * @link_frequencies: array of supported link frequencies
+ * @nr_of_link_frequencies: number of elements in link_frequenccies array
+ */
+struct v4l2_fwnode_endpoint {
+	struct fwnode_endpoint base;
+	/*
+	 * Fields below this line will be zeroed by
+	 * v4l2_fwnode_endpoint_parse()
+	 */
+	enum v4l2_mbus_type bus_type;
+	union {
+		struct v4l2_fwnode_bus_parallel parallel;
+		struct v4l2_fwnode_bus_mipi_csi1 mipi_csi1;
+		struct v4l2_fwnode_bus_mipi_csi2 mipi_csi2;
+	} bus;
+	u64 *link_frequencies;
+	unsigned int nr_of_link_frequencies;
+};
+
+/**
+ * struct v4l2_fwnode_link - a link between two endpoints
+ * @local_node: pointer to device_node of this endpoint
+ * @local_port: identifier of the port this endpoint belongs to
+ * @remote_node: pointer to device_node of the remote endpoint
+ * @remote_port: identifier of the port the remote endpoint belongs to
+ */
+struct v4l2_fwnode_link {
+	struct fwnode_handle *local_node;
+	unsigned int local_port;
+	struct fwnode_handle *remote_node;
+	unsigned int remote_port;
+};
+
+/**
+ * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
+ * @fwnode: pointer to the endpoint's fwnode handle
+ * @vep: pointer to the V4L2 fwnode data structure
+ *
+ * All properties are optional. If none are found, we don't set any flags. This
+ * means the port has a static configuration and no properties have to be
+ * specified explicitly. If any properties that identify the bus as parallel
+ * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
+ * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
+ * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
+ * reference to @fwnode.
+ *
+ * NOTE: This function does not parse properties the size of which is variable
+ * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in
+ * new drivers instead.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode,
+			       struct v4l2_fwnode_endpoint *vep);
+
+/**
+ * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by
+ * v4l2_fwnode_endpoint_alloc_parse()
+ * @vep: the V4L2 fwnode the resources of which are to be released
+ *
+ * It is safe to call this function with NULL argument or on a V4L2 fwnode the
+ * parsing of which failed.
+ */
+void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep);
+
+/**
+ * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties
+ * @fwnode: pointer to the endpoint's fwnode handle
+ *
+ * All properties are optional. If none are found, we don't set any flags. This
+ * means the port has a static configuration and no properties have to be
+ * specified explicitly. If any properties that identify the bus as parallel
+ * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if
+ * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we
+ * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a
+ * reference to @fwnode.
+ *
+ * v4l2_fwnode_endpoint_alloc_parse() has two important differences to
+ * v4l2_fwnode_endpoint_parse():
+ *
+ * 1. It also parses variable size data.
+ *
+ * 2. The memory it has allocated to store the variable size data must be freed
+ *    using v4l2_fwnode_endpoint_free() when no longer needed.
+ *
+ * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer
+ * on error.
+ */
+struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse(
+	struct fwnode_handle *fwnode);
+
+/**
+ * v4l2_fwnode_parse_link() - parse a link between two endpoints
+ * @fwnode: pointer to the endpoint's fwnode at the local end of the link
+ * @link: pointer to the V4L2 fwnode link data structure
+ *
+ * Fill the link structure with the local and remote nodes and port numbers.
+ * The local_node and remote_node fields are set to point to the local and
+ * remote port's parent nodes respectively (the port parent node being the
+ * parent node of the port node if that node isn't a 'ports' node, or the
+ * grand-parent node of the port node otherwise).
+ *
+ * A reference is taken to both the local and remote nodes, the caller must use
+ * v4l2_fwnode_put_link() to drop the references when done with the
+ * link.
+ *
+ * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be
+ * found.
+ */
+int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
+			   struct v4l2_fwnode_link *link);
+
+/**
+ * v4l2_fwnode_put_link() - drop references to nodes in a link
+ * @link: pointer to the V4L2 fwnode link data structure
+ *
+ * Drop references to the local and remote nodes in the link. This function
+ * must be called on every link parsed with v4l2_fwnode_parse_link().
+ */
+void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
+
+
+/**
+ * typedef parse_endpoint_func - Driver's callback function to be called on
+ *	each V4L2 fwnode endpoint.
+ *
+ * @dev: pointer to &struct device
+ * @vep: pointer to &struct v4l2_fwnode_endpoint
+ * @asd: pointer to &struct v4l2_async_subdev
+ *
+ * Return:
+ * * %0 on success
+ * * %-ENOTCONN if the endpoint is to be skipped but this
+ *   should not be considered as an error
+ * * %-EINVAL if the endpoint configuration is invalid
+ */
+typedef int (*parse_endpoint_func)(struct device *dev,
+				  struct v4l2_fwnode_endpoint *vep,
+				  struct v4l2_async_subdev *asd);
+
+
+/**
+ * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a
+ *						device node
+ * @dev: the device the endpoints of which are to be parsed
+ * @notifier: notifier for @dev
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *		     sizeof(struct v4l2_async_subdev). The &struct
+ *		     v4l2_async_subdev shall be the first member of
+ *		     the driver's async sub-device struct, i.e. both
+ *		     begin at the same memory address.
+ * @parse_endpoint: Driver's callback function called on each V4L2 fwnode
+ *		    endpoint. Optional.
+ *
+ * Parse the fwnode endpoints of the @dev device and populate the async sub-
+ * devices array of the notifier. The @parse_endpoint callback function is
+ * called for each endpoint with the corresponding async sub-device pointer to
+ * let the caller initialize the driver-specific part of the async sub-device
+ * structure.
+ *
+ * The notifier memory shall be zeroed before this function is called on the
+ * notifier.
+ *
+ * This function may not be called on a registered notifier and may be called on
+ * a notifier only once.
+ *
+ * Do not change the notifier's subdevs array, take references to the subdevs
+ * array itself or change the notifier's num_subdevs field. This is because this
+ * function allocates and reallocates the subdevs array based on parsing
+ * endpoints.
+ *
+ * The &struct v4l2_fwnode_endpoint passed to the callback function
+ * @parse_endpoint is released once the function is finished. If there is a need
+ * to retain that configuration, the user needs to allocate memory for it.
+ *
+ * Any notifier populated using this function must be released with a call to
+ * v4l2_async_notifier_cleanup() after it has been unregistered and the async
+ * sub-devices are no longer in use, even if the function returned an error.
+ *
+ * Return: %0 on success, including when no async sub-devices are found
+ *	   %-ENOMEM if memory allocation failed
+ *	   %-EINVAL if graph or endpoint parsing failed
+ *	   Other error codes as returned by @parse_endpoint
+ */
+int v4l2_async_notifier_parse_fwnode_endpoints(
+	struct device *dev, struct v4l2_async_notifier *notifier,
+	size_t asd_struct_size,
+	parse_endpoint_func parse_endpoint);
+
+/**
+ * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode
+ *							endpoints of a port in a
+ *							device node
+ * @dev: the device the endpoints of which are to be parsed
+ * @notifier: notifier for @dev
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *		     sizeof(struct v4l2_async_subdev). The &struct
+ *		     v4l2_async_subdev shall be the first member of
+ *		     the driver's async sub-device struct, i.e. both
+ *		     begin at the same memory address.
+ * @port: port number where endpoints are to be parsed
+ * @parse_endpoint: Driver's callback function called on each V4L2 fwnode
+ *		    endpoint. Optional.
+ *
+ * This function is just like v4l2_async_notifier_parse_fwnode_endpoints() with
+ * the exception that it only parses endpoints in a given port. This is useful
+ * on devices that have both sinks and sources: the async sub-devices connected
+ * to sources have already been configured by another driver (on capture
+ * devices). In this case the driver must know which ports to parse.
+ *
+ * Parse the fwnode endpoints of the @dev device on a given @port and populate
+ * the async sub-devices array of the notifier. The @parse_endpoint callback
+ * function is called for each endpoint with the corresponding async sub-device
+ * pointer to let the caller initialize the driver-specific part of the async
+ * sub-device structure.
+ *
+ * The notifier memory shall be zeroed before this function is called on the
+ * notifier the first time.
+ *
+ * This function may not be called on a registered notifier and may be called on
+ * a notifier only once per port.
+ *
+ * Do not change the notifier's subdevs array, take references to the subdevs
+ * array itself or change the notifier's num_subdevs field. This is because this
+ * function allocates and reallocates the subdevs array based on parsing
+ * endpoints.
+ *
+ * The &struct v4l2_fwnode_endpoint passed to the callback function
+ * @parse_endpoint is released once the function is finished. If there is a need
+ * to retain that configuration, the user needs to allocate memory for it.
+ *
+ * Any notifier populated using this function must be released with a call to
+ * v4l2_async_notifier_cleanup() after it has been unregistered and the async
+ * sub-devices are no longer in use, even if the function returned an error.
+ *
+ * Return: %0 on success, including when no async sub-devices are found
+ *	   %-ENOMEM if memory allocation failed
+ *	   %-EINVAL if graph or endpoint parsing failed
+ *	   Other error codes as returned by @parse_endpoint
+ */
+int v4l2_async_notifier_parse_fwnode_endpoints_by_port(
+	struct device *dev, struct v4l2_async_notifier *notifier,
+	size_t asd_struct_size, unsigned int port,
+	parse_endpoint_func parse_endpoint);
+
+/**
+ * v4l2_fwnode_reference_parse_sensor_common - parse common references on
+ *					       sensors for async sub-devices
+ * @dev: the device node the properties of which are parsed for references
+ * @notifier: the async notifier where the async subdevs will be added
+ *
+ * Parse common sensor properties for remote devices related to the
+ * sensor and set up async sub-devices for them.
+ *
+ * Any notifier populated using this function must be released with a call to
+ * v4l2_async_notifier_release() after it has been unregistered and the async
+ * sub-devices are no longer in use, even in the case the function returned an
+ * error.
+ *
+ * Return: 0 on success
+ *	   -ENOMEM if memory allocation failed
+ *	   -EINVAL if property parsing failed
+ */
+int v4l2_async_notifier_parse_fwnode_sensor_common(
+	struct device *dev, struct v4l2_async_notifier *notifier);
+
+#endif /* _V4L2_FWNODE_H */
diff --git a/include/media/v4l2-image-sizes.h b/include/media/v4l2-image-sizes.h
new file mode 100644
index 0000000..a07d7a6
--- /dev/null
+++ b/include/media/v4l2-image-sizes.h
@@ -0,0 +1,43 @@
+/*
+ * Standard image size definitions
+ *
+ * Copyright (C) 2013, Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _IMAGE_SIZES_H
+#define _IMAGE_SIZES_H
+
+#define CIF_WIDTH	352
+#define CIF_HEIGHT	288
+
+#define QCIF_WIDTH	176
+#define QCIF_HEIGHT	144
+
+#define QQCIF_WIDTH	88
+#define QQCIF_HEIGHT	72
+
+#define QQVGA_WIDTH	160
+#define QQVGA_HEIGHT	120
+
+#define QVGA_WIDTH	320
+#define QVGA_HEIGHT	240
+
+#define SVGA_WIDTH	800
+#define SVGA_HEIGHT	600
+
+#define SXGA_WIDTH	1280
+#define SXGA_HEIGHT	1024
+
+#define VGA_WIDTH	640
+#define VGA_HEIGHT	480
+
+#define UXGA_WIDTH	1600
+#define UXGA_HEIGHT	1200
+
+#define XGA_WIDTH	1024
+#define XGA_HEIGHT	768
+
+#endif /* _IMAGE_SIZES_H */
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
new file mode 100644
index 0000000..5848d92
--- /dev/null
+++ b/include/media/v4l2-ioctl.h
@@ -0,0 +1,726 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *
+ *	V 4 L 2   D R I V E R   H E L P E R   A P I
+ *
+ * Moved from videodev2.h
+ *
+ *	Some commonly needed functions for drivers (v4l2-common.o module)
+ */
+#ifndef _V4L2_IOCTL_H
+#define _V4L2_IOCTL_H
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/mutex.h>
+#include <linux/sched/signal.h>
+#include <linux/compiler.h> /* need __user */
+#include <linux/videodev2.h>
+
+struct v4l2_fh;
+
+/**
+ * struct v4l2_ioctl_ops - describe operations for each V4L2 ioctl
+ *
+ * @vidioc_querycap: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERYCAP <vidioc_querycap>` ioctl
+ * @vidioc_enum_fmt_vid_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for video capture in single plane mode
+ * @vidioc_enum_fmt_vid_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for video overlay
+ * @vidioc_enum_fmt_vid_out: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for video output in single plane mode
+ * @vidioc_enum_fmt_vid_cap_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for video capture in multiplane mode
+ * @vidioc_enum_fmt_vid_out_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for video output in multiplane mode
+ * @vidioc_enum_fmt_sdr_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for Software Defined Radio capture
+ * @vidioc_enum_fmt_sdr_out: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for Software Defined Radio output
+ * @vidioc_enum_fmt_meta_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ *	for metadata capture
+ * @vidioc_g_fmt_vid_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ *	in single plane mode
+ * @vidioc_g_fmt_vid_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * @vidioc_g_fmt_vid_out: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video out
+ *	in single plane mode
+ * @vidioc_g_fmt_vid_out_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video overlay output
+ * @vidioc_g_fmt_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for raw VBI capture
+ * @vidioc_g_fmt_vbi_out: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for raw VBI output
+ * @vidioc_g_fmt_sliced_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI capture
+ * @vidioc_g_fmt_sliced_vbi_out: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI output
+ * @vidioc_g_fmt_vid_cap_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ *	in multiple plane mode
+ * @vidioc_g_fmt_vid_out_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video out
+ *	in multiplane plane mode
+ * @vidioc_g_fmt_sdr_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ *	Radio capture
+ * @vidioc_g_fmt_sdr_out: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ *	Radio output
+ * @vidioc_g_fmt_meta_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
+ * @vidioc_s_fmt_vid_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ *	in single plane mode
+ * @vidioc_s_fmt_vid_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * @vidioc_s_fmt_vid_out: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video out
+ *	in single plane mode
+ * @vidioc_s_fmt_vid_out_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video overlay output
+ * @vidioc_s_fmt_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for raw VBI capture
+ * @vidioc_s_fmt_vbi_out: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for raw VBI output
+ * @vidioc_s_fmt_sliced_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI capture
+ * @vidioc_s_fmt_sliced_vbi_out: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI output
+ * @vidioc_s_fmt_vid_cap_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ *	in multiple plane mode
+ * @vidioc_s_fmt_vid_out_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video out
+ *	in multiplane plane mode
+ * @vidioc_s_fmt_sdr_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ *	Radio capture
+ * @vidioc_s_fmt_sdr_out: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ *	Radio output
+ * @vidioc_s_fmt_meta_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
+ * @vidioc_try_fmt_vid_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ *	in single plane mode
+ * @vidioc_try_fmt_vid_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * @vidioc_try_fmt_vid_out: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video out
+ *	in single plane mode
+ * @vidioc_try_fmt_vid_out_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ *	output
+ * @vidioc_try_fmt_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for raw VBI capture
+ * @vidioc_try_fmt_vbi_out: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for raw VBI output
+ * @vidioc_try_fmt_sliced_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI
+ *	capture
+ * @vidioc_try_fmt_sliced_vbi_out: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI output
+ * @vidioc_try_fmt_vid_cap_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ *	in multiple plane mode
+ * @vidioc_try_fmt_vid_out_mplane: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video out
+ *	in multiplane plane mode
+ * @vidioc_try_fmt_sdr_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ *	Radio capture
+ * @vidioc_try_fmt_sdr_out: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ *	Radio output
+ * @vidioc_try_fmt_meta_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
+ * @vidioc_reqbufs: pointer to the function that implements
+ *	:ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl
+ * @vidioc_querybuf: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERYBUF <vidioc_querybuf>` ioctl
+ * @vidioc_qbuf: pointer to the function that implements
+ *	:ref:`VIDIOC_QBUF <vidioc_qbuf>` ioctl
+ * @vidioc_expbuf: pointer to the function that implements
+ *	:ref:`VIDIOC_EXPBUF <vidioc_expbuf>` ioctl
+ * @vidioc_dqbuf: pointer to the function that implements
+ *	:ref:`VIDIOC_DQBUF <vidioc_qbuf>` ioctl
+ * @vidioc_create_bufs: pointer to the function that implements
+ *	:ref:`VIDIOC_CREATE_BUFS <vidioc_create_bufs>` ioctl
+ * @vidioc_prepare_buf: pointer to the function that implements
+ *	:ref:`VIDIOC_PREPARE_BUF <vidioc_prepare_buf>` ioctl
+ * @vidioc_overlay: pointer to the function that implements
+ *	:ref:`VIDIOC_OVERLAY <vidioc_overlay>` ioctl
+ * @vidioc_g_fbuf: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FBUF <vidioc_g_fbuf>` ioctl
+ * @vidioc_s_fbuf: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FBUF <vidioc_g_fbuf>` ioctl
+ * @vidioc_streamon: pointer to the function that implements
+ *	:ref:`VIDIOC_STREAMON <vidioc_streamon>` ioctl
+ * @vidioc_streamoff: pointer to the function that implements
+ *	:ref:`VIDIOC_STREAMOFF <vidioc_streamon>` ioctl
+ * @vidioc_g_std: pointer to the function that implements
+ *	:ref:`VIDIOC_G_STD <vidioc_g_std>` ioctl
+ * @vidioc_s_std: pointer to the function that implements
+ *	:ref:`VIDIOC_S_STD <vidioc_g_std>` ioctl
+ * @vidioc_querystd: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERYSTD <vidioc_querystd>` ioctl
+ * @vidioc_enum_input: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_INPUT <vidioc_g_input>` ioctl
+ * @vidioc_g_input: pointer to the function that implements
+ *	:ref:`VIDIOC_G_INPUT <vidioc_g_input>` ioctl
+ * @vidioc_s_input: pointer to the function that implements
+ *	:ref:`VIDIOC_S_INPUT <vidioc_g_input>` ioctl
+ * @vidioc_enum_output: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_OUTPUT <vidioc_g_output>` ioctl
+ * @vidioc_g_output: pointer to the function that implements
+ *	:ref:`VIDIOC_G_OUTPUT <vidioc_g_output>` ioctl
+ * @vidioc_s_output: pointer to the function that implements
+ *	:ref:`VIDIOC_S_OUTPUT <vidioc_g_output>` ioctl
+ * @vidioc_queryctrl: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERYCTRL <vidioc_queryctrl>` ioctl
+ * @vidioc_query_ext_ctrl: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERY_EXT_CTRL <vidioc_queryctrl>` ioctl
+ * @vidioc_g_ctrl: pointer to the function that implements
+ *	:ref:`VIDIOC_G_CTRL <vidioc_g_ctrl>` ioctl
+ * @vidioc_s_ctrl: pointer to the function that implements
+ *	:ref:`VIDIOC_S_CTRL <vidioc_g_ctrl>` ioctl
+ * @vidioc_g_ext_ctrls: pointer to the function that implements
+ *	:ref:`VIDIOC_G_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ * @vidioc_s_ext_ctrls: pointer to the function that implements
+ *	:ref:`VIDIOC_S_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ * @vidioc_try_ext_ctrls: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ * @vidioc_querymenu: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERYMENU <vidioc_queryctrl>` ioctl
+ * @vidioc_enumaudio: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUMAUDIO <vidioc_enumaudio>` ioctl
+ * @vidioc_g_audio: pointer to the function that implements
+ *	:ref:`VIDIOC_G_AUDIO <vidioc_g_audio>` ioctl
+ * @vidioc_s_audio: pointer to the function that implements
+ *	:ref:`VIDIOC_S_AUDIO <vidioc_g_audio>` ioctl
+ * @vidioc_enumaudout: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUMAUDOUT <vidioc_enumaudout>` ioctl
+ * @vidioc_g_audout: pointer to the function that implements
+ *	:ref:`VIDIOC_G_AUDOUT <vidioc_g_audout>` ioctl
+ * @vidioc_s_audout: pointer to the function that implements
+ *	:ref:`VIDIOC_S_AUDOUT <vidioc_g_audout>` ioctl
+ * @vidioc_g_modulator: pointer to the function that implements
+ *	:ref:`VIDIOC_G_MODULATOR <vidioc_g_modulator>` ioctl
+ * @vidioc_s_modulator: pointer to the function that implements
+ *	:ref:`VIDIOC_S_MODULATOR <vidioc_g_modulator>` ioctl
+ * @vidioc_cropcap: pointer to the function that implements
+ *	:ref:`VIDIOC_CROPCAP <vidioc_cropcap>` ioctl
+ * @vidioc_g_crop: pointer to the function that implements
+ *	:ref:`VIDIOC_G_CROP <vidioc_g_crop>` ioctl
+ * @vidioc_s_crop: pointer to the function that implements
+ *	:ref:`VIDIOC_S_CROP <vidioc_g_crop>` ioctl
+ * @vidioc_g_selection: pointer to the function that implements
+ *	:ref:`VIDIOC_G_SELECTION <vidioc_g_selection>` ioctl
+ * @vidioc_s_selection: pointer to the function that implements
+ *	:ref:`VIDIOC_S_SELECTION <vidioc_g_selection>` ioctl
+ * @vidioc_g_jpegcomp: pointer to the function that implements
+ *	:ref:`VIDIOC_G_JPEGCOMP <vidioc_g_jpegcomp>` ioctl
+ * @vidioc_s_jpegcomp: pointer to the function that implements
+ *	:ref:`VIDIOC_S_JPEGCOMP <vidioc_g_jpegcomp>` ioctl
+ * @vidioc_g_enc_index: pointer to the function that implements
+ *	:ref:`VIDIOC_G_ENC_INDEX <vidioc_g_enc_index>` ioctl
+ * @vidioc_encoder_cmd: pointer to the function that implements
+ *	:ref:`VIDIOC_ENCODER_CMD <vidioc_encoder_cmd>` ioctl
+ * @vidioc_try_encoder_cmd: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_ENCODER_CMD <vidioc_encoder_cmd>` ioctl
+ * @vidioc_decoder_cmd: pointer to the function that implements
+ *	:ref:`VIDIOC_DECODER_CMD <vidioc_decoder_cmd>` ioctl
+ * @vidioc_try_decoder_cmd: pointer to the function that implements
+ *	:ref:`VIDIOC_TRY_DECODER_CMD <vidioc_decoder_cmd>` ioctl
+ * @vidioc_g_parm: pointer to the function that implements
+ *	:ref:`VIDIOC_G_PARM <vidioc_g_parm>` ioctl
+ * @vidioc_s_parm: pointer to the function that implements
+ *	:ref:`VIDIOC_S_PARM <vidioc_g_parm>` ioctl
+ * @vidioc_g_tuner: pointer to the function that implements
+ *	:ref:`VIDIOC_G_TUNER <vidioc_g_tuner>` ioctl
+ * @vidioc_s_tuner: pointer to the function that implements
+ *	:ref:`VIDIOC_S_TUNER <vidioc_g_tuner>` ioctl
+ * @vidioc_g_frequency: pointer to the function that implements
+ *	:ref:`VIDIOC_G_FREQUENCY <vidioc_g_frequency>` ioctl
+ * @vidioc_s_frequency: pointer to the function that implements
+ *	:ref:`VIDIOC_S_FREQUENCY <vidioc_g_frequency>` ioctl
+ * @vidioc_enum_freq_bands: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FREQ_BANDS <vidioc_enum_freq_bands>` ioctl
+ * @vidioc_g_sliced_vbi_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_G_SLICED_VBI_CAP <vidioc_g_sliced_vbi_cap>` ioctl
+ * @vidioc_log_status: pointer to the function that implements
+ *	:ref:`VIDIOC_LOG_STATUS <vidioc_log_status>` ioctl
+ * @vidioc_s_hw_freq_seek: pointer to the function that implements
+ *	:ref:`VIDIOC_S_HW_FREQ_SEEK <vidioc_s_hw_freq_seek>` ioctl
+ * @vidioc_g_register: pointer to the function that implements
+ *	:ref:`VIDIOC_DBG_G_REGISTER <vidioc_dbg_g_register>` ioctl
+ * @vidioc_s_register: pointer to the function that implements
+ *	:ref:`VIDIOC_DBG_S_REGISTER <vidioc_dbg_g_register>` ioctl
+ * @vidioc_g_chip_info: pointer to the function that implements
+ *	:ref:`VIDIOC_DBG_G_CHIP_INFO <vidioc_dbg_g_chip_info>` ioctl
+ * @vidioc_enum_framesizes: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FRAMESIZES <vidioc_enum_framesizes>` ioctl
+ * @vidioc_enum_frameintervals: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_FRAMEINTERVALS <vidioc_enum_frameintervals>` ioctl
+ * @vidioc_s_dv_timings: pointer to the function that implements
+ *	:ref:`VIDIOC_S_DV_TIMINGS <vidioc_g_dv_timings>` ioctl
+ * @vidioc_g_dv_timings: pointer to the function that implements
+ *	:ref:`VIDIOC_G_DV_TIMINGS <vidioc_g_dv_timings>` ioctl
+ * @vidioc_query_dv_timings: pointer to the function that implements
+ *	:ref:`VIDIOC_QUERY_DV_TIMINGS <vidioc_query_dv_timings>` ioctl
+ * @vidioc_enum_dv_timings: pointer to the function that implements
+ *	:ref:`VIDIOC_ENUM_DV_TIMINGS <vidioc_enum_dv_timings>` ioctl
+ * @vidioc_dv_timings_cap: pointer to the function that implements
+ *	:ref:`VIDIOC_DV_TIMINGS_CAP <vidioc_dv_timings_cap>` ioctl
+ * @vidioc_g_edid: pointer to the function that implements
+ *	:ref:`VIDIOC_G_EDID <vidioc_g_edid>` ioctl
+ * @vidioc_s_edid: pointer to the function that implements
+ *	:ref:`VIDIOC_S_EDID <vidioc_g_edid>` ioctl
+ * @vidioc_subscribe_event: pointer to the function that implements
+ *	:ref:`VIDIOC_SUBSCRIBE_EVENT <vidioc_subscribe_event>` ioctl
+ * @vidioc_unsubscribe_event: pointer to the function that implements
+ *	:ref:`VIDIOC_UNSUBSCRIBE_EVENT <vidioc_unsubscribe_event>` ioctl
+ * @vidioc_default: pointed used to allow other ioctls
+ */
+struct v4l2_ioctl_ops {
+	/* ioctl callbacks */
+
+	/* VIDIOC_QUERYCAP handler */
+	int (*vidioc_querycap)(struct file *file, void *fh,
+			       struct v4l2_capability *cap);
+
+	/* VIDIOC_ENUM_FMT handlers */
+	int (*vidioc_enum_fmt_vid_cap)(struct file *file, void *fh,
+				       struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vid_overlay)(struct file *file, void *fh,
+					   struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vid_out)(struct file *file, void *fh,
+				       struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vid_cap_mplane)(struct file *file, void *fh,
+					      struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh,
+					      struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_sdr_cap)(struct file *file, void *fh,
+				       struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_sdr_out)(struct file *file, void *fh,
+				       struct v4l2_fmtdesc *f);
+	int (*vidioc_enum_fmt_meta_cap)(struct file *file, void *fh,
+					struct v4l2_fmtdesc *f);
+
+	/* VIDIOC_G_FMT handlers */
+	int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_out)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh,
+					    struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi_cap)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_g_fmt_vbi_out)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_cap_mplane)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_g_fmt_sdr_cap)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_g_fmt_sdr_out)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_g_fmt_meta_cap)(struct file *file, void *fh,
+				     struct v4l2_format *f);
+
+	/* VIDIOC_S_FMT handlers */
+	int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh,
+					struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_out)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh,
+					    struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi_cap)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_s_fmt_vbi_out)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_cap_mplane)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh,
+					   struct v4l2_format *f);
+	int (*vidioc_s_fmt_sdr_cap)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_s_fmt_sdr_out)(struct file *file, void *fh,
+				    struct v4l2_format *f);
+	int (*vidioc_s_fmt_meta_cap)(struct file *file, void *fh,
+				     struct v4l2_format *f);
+
+	/* VIDIOC_TRY_FMT handlers */
+	int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh,
+				      struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh,
+					  struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_out)(struct file *file, void *fh,
+				      struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh,
+					     struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi_cap)(struct file *file, void *fh,
+				      struct v4l2_format *f);
+	int (*vidioc_try_fmt_vbi_out)(struct file *file, void *fh,
+				      struct v4l2_format *f);
+	int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh,
+					     struct v4l2_format *f);
+	int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh,
+					     struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_cap_mplane)(struct file *file, void *fh,
+					     struct v4l2_format *f);
+	int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh,
+					     struct v4l2_format *f);
+	int (*vidioc_try_fmt_sdr_cap)(struct file *file, void *fh,
+				      struct v4l2_format *f);
+	int (*vidioc_try_fmt_sdr_out)(struct file *file, void *fh,
+				      struct v4l2_format *f);
+	int (*vidioc_try_fmt_meta_cap)(struct file *file, void *fh,
+				       struct v4l2_format *f);
+
+	/* Buffer handlers */
+	int (*vidioc_reqbufs)(struct file *file, void *fh,
+			      struct v4l2_requestbuffers *b);
+	int (*vidioc_querybuf)(struct file *file, void *fh,
+			       struct v4l2_buffer *b);
+	int (*vidioc_qbuf)(struct file *file, void *fh,
+			   struct v4l2_buffer *b);
+	int (*vidioc_expbuf)(struct file *file, void *fh,
+			     struct v4l2_exportbuffer *e);
+	int (*vidioc_dqbuf)(struct file *file, void *fh,
+			    struct v4l2_buffer *b);
+
+	int (*vidioc_create_bufs)(struct file *file, void *fh,
+				  struct v4l2_create_buffers *b);
+	int (*vidioc_prepare_buf)(struct file *file, void *fh,
+				  struct v4l2_buffer *b);
+
+	int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i);
+	int (*vidioc_g_fbuf)(struct file *file, void *fh,
+			     struct v4l2_framebuffer *a);
+	int (*vidioc_s_fbuf)(struct file *file, void *fh,
+			     const struct v4l2_framebuffer *a);
+
+		/* Stream on/off */
+	int (*vidioc_streamon)(struct file *file, void *fh,
+			       enum v4l2_buf_type i);
+	int (*vidioc_streamoff)(struct file *file, void *fh,
+				enum v4l2_buf_type i);
+
+		/*
+		 * Standard handling
+		 *
+		 * Note: ENUMSTD is handled by videodev.c
+		 */
+	int (*vidioc_g_std)(struct file *file, void *fh, v4l2_std_id *norm);
+	int (*vidioc_s_std)(struct file *file, void *fh, v4l2_std_id norm);
+	int (*vidioc_querystd)(struct file *file, void *fh, v4l2_std_id *a);
+
+		/* Input handling */
+	int (*vidioc_enum_input)(struct file *file, void *fh,
+				 struct v4l2_input *inp);
+	int (*vidioc_g_input)(struct file *file, void *fh, unsigned int *i);
+	int (*vidioc_s_input)(struct file *file, void *fh, unsigned int i);
+
+		/* Output handling */
+	int (*vidioc_enum_output)(struct file *file, void *fh,
+				  struct v4l2_output *a);
+	int (*vidioc_g_output)(struct file *file, void *fh, unsigned int *i);
+	int (*vidioc_s_output)(struct file *file, void *fh, unsigned int i);
+
+		/* Control handling */
+	int (*vidioc_queryctrl)(struct file *file, void *fh,
+				struct v4l2_queryctrl *a);
+	int (*vidioc_query_ext_ctrl)(struct file *file, void *fh,
+				     struct v4l2_query_ext_ctrl *a);
+	int (*vidioc_g_ctrl)(struct file *file, void *fh,
+			     struct v4l2_control *a);
+	int (*vidioc_s_ctrl)(struct file *file, void *fh,
+			     struct v4l2_control *a);
+	int (*vidioc_g_ext_ctrls)(struct file *file, void *fh,
+				  struct v4l2_ext_controls *a);
+	int (*vidioc_s_ext_ctrls)(struct file *file, void *fh,
+				  struct v4l2_ext_controls *a);
+	int (*vidioc_try_ext_ctrls)(struct file *file, void *fh,
+				    struct v4l2_ext_controls *a);
+	int (*vidioc_querymenu)(struct file *file, void *fh,
+				struct v4l2_querymenu *a);
+
+	/* Audio ioctls */
+	int (*vidioc_enumaudio)(struct file *file, void *fh,
+				struct v4l2_audio *a);
+	int (*vidioc_g_audio)(struct file *file, void *fh,
+			      struct v4l2_audio *a);
+	int (*vidioc_s_audio)(struct file *file, void *fh,
+			      const struct v4l2_audio *a);
+
+	/* Audio out ioctls */
+	int (*vidioc_enumaudout)(struct file *file, void *fh,
+				 struct v4l2_audioout *a);
+	int (*vidioc_g_audout)(struct file *file, void *fh,
+			       struct v4l2_audioout *a);
+	int (*vidioc_s_audout)(struct file *file, void *fh,
+			       const struct v4l2_audioout *a);
+	int (*vidioc_g_modulator)(struct file *file, void *fh,
+				  struct v4l2_modulator *a);
+	int (*vidioc_s_modulator)(struct file *file, void *fh,
+				  const struct v4l2_modulator *a);
+	/* Crop ioctls */
+	int (*vidioc_cropcap)(struct file *file, void *fh,
+			      struct v4l2_cropcap *a);
+	int (*vidioc_g_crop)(struct file *file, void *fh,
+			     struct v4l2_crop *a);
+	int (*vidioc_s_crop)(struct file *file, void *fh,
+			     const struct v4l2_crop *a);
+	int (*vidioc_g_selection)(struct file *file, void *fh,
+				  struct v4l2_selection *s);
+	int (*vidioc_s_selection)(struct file *file, void *fh,
+				  struct v4l2_selection *s);
+	/* Compression ioctls */
+	int (*vidioc_g_jpegcomp)(struct file *file, void *fh,
+				 struct v4l2_jpegcompression *a);
+	int (*vidioc_s_jpegcomp)(struct file *file, void *fh,
+				 const struct v4l2_jpegcompression *a);
+	int (*vidioc_g_enc_index)(struct file *file, void *fh,
+				  struct v4l2_enc_idx *a);
+	int (*vidioc_encoder_cmd)(struct file *file, void *fh,
+				  struct v4l2_encoder_cmd *a);
+	int (*vidioc_try_encoder_cmd)(struct file *file, void *fh,
+				      struct v4l2_encoder_cmd *a);
+	int (*vidioc_decoder_cmd)(struct file *file, void *fh,
+				  struct v4l2_decoder_cmd *a);
+	int (*vidioc_try_decoder_cmd)(struct file *file, void *fh,
+				      struct v4l2_decoder_cmd *a);
+
+	/* Stream type-dependent parameter ioctls */
+	int (*vidioc_g_parm)(struct file *file, void *fh,
+			     struct v4l2_streamparm *a);
+	int (*vidioc_s_parm)(struct file *file, void *fh,
+			     struct v4l2_streamparm *a);
+
+	/* Tuner ioctls */
+	int (*vidioc_g_tuner)(struct file *file, void *fh,
+			      struct v4l2_tuner *a);
+	int (*vidioc_s_tuner)(struct file *file, void *fh,
+			      const struct v4l2_tuner *a);
+	int (*vidioc_g_frequency)(struct file *file, void *fh,
+				  struct v4l2_frequency *a);
+	int (*vidioc_s_frequency)(struct file *file, void *fh,
+				  const struct v4l2_frequency *a);
+	int (*vidioc_enum_freq_bands)(struct file *file, void *fh,
+				      struct v4l2_frequency_band *band);
+
+	/* Sliced VBI cap */
+	int (*vidioc_g_sliced_vbi_cap)(struct file *file, void *fh,
+				       struct v4l2_sliced_vbi_cap *a);
+
+	/* Log status ioctl */
+	int (*vidioc_log_status)(struct file *file, void *fh);
+
+	int (*vidioc_s_hw_freq_seek)(struct file *file, void *fh,
+				     const struct v4l2_hw_freq_seek *a);
+
+	/* Debugging ioctls */
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	int (*vidioc_g_register)(struct file *file, void *fh,
+				 struct v4l2_dbg_register *reg);
+	int (*vidioc_s_register)(struct file *file, void *fh,
+				 const struct v4l2_dbg_register *reg);
+
+	int (*vidioc_g_chip_info)(struct file *file, void *fh,
+				  struct v4l2_dbg_chip_info *chip);
+#endif
+
+	int (*vidioc_enum_framesizes)(struct file *file, void *fh,
+				      struct v4l2_frmsizeenum *fsize);
+
+	int (*vidioc_enum_frameintervals)(struct file *file, void *fh,
+					  struct v4l2_frmivalenum *fival);
+
+	/* DV Timings IOCTLs */
+	int (*vidioc_s_dv_timings)(struct file *file, void *fh,
+				   struct v4l2_dv_timings *timings);
+	int (*vidioc_g_dv_timings)(struct file *file, void *fh,
+				   struct v4l2_dv_timings *timings);
+	int (*vidioc_query_dv_timings)(struct file *file, void *fh,
+				       struct v4l2_dv_timings *timings);
+	int (*vidioc_enum_dv_timings)(struct file *file, void *fh,
+				      struct v4l2_enum_dv_timings *timings);
+	int (*vidioc_dv_timings_cap)(struct file *file, void *fh,
+				     struct v4l2_dv_timings_cap *cap);
+	int (*vidioc_g_edid)(struct file *file, void *fh,
+			     struct v4l2_edid *edid);
+	int (*vidioc_s_edid)(struct file *file, void *fh,
+			     struct v4l2_edid *edid);
+
+	int (*vidioc_subscribe_event)(struct v4l2_fh *fh,
+				      const struct v4l2_event_subscription *sub);
+	int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh,
+					const struct v4l2_event_subscription *sub);
+
+	/* For other private ioctls */
+	long (*vidioc_default)(struct file *file, void *fh,
+			       bool valid_prio, unsigned int cmd, void *arg);
+};
+
+
+/* v4l debugging and diagnostics */
+
+/* Device debug flags to be used with the video device debug attribute */
+
+/* Just log the ioctl name + error code */
+#define V4L2_DEV_DEBUG_IOCTL		0x01
+/* Log the ioctl name arguments + error code */
+#define V4L2_DEV_DEBUG_IOCTL_ARG	0x02
+/* Log the file operations open, release, mmap and get_unmapped_area */
+#define V4L2_DEV_DEBUG_FOP		0x04
+/* Log the read and write file operations and the VIDIOC_(D)QBUF ioctls */
+#define V4L2_DEV_DEBUG_STREAMING	0x08
+/* Log poll() */
+#define V4L2_DEV_DEBUG_POLL		0x10
+
+/*  Video standard functions  */
+
+/**
+ * v4l2_norm_to_name - Ancillary routine to analog TV standard name from its ID.
+ *
+ * @id:	analog TV standard ID.
+ *
+ * Return: returns a string with the name of the analog TV standard.
+ * If the standard is not found or if @id points to multiple standard,
+ * it returns "Unknown".
+ */
+const char *v4l2_norm_to_name(v4l2_std_id id);
+
+/**
+ * v4l2_video_std_frame_period - Ancillary routine that fills a
+ *	struct &v4l2_fract pointer with the default framerate fraction.
+ *
+ * @id: analog TV standard ID.
+ * @frameperiod: struct &v4l2_fract pointer to be filled
+ *
+ */
+void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod);
+
+/**
+ * v4l2_video_std_construct - Ancillary routine that fills in the fields of
+ *	a &v4l2_standard structure according to the @id parameter.
+ *
+ * @vs: struct &v4l2_standard pointer to be filled
+ * @id: analog TV standard ID.
+ * @name: name of the standard to be used
+ *
+ * .. note::
+ *
+ *    This ancillary routine is obsolete. Shouldn't be used on newer drivers.
+ */
+int v4l2_video_std_construct(struct v4l2_standard *vs,
+				    int id, const char *name);
+
+/**
+ * v4l_video_std_enumstd - Ancillary routine that fills in the fields of
+ *	a &v4l2_standard structure according to the @id and @vs->index
+ *	parameters.
+ *
+ * @vs: struct &v4l2_standard pointer to be filled.
+ * @id: analog TV standard ID.
+ *
+ */
+int v4l_video_std_enumstd(struct v4l2_standard *vs, v4l2_std_id id);
+
+/**
+ * v4l_printk_ioctl - Ancillary routine that prints the ioctl in a
+ *	human-readable format.
+ *
+ * @prefix: prefix to be added at the ioctl prints.
+ * @cmd: ioctl name
+ *
+ * .. note::
+ *
+ *    If prefix != %NULL, then it will issue a
+ *    ``printk(KERN_DEBUG "%s: ", prefix)`` first.
+ */
+void v4l_printk_ioctl(const char *prefix, unsigned int cmd);
+
+struct video_device;
+
+/* names for fancy debug output */
+extern const char *v4l2_field_names[];
+extern const char *v4l2_type_names[];
+
+#ifdef CONFIG_COMPAT
+/**
+ * v4l2_compat_ioctl32 -32 Bits compatibility layer for 64 bits processors
+ *
+ * @file: Pointer to struct &file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ */
+long int v4l2_compat_ioctl32(struct file *file, unsigned int cmd,
+			     unsigned long arg);
+#endif
+
+/**
+ * typedef v4l2_kioctl - Typedef used to pass an ioctl handler.
+ *
+ * @file: Pointer to struct &file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ */
+typedef long (*v4l2_kioctl)(struct file *file, unsigned int cmd, void *arg);
+
+/**
+ * video_usercopy - copies data from/to userspace memory when an ioctl is
+ *	issued.
+ *
+ * @file: Pointer to struct &file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ * @func: function that will handle the ioctl
+ *
+ * .. note::
+ *
+ *    This routine should be used only inside the V4L2 core.
+ */
+long int video_usercopy(struct file *file, unsigned int cmd,
+			unsigned long int arg, v4l2_kioctl func);
+
+/**
+ * video_ioctl2 - Handles a V4L2 ioctl.
+ *
+ * @file: Pointer to struct &file.
+ * @cmd: Ioctl name.
+ * @arg: Ioctl argument.
+ *
+ * Method used to hancle an ioctl. Should be used to fill the
+ * &v4l2_ioctl_ops.unlocked_ioctl on all V4L2 drivers.
+ */
+long int video_ioctl2(struct file *file,
+		      unsigned int cmd, unsigned long int arg);
+
+#endif /* _V4L2_IOCTL_H */
diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h
new file mode 100644
index 0000000..2634d9d
--- /dev/null
+++ b/include/media/v4l2-mc.h
@@ -0,0 +1,246 @@
+/*
+ * v4l2-mc.h - Media Controller V4L2 types and prototypes
+ *
+ * Copyright (C) 2016 Mauro Carvalho Chehab <mchehab@kernel.org>
+ * Copyright (C) 2006-2010 Nokia Corporation
+ * Copyright (c) 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _V4L2_MC_H
+#define _V4L2_MC_H
+
+#include <media/media-device.h>
+#include <media/v4l2-dev.h>
+#include <linux/types.h>
+
+/**
+ * enum tuner_pad_index - tuner pad index for MEDIA_ENT_F_TUNER
+ *
+ * @TUNER_PAD_RF_INPUT:	Radiofrequency (RF) sink pad, usually linked to a
+ *			RF connector entity.
+ * @TUNER_PAD_OUTPUT:	Tuner video output source pad. Contains the video
+ *			chrominance and luminance or the hole bandwidth
+ *			of the signal converted to an Intermediate Frequency
+ *			(IF) or to baseband (on zero-IF tuners).
+ * @TUNER_PAD_AUD_OUT:	Tuner audio output source pad. Tuners used to decode
+ *			analog TV signals have an extra pad for audio output.
+ *			Old tuners use an analog stage with a saw filter for
+ *			the audio IF frequency. The output of the pad is, in
+ *			this case, the audio IF, with should be decoded either
+ *			by the bridge chipset (that's the case of cx2388x
+ *			chipsets) or may require an external IF sound
+ *			processor, like msp34xx. On modern silicon tuners,
+ *			the audio IF decoder is usually incorporated at the
+ *			tuner. On such case, the output of this pad is an
+ *			audio sampled data.
+ * @TUNER_NUM_PADS:	Number of pads of the tuner.
+ */
+enum tuner_pad_index {
+	TUNER_PAD_RF_INPUT,
+	TUNER_PAD_OUTPUT,
+	TUNER_PAD_AUD_OUT,
+	TUNER_NUM_PADS
+};
+
+/**
+ * enum if_vid_dec_pad_index - video IF-PLL pad index for
+ *			   MEDIA_ENT_F_IF_VID_DECODER
+ *
+ * @IF_VID_DEC_PAD_IF_INPUT:	video Intermediate Frequency (IF) sink pad
+ * @IF_VID_DEC_PAD_OUT:		IF-PLL video output source pad. Contains the
+ *				video chrominance and luminance IF signals.
+ * @IF_VID_DEC_PAD_NUM_PADS:	Number of pads of the video IF-PLL.
+ */
+enum if_vid_dec_pad_index {
+	IF_VID_DEC_PAD_IF_INPUT,
+	IF_VID_DEC_PAD_OUT,
+	IF_VID_DEC_PAD_NUM_PADS
+};
+
+/**
+ * enum if_aud_dec_pad_index - audio/sound IF-PLL pad index for
+ *			   MEDIA_ENT_F_IF_AUD_DECODER
+ *
+ * @IF_AUD_DEC_PAD_IF_INPUT:	audio Intermediate Frequency (IF) sink pad
+ * @IF_AUD_DEC_PAD_OUT:		IF-PLL audio output source pad. Contains the
+ *				audio sampled stream data, usually connected
+ *				to the bridge bus via an Inter-IC Sound (I2S)
+ *				bus.
+ * @IF_AUD_DEC_PAD_NUM_PADS:	Number of pads of the audio IF-PLL.
+ */
+enum if_aud_dec_pad_index {
+	IF_AUD_DEC_PAD_IF_INPUT,
+	IF_AUD_DEC_PAD_OUT,
+	IF_AUD_DEC_PAD_NUM_PADS
+};
+
+/**
+ * enum demod_pad_index - analog TV pad index for MEDIA_ENT_F_ATV_DECODER
+ *
+ * @DEMOD_PAD_IF_INPUT:	IF input sink pad.
+ * @DEMOD_PAD_VID_OUT:	Video output source pad.
+ * @DEMOD_PAD_VBI_OUT:	Vertical Blank Interface (VBI) output source pad.
+ * @DEMOD_PAD_AUDIO_OUT: Audio output source pad.
+ * @DEMOD_NUM_PADS:	Maximum number of output pads.
+ */
+enum demod_pad_index {
+	DEMOD_PAD_IF_INPUT,
+	DEMOD_PAD_VID_OUT,
+	DEMOD_PAD_VBI_OUT,
+	DEMOD_PAD_AUDIO_OUT,
+	DEMOD_NUM_PADS
+};
+
+/* We don't need to include pci.h or usb.h here */
+struct pci_dev;
+struct usb_device;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+/**
+ * v4l2_mc_create_media_graph() - create Media Controller links at the graph.
+ *
+ * @mdev:	pointer to the &media_device struct.
+ *
+ * Add links between the entities commonly found on PC customer's hardware at
+ * the V4L2 side: camera sensors, audio and video PLL-IF decoders, tuners,
+ * analog TV decoder and I/O entities (video, VBI and Software Defined Radio).
+ *
+ * .. note::
+ *
+ *    Webcams are modelled on a very simple way: the sensor is
+ *    connected directly to the I/O entity. All dirty details, like
+ *    scaler and crop HW are hidden. While such mapping is enough for v4l2
+ *    interface centric PC-consumer's hardware, V4L2 subdev centric camera
+ *    hardware should not use this routine, as it will not build the right graph.
+ */
+int v4l2_mc_create_media_graph(struct media_device *mdev);
+
+/**
+ * v4l_enable_media_source() -	Hold media source for exclusive use
+ *				if free
+ *
+ * @vdev:	pointer to struct video_device
+ *
+ * This interface calls enable_source handler to determine if
+ * media source is free for use. The enable_source handler is
+ * responsible for checking is the media source is free and
+ * start a pipeline between the media source and the media
+ * entity associated with the video device. This interface
+ * should be called from v4l2-core and dvb-core interfaces
+ * that change the source configuration.
+ *
+ * Return: returns zero on success or a negative error code.
+ */
+int v4l_enable_media_source(struct video_device *vdev);
+
+/**
+ * v4l_disable_media_source() -	Release media source
+ *
+ * @vdev:	pointer to struct video_device
+ *
+ * This interface calls disable_source handler to release
+ * the media source. The disable_source handler stops the
+ * active media pipeline between the media source and the
+ * media entity associated with the video device.
+ *
+ * Return: returns zero on success or a negative error code.
+ */
+void v4l_disable_media_source(struct video_device *vdev);
+
+/*
+ * v4l_vb2q_enable_media_tuner -  Hold media source for exclusive use
+ *				  if free.
+ * @q - pointer to struct vb2_queue
+ *
+ * Wrapper for v4l_enable_media_source(). This function should
+ * be called from v4l2-core to enable the media source with
+ * pointer to struct vb2_queue as the input argument. Some
+ * v4l2-core interfaces don't have access to video device and
+ * this interface finds the struct video_device for the q and
+ * calls v4l_enable_media_source().
+ */
+int v4l_vb2q_enable_media_source(struct vb2_queue *q);
+
+
+/**
+ * v4l2_pipeline_pm_use - Update the use count of an entity
+ * @entity: The entity
+ * @use: Use (1) or stop using (0) the entity
+ *
+ * Update the use count of all entities in the pipeline and power entities on or
+ * off accordingly.
+ *
+ * This function is intended to be called in video node open (use ==
+ * 1) and release (use == 0). It uses struct media_entity.use_count to
+ * track the power status. The use of this function should be paired
+ * with v4l2_pipeline_link_notify().
+ *
+ * Return 0 on success or a negative error code on failure. Powering entities
+ * off is assumed to never fail. No failure can occur when the use parameter is
+ * set to 0.
+ */
+int v4l2_pipeline_pm_use(struct media_entity *entity, int use);
+
+
+/**
+ * v4l2_pipeline_link_notify - Link management notification callback
+ * @link: The link
+ * @flags: New link flags that will be applied
+ * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
+ *
+ * React to link management on powered pipelines by updating the use count of
+ * all entities in the source and sink sides of the link. Entities are powered
+ * on or off accordingly. The use of this function should be paired
+ * with v4l2_pipeline_pm_use().
+ *
+ * Return 0 on success or a negative error code on failure. Powering entities
+ * off is assumed to never fail. This function will not fail for disconnection
+ * events.
+ */
+int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
+			      unsigned int notification);
+
+#else /* CONFIG_MEDIA_CONTROLLER */
+
+static inline int v4l2_mc_create_media_graph(struct media_device *mdev)
+{
+	return 0;
+}
+
+static inline int v4l_enable_media_source(struct video_device *vdev)
+{
+	return 0;
+}
+
+static inline void v4l_disable_media_source(struct video_device *vdev)
+{
+}
+
+static inline int v4l_vb2q_enable_media_source(struct vb2_queue *q)
+{
+	return 0;
+}
+
+static inline int v4l2_pipeline_pm_use(struct media_entity *entity, int use)
+{
+	return 0;
+}
+
+static inline int v4l2_pipeline_link_notify(struct media_link *link, u32 flags,
+					    unsigned int notification)
+{
+	return 0;
+}
+
+#endif /* CONFIG_MEDIA_CONTROLLER */
+#endif /* _V4L2_MC_H */
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
new file mode 100644
index 0000000..4bbb5f3
--- /dev/null
+++ b/include/media/v4l2-mediabus.h
@@ -0,0 +1,180 @@
+/*
+ * Media Bus API header
+ *
+ * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef V4L2_MEDIABUS_H
+#define V4L2_MEDIABUS_H
+
+#include <linux/v4l2-mediabus.h>
+#include <linux/bitops.h>
+
+
+/* Parallel flags */
+/*
+ * Can the client run in master or in slave mode. By "Master mode" an operation
+ * mode is meant, when the client (e.g., a camera sensor) is producing
+ * horizontal and vertical synchronisation. In "Slave mode" the host is
+ * providing these signals to the slave.
+ */
+#define V4L2_MBUS_MASTER			BIT(0)
+#define V4L2_MBUS_SLAVE				BIT(1)
+/*
+ * Signal polarity flags
+ * Note: in BT.656 mode HSYNC, FIELD, and VSYNC are unused
+ * V4L2_MBUS_[HV]SYNC* flags should be also used for specifying
+ * configuration of hardware that uses [HV]REF signals
+ */
+#define V4L2_MBUS_HSYNC_ACTIVE_HIGH		BIT(2)
+#define V4L2_MBUS_HSYNC_ACTIVE_LOW		BIT(3)
+#define V4L2_MBUS_VSYNC_ACTIVE_HIGH		BIT(4)
+#define V4L2_MBUS_VSYNC_ACTIVE_LOW		BIT(5)
+#define V4L2_MBUS_PCLK_SAMPLE_RISING		BIT(6)
+#define V4L2_MBUS_PCLK_SAMPLE_FALLING		BIT(7)
+#define V4L2_MBUS_DATA_ACTIVE_HIGH		BIT(8)
+#define V4L2_MBUS_DATA_ACTIVE_LOW		BIT(9)
+/* FIELD = 0/1 - Field1 (odd)/Field2 (even) */
+#define V4L2_MBUS_FIELD_EVEN_HIGH		BIT(10)
+/* FIELD = 1/0 - Field1 (odd)/Field2 (even) */
+#define V4L2_MBUS_FIELD_EVEN_LOW		BIT(11)
+/* Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. */
+#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH		BIT(12)
+#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW		BIT(13)
+#define V4L2_MBUS_DATA_ENABLE_HIGH		BIT(14)
+#define V4L2_MBUS_DATA_ENABLE_LOW		BIT(15)
+
+/* Serial flags */
+/* How many lanes the client can use */
+#define V4L2_MBUS_CSI2_1_LANE			BIT(0)
+#define V4L2_MBUS_CSI2_2_LANE			BIT(1)
+#define V4L2_MBUS_CSI2_3_LANE			BIT(2)
+#define V4L2_MBUS_CSI2_4_LANE			BIT(3)
+/* On which channels it can send video data */
+#define V4L2_MBUS_CSI2_CHANNEL_0		BIT(4)
+#define V4L2_MBUS_CSI2_CHANNEL_1		BIT(5)
+#define V4L2_MBUS_CSI2_CHANNEL_2		BIT(6)
+#define V4L2_MBUS_CSI2_CHANNEL_3		BIT(7)
+/* Does it support only continuous or also non-continuous clock mode */
+#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK		BIT(8)
+#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK	BIT(9)
+
+#define V4L2_MBUS_CSI2_LANES		(V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \
+					 V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE)
+#define V4L2_MBUS_CSI2_CHANNELS		(V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CHANNEL_1 | \
+					 V4L2_MBUS_CSI2_CHANNEL_2 | V4L2_MBUS_CSI2_CHANNEL_3)
+
+/**
+ * enum v4l2_mbus_type - media bus type
+ * @V4L2_MBUS_PARALLEL:	parallel interface with hsync and vsync
+ * @V4L2_MBUS_BT656:	parallel interface with embedded synchronisation, can
+ *			also be used for BT.1120
+ * @V4L2_MBUS_CSI1:	MIPI CSI-1 serial interface
+ * @V4L2_MBUS_CCP2:	CCP2 (Compact Camera Port 2)
+ * @V4L2_MBUS_CSI2:	MIPI CSI-2 serial interface
+ */
+enum v4l2_mbus_type {
+	V4L2_MBUS_PARALLEL,
+	V4L2_MBUS_BT656,
+	V4L2_MBUS_CSI1,
+	V4L2_MBUS_CCP2,
+	V4L2_MBUS_CSI2,
+};
+
+/**
+ * struct v4l2_mbus_config - media bus configuration
+ * @type:	in: interface type
+ * @flags:	in / out: configuration flags, depending on @type
+ */
+struct v4l2_mbus_config {
+	enum v4l2_mbus_type type;
+	unsigned int flags;
+};
+
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_pix_format fields from a &struct v4l2_mbus_framefmt.
+ *
+ * @pix_fmt:	pointer to &struct v4l2_pix_format to be filled
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be used as model
+ */
+static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
+				const struct v4l2_mbus_framefmt *mbus_fmt)
+{
+	pix_fmt->width = mbus_fmt->width;
+	pix_fmt->height = mbus_fmt->height;
+	pix_fmt->field = mbus_fmt->field;
+	pix_fmt->colorspace = mbus_fmt->colorspace;
+	pix_fmt->ycbcr_enc = mbus_fmt->ycbcr_enc;
+	pix_fmt->quantization = mbus_fmt->quantization;
+	pix_fmt->xfer_func = mbus_fmt->xfer_func;
+}
+
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_mbus_framefmt from a &struct v4l2_pix_format and a
+ *	data format code.
+ *
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be filled
+ * @pix_fmt:	pointer to &struct v4l2_pix_format to be used as model
+ * @code:	data format code (from &enum v4l2_mbus_pixelcode)
+ */
+static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
+			   const struct v4l2_pix_format *pix_fmt,
+			   u32 code)
+{
+	mbus_fmt->width = pix_fmt->width;
+	mbus_fmt->height = pix_fmt->height;
+	mbus_fmt->field = pix_fmt->field;
+	mbus_fmt->colorspace = pix_fmt->colorspace;
+	mbus_fmt->ycbcr_enc = pix_fmt->ycbcr_enc;
+	mbus_fmt->quantization = pix_fmt->quantization;
+	mbus_fmt->xfer_func = pix_fmt->xfer_func;
+	mbus_fmt->code = code;
+}
+
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_pix_format_mplane fields from a media bus structure.
+ *
+ * @pix_mp_fmt:	pointer to &struct v4l2_pix_format_mplane to be filled
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be used as model
+ */
+static inline void v4l2_fill_pix_format_mplane(
+				struct v4l2_pix_format_mplane *pix_mp_fmt,
+				const struct v4l2_mbus_framefmt *mbus_fmt)
+{
+	pix_mp_fmt->width = mbus_fmt->width;
+	pix_mp_fmt->height = mbus_fmt->height;
+	pix_mp_fmt->field = mbus_fmt->field;
+	pix_mp_fmt->colorspace = mbus_fmt->colorspace;
+	pix_mp_fmt->ycbcr_enc = mbus_fmt->ycbcr_enc;
+	pix_mp_fmt->quantization = mbus_fmt->quantization;
+	pix_mp_fmt->xfer_func = mbus_fmt->xfer_func;
+}
+
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_mbus_framefmt from a &struct v4l2_pix_format_mplane.
+ *
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be filled
+ * @pix_mp_fmt:	pointer to &struct v4l2_pix_format_mplane to be used as model
+ */
+static inline void v4l2_fill_mbus_format_mplane(
+				struct v4l2_mbus_framefmt *mbus_fmt,
+				const struct v4l2_pix_format_mplane *pix_mp_fmt)
+{
+	mbus_fmt->width = pix_mp_fmt->width;
+	mbus_fmt->height = pix_mp_fmt->height;
+	mbus_fmt->field = pix_mp_fmt->field;
+	mbus_fmt->colorspace = pix_mp_fmt->colorspace;
+	mbus_fmt->ycbcr_enc = pix_mp_fmt->ycbcr_enc;
+	mbus_fmt->quantization = pix_mp_fmt->quantization;
+	mbus_fmt->xfer_func = pix_mp_fmt->xfer_func;
+}
+
+#endif
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
new file mode 100644
index 0000000..d655720
--- /dev/null
+++ b/include/media/v4l2-mem2mem.h
@@ -0,0 +1,649 @@
+/*
+ * Memory-to-memory device framework for Video for Linux 2.
+ *
+ * Helper functions for devices that use memory buffers for both source
+ * and destination.
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * Pawel Osciak, <pawel@osciak.com>
+ * Marek Szyprowski, <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+#ifndef _MEDIA_V4L2_MEM2MEM_H
+#define _MEDIA_V4L2_MEM2MEM_H
+
+#include <media/videobuf2-v4l2.h>
+
+/**
+ * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
+ * @device_run:	required. Begin the actual job (transaction) inside this
+ *		callback.
+ *		The job does NOT have to end before this callback returns
+ *		(and it will be the usual case). When the job finishes,
+ *		v4l2_m2m_job_finish() has to be called.
+ * @job_ready:	optional. Should return 0 if the driver does not have a job
+ *		fully prepared to run yet (i.e. it will not be able to finish a
+ *		transaction without sleeping). If not provided, it will be
+ *		assumed that one source and one destination buffer are all
+ *		that is required for the driver to perform one full transaction.
+ *		This method may not sleep.
+ * @job_abort:	optional. Informs the driver that it has to abort the currently
+ *		running transaction as soon as possible (i.e. as soon as it can
+ *		stop the device safely; e.g. in the next interrupt handler),
+ *		even if the transaction would not have been finished by then.
+ *		After the driver performs the necessary steps, it has to call
+ *		v4l2_m2m_job_finish() (as if the transaction ended normally).
+ *		This function does not have to (and will usually not) wait
+ *		until the device enters a state when it can be stopped.
+ */
+struct v4l2_m2m_ops {
+	void (*device_run)(void *priv);
+	int (*job_ready)(void *priv);
+	void (*job_abort)(void *priv);
+};
+
+struct video_device;
+struct v4l2_m2m_dev;
+
+/**
+ * struct v4l2_m2m_queue_ctx - represents a queue for buffers ready to be
+ *	processed
+ *
+ * @q:		pointer to struct &vb2_queue
+ * @rdy_queue:	List of V4L2 mem-to-mem queues
+ * @rdy_spinlock: spin lock to protect the struct usage
+ * @num_rdy:	number of buffers ready to be processed
+ * @buffered:	is the queue buffered?
+ *
+ * Queue for buffers ready to be processed as soon as this
+ * instance receives access to the device.
+ */
+
+struct v4l2_m2m_queue_ctx {
+	struct vb2_queue	q;
+
+	struct list_head	rdy_queue;
+	spinlock_t		rdy_spinlock;
+	u8			num_rdy;
+	bool			buffered;
+};
+
+/**
+ * struct v4l2_m2m_ctx - Memory to memory context structure
+ *
+ * @q_lock: struct &mutex lock
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @cap_q_ctx: Capture (output to memory) queue context
+ * @out_q_ctx: Output (input from memory) queue context
+ * @queue: List of memory to memory contexts
+ * @job_flags: Job queue flags, used internally by v4l2-mem2mem.c:
+ *		%TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT.
+ * @finished: Wait queue used to signalize when a job queue finished.
+ * @priv: Instance private data
+ *
+ * The memory to memory context is specific to a file handle, NOT to e.g.
+ * a device.
+ */
+struct v4l2_m2m_ctx {
+	/* optional cap/out vb2 queues lock */
+	struct mutex			*q_lock;
+
+	/* internal use only */
+	struct v4l2_m2m_dev		*m2m_dev;
+
+	struct v4l2_m2m_queue_ctx	cap_q_ctx;
+
+	struct v4l2_m2m_queue_ctx	out_q_ctx;
+
+	/* For device job queue */
+	struct list_head		queue;
+	unsigned long			job_flags;
+	wait_queue_head_t		finished;
+
+	void				*priv;
+};
+
+/**
+ * struct v4l2_m2m_buffer - Memory to memory buffer
+ *
+ * @vb: pointer to struct &vb2_v4l2_buffer
+ * @list: list of m2m buffers
+ */
+struct v4l2_m2m_buffer {
+	struct vb2_v4l2_buffer	vb;
+	struct list_head	list;
+};
+
+/**
+ * v4l2_m2m_get_curr_priv() - return driver private data for the currently
+ * running instance or NULL if no instance is running
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ */
+void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev);
+
+/**
+ * v4l2_m2m_get_vq() - return vb2_queue for the given type
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type
+ */
+struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
+				       enum v4l2_buf_type type);
+
+/**
+ * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to
+ * the pending job queue and add it if so.
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ *
+ * There are three basic requirements an instance has to meet to be able to run:
+ * 1) at least one source buffer has to be queued,
+ * 2) at least one destination buffer has to be queued,
+ * 3) streaming has to be on.
+ *
+ * If a queue is buffered (for example a decoder hardware ringbuffer that has
+ * to be drained before doing streamoff), allow scheduling without v4l2 buffers
+ * on that queue.
+ *
+ * There may also be additional, custom requirements. In such case the driver
+ * should supply a custom callback (job_ready in v4l2_m2m_ops) that should
+ * return 1 if the instance is ready.
+ * An example of the above could be an instance that requires more than one
+ * src/dst buffer per transaction.
+ */
+void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx);
+
+/**
+ * v4l2_m2m_job_finish() - inform the framework that a job has been finished
+ * and have it clean up
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ *
+ * Called by a driver to yield back the device after it has finished with it.
+ * Should be called as soon as possible after reaching a state which allows
+ * other instances to take control of the device.
+ *
+ * This function has to be called only after &v4l2_m2m_ops->device_run
+ * callback has been called on the driver. To prevent recursion, it should
+ * not be called directly from the &v4l2_m2m_ops->device_run callback though.
+ */
+void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
+			 struct v4l2_m2m_ctx *m2m_ctx);
+
+static inline void
+v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
+{
+	vb2_buffer_done(&buf->vb2_buf, state);
+}
+
+/**
+ * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @reqbufs: pointer to struct &v4l2_requestbuffers
+ */
+int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		     struct v4l2_requestbuffers *reqbufs);
+
+/**
+ * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @buf: pointer to struct &v4l2_buffer
+ *
+ * See v4l2_m2m_mmap() documentation for details.
+ */
+int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		      struct v4l2_buffer *buf);
+
+/**
+ * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on
+ * the type
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @buf: pointer to struct &v4l2_buffer
+ */
+int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		  struct v4l2_buffer *buf);
+
+/**
+ * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on
+ * the type
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @buf: pointer to struct &v4l2_buffer
+ */
+int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		   struct v4l2_buffer *buf);
+
+/**
+ * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on
+ * the type
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @buf: pointer to struct &v4l2_buffer
+ */
+int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+			 struct v4l2_buffer *buf);
+
+/**
+ * v4l2_m2m_create_bufs() - create a source or destination buffer, depending
+ * on the type
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @create: pointer to struct &v4l2_create_buffers
+ */
+int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+			 struct v4l2_create_buffers *create);
+
+/**
+ * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
+ * the type
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @eb: pointer to struct &v4l2_exportbuffer
+ */
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		   struct v4l2_exportbuffer *eb);
+
+/**
+ * v4l2_m2m_streamon() - turn on streaming for a video queue
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type
+ */
+int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		      enum v4l2_buf_type type);
+
+/**
+ * v4l2_m2m_streamoff() - turn off streaming for a video queue
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type
+ */
+int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		       enum v4l2_buf_type type);
+
+/**
+ * v4l2_m2m_poll() - poll replacement, for destination buffers only
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @wait: pointer to struct &poll_table_struct
+ *
+ * Call from the driver's poll() function. Will poll both queues. If a buffer
+ * is available to dequeue (with dqbuf) from the source queue, this will
+ * indicate that a non-blocking write can be performed, while read will be
+ * returned in case of the destination queue.
+ */
+__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+			   struct poll_table_struct *wait);
+
+/**
+ * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer
+ *
+ * @file: pointer to struct &file
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @vma: pointer to struct &vm_area_struct
+ *
+ * Call from driver's mmap() function. Will handle mmap() for both queues
+ * seamlessly for videobuffer, which will receive normal per-queue offsets and
+ * proper videobuf queue pointers. The differentiation is made outside videobuf
+ * by adding a predefined offset to buffers from one of the queues and
+ * subtracting it before passing it back to videobuf. Only drivers (and
+ * thus applications) receive modified offsets.
+ */
+int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		  struct vm_area_struct *vma);
+
+/**
+ * v4l2_m2m_init() - initialize per-driver m2m data
+ *
+ * @m2m_ops: pointer to struct v4l2_m2m_ops
+ *
+ * Usually called from driver's ``probe()`` function.
+ *
+ * Return: returns an opaque pointer to the internal data to handle M2M context
+ */
+struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops);
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+void v4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev);
+int v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev,
+			struct video_device *vdev, int function);
+#else
+static inline void
+v4l2_m2m_unregister_media_controller(struct v4l2_m2m_dev *m2m_dev)
+{
+}
+
+static inline int
+v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev,
+		struct video_device *vdev, int function)
+{
+	return 0;
+}
+#endif
+
+/**
+ * v4l2_m2m_release() - cleans up and frees a m2m_dev structure
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ *
+ * Usually called from driver's ``remove()`` function.
+ */
+void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
+
+/**
+ * v4l2_m2m_ctx_init() - allocate and initialize a m2m context
+ *
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
+ * @drv_priv: driver's instance private data
+ * @queue_init: a callback for queue type-specific initialization function
+ *	to be used for initializing videobuf_queues
+ *
+ * Usually called from driver's ``open()`` function.
+ */
+struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
+		void *drv_priv,
+		int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq));
+
+static inline void v4l2_m2m_set_src_buffered(struct v4l2_m2m_ctx *m2m_ctx,
+					     bool buffered)
+{
+	m2m_ctx->out_q_ctx.buffered = buffered;
+}
+
+static inline void v4l2_m2m_set_dst_buffered(struct v4l2_m2m_ctx *m2m_ctx,
+					     bool buffered)
+{
+	m2m_ctx->cap_q_ctx.buffered = buffered;
+}
+
+/**
+ * v4l2_m2m_ctx_release() - release m2m context
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ *
+ * Usually called from driver's release() function.
+ */
+void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
+
+/**
+ * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list.
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @vbuf: pointer to struct &vb2_v4l2_buffer
+ *
+ * Call from videobuf_queue_ops->ops->buf_queue, videobuf_queue_ops callback.
+ */
+void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx,
+			struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for
+ * use
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline
+unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return m2m_ctx->out_q_ctx.num_rdy;
+}
+
+/**
+ * v4l2_m2m_num_dst_bufs_ready() - return the number of destination buffers
+ * ready for use
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline
+unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return m2m_ctx->cap_q_ctx.num_rdy;
+}
+
+/**
+ * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ */
+void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx);
+
+/**
+ * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx);
+}
+
+/**
+ * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of
+ * ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx);
+}
+
+/**
+ * v4l2_m2m_last_buf() - return last buffer from the list of ready buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ */
+void *v4l2_m2m_last_buf(struct v4l2_m2m_queue_ctx *q_ctx);
+
+/**
+ * v4l2_m2m_last_src_buf() - return last destination buffer from the list of
+ * ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void *v4l2_m2m_last_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return v4l2_m2m_last_buf(&m2m_ctx->out_q_ctx);
+}
+
+/**
+ * v4l2_m2m_last_dst_buf() - return last destination buffer from the list of
+ * ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void *v4l2_m2m_last_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return v4l2_m2m_last_buf(&m2m_ctx->cap_q_ctx);
+}
+
+/**
+ * v4l2_m2m_for_each_dst_buf() - iterate over a list of destination ready
+ * buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_dst_buf(m2m_ctx, b)	\
+	list_for_each_entry(b, &m2m_ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf() - iterate over a list of source ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ */
+#define v4l2_m2m_for_each_src_buf(m2m_ctx, b)	\
+	list_for_each_entry(b, &m2m_ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_dst_buf_safe() - iterate over a list of destination ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, b, n)	\
+	list_for_each_entry_safe(b, n, &m2m_ctx->cap_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_for_each_src_buf_safe() - iterate over a list of source ready
+ * buffers safely
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @b: current buffer of type struct v4l2_m2m_buffer
+ * @n: used as temporary storage
+ */
+#define v4l2_m2m_for_each_src_buf_safe(m2m_ctx, b, n)	\
+	list_for_each_entry_safe(b, n, &m2m_ctx->out_q_ctx.rdy_queue, list)
+
+/**
+ * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline
+struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return &m2m_ctx->out_q_ctx.q;
+}
+
+/**
+ * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline
+struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return &m2m_ctx->cap_q_ctx.q;
+}
+
+/**
+ * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
+ * return it
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ */
+void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
+
+/**
+ * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
+ * buffers and return it
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of
+ * ready buffers and return it
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ */
+static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
+{
+	return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
+}
+
+/**
+ * v4l2_m2m_buf_remove_by_buf() - take off exact buffer from the list of ready
+ * buffers
+ *
+ * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx
+ * @vbuf: the buffer to be removed
+ */
+void v4l2_m2m_buf_remove_by_buf(struct v4l2_m2m_queue_ctx *q_ctx,
+				struct vb2_v4l2_buffer *vbuf);
+
+/**
+ * v4l2_m2m_src_buf_remove_by_buf() - take off exact source buffer from the list
+ * of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_src_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+						  struct vb2_v4l2_buffer *vbuf)
+{
+	v4l2_m2m_buf_remove_by_buf(&m2m_ctx->out_q_ctx, vbuf);
+}
+
+/**
+ * v4l2_m2m_dst_buf_remove_by_buf() - take off exact destination buffer from the
+ * list of ready buffers
+ *
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
+ * @vbuf: the buffer to be removed
+ */
+static inline void v4l2_m2m_dst_buf_remove_by_buf(struct v4l2_m2m_ctx *m2m_ctx,
+						  struct vb2_v4l2_buffer *vbuf)
+{
+	v4l2_m2m_buf_remove_by_buf(&m2m_ctx->cap_q_ctx, vbuf);
+}
+
+struct vb2_v4l2_buffer *
+v4l2_m2m_buf_remove_by_idx(struct v4l2_m2m_queue_ctx *q_ctx, unsigned int idx);
+
+static inline struct vb2_v4l2_buffer *
+v4l2_m2m_src_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
+{
+	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->out_q_ctx, idx);
+}
+
+static inline struct vb2_v4l2_buffer *
+v4l2_m2m_dst_buf_remove_by_idx(struct v4l2_m2m_ctx *m2m_ctx, unsigned int idx)
+{
+	return v4l2_m2m_buf_remove_by_idx(&m2m_ctx->cap_q_ctx, idx);
+}
+
+/* v4l2 ioctl helpers */
+
+int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv,
+				struct v4l2_requestbuffers *rb);
+int v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh,
+				struct v4l2_create_buffers *create);
+int v4l2_m2m_ioctl_querybuf(struct file *file, void *fh,
+				struct v4l2_buffer *buf);
+int v4l2_m2m_ioctl_expbuf(struct file *file, void *fh,
+				struct v4l2_exportbuffer *eb);
+int v4l2_m2m_ioctl_qbuf(struct file *file, void *fh,
+				struct v4l2_buffer *buf);
+int v4l2_m2m_ioctl_dqbuf(struct file *file, void *fh,
+				struct v4l2_buffer *buf);
+int v4l2_m2m_ioctl_prepare_buf(struct file *file, void *fh,
+			       struct v4l2_buffer *buf);
+int v4l2_m2m_ioctl_streamon(struct file *file, void *fh,
+				enum v4l2_buf_type type);
+int v4l2_m2m_ioctl_streamoff(struct file *file, void *fh,
+				enum v4l2_buf_type type);
+int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
+__poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
+
+#endif /* _MEDIA_V4L2_MEM2MEM_H */
+
diff --git a/include/media/v4l2-rect.h b/include/media/v4l2-rect.h
new file mode 100644
index 0000000..595c3ba
--- /dev/null
+++ b/include/media/v4l2-rect.h
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * v4l2-rect.h - v4l2_rect helper functions
+ *
+ * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _V4L2_RECT_H_
+#define _V4L2_RECT_H_
+
+#include <linux/videodev2.h>
+
+/**
+ * v4l2_rect_set_size_to() - copy the width/height values.
+ * @r: rect whose width and height fields will be set
+ * @size: rect containing the width and height fields you need.
+ */
+static inline void v4l2_rect_set_size_to(struct v4l2_rect *r,
+					 const struct v4l2_rect *size)
+{
+	r->width = size->width;
+	r->height = size->height;
+}
+
+/**
+ * v4l2_rect_set_min_size() - width and height of r should be >= min_size.
+ * @r: rect whose width and height will be modified
+ * @min_size: rect containing the minimal width and height
+ */
+static inline void v4l2_rect_set_min_size(struct v4l2_rect *r,
+					  const struct v4l2_rect *min_size)
+{
+	if (r->width < min_size->width)
+		r->width = min_size->width;
+	if (r->height < min_size->height)
+		r->height = min_size->height;
+}
+
+/**
+ * v4l2_rect_set_max_size() - width and height of r should be <= max_size
+ * @r: rect whose width and height will be modified
+ * @max_size: rect containing the maximum width and height
+ */
+static inline void v4l2_rect_set_max_size(struct v4l2_rect *r,
+					  const struct v4l2_rect *max_size)
+{
+	if (r->width > max_size->width)
+		r->width = max_size->width;
+	if (r->height > max_size->height)
+		r->height = max_size->height;
+}
+
+/**
+ * v4l2_rect_map_inside()- r should be inside boundary.
+ * @r: rect that will be modified
+ * @boundary: rect containing the boundary for @r
+ */
+static inline void v4l2_rect_map_inside(struct v4l2_rect *r,
+					const struct v4l2_rect *boundary)
+{
+	v4l2_rect_set_max_size(r, boundary);
+	if (r->left < boundary->left)
+		r->left = boundary->left;
+	if (r->top < boundary->top)
+		r->top = boundary->top;
+	if (r->left + r->width > boundary->width)
+		r->left = boundary->width - r->width;
+	if (r->top + r->height > boundary->height)
+		r->top = boundary->height - r->height;
+}
+
+/**
+ * v4l2_rect_same_size() - return true if r1 has the same size as r2
+ * @r1: rectangle.
+ * @r2: rectangle.
+ *
+ * Return true if both rectangles have the same size.
+ */
+static inline bool v4l2_rect_same_size(const struct v4l2_rect *r1,
+				       const struct v4l2_rect *r2)
+{
+	return r1->width == r2->width && r1->height == r2->height;
+}
+
+/**
+ * v4l2_rect_intersect() - calculate the intersection of two rects.
+ * @r: intersection of @r1 and @r2.
+ * @r1: rectangle.
+ * @r2: rectangle.
+ */
+static inline void v4l2_rect_intersect(struct v4l2_rect *r,
+				       const struct v4l2_rect *r1,
+				       const struct v4l2_rect *r2)
+{
+	int right, bottom;
+
+	r->top = max(r1->top, r2->top);
+	r->left = max(r1->left, r2->left);
+	bottom = min(r1->top + r1->height, r2->top + r2->height);
+	right = min(r1->left + r1->width, r2->left + r2->width);
+	r->height = max(0, bottom - r->top);
+	r->width = max(0, right - r->left);
+}
+
+/**
+ * v4l2_rect_scale() - scale rect r by to/from
+ * @r: rect to be scaled.
+ * @from: from rectangle.
+ * @to: to rectangle.
+ *
+ * This scales rectangle @r horizontally by @to->width / @from->width and
+ * vertically by @to->height / @from->height.
+ *
+ * Typically @r is a rectangle inside @from and you want the rectangle as
+ * it would appear after scaling @from to @to. So the resulting @r will
+ * be the scaled rectangle inside @to.
+ */
+static inline void v4l2_rect_scale(struct v4l2_rect *r,
+				   const struct v4l2_rect *from,
+				   const struct v4l2_rect *to)
+{
+	if (from->width == 0 || from->height == 0) {
+		r->left = r->top = r->width = r->height = 0;
+		return;
+	}
+	r->left = (((r->left - from->left) * to->width) / from->width) & ~1;
+	r->width = ((r->width * to->width) / from->width) & ~1;
+	r->top = ((r->top - from->top) * to->height) / from->height;
+	r->height = (r->height * to->height) / from->height;
+}
+
+/**
+ * v4l2_rect_overlap() - do r1 and r2 overlap?
+ * @r1: rectangle.
+ * @r2: rectangle.
+ *
+ * Returns true if @r1 and @r2 overlap.
+ */
+static inline bool v4l2_rect_overlap(const struct v4l2_rect *r1,
+				     const struct v4l2_rect *r2)
+{
+	/*
+	 * IF the left side of r1 is to the right of the right side of r2 OR
+	 *    the left side of r2 is to the right of the right side of r1 THEN
+	 * they do not overlap.
+	 */
+	if (r1->left >= r2->left + r2->width ||
+	    r2->left >= r1->left + r1->width)
+		return false;
+	/*
+	 * IF the top side of r1 is below the bottom of r2 OR
+	 *    the top side of r2 is below the bottom of r1 THEN
+	 * they do not overlap.
+	 */
+	if (r1->top >= r2->top + r2->height ||
+	    r2->top >= r1->top + r1->height)
+		return false;
+	return true;
+}
+
+#endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
new file mode 100644
index 0000000..9102d6c
--- /dev/null
+++ b/include/media/v4l2-subdev.h
@@ -0,0 +1,1126 @@
+/*
+ *  V4L2 sub-device support header.
+ *
+ *  Copyright (C) 2008  Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef _V4L2_SUBDEV_H
+#define _V4L2_SUBDEV_H
+
+#include <linux/types.h>
+#include <linux/v4l2-subdev.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-mediabus.h>
+
+/* generic v4l2_device notify callback notification values */
+#define V4L2_SUBDEV_IR_RX_NOTIFY		_IOW('v', 0, u32)
+#define V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ	0x00000001
+#define V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED	0x00000002
+#define V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN	0x00000004
+#define V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN	0x00000008
+
+#define V4L2_SUBDEV_IR_TX_NOTIFY		_IOW('v', 1, u32)
+#define V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ	0x00000001
+
+#define	V4L2_DEVICE_NOTIFY_EVENT		_IOW('v', 2, struct v4l2_event)
+
+struct v4l2_device;
+struct v4l2_ctrl_handler;
+struct v4l2_event;
+struct v4l2_event_subscription;
+struct v4l2_fh;
+struct v4l2_subdev;
+struct v4l2_subdev_fh;
+struct tuner_setup;
+struct v4l2_mbus_frame_desc;
+
+/**
+ * struct v4l2_decode_vbi_line - used to decode_vbi_line
+ *
+ * @is_second_field: Set to 0 for the first (odd) field;
+ *	set to 1 for the second (even) field.
+ * @p: Pointer to the sliced VBI data from the decoder. On exit, points to
+ *	the start of the payload.
+ * @line: Line number of the sliced VBI data (1-23)
+ * @type: VBI service type (V4L2_SLICED_*). 0 if no service found
+ */
+struct v4l2_decode_vbi_line {
+	u32 is_second_field;
+	u8 *p;
+	u32 line;
+	u32 type;
+};
+
+/*
+ * Sub-devices are devices that are connected somehow to the main bridge
+ * device. These devices are usually audio/video muxers/encoders/decoders or
+ * sensors and webcam controllers.
+ *
+ * Usually these devices are controlled through an i2c bus, but other busses
+ * may also be used.
+ *
+ * The v4l2_subdev struct provides a way of accessing these devices in a
+ * generic manner. Most operations that these sub-devices support fall in
+ * a few categories: core ops, audio ops, video ops and tuner ops.
+ *
+ * More categories can be added if needed, although this should remain a
+ * limited set (no more than approx. 8 categories).
+ *
+ * Each category has its own set of ops that subdev drivers can implement.
+ *
+ * A subdev driver can leave the pointer to the category ops NULL if
+ * it does not implement them (e.g. an audio subdev will generally not
+ * implement the video category ops). The exception is the core category:
+ * this must always be present.
+ *
+ * These ops are all used internally so it is no problem to change, remove
+ * or add ops or move ops from one to another category. Currently these
+ * ops are based on the original ioctls, but since ops are not limited to
+ * one argument there is room for improvement here once all i2c subdev
+ * drivers are converted to use these ops.
+ */
+
+/*
+ * Core ops: it is highly recommended to implement at least these ops:
+ *
+ * log_status
+ * g_register
+ * s_register
+ *
+ * This provides basic debugging support.
+ *
+ * The ioctl ops is meant for generic ioctl-like commands. Depending on
+ * the use-case it might be better to use subdev-specific ops (currently
+ * not yet implemented) since ops provide proper type-checking.
+ */
+
+/**
+ * enum v4l2_subdev_io_pin_bits - Subdevice external IO pin configuration
+ *	bits
+ *
+ * @V4L2_SUBDEV_IO_PIN_DISABLE: disables a pin config. ENABLE assumed.
+ * @V4L2_SUBDEV_IO_PIN_OUTPUT: set it if pin is an output.
+ * @V4L2_SUBDEV_IO_PIN_INPUT: set it if pin is an input.
+ * @V4L2_SUBDEV_IO_PIN_SET_VALUE: to set the output value via
+ *				  &struct v4l2_subdev_io_pin_config->value.
+ * @V4L2_SUBDEV_IO_PIN_ACTIVE_LOW: pin active is bit 0.
+ *				   Otherwise, ACTIVE HIGH is assumed.
+ */
+enum v4l2_subdev_io_pin_bits {
+	V4L2_SUBDEV_IO_PIN_DISABLE	= 0,
+	V4L2_SUBDEV_IO_PIN_OUTPUT	= 1,
+	V4L2_SUBDEV_IO_PIN_INPUT	= 2,
+	V4L2_SUBDEV_IO_PIN_SET_VALUE	= 3,
+	V4L2_SUBDEV_IO_PIN_ACTIVE_LOW	= 4,
+};
+
+/**
+ * struct v4l2_subdev_io_pin_config - Subdevice external IO pin configuration
+ *
+ * @flags: bitmask with flags for this pin's config, whose bits are defined by
+ *	   &enum v4l2_subdev_io_pin_bits.
+ * @pin: Chip external IO pin to configure
+ * @function: Internal signal pad/function to route to IO pin
+ * @value: Initial value for pin - e.g. GPIO output value
+ * @strength: Pin drive strength
+ */
+struct v4l2_subdev_io_pin_config {
+	u32 flags;
+	u8 pin;
+	u8 function;
+	u8 value;
+	u8 strength;
+};
+
+/**
+ * struct v4l2_subdev_core_ops - Define core ops callbacks for subdevs
+ *
+ * @log_status: callback for VIDIOC_LOG_STATUS() ioctl handler code.
+ *
+ * @s_io_pin_config: configure one or more chip I/O pins for chips that
+ *	multiplex different internal signal pads out to IO pins.  This function
+ *	takes a pointer to an array of 'n' pin configuration entries, one for
+ *	each pin being configured.  This function could be called at times
+ *	other than just subdevice initialization.
+ *
+ * @init: initialize the sensor registers to some sort of reasonable default
+ *	values. Do not use for new drivers and should be removed in existing
+ *	drivers.
+ *
+ * @load_fw: load firmware.
+ *
+ * @reset: generic reset command. The argument selects which subsystems to
+ *	reset. Passing 0 will always reset the whole chip. Do not use for new
+ *	drivers without discussing this first on the linux-media mailinglist.
+ *	There should be no reason normally to reset a device.
+ *
+ * @s_gpio: set GPIO pins. Very simple right now, might need to be extended with
+ *	a direction argument if needed.
+ *
+ * @ioctl: called at the end of ioctl() syscall handler at the V4L2 core.
+ *	   used to provide support for private ioctls used on the driver.
+ *
+ * @compat_ioctl32: called when a 32 bits application uses a 64 bits Kernel,
+ *		    in order to fix data passed from/to userspace.
+ *
+ * @g_register: callback for VIDIOC_DBG_G_REGISTER() ioctl handler code.
+ *
+ * @s_register: callback for VIDIOC_DBG_S_REGISTER() ioctl handler code.
+ *
+ * @s_power: puts subdevice in power saving mode (on == 0) or normal operation
+ *	mode (on == 1).
+ *
+ * @interrupt_service_routine: Called by the bridge chip's interrupt service
+ *	handler, when an interrupt status has be raised due to this subdev,
+ *	so that this subdev can handle the details.  It may schedule work to be
+ *	performed later.  It must not sleep. **Called from an IRQ context**.
+ *
+ * @subscribe_event: used by the drivers to request the control framework that
+ *		     for it to be warned when the value of a control changes.
+ *
+ * @unsubscribe_event: remove event subscription from the control framework.
+ */
+struct v4l2_subdev_core_ops {
+	int (*log_status)(struct v4l2_subdev *sd);
+	int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n,
+				      struct v4l2_subdev_io_pin_config *pincfg);
+	int (*init)(struct v4l2_subdev *sd, u32 val);
+	int (*load_fw)(struct v4l2_subdev *sd);
+	int (*reset)(struct v4l2_subdev *sd, u32 val);
+	int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
+	long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
+#ifdef CONFIG_COMPAT
+	long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd,
+			       unsigned long arg);
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
+	int (*s_register)(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg);
+#endif
+	int (*s_power)(struct v4l2_subdev *sd, int on);
+	int (*interrupt_service_routine)(struct v4l2_subdev *sd,
+						u32 status, bool *handled);
+	int (*subscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+			       struct v4l2_event_subscription *sub);
+	int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+				 struct v4l2_event_subscription *sub);
+};
+
+/**
+ * struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened
+ *	in radio mode.
+ *
+ * @standby: puts the tuner in standby mode. It will be woken up
+ *	     automatically the next time it is used.
+ *
+ * @s_radio: callback that switches the tuner to radio mode.
+ *	     drivers should explicitly call it when a tuner ops should
+ *	     operate on radio mode, before being able to handle it.
+ *	     Used on devices that have both AM/FM radio receiver and TV.
+ *
+ * @s_frequency: callback for VIDIOC_S_FREQUENCY() ioctl handler code.
+ *
+ * @g_frequency: callback for VIDIOC_G_FREQUENCY() ioctl handler code.
+ *		 freq->type must be filled in. Normally done by video_ioctl2()
+ *		 or the bridge driver.
+ *
+ * @enum_freq_bands: callback for VIDIOC_ENUM_FREQ_BANDS() ioctl handler code.
+ *
+ * @g_tuner: callback for VIDIOC_G_TUNER() ioctl handler code.
+ *
+ * @s_tuner: callback for VIDIOC_S_TUNER() ioctl handler code. @vt->type must be
+ *	     filled in. Normally done by video_ioctl2 or the
+ *	     bridge driver.
+ *
+ * @g_modulator: callback for VIDIOC_G_MODULATOR() ioctl handler code.
+ *
+ * @s_modulator: callback for VIDIOC_S_MODULATOR() ioctl handler code.
+ *
+ * @s_type_addr: sets tuner type and its I2C addr.
+ *
+ * @s_config: sets tda9887 specific stuff, like port1, port2 and qss
+ *
+ * .. note::
+ *
+ *	On devices that have both AM/FM and TV, it is up to the driver
+ *	to explicitly call s_radio when the tuner should be switched to
+ *	radio mode, before handling other &struct v4l2_subdev_tuner_ops
+ *	that would require it. An example of such usage is::
+ *
+ *	  static void s_frequency(void *priv, const struct v4l2_frequency *f)
+ *	  {
+ *		...
+ *		if (f.type == V4L2_TUNER_RADIO)
+ *			v4l2_device_call_all(v4l2_dev, 0, tuner, s_radio);
+ *		...
+ *		v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency);
+ *	  }
+ */
+struct v4l2_subdev_tuner_ops {
+	int (*standby)(struct v4l2_subdev *sd);
+	int (*s_radio)(struct v4l2_subdev *sd);
+	int (*s_frequency)(struct v4l2_subdev *sd, const struct v4l2_frequency *freq);
+	int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
+	int (*enum_freq_bands)(struct v4l2_subdev *sd, struct v4l2_frequency_band *band);
+	int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
+	int (*s_tuner)(struct v4l2_subdev *sd, const struct v4l2_tuner *vt);
+	int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
+	int (*s_modulator)(struct v4l2_subdev *sd, const struct v4l2_modulator *vm);
+	int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
+	int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
+};
+
+/**
+ * struct v4l2_subdev_audio_ops - Callbacks used for audio-related settings
+ *
+ * @s_clock_freq: set the frequency (in Hz) of the audio clock output.
+ *	Used to slave an audio processor to the video decoder, ensuring that
+ *	audio and video remain synchronized. Usual values for the frequency
+ *	are 48000, 44100 or 32000 Hz. If the frequency is not supported, then
+ *	-EINVAL is returned.
+ *
+ * @s_i2s_clock_freq: sets I2S speed in bps. This is used to provide a standard
+ *	way to select I2S clock used by driving digital audio streams at some
+ *	board designs. Usual values for the frequency are 1024000 and 2048000.
+ *	If the frequency is not supported, then %-EINVAL is returned.
+ *
+ * @s_routing: used to define the input and/or output pins of an audio chip,
+ *	and any additional configuration data.
+ *	Never attempt to use user-level input IDs (e.g. Composite, S-Video,
+ *	Tuner) at this level. An i2c device shouldn't know about whether an
+ *	input pin is connected to a Composite connector, become on another
+ *	board or platform it might be connected to something else entirely.
+ *	The calling driver is responsible for mapping a user-level input to
+ *	the right pins on the i2c device.
+ *
+ * @s_stream: used to notify the audio code that stream will start or has
+ *	stopped.
+ */
+struct v4l2_subdev_audio_ops {
+	int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
+	int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq);
+	int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
+	int (*s_stream)(struct v4l2_subdev *sd, int enable);
+};
+
+/**
+ * enum v4l2_mbus_frame_desc_entry - media bus frame description flags
+ *
+ * @V4L2_MBUS_FRAME_DESC_FL_LEN_MAX:
+ *	Indicates that &struct v4l2_mbus_frame_desc_entry->length field
+ *	specifies maximum data length.
+ * @V4L2_MBUS_FRAME_DESC_FL_BLOB:
+ *	Indicates that the format does not have line offsets, i.e.
+ *	the receiver should use 1D DMA.
+ */
+enum v4l2_mbus_frame_desc_flags {
+	V4L2_MBUS_FRAME_DESC_FL_LEN_MAX	= BIT(0),
+	V4L2_MBUS_FRAME_DESC_FL_BLOB	= BIT(1),
+};
+
+/**
+ * struct v4l2_mbus_frame_desc_entry - media bus frame description structure
+ *
+ * @flags:	bitmask flags, as defined by &enum v4l2_mbus_frame_desc_flags.
+ * @pixelcode:	media bus pixel code, valid if @flags
+ *		%FRAME_DESC_FL_BLOB is not set.
+ * @length:	number of octets per frame, valid if @flags
+ *		%V4L2_MBUS_FRAME_DESC_FL_LEN_MAX is set.
+ */
+struct v4l2_mbus_frame_desc_entry {
+	enum v4l2_mbus_frame_desc_flags flags;
+	u32 pixelcode;
+	u32 length;
+};
+
+#define V4L2_FRAME_DESC_ENTRY_MAX	4
+
+/**
+ * struct v4l2_mbus_frame_desc - media bus data frame description
+ * @entry: frame descriptors array
+ * @num_entries: number of entries in @entry array
+ */
+struct v4l2_mbus_frame_desc {
+	struct v4l2_mbus_frame_desc_entry entry[V4L2_FRAME_DESC_ENTRY_MAX];
+	unsigned short num_entries;
+};
+
+/**
+ * struct v4l2_subdev_video_ops - Callbacks used when v4l device was opened
+ *				  in video mode.
+ *
+ * @s_routing: see s_routing in audio_ops, except this version is for video
+ *	devices.
+ *
+ * @s_crystal_freq: sets the frequency of the crystal used to generate the
+ *	clocks in Hz. An extra flags field allows device specific configuration
+ *	regarding clock frequency dividers, etc. If not used, then set flags
+ *	to 0. If the frequency is not supported, then -EINVAL is returned.
+ *
+ * @g_std: callback for VIDIOC_G_STD() ioctl handler code.
+ *
+ * @s_std: callback for VIDIOC_S_STD() ioctl handler code.
+ *
+ * @s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
+ *	video input devices.
+ *
+ * @g_std_output: get current standard for video OUTPUT devices. This is ignored
+ *	by video input devices.
+ *
+ * @querystd: callback for VIDIOC_QUERYSTD() ioctl handler code.
+ *
+ * @g_tvnorms: get &v4l2_std_id with all standards supported by the video
+ *	CAPTURE device. This is ignored by video output devices.
+ *
+ * @g_tvnorms_output: get v4l2_std_id with all standards supported by the video
+ *	OUTPUT device. This is ignored by video capture devices.
+ *
+ * @g_input_status: get input status. Same as the status field in the
+ *	&struct &v4l2_input
+ *
+ * @s_stream: used to notify the driver that a video stream will start or has
+ *	stopped.
+ *
+ * @g_pixelaspect: callback to return the pixelaspect ratio.
+ *
+ * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL()
+ *		      ioctl handler code.
+ *
+ * @s_frame_interval: callback for VIDIOC_SUBDEV_S_FRAME_INTERVAL()
+ *		      ioctl handler code.
+ *
+ * @s_dv_timings: Set custom dv timings in the sub device. This is used
+ *	when sub device is capable of setting detailed timing information
+ *	in the hardware to generate/detect the video signal.
+ *
+ * @g_dv_timings: Get custom dv timings in the sub device.
+ *
+ * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code.
+ *
+ * @g_mbus_config: get supported mediabus configurations
+ *
+ * @s_mbus_config: set a certain mediabus configuration. This operation is added
+ *	for compatibility with soc-camera drivers and should not be used by new
+ *	software.
+ *
+ * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev
+ *	can adjust @size to a lower value and must not write more data to the
+ *	buffer starting at @data than the original value of @size.
+ */
+struct v4l2_subdev_video_ops {
+	int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config);
+	int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags);
+	int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm);
+	int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm);
+	int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std);
+	int (*g_std_output)(struct v4l2_subdev *sd, v4l2_std_id *std);
+	int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std);
+	int (*g_tvnorms)(struct v4l2_subdev *sd, v4l2_std_id *std);
+	int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std);
+	int (*g_input_status)(struct v4l2_subdev *sd, u32 *status);
+	int (*s_stream)(struct v4l2_subdev *sd, int enable);
+	int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect);
+	int (*g_frame_interval)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_frame_interval *interval);
+	int (*s_frame_interval)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_frame_interval *interval);
+	int (*s_dv_timings)(struct v4l2_subdev *sd,
+			struct v4l2_dv_timings *timings);
+	int (*g_dv_timings)(struct v4l2_subdev *sd,
+			struct v4l2_dv_timings *timings);
+	int (*query_dv_timings)(struct v4l2_subdev *sd,
+			struct v4l2_dv_timings *timings);
+	int (*g_mbus_config)(struct v4l2_subdev *sd,
+			     struct v4l2_mbus_config *cfg);
+	int (*s_mbus_config)(struct v4l2_subdev *sd,
+			     const struct v4l2_mbus_config *cfg);
+	int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf,
+			   unsigned int *size);
+};
+
+/**
+ * struct v4l2_subdev_vbi_ops - Callbacks used when v4l device was opened
+ *				  in video mode via the vbi device node.
+ *
+ *  @decode_vbi_line: video decoders that support sliced VBI need to implement
+ *	this ioctl. Field p of the &struct v4l2_decode_vbi_line is set to the
+ *	start of the VBI data that was generated by the decoder. The driver
+ *	then parses the sliced VBI data and sets the other fields in the
+ *	struct accordingly. The pointer p is updated to point to the start of
+ *	the payload which can be copied verbatim into the data field of the
+ *	&struct v4l2_sliced_vbi_data. If no valid VBI data was found, then the
+ *	type field is set to 0 on return.
+ *
+ * @s_vbi_data: used to generate VBI signals on a video signal.
+ *	&struct v4l2_sliced_vbi_data is filled with the data packets that
+ *	should be output. Note that if you set the line field to 0, then that
+ *	VBI signal is disabled. If no valid VBI data was found, then the type
+ *	field is set to 0 on return.
+ *
+ * @g_vbi_data: used to obtain the sliced VBI packet from a readback register.
+ *	Not all video decoders support this. If no data is available because
+ *	the readback register contains invalid or erroneous data %-EIO is
+ *	returned. Note that you must fill in the 'id' member and the 'field'
+ *	member (to determine whether CC data from the first or second field
+ *	should be obtained).
+ *
+ * @g_sliced_vbi_cap: callback for VIDIOC_G_SLICED_VBI_CAP() ioctl handler
+ *		      code.
+ *
+ * @s_raw_fmt: setup the video encoder/decoder for raw VBI.
+ *
+ * @g_sliced_fmt: retrieve the current sliced VBI settings.
+ *
+ * @s_sliced_fmt: setup the sliced VBI settings.
+ */
+struct v4l2_subdev_vbi_ops {
+	int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line);
+	int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data);
+	int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data);
+	int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap);
+	int (*s_raw_fmt)(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
+	int (*g_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
+	int (*s_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
+};
+
+/**
+ * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations
+ * @g_skip_top_lines: number of lines at the top of the image to be skipped.
+ *		      This is needed for some sensors, which always corrupt
+ *		      several top lines of the output image, or which send their
+ *		      metadata in them.
+ * @g_skip_frames: number of frames to skip at stream start. This is needed for
+ *		   buggy sensors that generate faulty frames when they are
+ *		   turned on.
+ */
+struct v4l2_subdev_sensor_ops {
+	int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines);
+	int (*g_skip_frames)(struct v4l2_subdev *sd, u32 *frames);
+};
+
+/**
+ * enum v4l2_subdev_ir_mode- describes the type of IR supported
+ *
+ * @V4L2_SUBDEV_IR_MODE_PULSE_WIDTH: IR uses struct ir_raw_event records
+ */
+enum v4l2_subdev_ir_mode {
+	V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
+};
+
+/**
+ * struct v4l2_subdev_ir_parameters - Parameters for IR TX or TX
+ *
+ * @bytes_per_data_element: bytes per data element of data in read or
+ *	write call.
+ * @mode: IR mode as defined by &enum v4l2_subdev_ir_mode.
+ * @enable: device is active if true
+ * @interrupt_enable: IR interrupts are enabled if true
+ * @shutdown: if true: set hardware to low/no power, false: normal mode
+ *
+ * @modulation: if true, it uses carrier, if false: baseband
+ * @max_pulse_width:  maximum pulse width in ns, valid only for baseband signal
+ * @carrier_freq: carrier frequency in Hz, valid only for modulated signal
+ * @duty_cycle: duty cycle percentage, valid only for modulated signal
+ * @invert_level: invert signal level
+ *
+ * @invert_carrier_sense: Send 0/space as a carrier burst. used only in TX.
+ *
+ * @noise_filter_min_width: min time of a valid pulse, in ns. Used only for RX.
+ * @carrier_range_lower: Lower carrier range, in Hz, valid only for modulated
+ *	signal. Used only for RX.
+ * @carrier_range_upper: Upper carrier range, in Hz, valid only for modulated
+ *	signal. Used only for RX.
+ * @resolution: The receive resolution, in ns . Used only for RX.
+ */
+struct v4l2_subdev_ir_parameters {
+	unsigned int bytes_per_data_element;
+	enum v4l2_subdev_ir_mode mode;
+
+	bool enable;
+	bool interrupt_enable;
+	bool shutdown;
+
+	bool modulation;
+	u32 max_pulse_width;
+	unsigned int carrier_freq;
+	unsigned int duty_cycle;
+	bool invert_level;
+
+	/* Tx only */
+	bool invert_carrier_sense;
+
+	/* Rx only */
+	u32 noise_filter_min_width;
+	unsigned int carrier_range_lower;
+	unsigned int carrier_range_upper;
+	u32 resolution;
+};
+
+/**
+ * struct v4l2_subdev_ir_ops - operations for IR subdevices
+ *
+ * @rx_read: Reads received codes or pulse width data.
+ *	The semantics are similar to a non-blocking read() call.
+ * @rx_g_parameters: Get the current operating parameters and state of the
+ *	the IR receiver.
+ * @rx_s_parameters: Set the current operating parameters and state of the
+ *	the IR receiver.  It is recommended to call
+ *	[rt]x_g_parameters first to fill out the current state, and only change
+ *	the fields that need to be changed.  Upon return, the actual device
+ *	operating parameters and state will be returned.  Note that hardware
+ *	limitations may prevent the actual settings from matching the requested
+ *	settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
+ *	was requested.  An exception is when the shutdown parameter is true.
+ *	The last used operational parameters will be returned, but the actual
+ *	state of the hardware be different to minimize power consumption and
+ *	processing when shutdown is true.
+ *
+ * @tx_write: Writes codes or pulse width data for transmission.
+ *	The semantics are similar to a non-blocking write() call.
+ * @tx_g_parameters: Get the current operating parameters and state of the
+ *	the IR transmitter.
+ * @tx_s_parameters: Set the current operating parameters and state of the
+ *	the IR transmitter.  It is recommended to call
+ *	[rt]x_g_parameters first to fill out the current state, and only change
+ *	the fields that need to be changed.  Upon return, the actual device
+ *	operating parameters and state will be returned.  Note that hardware
+ *	limitations may prevent the actual settings from matching the requested
+ *	settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
+ *	was requested.  An exception is when the shutdown parameter is true.
+ *	The last used operational parameters will be returned, but the actual
+ *	state of the hardware be different to minimize power consumption and
+ *	processing when shutdown is true.
+ */
+struct v4l2_subdev_ir_ops {
+	/* Receiver */
+	int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count,
+				ssize_t *num);
+
+	int (*rx_g_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+	int (*rx_s_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+
+	/* Transmitter */
+	int (*tx_write)(struct v4l2_subdev *sd, u8 *buf, size_t count,
+				ssize_t *num);
+
+	int (*tx_g_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+	int (*tx_s_parameters)(struct v4l2_subdev *sd,
+				struct v4l2_subdev_ir_parameters *params);
+};
+
+/**
+ * struct v4l2_subdev_pad_config - Used for storing subdev pad information.
+ *
+ * @try_fmt: &struct v4l2_mbus_framefmt
+ * @try_crop: &struct v4l2_rect to be used for crop
+ * @try_compose: &struct v4l2_rect to be used for compose
+ *
+ * This structure only needs to be passed to the pad op if the 'which' field
+ * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For
+ * %V4L2_SUBDEV_FORMAT_ACTIVE it is safe to pass %NULL.
+ */
+struct v4l2_subdev_pad_config {
+	struct v4l2_mbus_framefmt try_fmt;
+	struct v4l2_rect try_crop;
+	struct v4l2_rect try_compose;
+};
+
+/**
+ * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
+ *
+ * @init_cfg: initialize the pad config to default values
+ * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE() ioctl handler
+ *		    code.
+ * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE() ioctl handler
+ *		     code.
+ *
+ * @enum_frame_interval: callback for VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL() ioctl
+ *			 handler code.
+ *
+ * @get_fmt: callback for VIDIOC_SUBDEV_G_FMT() ioctl handler code.
+ *
+ * @set_fmt: callback for VIDIOC_SUBDEV_S_FMT() ioctl handler code.
+ *
+ * @get_selection: callback for VIDIOC_SUBDEV_G_SELECTION() ioctl handler code.
+ *
+ * @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION() ioctl handler code.
+ *
+ * @get_edid: callback for VIDIOC_SUBDEV_G_EDID() ioctl handler code.
+ *
+ * @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code.
+ *
+ * @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler
+ *		    code.
+ *
+ * @enum_dv_timings: callback for VIDIOC_SUBDEV_ENUM_DV_TIMINGS() ioctl handler
+ *		     code.
+ *
+ * @link_validate: used by the media controller code to check if the links
+ *		   that belongs to a pipeline can be used for stream.
+ *
+ * @get_frame_desc: get the current low level media bus frame parameters.
+ *
+ * @set_frame_desc: set the low level media bus frame parameters, @fd array
+ *                  may be adjusted by the subdev driver to device capabilities.
+ */
+struct v4l2_subdev_pad_ops {
+	int (*init_cfg)(struct v4l2_subdev *sd,
+			struct v4l2_subdev_pad_config *cfg);
+	int (*enum_mbus_code)(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_mbus_code_enum *code);
+	int (*enum_frame_size)(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_frame_size_enum *fse);
+	int (*enum_frame_interval)(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_frame_interval_enum *fie);
+	int (*get_fmt)(struct v4l2_subdev *sd,
+		       struct v4l2_subdev_pad_config *cfg,
+		       struct v4l2_subdev_format *format);
+	int (*set_fmt)(struct v4l2_subdev *sd,
+		       struct v4l2_subdev_pad_config *cfg,
+		       struct v4l2_subdev_format *format);
+	int (*get_selection)(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_selection *sel);
+	int (*set_selection)(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_selection *sel);
+	int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
+	int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
+	int (*dv_timings_cap)(struct v4l2_subdev *sd,
+			      struct v4l2_dv_timings_cap *cap);
+	int (*enum_dv_timings)(struct v4l2_subdev *sd,
+			       struct v4l2_enum_dv_timings *timings);
+#ifdef CONFIG_MEDIA_CONTROLLER
+	int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
+			     struct v4l2_subdev_format *source_fmt,
+			     struct v4l2_subdev_format *sink_fmt);
+#endif /* CONFIG_MEDIA_CONTROLLER */
+	int (*get_frame_desc)(struct v4l2_subdev *sd, unsigned int pad,
+			      struct v4l2_mbus_frame_desc *fd);
+	int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad,
+			      struct v4l2_mbus_frame_desc *fd);
+};
+
+/**
+ * struct v4l2_subdev_ops - Subdev operations
+ *
+ * @core: pointer to &struct v4l2_subdev_core_ops. Can be %NULL
+ * @tuner: pointer to &struct v4l2_subdev_tuner_ops. Can be %NULL
+ * @audio: pointer to &struct v4l2_subdev_audio_ops. Can be %NULL
+ * @video: pointer to &struct v4l2_subdev_video_ops. Can be %NULL
+ * @vbi: pointer to &struct v4l2_subdev_vbi_ops. Can be %NULL
+ * @ir: pointer to &struct v4l2_subdev_ir_ops. Can be %NULL
+ * @sensor: pointer to &struct v4l2_subdev_sensor_ops. Can be %NULL
+ * @pad: pointer to &struct v4l2_subdev_pad_ops. Can be %NULL
+ */
+struct v4l2_subdev_ops {
+	const struct v4l2_subdev_core_ops	*core;
+	const struct v4l2_subdev_tuner_ops	*tuner;
+	const struct v4l2_subdev_audio_ops	*audio;
+	const struct v4l2_subdev_video_ops	*video;
+	const struct v4l2_subdev_vbi_ops	*vbi;
+	const struct v4l2_subdev_ir_ops		*ir;
+	const struct v4l2_subdev_sensor_ops	*sensor;
+	const struct v4l2_subdev_pad_ops	*pad;
+};
+
+/**
+ * struct v4l2_subdev_internal_ops - V4L2 subdev internal ops
+ *
+ * @registered: called when this subdev is registered. When called the v4l2_dev
+ *	field is set to the correct v4l2_device.
+ *
+ * @unregistered: called when this subdev is unregistered. When called the
+ *	v4l2_dev field is still set to the correct v4l2_device.
+ *
+ * @open: called when the subdev device node is opened by an application.
+ *
+ * @close: called when the subdev device node is closed.
+ *
+ * .. note::
+ *	Never call this from drivers, only the v4l2 framework can call
+ *	these ops.
+ */
+struct v4l2_subdev_internal_ops {
+	int (*registered)(struct v4l2_subdev *sd);
+	void (*unregistered)(struct v4l2_subdev *sd);
+	int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
+	int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
+};
+
+#define V4L2_SUBDEV_NAME_SIZE 32
+
+/* Set this flag if this subdev is a i2c device. */
+#define V4L2_SUBDEV_FL_IS_I2C			(1U << 0)
+/* Set this flag if this subdev is a spi device. */
+#define V4L2_SUBDEV_FL_IS_SPI			(1U << 1)
+/* Set this flag if this subdev needs a device node. */
+#define V4L2_SUBDEV_FL_HAS_DEVNODE		(1U << 2)
+/* Set this flag if this subdev generates events. */
+#define V4L2_SUBDEV_FL_HAS_EVENTS		(1U << 3)
+
+struct regulator_bulk_data;
+
+/**
+ * struct v4l2_subdev_platform_data - regulators config struct
+ *
+ * @regulators: Optional regulators used to power on/off the subdevice
+ * @num_regulators: Number of regululators
+ * @host_priv: Per-subdevice data, specific for a certain video host device
+ */
+struct v4l2_subdev_platform_data {
+	struct regulator_bulk_data *regulators;
+	int num_regulators;
+
+	void *host_priv;
+};
+
+/**
+ * struct v4l2_subdev - describes a V4L2 sub-device
+ *
+ * @entity: pointer to &struct media_entity
+ * @list: List of sub-devices
+ * @owner: The owner is the same as the driver's &struct device owner.
+ * @owner_v4l2_dev: true if the &sd->owner matches the owner of @v4l2_dev->dev
+ *	owner. Initialized by v4l2_device_register_subdev().
+ * @flags: subdev flags. Can be:
+ *   %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device;
+ *   %V4L2_SUBDEV_FL_IS_SPI - Set this flag if this subdev is a spi device;
+ *   %V4L2_SUBDEV_FL_HAS_DEVNODE - Set this flag if this subdev needs a
+ *   device node;
+ *   %V4L2_SUBDEV_FL_HAS_EVENTS -  Set this flag if this subdev generates
+ *   events.
+ *
+ * @v4l2_dev: pointer to struct &v4l2_device
+ * @ops: pointer to struct &v4l2_subdev_ops
+ * @internal_ops: pointer to struct &v4l2_subdev_internal_ops.
+ *	Never call these internal ops from within a driver!
+ * @ctrl_handler: The control handler of this subdev. May be NULL.
+ * @name: Name of the sub-device. Please notice that the name must be unique.
+ * @grp_id: can be used to group similar subdevs. Value is driver-specific
+ * @dev_priv: pointer to private data
+ * @host_priv: pointer to private data used by the device where the subdev
+ *	is attached.
+ * @devnode: subdev device node
+ * @dev: pointer to the physical device, if any
+ * @fwnode: The fwnode_handle of the subdev, usually the same as
+ *	    either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL).
+ * @async_list: Links this subdev to a global subdev_list or @notifier->done
+ *	list.
+ * @asd: Pointer to respective &struct v4l2_async_subdev.
+ * @notifier: Pointer to the managing notifier.
+ * @subdev_notifier: A sub-device notifier implicitly registered for the sub-
+ *		     device using v4l2_device_register_sensor_subdev().
+ * @pdata: common part of subdevice platform data
+ *
+ * Each instance of a subdev driver should create this struct, either
+ * stand-alone or embedded in a larger struct.
+ *
+ * This structure should be initialized by v4l2_subdev_init() or one of
+ * its variants: v4l2_spi_subdev_init(), v4l2_i2c_subdev_init().
+ */
+struct v4l2_subdev {
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	struct media_entity entity;
+#endif
+	struct list_head list;
+	struct module *owner;
+	bool owner_v4l2_dev;
+	u32 flags;
+	struct v4l2_device *v4l2_dev;
+	const struct v4l2_subdev_ops *ops;
+	const struct v4l2_subdev_internal_ops *internal_ops;
+	struct v4l2_ctrl_handler *ctrl_handler;
+	char name[V4L2_SUBDEV_NAME_SIZE];
+	u32 grp_id;
+	void *dev_priv;
+	void *host_priv;
+	struct video_device *devnode;
+	struct device *dev;
+	struct fwnode_handle *fwnode;
+	struct list_head async_list;
+	struct v4l2_async_subdev *asd;
+	struct v4l2_async_notifier *notifier;
+	struct v4l2_async_notifier *subdev_notifier;
+	struct v4l2_subdev_platform_data *pdata;
+};
+
+
+/**
+ * media_entity_to_v4l2_subdev - Returns a &struct v4l2_subdev from
+ *    the &struct media_entity embedded in it.
+ *
+ * @ent: pointer to &struct media_entity.
+ */
+#define media_entity_to_v4l2_subdev(ent)				\
+({									\
+	typeof(ent) __me_sd_ent = (ent);				\
+									\
+	__me_sd_ent ?							\
+		container_of(__me_sd_ent, struct v4l2_subdev, entity) :	\
+		NULL;							\
+})
+
+/**
+ * vdev_to_v4l2_subdev - Returns a &struct v4l2_subdev from
+ *	the &struct video_device embedded on it.
+ *
+ * @vdev: pointer to &struct video_device
+ */
+#define vdev_to_v4l2_subdev(vdev) \
+	((struct v4l2_subdev *)video_get_drvdata(vdev))
+
+/**
+ * struct v4l2_subdev_fh - Used for storing subdev information per file handle
+ *
+ * @vfh: pointer to &struct v4l2_fh
+ * @pad: pointer to &struct v4l2_subdev_pad_config
+ */
+struct v4l2_subdev_fh {
+	struct v4l2_fh vfh;
+#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
+	struct v4l2_subdev_pad_config *pad;
+#endif
+};
+
+/**
+ * to_v4l2_subdev_fh - Returns a &struct v4l2_subdev_fh from
+ *	the &struct v4l2_fh embedded on it.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ */
+#define to_v4l2_subdev_fh(fh)	\
+	container_of(fh, struct v4l2_subdev_fh, vfh)
+
+#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
+
+/**
+ * v4l2_subdev_get_try_format - ancillary routine to call
+ *	&struct v4l2_subdev_pad_config->try_fmt
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @cfg: pointer to &struct v4l2_subdev_pad_config array.
+ * @pad: index of the pad in the @cfg array.
+ */
+static inline struct v4l2_mbus_framefmt
+*v4l2_subdev_get_try_format(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_pad_config *cfg,
+			    unsigned int pad)
+{
+	if (WARN_ON(pad >= sd->entity.num_pads))
+		pad = 0;
+	return &cfg[pad].try_fmt;
+}
+
+/**
+ * v4l2_subdev_get_try_crop - ancillary routine to call
+ *	&struct v4l2_subdev_pad_config->try_crop
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @cfg: pointer to &struct v4l2_subdev_pad_config array.
+ * @pad: index of the pad in the @cfg array.
+ */
+static inline struct v4l2_rect
+*v4l2_subdev_get_try_crop(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  unsigned int pad)
+{
+	if (WARN_ON(pad >= sd->entity.num_pads))
+		pad = 0;
+	return &cfg[pad].try_crop;
+}
+
+/**
+ * v4l2_subdev_get_try_crop - ancillary routine to call
+ *	&struct v4l2_subdev_pad_config->try_compose
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @cfg: pointer to &struct v4l2_subdev_pad_config array.
+ * @pad: index of the pad in the @cfg array.
+ */
+static inline struct v4l2_rect
+*v4l2_subdev_get_try_compose(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     unsigned int pad)
+{
+	if (WARN_ON(pad >= sd->entity.num_pads))
+		pad = 0;
+	return &cfg[pad].try_compose;
+}
+#endif
+
+extern const struct v4l2_file_operations v4l2_subdev_fops;
+
+/**
+ * v4l2_set_subdevdata - Sets V4L2 dev private device data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @p: pointer to the private device data to be stored.
+ */
+static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)
+{
+	sd->dev_priv = p;
+}
+
+/**
+ * v4l2_get_subdevdata - Gets V4L2 dev private device data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * Returns the pointer to the private device data to be stored.
+ */
+static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd)
+{
+	return sd->dev_priv;
+}
+
+/**
+ * v4l2_set_subdev_hostdata - Sets V4L2 dev private host data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @p: pointer to the private data to be stored.
+ */
+static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p)
+{
+	sd->host_priv = p;
+}
+
+/**
+ * v4l2_get_subdev_hostdata - Gets V4L2 dev private data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * Returns the pointer to the private host data to be stored.
+ */
+static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
+{
+	return sd->host_priv;
+}
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+
+/**
+ * v4l2_subdev_link_validate_default - validates a media link
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @link: pointer to &struct media_link
+ * @source_fmt: pointer to &struct v4l2_subdev_format
+ * @sink_fmt: pointer to &struct v4l2_subdev_format
+ *
+ * This function ensures that width, height and the media bus pixel
+ * code are equal on both source and sink of the link.
+ */
+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);
+
+/**
+ * v4l2_subdev_link_validate - validates a media link
+ *
+ * @link: pointer to &struct media_link
+ *
+ * This function calls the subdev's link_validate ops to validate
+ * if a media link is valid for streaming. It also internally
+ * calls v4l2_subdev_link_validate_default() to ensure that
+ * width, height and the media bus pixel code are equal on both
+ * source and sink of the link.
+ */
+int v4l2_subdev_link_validate(struct media_link *link);
+
+/**
+ * v4l2_subdev_alloc_pad_config - Allocates memory for pad config
+ *
+ * @sd: pointer to struct v4l2_subdev
+ */
+struct
+v4l2_subdev_pad_config *v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd);
+
+/**
+ * v4l2_subdev_free_pad_config - Frees memory allocated by
+ *	v4l2_subdev_alloc_pad_config().
+ *
+ * @cfg: pointer to &struct v4l2_subdev_pad_config
+ */
+void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg);
+#endif /* CONFIG_MEDIA_CONTROLLER */
+
+/**
+ * v4l2_subdev_init - initializes the sub-device struct
+ *
+ * @sd: pointer to the &struct v4l2_subdev to be initialized
+ * @ops: pointer to &struct v4l2_subdev_ops.
+ */
+void v4l2_subdev_init(struct v4l2_subdev *sd,
+		      const struct v4l2_subdev_ops *ops);
+
+/**
+ * v4l2_subdev_call - call an operation of a v4l2_subdev.
+ *
+ * @sd: pointer to the &struct v4l2_subdev
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of callbacks functions.
+ * @f: callback function that will be called if @cond matches.
+ *     The callback functions are defined in groups, according to
+ *     each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Example: err = v4l2_subdev_call(sd, video, s_std, norm);
+ */
+#define v4l2_subdev_call(sd, o, f, args...)				\
+	({								\
+		int __result;						\
+		if (!(sd))						\
+			__result = -ENODEV;				\
+		else if (!((sd)->ops->o && (sd)->ops->o->f))		\
+			__result = -ENOIOCTLCMD;			\
+		else							\
+			__result = (sd)->ops->o->f((sd), ##args);	\
+		__result;						\
+	})
+
+/**
+ * v4l2_subdev_has_op - Checks if a subdev defines a certain operation.
+ *
+ * @sd: pointer to the &struct v4l2_subdev
+ * @o: The group of callback functions in &struct v4l2_subdev_ops
+ * which @f is a part of.
+ * @f: callback function to be checked for its existence.
+ */
+#define v4l2_subdev_has_op(sd, o, f) \
+	((sd)->ops->o && (sd)->ops->o->f)
+
+/**
+ * v4l2_subdev_notify_event() - Delivers event notification for subdevice
+ * @sd: The subdev for which to deliver the event
+ * @ev: The event to deliver
+ *
+ * Will deliver the specified event to all userspace event listeners which are
+ * subscribed to the v42l subdev event queue as well as to the bridge driver
+ * using the notify callback. The notification type for the notify callback
+ * will be %V4L2_DEVICE_NOTIFY_EVENT.
+ */
+void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
+			      const struct v4l2_event *ev);
+
+#endif
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
new file mode 100644
index 0000000..60a664f
--- /dev/null
+++ b/include/media/videobuf-core.h
@@ -0,0 +1,236 @@
+/*
+ * generic helper functions for handling video4linux capture buffers
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org>
+ *
+ * Highly based on video-buf written originally by:
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
+ * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org>
+ * (c) 2006 Ted Walther and John Sokol
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+
+#ifndef _VIDEOBUF_CORE_H
+#define _VIDEOBUF_CORE_H
+
+#include <linux/poll.h>
+#include <linux/videodev2.h>
+
+#define UNSET (-1U)
+
+
+struct videobuf_buffer;
+struct videobuf_queue;
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * A small set of helper functions to manage video4linux buffers.
+ *
+ * struct videobuf_buffer holds the data structures used by the helper
+ * functions, additionally some commonly used fields for v4l buffers
+ * (width, height, lists, waitqueue) are in there.  That struct should
+ * be used as first element in the drivers buffer struct.
+ *
+ * about the mmap helpers (videobuf_mmap_*):
+ *
+ * The mmaper function allows to map any subset of contiguous buffers.
+ * This includes one mmap() call for all buffers (which the original
+ * video4linux API uses) as well as one mmap() for every single buffer
+ * (which v4l2 uses).
+ *
+ * If there is a valid mapping for a buffer, buffer->baddr/bsize holds
+ * userspace address + size which can be feeded into the
+ * videobuf_dma_init_user function listed above.
+ *
+ */
+
+struct videobuf_mapping {
+	unsigned int count;
+	struct videobuf_queue *q;
+};
+
+enum videobuf_state {
+	VIDEOBUF_NEEDS_INIT = 0,
+	VIDEOBUF_PREPARED   = 1,
+	VIDEOBUF_QUEUED     = 2,
+	VIDEOBUF_ACTIVE     = 3,
+	VIDEOBUF_DONE       = 4,
+	VIDEOBUF_ERROR      = 5,
+	VIDEOBUF_IDLE       = 6,
+};
+
+struct videobuf_buffer {
+	unsigned int            i;
+	u32                     magic;
+
+	/* info about the buffer */
+	unsigned int            width;
+	unsigned int            height;
+	unsigned int            bytesperline; /* use only if != 0 */
+	unsigned long           size;
+	enum v4l2_field         field;
+	enum videobuf_state     state;
+	struct list_head        stream;  /* QBUF/DQBUF list */
+
+	/* touched by irq handler */
+	struct list_head        queue;
+	wait_queue_head_t       done;
+	unsigned int            field_count;
+	struct timeval          ts;
+
+	/* Memory type */
+	enum v4l2_memory        memory;
+
+	/* buffer size */
+	size_t                  bsize;
+
+	/* buffer offset (mmap + overlay) */
+	size_t                  boff;
+
+	/* buffer addr (userland ptr!) */
+	unsigned long           baddr;
+
+	/* for mmap'ed buffers */
+	struct videobuf_mapping *map;
+
+	/* Private pointer to allow specific methods to store their data */
+	int			privsize;
+	void                    *priv;
+};
+
+struct videobuf_queue_ops {
+	int (*buf_setup)(struct videobuf_queue *q,
+			 unsigned int *count, unsigned int *size);
+	int (*buf_prepare)(struct videobuf_queue *q,
+			   struct videobuf_buffer *vb,
+			   enum v4l2_field field);
+	void (*buf_queue)(struct videobuf_queue *q,
+			  struct videobuf_buffer *vb);
+	void (*buf_release)(struct videobuf_queue *q,
+			    struct videobuf_buffer *vb);
+};
+
+#define MAGIC_QTYPE_OPS	0x12261003
+
+/* Helper operations - device type dependent */
+struct videobuf_qtype_ops {
+	u32                     magic;
+
+	struct videobuf_buffer *(*alloc_vb)(size_t size);
+	void *(*vaddr)		(struct videobuf_buffer *buf);
+	int (*iolock)		(struct videobuf_queue *q,
+				 struct videobuf_buffer *vb,
+				 struct v4l2_framebuffer *fbuf);
+	int (*sync)		(struct videobuf_queue *q,
+				 struct videobuf_buffer *buf);
+	int (*mmap_mapper)	(struct videobuf_queue *q,
+				 struct videobuf_buffer *buf,
+				 struct vm_area_struct *vma);
+};
+
+struct videobuf_queue {
+	struct mutex               vb_lock;
+	struct mutex               *ext_lock;
+	spinlock_t                 *irqlock;
+	struct device		   *dev;
+
+	wait_queue_head_t	   wait; /* wait if queue is empty */
+
+	enum v4l2_buf_type         type;
+	unsigned int               msize;
+	enum v4l2_field            field;
+	enum v4l2_field            last;   /* for field=V4L2_FIELD_ALTERNATE */
+	struct videobuf_buffer     *bufs[VIDEO_MAX_FRAME];
+	const struct videobuf_queue_ops  *ops;
+	struct videobuf_qtype_ops  *int_ops;
+
+	unsigned int               streaming:1;
+	unsigned int               reading:1;
+
+	/* capture via mmap() + ioctl(QBUF/DQBUF) */
+	struct list_head           stream;
+
+	/* capture via read() */
+	unsigned int               read_off;
+	struct videobuf_buffer     *read_buf;
+
+	/* driver private data */
+	void                       *priv_data;
+};
+
+static inline void videobuf_queue_lock(struct videobuf_queue *q)
+{
+	if (!q->ext_lock)
+		mutex_lock(&q->vb_lock);
+}
+
+static inline void videobuf_queue_unlock(struct videobuf_queue *q)
+{
+	if (!q->ext_lock)
+		mutex_unlock(&q->vb_lock);
+}
+
+int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb,
+		int non_blocking, int intr);
+int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
+		struct v4l2_framebuffer *fbuf);
+
+struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q);
+
+/* Used on videobuf-dvb */
+void *videobuf_queue_to_vaddr(struct videobuf_queue *q,
+			      struct videobuf_buffer *buf);
+
+void videobuf_queue_core_init(struct videobuf_queue *q,
+			 const struct videobuf_queue_ops *ops,
+			 struct device *dev,
+			 spinlock_t *irqlock,
+			 enum v4l2_buf_type type,
+			 enum v4l2_field field,
+			 unsigned int msize,
+			 void *priv,
+			 struct videobuf_qtype_ops *int_ops,
+			 struct mutex *ext_lock);
+int  videobuf_queue_is_busy(struct videobuf_queue *q);
+void videobuf_queue_cancel(struct videobuf_queue *q);
+
+enum v4l2_field videobuf_next_field(struct videobuf_queue *q);
+int videobuf_reqbufs(struct videobuf_queue *q,
+		     struct v4l2_requestbuffers *req);
+int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
+int videobuf_qbuf(struct videobuf_queue *q,
+		  struct v4l2_buffer *b);
+int videobuf_dqbuf(struct videobuf_queue *q,
+		   struct v4l2_buffer *b, int nonblocking);
+int videobuf_streamon(struct videobuf_queue *q);
+int videobuf_streamoff(struct videobuf_queue *q);
+
+void videobuf_stop(struct videobuf_queue *q);
+
+int videobuf_read_start(struct videobuf_queue *q);
+void videobuf_read_stop(struct videobuf_queue *q);
+ssize_t videobuf_read_stream(struct videobuf_queue *q,
+			     char __user *data, size_t count, loff_t *ppos,
+			     int vbihack, int nonblocking);
+ssize_t videobuf_read_one(struct videobuf_queue *q,
+			  char __user *data, size_t count, loff_t *ppos,
+			  int nonblocking);
+__poll_t videobuf_poll_stream(struct file *file,
+				  struct videobuf_queue *q,
+				  poll_table *wait);
+
+int videobuf_mmap_setup(struct videobuf_queue *q,
+			unsigned int bcount, unsigned int bsize,
+			enum v4l2_memory memory);
+int __videobuf_mmap_setup(struct videobuf_queue *q,
+			unsigned int bcount, unsigned int bsize,
+			enum v4l2_memory memory);
+int videobuf_mmap_free(struct videobuf_queue *q);
+int videobuf_mmap_mapper(struct videobuf_queue *q,
+			 struct vm_area_struct *vma);
+
+#endif
diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h
new file mode 100644
index 0000000..f0ed825
--- /dev/null
+++ b/include/media/videobuf-dma-contig.h
@@ -0,0 +1,33 @@
+/*
+ * helper functions for physically contiguous capture buffers
+ *
+ * The functions support hardware lacking scatter gather support
+ * (i.e. the buffers must be linear in physical memory)
+ *
+ * Copyright (c) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+#ifndef _VIDEOBUF_DMA_CONTIG_H
+#define _VIDEOBUF_DMA_CONTIG_H
+
+#include <linux/dma-mapping.h>
+#include <media/videobuf-core.h>
+
+void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
+				    const struct videobuf_queue_ops *ops,
+				    struct device *dev,
+				    spinlock_t *irqlock,
+				    enum v4l2_buf_type type,
+				    enum v4l2_field field,
+				    unsigned int msize,
+				    void *priv,
+				    struct mutex *ext_lock);
+
+dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
+void videobuf_dma_contig_free(struct videobuf_queue *q,
+			      struct videobuf_buffer *buf);
+
+#endif /* _VIDEOBUF_DMA_CONTIG_H */
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
new file mode 100644
index 0000000..01bd142
--- /dev/null
+++ b/include/media/videobuf-dma-sg.h
@@ -0,0 +1,105 @@
+/*
+ * helper functions for SG DMA video4linux capture buffers
+ *
+ * The functions expect the hardware being able to scatter gather
+ * (i.e. the buffers are not linear in physical memory, but fragmented
+ * into PAGE_SIZE chunks).  They also assume the driver does not need
+ * to touch the video data.
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org>
+ *
+ * Highly based on video-buf written originally by:
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
+ * (c) 2006 Mauro Carvalho Chehab, <mchehab@kernel.org>
+ * (c) 2006 Ted Walther and John Sokol
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+#ifndef _VIDEOBUF_DMA_SG_H
+#define _VIDEOBUF_DMA_SG_H
+
+#include <media/videobuf-core.h>
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * A small set of helper functions to manage buffers (both userland
+ * and kernel) for DMA.
+ *
+ * videobuf_dma_init_*()
+ *	creates a buffer.  The userland version takes a userspace
+ *	pointer + length.  The kernel version just wants the size and
+ *	does memory allocation too using vmalloc_32().
+ *
+ * videobuf_dma_*()
+ *	see Documentation/DMA-API-HOWTO.txt, these functions to
+ *	basically the same.  The map function does also build a
+ *	scatterlist for the buffer (and unmap frees it ...)
+ *
+ * videobuf_dma_free()
+ *	no comment ...
+ *
+ */
+
+struct videobuf_dmabuf {
+	u32                 magic;
+
+	/* for userland buffer */
+	int                 offset;
+	size_t		    size;
+	struct page         **pages;
+
+	/* for kernel buffers */
+	void                *vaddr;
+	struct page         **vaddr_pages;
+	dma_addr_t          *dma_addr;
+	struct device       *dev;
+
+	/* for overlay buffers (pci-pci dma) */
+	dma_addr_t          bus_addr;
+
+	/* common */
+	struct scatterlist  *sglist;
+	int                 sglen;
+	int                 nr_pages;
+	int                 direction;
+};
+
+struct videobuf_dma_sg_memory {
+	u32                 magic;
+
+	/* for mmap'ed buffers */
+	struct videobuf_dmabuf  dma;
+};
+
+/*
+ * Scatter-gather DMA buffer API.
+ *
+ * These functions provide a simple way to create a page list and a
+ * scatter-gather list from a kernel, userspace of physical address and map the
+ * memory for DMA operation.
+ *
+ * Despite the name, this is totally unrelated to videobuf, except that
+ * videobuf-dma-sg uses the same API internally.
+ */
+int videobuf_dma_free(struct videobuf_dmabuf *dma);
+
+int videobuf_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma);
+struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
+
+void *videobuf_sg_alloc(size_t size);
+
+void videobuf_queue_sg_init(struct videobuf_queue *q,
+			 const struct videobuf_queue_ops *ops,
+			 struct device *dev,
+			 spinlock_t *irqlock,
+			 enum v4l2_buf_type type,
+			 enum v4l2_field field,
+			 unsigned int msize,
+			 void *priv,
+			 struct mutex *ext_lock);
+
+#endif /* _VIDEOBUF_DMA_SG_H */
+
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
new file mode 100644
index 0000000..36c6a4a
--- /dev/null
+++ b/include/media/videobuf-vmalloc.h
@@ -0,0 +1,46 @@
+/*
+ * helper functions for vmalloc capture buffers
+ *
+ * The functions expect the hardware being able to scatter gather
+ * (i.e. the buffers are not linear in physical memory, but fragmented
+ * into PAGE_SIZE chunks).  They also assume the driver does not need
+ * to touch the video data.
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+#ifndef _VIDEOBUF_VMALLOC_H
+#define _VIDEOBUF_VMALLOC_H
+
+#include <media/videobuf-core.h>
+
+/* --------------------------------------------------------------------- */
+
+struct videobuf_vmalloc_memory {
+	u32                 magic;
+
+	void                *vaddr;
+
+	/* remap_vmalloc_range seems to need to run
+	 * after mmap() on some cases */
+	struct vm_area_struct *vma;
+};
+
+void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
+			 const struct videobuf_queue_ops *ops,
+			 struct device *dev,
+			 spinlock_t *irqlock,
+			 enum v4l2_buf_type type,
+			 enum v4l2_field field,
+			 unsigned int msize,
+			 void *priv,
+			 struct mutex *ext_lock);
+
+void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
+
+void videobuf_vmalloc_free(struct videobuf_buffer *buf);
+
+#endif
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
new file mode 100644
index 0000000..f6818f7
--- /dev/null
+++ b/include/media/videobuf2-core.h
@@ -0,0 +1,1146 @@
+/*
+ * videobuf2-core.h - Video Buffer 2 Core Framework
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak <pawel@osciak.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+#ifndef _MEDIA_VIDEOBUF2_CORE_H
+#define _MEDIA_VIDEOBUF2_CORE_H
+
+#include <linux/mm_types.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/dma-buf.h>
+#include <linux/bitops.h>
+
+#define VB2_MAX_FRAME	(32)
+#define VB2_MAX_PLANES	(8)
+
+/**
+ * enum vb2_memory - type of memory model used to make the buffers visible
+ *	on userspace.
+ *
+ * @VB2_MEMORY_UNKNOWN:	Buffer status is unknown or it is not used yet on
+ *			userspace.
+ * @VB2_MEMORY_MMAP:	The buffers are allocated by the Kernel and it is
+ *			memory mapped via mmap() ioctl. This model is
+ *			also used when the user is using the buffers via
+ *			read() or write() system calls.
+ * @VB2_MEMORY_USERPTR:	The buffers was allocated in userspace and it is
+ *			memory mapped via mmap() ioctl.
+ * @VB2_MEMORY_DMABUF:	The buffers are passed to userspace via DMA buffer.
+ */
+enum vb2_memory {
+	VB2_MEMORY_UNKNOWN	= 0,
+	VB2_MEMORY_MMAP		= 1,
+	VB2_MEMORY_USERPTR	= 2,
+	VB2_MEMORY_DMABUF	= 4,
+};
+
+struct vb2_fileio_data;
+struct vb2_threadio_data;
+
+/**
+ * struct vb2_mem_ops - memory handling/memory allocator operations.
+ * @alloc:	allocate video memory and, optionally, allocator private data,
+ *		return ERR_PTR() on failure or a pointer to allocator private,
+ *		per-buffer data on success; the returned private structure
+ *		will then be passed as @buf_priv argument to other ops in this
+ *		structure. Additional gfp_flags to use when allocating the
+ *		are also passed to this operation. These flags are from the
+ *		gfp_flags field of vb2_queue.
+ * @put:	inform the allocator that the buffer will no longer be used;
+ *		usually will result in the allocator freeing the buffer (if
+ *		no other users of this buffer are present); the @buf_priv
+ *		argument is the allocator private per-buffer structure
+ *		previously returned from the alloc callback.
+ * @get_dmabuf: acquire userspace memory for a hardware operation; used for
+ *		 DMABUF memory types.
+ * @get_userptr: acquire userspace memory for a hardware operation; used for
+ *		 USERPTR memory types; vaddr is the address passed to the
+ *		 videobuf layer when queuing a video buffer of USERPTR type;
+ *		 should return an allocator private per-buffer structure
+ *		 associated with the buffer on success, ERR_PTR() on failure;
+ *		 the returned private structure will then be passed as @buf_priv
+ *		 argument to other ops in this structure.
+ * @put_userptr: inform the allocator that a USERPTR buffer will no longer
+ *		 be used.
+ * @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation;
+ *		   used for DMABUF memory types; dev is the alloc device
+ *		   dbuf is the shared dma_buf; returns ERR_PTR() on failure;
+ *		   allocator private per-buffer structure on success;
+ *		   this needs to be used for further accesses to the buffer.
+ * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF
+ *		   buffer is no longer used; the @buf_priv argument is the
+ *		   allocator private per-buffer structure previously returned
+ *		   from the attach_dmabuf callback.
+ * @map_dmabuf: request for access to the dmabuf from allocator; the allocator
+ *		of dmabuf is informed that this driver is going to use the
+ *		dmabuf.
+ * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
+ *		  that this driver is done using the dmabuf for now.
+ * @prepare:	called every time the buffer is passed from userspace to the
+ *		driver, useful for cache synchronisation, optional.
+ * @finish:	called every time the buffer is passed back from the driver
+ *		to the userspace, also optional.
+ * @vaddr:	return a kernel virtual address to a given memory buffer
+ *		associated with the passed private structure or NULL if no
+ *		such mapping exists.
+ * @cookie:	return allocator specific cookie for a given memory buffer
+ *		associated with the passed private structure or NULL if not
+ *		available.
+ * @num_users:	return the current number of users of a memory buffer;
+ *		return 1 if the videobuf layer (or actually the driver using
+ *		it) is the only user.
+ * @mmap:	setup a userspace mapping for a given memory buffer under
+ *		the provided virtual memory region.
+ *
+ * Those operations are used by the videobuf2 core to implement the memory
+ * handling/memory allocators for each type of supported streaming I/O method.
+ *
+ * .. note::
+ *    #) Required ops for USERPTR types: get_userptr, put_userptr.
+ *
+ *    #) Required ops for MMAP types: alloc, put, num_users, mmap.
+ *
+ *    #) Required ops for read/write access types: alloc, put, num_users, vaddr.
+ *
+ *    #) Required ops for DMABUF types: attach_dmabuf, detach_dmabuf,
+ *       map_dmabuf, unmap_dmabuf.
+ */
+struct vb2_mem_ops {
+	void		*(*alloc)(struct device *dev, unsigned long attrs,
+				  unsigned long size,
+				  enum dma_data_direction dma_dir,
+				  gfp_t gfp_flags);
+	void		(*put)(void *buf_priv);
+	struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags);
+
+	void		*(*get_userptr)(struct device *dev, unsigned long vaddr,
+					unsigned long size,
+					enum dma_data_direction dma_dir);
+	void		(*put_userptr)(void *buf_priv);
+
+	void		(*prepare)(void *buf_priv);
+	void		(*finish)(void *buf_priv);
+
+	void		*(*attach_dmabuf)(struct device *dev,
+					  struct dma_buf *dbuf,
+					  unsigned long size,
+					  enum dma_data_direction dma_dir);
+	void		(*detach_dmabuf)(void *buf_priv);
+	int		(*map_dmabuf)(void *buf_priv);
+	void		(*unmap_dmabuf)(void *buf_priv);
+
+	void		*(*vaddr)(void *buf_priv);
+	void		*(*cookie)(void *buf_priv);
+
+	unsigned int	(*num_users)(void *buf_priv);
+
+	int		(*mmap)(void *buf_priv, struct vm_area_struct *vma);
+};
+
+/**
+ * struct vb2_plane - plane information.
+ * @mem_priv:	private data with this plane.
+ * @dbuf:	dma_buf - shared buffer object.
+ * @dbuf_mapped:	flag to show whether dbuf is mapped or not
+ * @bytesused:	number of bytes occupied by data in the plane (payload).
+ * @length:	size of this plane (NOT the payload) in bytes.
+ * @min_length:	minimum required size of this plane (NOT the payload) in bytes.
+ *		@length is always greater or equal to @min_length.
+ * @m:		Union with memtype-specific data.
+ * @m.offset:	when memory in the associated struct vb2_buffer is
+ *		%VB2_MEMORY_MMAP, equals the offset from the start of
+ *		the device memory for this plane (or is a "cookie" that
+ *		should be passed to mmap() called on the video node).
+ * @m.userptr:	when memory is %VB2_MEMORY_USERPTR, a userspace pointer
+ *		pointing to this plane.
+ * @m.fd:	when memory is %VB2_MEMORY_DMABUF, a userspace file
+ *		descriptor associated with this plane.
+ * @data_offset:	offset in the plane to the start of data; usually 0,
+ *		unless there is a header in front of the data.
+ *
+ * Should contain enough information to be able to cover all the fields
+ * of &struct v4l2_plane at videodev2.h.
+ */
+struct vb2_plane {
+	void			*mem_priv;
+	struct dma_buf		*dbuf;
+	unsigned int		dbuf_mapped;
+	unsigned int		bytesused;
+	unsigned int		length;
+	unsigned int		min_length;
+	union {
+		unsigned int	offset;
+		unsigned long	userptr;
+		int		fd;
+	} m;
+	unsigned int		data_offset;
+};
+
+/**
+ * enum vb2_io_modes - queue access methods.
+ * @VB2_MMAP:		driver supports MMAP with streaming API.
+ * @VB2_USERPTR:	driver supports USERPTR with streaming API.
+ * @VB2_READ:		driver supports read() style access.
+ * @VB2_WRITE:		driver supports write() style access.
+ * @VB2_DMABUF:		driver supports DMABUF with streaming API.
+ */
+enum vb2_io_modes {
+	VB2_MMAP	= BIT(0),
+	VB2_USERPTR	= BIT(1),
+	VB2_READ	= BIT(2),
+	VB2_WRITE	= BIT(3),
+	VB2_DMABUF	= BIT(4),
+};
+
+/**
+ * enum vb2_buffer_state - current video buffer state.
+ * @VB2_BUF_STATE_DEQUEUED:	buffer under userspace control.
+ * @VB2_BUF_STATE_PREPARING:	buffer is being prepared in videobuf.
+ * @VB2_BUF_STATE_PREPARED:	buffer prepared in videobuf and by the driver.
+ * @VB2_BUF_STATE_QUEUED:	buffer queued in videobuf, but not in driver.
+ * @VB2_BUF_STATE_REQUEUEING:	re-queue a buffer to the driver.
+ * @VB2_BUF_STATE_ACTIVE:	buffer queued in driver and possibly used
+ *				in a hardware operation.
+ * @VB2_BUF_STATE_DONE:		buffer returned from driver to videobuf, but
+ *				not yet dequeued to userspace.
+ * @VB2_BUF_STATE_ERROR:	same as above, but the operation on the buffer
+ *				has ended with an error, which will be reported
+ *				to the userspace when it is dequeued.
+ */
+enum vb2_buffer_state {
+	VB2_BUF_STATE_DEQUEUED,
+	VB2_BUF_STATE_PREPARING,
+	VB2_BUF_STATE_PREPARED,
+	VB2_BUF_STATE_QUEUED,
+	VB2_BUF_STATE_REQUEUEING,
+	VB2_BUF_STATE_ACTIVE,
+	VB2_BUF_STATE_DONE,
+	VB2_BUF_STATE_ERROR,
+};
+
+struct vb2_queue;
+
+/**
+ * struct vb2_buffer - represents a video buffer.
+ * @vb2_queue:		pointer to &struct vb2_queue with the queue to
+ *			which this driver belongs.
+ * @index:		id number of the buffer.
+ * @type:		buffer type.
+ * @memory:		the method, in which the actual data is passed.
+ * @num_planes:		number of planes in the buffer
+ *			on an internal driver queue.
+ * @timestamp:		frame timestamp in ns.
+ */
+struct vb2_buffer {
+	struct vb2_queue	*vb2_queue;
+	unsigned int		index;
+	unsigned int		type;
+	unsigned int		memory;
+	unsigned int		num_planes;
+	u64			timestamp;
+
+	/* private: internal use only
+	 *
+	 * state:		current buffer state; do not change
+	 * queued_entry:	entry on the queued buffers list, which holds
+	 *			all buffers queued from userspace
+	 * done_entry:		entry on the list that stores all buffers ready
+	 *			to be dequeued to userspace
+	 * vb2_plane:		per-plane information; do not change
+	 */
+	enum vb2_buffer_state	state;
+
+	struct vb2_plane	planes[VB2_MAX_PLANES];
+	struct list_head	queued_entry;
+	struct list_head	done_entry;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	/*
+	 * Counters for how often these buffer-related ops are
+	 * called. Used to check for unbalanced ops.
+	 */
+	u32		cnt_mem_alloc;
+	u32		cnt_mem_put;
+	u32		cnt_mem_get_dmabuf;
+	u32		cnt_mem_get_userptr;
+	u32		cnt_mem_put_userptr;
+	u32		cnt_mem_prepare;
+	u32		cnt_mem_finish;
+	u32		cnt_mem_attach_dmabuf;
+	u32		cnt_mem_detach_dmabuf;
+	u32		cnt_mem_map_dmabuf;
+	u32		cnt_mem_unmap_dmabuf;
+	u32		cnt_mem_vaddr;
+	u32		cnt_mem_cookie;
+	u32		cnt_mem_num_users;
+	u32		cnt_mem_mmap;
+
+	u32		cnt_buf_init;
+	u32		cnt_buf_prepare;
+	u32		cnt_buf_finish;
+	u32		cnt_buf_cleanup;
+	u32		cnt_buf_queue;
+
+	/* This counts the number of calls to vb2_buffer_done() */
+	u32		cnt_buf_done;
+#endif
+};
+
+/**
+ * struct vb2_ops - driver-specific callbacks.
+ *
+ * These operations are not called from interrupt context except where
+ * mentioned specifically.
+ *
+ * @queue_setup:	called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS()
+ *			handlers before memory allocation. It can be called
+ *			twice: if the original number of requested buffers
+ *			could not be allocated, then it will be called a
+ *			second time with the actually allocated number of
+ *			buffers to verify if that is OK.
+ *			The driver should return the required number of buffers
+ *			in \*num_buffers, the required number of planes per
+ *			buffer in \*num_planes, the size of each plane should be
+ *			set in the sizes\[\] array and optional per-plane
+ *			allocator specific device in the alloc_devs\[\] array.
+ *			When called from VIDIOC_REQBUFS(), \*num_planes == 0,
+ *			the driver has to use the currently configured format to
+ *			determine the plane sizes and \*num_buffers is the total
+ *			number of buffers that are being allocated. When called
+ *			from VIDIOC_CREATE_BUFS(), \*num_planes != 0 and it
+ *			describes the requested number of planes and sizes\[\]
+ *			contains the requested plane sizes. In this case
+ *			\*num_buffers are being allocated additionally to
+ *			q->num_buffers. If either \*num_planes or the requested
+ *			sizes are invalid callback must return %-EINVAL.
+ * @wait_prepare:	release any locks taken while calling vb2 functions;
+ *			it is called before an ioctl needs to wait for a new
+ *			buffer to arrive; required to avoid a deadlock in
+ *			blocking access type.
+ * @wait_finish:	reacquire all locks released in the previous callback;
+ *			required to continue operation after sleeping while
+ *			waiting for a new buffer to arrive.
+ * @buf_init:		called once after allocating a buffer (in MMAP case)
+ *			or after acquiring a new USERPTR buffer; drivers may
+ *			perform additional buffer-related initialization;
+ *			initialization failure (return != 0) will prevent
+ *			queue setup from completing successfully; optional.
+ * @buf_prepare:	called every time the buffer is queued from userspace
+ *			and from the VIDIOC_PREPARE_BUF() ioctl; drivers may
+ *			perform any initialization required before each
+ *			hardware operation in this callback; drivers can
+ *			access/modify the buffer here as it is still synced for
+ *			the CPU; drivers that support VIDIOC_CREATE_BUFS() must
+ *			also validate the buffer size; if an error is returned,
+ *			the buffer will not be queued in driver; optional.
+ * @buf_finish:		called before every dequeue of the buffer back to
+ *			userspace; the buffer is synced for the CPU, so drivers
+ *			can access/modify the buffer contents; drivers may
+ *			perform any operations required before userspace
+ *			accesses the buffer; optional. The buffer state can be
+ *			one of the following: %DONE and %ERROR occur while
+ *			streaming is in progress, and the %PREPARED state occurs
+ *			when the queue has been canceled and all pending
+ *			buffers are being returned to their default %DEQUEUED
+ *			state. Typically you only have to do something if the
+ *			state is %VB2_BUF_STATE_DONE, since in all other cases
+ *			the buffer contents will be ignored anyway.
+ * @buf_cleanup:	called once before the buffer is freed; drivers may
+ *			perform any additional cleanup; optional.
+ * @start_streaming:	called once to enter 'streaming' state; the driver may
+ *			receive buffers with @buf_queue callback
+ *			before @start_streaming is called; the driver gets the
+ *			number of already queued buffers in count parameter;
+ *			driver can return an error if hardware fails, in that
+ *			case all buffers that have been already given by
+ *			the @buf_queue callback are to be returned by the driver
+ *			by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED
+ *			or %VB2_BUF_STATE_REQUEUEING. If you need a minimum
+ *			number of buffers before you can start streaming, then
+ *			set &vb2_queue->min_buffers_needed. If that is non-zero
+ *			then @start_streaming won't be called until at least
+ *			that many buffers have been queued up by userspace.
+ * @stop_streaming:	called when 'streaming' state must be disabled; driver
+ *			should stop any DMA transactions or wait until they
+ *			finish and give back all buffers it got from &buf_queue
+ *			callback by calling vb2_buffer_done() with either
+ *			%VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
+ *			vb2_wait_for_all_buffers() function
+ * @buf_queue:		passes buffer vb to the driver; driver may start
+ *			hardware operation on this buffer; driver should give
+ *			the buffer back by calling vb2_buffer_done() function;
+ *			it is allways called after calling VIDIOC_STREAMON()
+ *			ioctl; might be called before @start_streaming callback
+ *			if user pre-queued buffers before calling
+ *			VIDIOC_STREAMON().
+ */
+struct vb2_ops {
+	int (*queue_setup)(struct vb2_queue *q,
+			   unsigned int *num_buffers, unsigned int *num_planes,
+			   unsigned int sizes[], struct device *alloc_devs[]);
+
+	void (*wait_prepare)(struct vb2_queue *q);
+	void (*wait_finish)(struct vb2_queue *q);
+
+	int (*buf_init)(struct vb2_buffer *vb);
+	int (*buf_prepare)(struct vb2_buffer *vb);
+	void (*buf_finish)(struct vb2_buffer *vb);
+	void (*buf_cleanup)(struct vb2_buffer *vb);
+
+	int (*start_streaming)(struct vb2_queue *q, unsigned int count);
+	void (*stop_streaming)(struct vb2_queue *q);
+
+	void (*buf_queue)(struct vb2_buffer *vb);
+};
+
+/**
+ * struct vb2_buf_ops - driver-specific callbacks.
+ *
+ * @verify_planes_array: Verify that a given user space structure contains
+ *			enough planes for the buffer. This is called
+ *			for each dequeued buffer.
+ * @fill_user_buffer:	given a &vb2_buffer fill in the userspace structure.
+ *			For V4L2 this is a &struct v4l2_buffer.
+ * @fill_vb2_buffer:	given a userspace structure, fill in the &vb2_buffer.
+ *			If the userspace structure is invalid, then this op
+ *			will return an error.
+ * @copy_timestamp:	copy the timestamp from a userspace structure to
+ *			the &struct vb2_buffer.
+ */
+struct vb2_buf_ops {
+	int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
+	void (*fill_user_buffer)(struct vb2_buffer *vb, void *pb);
+	int (*fill_vb2_buffer)(struct vb2_buffer *vb, const void *pb,
+				struct vb2_plane *planes);
+	void (*copy_timestamp)(struct vb2_buffer *vb, const void *pb);
+};
+
+/**
+ * struct vb2_queue - a videobuf queue.
+ *
+ * @type:	private buffer type whose content is defined by the vb2-core
+ *		caller. For example, for V4L2, it should match
+ *		the types defined on &enum v4l2_buf_type.
+ * @io_modes:	supported io methods (see &enum vb2_io_modes).
+ * @alloc_devs:	&struct device memory type/allocator-specific per-plane device
+ * @dev:	device to use for the default allocation context if the driver
+ *		doesn't fill in the @alloc_devs array.
+ * @dma_attrs:	DMA attributes to use for the DMA.
+ * @bidirectional: when this flag is set the DMA direction for the buffers of
+ *		this queue will be overridden with %DMA_BIDIRECTIONAL direction.
+ *		This is useful in cases where the hardware (firmware) writes to
+ *		a buffer which is mapped as read (%DMA_TO_DEVICE), or reads from
+ *		buffer which is mapped for write (%DMA_FROM_DEVICE) in order
+ *		to satisfy some internal hardware restrictions or adds a padding
+ *		needed by the processing algorithm. In case the DMA mapping is
+ *		not bidirectional but the hardware (firmware) trying to access
+ *		the buffer (in the opposite direction) this could lead to an
+ *		IOMMU protection faults.
+ * @fileio_read_once:		report EOF after reading the first buffer
+ * @fileio_write_immediately:	queue buffer after each write() call
+ * @allow_zero_bytesused:	allow bytesused == 0 to be passed to the driver
+ * @quirk_poll_must_check_waiting_for_buffers: Return %EPOLLERR at poll when QBUF
+ *              has not been called. This is a vb1 idiom that has been adopted
+ *              also by vb2.
+ * @lock:	pointer to a mutex that protects the &struct vb2_queue. The
+ *		driver can set this to a mutex to let the v4l2 core serialize
+ *		the queuing ioctls. If the driver wants to handle locking
+ *		itself, then this should be set to NULL. This lock is not used
+ *		by the videobuf2 core API.
+ * @owner:	The filehandle that 'owns' the buffers, i.e. the filehandle
+ *		that called reqbufs, create_buffers or started fileio.
+ *		This field is not used by the videobuf2 core API, but it allows
+ *		drivers to easily associate an owner filehandle with the queue.
+ * @ops:	driver-specific callbacks
+ * @mem_ops:	memory allocator specific callbacks
+ * @buf_ops:	callbacks to deliver buffer information.
+ *		between user-space and kernel-space.
+ * @drv_priv:	driver private data.
+ * @buf_struct_size: size of the driver-specific buffer structure;
+ *		"0" indicates the driver doesn't want to use a custom buffer
+ *		structure type. for example, ``sizeof(struct vb2_v4l2_buffer)``
+ *		will be used for v4l2.
+ * @timestamp_flags: Timestamp flags; ``V4L2_BUF_FLAG_TIMESTAMP_*`` and
+ *		``V4L2_BUF_FLAG_TSTAMP_SRC_*``
+ * @gfp_flags:	additional gfp flags used when allocating the buffers.
+ *		Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
+ *		to force the buffer allocation to a specific memory zone.
+ * @min_buffers_needed: the minimum number of buffers needed before
+ *		@start_streaming can be called. Used when a DMA engine
+ *		cannot be started unless at least this number of buffers
+ *		have been queued into the driver.
+ */
+/*
+ * Private elements (won't appear at the uAPI book):
+ * @mmap_lock:	private mutex used when buffers are allocated/freed/mmapped
+ * @memory:	current memory type used
+ * @dma_dir:	DMA mapping direction.
+ * @bufs:	videobuf buffer structures
+ * @num_buffers: number of allocated/used buffers
+ * @queued_list: list of buffers currently queued from userspace
+ * @queued_count: number of buffers queued and ready for streaming.
+ * @owned_by_drv_count: number of buffers owned by the driver
+ * @done_list:	list of buffers ready to be dequeued to userspace
+ * @done_lock:	lock to protect done_list list
+ * @done_wq:	waitqueue for processes waiting for buffers ready to be dequeued
+ * @streaming:	current streaming state
+ * @start_streaming_called: @start_streaming was called successfully and we
+ *		started streaming.
+ * @error:	a fatal error occurred on the queue
+ * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
+ *		buffers. Only set for capture queues if qbuf has not yet been
+ *		called since poll() needs to return %EPOLLERR in that situation.
+ * @is_multiplanar: set if buffer type is multiplanar
+ * @is_output:	set if buffer type is output
+ * @copy_timestamp: set if vb2-core should set timestamps
+ * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
+ *		last decoded buffer was already dequeued. Set for capture queues
+ *		when a buffer with the %V4L2_BUF_FLAG_LAST is dequeued.
+ * @fileio:	file io emulator internal data, used only if emulator is active
+ * @threadio:	thread io internal data, used only if thread is active
+ */
+struct vb2_queue {
+	unsigned int			type;
+	unsigned int			io_modes;
+	struct device			*dev;
+	unsigned long			dma_attrs;
+	unsigned			bidirectional:1;
+	unsigned			fileio_read_once:1;
+	unsigned			fileio_write_immediately:1;
+	unsigned			allow_zero_bytesused:1;
+	unsigned		   quirk_poll_must_check_waiting_for_buffers:1;
+
+	struct mutex			*lock;
+	void				*owner;
+
+	const struct vb2_ops		*ops;
+	const struct vb2_mem_ops	*mem_ops;
+	const struct vb2_buf_ops	*buf_ops;
+
+	void				*drv_priv;
+	unsigned int			buf_struct_size;
+	u32				timestamp_flags;
+	gfp_t				gfp_flags;
+	u32				min_buffers_needed;
+
+	struct device			*alloc_devs[VB2_MAX_PLANES];
+
+	/* private: internal use only */
+	struct mutex			mmap_lock;
+	unsigned int			memory;
+	enum dma_data_direction		dma_dir;
+	struct vb2_buffer		*bufs[VB2_MAX_FRAME];
+	unsigned int			num_buffers;
+
+	struct list_head		queued_list;
+	unsigned int			queued_count;
+
+	atomic_t			owned_by_drv_count;
+	struct list_head		done_list;
+	spinlock_t			done_lock;
+	wait_queue_head_t		done_wq;
+
+	unsigned int			streaming:1;
+	unsigned int			start_streaming_called:1;
+	unsigned int			error:1;
+	unsigned int			waiting_for_buffers:1;
+	unsigned int			is_multiplanar:1;
+	unsigned int			is_output:1;
+	unsigned int			copy_timestamp:1;
+	unsigned int			last_buffer_dequeued:1;
+
+	struct vb2_fileio_data		*fileio;
+	struct vb2_threadio_data	*threadio;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	/*
+	 * Counters for how often these queue-related ops are
+	 * called. Used to check for unbalanced ops.
+	 */
+	u32				cnt_queue_setup;
+	u32				cnt_wait_prepare;
+	u32				cnt_wait_finish;
+	u32				cnt_start_streaming;
+	u32				cnt_stop_streaming;
+#endif
+};
+
+/**
+ * vb2_plane_vaddr() - Return a kernel virtual address of a given plane.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which the address is to be returned.
+ *
+ * This function returns a kernel virtual address of a given plane if
+ * such a mapping exist, NULL otherwise.
+ */
+void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
+
+/**
+ * vb2_plane_cookie() - Return allocator specific cookie for the given plane.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which the cookie is to be returned.
+ *
+ * This function returns an allocator specific cookie for a given plane if
+ * available, NULL otherwise. The allocator should provide some simple static
+ * inline function, which would convert this cookie to the allocator specific
+ * type that can be used directly by the driver to access the buffer. This can
+ * be for example physical address, pointer to scatter list or IOMMU mapping.
+ */
+void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
+
+/**
+ * vb2_buffer_done() - inform videobuf that an operation on a buffer
+ *	is finished.
+ * @vb:		pointer to &struct vb2_buffer to be used.
+ * @state:	state of the buffer, as defined by &enum vb2_buffer_state.
+ *		Either %VB2_BUF_STATE_DONE if the operation finished
+ *		successfully, %VB2_BUF_STATE_ERROR if the operation finished
+ *		with an error or any of %VB2_BUF_STATE_QUEUED or
+ *		%VB2_BUF_STATE_REQUEUEING if the driver wants to
+ *		requeue buffers (see below).
+ *
+ * This function should be called by the driver after a hardware operation on
+ * a buffer is finished and the buffer may be returned to userspace. The driver
+ * cannot use this buffer anymore until it is queued back to it by videobuf
+ * by the means of &vb2_ops->buf_queue callback. Only buffers previously queued
+ * to the driver by &vb2_ops->buf_queue can be passed to this function.
+ *
+ * While streaming a buffer can only be returned in state DONE or ERROR.
+ * The &vb2_ops->start_streaming op can also return them in case the DMA engine
+ * cannot be started for some reason. In that case the buffers should be
+ * returned with state QUEUED or REQUEUEING to put them back into the queue.
+ *
+ * %VB2_BUF_STATE_REQUEUEING is like %VB2_BUF_STATE_QUEUED, but it also calls
+ * &vb2_ops->buf_queue to queue buffers back to the driver. Note that calling
+ * vb2_buffer_done(..., VB2_BUF_STATE_REQUEUEING) from interrupt context will
+ * result in &vb2_ops->buf_queue being called in interrupt context as well.
+ */
+void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
+
+/**
+ * vb2_discard_done() - discard all buffers marked as DONE.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This function is intended to be used with suspend/resume operations. It
+ * discards all 'done' buffers as they would be too old to be requested after
+ * resume.
+ *
+ * Drivers must stop the hardware and synchronize with interrupt handlers and/or
+ * delayed works before calling this function to make sure no buffer will be
+ * touched by the driver and/or hardware.
+ */
+void vb2_discard_done(struct vb2_queue *q);
+
+/**
+ * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This function will wait until all buffers that have been given to the driver
+ * by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). It
+ * doesn't call &vb2_ops->wait_prepare/&vb2_ops->wait_finish pair.
+ * It is intended to be called with all locks taken, for example from
+ * &vb2_ops->stop_streaming callback.
+ */
+int vb2_wait_for_all_buffers(struct vb2_queue *q);
+
+/**
+ * vb2_core_querybuf() - query video buffer information.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @index:	id number of the buffer.
+ * @pb:		buffer struct passed from userspace.
+ *
+ * Videobuf2 core helper to implement VIDIOC_QUERYBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * The passed buffer should have been verified.
+ *
+ * This function fills the relevant information for the userspace.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
+
+/**
+ * vb2_core_reqbufs() - Initiate streaming.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory:	memory type, as defined by &enum vb2_memory.
+ * @count:	requested buffer count.
+ *
+ * Videobuf2 core helper to implement VIDIOC_REQBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * This function:
+ *
+ * #) verifies streaming parameters passed from the userspace;
+ * #) sets up the queue;
+ * #) negotiates number of buffers and planes per buffer with the driver
+ *    to be used during streaming;
+ * #) allocates internal buffer structures (&struct vb2_buffer), according to
+ *    the agreed parameters;
+ * #) for MMAP memory type, allocates actual video memory, using the
+ *    memory handling/allocation routines provided during queue initialization.
+ *
+ * If req->count is 0, all the memory will be freed instead.
+ *
+ * If the queue has been allocated previously by a previous vb2_core_reqbufs()
+ * call and the queue is not busy, memory will be reallocated.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+		unsigned int *count);
+
+/**
+ * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory: memory type, as defined by &enum vb2_memory.
+ * @count: requested buffer count.
+ * @requested_planes: number of planes requested.
+ * @requested_sizes: array with the size of the planes.
+ *
+ * Videobuf2 core helper to implement VIDIOC_CREATE_BUFS() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
+ * This function:
+ *
+ * #) verifies parameter sanity;
+ * #) calls the &vb2_ops->queue_setup queue operation;
+ * #) performs any necessary memory allocations.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+			 unsigned int *count, unsigned int requested_planes,
+			 const unsigned int requested_sizes[]);
+
+/**
+ * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace
+ *			to the kernel.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @index:	id number of the buffer.
+ * @pb:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
+ *
+ * Videobuf2 core helper to implement VIDIOC_PREPARE_BUF() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
+ * The passed buffer should have been verified.
+ *
+ * This function calls vb2_ops->buf_prepare callback in the driver
+ * (if provided), in which driver-specific buffer initialization can
+ * be performed.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb);
+
+/**
+ * vb2_core_qbuf() - Queue a buffer from userspace
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @index:	id number of the buffer
+ * @pb:		buffer structure passed from userspace to
+ *		v4l2_ioctl_ops->vidioc_qbuf handler in driver
+ *
+ * Videobuf2 core helper to implement VIDIOC_QBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * This function:
+ *
+ * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
+ *    (if provided), in which driver-specific buffer initialization can
+ *    be performed;
+ * #) if streaming is on, queues the buffer in driver by the means of
+ *    &vb2_ops->buf_queue callback for processing.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb);
+
+/**
+ * vb2_core_dqbuf() - Dequeue a buffer to the userspace
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue
+ * @pindex:	pointer to the buffer index. May be NULL
+ * @pb:		buffer structure passed from userspace to
+ *		v4l2_ioctl_ops->vidioc_dqbuf handler in driver.
+ * @nonblocking: if true, this call will not sleep waiting for a buffer if no
+ *		 buffers ready for dequeuing are present. Normally the driver
+ *		 would be passing (file->f_flags & O_NONBLOCK) here.
+ *
+ * Videobuf2 core helper to implement VIDIOC_DQBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * This function:
+ *
+ * #) calls buf_finish callback in the driver (if provided), in which
+ *    driver can perform any additional operations that may be required before
+ *    returning the buffer to userspace, such as cache sync,
+ * #) the buffer struct members are filled with relevant information for
+ *    the userspace.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
+		   bool nonblocking);
+
+/**
+ * vb2_core_streamon() - Implements VB2 stream ON logic
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue
+ * @type:	type of the queue to be started.
+ *		For V4L2, this is defined by &enum v4l2_buf_type type.
+ *
+ * Videobuf2 core helper to implement VIDIOC_STREAMON() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_streamon(struct vb2_queue *q, unsigned int type);
+
+/**
+ * vb2_core_streamoff() - Implements VB2 stream OFF logic
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue
+ * @type:	type of the queue to be started.
+ *		For V4L2, this is defined by &enum v4l2_buf_type type.
+ *
+ * Videobuf2 core helper to implement VIDIOC_STREAMOFF() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_streamoff(struct vb2_queue *q, unsigned int type);
+
+/**
+ * vb2_core_expbuf() - Export a buffer as a file descriptor.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @fd:		pointer to the file descriptor associated with DMABUF
+ *		(set by driver).
+ * @type:	buffer type.
+ * @index:	id number of the buffer.
+ * @plane:	index of the plane to be exported, 0 for single plane queues
+ * @flags:	file flags for newly created file, as defined at
+ *		include/uapi/asm-generic/fcntl.h.
+ *		Currently, the only used flag is %O_CLOEXEC.
+ *		is supported, refer to manual of open syscall for more details.
+ *
+ *
+ * Videobuf2 core helper to implement VIDIOC_EXPBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
+int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
+		unsigned int index, unsigned int plane, unsigned int flags);
+
+/**
+ * vb2_core_queue_init() - initialize a videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *		This structure should be allocated in driver
+ *
+ * The &vb2_queue structure should be allocated by the driver. The driver is
+ * responsible of clearing it's content and setting initial values for some
+ * required entries before calling this function.
+ *
+ * .. note::
+ *
+ *    The following fields at @q should be set before calling this function:
+ *    &vb2_queue->ops, &vb2_queue->mem_ops, &vb2_queue->type.
+ */
+int vb2_core_queue_init(struct vb2_queue *q);
+
+/**
+ * vb2_core_queue_release() - stop streaming, release the queue and free memory
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This function stops streaming and performs necessary clean ups, including
+ * freeing video buffer memory. The driver is responsible for freeing
+ * the &struct vb2_queue itself.
+ */
+void vb2_core_queue_release(struct vb2_queue *q);
+
+/**
+ * vb2_queue_error() - signal a fatal error on the queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * Flag that a fatal unrecoverable error has occurred and wake up all processes
+ * waiting on the queue. Polling will now set %EPOLLERR and queuing and dequeuing
+ * buffers will return %-EIO.
+ *
+ * The error flag will be cleared when canceling the queue, either from
+ * vb2_streamoff() or vb2_queue_release(). Drivers should thus not call this
+ * function before starting the stream, otherwise the error flag will remain set
+ * until the queue is released when closing the device node.
+ */
+void vb2_queue_error(struct vb2_queue *q);
+
+/**
+ * vb2_mmap() - map video buffers into application address space.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @vma:	pointer to &struct vm_area_struct with the vma passed
+ *		to the mmap file operation handler in the driver.
+ *
+ * Should be called from mmap file operation handler of a driver.
+ * This function maps one plane of one of the available video buffers to
+ * userspace. To map whole video memory allocated on reqbufs, this function
+ * has to be called once per each plane per each buffer previously allocated.
+ *
+ * When the userspace application calls mmap, it passes to it an offset returned
+ * to it earlier by the means of &v4l2_ioctl_ops->vidioc_querybuf handler.
+ * That offset acts as a "cookie", which is then used to identify the plane
+ * to be mapped.
+ *
+ * This function finds a plane with a matching offset and a mapping is performed
+ * by the means of a provided memory operation.
+ *
+ * The return values from this function are intended to be directly returned
+ * from the mmap handler in driver.
+ */
+int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
+
+#ifndef CONFIG_MMU
+/**
+ * vb2_get_unmapped_area - map video buffers into application address space.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @addr:	memory address.
+ * @len:	buffer size.
+ * @pgoff:	page offset.
+ * @flags:	memory flags.
+ *
+ * This function is used in noMMU platforms to propose address mapping
+ * for a given buffer. It's intended to be used as a handler for the
+ * &file_operations->get_unmapped_area operation.
+ *
+ * This is called by the mmap() syscall routines will call this
+ * to get a proposed address for the mapping, when ``!CONFIG_MMU``.
+ */
+unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
+				    unsigned long addr,
+				    unsigned long len,
+				    unsigned long pgoff,
+				    unsigned long flags);
+#endif
+
+/**
+ * vb2_core_poll() - implements poll syscall() logic.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @file:	&struct file argument passed to the poll
+ *		file operation handler.
+ * @wait:	&poll_table wait argument passed to the poll
+ *		file operation handler.
+ *
+ * This function implements poll file operation handler for a driver.
+ * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
+ * be informed that the file descriptor of a video device is available for
+ * reading.
+ * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
+ * will be reported as available for writing.
+ *
+ * The return values from this function are intended to be directly returned
+ * from poll handler in driver.
+ */
+__poll_t vb2_core_poll(struct vb2_queue *q, struct file *file,
+			   poll_table *wait);
+
+/**
+ * vb2_read() - implements read() syscall logic.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @data:	pointed to target userspace buffer
+ * @count:	number of bytes to read
+ * @ppos:	file handle position tracking pointer
+ * @nonblock:	mode selector (1 means blocking calls, 0 means nonblocking)
+ */
+size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
+		loff_t *ppos, int nonblock);
+/**
+ * vb2_read() - implements write() syscall logic.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @data:	pointed to target userspace buffer
+ * @count:	number of bytes to write
+ * @ppos:	file handle position tracking pointer
+ * @nonblock:	mode selector (1 means blocking calls, 0 means nonblocking)
+ */
+size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
+		loff_t *ppos, int nonblock);
+
+/**
+ * typedef vb2_thread_fnc - callback function for use with vb2_thread.
+ *
+ * @vb: pointer to struct &vb2_buffer.
+ * @priv: pointer to a private data.
+ *
+ * This is called whenever a buffer is dequeued in the thread.
+ */
+typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv);
+
+/**
+ * vb2_thread_start() - start a thread for the given queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @fnc:	&vb2_thread_fnc callback function.
+ * @priv:	priv pointer passed to the callback function.
+ * @thread_name:the name of the thread. This will be prefixed with "vb2-".
+ *
+ * This starts a thread that will queue and dequeue until an error occurs
+ * or vb2_thread_stop() is called.
+ *
+ * .. attention::
+ *
+ *   This function should not be used for anything else but the videobuf2-dvb
+ *   support. If you think you have another good use-case for this, then please
+ *   contact the linux-media mailing list first.
+ */
+int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
+		     const char *thread_name);
+
+/**
+ * vb2_thread_stop() - stop the thread for the given queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ */
+int vb2_thread_stop(struct vb2_queue *q);
+
+/**
+ * vb2_is_streaming() - return streaming status of the queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ */
+static inline bool vb2_is_streaming(struct vb2_queue *q)
+{
+	return q->streaming;
+}
+
+/**
+ * vb2_fileio_is_active() - return true if fileio is active.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This returns true if read() or write() is used to stream the data
+ * as opposed to stream I/O. This is almost never an important distinction,
+ * except in rare cases. One such case is that using read() or write() to
+ * stream a format using %V4L2_FIELD_ALTERNATE is not allowed since there
+ * is no way you can pass the field information of each buffer to/from
+ * userspace. A driver that supports this field format should check for
+ * this in the &vb2_ops->queue_setup op and reject it if this function returns
+ * true.
+ */
+static inline bool vb2_fileio_is_active(struct vb2_queue *q)
+{
+	return q->fileio;
+}
+
+/**
+ * vb2_is_busy() - return busy status of the queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This function checks if queue has any buffers allocated.
+ */
+static inline bool vb2_is_busy(struct vb2_queue *q)
+{
+	return (q->num_buffers > 0);
+}
+
+/**
+ * vb2_get_drv_priv() - return driver private data associated with the queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ */
+static inline void *vb2_get_drv_priv(struct vb2_queue *q)
+{
+	return q->drv_priv;
+}
+
+/**
+ * vb2_set_plane_payload() - set bytesused for the plane @plane_no.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which payload should be set.
+ * @size:	payload in bytes.
+ */
+static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
+				 unsigned int plane_no, unsigned long size)
+{
+	if (plane_no < vb->num_planes)
+		vb->planes[plane_no].bytesused = size;
+}
+
+/**
+ * vb2_get_plane_payload() - get bytesused for the plane plane_no
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which payload should be set.
+ */
+static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
+				 unsigned int plane_no)
+{
+	if (plane_no < vb->num_planes)
+		return vb->planes[plane_no].bytesused;
+	return 0;
+}
+
+/**
+ * vb2_plane_size() - return plane size in bytes.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which size should be returned.
+ */
+static inline unsigned long
+vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
+{
+	if (plane_no < vb->num_planes)
+		return vb->planes[plane_no].length;
+	return 0;
+}
+
+/**
+ * vb2_start_streaming_called() - return streaming status of driver.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ */
+static inline bool vb2_start_streaming_called(struct vb2_queue *q)
+{
+	return q->start_streaming_called;
+}
+
+/**
+ * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ */
+static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
+{
+	q->last_buffer_dequeued = false;
+}
+
+/*
+ * The following functions are not part of the vb2 core API, but are useful
+ * functions for videobuf2-*.
+ */
+
+/**
+ * vb2_buffer_in_use() - return true if the buffer is in use and
+ * the queue cannot be freed (by the means of VIDIOC_REQBUFS(0)) call.
+ *
+ * @vb:		buffer for which plane size should be returned.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ */
+bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
+
+/**
+ * vb2_verify_memory_type() - Check whether the memory type and buffer type
+ * passed to a buffer operation are compatible with the queue.
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory:	memory model, as defined by enum &vb2_memory.
+ * @type:	private buffer type whose content is defined by the vb2-core
+ *		caller. For example, for V4L2, it should match
+ *		the types defined on enum &v4l2_buf_type.
+ */
+int vb2_verify_memory_type(struct vb2_queue *q,
+		enum vb2_memory memory, unsigned int type);
+#endif /* _MEDIA_VIDEOBUF2_CORE_H */
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
new file mode 100644
index 0000000..5604818
--- /dev/null
+++ b/include/media/videobuf2-dma-contig.h
@@ -0,0 +1,32 @@
+/*
+ * videobuf2-dma-contig.h - DMA contig memory allocator for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak <pawel@osciak.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _MEDIA_VIDEOBUF2_DMA_CONTIG_H
+#define _MEDIA_VIDEOBUF2_DMA_CONTIG_H
+
+#include <media/videobuf2-v4l2.h>
+#include <linux/dma-mapping.h>
+
+static inline dma_addr_t
+vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no)
+{
+	dma_addr_t *addr = vb2_plane_cookie(vb, plane_no);
+
+	return *addr;
+}
+
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
+void vb2_dma_contig_clear_max_seg_size(struct device *dev);
+
+extern const struct vb2_mem_ops vb2_dma_contig_memops;
+
+#endif
diff --git a/include/media/videobuf2-dma-sg.h b/include/media/videobuf2-dma-sg.h
new file mode 100644
index 0000000..52afa0e
--- /dev/null
+++ b/include/media/videobuf2-dma-sg.h
@@ -0,0 +1,26 @@
+/*
+ * videobuf2-dma-sg.h - DMA scatter/gather memory allocator for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _MEDIA_VIDEOBUF2_DMA_SG_H
+#define _MEDIA_VIDEOBUF2_DMA_SG_H
+
+#include <media/videobuf2-v4l2.h>
+
+static inline struct sg_table *vb2_dma_sg_plane_desc(
+		struct vb2_buffer *vb, unsigned int plane_no)
+{
+	return (struct sg_table *)vb2_plane_cookie(vb, plane_no);
+}
+
+extern const struct vb2_mem_ops vb2_dma_sg_memops;
+
+#endif
diff --git a/include/media/videobuf2-dvb.h b/include/media/videobuf2-dvb.h
new file mode 100644
index 0000000..8605366
--- /dev/null
+++ b/include/media/videobuf2-dvb.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VIDEOBUF2_DVB_H_
+#define	_VIDEOBUF2_DVB_H_
+
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
+#include <media/videobuf2-v4l2.h>
+
+/* We don't actually need to include media-device.h here */
+struct media_device;
+
+/*
+ * TODO: This header file should be replaced with videobuf2-core.h
+ * Currently, vb2_thread is not a stuff of videobuf2-core,
+ * since vb2_thread has many dependencies on videobuf2-v4l2.
+ */
+
+struct vb2_dvb {
+	/* filling that the job of the driver */
+	char			*name;
+	struct dvb_frontend	*frontend;
+	struct vb2_queue	dvbq;
+
+	/* video-buf-dvb state info */
+	struct mutex		lock;
+	int			nfeeds;
+
+	/* vb2_dvb_(un)register manages this */
+	struct dvb_demux	demux;
+	struct dmxdev		dmxdev;
+	struct dmx_frontend	fe_hw;
+	struct dmx_frontend	fe_mem;
+	struct dvb_net		net;
+};
+
+struct vb2_dvb_frontend {
+	struct list_head felist;
+	int id;
+	struct vb2_dvb dvb;
+};
+
+struct vb2_dvb_frontends {
+	struct list_head felist;
+	struct mutex lock;
+	struct dvb_adapter adapter;
+	int active_fe_id; /* Indicates which frontend in the felist is in use */
+	int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */
+};
+
+int vb2_dvb_register_bus(struct vb2_dvb_frontends *f,
+			 struct module *module,
+			 void *adapter_priv,
+			 struct device *device,
+			 struct media_device *mdev,
+			 short *adapter_nr,
+			 int mfe_shared);
+
+void vb2_dvb_unregister_bus(struct vb2_dvb_frontends *f);
+
+struct vb2_dvb_frontend *vb2_dvb_alloc_frontend(struct vb2_dvb_frontends *f, int id);
+void vb2_dvb_dealloc_frontends(struct vb2_dvb_frontends *f);
+
+struct vb2_dvb_frontend *vb2_dvb_get_frontend(struct vb2_dvb_frontends *f, int id);
+int vb2_dvb_find_frontend(struct vb2_dvb_frontends *f, struct dvb_frontend *p);
+
+#endif			/* _VIDEOBUF2_DVB_H_ */
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
new file mode 100644
index 0000000..4b5b84f
--- /dev/null
+++ b/include/media/videobuf2-memops.h
@@ -0,0 +1,41 @@
+/*
+ * videobuf2-memops.h - generic memory handling routines for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak <pawel@osciak.com>
+ *	   Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _MEDIA_VIDEOBUF2_MEMOPS_H
+#define _MEDIA_VIDEOBUF2_MEMOPS_H
+
+#include <media/videobuf2-v4l2.h>
+#include <linux/mm.h>
+#include <linux/refcount.h>
+
+/**
+ * struct vb2_vmarea_handler - common vma refcount tracking handler.
+ *
+ * @refcount:	pointer to &refcount_t entry in the buffer.
+ * @put:	callback to function that decreases buffer refcount.
+ * @arg:	argument for @put callback.
+ */
+struct vb2_vmarea_handler {
+	refcount_t		*refcount;
+	void			(*put)(void *arg);
+	void			*arg;
+};
+
+extern const struct vm_operations_struct vb2_common_vm_ops;
+
+struct frame_vector *vb2_create_framevec(unsigned long start,
+					 unsigned long length,
+					 bool write);
+void vb2_destroy_framevec(struct frame_vector *vec);
+
+#endif
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
new file mode 100644
index 0000000..3d5e2d7
--- /dev/null
+++ b/include/media/videobuf2-v4l2.h
@@ -0,0 +1,294 @@
+/*
+ * videobuf2-v4l2.h - V4L2 driver helper framework
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak <pawel@osciak.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+#ifndef _MEDIA_VIDEOBUF2_V4L2_H
+#define _MEDIA_VIDEOBUF2_V4L2_H
+
+#include <linux/videodev2.h>
+#include <media/videobuf2-core.h>
+
+#if VB2_MAX_FRAME != VIDEO_MAX_FRAME
+#error VB2_MAX_FRAME != VIDEO_MAX_FRAME
+#endif
+
+#if VB2_MAX_PLANES != VIDEO_MAX_PLANES
+#error VB2_MAX_PLANES != VIDEO_MAX_PLANES
+#endif
+
+/**
+ * struct vb2_v4l2_buffer - video buffer information for v4l2.
+ *
+ * @vb2_buf:	embedded struct &vb2_buffer.
+ * @flags:	buffer informational flags.
+ * @field:	field order of the image in the buffer, as defined by
+ *		&enum v4l2_field.
+ * @timecode:	frame timecode.
+ * @sequence:	sequence count of this frame.
+ *
+ * Should contain enough information to be able to cover all the fields
+ * of &struct v4l2_buffer at ``videodev2.h``.
+ */
+struct vb2_v4l2_buffer {
+	struct vb2_buffer	vb2_buf;
+
+	__u32			flags;
+	__u32			field;
+	struct v4l2_timecode	timecode;
+	__u32			sequence;
+};
+
+/*
+ * to_vb2_v4l2_buffer() - cast struct vb2_buffer * to struct vb2_v4l2_buffer *
+ */
+#define to_vb2_v4l2_buffer(vb) \
+	container_of(vb, struct vb2_v4l2_buffer, vb2_buf)
+
+int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
+
+/**
+ * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies
+ * the memory and type values.
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @req:	&struct v4l2_requestbuffers passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_reqbufs handler in driver.
+ */
+int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
+
+/**
+ * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies
+ * the memory and type values.
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @create:	creation parameters, passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_create_bufs handler in driver
+ */
+int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
+
+/**
+ * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @b:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_prepare_buf handler in driver
+ *
+ * Should be called from &v4l2_ioctl_ops->vidioc_prepare_buf ioctl handler
+ * of a driver.
+ *
+ * This function:
+ *
+ * #) verifies the passed buffer,
+ * #) calls &vb2_ops->buf_prepare callback in the driver (if provided),
+ *    in which driver-specific buffer initialization can be performed.
+ *
+ * The return values from this function are intended to be directly returned
+ * from &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
+ */
+int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
+
+/**
+ * vb2_qbuf() - Queue a buffer from userspace
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @b:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_qbuf handler in driver
+ *
+ * Should be called from &v4l2_ioctl_ops->vidioc_qbuf handler of a driver.
+ *
+ * This function:
+ *
+ * #) verifies the passed buffer;
+ * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
+ *    (if provided), in which driver-specific buffer initialization can
+ *    be performed;
+ * #) if streaming is on, queues the buffer in driver by the means of
+ *    &vb2_ops->buf_queue callback for processing.
+ *
+ * The return values from this function are intended to be directly returned
+ * from &v4l2_ioctl_ops->vidioc_qbuf handler in driver.
+ */
+int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+
+/**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @eb:		export buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_expbuf handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from &v4l2_ioctl_ops->vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
+
+/**
+ * vb2_dqbuf() - Dequeue a buffer to the userspace
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @b:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_dqbuf handler in driver
+ * @nonblocking: if true, this call will not sleep waiting for a buffer if no
+ *		 buffers ready for dequeuing are present. Normally the driver
+ *		 would be passing (&file->f_flags & %O_NONBLOCK) here
+ *
+ * Should be called from &v4l2_ioctl_ops->vidioc_dqbuf ioctl handler
+ * of a driver.
+ *
+ * This function:
+ *
+ * #) verifies the passed buffer;
+ * #) calls &vb2_ops->buf_finish callback in the driver (if provided), in which
+ *    driver can perform any additional operations that may be required before
+ *    returning the buffer to userspace, such as cache sync;
+ * #) the buffer struct members are filled with relevant information for
+ *    the userspace.
+ *
+ * The return values from this function are intended to be directly returned
+ * from &v4l2_ioctl_ops->vidioc_dqbuf handler in driver.
+ */
+int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
+
+/**
+ * vb2_streamon - start streaming
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @type:	type argument passed from userspace to vidioc_streamon handler,
+ *		as defined by &enum v4l2_buf_type.
+ *
+ * Should be called from &v4l2_ioctl_ops->vidioc_streamon handler of a driver.
+ *
+ * This function:
+ *
+ * 1) verifies current state
+ * 2) passes any previously queued buffers to the driver and starts streaming
+ *
+ * The return values from this function are intended to be directly returned
+ * from &v4l2_ioctl_ops->vidioc_streamon handler in the driver.
+ */
+int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
+
+/**
+ * vb2_streamoff - stop streaming
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @type:	type argument passed from userspace to vidioc_streamoff handler
+ *
+ * Should be called from vidioc_streamoff handler of a driver.
+ *
+ * This function:
+ *
+ * #) verifies current state,
+ * #) stop streaming and dequeues any queued buffers, including those previously
+ *    passed to the driver (after waiting for the driver to finish).
+ *
+ * This call can be used for pausing playback.
+ * The return values from this function are intended to be directly returned
+ * from vidioc_streamoff handler in the driver
+ */
+int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
+
+/**
+ * vb2_queue_init() - initialize a videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * The vb2_queue structure should be allocated by the driver. The driver is
+ * responsible of clearing it's content and setting initial values for some
+ * required entries before calling this function.
+ * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
+ * to the struct vb2_queue description in include/media/videobuf2-core.h
+ * for more information.
+ */
+int __must_check vb2_queue_init(struct vb2_queue *q);
+
+/**
+ * vb2_queue_release() - stop streaming, release the queue and free memory
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *
+ * This function stops streaming and performs necessary clean ups, including
+ * freeing video buffer memory. The driver is responsible for freeing
+ * the vb2_queue structure itself.
+ */
+void vb2_queue_release(struct vb2_queue *q);
+
+/**
+ * vb2_poll() - implements poll userspace operation
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @file:	file argument passed to the poll file operation handler
+ * @wait:	wait argument passed to the poll file operation handler
+ *
+ * This function implements poll file operation handler for a driver.
+ * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
+ * be informed that the file descriptor of a video device is available for
+ * reading.
+ * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
+ * will be reported as available for writing.
+ *
+ * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any
+ * pending events.
+ *
+ * The return values from this function are intended to be directly returned
+ * from poll handler in driver.
+ */
+__poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
+
+/*
+ * The following functions are not part of the vb2 core API, but are simple
+ * helper functions that you can use in your struct v4l2_file_operations,
+ * struct v4l2_ioctl_ops and struct vb2_ops. They will serialize if vb2_queue->lock
+ * or video_device->lock is set, and they will set and test vb2_queue->owner
+ * to check if the calling filehandle is permitted to do the queuing operation.
+ */
+
+/* struct v4l2_ioctl_ops helpers */
+
+int vb2_ioctl_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *p);
+int vb2_ioctl_create_bufs(struct file *file, void *priv,
+			  struct v4l2_create_buffers *p);
+int vb2_ioctl_prepare_buf(struct file *file, void *priv,
+			  struct v4l2_buffer *p);
+int vb2_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *p);
+int vb2_ioctl_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
+int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p);
+int vb2_ioctl_streamon(struct file *file, void *priv, enum v4l2_buf_type i);
+int vb2_ioctl_streamoff(struct file *file, void *priv, enum v4l2_buf_type i);
+int vb2_ioctl_expbuf(struct file *file, void *priv,
+	struct v4l2_exportbuffer *p);
+
+/* struct v4l2_file_operations helpers */
+
+int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma);
+int vb2_fop_release(struct file *file);
+int _vb2_fop_release(struct file *file, struct mutex *lock);
+ssize_t vb2_fop_write(struct file *file, const char __user *buf,
+		size_t count, loff_t *ppos);
+ssize_t vb2_fop_read(struct file *file, char __user *buf,
+		size_t count, loff_t *ppos);
+__poll_t vb2_fop_poll(struct file *file, poll_table *wait);
+#ifndef CONFIG_MMU
+unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags);
+#endif
+
+/**
+ * vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue
+ *
+ * @vq: pointer to &struct vb2_queue
+ *
+ * ..note:: only use if vq->lock is non-NULL.
+ */
+void vb2_ops_wait_prepare(struct vb2_queue *vq);
+
+/**
+ * vb2_ops_wait_finish - helper function to unlock a struct &vb2_queue
+ *
+ * @vq: pointer to &struct vb2_queue
+ *
+ * ..note:: only use if vq->lock is non-NULL.
+ */
+void vb2_ops_wait_finish(struct vb2_queue *vq);
+
+#endif /* _MEDIA_VIDEOBUF2_V4L2_H */
diff --git a/include/media/videobuf2-vmalloc.h b/include/media/videobuf2-vmalloc.h
new file mode 100644
index 0000000..a63fe66
--- /dev/null
+++ b/include/media/videobuf2-vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * videobuf2-vmalloc.h - vmalloc memory allocator for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak <pawel@osciak.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _MEDIA_VIDEOBUF2_VMALLOC_H
+#define _MEDIA_VIDEOBUF2_VMALLOC_H
+
+#include <media/videobuf2-v4l2.h>
+
+extern const struct vb2_mem_ops vb2_vmalloc_memops;
+
+#endif
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
new file mode 100644
index 0000000..3093b9c
--- /dev/null
+++ b/include/media/vsp1.h
@@ -0,0 +1,105 @@
+/*
+ * vsp1.h  --  R-Car VSP1 API
+ *
+ * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MEDIA_VSP1_H__
+#define __MEDIA_VSP1_H__
+
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+struct device;
+
+int vsp1_du_init(struct device *dev);
+
+/**
+ * struct vsp1_du_lif_config - VSP LIF configuration
+ * @width: output frame width
+ * @height: output frame height
+ * @interlaced: true for interlaced pipelines
+ * @callback: frame completion callback function (optional). When a callback
+ *	      is provided, the VSP driver guarantees that it will be called once
+ *	      and only once for each vsp1_du_atomic_flush() call.
+ * @callback_data: data to be passed to the frame completion callback
+ */
+struct vsp1_du_lif_config {
+	unsigned int width;
+	unsigned int height;
+	bool interlaced;
+
+	void (*callback)(void *data, bool completed, u32 crc);
+	void *callback_data;
+};
+
+int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
+		      const struct vsp1_du_lif_config *cfg);
+
+/**
+ * struct vsp1_du_atomic_config - VSP atomic configuration parameters
+ * @pixelformat: plane pixel format (V4L2 4CC)
+ * @pitch: line pitch in bytes, for all planes
+ * @mem: DMA memory address for each plane of the frame buffer
+ * @src: source rectangle in the frame buffer (integer coordinates)
+ * @dst: destination rectangle on the display (integer coordinates)
+ * @alpha: alpha value (0: fully transparent, 255: fully opaque)
+ * @zpos: Z position of the plane (from 0 to number of planes minus 1)
+ */
+struct vsp1_du_atomic_config {
+	u32 pixelformat;
+	unsigned int pitch;
+	dma_addr_t mem[3];
+	struct v4l2_rect src;
+	struct v4l2_rect dst;
+	unsigned int alpha;
+	unsigned int zpos;
+};
+
+/**
+ * enum vsp1_du_crc_source - Source used for CRC calculation
+ * @VSP1_DU_CRC_NONE: CRC calculation disabled
+ * @VSP1_DU_CRC_PLANE: Perform CRC calculation on an input plane
+ * @VSP1_DU_CRC_OUTPUT: Perform CRC calculation on the composed output
+ */
+enum vsp1_du_crc_source {
+	VSP1_DU_CRC_NONE,
+	VSP1_DU_CRC_PLANE,
+	VSP1_DU_CRC_OUTPUT,
+};
+
+/**
+ * struct vsp1_du_crc_config - VSP CRC computation configuration parameters
+ * @source: source for CRC calculation
+ * @index: index of the CRC source plane (when source is set to plane)
+ */
+struct vsp1_du_crc_config {
+	enum vsp1_du_crc_source source;
+	unsigned int index;
+};
+
+/**
+ * struct vsp1_du_atomic_pipe_config - VSP atomic pipe configuration parameters
+ * @crc: CRC computation configuration
+ */
+struct vsp1_du_atomic_pipe_config {
+	struct vsp1_du_crc_config crc;
+};
+
+void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
+int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+			  unsigned int rpf,
+			  const struct vsp1_du_atomic_config *cfg);
+void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index,
+			  const struct vsp1_du_atomic_pipe_config *cfg);
+int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
+void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
+
+#endif /* __MEDIA_VSP1_H__ */