aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Documentation/driver-api/media
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/driver-api/media')
-rw-r--r--Documentation/driver-api/media/camera-sensor.rst148
-rw-r--r--Documentation/driver-api/media/cec-core.rst120
-rw-r--r--Documentation/driver-api/media/csi2.rst91
-rw-r--r--Documentation/driver-api/media/drivers/bttv-devel.rst2
-rw-r--r--Documentation/driver-api/media/drivers/ccs/ccs-regs.asc1041
-rw-r--r--Documentation/driver-api/media/drivers/ccs/ccs.rst82
-rwxr-xr-xDocumentation/driver-api/media/drivers/ccs/mk-ccs-regs480
-rw-r--r--Documentation/driver-api/media/drivers/cpia2_devel.rst56
-rw-r--r--Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst39
-rw-r--r--Documentation/driver-api/media/drivers/fimc-devel.rst14
-rw-r--r--Documentation/driver-api/media/drivers/index.rst6
-rw-r--r--Documentation/driver-api/media/drivers/pvrusb2.rst2
-rw-r--r--Documentation/driver-api/media/drivers/pxa_camera.rst2
-rw-r--r--Documentation/driver-api/media/drivers/rkisp1.rst43
-rw-r--r--Documentation/driver-api/media/drivers/tuners.rst2
-rw-r--r--Documentation/driver-api/media/drivers/vidtv.rst513
-rw-r--r--Documentation/driver-api/media/drivers/zoran.rst575
-rw-r--r--Documentation/driver-api/media/dtv-common.rst9
-rw-r--r--Documentation/driver-api/media/dtv-demux.rst2
-rw-r--r--Documentation/driver-api/media/dtv-frontend.rst10
-rw-r--r--Documentation/driver-api/media/index.rst18
-rw-r--r--Documentation/driver-api/media/maintainer-entry-profile.rst206
-rw-r--r--Documentation/driver-api/media/mc-core.rst61
-rw-r--r--Documentation/driver-api/media/tx-rx.rst134
-rw-r--r--Documentation/driver-api/media/v4l2-cci.rst5
-rw-r--r--Documentation/driver-api/media/v4l2-clocks.rst31
-rw-r--r--Documentation/driver-api/media/v4l2-controls.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-core.rst3
-rw-r--r--Documentation/driver-api/media/v4l2-dev.rst18
-rw-r--r--Documentation/driver-api/media/v4l2-device.rst6
-rw-r--r--Documentation/driver-api/media/v4l2-event.rst12
-rw-r--r--Documentation/driver-api/media/v4l2-fh.rst16
-rw-r--r--Documentation/driver-api/media/v4l2-subdev.rst268
-rw-r--r--Documentation/driver-api/media/v4l2-videobuf.rst403
34 files changed, 3606 insertions, 818 deletions
diff --git a/Documentation/driver-api/media/camera-sensor.rst b/Documentation/driver-api/media/camera-sensor.rst
new file mode 100644
index 000000000000..b4920b34cebc
--- /dev/null
+++ b/Documentation/driver-api/media/camera-sensor.rst
@@ -0,0 +1,148 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _media_writing_camera_sensor_drivers:
+
+Writing camera sensor drivers
+=============================
+
+This document covers the in-kernel APIs only. For the best practices on
+userspace API implementation in camera sensor drivers, please see
+:ref:`media_using_camera_sensor_drivers`.
+
+CSI-2, parallel and BT.656 buses
+--------------------------------
+
+Please see :ref:`transmitter-receiver`.
+
+Handling clocks
+---------------
+
+Camera sensors have an internal clock tree including a PLL and a number of
+divisors. The clock tree is generally configured by the driver based on a few
+input parameters that are specific to the hardware: the external clock frequency
+and the link frequency. The two parameters generally are obtained from system
+firmware. **No other frequencies should be used in any circumstances.**
+
+The reason why the clock frequencies are so important is that the clock signals
+come out of the SoC, and in many cases a specific frequency is designed to be
+used in the system. Using another frequency may cause harmful effects
+elsewhere. Therefore only the pre-determined frequencies are configurable by the
+user.
+
+ACPI
+~~~~
+
+Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
+can rely on this frequency being used.
+
+Devicetree
+~~~~~~~~~~
+
+The preferred way to achieve this is using ``assigned-clocks``,
+``assigned-clock-parents`` and ``assigned-clock-rates`` properties. See the
+`clock device tree bindings
+<https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml>`_
+for more information. The driver then gets the frequency using
+``clk_get_rate()``.
+
+This approach has the drawback that there's no guarantee that the frequency
+hasn't been modified directly or indirectly by another driver, or supported by
+the board's clock tree to begin with. Changes to the Common Clock Framework API
+are required to ensure reliability.
+
+Power management
+----------------
+
+Camera sensors are used in conjunction with other devices to form a camera
+pipeline. They must obey the rules listed herein to ensure coherent power
+management over the pipeline.
+
+Camera sensor drivers are responsible for controlling the power state of the
+device they otherwise control as well. They shall use runtime PM to manage
+power states. Runtime PM shall be enabled at probe time and disabled at remove
+time. Drivers should enable runtime PM autosuspend. Also see
+:ref:`async sub-device registration <media-registering-async-subdevs>`.
+
+The runtime PM handlers shall handle clocks, regulators, GPIOs, and other
+system resources required to power the sensor up and down. For drivers that
+don't use any of those resources (such as drivers that support ACPI systems
+only), the runtime PM handlers may be left unimplemented.
+
+In general, the device shall be powered on at least when its registers are
+being accessed and when it is streaming. Drivers should use
+``pm_runtime_resume_and_get()`` when starting streaming and
+``pm_runtime_put()`` or ``pm_runtime_put_autosuspend()`` when stopping
+streaming. They may power the device up at probe time (for example to read
+identification registers), but should not keep it powered unconditionally after
+probe.
+
+At system suspend time, the whole camera pipeline must stop streaming, and
+restart when the system is resumed. This requires coordination between the
+camera sensor and the rest of the camera pipeline. Bridge drivers are
+responsible for this coordination, and instruct camera sensors to stop and
+restart streaming by calling the appropriate subdev operations
+(``.s_stream()``, ``.enable_streams()`` or ``.disable_streams()``). Camera
+sensor drivers shall therefore **not** keep track of the streaming state to
+stop streaming in the PM suspend handler and restart it in the resume handler.
+Drivers should in general not implement the system PM handlers.
+
+Camera sensor drivers shall **not** implement the subdev ``.s_power()``
+operation, as it is deprecated. While this operation is implemented in some
+existing drivers as they predate the deprecation, new drivers shall use runtime
+PM instead. If you feel you need to begin calling ``.s_power()`` from an ISP or
+a bridge driver, instead add runtime PM support to the sensor driver you are
+using and drop its ``.s_power()`` handler.
+
+Please also see :ref:`examples <media-camera-sensor-examples>`.
+
+Control framework
+~~~~~~~~~~~~~~~~~
+
+``v4l2_ctrl_handler_setup()`` function may not be used in the device's runtime
+PM ``runtime_resume`` callback, as it has no way to figure out the power state
+of the device. This is because the power state of the device is only changed
+after the power state transition has taken place. The ``s_ctrl`` callback can be
+used to obtain device's power state after the power state transition:
+
+.. c:function:: int pm_runtime_get_if_in_use(struct device *dev);
+
+The function returns a non-zero value if it succeeded getting the power count or
+runtime PM was disabled, in either of which cases the driver may proceed to
+access the device.
+
+Rotation, orientation and flipping
+----------------------------------
+
+Use ``v4l2_fwnode_device_parse()`` to obtain rotation and orientation
+information from system firmware and ``v4l2_ctrl_new_fwnode_properties()`` to
+register the appropriate controls.
+
+.. _media-camera-sensor-examples:
+
+Example drivers
+---------------
+
+Features implemented by sensor drivers vary, and depending on the set of
+supported features and other qualities, particular sensor drivers better serve
+the purpose of an example. The following drivers are known to be good examples:
+
+.. flat-table:: Example sensor drivers
+ :header-rows: 0
+ :widths: 1 1 1 2
+
+ * - Driver name
+ - File(s)
+ - Driver type
+ - Example topic
+ * - CCS
+ - ``drivers/media/i2c/ccs/``
+ - Freely configurable
+ - Power management (ACPI and DT), UAPI
+ * - imx219
+ - ``drivers/media/i2c/imx219.c``
+ - Register list based
+ - Power management (DT), UAPI, mode selection
+ * - imx319
+ - ``drivers/media/i2c/imx319.c``
+ - Register list based
+ - Power management (ACPI and DT)
diff --git a/Documentation/driver-api/media/cec-core.rst b/Documentation/driver-api/media/cec-core.rst
index 3ce26b7c2b2b..f1ffdec388f3 100644
--- a/Documentation/driver-api/media/cec-core.rst
+++ b/Documentation/driver-api/media/cec-core.rst
@@ -26,7 +26,7 @@ It is documented in the HDMI 1.4 specification with the new 2.0 bits documented
in the HDMI 2.0 specification. But for most of the features the freely available
HDMI 1.3a specification is sufficient:
-http://www.microprocessor.org/HDMISpecification13a.pdf
+https://www.hdmi.org/spec/index
CEC Adapter Interface
@@ -36,8 +36,9 @@ The struct cec_adapter represents the CEC adapter hardware. It is created by
calling cec_allocate_adapter() and deleted by calling cec_delete_adapter():
.. c:function::
- struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, void *priv,
- const char *name, u32 caps, u8 available_las);
+ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, \
+ void *priv, const char *name, \
+ u32 caps, u8 available_las);
.. c:function::
void cec_delete_adapter(struct cec_adapter *adap);
@@ -74,7 +75,8 @@ To register the /dev/cecX device node and the remote control device (if
CEC_CAP_RC is set) you call:
.. c:function::
- int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
+ int cec_register_adapter(struct cec_adapter *adap, \
+ struct device *parent);
where parent is the parent device.
@@ -96,7 +98,7 @@ Implementing the Low-Level CEC Adapter
The following low-level adapter operations have to be implemented in
your driver:
-.. c:type:: struct cec_adap_ops
+.. c:struct:: cec_adap_ops
.. code-block:: none
@@ -107,52 +109,55 @@ your driver:
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);
+ void (*adap_unconfigured)(struct cec_adapter *adap);
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);
+ void (*adap_nb_transmit_canceled)(struct cec_adapter *adap,
+ const 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 */
...
- /* High-level callbacks */
+ /* High-level callback */
...
};
-The seven low-level ops deal with various aspects of controlling the CEC adapter
-hardware:
+These low-level ops deal with various aspects of controlling the CEC adapter
+hardware. They are all called with the mutex adap->lock held.
-To enable/disable the hardware:
+To enable/disable the hardware::
-.. c:function::
int (*adap_enable)(struct cec_adapter *adap, bool enable);
This callback enables or disables the CEC hardware. Enabling the CEC hardware
-means powering it up in a state where no logical addresses are claimed. This
-op assumes that the physical address (adap->phys_addr) is valid when enable is
-true and will not change while the CEC adapter remains enabled. The initial
+means powering it up in a state where no logical addresses are claimed. The
+physical address will always be valid if CEC_CAP_NEEDS_HPD is set. If that
+capability is not set, then the physical address can change while the CEC
+hardware is enabled. CEC drivers should not set CEC_CAP_NEEDS_HPD unless
+the hardware design requires that as this will make it impossible to wake
+up displays that pull the HPD low when in standby mode. The initial
state of the CEC adapter after calling cec_allocate_adapter() is disabled.
Note that adap_enable must return 0 if enable is false.
-To enable/disable the 'monitor all' mode:
+To enable/disable the 'monitor all' mode::
-.. c:function::
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
If enabled, then the adapter should be put in a mode to also monitor messages
-that not for us. Not all hardware supports this and this function is only
+that are not for us. Not all hardware supports this and this function is only
called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional
(some hardware may always be in 'monitor all' mode).
Note that adap_monitor_all_enable must return 0 if enable is false.
-To enable/disable the 'monitor pin' mode:
+To enable/disable the 'monitor pin' mode::
-.. c:function::
int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
If enabled, then the adapter should be put in a mode to also monitor CEC pin
@@ -163,9 +168,8 @@ the CEC_CAP_MONITOR_PIN capability is set. This callback is optional
Note that adap_monitor_pin_enable must return 0 if enable is false.
-To program a new logical address:
+To program a new logical address::
-.. c:function::
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
If logical_addr == CEC_LOG_ADDR_INVALID then all programmed logical addresses
@@ -177,9 +181,16 @@ can receive directed messages to that address.
Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID.
-To transmit a new message:
+Called when the adapter is unconfigured::
+
+ void (*adap_unconfigured)(struct cec_adapter *adap);
+
+The adapter is unconfigured. If the driver has to take specific actions after
+unconfiguration, then that can be done through this optional callback.
+
+
+To transmit a new message::
-.. c:function::
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);
@@ -196,17 +207,28 @@ The CEC_FREE_TIME_TO_USEC macro can be used to convert signal_free_time to
microseconds (one data bit period is 2.4 ms).
-To log the current CEC hardware status:
+To pass on the result of a canceled non-blocking transmit::
+
+ void (*adap_nb_transmit_canceled)(struct cec_adapter *adap,
+ const struct cec_msg *msg);
+
+This optional callback can be used to obtain the result of a canceled
+non-blocking transmit with sequence number msg->sequence. This is
+called if the transmit was aborted, the transmit timed out (i.e. the
+hardware never signaled that the transmit finished), or the transmit
+was successful, but the wait for the expected reply was either aborted
+or it timed out.
+
+
+To log the current CEC hardware status::
-.. c:function::
void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
This optional callback can be used to show the status of the CEC hardware.
The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status
-To free any resources when the adapter is deleted:
+To free any resources when the adapter is deleted::
-.. c:function::
void (*adap_free)(struct cec_adapter *adap);
This optional callback can be used to free any resources that might have been
@@ -216,15 +238,14 @@ allocated by the driver. It's called from cec_delete_adapter.
Your adapter driver will also have to react to events (typically interrupt
driven) by calling into the framework in the following situations:
-When a transmit finished (successfully or otherwise):
+When a transmit finished (successfully or otherwise)::
-.. c:function::
- void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
- u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
+ void cec_transmit_done(struct cec_adapter *adap, u8 status,
+ u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
+ u8 error_cnt);
-or:
+or::
-.. c:function::
void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
The status can be one of:
@@ -341,17 +362,15 @@ So this must work:
$ cat einj.txt >error-inj
The first callback is called when this file is read and it should show the
-the current error injection state:
+current error injection state::
-.. c:function::
int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
It is recommended that it starts with a comment block with basic usage
information. It returns 0 for success and an error otherwise.
-The second callback will parse commands written to the ``error-inj`` file:
+The second callback will parse commands written to the ``error-inj`` file::
-.. c:function::
bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
The ``line`` argument points to the start of the command. Any leading
@@ -366,7 +385,8 @@ Implementing the High-Level CEC Adapter
---------------------------------------
The low-level operations drive the hardware, the high-level operations are
-CEC protocol driven. The following high-level callbacks are available:
+CEC protocol driven. The high-level callbacks are called without the adap->lock
+mutex being held. The following high-level callbacks are available:
.. code-block:: none
@@ -378,13 +398,22 @@ CEC protocol driven. The following high-level callbacks are available:
...
/* High-level CEC message callback */
+ void (*configured)(struct cec_adapter *adap);
int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
};
+Called when the adapter is configured::
+
+ void (*configured)(struct cec_adapter *adap);
+
+The adapter is fully configured, i.e. all logical addresses have been
+successfully claimed. If the driver has to take specific actions after
+configuration, then that can be done through this optional callback.
+
+
The received() callback allows the driver to optionally handle a newly
-received CEC message
+received CEC message::
-.. c:function::
int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
If the driver wants to process a CEC message, then it can implement this
@@ -399,15 +428,14 @@ CEC framework functions
CEC Adapter drivers can call the following CEC framework functions:
.. c:function::
- int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
- bool block);
+ int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg, \
+ bool block);
Transmit a CEC message. If block is true, then wait until the message has been
transmitted, otherwise just queue it and return.
.. c:function::
- void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
- bool block);
+ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block);
Change the physical address. This function will set adap->phys_addr and
send an event if it has changed. If cec_s_log_addrs() has been called and
@@ -422,15 +450,15 @@ to another valid physical address, then this function will first set the
address to CEC_PHYS_ADDR_INVALID before enabling the new physical address.
.. c:function::
- void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
- const struct edid *edid);
+ void cec_s_phys_addr_from_edid(struct cec_adapter *adap, \
+ const struct edid *edid);
A helper function that extracts the physical address from the edid struct
and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID
if the EDID did not contain a physical address or edid was a NULL pointer.
.. c:function::
- int cec_s_log_addrs(struct cec_adapter *adap,
+ int cec_s_log_addrs(struct cec_adapter *adap, \
struct cec_log_addrs *log_addrs, bool block);
Claim the CEC logical addresses. Should never be called if CEC_CAP_LOG_ADDRS
diff --git a/Documentation/driver-api/media/csi2.rst b/Documentation/driver-api/media/csi2.rst
deleted file mode 100644
index 17cad435f1a0..000000000000
--- a/Documentation/driver-api/media/csi2.rst
+++ /dev/null
@@ -1,91 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-MIPI CSI-2
-==========
-
-CSI-2 is a data bus intended for transferring images from cameras to
-the host SoC. It is defined by the `MIPI alliance`_.
-
-.. _`MIPI alliance`: http://www.mipi.org/
-
-Media bus formats
------------------
-
-See :ref:`v4l2-mbus-pixelcode` for details on which media bus formats should
-be used for CSI-2 interfaces.
-
-Transmitter drivers
--------------------
-
-CSI-2 transmitter, such as a sensor or a TV tuner, drivers need to
-provide the CSI-2 receiver with information on the CSI-2 bus
-configuration. These include the V4L2_CID_LINK_FREQ and
-V4L2_CID_PIXEL_RATE controls and
-(:c:type:`v4l2_subdev_video_ops`->s_stream() callback). These
-interface elements must be present on the sub-device represents the
-CSI-2 transmitter.
-
-The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the
-frequency (and not the symbol rate) of the link. The
-V4L2_CID_PIXEL_RATE is may be used by the receiver to obtain the pixel
-rate the transmitter uses. The
-:c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
-ability to start and stop the stream.
-
-The value of the V4L2_CID_PIXEL_RATE is calculated as follows::
-
- pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
-
-where
-
-.. list-table:: variables in pixel rate calculation
- :header-rows: 1
-
- * - variable or constant
- - description
- * - link_freq
- - The value of the V4L2_CID_LINK_FREQ integer64 menu item.
- * - nr_of_lanes
- - Number of data lanes used on the CSI-2 link. This can
- be obtained from the OF endpoint configuration.
- * - 2
- - Two bits are transferred per clock cycle per lane.
- * - bits_per_sample
- - Number of bits per sample.
-
-The transmitter drivers must, if possible, configure the CSI-2
-transmitter to *LP-11 mode* whenever the transmitter is powered on but
-not active, and maintain *LP-11 mode* until stream on. Only at stream
-on should the transmitter activate the clock on the clock lane and
-transition to *HS mode*.
-
-Some transmitters do this automatically but some have to be explicitly
-programmed to do so, and some are unable to do so altogether due to
-hardware constraints.
-
-Stopping the transmitter
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-A transmitter stops sending the stream of images as a result of
-calling the ``.s_stream()`` callback. Some transmitters may stop the
-stream at a frame boundary whereas others stop immediately,
-effectively leaving the current frame unfinished. The receiver driver
-should not make assumptions either way, but function properly in both
-cases.
-
-Receiver drivers
-----------------
-
-Before the receiver driver may enable the CSI-2 transmitter by using
-the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered
-the transmitter up by using the
-:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
-place either indirectly by using :c:func:`v4l2_pipeline_pm_get` or
-directly.
-
-Formats
--------
-
-The media bus pixel codes document parallel formats. Should the pixel data be
-transported over a serial bus, the media bus pixel code that describes a
-parallel format that transfers a sample on a single clock cycle is used.
diff --git a/Documentation/driver-api/media/drivers/bttv-devel.rst b/Documentation/driver-api/media/drivers/bttv-devel.rst
index c9aa8b95a5e5..0885a04563a9 100644
--- a/Documentation/driver-api/media/drivers/bttv-devel.rst
+++ b/Documentation/driver-api/media/drivers/bttv-devel.rst
@@ -21,7 +21,7 @@ log, telling which card type is used. Like this one::
You should verify this is correct. If it isn't, you have to pass the
correct board type as insmod argument, ``insmod bttv card=2`` for
-example. The file :doc:`/admin-guide/media/bttv-cardlist` has a list
+example. The file Documentation/admin-guide/media/bttv-cardlist.rst has a list
of valid arguments for card.
If your card isn't listed there, you might check the source code for
diff --git a/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc b/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc
new file mode 100644
index 000000000000..bbf9213c3388
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/ccs/ccs-regs.asc
@@ -0,0 +1,1041 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
+# Copyright (C) 2019--2020 Intel Corporation
+
+# register rflags
+# - f field LSB MSB rflags
+# - e enum value # after a field
+# - e enum value [LSB MSB]
+# - b bool bit
+# - l arg name min max elsize [discontig...]
+#
+# rflags
+# 8, 16, 32 register bits (default is 8)
+# v1.1 defined in version 1.1
+# f formula
+# float_ireal iReal or IEEE 754; 32 bits
+# ireal unsigned iReal
+
+# general status registers
+module_model_id 0x0000 16
+module_revision_number_major 0x0002 8
+frame_count 0x0005 8
+pixel_order 0x0006 8
+- e GRBG 0
+- e RGGB 1
+- e BGGR 2
+- e GBRG 3
+MIPI_CCS_version 0x0007 8
+- e v1_0 0x10
+- e v1_1 0x11
+- f major 4 7
+- f minor 0 3
+data_pedestal 0x0008 16
+module_manufacturer_id 0x000e 16
+module_revision_number_minor 0x0010 8
+module_date_year 0x0012 8
+module_date_month 0x0013 8
+module_date_day 0x0014 8
+module_date_phase 0x0015 8
+- f 0 2
+- e ts 0
+- e es 1
+- e cs 2
+- e mp 3
+sensor_model_id 0x0016 16
+sensor_revision_number 0x0018 8
+sensor_firmware_version 0x001a 8
+serial_number 0x001c 32
+sensor_manufacturer_id 0x0020 16
+sensor_revision_number_16 0x0022 16
+
+# frame format description registers
+frame_format_model_type 0x0040 8
+- e 2-byte 1
+- e 4-byte 2
+frame_format_model_subtype 0x0041 8
+- f rows 0 3
+- f columns 4 7
+frame_format_descriptor(n) 0x0042 16 f
+- l n 0 14 2
+- f pixels 0 11
+- f pcode 12 15
+- e embedded 1
+- e dummy_pixel 2
+- e black_pixel 3
+- e dark_pixel 4
+- e visible_pixel 5
+- e manuf_specific_0 8
+- e manuf_specific_1 9
+- e manuf_specific_2 10
+- e manuf_specific_3 11
+- e manuf_specific_4 12
+- e manuf_specific_5 13
+- e manuf_specific_6 14
+frame_format_descriptor_4(n) 0x0060 32 f
+- l n 0 7 4
+- f pixels 0 15
+- f pcode 28 31
+- e embedded 1
+- e dummy_pixel 2
+- e black_pixel 3
+- e dark_pixel 4
+- e visible_pixel 5
+- e manuf_specific_0 8
+- e manuf_specific_1 9
+- e manuf_specific_2 10
+- e manuf_specific_3 11
+- e manuf_specific_4 12
+- e manuf_specific_5 13
+- e manuf_specific_6 14
+
+# analog gain description registers
+analog_gain_capability 0x0080 16
+- e global 0
+- e alternate_global 2
+analog_gain_code_min 0x0084 16
+analog_gain_code_max 0x0086 16
+analog_gain_code_step 0x0088 16
+analog_gain_type 0x008a 16
+analog_gain_m0 0x008c 16
+analog_gain_c0 0x008e 16
+analog_gain_m1 0x0090 16
+analog_gain_c1 0x0092 16
+analog_linear_gain_min 0x0094 16 v1.1
+analog_linear_gain_max 0x0096 16 v1.1
+analog_linear_gain_step_size 0x0098 16 v1.1
+analog_exponential_gain_min 0x009a 16 v1.1
+analog_exponential_gain_max 0x009c 16 v1.1
+analog_exponential_gain_step_size 0x009e 16 v1.1
+
+# data format description registers
+data_format_model_type 0x00c0 8
+- e normal 1
+- e extended 2
+data_format_model_subtype 0x00c1 8
+- f rows 0 3
+- f columns 4 7
+data_format_descriptor(n) 0x00c2 16 f
+- l n 0 15 2
+- f compressed 0 7
+- f uncompressed 8 15
+
+# general set-up registers
+mode_select 0x0100 8
+- e software_standby 0
+- e streaming 1
+image_orientation 0x0101 8
+- b horizontal_mirror 0
+- b vertical_flip 1
+software_reset 0x0103 8
+- e off 0
+- e on 1
+grouped_parameter_hold 0x0104 8
+mask_corrupted_frames 0x0105 8
+- e allow 0
+- e mask 1
+fast_standby_ctrl 0x0106 8
+- e complete_frames 0
+- e frame_truncation 1
+CCI_address_ctrl 0x0107 8
+2nd_CCI_if_ctrl 0x0108 8
+- b enable 0
+- b ack 1
+2nd_CCI_address_ctrl 0x0109 8
+CSI_channel_identifier 0x0110 8
+CSI_signaling_mode 0x0111 8
+- e csi_2_dphy 2
+- e csi_2_cphy 3
+CSI_data_format 0x0112 16
+CSI_lane_mode 0x0114 8
+DPCM_Frame_DT 0x011d 8
+Bottom_embedded_data_DT 0x011e 8
+Bottom_embedded_data_VC 0x011f 8
+
+gain_mode 0x0120 8
+- e global 0
+- e alternate 1
+ADC_bit_depth 0x0121 8
+emb_data_ctrl 0x0122 v1.1
+- b raw8_packing_for_raw16 0
+- b raw10_packing_for_raw20 1
+- b raw12_packing_for_raw24 2
+
+GPIO_TRIG_mode 0x0130 8
+extclk_frequency_mhz 0x0136 16 ireal
+temp_sensor_ctrl 0x0138 8
+- b enable 0
+temp_sensor_mode 0x0139 8
+temp_sensor_output 0x013a 8
+
+# integration time registers
+fine_integration_time 0x0200 16
+coarse_integration_time 0x0202 16
+
+# analog gain registers
+analog_gain_code_global 0x0204 16
+analog_linear_gain_global 0x0206 16 v1.1
+analog_exponential_gain_global 0x0208 16 v1.1
+
+# digital gain registers
+digital_gain_global 0x020e 16
+
+# hdr control registers
+Short_analog_gain_global 0x0216 16
+Short_digital_gain_global 0x0218 16
+
+HDR_mode 0x0220 8
+- b enabled 0
+- b separate_analog_gain 1
+- b upscaling 2
+- b reset_sync 3
+- b timing_mode 4
+- b exposure_ctrl_direct 5
+- b separate_digital_gain 6
+HDR_resolution_reduction 0x0221 8
+- f row 0 3
+- f column 4 7
+Exposure_ratio 0x0222 8
+HDR_internal_bit_depth 0x0223 8
+Direct_short_integration_time 0x0224 16
+Short_analog_linear_gain_global 0x0226 16 v1.1
+Short_analog_exponential_gain_global 0x0228 16 v1.1
+
+# clock set-up registers
+vt_pix_clk_div 0x0300 16
+vt_sys_clk_div 0x0302 16
+pre_pll_clk_div 0x0304 16
+#vt_pre_pll_clk_div 0x0304 16
+pll_multiplier 0x0306 16
+#vt_pll_multiplier 0x0306 16
+op_pix_clk_div 0x0308 16
+op_sys_clk_div 0x030a 16
+op_pre_pll_clk_div 0x030c 16
+op_pll_multiplier 0x030e 16
+pll_mode 0x0310 8
+- f 0 0
+- e single 0
+- e dual 1
+op_pix_clk_div_rev 0x0312 16 v1.1
+op_sys_clk_div_rev 0x0314 16 v1.1
+
+# frame timing registers
+frame_length_lines 0x0340 16
+line_length_pck 0x0342 16
+
+# image size registers
+x_addr_start 0x0344 16
+y_addr_start 0x0346 16
+x_addr_end 0x0348 16
+y_addr_end 0x034a 16
+x_output_size 0x034c 16
+y_output_size 0x034e 16
+
+# timing mode registers
+Frame_length_ctrl 0x0350 8
+- b automatic 0
+Timing_mode_ctrl 0x0352 8
+- b manual_readout 0
+- b delayed_exposure 1
+Start_readout_rs 0x0353 8
+- b manual_readout_start 0
+Frame_margin 0x0354 16
+
+# sub-sampling registers
+x_even_inc 0x0380 16
+x_odd_inc 0x0382 16
+y_even_inc 0x0384 16
+y_odd_inc 0x0386 16
+
+# monochrome readout registers
+monochrome_en 0x0390 v1.1
+- e enabled 0
+
+# image scaling registers
+Scaling_mode 0x0400 16
+- e no_scaling 0
+- e horizontal 1
+scale_m 0x0404 16
+scale_n 0x0406 16
+digital_crop_x_offset 0x0408 16
+digital_crop_y_offset 0x040a 16
+digital_crop_image_width 0x040c 16
+digital_crop_image_height 0x040e 16
+
+# image compression registers
+compression_mode 0x0500 16
+- e none 0
+- e dpcm_pcm_simple 1
+
+# test pattern registers
+test_pattern_mode 0x0600 16
+- e none 0
+- e solid_color 1
+- e color_bars 2
+- e fade_to_grey 3
+- e pn9 4
+- e color_tile 5
+test_data_red 0x0602 16
+test_data_greenR 0x0604 16
+test_data_blue 0x0606 16
+test_data_greenB 0x0608 16
+value_step_size_smooth 0x060a 8
+value_step_size_quantised 0x060b 8
+
+# phy configuration registers
+tclk_post 0x0800 8
+ths_prepare 0x0801 8
+ths_zero_min 0x0802 8
+ths_trail 0x0803 8
+tclk_trail_min 0x0804 8
+tclk_prepare 0x0805 8
+tclk_zero 0x0806 8
+tlpx 0x0807 8
+phy_ctrl 0x0808 8
+- e auto 0
+- e UI 1
+- e manual 2
+tclk_post_ex 0x080a 16
+ths_prepare_ex 0x080c 16
+ths_zero_min_ex 0x080e 16
+ths_trail_ex 0x0810 16
+tclk_trail_min_ex 0x0812 16
+tclk_prepare_ex 0x0814 16
+tclk_zero_ex 0x0816 16
+tlpx_ex 0x0818 16
+
+# link rate register
+requested_link_rate 0x0820 32 u16.16
+
+# equalization control registers
+DPHY_equalization_mode 0x0824 8 v1.1
+- b eq2 0
+PHY_equalization_ctrl 0x0825 8 v1.1
+- b enable 0
+
+# d-phy preamble control registers
+DPHY_preamble_ctrl 0x0826 8 v1.1
+- b enable 0
+DPHY_preamble_length 0x0826 8 v1.1
+
+# d-phy spread spectrum control registers
+PHY_SSC_ctrl 0x0828 8 v1.1
+- b enable 0
+
+# manual lp control register
+manual_LP_ctrl 0x0829 8 v1.1
+- b enable 0
+
+# additional phy configuration registers
+twakeup 0x082a v1.1
+tinit 0x082b v1.1
+ths_exit 0x082c v1.1
+ths_exit_ex 0x082e 16 v1.1
+
+# phy calibration configuration registers
+PHY_periodic_calibration_ctrl 0x0830 8
+- b frame_blanking 0
+PHY_periodic_calibration_interval 0x0831 8
+PHY_init_calibration_ctrl 0x0832 8
+- b stream_start 0
+DPHY_calibration_mode 0x0833 8 v1.1
+- b also_alternate 0
+CPHY_calibration_mode 0x0834 8 v1.1
+- e format_1 0
+- e format_2 1
+- e format_3 2
+t3_calpreamble_length 0x0835 8 v1.1
+t3_calpreamble_length_per 0x0836 8 v1.1
+t3_calaltseq_length 0x0837 8 v1.1
+t3_calaltseq_length_per 0x0838 8 v1.1
+FM2_init_seed 0x083a 16 v1.1
+t3_caludefseq_length 0x083c 16 v1.1
+t3_caludefseq_length_per 0x083e 16 v1.1
+
+# c-phy manual control registers
+TGR_Preamble_Length 0x0841 8
+- b preamable_prog_seq 7
+- f begin_preamble_length 0 5
+TGR_Post_Length 0x0842 8
+- f post_length 0 4
+TGR_Preamble_Prog_Sequence(n2) 0x0843
+- l n2 0 6 1
+- f symbol_n_1 3 5
+- f symbol_n 0 2
+t3_prepare 0x084e 16
+t3_lpx 0x0850 16
+
+# alps control register
+ALPS_ctrl 0x085a 8
+- b lvlp_dphy 0
+- b lvlp_cphy 1
+- b alp_cphy 2
+
+# lrte control registers
+TX_REG_CSI_EPD_EN_SSP_cphy 0x0860 16
+TX_REG_CSI_EPD_OP_SLP_cphy 0x0862 16
+TX_REG_CSI_EPD_EN_SSP_dphy 0x0864 16
+TX_REG_CSI_EPD_OP_SLP_dphy 0x0866 16
+TX_REG_CSI_EPD_MISC_OPTION_cphy 0x0868 v1.1
+TX_REG_CSI_EPD_MISC_OPTION_dphy 0x0869 v1.1
+
+# scrambling control registers
+Scrambling_ctrl 0x0870
+- b enabled 0
+- f 2 3
+- e 1_seed_cphy 0
+- e 4_seed_cphy 3
+lane_seed_value(seed, lane) 0x0872 16
+- l seed 0 3 0x10
+- l lane 0 7 0x2
+
+# usl control registers
+TX_USL_REV_ENTRY 0x08c0 16 v1.1
+TX_USL_REV_Clock_Counter 0x08c2 16 v1.1
+TX_USL_REV_LP_Counter 0x08c4 16 v1.1
+TX_USL_REV_Frame_Counter 0x08c6 16 v1.1
+TX_USL_REV_Chronological_Timer 0x08c8 16 v1.1
+TX_USL_FWD_ENTRY 0x08ca 16 v1.1
+TX_USL_GPIO 0x08cc 16 v1.1
+TX_USL_Operation 0x08ce 16 v1.1
+- b reset 0
+TX_USL_ALP_ctrl 0x08d0 16 v1.1
+- b clock_pause 0
+TX_USL_APP_BTA_ACK_TIMEOUT 0x08d2 16 v1.1
+TX_USL_SNS_BTA_ACK_TIMEOUT 0x08d2 16 v1.1
+USL_Clock_Mode_d_ctrl 0x08d2 v1.1
+- b cont_clock_standby 0
+- b cont_clock_vblank 1
+- b cont_clock_hblank 2
+
+# binning configuration registers
+binning_mode 0x0900 8
+binning_type 0x0901 8
+binning_weighting 0x0902 8
+
+# data transfer interface registers
+data_transfer_if_1_ctrl 0x0a00 8
+- b enable 0
+- b write 1
+- b clear_error 2
+data_transfer_if_1_status 0x0a01 8
+- b read_if_ready 0
+- b write_if_ready 1
+- b data_corrupted 2
+- b improper_if_usage 3
+data_transfer_if_1_page_select 0x0a02 8
+data_transfer_if_1_data(p) 0x0a04 8 f
+- l p 0 63 1
+
+# image processing and sensor correction configuration registers
+shading_correction_en 0x0b00 8
+- b enable 0
+luminance_correction_level 0x0b01 8
+green_imbalance_filter_en 0x0b02 8
+- b enable 0
+mapped_defect_correct_en 0x0b05 8
+- b enable 0
+single_defect_correct_en 0x0b06 8
+- b enable 0
+dynamic_couplet_correct_en 0x0b08 8
+- b enable 0
+combined_defect_correct_en 0x0b0a 8
+- b enable 0
+module_specific_correction_en 0x0b0c 8
+- b enable 0
+dynamic_triplet_defect_correct_en 0x0b13 8
+- b enable 0
+NF_ctrl 0x0b15 8
+- b luma 0
+- b chroma 1
+- b combined 2
+
+# optical black pixel readout registers
+OB_readout_control 0x0b30 8
+- b enable 0
+- b interleaving 1
+OB_virtual_channel 0x0b31 8
+OB_DT 0x0b32 8
+OB_data_format 0x0b33 8
+
+# color temperature feedback registers
+color_temperature 0x0b8c 16
+absolute_gain_greenr 0x0b8e 16
+absolute_gain_red 0x0b90 16
+absolute_gain_blue 0x0b92 16
+absolute_gain_greenb 0x0b94 16
+
+# cfa conversion registers
+CFA_conversion_ctrl 0x0ba0 v1.1
+- b bayer_conversion_enable 0
+
+# flash strobe and sa strobe control registers
+flash_strobe_adjustment 0x0c12 8
+flash_strobe_start_point 0x0c14 16
+tflash_strobe_delay_rs_ctrl 0x0c16 16
+tflash_strobe_width_high_rs_ctrl 0x0c18 16
+flash_mode_rs 0x0c1a 8
+- b continuous 0
+- b truncate 1
+- b async 3
+flash_trigger_rs 0x0c1b 8
+flash_status 0x0c1c 8
+- b retimed 0
+sa_strobe_mode 0x0c1d 8
+- b continuous 0
+- b truncate 1
+- b async 3
+- b adjust_edge 4
+sa_strobe_start_point 0x0c1e 16
+tsa_strobe_delay_ctrl 0x0c20 16
+tsa_strobe_width_ctrl 0x0c22 16
+sa_strobe_trigger 0x0c24 8
+sa_strobe_status 0x0c25 8
+- b retimed 0
+tSA_strobe_re_delay_ctrl 0x0c30 16
+tSA_strobe_fe_delay_ctrl 0x0c32 16
+
+# pdaf control registers
+PDAF_ctrl 0x0d00 16
+- b enable 0
+- b processed 1
+- b interleaved 2
+- b visible_pdaf_correction 3
+PDAF_VC 0x0d02 8
+PDAF_DT 0x0d03 8
+pd_x_addr_start 0x0d04 16
+pd_y_addr_start 0x0d06 16
+pd_x_addr_end 0x0d08 16
+pd_y_addr_end 0x0d0a 16
+
+# bracketing interface configuration registers
+bracketing_LUT_ctrl 0x0e00 8
+bracketing_LUT_mode 0x0e01 8
+- b continue_streaming 0
+- b loop_mode 1
+bracketing_LUT_entry_ctrl 0x0e02 8
+bracketing_LUT_frame(n) 0x0e10 v1.1 f
+- l n 0 0xef 1
+
+# integration time and gain parameter limit registers
+integration_time_capability 0x1000 16
+- b fine 0
+coarse_integration_time_min 0x1004 16
+coarse_integration_time_max_margin 0x1006 16
+fine_integration_time_min 0x1008 16
+fine_integration_time_max_margin 0x100a 16
+
+# digital gain parameter limit registers
+digital_gain_capability 0x1081
+- e none 0
+- e global 2
+digital_gain_min 0x1084 16
+digital_gain_max 0x1086 16
+digital_gain_step_size 0x1088 16
+
+# data pedestal capability registers
+Pedestal_capability 0x10e0 8 v1.1
+
+# adc capability registers
+ADC_capability 0x10f0 8
+- b bit_depth_ctrl 0
+ADC_bit_depth_capability 0x10f4 32 v1.1
+
+# video timing parameter limit registers
+min_ext_clk_freq_mhz 0x1100 32 float_ireal
+max_ext_clk_freq_mhz 0x1104 32 float_ireal
+min_pre_pll_clk_div 0x1108 16
+# min_vt_pre_pll_clk_div 0x1108 16
+max_pre_pll_clk_div 0x110a 16
+# max_vt_pre_pll_clk_div 0x110a 16
+min_pll_ip_clk_freq_mhz 0x110c 32 float_ireal
+# min_vt_pll_ip_clk_freq_mhz 0x110c 32 float_ireal
+max_pll_ip_clk_freq_mhz 0x1110 32 float_ireal
+# max_vt_pll_ip_clk_freq_mhz 0x1110 32 float_ireal
+min_pll_multiplier 0x1114 16
+# min_vt_pll_multiplier 0x1114 16
+max_pll_multiplier 0x1116 16
+# max_vt_pll_multiplier 0x1116 16
+min_pll_op_clk_freq_mhz 0x1118 32 float_ireal
+max_pll_op_clk_freq_mhz 0x111c 32 float_ireal
+
+# video timing set-up capability registers
+min_vt_sys_clk_div 0x1120 16
+max_vt_sys_clk_div 0x1122 16
+min_vt_sys_clk_freq_mhz 0x1124 32 float_ireal
+max_vt_sys_clk_freq_mhz 0x1128 32 float_ireal
+min_vt_pix_clk_freq_mhz 0x112c 32 float_ireal
+max_vt_pix_clk_freq_mhz 0x1130 32 float_ireal
+min_vt_pix_clk_div 0x1134 16
+max_vt_pix_clk_div 0x1136 16
+clock_calculation 0x1138
+- b lane_speed 0
+- b link_decoupled 1
+- b dual_pll_op_sys_ddr 2
+- b dual_pll_op_pix_ddr 3
+num_of_vt_lanes 0x1139
+num_of_op_lanes 0x113a
+op_bits_per_lane 0x113b 8 v1.1
+
+# frame timing parameter limits
+min_frame_length_lines 0x1140 16
+max_frame_length_lines 0x1142 16
+min_line_length_pck 0x1144 16
+max_line_length_pck 0x1146 16
+min_line_blanking_pck 0x1148 16
+min_frame_blanking_lines 0x114a 16
+min_line_length_pck_step_size 0x114c
+timing_mode_capability 0x114d
+- b auto_frame_length 0
+- b rolling_shutter_manual_readout 2
+- b delayed_exposure_start 3
+- b manual_exposure_embedded_data 4
+frame_margin_max_value 0x114e 16
+frame_margin_min_value 0x1150
+gain_delay_type 0x1151
+- e fixed 0
+- e variable 1
+
+# output clock set-up capability registers
+min_op_sys_clk_div 0x1160 16
+max_op_sys_clk_div 0x1162 16
+min_op_sys_clk_freq_mhz 0x1164 32 float_ireal
+max_op_sys_clk_freq_mhz 0x1168 32 float_ireal
+min_op_pix_clk_div 0x116c 16
+max_op_pix_clk_div 0x116e 16
+min_op_pix_clk_freq_mhz 0x1170 32 float_ireal
+max_op_pix_clk_freq_mhz 0x1174 32 float_ireal
+
+# image size parameter limit registers
+x_addr_min 0x1180 16
+y_addr_min 0x1182 16
+x_addr_max 0x1184 16
+y_addr_max 0x1186 16
+min_x_output_size 0x1188 16
+min_y_output_size 0x118a 16
+max_x_output_size 0x118c 16
+max_y_output_size 0x118e 16
+
+x_addr_start_div_constant 0x1190 v1.1
+y_addr_start_div_constant 0x1191 v1.1
+x_addr_end_div_constant 0x1192 v1.1
+y_addr_end_div_constant 0x1193 v1.1
+x_size_div 0x1194 v1.1
+y_size_div 0x1195 v1.1
+x_output_div 0x1196 v1.1
+y_output_div 0x1197 v1.1
+non_flexible_resolution_support 0x1198 v1.1
+- b new_pix_addr 0
+- b new_output_res 1
+- b output_crop_no_pad 2
+- b output_size_lane_dep 3
+
+min_op_pre_pll_clk_div 0x11a0 16
+max_op_pre_pll_clk_div 0x11a2 16
+min_op_pll_ip_clk_freq_mhz 0x11a4 32 float_ireal
+max_op_pll_ip_clk_freq_mhz 0x11a8 32 float_ireal
+min_op_pll_multiplier 0x11ac 16
+max_op_pll_multiplier 0x11ae 16
+min_op_pll_op_clk_freq_mhz 0x11b0 32 float_ireal
+max_op_pll_op_clk_freq_mhz 0x11b4 32 float_ireal
+clock_tree_pll_capability 0x11b8 8
+- b dual_pll 0
+- b single_pll 1
+- b ext_divider 2
+- b flexible_op_pix_clk_div 3
+clock_capa_type_capability 0x11b9 v1.1
+- b ireal 0
+
+# sub-sampling parameters limit registers
+min_even_inc 0x11c0 16
+min_odd_inc 0x11c2 16
+max_even_inc 0x11c4 16
+max_odd_inc 0x11c6 16
+aux_subsamp_capability 0x11c8 v1.1
+- b factor_power_of_2 1
+aux_subsamp_mono_capability 0x11c9 v1.1
+- b factor_power_of_2 1
+monochrome_capability 0x11ca v1.1
+- e inc_odd 0
+- e inc_even 1
+pixel_readout_capability 0x11cb v1.1
+- e bayer 0
+- e monochrome 1
+- e bayer_and_mono 2
+min_even_inc_mono 0x11cc 16 v1.1
+max_even_inc_mono 0x11ce 16 v1.1
+min_odd_inc_mono 0x11d0 16 v1.1
+max_odd_inc_mono 0x11d2 16 v1.1
+min_even_inc_bc2 0x11d4 16 v1.1
+max_even_inc_bc2 0x11d6 16 v1.1
+min_odd_inc_bc2 0x11d8 16 v1.1
+max_odd_inc_bc2 0x11da 16 v1.1
+min_even_inc_mono_bc2 0x11dc 16 v1.1
+max_even_inc_mono_bc2 0x11de 16 v1.1
+min_odd_inc_mono_bc2 0x11f0 16 v1.1
+max_odd_inc_mono_bc2 0x11f2 16 v1.1
+
+# image scaling limit parameters
+scaling_capability 0x1200 16
+- e none 0
+- e horizontal 1
+- e reserved 2
+scaler_m_min 0x1204 16
+scaler_m_max 0x1206 16
+scaler_n_min 0x1208 16
+scaler_n_max 0x120a 16
+digital_crop_capability 0x120e
+- e none 0
+- e input_crop 1
+
+# hdr limit registers
+hdr_capability_1 0x1210
+- b 2x2_binning 0
+- b combined_analog_gain 1
+- b separate_analog_gain 2
+- b upscaling 3
+- b reset_sync 4
+- b direct_short_exp_timing 5
+- b direct_short_exp_synthesis 6
+min_hdr_bit_depth 0x1211
+hdr_resolution_sub_types 0x1212
+hdr_resolution_sub_type(n) 0x1213
+- l n 0 1 1
+- f row 0 3
+- f column 4 7
+hdr_capability_2 0x121b
+- b combined_digital_gain 0
+- b separate_digital_gain 1
+- b timing_mode 3
+- b synthesis_mode 4
+max_hdr_bit_depth 0x121c
+
+# usl capability register
+usl_support_capability 0x1230 v1.1
+- b clock_tree 0
+- b rev_clock_tree 1
+- b rev_clock_calc 2
+usl_clock_mode_d_capability 0x1231 v1.1
+- b cont_clock_standby 0
+- b cont_clock_vblank 1
+- b cont_clock_hblank 2
+- b noncont_clock_standby 3
+- b noncont_clock_vblank 4
+- b noncont_clock_hblank 5
+min_op_sys_clk_div_rev 0x1234 v1.1
+max_op_sys_clk_div_rev 0x1236 v1.1
+min_op_pix_clk_div_rev 0x1238 v1.1
+max_op_pix_clk_div_rev 0x123a v1.1
+min_op_sys_clk_freq_rev_mhz 0x123c 32 v1.1 float_ireal
+max_op_sys_clk_freq_rev_mhz 0x1240 32 v1.1 float_ireal
+min_op_pix_clk_freq_rev_mhz 0x1244 32 v1.1 float_ireal
+max_op_pix_clk_freq_rev_mhz 0x1248 32 v1.1 float_ireal
+max_bitrate_rev_d_mode_mbps 0x124c 32 v1.1 ireal
+max_symrate_rev_c_mode_msps 0x1250 32 v1.1 ireal
+
+# image compression capability registers
+compression_capability 0x1300
+- b dpcm_pcm_simple 0
+
+# test mode capability registers
+test_mode_capability 0x1310 16
+- b solid_color 0
+- b color_bars 1
+- b fade_to_grey 2
+- b pn9 3
+- b color_tile 5
+pn9_data_format1 0x1312
+pn9_data_format2 0x1313
+pn9_data_format3 0x1314
+pn9_data_format4 0x1315
+pn9_misc_capability 0x1316
+- f num_pixels 0 2
+- b compression 3
+test_pattern_capability 0x1317 v1.1
+- b no_repeat 1
+pattern_size_div_m1 0x1318 v1.1
+
+# fifo capability registers
+fifo_support_capability 0x1502
+- e none 0
+- e derating 1
+- e derating_overrating 2
+
+# csi-2 capability registers
+phy_ctrl_capability 0x1600
+- b auto_phy_ctl 0
+- b ui_phy_ctl 1
+- b dphy_time_ui_reg_1_ctl 2
+- b dphy_time_ui_reg_2_ctl 3
+- b dphy_time_ctl 4
+- b dphy_ext_time_ui_reg_1_ctl 5
+- b dphy_ext_time_ui_reg_2_ctl 6
+- b dphy_ext_time_ctl 7
+csi_dphy_lane_mode_capability 0x1601
+- b 1_lane 0
+- b 2_lane 1
+- b 3_lane 2
+- b 4_lane 3
+- b 5_lane 4
+- b 6_lane 5
+- b 7_lane 6
+- b 8_lane 7
+csi_signaling_mode_capability 0x1602
+- b csi_dphy 2
+- b csi_cphy 3
+fast_standby_capability 0x1603
+- e no_frame_truncation 0
+- e frame_truncation 1
+csi_address_control_capability 0x1604
+- b cci_addr_change 0
+- b 2nd_cci_addr 1
+- b sw_changeable_2nd_cci_addr 2
+data_type_capability 0x1605
+- b dpcm_programmable 0
+- b bottom_embedded_dt_programmable 1
+- b bottom_embedded_vc_programmable 2
+- b ext_vc_range 3
+csi_cphy_lane_mode_capability 0x1606
+- b 1_lane 0
+- b 2_lane 1
+- b 3_lane 2
+- b 4_lane 3
+- b 5_lane 4
+- b 6_lane 5
+- b 7_lane 6
+- b 8_lane 7
+emb_data_capability 0x1607 v1.1
+- b two_bytes_per_raw16 0
+- b two_bytes_per_raw20 1
+- b two_bytes_per_raw24 2
+- b no_one_byte_per_raw16 3
+- b no_one_byte_per_raw20 4
+- b no_one_byte_per_raw24 5
+max_per_lane_bitrate_lane_d_mode_mbps(n) 0x1608 32 ireal
+- l n 0 7 4 4,0x32
+temp_sensor_capability 0x1618
+- b supported 0
+- b CCS_format 1
+- b reset_0x80 2
+max_per_lane_bitrate_lane_c_mode_mbps(n) 0x161a 32 ireal
+- l n 0 7 4 4,0x30
+dphy_equalization_capability 0x162b
+- b equalization_ctrl 0
+- b eq1 1
+- b eq2 2
+cphy_equalization_capability 0x162c
+- b equalization_ctrl 0
+dphy_preamble_capability 0x162d
+- b preamble_seq_ctrl 0
+dphy_ssc_capability 0x162e
+- b supported 0
+cphy_calibration_capability 0x162f
+- b manual 0
+- b manual_streaming 1
+- b format_1_ctrl 2
+- b format_2_ctrl 3
+- b format_3_ctrl 4
+dphy_calibration_capability 0x1630
+- b manual 0
+- b manual_streaming 1
+- b alternate_seq 2
+phy_ctrl_capability_2 0x1631
+- b tgr_length 0
+- b tgr_preamble_prog_seq 1
+- b extra_cphy_manual_timing 2
+- b clock_based_manual_cdphy 3
+- b clock_based_manual_dphy 4
+- b clock_based_manual_cphy 5
+- b manual_lp_dphy 6
+- b manual_lp_cphy 7
+lrte_cphy_capability 0x1632
+- b pdq_short 0
+- b spacer_short 1
+- b pdq_long 2
+- b spacer_long 3
+- b spacer_no_pdq 4
+lrte_dphy_capability 0x1633
+- b pdq_short_opt1 0
+- b spacer_short_opt1 1
+- b pdq_long_opt1 2
+- b spacer_long_opt1 3
+- b spacer_short_opt2 4
+- b spacer_long_opt2 5
+- b spacer_no_pdq_opt1 6
+- b spacer_variable_opt2 7
+alps_capability_dphy 0x1634
+- e lvlp_not_supported 0 0x3
+- e lvlp_supported 1 0x3
+- e controllable_lvlp 2 0x3
+alps_capability_cphy 0x1635
+- e lvlp_not_supported 0 0x3
+- e lvlp_supported 1 0x3
+- e controllable_lvlp 2 0x3
+- e alp_not_supported 0xc 0xc
+- e alp_supported 0xd 0xc
+- e controllable_alp 0xe 0xc
+scrambling_capability 0x1636
+- b scrambling_supported 0
+- f max_seeds_per_lane_c 1 2
+- e 1 0
+- e 4 3
+- f num_seed_regs 3 5
+- e 0 0
+- e 1 1
+- e 4 4
+- b num_seed_per_lane 6
+dphy_manual_constant 0x1637
+cphy_manual_constant 0x1638
+CSI2_interface_capability_misc 0x1639 v1.1
+- b eotp_short_pkt_opt2 0
+PHY_ctrl_capability_3 0x165c v1.1
+- b dphy_timing_not_multiple 0
+- b dphy_min_timing_value_1 1
+- b twakeup_supported 2
+- b tinit_supported 3
+- b ths_exit_supported 4
+- b cphy_timing_not_multiple 5
+- b cphy_min_timing_value_1 6
+dphy_sf 0x165d v1.1
+cphy_sf 0x165e v1.1
+- f twakeup 0 3
+- f tinit 4 7
+dphy_limits_1 0x165f v1.1
+- f ths_prepare 0 3
+- f ths_zero 4 7
+dphy_limits_2 0x1660 v1.1
+- f ths_trail 0 3
+- f tclk_trail_min 4 7
+dphy_limits_3 0x1661 v1.1
+- f tclk_prepare 0 3
+- f tclk_zero 4 7
+dphy_limits_4 0x1662 v1.1
+- f tclk_post 0 3
+- f tlpx 4 7
+dphy_limits_5 0x1663 v1.1
+- f ths_exit 0 3
+- f twakeup 4 7
+dphy_limits_6 0x1664 v1.1
+- f tinit 0 3
+cphy_limits_1 0x1665 v1.1
+- f t3_prepare_max 0 3
+- f t3_lpx_max 4 7
+cphy_limits_2 0x1666 v1.1
+- f ths_exit_max 0 3
+- f twakeup_max 4 7
+cphy_limits_3 0x1667 v1.1
+- f tinit_max 0 3
+
+# binning capability registers
+min_frame_length_lines_bin 0x1700 16
+max_frame_length_lines_bin 0x1702 16
+min_line_length_pck_bin 0x1704 16
+max_line_length_pck_bin 0x1706 16
+min_line_blanking_pck_bin 0x1708 16
+fine_integration_time_min_bin 0x170a 16
+fine_integration_time_max_margin_bin 0x170c 16
+binning_capability 0x1710
+- e unsupported 0
+- e binning_then_subsampling 1
+- e subsampling_then_binning 2
+binning_weighting_capability 0x1711
+- b averaged 0
+- b summed 1
+- b bayer_corrected 2
+- b module_specific_weight 3
+binning_sub_types 0x1712
+binning_sub_type(n) 0x1713
+- l n 0 63 1
+- f row 0 3
+- f column 4 7
+binning_weighting_mono_capability 0x1771 v1.1
+- b averaged 0
+- b summed 1
+- b bayer_corrected 2
+- b module_specific_weight 3
+binning_sub_types_mono 0x1772 v1.1
+binning_sub_type_mono(n) 0x1773 v1.1 f
+- l n 0 63 1
+
+# data transfer interface capability registers
+data_transfer_if_capability 0x1800
+- b supported 0
+- b polling 2
+
+# sensor correction capability registers
+shading_correction_capability 0x1900
+- b color_shading 0
+- b luminance_correction 1
+green_imbalance_capability 0x1901
+- b supported 0
+module_specific_correction_capability 0x1903
+defect_correction_capability 0x1904 16
+- b mapped_defect 0
+- b dynamic_couplet 2
+- b dynamic_single 5
+- b combined_dynamic 8
+defect_correction_capability_2 0x1906 16
+- b dynamic_triplet 3
+nf_capability 0x1908
+- b luma 0
+- b chroma 1
+- b combined 2
+
+# optical black readout capability registers
+ob_readout_capability 0x1980
+- b controllable_readout 0
+- b visible_pixel_readout 1
+- b different_vc_readout 2
+- b different_dt_readout 3
+- b prog_data_format 4
+
+# color feedback capability registers
+color_feedback_capability 0x1987
+- b kelvin 0
+- b awb_gain 1
+
+# cfa pattern capability registers
+CFA_pattern_capability 0x1990 v1.1
+- e bayer 0
+- e monochrome 1
+- e 4x4_quad_bayer 2
+- e vendor_specific 3
+CFA_pattern_conversion_capability 0x1991 v1.1
+- b bayer 0
+
+# timer capability registers
+flash_mode_capability 0x1a02
+- b single_strobe 0
+sa_strobe_mode_capability 0x1a03
+- b fixed_width 0
+- b edge_ctrl 1
+
+# soft reset capability registers
+reset_max_delay 0x1a10 v1.1
+reset_min_time 0x1a11 v1.1
+
+# pdaf capability registers
+pdaf_capability_1 0x1b80
+- b supported 0
+- b processed_bottom_embedded 1
+- b processed_interleaved 2
+- b raw_bottom_embedded 3
+- b raw_interleaved 4
+- b visible_pdaf_correction 5
+- b vc_interleaving 6
+- b dt_interleaving 7
+pdaf_capability_2 0x1b81
+- b ROI 0
+- b after_digital_crop 1
+- b ctrl_retimed 2
+
+# bracketing interface capability registers
+bracketing_lut_capability_1 0x1c00
+- b coarse_integration 0
+- b global_analog_gain 1
+- b flash 4
+- b global_digital_gain 5
+- b alternate_global_analog_gain 6
+bracketing_lut_capability_2 0x1c01
+- b single_bracketing_mode 0
+- b looped_bracketing_mode 1
+bracketing_lut_size 0x1c02
diff --git a/Documentation/driver-api/media/drivers/ccs/ccs.rst b/Documentation/driver-api/media/drivers/ccs/ccs.rst
new file mode 100644
index 000000000000..5d4451339b7f
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/ccs/ccs.rst
@@ -0,0 +1,82 @@
+.. SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
+
+.. include:: <isonum.txt>
+
+.. _media-ccs-driver:
+
+MIPI CCS camera sensor driver
+=============================
+
+The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS
+<https://www.mipi.org/specifications/camera-command-set>`_ compliant
+camera sensors.
+
+Also see :ref:`the CCS driver UAPI documentation <media-ccs-uapi>`.
+
+CCS static data
+---------------
+
+The MIPI CCS driver supports CCS static data for all compliant devices,
+including not just those compliant with CCS 1.1 but also CCS 1.0 and SMIA(++).
+For CCS the file names are formed as
+
+ ccs/ccs-sensor-vvvv-mmmm-rrrr.fw (sensor) and
+ ccs/ccs-module-vvvv-mmmm-rrrr.fw (module).
+
+For SMIA++ compliant devices the corresponding file names are
+
+ ccs/smiapp-sensor-vv-mmmm-rr.fw (sensor) and
+ ccs/smiapp-module-vv-mmmm-rrrr.fw (module).
+
+For SMIA (non-++) compliant devices the static data file name is
+
+ ccs/smia-sensor-vv-mmmm-rr.fw (sensor).
+
+vvvv or vv denotes MIPI and SMIA manufacturer IDs respectively, mmmm model ID
+and rrrr or rr revision number.
+
+CCS tools
+~~~~~~~~~
+
+`CCS tools <https://github.com/MIPI-Alliance/ccs-tools/>`_ is a set of
+tools for working with CCS static data files. CCS tools includes a
+definition of the human-readable CCS static data YAML format and includes a
+program to convert it to a binary.
+
+Register definition generator
+-----------------------------
+
+The ccs-regs.asc file contains MIPI CCS register definitions that are used
+to produce C source code files for definitions that can be better used by
+programs written in C language. As there are many dependencies between the
+produced files, please do not modify them manually as it's error-prone and
+in vain, but instead change the script producing them.
+
+Usage
+~~~~~
+
+Conventionally the script is called this way to update the CCS driver
+definitions:
+
+.. code-block:: none
+
+ $ Documentation/driver-api/media/drivers/ccs/mk-ccs-regs -k \
+ -e drivers/media/i2c/ccs/ccs-regs.h \
+ -L drivers/media/i2c/ccs/ccs-limits.h \
+ -l drivers/media/i2c/ccs/ccs-limits.c \
+ -c Documentation/driver-api/media/drivers/ccs/ccs-regs.asc
+
+CCS PLL calculator
+==================
+
+The CCS PLL calculator is used to compute the PLL configuration, given sensor's
+capabilities as well as board configuration and user specified configuration. As
+the configuration space that encompasses all these configurations is vast, the
+PLL calculator isn't entirely trivial. Yet it is relatively simple to use for a
+driver.
+
+The PLL model implemented by the PLL calculator corresponds to MIPI CCS 1.1.
+
+.. kernel-doc:: drivers/media/i2c/ccs-pll.h
+
+**Copyright** |copy| 2020 Intel Corporation
diff --git a/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs b/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs
new file mode 100755
index 000000000000..3d3152b45821
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/ccs/mk-ccs-regs
@@ -0,0 +1,480 @@
+#!/usr/bin/perl -w
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
+# Copyright (C) 2019--2020 Intel Corporation
+
+use Getopt::Long qw(:config no_ignore_case);
+use File::Basename;
+
+my $ccsregs = "ccs-regs.asc";
+my $header;
+my $regarray;
+my $limitc;
+my $limith;
+my $kernel;
+my $help;
+
+GetOptions("ccsregs|c=s" => \$ccsregs,
+ "header|e=s" => \$header,
+ "regarray|r=s" => \$regarray,
+ "limitc|l=s" => \$limitc,
+ "limith|L=s" => \$limith,
+ "kernel|k" => \$kernel,
+ "help|h" => \$help) or die "can't parse options";
+
+$help = 1 if ! defined $header || ! defined $limitc || ! defined $limith;
+
+if (defined $help) {
+ print <<EOH
+$0 - Create CCS register definitions for C
+
+usage: $0 -c ccs-regs.asc -e header -r regarray -l limit-c -L limit-header [-k]
+
+ -c ccs register file
+ -e header file name
+ -r register description array file name
+ -l limit and capability array file name
+ -L limit and capability header file name
+ -k generate files for kernel space consumption
+EOH
+ ;
+ exit 0;
+}
+
+my $lh_hdr = ! defined $kernel
+ ? '#include "ccs-os.h"' . "\n"
+ : "#include <linux/bits.h>\n#include <linux/types.h>\n";
+my $uint32_t = ! defined $kernel ? 'uint32_t' : 'u32';
+my $uint16_t = ! defined $kernel ? 'uint16_t' : 'u16';
+
+open(my $R, "< $ccsregs") or die "can't open $ccsregs";
+
+open(my $H, "> $header") or die "can't open $header";
+my $A;
+if (defined $regarray) {
+ open($A, "> $regarray") or die "can't open $regarray";
+}
+open(my $LC, "> $limitc") or die "can't open $limitc";
+open(my $LH, "> $limith") or die "can't open $limith";
+
+my %this;
+
+sub is_limit_reg($) {
+ my $addr = hex $_[0];
+
+ return 0 if $addr < 0x40; # weed out status registers
+ return 0 if $addr >= 0x100 && $addr < 0xfff; # weed out configuration registers
+
+ return 1;
+}
+
+my $uc_header = basename uc $header;
+$uc_header =~ s/[^A-Z0-9]/_/g;
+
+my $copyright = "/* Copyright (C) 2019--2020 Intel Corporation */\n";
+my $license = "SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause";
+my $note = "/*\n * Generated by $0;\n * do not modify.\n */\n";
+
+for my $fh ($A, $LC) {
+ print $fh "// $license\n$copyright$note\n" if defined $fh;
+}
+
+for my $fh ($H, $LH) {
+ print $fh "/* $license */\n$copyright$note\n";
+}
+
+print $H <<EOF
+#ifndef __${uc_header}__
+#define __${uc_header}__
+
+EOF
+ ;
+
+print $H <<EOF
+#include <linux/bits.h>
+
+#include <media/v4l2-cci.h>
+
+EOF
+ if defined $kernel;
+
+print $H "#define CCS_FL_BASE " .
+ (defined $kernel ? "CCI_REG_PRIVATE_SHIFT" : 16) . "\n";
+
+my $flag = -1;
+my $all_flags;
+
+sub bit_def($) {
+ my $bit = shift @_;
+
+ if (defined $kernel) {
+ return "BIT$bit" if $bit =~ /^\(.*\)$/;
+ return "BIT($bit)";
+ }
+ return "(1U << $bit)";
+}
+
+sub flag_str($$) {
+ my ($flag, $check) = @_;
+
+ $$flag++;
+
+ my $flag_str = !$$flag ? "CCS_FL_BASE" : "(CCS_FL_BASE + $$flag)";
+
+ $flag_str = bit_def($flag_str);
+
+ $$check .= " | " if defined $$check;
+
+ $$check .= $flag_str;
+
+ return $flag_str;
+}
+
+if (! defined $kernel) {
+ print $H "#define CCS_FL_16BIT " . flag_str(\$flag, \$all_flags) . "\n";
+ print $H "#define CCS_FL_32BIT " . flag_str(\$flag, \$all_flags) . "\n";
+}
+
+print $H "#define CCS_FL_FLOAT_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
+print $H "#define CCS_FL_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
+print $H "#define CCS_BUILD_BUG \\
+ BUILD_BUG_ON(~CCI_REG_PRIVATE_MASK & ($all_flags))\n"
+ if defined $kernel;
+
+print $H <<EOF
+
+#define CCS_R_ADDR(r) ((r) & 0xffff)
+
+EOF
+ if ! defined $kernel;
+
+print $A <<EOF
+#include <stdint.h>
+#include <stdio.h>
+#include "ccs-extra.h"
+#include "ccs-regs.h"
+
+EOF
+ if defined $A;
+
+my $uc_limith = basename uc $limith;
+$uc_limith =~ s/[^A-Z0-9]/_/g;
+
+print $LH <<EOF
+#ifndef __${uc_limith}__
+#define __${uc_limith}__
+
+$lh_hdr
+struct ccs_limit {
+ $uint32_t reg;
+ $uint16_t size;
+ $uint16_t flags;
+ const char *name;
+};
+
+EOF
+ ;
+print $LH "#define CCS_L_FL_SAME_REG " . bit_def(0) . "\n\n";
+
+print $LH <<EOF
+extern const struct ccs_limit ccs_limits[];
+
+EOF
+ ;
+
+print $LC <<EOF
+#include "ccs-limits.h"
+#include "ccs-regs.h"
+
+const struct ccs_limit ccs_limits[] = {
+EOF
+ ;
+
+my $limitcount = 0;
+my $argdescs;
+my $reglist = "const struct ccs_reg_desc ccs_reg_desc[] = {\n";
+
+sub name_split($$) {
+ my ($name, $addr) = @_;
+ my $args;
+
+ $name =~ /([^\(]+?)(\(.*)/;
+ ($name, $args) = ($1, $2);
+ $args = [split /,\s*/, $args];
+ foreach my $t (@$args) {
+ $t =~ s/[\(\)]//g;
+ $t =~ s/\//\\\//g;
+ }
+
+ return ($name, $addr, $args);
+}
+
+sub tabconv($) {
+ $_ = shift;
+
+ my @l = split "\n", $_;
+
+ map {
+ s/ {8,8}/\t/g;
+ s/\t\K +//;
+ } @l;
+
+ return (join "\n", @l) . "\n";
+}
+
+sub elem_bits(@) {
+ my @flags = @_;
+
+ return 16 if grep /^16$/, @flags;
+ return 32 if grep /^32$/, @flags;
+ return 8;
+}
+
+sub arr_size($) {
+ my $this = $_[0];
+ my $size = $this->{elsize};
+ my $h = $this->{argparams};
+
+ foreach my $arg (@{$this->{args}}) {
+ my $apref = $h->{$arg};
+
+ $size *= $apref->{max} - $apref->{min} + 1;
+ }
+
+ return $size;
+}
+
+sub print_args($$$) {
+ my ($this, $postfix, $is_same_reg) = @_;
+ my ($args, $argparams, $name) =
+ ($this->{args}, $this->{argparams}, $this->{name});
+ my $varname = "ccs_reg_arg_" . (lc $name) . $postfix;
+ my @mins;
+ my @sorted_args = @{$this->{sorted_args}};
+ my $lim_arg;
+ my $size = arr_size($this);
+
+ $argdescs .= "static const struct ccs_reg_arg " . $varname . "[] = {\n";
+
+ foreach my $sorted_arg (@sorted_args) {
+ push @mins, $argparams->{$sorted_arg}->{min};
+ }
+
+ foreach my $sorted_arg (@sorted_args) {
+ my $h = $argparams->{$sorted_arg};
+
+ $argdescs .= "\t{ \"$sorted_arg\", $h->{min}, $h->{max}, $h->{elsize} },\n";
+
+ $lim_arg .= defined $lim_arg ? ", $h->{min}" : "$h->{min}";
+ }
+
+ $argdescs .= "};\n\n";
+
+ $reglist .= "\t{ CCS_R_" . (uc $name) . "(" . (join ",", (@mins)) .
+ "), $size, sizeof($varname) / sizeof(*$varname)," .
+ " \"" . (lc $name) . "\", $varname },\n";
+
+ print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . "($lim_arg), " .
+ $size . ", " . ($is_same_reg ? "CCS_L_FL_SAME_REG" : "0") .
+ ", \"$name" . (defined $this->{discontig} ? " $lim_arg" : "") . "\" },\n"
+ if is_limit_reg $this->{base_addr};
+}
+
+my $hdr_data;
+
+while (<$R>) {
+ chop;
+ s/^\s*//;
+ next if /^[#;]/ || /^$/;
+ if (s/^-\s*//) {
+ if (s/^b\s*//) {
+ my ($bit, $addr) = split /\t+/;
+ $bit = uc $bit;
+ $hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) ."_$bit", bit_def($addr) . "\n";
+ } elsif (s/^f\s*//) {
+ s/[,\.-]/_/g;
+ my @a = split /\s+/;
+ my ($msb, $lsb, $this_field) = reverse @a;
+ @a = ( { "name" => "SHIFT", "addr" => $lsb, "fmt" => "%uU", },
+ { "name" => "MASK", "addr" => (1 << ($msb + 1)) - 1 - ((1 << $lsb) - 1), "fmt" => "0x%" . join(".", ($this{"elsize"} >> 2) x 2) . "x" } );
+ $this{"field"} = $this_field;
+ foreach my $ar (@a) {
+ #print $ar->{fmt}."\n";
+ $hdr_data .= sprintf "#define %-62s " . $ar->{"fmt"} . "\n", "CCS_" . (uc $this{"name"}) . (defined $this_field ? "_" . uc $this_field : "") . "_" . $ar->{"name"}, $ar->{"addr"} . "\n";
+ }
+ } elsif (s/^e\s*//) {
+ s/[,\.-]/_/g;
+ my ($enum, $addr) = split /\s+/;
+ $enum = uc $enum;
+ $hdr_data .= sprintf "#define %-62s %s", "CCS_" . (uc ${this{name}}) . (defined $this{"field"} ? "_" . uc $this{"field"} : "") ."_$enum", $addr . ($addr =~ /0x/i ? "" : "U") . "\n";
+ } elsif (s/^l\s*//) {
+ my ($arg, $min, $max, $elsize, @discontig) = split /\s+/;
+ my $size;
+
+ foreach my $num ($min, $max) {
+ $num = hex $num if $num =~ /0x/i;
+ }
+
+ $hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MIN_$arg"), $min . ($min =~ /0x/i ? "" : "U") . "\n";
+ $hdr_data .= sprintf "#define %-62s %s", "CCS_LIM_" . (uc ${this{name}} . "_MAX_$arg"), $max . ($max =~ /0x/i ? "" : "U") . "\n";
+
+ my $h = $this{argparams};
+
+ $h->{$arg} = { "min" => $min,
+ "max" => $max,
+ "elsize" => $elsize =~ /^0x/ ? hex $elsize : $elsize,
+ "discontig" => \@discontig };
+
+ $this{discontig} = $arg if @discontig;
+
+ next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};
+
+ my $reg_formula = "$this{addr}";
+ my $lim_formula;
+
+ chop $reg_formula;
+
+ $reg_formula = "(" . $reg_formula if $this{flagstring} ne "";
+
+ foreach my $arg (@{$this{args}}) {
+ my $d = $h->{$arg}->{discontig};
+ my $times = $h->{$arg}->{elsize} != 1 ?
+ " * " . $h->{$arg}->{elsize} : "";
+
+ if (@$d) {
+ my ($lim, $offset) = split /,/, $d->[0];
+
+ $reg_formula .= " + (($arg) < $lim ? ($arg)$times : $offset + (($arg) - $lim)$times)";
+ } else {
+ $reg_formula .= " + ($arg)$times";
+ }
+
+ $lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
+ }
+
+ $reg_formula .= ")";
+ $lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
+
+ print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
+ $this{arglist}, $reg_formula .
+ (($this{flagstring} eq "") ? "" :
+ " | " . $this{flagstring} . ")") . "\n");
+
+ print $H tabconv $hdr_data;
+ undef $hdr_data;
+
+ # Sort arguments in descending order by size
+ @{$this{sorted_args}} = sort {
+ $h->{$a}->{elsize} <= $h->{$b}->{elsize}
+ } @{$this{args}};
+
+ if (defined $this{discontig}) {
+ my $da = $this{argparams}->{$this{discontig}};
+ my ($first_discontig) = split /,/, $da->{discontig}->[0];
+ my $max = $da->{max};
+
+ $da->{max} = $first_discontig - 1;
+ print_args(\%this, "", 0);
+
+ $da->{min} = $da->{max} + 1;
+ $da->{max} = $max;
+ print_args(\%this, $first_discontig, 1);
+ } else {
+ print_args(\%this, "", 0);
+ }
+
+ next unless is_limit_reg $this{base_addr};
+
+ print $LH tabconv sprintf "#define %-63s%s\n",
+ "CCS_L_" . (uc $this{name}) . "_OFFSET(" .
+ (join ", ", @{$this{args}}) . ")", "($lim_formula)";
+ }
+
+ if (! @{$this{args}}) {
+ print $H tabconv($hdr_data);
+ undef $hdr_data;
+ }
+
+ next;
+ }
+
+ my ($name, $addr, @flags) = split /\t+/, $_;
+ my $args = [];
+
+ my $sp;
+
+ ($name, $addr, $args) = name_split($name, $addr) if /\(.*\)/;
+
+ $name =~ s/[,\.-]/_/g;
+
+ my $flagstring = "";
+ my $bits = elem_bits(@flags);
+ if (! defined $kernel) {
+ $flagstring .= "| CCS_FL_16BIT " if $bits == 16;
+ $flagstring .= "| CCS_FL_32BIT " if $bits == 32;
+ }
+ $flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
+ $flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
+ $flagstring =~ s/^\| //;
+ $flagstring =~ s/ $//;
+ $flagstring = "($flagstring)" if $flagstring =~ /\|/;
+ my $base_addr = $addr;
+ $addr = "CCI_REG$bits($addr)" if defined $kernel;
+
+ if ($flagstring ne "" && !@$args) {
+ $addr = "($addr | $flagstring)";
+ $flagstring = "";
+ }
+
+ my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
+ $hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
+ if !@$args;
+
+ $name =~ s/\(.*//;
+
+ %this = ( name => $name,
+ addr => $addr,
+ flagstring => $flagstring,
+ base_addr => $base_addr,
+ argparams => {},
+ args => $args,
+ arglist => $arglist,
+ elsize => $bits / 8,
+ );
+
+ if (!@$args) {
+ $reglist .= "\t{ CCS_R_" . (uc $name) . ", 1, 0, \"" . (lc $name) . "\", NULL },\n";
+ print $H tabconv $hdr_data;
+ undef $hdr_data;
+
+ print $LC tabconv sprintf "\t{ CCS_R_" . (uc $name) . ", " .
+ $this{elsize} . ", 0, \"$name\" },\n"
+ if is_limit_reg $this{base_addr};
+ }
+
+ print $LH tabconv sprintf "#define %-63s%s\n",
+ "CCS_L_" . (uc $this{name}), $limitcount++
+ if is_limit_reg $this{base_addr};
+}
+
+if (defined $A) {
+ print $A $argdescs, $reglist;
+
+ print $A "\t{ 0 }\n";
+
+ print $A "};\n";
+}
+
+print $H "\n#endif /* __${uc_header}__ */\n";
+
+print $LH tabconv sprintf "#define %-63s%s\n", "CCS_L_LAST", $limitcount;
+
+print $LH "\n#endif /* __${uc_limith}__ */\n";
+
+print $LC "\t{ 0 } /* Guardian */\n";
+print $LC "};\n";
+
+close($R);
+close($H);
+close($A) if defined $A;
+close($LC);
+close($LH);
diff --git a/Documentation/driver-api/media/drivers/cpia2_devel.rst b/Documentation/driver-api/media/drivers/cpia2_devel.rst
deleted file mode 100644
index decaa4768c78..000000000000
--- a/Documentation/driver-api/media/drivers/cpia2_devel.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The cpia2 driver
-================
-
-Authors: Peter Pregler <Peter_Pregler@email.com>,
-Scott J. Bertin <scottbertin@yahoo.com>, and
-Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
-this one was modelled from.
-
-
-Notes to developers
-~~~~~~~~~~~~~~~~~~~
-
- - This is a driver version stripped of the 2.4 back compatibility
- and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support.
-
-Programmer's overview of cpia2 driver
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a
-division of ST Microelectronics). There are two versions. The first is the
-STV0672, which is capable of up to 30 frames per second (fps) in frame sizes
-up to CIF, and 15 fps for VGA frames. The STV0676 is an improved version,
-which can handle up to 30 fps VGA. Both coprocessors can be attached to two
-CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor. These will
-be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors.
-
-The two chipsets operate almost identically. The core is an 8051 processor,
-running two different versions of firmware. The 672 runs the VP4 video
-processor code, the 676 runs VP5. There are a few differences in register
-mappings for the two chips. In these cases, the symbols defined in the
-header files are marked with VP4 or VP5 as part of the symbol name.
-
-The cameras appear externally as three sets of registers. Setting register
-values is the only way to control the camera. Some settings are
-interdependant, such as the sequence required to power up the camera. I will
-try to make note of all of these cases.
-
-The register sets are called blocks. Block 0 is the system block. This
-section is always powered on when the camera is plugged in. It contains
-registers that control housekeeping functions such as powering up the video
-processor. The video processor is the VP block. These registers control
-how the video from the sensor is processed. Examples are timing registers,
-user mode (vga, qvga), scaling, cropping, framerates, and so on. The last
-block is the video compressor (VC). The video stream sent from the camera is
-compressed as Motion JPEG (JPEGA). The VC controls all of the compression
-parameters. Looking at the file cpia2_registers.h, you can get a full view
-of these registers and the possible values for most of them.
-
-One or more registers can be set or read by sending a usb control message to
-the camera. There are three modes for this. Block mode requests a number
-of contiguous registers. Random mode reads or writes random registers with
-a tuple structure containing address/value pairs. The repeat mode is only
-used by VP4 to load a firmware patch. It contains a starting address and
-a sequence of bytes to be written into a gpio port.
diff --git a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
deleted file mode 100644
index f0961672e6a3..000000000000
--- a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-The VPBE V4L2 driver design
-===========================
-
-File partitioning
------------------
-
- V4L2 display device driver
- drivers/media/platform/davinci/vpbe_display.c
- drivers/media/platform/davinci/vpbe_display.h
-
- VPBE display controller
- drivers/media/platform/davinci/vpbe.c
- drivers/media/platform/davinci/vpbe.h
-
- VPBE venc sub device driver
- drivers/media/platform/davinci/vpbe_venc.c
- drivers/media/platform/davinci/vpbe_venc.h
- drivers/media/platform/davinci/vpbe_venc_regs.h
-
- VPBE osd driver
- drivers/media/platform/davinci/vpbe_osd.c
- drivers/media/platform/davinci/vpbe_osd.h
- drivers/media/platform/davinci/vpbe_osd_regs.h
-
-To be done
-----------
-
-vpbe display controller
- - Add support for external encoders.
- - add support for selecting external encoder as default at probe time.
-
-vpbe venc sub device
- - add timings for supporting ths8200
- - add support for LogicPD LCD.
-
-FB drivers
- - Add support for fbdev drivers.- Ready and part of subsequent patches.
diff --git a/Documentation/driver-api/media/drivers/fimc-devel.rst b/Documentation/driver-api/media/drivers/fimc-devel.rst
index 956e3a9901f8..4c6b7c8be19f 100644
--- a/Documentation/driver-api/media/drivers/fimc-devel.rst
+++ b/Documentation/driver-api/media/drivers/fimc-devel.rst
@@ -12,22 +12,22 @@ Files partitioning
- media device driver
- drivers/media/platform/exynos4-is/media-dev.[ch]
+ drivers/media/platform/samsung/exynos4-is/media-dev.[ch]
- camera capture video device driver
- drivers/media/platform/exynos4-is/fimc-capture.c
+ drivers/media/platform/samsung/exynos4-is/fimc-capture.c
- MIPI-CSI2 receiver subdev
- drivers/media/platform/exynos4-is/mipi-csis.[ch]
+ drivers/media/platform/samsung/exynos4-is/mipi-csis.[ch]
- video post-processor (mem-to-mem)
- drivers/media/platform/exynos4-is/fimc-core.c
+ drivers/media/platform/samsung/exynos4-is/fimc-core.c
- common files
- drivers/media/platform/exynos4-is/fimc-core.h
- drivers/media/platform/exynos4-is/fimc-reg.h
- drivers/media/platform/exynos4-is/regs-fimc.h
+ drivers/media/platform/samsung/exynos4-is/fimc-core.h
+ drivers/media/platform/samsung/exynos4-is/fimc-reg.h
+ drivers/media/platform/samsung/exynos4-is/regs-fimc.h
diff --git a/Documentation/driver-api/media/drivers/index.rst b/Documentation/driver-api/media/drivers/index.rst
index 0df85fc96605..c4123a16b5f9 100644
--- a/Documentation/driver-api/media/drivers/index.rst
+++ b/Documentation/driver-api/media/drivers/index.rst
@@ -13,18 +13,19 @@ Video4Linux (V4L) drivers
:maxdepth: 5
bttv-devel
- cpia2_devel
cx2341x-devel
cx88-devel
- davinci-vpbe-devel
fimc-devel
pvrusb2
pxa_camera
radiotrack
+ rkisp1
saa7134-devel
sh_mobile_ceu_camera
tuners
vimc-devel
+ zoran
+ ccs/ccs
Digital TV drivers
@@ -35,4 +36,5 @@ Digital TV drivers
dvb-usb
frontends
+ vidtv
contributors
diff --git a/Documentation/driver-api/media/drivers/pvrusb2.rst b/Documentation/driver-api/media/drivers/pvrusb2.rst
index 83bfaa531ea8..cbd9359c247a 100644
--- a/Documentation/driver-api/media/drivers/pvrusb2.rst
+++ b/Documentation/driver-api/media/drivers/pvrusb2.rst
@@ -20,7 +20,7 @@ last known snapshot and evolved the driver to the state it is in
here.
More information on this driver can be found at:
-http://www.isely.net/pvrusb2.html
+https://www.isely.net/pvrusb2.html
This driver has a strong separation of layers. They are very
diff --git a/Documentation/driver-api/media/drivers/pxa_camera.rst b/Documentation/driver-api/media/drivers/pxa_camera.rst
index ee1bd96b66dd..46919919baac 100644
--- a/Documentation/driver-api/media/drivers/pxa_camera.rst
+++ b/Documentation/driver-api/media/drivers/pxa_camera.rst
@@ -19,7 +19,7 @@ Global video workflow
a) QCI stopped
Initially, the QCI interface is stopped.
- When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
+ When a buffer is queued, start_streaming is called and the QCI starts.
b) QCI started
More buffers can be queued while the QCI is started without halting the
diff --git a/Documentation/driver-api/media/drivers/rkisp1.rst b/Documentation/driver-api/media/drivers/rkisp1.rst
new file mode 100644
index 000000000000..ea336958a3af
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/rkisp1.rst
@@ -0,0 +1,43 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Rockchip Image Signal Processor Driver (rkisp1)
+===================================================
+
+Versions and their differences
+------------------------------
+
+The rkisp1 block underwent some changes between SoC implementations.
+The vendor designates them as:
+
+- V10: used at least in rk3288 and rk3399
+- V11: declared in the original vendor code, but not used
+- V12: used at least in rk3326 and px30
+- V13: used at least in rk1808
+- V20: used in rk3568 and beyond
+
+Right now the kernel supports rkisp1 implementations based
+on V10 and V12 variants. V11 does not seem to be actually used
+and V13 will need some more additions but isn't researched yet,
+especially as it seems to be limited to the rk1808 which hasn't
+reached much market spread.
+
+V20 on the other hand will probably be used in future SoCs and
+has seen really big changes in the vendor kernel, so will need
+quite a bit of research.
+
+Changes from V10 to V12
+-----------------------
+
+- V12 supports a new CSI-host implementation but can still
+ also use the same implementation from V10
+- The module for lens shading correction got changed
+ from 12bit to 13bit width
+- The AWB and AEC modules got replaced to support finer
+ grained data collection
+
+Changes from V12 to V13
+-----------------------
+
+The list for V13 is incomplete and needs further investigation.
+
+- V13 does not support the old CSI-host implementation anymore
diff --git a/Documentation/driver-api/media/drivers/tuners.rst b/Documentation/driver-api/media/drivers/tuners.rst
index 7509be888909..d7924141c544 100644
--- a/Documentation/driver-api/media/drivers/tuners.rst
+++ b/Documentation/driver-api/media/drivers/tuners.rst
@@ -18,7 +18,7 @@ These differ mainly by the bandswitch byte.
Tuner Manufacturers
-------------------
-- SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
+- Samsung Tuner identification: (e.g. TCPM9091PD27)
.. code-block:: none
diff --git a/Documentation/driver-api/media/drivers/vidtv.rst b/Documentation/driver-api/media/drivers/vidtv.rst
new file mode 100644
index 000000000000..54f269f478d3
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/vidtv.rst
@@ -0,0 +1,513 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+================================
+vidtv: Virtual Digital TV driver
+================================
+
+Author: Daniel W. S. Almeida <dwlsalmeida@gmail.com>, June 2020.
+
+Background
+----------
+
+Vidtv is a virtual DVB driver that aims to serve as a reference for driver
+writers by serving as a template. It also validates the existing media DVB
+APIs, thus helping userspace application writers.
+
+Currently, it consists of:
+
+- A fake tuner driver, which will report a bad signal quality if the chosen
+ frequency is too far away from a table of valid frequencies for a
+ particular delivery system.
+
+- A fake demod driver, which will constantly poll the fake signal quality
+ returned by the tuner, simulating a device that can lose/reacquire a lock
+ on the signal depending on the CNR levels.
+
+- A fake bridge driver, which is the module responsible for modprobing the
+ fake tuner and demod modules and implementing the demux logic. This module
+ takes parameters at initialization that will dictate how the simulation
+ behaves.
+
+- Code responsible for encoding a valid MPEG Transport Stream, which is then
+ passed to the bridge driver. This fake stream contains some hardcoded content.
+ For now, we have a single, audio-only channel containing a single MPEG
+ Elementary Stream, which in turn contains a SMPTE 302m encoded sine-wave.
+ Note that this particular encoder was chosen because it is the easiest
+ way to encode PCM audio data in a MPEG Transport Stream.
+
+Building vidtv
+--------------
+vidtv is a test driver and thus is **not** enabled by default when
+compiling the kernel.
+
+In order to enable compilation of vidtv:
+
+- Enable **DVB_TEST_DRIVERS**, then
+- Enable **DVB_VIDTV**
+
+When compiled as a module, expect the following .ko files:
+
+- dvb_vidtv_tuner.ko
+
+- dvb_vidtv_demod.ko
+
+- dvb_vidtv_bridge.ko
+
+Running vidtv
+-------------
+When compiled as a module, run::
+
+ modprobe vidtv
+
+That's it! The bridge driver will initialize the tuner and demod drivers as
+part of its own initialization.
+
+By default, it will accept the following frequencies:
+
+ - 474 MHz for DVB-T/T2/C;
+ - 11,362 GHz for DVB-S/S2.
+
+For satellite systems, the driver simulates an universal extended
+LNBf, with frequencies at Ku-Band, ranging from 10.7 GHz to 12.75 GHz.
+
+You can optionally define some command-line arguments to vidtv.
+
+Command-line arguments to vidtv
+-------------------------------
+Below is a list of all arguments that can be supplied to vidtv:
+
+drop_tslock_prob_on_low_snr
+ Probability of losing the TS lock if the signal quality is bad.
+ This probability be used by the fake demodulator driver to
+ eventually return a status of 0 when the signal quality is not
+ good.
+
+recover_tslock_prob_on_good_snr:
+ Probability recovering the TS lock when the signal improves. This
+ probability be used by the fake demodulator driver to eventually
+ return a status of 0x1f when/if the signal quality improves.
+
+mock_power_up_delay_msec
+ Simulate a power up delay. Default: 0.
+
+mock_tune_delay_msec
+ Simulate a tune delay. Default 0.
+
+vidtv_valid_dvb_t_freqs
+ Valid DVB-T frequencies to simulate, in Hz.
+
+vidtv_valid_dvb_c_freqs
+ Valid DVB-C frequencies to simulate, in Hz.
+
+vidtv_valid_dvb_s_freqs
+ Valid DVB-S/S2 frequencies to simulate at Ku-Band, in kHz.
+
+max_frequency_shift_hz,
+ Maximum shift in HZ allowed when tuning in a channel.
+
+si_period_msec
+ How often to send SI packets. Default: 40ms.
+
+pcr_period_msec
+ How often to send PCR packets. Default: 40ms.
+
+mux_rate_kbytes_sec
+ Attempt to maintain this bit rate by inserting TS null packets, if
+ necessary. Default: 4096.
+
+pcr_pid,
+ PCR PID for all channels. Default: 0x200.
+
+mux_buf_sz_pkts,
+ Size for the mux buffer in multiples of 188 bytes.
+
+vidtv internal structure
+------------------------
+The kernel modules are split in the following way:
+
+vidtv_tuner.[ch]
+ Implements a fake tuner DVB driver.
+
+vidtv_demod.[ch]
+ Implements a fake demodulator DVB driver.
+
+vidtv_bridge.[ch]
+ Implements a bridge driver.
+
+The MPEG related code is split in the following way:
+
+vidtv_ts.[ch]
+ Code to work with MPEG TS packets, such as TS headers, adaptation
+ fields, PCR packets and NULL packets.
+
+vidtv_psi.[ch]
+ This is the PSI generator. PSI packets contain general information
+ about a MPEG Transport Stream. A PSI generator is needed so
+ userspace apps can retrieve information about the Transport Stream
+ and eventually tune into a (dummy) channel.
+
+ Because the generator is implemented in a separate file, it can be
+ reused elsewhere in the media subsystem.
+
+ Currently vidtv supports working with 5 PSI tables: PAT, PMT,
+ SDT, NIT and EIT.
+
+ The specification for PAT and PMT can be found in *ISO 13818-1:
+ Systems*, while the specification for the SDT, NIT, EIT can be found in *ETSI
+ EN 300 468: Specification for Service Information (SI) in DVB
+ systems*.
+
+ It isn't strictly necessary, but using a real TS file helps when
+ debugging PSI tables. Vidtv currently tries to replicate the PSI
+ structure found in this file: `TS1Globo.ts
+ <https://tsduck.io/streams/brazil-isdb-tb/TS1globo.ts>`_.
+
+ A good way to visualize the structure of streams is by using
+ `DVBInspector <https://sourceforge.net/projects/dvbinspector/>`_.
+
+vidtv_pes.[ch]
+ Implements the PES logic to convert encoder data into MPEG TS
+ packets. These can then be fed into a TS multiplexer and eventually
+ into userspace.
+
+vidtv_encoder.h
+ An interface for vidtv encoders. New encoders can be added to this
+ driver by implementing the calls in this file.
+
+vidtv_s302m.[ch]
+ Implements a S302M encoder to make it possible to insert PCM audio
+ data in the generated MPEG Transport Stream. The relevant
+ specification is available online as *SMPTE 302M-2007: Television -
+ Mapping of AES3 Data into MPEG-2 Transport Stream*.
+
+
+ The resulting MPEG Elementary Stream is conveyed in a private
+ stream with a S302M registration descriptor attached.
+
+ This shall enable passing an audio signal into userspace so it can
+ be decoded and played by media software. The corresponding decoder
+ in ffmpeg is located in 'libavcodec/s302m.c' and is experimental.
+
+vidtv_channel.[ch]
+ Implements a 'channel' abstraction.
+
+ When vidtv boots, it will create some hardcoded channels:
+
+ #. Their services will be concatenated to populate the SDT.
+
+ #. Their programs will be concatenated to populate the PAT
+
+ #. Their events will be concatenated to populate the EIT
+
+ #. For each program in the PAT, a PMT section will be created
+
+ #. The PMT section for a channel will be assigned its streams.
+
+ #. Every stream will have its corresponding encoder polled in a
+ loop to produce TS packets.
+ These packets may be interleaved by the muxer and then delivered
+ to the bridge.
+
+vidtv_mux.[ch]
+ Implements a MPEG TS mux, loosely based on the ffmpeg
+ implementation in "libavcodec/mpegtsenc.c"
+
+ The muxer runs a loop which is responsible for:
+
+ #. Keeping track of the amount of time elapsed since the last
+ iteration.
+
+ #. Polling encoders in order to fetch 'elapsed_time' worth of data.
+
+ #. Inserting PSI and/or PCR packets, if needed.
+
+ #. Padding the resulting stream with NULL packets if
+ necessary in order to maintain the chosen bit rate.
+
+ #. Delivering the resulting TS packets to the bridge
+ driver so it can pass them to the demux.
+
+Testing vidtv with v4l-utils
+----------------------------
+
+Using the tools in v4l-utils is a great way to test and inspect the output of
+vidtv. It is hosted here: `v4l-utils Documentation
+<https://linuxtv.org/wiki/index.php/V4l-utils>`_.
+
+From its webpage::
+
+ The v4l-utils are a series of packages for handling media devices.
+
+ It is hosted at http://git.linuxtv.org/v4l-utils.git, and packaged
+ on most distributions.
+
+ It provides a series of libraries and utilities to be used to
+ control several aspect of the media boards.
+
+
+Start by installing v4l-utils and then modprobing vidtv::
+
+ modprobe dvb_vidtv_bridge
+
+If the driver is OK, it should load and its probing code will run. This will
+pull in the tuner and demod drivers.
+
+Using dvb-fe-tool
+~~~~~~~~~~~~~~~~~
+
+The first step to check whether the demod loaded successfully is to run::
+
+ $ dvb-fe-tool
+ Device Dummy demod for DVB-T/T2/C/S/S2 (/dev/dvb/adapter0/frontend0) capabilities:
+ CAN_FEC_1_2
+ CAN_FEC_2_3
+ CAN_FEC_3_4
+ CAN_FEC_4_5
+ CAN_FEC_5_6
+ CAN_FEC_6_7
+ CAN_FEC_7_8
+ CAN_FEC_8_9
+ CAN_FEC_AUTO
+ CAN_GUARD_INTERVAL_AUTO
+ CAN_HIERARCHY_AUTO
+ CAN_INVERSION_AUTO
+ CAN_QAM_16
+ CAN_QAM_32
+ CAN_QAM_64
+ CAN_QAM_128
+ CAN_QAM_256
+ CAN_QAM_AUTO
+ CAN_QPSK
+ CAN_TRANSMISSION_MODE_AUTO
+ DVB API Version 5.11, Current v5 delivery system: DVBC/ANNEX_A
+ Supported delivery systems:
+ DVBT
+ DVBT2
+ [DVBC/ANNEX_A]
+ DVBS
+ DVBS2
+ Frequency range for the current standard:
+ From: 51.0 MHz
+ To: 2.15 GHz
+ Step: 62.5 kHz
+ Tolerance: 29.5 MHz
+ Symbol rate ranges for the current standard:
+ From: 1.00 MBauds
+ To: 45.0 MBauds
+
+This should return what is currently set up at the demod struct, i.e.::
+
+ static const struct dvb_frontend_ops vidtv_demod_ops = {
+ .delsys = {
+ SYS_DVBT,
+ SYS_DVBT2,
+ SYS_DVBC_ANNEX_A,
+ SYS_DVBS,
+ SYS_DVBS2,
+ },
+
+ .info = {
+ .name = "Dummy demod for DVB-T/T2/C/S/S2",
+ .frequency_min_hz = 51 * MHz,
+ .frequency_max_hz = 2150 * MHz,
+ .frequency_stepsize_hz = 62500,
+ .frequency_tolerance_hz = 29500 * kHz,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+
+ .caps = FE_CAN_FEC_1_2 |
+ FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_4_5 |
+ FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_6_7 |
+ FE_CAN_FEC_7_8 |
+ FE_CAN_FEC_8_9 |
+ FE_CAN_QAM_16 |
+ FE_CAN_QAM_64 |
+ FE_CAN_QAM_32 |
+ FE_CAN_QAM_128 |
+ FE_CAN_QAM_256 |
+ FE_CAN_QAM_AUTO |
+ FE_CAN_QPSK |
+ FE_CAN_FEC_AUTO |
+ FE_CAN_INVERSION_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_HIERARCHY_AUTO,
+ }
+
+ ....
+
+For more information on dvb-fe-tools check its online documentation here:
+`dvb-fe-tool Documentation
+<https://www.linuxtv.org/wiki/index.php/Dvb-fe-tool>`_.
+
+Using dvb-scan
+~~~~~~~~~~~~~~
+
+In order to tune into a channel and read the PSI tables, we can use dvb-scan.
+
+For this, one should provide a configuration file known as a 'scan file',
+here's an example::
+
+ [Channel]
+ FREQUENCY = 474000000
+ MODULATION = QAM/AUTO
+ SYMBOL_RATE = 6940000
+ INNER_FEC = AUTO
+ DELIVERY_SYSTEM = DVBC/ANNEX_A
+
+.. note::
+ The parameters depend on the video standard you're testing.
+
+.. note::
+ Vidtv is a fake driver and does not validate much of the information
+ in the scan file. Just specifying 'FREQUENCY' and 'DELIVERY_SYSTEM'
+ should be enough for DVB-T/DVB-T2. For DVB-S/DVB-C however, you
+ should also provide 'SYMBOL_RATE'.
+
+You can browse scan tables online here: `dvb-scan-tables
+<https://git.linuxtv.org/dtv-scan-tables.git>`_.
+
+Assuming this channel is named 'channel.conf', you can then run::
+
+ $ dvbv5-scan channel.conf
+ dvbv5-scan ~/vidtv.conf
+ ERROR command BANDWIDTH_HZ (5) not found during retrieve
+ Cannot calc frequency shift. Either bandwidth/symbol-rate is unavailable (yet).
+ Scanning frequency #1 330000000
+ (0x00) Signal= -68.00dBm
+ Scanning frequency #2 474000000
+ Lock (0x1f) Signal= -34.45dBm C/N= 33.74dB UCB= 0
+ Service Beethoven, provider LinuxTV.org: digital television
+
+For more information on dvb-scan, check its documentation online here:
+`dvb-scan Documentation <https://www.linuxtv.org/wiki/index.php/Dvbscan>`_.
+
+Using dvb-zap
+~~~~~~~~~~~~~
+
+dvbv5-zap is a command line tool that can be used to record MPEG-TS to disk. The
+typical use is to tune into a channel and put it into record mode. The example
+below - which is taken from the documentation - illustrates that\ [1]_::
+
+ $ dvbv5-zap -c dvb_channel.conf "beethoven" -o music.ts -P -t 10
+ using demux 'dvb0.demux0'
+ reading channels from file 'dvb_channel.conf'
+ tuning to 474000000 Hz
+ pass all PID's to TS
+ dvb_set_pesfilter 8192
+ dvb_dev_set_bufsize: buffer set to 6160384
+ Lock (0x1f) Quality= Good Signal= -34.66dBm C/N= 33.41dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
+ Lock (0x1f) Quality= Good Signal= -34.57dBm C/N= 33.46dB UCB= 0 postBER= 0 preBER= 1.05x10^-3 PER= 0
+ Record to file 'music.ts' started
+ received 24587768 bytes (2401 Kbytes/sec)
+ Lock (0x1f) Quality= Good Signal= -34.42dBm C/N= 33.89dB UCB= 0 postBER= 0 preBER= 2.44x10^-3 PER= 0
+
+.. [1] In this example, it records 10 seconds with all program ID's stored
+ at the music.ts file.
+
+
+The channel can be watched by playing the contents of the stream with some
+player that recognizes the MPEG-TS format, such as ``mplayer`` or ``vlc``.
+
+By playing the contents of the stream one can visually inspect the workings of
+vidtv, e.g., to play a recorded TS file with::
+
+ $ mplayer music.ts
+
+or, alternatively, running this command on one terminal::
+
+ $ dvbv5-zap -c dvb_channel.conf "beethoven" -P -r &
+
+And, on a second terminal, playing the contents from DVR interface with::
+
+ $ mplayer /dev/dvb/adapter0/dvr0
+
+For more information on dvb-zap check its online documentation here:
+`dvb-zap Documentation
+<https://www.linuxtv.org/wiki/index.php/Dvbv5-zap>`_.
+See also: `zap <https://www.linuxtv.org/wiki/index.php/Zap>`_.
+
+
+What can still be improved in vidtv
+-----------------------------------
+
+Add *debugfs* integration
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Although frontend drivers provide DVBv5 statistics via the .read_status
+call, a nice addition would be to make additional statistics available to
+userspace via debugfs, which is a simple-to-use, RAM-based filesystem
+specifically designed for debug purposes.
+
+The logic for this would be implemented on a separate file so as not to
+pollute the frontend driver. These statistics are driver-specific and can
+be useful during tests.
+
+The Siano driver is one example of a driver using
+debugfs to convey driver-specific statistics to userspace and it can be
+used as a reference.
+
+This should be further enabled and disabled via a Kconfig
+option for convenience.
+
+Add a way to test video
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Currently, vidtv can only encode PCM audio. It would be great to implement
+a barebones version of MPEG-2 video encoding so we can also test video. The
+first place to look into is *ISO 13818-2: Information technology — Generic
+coding of moving pictures and associated audio information — Part 2: Video*,
+which covers the encoding of compressed video in MPEG Transport Streams.
+
+This might optionally use the Video4Linux2 Test Pattern Generator, v4l2-tpg,
+which resides at::
+
+ drivers/media/common/v4l2-tpg/
+
+
+Add white noise simulation
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The vidtv tuner already has code to identify whether the chosen frequency
+is too far away from a table of valid frequencies. For now, this means that
+the demodulator can eventually lose the lock on the signal, since the tuner will
+report a bad signal quality.
+
+A nice addition is to simulate some noise when the signal quality is bad by:
+
+- Randomly dropping some TS packets. This will trigger a continuity error if the
+ continuity counter is updated but the packet is not passed on to the demux.
+
+- Updating the error statistics accordingly (e.g. BER, etc).
+
+- Simulating some noise in the encoded data.
+
+Functions and structs used within vidtv
+---------------------------------------
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_bridge.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_channel.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_demod.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_encoder.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_mux.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_pes.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_psi.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_s302m.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_ts.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.h
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_common.c
+
+.. kernel-doc:: drivers/media/test-drivers/vidtv/vidtv_tuner.c
diff --git a/Documentation/driver-api/media/drivers/zoran.rst b/Documentation/driver-api/media/drivers/zoran.rst
new file mode 100644
index 000000000000..b205e10c3154
--- /dev/null
+++ b/Documentation/driver-api/media/drivers/zoran.rst
@@ -0,0 +1,575 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+The Zoran driver
+================
+
+unified zoran driver (zr360x7, zoran, buz, dc10(+), dc30(+), lml33)
+
+website: http://mjpeg.sourceforge.net/driver-zoran/
+
+
+Frequently Asked Questions
+--------------------------
+
+What cards are supported
+------------------------
+
+Iomega Buz, Linux Media Labs LML33/LML33R10, Pinnacle/Miro
+DC10/DC10+/DC30/DC30+ and related boards (available under various names).
+
+Iomega Buz
+~~~~~~~~~~
+
+* Zoran zr36067 PCI controller
+* Zoran zr36060 MJPEG codec
+* Philips saa7111 TV decoder
+* Philips saa7185 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, saa7111, saa7185, zr36060, zr36067
+
+Inputs/outputs: Composite and S-video
+
+Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+
+Card number: 7
+
+AverMedia 6 Eyes AVS6EYES
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36067 PCI controller
+* Zoran zr36060 MJPEG codec
+* Samsung ks0127 TV decoder
+* Conexant bt866 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, ks0127, bt866, zr36060, zr36067
+
+Inputs/outputs:
+ Six physical inputs. 1-6 are composite,
+ 1-2, 3-4, 5-6 doubles as S-video,
+ 1-3 triples as component.
+ One composite output.
+
+Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+
+Card number: 8
+
+.. note::
+
+ Not autodetected, card=8 is necessary.
+
+Linux Media Labs LML33
+~~~~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36067 PCI controller
+* Zoran zr36060 MJPEG codec
+* Brooktree bt819 TV decoder
+* Brooktree bt856 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, bt819, bt856, zr36060, zr36067
+
+Inputs/outputs: Composite and S-video
+
+Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+
+Card number: 5
+
+Linux Media Labs LML33R10
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36067 PCI controller
+* Zoran zr36060 MJPEG codec
+* Philips saa7114 TV decoder
+* Analog Devices adv7170 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, saa7114, adv7170, zr36060, zr36067
+
+Inputs/outputs: Composite and S-video
+
+Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps)
+
+Card number: 6
+
+Pinnacle/Miro DC10(new)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36057 PCI controller
+* Zoran zr36060 MJPEG codec
+* Philips saa7110a TV decoder
+* Analog Devices adv7176 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, saa7110, adv7175, zr36060, zr36067
+
+Inputs/outputs: Composite, S-video and Internal
+
+Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+
+Card number: 1
+
+Pinnacle/Miro DC10+
+~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36067 PCI controller
+* Zoran zr36060 MJPEG codec
+* Philips saa7110a TV decoder
+* Analog Devices adv7176 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, saa7110, adv7175, zr36060, zr36067
+
+Inputs/outputs: Composite, S-video and Internal
+
+Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+
+Card number: 2
+
+Pinnacle/Miro DC10(old)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36057 PCI controller
+* Zoran zr36050 MJPEG codec
+* Zoran zr36016 Video Front End or Fuji md0211 Video Front End (clone?)
+* Micronas vpx3220a TV decoder
+* mse3000 TV encoder or Analog Devices adv7176 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067
+
+Inputs/outputs: Composite, S-video and Internal
+
+Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+
+Card number: 0
+
+Pinnacle/Miro DC30
+~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36057 PCI controller
+* Zoran zr36050 MJPEG codec
+* Zoran zr36016 Video Front End
+* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
+* Analog Devices adv7176 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067
+
+Inputs/outputs: Composite, S-video and Internal
+
+Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+
+Card number: 3
+
+Pinnacle/Miro DC30+
+~~~~~~~~~~~~~~~~~~~
+
+* Zoran zr36067 PCI controller
+* Zoran zr36050 MJPEG codec
+* Zoran zr36016 Video Front End
+* Micronas vpx3225d/vpx3220a/vpx3216b TV decoder
+* Analog Devices adv7176 TV encoder
+
+Drivers to use: videodev, i2c-core, i2c-algo-bit,
+videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zr36067
+
+Inputs/outputs: Composite, S-video and Internal
+
+Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps)
+
+Card number: 4
+
+.. note::
+
+ #) No module for the mse3000 is available yet
+ #) No module for the vpx3224 is available yet
+
+1.1 What the TV decoder can do an what not
+------------------------------------------
+
+The best know TV standards are NTSC/PAL/SECAM. but for decoding a frame that
+information is not enough. There are several formats of the TV standards.
+And not every TV decoder is able to handle every format. Also the every
+combination is supported by the driver. There are currently 11 different
+tv broadcast formats all aver the world.
+
+The CCIR defines parameters needed for broadcasting the signal.
+The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,...
+The CCIR says not much about the colorsystem used !!!
+And talking about a colorsystem says not to much about how it is broadcast.
+
+The CCIR standards A,E,F are not used any more.
+
+When you speak about NTSC, you usually mean the standard: CCIR - M using
+the NTSC colorsystem which is used in the USA, Japan, Mexico, Canada
+and a few others.
+
+When you talk about PAL, you usually mean: CCIR - B/G using the PAL
+colorsystem which is used in many Countries.
+
+When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem
+which is used in France, and a few others.
+
+There the other version of SECAM, CCIR - D/K is used in Bulgaria, China,
+Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others.
+
+The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in
+Egypt, Libya, Sri Lanka, Syrain Arab. Rep.
+
+The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong,
+Ireland, Nigeria, South Africa.
+
+The CCIR - N uses the PAL colorsystem and PAL frame size but the NTSC framerate,
+and is used in Argentinia, Uruguay, an a few others
+
+We do not talk about how the audio is broadcast !
+
+A rather good sites about the TV standards are:
+http://www.sony.jp/support/
+http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/
+and http://www.cabl.com/restaurant/channel.html
+
+Other weird things around: NTSC 4.43 is a modificated NTSC, which is mainly
+used in PAL VCR's that are able to play back NTSC. PAL 60 seems to be the same
+as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would
+be the same as NTSC 4.43.
+NTSC Combs seems to be a decoder mode where the decoder uses a comb filter
+to split coma and luma instead of a Delay line.
+
+But I did not defiantly find out what NTSC Comb is.
+
+Philips saa7111 TV decoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1997, is used in the BUZ and
+- can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM
+
+Philips saa7110a TV decoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1995, is used in the Pinnacle/Miro DC10(new), DC10+ and
+- can handle: PAL B/G, NTSC M and SECAM
+
+Philips saa7114 TV decoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 2000, is used in the LML33R10 and
+- can handle: PAL B/G/D/H/I/N, PAL N, PAL M, NTSC M, NTSC 4.43 and SECAM
+
+Brooktree bt819 TV decoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1996, and is used in the LML33 and
+- can handle: PAL B/D/G/H/I, NTSC M
+
+Micronas vpx3220a TV decoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1996, is used in the DC30 and DC30+ and
+- can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC 44, PAL 60, SECAM,NTSC Comb
+
+Samsung ks0127 TV decoder
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- is used in the AVS6EYES card and
+- can handle: NTSC-M/N/44, PAL-M/N/B/G/H/I/D/K/L and SECAM
+
+
+What the TV encoder can do an what not
+--------------------------------------
+
+The TV encoder is doing the "same" as the decoder, but in the other direction.
+You feed them digital data and the generate a Composite or SVHS signal.
+For information about the colorsystems and TV norm take a look in the
+TV decoder section.
+
+Philips saa7185 TV Encoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1996, is used in the BUZ
+- can generate: PAL B/G, NTSC M
+
+Brooktree bt856 TV Encoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1994, is used in the LML33
+- can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL-N (Argentina)
+
+Analog Devices adv7170 TV Encoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 2000, is used in the LML300R10
+- can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL 60
+
+Analog Devices adv7175 TV Encoder
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1996, is used in the DC10, DC10+, DC10 old, DC30, DC30+
+- can generate: PAL B/D/G/H/I/N, PAL M, NTSC M
+
+ITT mse3000 TV encoder
+~~~~~~~~~~~~~~~~~~~~~~
+
+- was introduced in 1991, is used in the DC10 old
+- can generate: PAL , NTSC , SECAM
+
+Conexant bt866 TV encoder
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- is used in AVS6EYES, and
+- can generate: NTSC/PAL, PAL-M, PAL-N
+
+The adv717x, should be able to produce PAL N. But you find nothing PAL N
+specific in the registers. Seem that you have to reuse a other standard
+to generate PAL N, maybe it would work if you use the PAL M settings.
+
+How do I get this damn thing to work
+------------------------------------
+
+Load zr36067.o. If it can't autodetect your card, use the card=X insmod
+option with X being the card number as given in the previous section.
+To have more than one card, use card=X1[,X2[,X3,[X4[..]]]]
+
+To automate this, add the following to your /etc/modprobe.d/zoran.conf:
+
+options zr36067 card=X1[,X2[,X3[,X4[..]]]]
+alias char-major-81-0 zr36067
+
+One thing to keep in mind is that this doesn't load zr36067.o itself yet. It
+just automates loading. If you start using xawtv, the device won't load on
+some systems, since you're trying to load modules as a user, which is not
+allowed ("permission denied"). A quick workaround is to add 'Load "v4l"' to
+XF86Config-4 when you use X by default, or to run 'v4l-conf -c <device>' in
+one of your startup scripts (normally rc.local) if you don't use X. Both
+make sure that the modules are loaded on startup, under the root account.
+
+What mainboard should I use (or why doesn't my card work)
+---------------------------------------------------------
+
+
+<insert lousy disclaimer here>. In short: good=SiS/Intel, bad=VIA.
+
+Experience tells us that people with a Buz, on average, have more problems
+than users with a DC10+/LML33. Also, it tells us that people owning a VIA-
+based mainboard (ktXXX, MVP3) have more problems than users with a mainboard
+based on a different chipset. Here's some notes from Andrew Stevens:
+
+Here's my experience of using LML33 and Buz on various motherboards:
+
+- VIA MVP3
+ - Forget it. Pointless. Doesn't work.
+- Intel 430FX (Pentium 200)
+ - LML33 perfect, Buz tolerable (3 or 4 frames dropped per movie)
+- Intel 440BX (early stepping)
+ - LML33 tolerable. Buz starting to get annoying (6-10 frames/hour)
+- Intel 440BX (late stepping)
+ - Buz tolerable, LML3 almost perfect (occasional single frame drops)
+- SiS735
+ - LML33 perfect, Buz tolerable.
+- VIA KT133(*)
+ - LML33 starting to get annoying, Buz poor enough that I have up.
+
+- Both 440BX boards were dual CPU versions.
+
+Bernhard Praschinger later added:
+
+- AMD 751
+ - Buz perfect-tolerable
+- AMD 760
+ - Buz perfect-tolerable
+
+In general, people on the user mailinglist won't give you much of a chance
+if you have a VIA-based motherboard. They may be cheap, but sometimes, you'd
+rather want to spend some more money on better boards. In general, VIA
+mainboard's IDE/PCI performance will also suck badly compared to others.
+You'll noticed the DC10+/DC30+ aren't mentioned anywhere in the overview.
+Basically, you can assume that if the Buz works, the LML33 will work too. If
+the LML33 works, the DC10+/DC30+ will work too. They're most tolerant to
+different mainboard chipsets from all of the supported cards.
+
+If you experience timeouts during capture, buy a better mainboard or lower
+the quality/buffersize during capture (see 'Concerning buffer sizes, quality,
+output size etc.'). If it hangs, there's little we can do as of now. Check
+your IRQs and make sure the card has its own interrupts.
+
+Programming interface
+---------------------
+
+This driver conforms to video4linux2. Support for V4L1 and for the custom
+zoran ioctls has been removed in kernel 2.6.38.
+
+For programming example, please, look at lavrec.c and lavplay.c code in
+the MJPEG-tools (http://mjpeg.sf.net/).
+
+Additional notes for software developers:
+
+ The driver returns maxwidth and maxheight parameters according to
+ the current TV standard (norm). Therefore, the software which
+ communicates with the driver and "asks" for these parameters should
+ first set the correct norm. Well, it seems logically correct: TV
+ standard is "more constant" for current country than geometry
+ settings of a variety of TV capture cards which may work in ITU or
+ square pixel format.
+
+Applications
+------------
+
+Applications known to work with this driver:
+
+TV viewing:
+
+* xawtv
+* kwintv
+* probably any TV application that supports video4linux or video4linux2.
+
+MJPEG capture/playback:
+
+* mjpegtools/lavtools (or Linux Video Studio)
+* gstreamer
+* mplayer
+
+General raw capture:
+
+* xawtv
+* gstreamer
+* probably any application that supports video4linux or video4linux2
+
+Video editing:
+
+* Cinelerra
+* MainActor
+* mjpegtools (or Linux Video Studio)
+
+
+Concerning buffer sizes, quality, output size etc.
+--------------------------------------------------
+
+
+The zr36060 can do 1:2 JPEG compression. This is really the theoretical
+maximum that the chipset can reach. The driver can, however, limit compression
+to a maximum (size) of 1:4. The reason for this is that some cards (e.g. Buz)
+can't handle 1:2 compression without stopping capture after only a few minutes.
+With 1:4, it'll mostly work. If you have a Buz, use 'low_bitrate=1' to go into
+1:4 max. compression mode.
+
+100% JPEG quality is thus 1:2 compression in practice. So for a full PAL frame
+(size 720x576). The JPEG fields are stored in YUY2 format, so the size of the
+fields are 720x288x16/2 bits/field (2 fields/frame) = 207360 bytes/field x 2 =
+414720 bytes/frame (add some more bytes for headers and DHT (huffman)/DQT
+(quantization) tables, and you'll get to something like 512kB per frame for
+1:2 compression. For 1:4 compression, you'd have frames of half this size.
+
+Some additional explanation by Martin Samuelsson, which also explains the
+importance of buffer sizes:
+--
+> Hmm, I do not think it is really that way. With the current (downloaded
+> at 18:00 Monday) driver I get that output sizes for 10 sec:
+> -q 50 -b 128 : 24.283.332 Bytes
+> -q 50 -b 256 : 48.442.368
+> -q 25 -b 128 : 24.655.992
+> -q 25 -b 256 : 25.859.820
+
+I woke up, and can't go to sleep again. I'll kill some time explaining why
+this doesn't look strange to me.
+
+Let's do some math using a width of 704 pixels. I'm not sure whether the Buz
+actually use that number or not, but that's not too important right now.
+
+704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block;
+3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block;
+1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum
+output becomes 512 bits per block. Actually 510, but 512 is simpler to use
+for calculations.
+
+Let's say that we specify d1q50. We thus want 256 bits per block; times 3168
+becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes
+here, so we don't need to do any fancy corrections for bits-per-pixel or such
+things. 101376 bytes per field.
+
+d1 video contains two fields per frame. Those sum up to 202752 bytes per
+frame, and one of those frames goes into each buffer.
+
+But wait a second! -b128 gives 128kB buffers! It's not possible to cram
+202752 bytes of JPEG data into 128kB!
+
+This is what the driver notice and automatically compensate for in your
+examples. Let's do some math using this information:
+
+128kB is 131072 bytes. In this buffer, we want to store two fields, which
+leaves 65536 bytes for each field. Using 3168 blocks per field, we get
+20.68686868... available bytes per block; 165 bits. We can't allow the
+request for 256 bits per block when there's only 165 bits available! The -q50
+option is silently overridden, and the -b128 option takes precedence, leaving
+us with the equivalence of -q32.
+
+This gives us a data rate of 165 bits per block, which, times 3168, sums up
+to 65340 bytes per field, out of the allowed 65536. The current driver has
+another level of rate limiting; it won't accept -q values that fill more than
+6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be
+a safe bet. Personally, I think I would have lowered requested-bits-per-block
+by one, or something like that.) We can't use 165 bits per block, but have to
+lower it again, to 6/8 of the available buffer space: We end up with 124 bits
+per block, the equivalence of -q24. With 128kB buffers, you can't use greater
+than -q24 at -d1. (And PAL, and 704 pixels width...)
+
+The third example is limited to -q24 through the same process. The second
+example, using very similar calculations, is limited to -q48. The only
+example that actually grab at the specified -q value is the last one, which
+is clearly visible, looking at the file size.
+--
+
+Conclusion: the quality of the resulting movie depends on buffer size, quality,
+whether or not you use 'low_bitrate=1' as insmod option for the zr36060.c
+module to do 1:4 instead of 1:2 compression, etc.
+
+If you experience timeouts, lowering the quality/buffersize or using
+'low_bitrate=1 as insmod option for zr36060.o might actually help, as is
+proven by the Buz.
+
+It hangs/crashes/fails/whatevers! Help!
+---------------------------------------
+
+Make sure that the card has its own interrupts (see /proc/interrupts), check
+the output of dmesg at high verbosity (load zr36067.o with debug=2,
+load all other modules with debug=1). Check that your mainboard is favorable
+(see question 2) and if not, test the card in another computer. Also see the
+notes given in question 3 and try lowering quality/buffersize/capturesize
+if recording fails after a period of time.
+
+If all this doesn't help, give a clear description of the problem including
+detailed hardware information (memory+brand, mainboard+chipset+brand, which
+MJPEG card, processor, other PCI cards that might be of interest), give the
+system PnP information (/proc/interrupts, /proc/dma, /proc/devices), and give
+the kernel version, driver version, glibc version, gcc version and any other
+information that might possibly be of interest. Also provide the dmesg output
+at high verbosity. See 'Contacting' on how to contact the developers.
+
+Maintainers/Contacting
+----------------------
+
+Previous maintainers/developers of this driver are
+- Laurent Pinchart <laurent.pinchart@skynet.be>
+- Ronald Bultje rbultje@ronald.bitfreak.net
+- Serguei Miridonov <mirsev@cicese.mx>
+- Wolfgang Scherr <scherr@net4you.net>
+- Dave Perks <dperks@ibm.net>
+- Rainer Johanni <Rainer@Johanni.de>
+
+Driver's License
+----------------
+
+ This driver is distributed under the terms of the General Public License.
+
+ 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.
+
+See http://www.gnu.org/ for more information.
diff --git a/Documentation/driver-api/media/dtv-common.rst b/Documentation/driver-api/media/dtv-common.rst
index f8b2c4dc8170..207a22bcaf4a 100644
--- a/Documentation/driver-api/media/dtv-common.rst
+++ b/Documentation/driver-api/media/dtv-common.rst
@@ -3,15 +3,6 @@
Digital TV Common functions
---------------------------
-Math functions
-~~~~~~~~~~~~~~
-
-Provide some commonly-used math functions, usually required in order to
-estimate signal strength and signal to noise measurements in dB.
-
-.. kernel-doc:: include/media/dvb_math.h
-
-
DVB devices
~~~~~~~~~~~
diff --git a/Documentation/driver-api/media/dtv-demux.rst b/Documentation/driver-api/media/dtv-demux.rst
index c0ae5dec5328..144124142622 100644
--- a/Documentation/driver-api/media/dtv-demux.rst
+++ b/Documentation/driver-api/media/dtv-demux.rst
@@ -24,7 +24,7 @@ unless this is fixed in the HW platform.
The demux kABI only controls front-ends regarding to their connections with
demuxes; the kABI used to set the other front-end parameters, such as
-tuning, are devined via the Digital TV Frontend kABI.
+tuning, are defined via the Digital TV Frontend kABI.
The functions that implement the abstract interface demux should be defined
static or module private and registered to the Demux core for external
diff --git a/Documentation/driver-api/media/dtv-frontend.rst b/Documentation/driver-api/media/dtv-frontend.rst
index b362109bb131..ea43cdb5b0e4 100644
--- a/Documentation/driver-api/media/dtv-frontend.rst
+++ b/Documentation/driver-api/media/dtv-frontend.rst
@@ -125,7 +125,7 @@ responsible for tuning the device. It supports multiple algorithms to
detect a channel, as defined at enum :c:func:`dvbfe_algo`.
The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
-doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to
+doesn't fill its field at struct dvb_frontend_ops, it will default to
``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
e. g. it will try first to use the specified center frequency ``f``,
then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
@@ -140,7 +140,7 @@ define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
define its own hardware-assisted algorithm. Very few hardware need to
use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
- function callbacks at struct :c:type:`dvb_frontend_ops`.
+ function callbacks at struct dvb_frontend_ops.
Attaching frontend driver to the bridge driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -244,7 +244,7 @@ Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
Having it available after inner FEC is more common.
Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
- - Those counters measure the number of bits and bit errors errors after
+ - Those counters measure the number of bits and bit errors after
the forward error correction (FEC) on the inner coding block
(after Viterbi, LDPC or other inner code).
@@ -253,7 +253,7 @@ Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POS
see :c:type:`fe_status`).
Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
- - Those counters measure the number of bits and bit errors errors before
+ - Those counters measure the number of bits and bit errors before
the forward error correction (FEC) on the inner coding block
(before Viterbi, LDPC or other inner code).
@@ -263,7 +263,7 @@ Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-T
after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
- - Those counters measure the number of blocks and block errors errors after
+ - Those counters measure the number of blocks and block errors after
the forward error correction (FEC) on the inner coding block
(before Viterbi, LDPC or other inner code).
diff --git a/Documentation/driver-api/media/index.rst b/Documentation/driver-api/media/index.rst
index 328350924853..d5593182a3f9 100644
--- a/Documentation/driver-api/media/index.rst
+++ b/Documentation/driver-api/media/index.rst
@@ -11,29 +11,29 @@ its supported drivers.
Please see:
-- :doc:`/admin-guide/media/index`
- for usage information about media subsystem and supported drivers;
+Documentation/admin-guide/media/index.rst
-- :doc:`/userspace-api/media/index`
- for the userspace APIs used on media devices.
+ - for usage information about media subsystem and supported drivers;
+Documentation/userspace-api/media/index.rst
-.. only:: html
+ - for the userspace APIs used on media devices.
- .. class:: toc-title
-
- Table of Contents
.. toctree::
+ :caption: Table of Contents
:maxdepth: 5
:numbered:
+ maintainer-entry-profile
+
v4l2-core
dtv-core
rc-core
mc-core
cec-core
- csi2
+ tx-rx
+ camera-sensor
drivers/index
diff --git a/Documentation/driver-api/media/maintainer-entry-profile.rst b/Documentation/driver-api/media/maintainer-entry-profile.rst
new file mode 100644
index 000000000000..ffc712a5f632
--- /dev/null
+++ b/Documentation/driver-api/media/maintainer-entry-profile.rst
@@ -0,0 +1,206 @@
+Media Subsystem Profile
+=======================
+
+Overview
+--------
+
+The media subsystem covers support for a variety of devices: stream
+capture, analog and digital TV streams, cameras, remote controllers, HDMI CEC
+and media pipeline control.
+
+It covers, mainly, the contents of those directories:
+
+ - drivers/media
+ - drivers/staging/media
+ - Documentation/admin-guide/media
+ - Documentation/driver-api/media
+ - Documentation/userspace-api/media
+ - Documentation/devicetree/bindings/media/\ [1]_
+ - include/media
+
+.. [1] Device tree bindings are maintained by the
+ OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS maintainers
+ (see the MAINTAINERS file). So, changes there must be reviewed
+ by them before being merged via the media subsystem's development
+ tree.
+
+Both media userspace and Kernel APIs are documented and the documentation
+must be kept in sync with the API changes. It means that all patches that
+add new features to the subsystem must also bring changes to the
+corresponding API files.
+
+Due to the size and wide scope of the media subsystem, media's
+maintainership model is to have sub-maintainers that have a broad
+knowledge of a specific aspect of the subsystem. It is the sub-maintainers'
+task to review the patches, providing feedback to users if the patches are
+following the subsystem rules and are properly using the media kernel and
+userspace APIs.
+
+Patches for the media subsystem must be sent to the media mailing list
+at linux-media@vger.kernel.org as plain text only e-mail. Emails with
+HTML will be automatically rejected by the mail server. It could be wise
+to also copy the sub-maintainer(s).
+
+Media's workflow is heavily based on Patchwork, meaning that, once a patch
+is submitted, the e-mail will first be accepted by the mailing list
+server, and, after a while, it should appear at:
+
+ - https://patchwork.linuxtv.org/project/linux-media/list/
+
+If it doesn't automatically appear there after a few minutes, then
+probably something went wrong on your submission. Please check if the
+email is in plain text\ [2]_ only and if your emailer is not mangling
+whitespaces before complaining or submitting them again.
+
+You can check if the mailing list server accepted your patch, by looking at:
+
+ - https://lore.kernel.org/linux-media/
+
+.. [2] If your email contains HTML, the mailing list server will simply
+ drop it, without any further notice.
+
+
+Media maintainers
++++++++++++++++++
+
+At the media subsystem, we have a group of senior developers that
+are responsible for doing the code reviews at the drivers (also known as
+sub-maintainers), and another senior developer responsible for the
+subsystem as a whole. For core changes, whenever possible, multiple
+media maintainers do the review.
+
+The media maintainers that work on specific areas of the subsystem are:
+
+- Remote Controllers (infrared):
+ Sean Young <sean@mess.org>
+
+- HDMI CEC:
+ Hans Verkuil <hverkuil@xs4all.nl>
+
+- Media controller drivers:
+ Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+- ISP, v4l2-async, v4l2-fwnode, v4l2-flash-led-class and Sensor drivers:
+ Sakari Ailus <sakari.ailus@linux.intel.com>
+
+- V4L2 drivers and core V4L2 frameworks:
+ Hans Verkuil <hverkuil@xs4all.nl>
+
+The subsystem maintainer is:
+ Mauro Carvalho Chehab <mchehab@kernel.org>
+
+Media maintainers may delegate a patch to other media maintainers as needed.
+On such case, checkpatch's ``delegate`` field indicates who's currently
+responsible for reviewing a patch.
+
+Submit Checklist Addendum
+-------------------------
+
+Patches that change the Open Firmware/Device Tree bindings must be
+reviewed by the Device Tree maintainers. So, DT maintainers should be
+Cc:ed when those are submitted via devicetree@vger.kernel.org mailing
+list.
+
+There is a set of compliance tools at https://git.linuxtv.org/v4l-utils.git/
+that should be used in order to check if the drivers are properly
+implementing the media APIs:
+
+==================== =======================================================
+Type Tool
+==================== =======================================================
+V4L2 drivers\ [3]_ ``v4l2-compliance``
+V4L2 virtual drivers ``contrib/test/test-media``
+CEC drivers ``cec-compliance``
+==================== =======================================================
+
+.. [3] The ``v4l2-compliance`` also covers the media controller usage inside
+ V4L2 drivers.
+
+Other compilance tools are under development to check other parts of the
+subsystem.
+
+Those tests need to pass before the patches go upstream.
+
+Also, please notice that we build the Kernel with::
+
+ make CF=-D__CHECK_ENDIAN__ CONFIG_DEBUG_SECTION_MISMATCH=y C=1 W=1 CHECK=check_script
+
+Where the check script is::
+
+ #!/bin/bash
+ /devel/smatch/smatch -p=kernel $@ >&2
+ /devel/sparse/sparse $@ >&2
+
+Be sure to not introduce new warnings on your patches without a
+very good reason.
+
+Style Cleanup Patches
++++++++++++++++++++++
+
+Style cleanups are welcome when they come together with other changes
+at the files where the style changes will affect.
+
+We may accept pure standalone style cleanups, but they should ideally
+be one patch for the whole subsystem (if the cleanup is low volume),
+or at least be grouped per directory. So, for example, if you're doing a
+big cleanup change set at drivers under drivers/media, please send a single
+patch for all drivers under drivers/media/pci, another one for
+drivers/media/usb and so on.
+
+Coding Style Addendum
++++++++++++++++++++++
+
+Media development uses ``checkpatch.pl`` on strict mode to verify the code
+style, e.g.::
+
+ $ ./scripts/checkpatch.pl --strict --max-line-length=80
+
+In principle, patches should follow the coding style rules, but exceptions
+are allowed if there are good reasons. On such case, maintainers and reviewers
+may question about the rationale for not addressing the ``checkpatch.pl``.
+
+Please notice that the goal here is to improve code readability. On
+a few cases, ``checkpatch.pl`` may actually point to something that would
+look worse. So, you should use good sense.
+
+Note that addressing one ``checkpatch.pl`` issue (of any kind) alone may lead
+to having longer lines than 80 characters per line. While this is not
+strictly prohibited, efforts should be made towards staying within 80
+characters per line. This could include using re-factoring code that leads
+to less indentation, shorter variable or function names and last but not
+least, simply wrapping the lines.
+
+In particular, we accept lines with more than 80 columns:
+
+ - on strings, as they shouldn't be broken due to line length limits;
+ - when a function or variable name need to have a big identifier name,
+ which keeps hard to honor the 80 columns limit;
+ - on arithmetic expressions, when breaking lines makes them harder to
+ read;
+ - when they avoid a line to end with an open parenthesis or an open
+ bracket.
+
+Key Cycle Dates
+---------------
+
+New submissions can be sent at any time, but if they intend to hit the
+next merge window they should be sent before -rc5, and ideally stabilized
+in the linux-media branch by -rc6.
+
+Review Cadence
+--------------
+
+Provided that your patch is at https://patchwork.linuxtv.org, it should
+be sooner or later handled, so you don't need to re-submit a patch.
+
+Except for bug fixes, we don't usually add new patches to the development
+tree between -rc6 and the next -rc1.
+
+Please notice that the media subsystem is a high traffic one, so it
+could take a while for us to be able to review your patches. Feel free
+to ping if you don't get a feedback in a couple of weeks or to ask
+other developers to publicly add Reviewed-by and, more importantly,
+``Tested-by:`` tags.
+
+Please note that we expect a detailed description for ``Tested-by:``,
+identifying what boards were used at the test and what it was tested.
diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst
index 05bba0b61748..2456950ce8ff 100644
--- a/Documentation/driver-api/media/mc-core.rst
+++ b/Documentation/driver-api/media/mc-core.rst
@@ -36,20 +36,27 @@ pad to a sink pad.
Media device
^^^^^^^^^^^^
-A media device is represented by a struct :c:type:`media_device`
+A media device is represented by a struct media_device
instance, defined in ``include/media/media-device.h``.
Allocation of the structure is handled by the media device driver, usually by
embedding the :c:type:`media_device` instance in a larger driver-specific
structure.
-Drivers register media device instances by calling
-:c:func:`__media_device_register()` via the macro ``media_device_register()``
-and unregistered by calling :c:func:`media_device_unregister()`.
+Drivers initialise media device instances by calling
+:c:func:`media_device_init()`. After initialising a media device instance, it is
+registered by calling :c:func:`__media_device_register()` via the macro
+``media_device_register()`` and unregistered by calling
+:c:func:`media_device_unregister()`. An initialised media device must be
+eventually cleaned up by calling :c:func:`media_device_cleanup()`.
+
+Note that it is not allowed to unregister a media device instance that was not
+previously registered, or clean up a media device instance that was not
+previously initialised.
Entities
^^^^^^^^
-Entities are represented by a struct :c:type:`media_entity`
+Entities are represented by a struct media_entity
instance, defined in ``include/media/media-entity.h``. The structure is usually
embedded into a higher-level structure, such as
:c:type:`v4l2_subdev` or :c:type:`video_device`
@@ -67,10 +74,10 @@ Interfaces
^^^^^^^^^^
Interfaces are represented by a
-struct :c:type:`media_interface` instance, defined in
+struct media_interface instance, defined in
``include/media/media-entity.h``. Currently, only one type of interface is
defined: a device node. Such interfaces are represented by a
-struct :c:type:`media_intf_devnode`.
+struct media_intf_devnode.
Drivers initialize and create device node interfaces by calling
:c:func:`media_devnode_create()`
@@ -79,7 +86,7 @@ and remove them by calling:
Pads
^^^^
-Pads are represented by a struct :c:type:`media_pad` instance,
+Pads are represented by a struct media_pad instance,
defined in ``include/media/media-entity.h``. Each entity stores its pads in
a pads array managed by the entity driver. Drivers usually embed the array in
a driver-specific structure.
@@ -87,8 +94,8 @@ a driver-specific structure.
Pads are identified by their entity and their 0-based index in the pads
array.
-Both information are stored in the struct :c:type:`media_pad`,
-making the struct :c:type:`media_pad` pointer the canonical way
+Both information are stored in the struct media_pad,
+making the struct media_pad pointer the canonical way
to store and pass link references.
Pads have flags that describe the pad capabilities and state.
@@ -104,7 +111,7 @@ Pads have flags that describe the pad capabilities and state.
Links
^^^^^
-Links are represented by a struct :c:type:`media_link` instance,
+Links are represented by a struct media_link instance,
defined in ``include/media/media-entity.h``. There are two types of links:
**1. pad to pad links**:
@@ -179,15 +186,16 @@ is required and the graph structure can be freed normally.
Helper functions can be used to find a link between two given pads, or a pad
connected to another pad through an enabled link
-:c:func:`media_entity_find_link()` and
-:c:func:`media_entity_remote_pad()`.
+(:c:func:`media_entity_find_link()`, :c:func:`media_pad_remote_pad_first()`,
+:c:func:`media_entity_remote_source_pad_unique()` and
+:c:func:`media_pad_remote_pad_unique()`).
Use count and power handling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Due to the wide differences between drivers regarding power management
needs, the media controller does not implement power management. However,
-the struct :c:type:`media_entity` includes a ``use_count``
+the struct media_entity includes a ``use_count``
field that media drivers
can use to track the number of users of every entity for power management
needs.
@@ -206,19 +214,28 @@ Link properties can be modified at runtime by calling
Pipelines and media streams
^^^^^^^^^^^^^^^^^^^^^^^^^^^
+A media stream is a stream of pixels or metadata originating from one or more
+source devices (such as a sensors) and flowing through media entity pads
+towards the final sinks. The stream can be modified on the route by the
+devices (e.g. scaling or pixel format conversions), or it can be split into
+multiple branches, or multiple branches can be merged.
+
+A media pipeline is a set of media streams which are interdependent. This
+interdependency can be caused by the hardware (e.g. configuration of a second
+stream cannot be changed if the first stream has been enabled) or by the driver
+due to the software design. Most commonly a media pipeline consists of a single
+stream which does not branch.
+
When starting streaming, drivers must notify all entities in the pipeline to
prevent link states from being modified during streaming by calling
:c:func:`media_pipeline_start()`.
-The function will mark all entities connected to the given entity through
-enabled links, either directly or indirectly, as streaming.
+The function will mark all the pads which are part of the pipeline as streaming.
-The struct :c:type:`media_pipeline` instance pointed to by
-the pipe argument will be stored in every entity in the pipeline.
-Drivers should embed the struct :c:type:`media_pipeline`
-in higher-level pipeline structures and can then access the
-pipeline through the struct :c:type:`media_entity`
-pipe field.
+The struct media_pipeline instance pointed to by the pipe argument will be
+stored in every pad in the pipeline. Drivers should embed the struct
+media_pipeline in higher-level pipeline structures and can then access the
+pipeline through the struct media_pad pipe field.
Calls to :c:func:`media_pipeline_start()` can be nested.
The pipeline pointer must be identical for all nested calls to the function.
diff --git a/Documentation/driver-api/media/tx-rx.rst b/Documentation/driver-api/media/tx-rx.rst
new file mode 100644
index 000000000000..29d66a47b56e
--- /dev/null
+++ b/Documentation/driver-api/media/tx-rx.rst
@@ -0,0 +1,134 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _transmitter-receiver:
+
+Pixel data transmitter and receiver drivers
+===========================================
+
+V4L2 supports various devices that transmit and receive pixel data. Examples of
+these devices include a camera sensor, a TV tuner and a parallel, a BT.656 or a
+CSI-2 receiver in an SoC.
+
+Bus types
+---------
+
+The following busses are the most common. This section discusses these two only.
+
+MIPI CSI-2
+^^^^^^^^^^
+
+CSI-2 is a data bus intended for transferring images from cameras to
+the host SoC. It is defined by the `MIPI alliance`_.
+
+.. _`MIPI alliance`: https://www.mipi.org/
+
+Parallel and BT.656
+^^^^^^^^^^^^^^^^^^^
+
+The parallel and `BT.656`_ buses transport one bit of data on each clock cycle
+per data line. The parallel bus uses synchronisation and other additional
+signals whereas BT.656 embeds synchronisation.
+
+.. _`BT.656`: https://en.wikipedia.org/wiki/ITU-R_BT.656
+
+Transmitter drivers
+-------------------
+
+Transmitter drivers generally need to provide the receiver drivers with the
+configuration of the transmitter. What is required depends on the type of the
+bus. These are common for both busses.
+
+Media bus pixel code
+^^^^^^^^^^^^^^^^^^^^
+
+See :ref:`v4l2-mbus-pixelcode`.
+
+Link frequency
+^^^^^^^^^^^^^^
+
+The :ref:`V4L2_CID_LINK_FREQ <v4l2-cid-link-freq>` control is used to tell the
+receiver the frequency of the bus (i.e. it is not the same as the symbol rate).
+
+``.s_stream()`` callback
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The struct struct v4l2_subdev_video_ops->s_stream() callback is used by the
+receiver driver to control the transmitter driver's streaming state.
+
+
+CSI-2 transmitter drivers
+-------------------------
+
+Pixel rate
+^^^^^^^^^^
+
+The pixel rate on the bus is calculated as follows::
+
+ pixel_rate = link_freq * 2 * nr_of_lanes * 16 / k / bits_per_sample
+
+where
+
+.. list-table:: variables in pixel rate calculation
+ :header-rows: 1
+
+ * - variable or constant
+ - description
+ * - link_freq
+ - The value of the ``V4L2_CID_LINK_FREQ`` integer64 menu item.
+ * - nr_of_lanes
+ - Number of data lanes used on the CSI-2 link. This can
+ be obtained from the OF endpoint configuration.
+ * - 2
+ - Data is transferred on both rising and falling edge of the signal.
+ * - bits_per_sample
+ - Number of bits per sample.
+ * - k
+ - 16 for D-PHY and 7 for C-PHY
+
+.. note::
+
+ The pixel rate calculated this way is **not** the same thing as the
+ pixel rate on the camera sensor's pixel array which is indicated by the
+ :ref:`V4L2_CID_PIXEL_RATE <v4l2-cid-pixel-rate>` control.
+
+LP-11 and LP-111 states
+^^^^^^^^^^^^^^^^^^^^^^^
+
+As part of transitioning to high speed mode, a CSI-2 transmitter typically
+briefly sets the bus to LP-11 or LP-111 state, depending on the PHY. This period
+may be as short as 100 µs, during which the receiver observes this state and
+proceeds its own part of high speed mode transition.
+
+Most receivers are capable of autonomously handling this once the software has
+configured them to do so, but there are receivers which require software
+involvement in observing LP-11 or LP-111 state. 100 µs is a brief period to hit
+in software, especially when there is no interrupt telling something is
+happening.
+
+One way to address this is to configure the transmitter side explicitly to LP-11
+or LP-111 state, which requires support from the transmitter hardware. This is
+not universally available. Many devices return to this state once streaming is
+stopped while the state after power-on is LP-00 or LP-000.
+
+The ``.pre_streamon()`` callback may be used to prepare a transmitter for
+transitioning to streaming state, but not yet start streaming. Similarly, the
+``.post_streamoff()`` callback is used to undo what was done by the
+``.pre_streamon()`` callback. The caller of ``.pre_streamon()`` is thus required
+to call ``.post_streamoff()`` for each successful call of ``.pre_streamon()``.
+
+In the context of CSI-2, the ``.pre_streamon()`` callback is used to transition
+the transmitter to the LP-11 or LP-111 state. This also requires powering on the
+device, so this should be only done when it is needed.
+
+Receiver drivers that do not need explicit LP-11 or LP-111 state setup are
+waived from calling the two callbacks.
+
+Stopping the transmitter
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+A transmitter stops sending the stream of images as a result of
+calling the ``.s_stream()`` callback. Some transmitters may stop the
+stream at a frame boundary whereas others stop immediately,
+effectively leaving the current frame unfinished. The receiver driver
+should not make assumptions either way, but function properly in both
+cases.
diff --git a/Documentation/driver-api/media/v4l2-cci.rst b/Documentation/driver-api/media/v4l2-cci.rst
new file mode 100644
index 000000000000..dd297a40ed20
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-cci.rst
@@ -0,0 +1,5 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 CCI kAPI
+^^^^^^^^^^^^^
+.. kernel-doc:: include/media/v4l2-cci.h
diff --git a/Documentation/driver-api/media/v4l2-clocks.rst b/Documentation/driver-api/media/v4l2-clocks.rst
deleted file mode 100644
index 5c22eecab7ba..000000000000
--- a/Documentation/driver-api/media/v4l2-clocks.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-V4L2 clocks
------------
-
-.. attention::
-
- This is a temporary API and it shall be replaced by the generic
- clock API, when the latter becomes widely available.
-
-Many subdevices, like camera sensors, TV decoders and encoders, need a clock
-signal to be supplied by the system. Often this clock is supplied by the
-respective bridge device. The Linux kernel provides a Common Clock Framework for
-this purpose. However, it is not (yet) available on all architectures. Besides,
-the nature of the multi-functional (clock, data + synchronisation, I2C control)
-connection of subdevices to the system might impose special requirements on the
-clock API usage. E.g. V4L2 has to support clock provider driver unregistration
-while a subdevice driver is holding a reference to the clock. For these reasons
-a V4L2 clock helper API has been developed and is provided to bridge and
-subdevice drivers.
-
-The API consists of two parts: two functions to register and unregister a V4L2
-clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
-a clock object, similar to the respective generic clock API calls:
-v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
-v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
-clock operations that will be called when clock users invoke respective API
-methods.
-
-It is expected that once the CCF becomes available on all relevant
-architectures this API will be removed.
diff --git a/Documentation/driver-api/media/v4l2-controls.rst b/Documentation/driver-api/media/v4l2-controls.rst
index 5129019afb49..b2e91804829b 100644
--- a/Documentation/driver-api/media/v4l2-controls.rst
+++ b/Documentation/driver-api/media/v4l2-controls.rst
@@ -27,7 +27,7 @@ V4L2 specification with respect to controls in a central place. And to make
life as easy as possible for the driver developer.
Note that the control framework relies on the presence of a struct
-:c:type:`v4l2_device` for V4L2 drivers and struct :c:type:`v4l2_subdev` for
+:c:type:`v4l2_device` for V4L2 drivers and struct v4l2_subdev for
sub-device drivers.
@@ -335,7 +335,7 @@ current and new values:
union v4l2_ctrl_ptr p_new;
union v4l2_ctrl_ptr p_cur;
-If the control has a simple s32 type type, then:
+If the control has a simple s32 type, then:
.. code-block:: c
@@ -349,7 +349,7 @@ Within the control ops you can freely use these. The val and cur.val speak for
themselves. The p_char pointers point to character buffers of length
ctrl->maximum + 1, and are always 0-terminated.
-Unless the control is marked volatile the p_cur field points to the the
+Unless the control is marked volatile the p_cur field points to the
current cached control value. When you create a new control this value is made
identical to the default value. After calling v4l2_ctrl_handler_setup() this
value is passed to the hardware. It is generally a good idea to call this
diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst
index 0dcad7a23141..58cba831ade5 100644
--- a/Documentation/driver-api/media/v4l2-core.rst
+++ b/Documentation/driver-api/media/v4l2-core.rst
@@ -13,9 +13,7 @@ Video4Linux devices
v4l2-subdev
v4l2-event
v4l2-controls
- v4l2-videobuf
v4l2-videobuf2
- v4l2-clocks
v4l2-dv-timings
v4l2-flash-led-class
v4l2-mc
@@ -23,6 +21,7 @@ Video4Linux devices
v4l2-mem2mem
v4l2-async
v4l2-fwnode
+ v4l2-cci
v4l2-rect
v4l2-tuner
v4l2-common
diff --git a/Documentation/driver-api/media/v4l2-dev.rst b/Documentation/driver-api/media/v4l2-dev.rst
index 63c064837c00..d5cb19b21a9f 100644
--- a/Documentation/driver-api/media/v4l2-dev.rst
+++ b/Documentation/driver-api/media/v4l2-dev.rst
@@ -67,7 +67,7 @@ You should also set these fields of :c:type:`video_device`:
file operation is called this lock will be taken by the core and released
afterwards. See the next section for more details.
-- :c:type:`video_device`->queue: a pointer to the struct :c:type:`vb2_queue`
+- :c:type:`video_device`->queue: a pointer to the struct vb2_queue
associated with this device node.
If queue is not ``NULL``, and queue->lock is not ``NULL``, then queue->lock
is used for the queuing ioctls (``VIDIOC_REQBUFS``, ``CREATE_BUFS``,
@@ -81,7 +81,7 @@ You should also set these fields of :c:type:`video_device`:
- :c:type:`video_device`->prio: keeps track of the priorities. Used to
implement ``VIDIOC_G_PRIORITY`` and ``VIDIOC_S_PRIORITY``.
- If left to ``NULL``, then it will use the struct :c:type:`v4l2_prio_state`
+ If left to ``NULL``, then it will use the struct v4l2_prio_state
in :c:type:`v4l2_device`. If you want to have a separate priority state per
(group of) device node(s), then you can point it to your own struct
:c:type:`v4l2_prio_state`.
@@ -95,7 +95,7 @@ You should also set these fields of :c:type:`video_device`:
but it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
(cx8802). Since the :c:type:`v4l2_device` cannot be associated with two PCI
devices at the same time it is setup without a parent device. But when the
- struct :c:type:`video_device` is initialized you **do** know which parent
+ struct video_device is initialized you **do** know which parent
PCI device to use and so you set ``dev_device`` to the correct PCI device.
If you use :c:type:`v4l2_ioctl_ops`, then you should set
@@ -138,7 +138,7 @@ ioctls and locking
------------------
The V4L core provides optional locking services. The main service is the
-lock field in struct :c:type:`video_device`, which is a pointer to a mutex.
+lock field in struct video_device, which is a pointer to a mutex.
If you set this pointer, then that will be used by unlocked_ioctl to
serialize all ioctls.
@@ -157,14 +157,6 @@ changing the e.g. exposure of the webcam.
Of course, you can always do all the locking yourself by leaving both lock
pointers at ``NULL``.
-If you use the old :ref:`videobuf framework <vb_framework>` then you must
-pass the :c:type:`video_device`->lock to the videobuf queue initialize
-function: if videobuf has to wait for a frame to arrive, then it will
-temporarily unlock the lock and relock it afterwards. If your driver also
-waits in the code, then you should do the same to allow other
-processes to access the device node while the first process is waiting for
-something.
-
In the case of :ref:`videobuf2 <vb2_framework>` you will need to implement the
``wait_prepare()`` and ``wait_finish()`` callbacks to unlock/lock if applicable.
If you use the ``queue->lock`` pointer, then you can use the helper functions
@@ -212,7 +204,7 @@ types exist:
========================== ==================== ==============================
The last argument gives you a certain amount of control over the device
-device node number used (i.e. the X in ``videoX``). Normally you will pass -1
+node number used (i.e. the X in ``videoX``). Normally you will pass -1
to let the v4l2 framework pick the first free number. But sometimes users
want to select a specific node number. It is common that drivers allow
the user to select a specific device node number through a driver module
diff --git a/Documentation/driver-api/media/v4l2-device.rst b/Documentation/driver-api/media/v4l2-device.rst
index 5e25bf182c18..7bd9c45f551b 100644
--- a/Documentation/driver-api/media/v4l2-device.rst
+++ b/Documentation/driver-api/media/v4l2-device.rst
@@ -3,7 +3,7 @@
V4L2 device instance
--------------------
-Each device instance is represented by a struct :c:type:`v4l2_device`.
+Each device instance is represented by a struct v4l2_device.
Very simple devices can just allocate this struct, but most of the time you
would embed this struct inside a larger struct.
@@ -18,9 +18,9 @@ dev->driver_data field is ``NULL``, it will be linked to
Drivers that want integration with the media device framework need to set
dev->driver_data manually to point to the driver-specific device structure
-that embed the struct :c:type:`v4l2_device` instance. This is achieved by a
+that embed the struct v4l2_device instance. This is achieved by a
``dev_set_drvdata()`` call before registering the V4L2 device instance.
-They must also set the struct :c:type:`v4l2_device` mdev field to point to a
+They must also set the struct v4l2_device mdev field to point to a
properly initialized and registered :c:type:`media_device` instance.
If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a
diff --git a/Documentation/driver-api/media/v4l2-event.rst b/Documentation/driver-api/media/v4l2-event.rst
index a4b7ae2b94d8..52d4fbc5d819 100644
--- a/Documentation/driver-api/media/v4l2-event.rst
+++ b/Documentation/driver-api/media/v4l2-event.rst
@@ -44,18 +44,18 @@ such objects.
So to summarize:
-- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
+- struct v4l2_fh has two lists: one of the ``subscribed`` events,
and one of the ``available`` events.
-- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
+- struct v4l2_subscribed_event has a ringbuffer of raised
(pending) events of that particular type.
-- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
+- If struct v4l2_subscribed_event is associated with a specific
object, then that object will have an internal list of
- struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
+ struct v4l2_subscribed_event so it knows who subscribed an
event to that object.
-Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
+Furthermore, the internal struct v4l2_subscribed_event has
``merge()`` and ``replace()`` callbacks which drivers can set. These
callbacks are called when a new event is raised and there is no more room.
@@ -167,7 +167,7 @@ The first event type in the class is reserved for future use, so the first
available event type is 'class base + 1'.
An example on how the V4L2 events may be used can be found in the OMAP
-3 ISP driver (``drivers/media/platform/omap3isp``).
+3 ISP driver (``drivers/media/platform/ti/omap3isp``).
A subdev can directly send an event to the :c:type:`v4l2_device` notify
function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
diff --git a/Documentation/driver-api/media/v4l2-fh.rst b/Documentation/driver-api/media/v4l2-fh.rst
index 4c62b19af744..3eeaa8da0c9e 100644
--- a/Documentation/driver-api/media/v4l2-fh.rst
+++ b/Documentation/driver-api/media/v4l2-fh.rst
@@ -3,11 +3,11 @@
V4L2 File handlers
------------------
-struct :c:type:`v4l2_fh` provides a way to easily keep file handle specific
+struct v4l2_fh provides a way to easily keep file handle specific
data that is used by the V4L2 framework.
.. attention::
- New drivers must use struct :c:type:`v4l2_fh`
+ New drivers must use struct v4l2_fh
since it is also used to implement priority handling
(:ref:`VIDIOC_G_PRIORITY`).
@@ -16,11 +16,11 @@ whether a driver uses :c:type:`v4l2_fh` as its ``file->private_data`` pointer
by testing the ``V4L2_FL_USES_V4L2_FH`` bit in :c:type:`video_device`->flags.
This bit is set whenever :c:func:`v4l2_fh_init` is called.
-struct :c:type:`v4l2_fh` is allocated as a part of the driver's own file handle
+struct v4l2_fh is allocated as a part of the driver's own file handle
structure and ``file->private_data`` is set to it in the driver's ``open()``
function by the driver.
-In many cases the struct :c:type:`v4l2_fh` will be embedded in a larger
+In many cases the struct v4l2_fh will be embedded in a larger
structure. In that case you should call:
#) :c:func:`v4l2_fh_init` and :c:func:`v4l2_fh_add` in ``open()``
@@ -102,18 +102,18 @@ Below is a short description of the :c:type:`v4l2_fh` functions used:
memory can be freed.
-If struct :c:type:`v4l2_fh` is not embedded, then you can use these helper functions:
+If struct v4l2_fh is not embedded, then you can use these helper functions:
:c:func:`v4l2_fh_open <v4l2_fh_open>`
(struct file \*filp)
-- This allocates a struct :c:type:`v4l2_fh`, initializes it and adds it to
- the struct :c:type:`video_device` associated with the file struct.
+- This allocates a struct v4l2_fh, initializes it and adds it to
+ the struct video_device associated with the file struct.
:c:func:`v4l2_fh_release <v4l2_fh_release>`
(struct file \*filp)
-- This deletes it from the struct :c:type:`video_device` associated with the
+- This deletes it from the struct video_device associated with the
file struct, uninitialised the :c:type:`v4l2_fh` and frees it.
These two functions can be plugged into the v4l2_file_operation's ``open()``
diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
index bc7e1fc40a9d..13aec460e802 100644
--- a/Documentation/driver-api/media/v4l2-subdev.rst
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -34,7 +34,7 @@ provides host private data for that purpose that can be accessed with
From the bridge driver perspective, you load the sub-device module and somehow
obtain the :c:type:`v4l2_subdev` pointer. For i2c devices this is easy: you call
``i2c_get_clientdata()``. For other buses something similar needs to be done.
-Helper functions exists for sub-devices on an I2C bus that do most of this
+Helper functions exist for sub-devices on an I2C bus that do most of this
tricky work for you.
Each :c:type:`v4l2_subdev` contains function pointers that sub-device drivers
@@ -110,7 +110,7 @@ pads:
err = media_entity_pads_init(&sd->entity, npads, pads);
The pads array must have been previously initialized. There is no need to
-manually set the struct :c:type:`media_entity` function and name fields, but the
+manually set the struct media_entity function and name fields, but the
revision field must be initialized if needed.
A reference to the entity will be automatically acquired/released when the
@@ -122,15 +122,12 @@ Don't forget to cleanup the media entity before the sub-device is destroyed:
media_entity_cleanup(&sd->entity);
-If the subdev driver intends to process video and integrate with the media
-framework, it must implement format related functionality using
-:c:type:`v4l2_subdev_pad_ops` instead of :c:type:`v4l2_subdev_video_ops`.
-
-In that case, the subdev driver may set the link_validate field to provide
-its own link validation function. The link validation function is called for
-every link in the pipeline where both of the ends of the links are V4L2
-sub-devices. The driver is still responsible for validating the correctness
-of the format configuration between sub-devices and video nodes.
+If a sub-device driver implements sink pads, the subdev driver may set the
+link_validate field in :c:type:`v4l2_subdev_pad_ops` to provide its own link
+validation function. For every link in the pipeline, the link_validate pad
+operation of the sink end of the link is called. In both cases the driver is
+still responsible for validating the correctness of the format configuration
+between sub-devices and video nodes.
If link_validate op is not set, the default function
:c:func:`v4l2_subdev_link_validate_default` is used instead. This function
@@ -138,6 +135,9 @@ ensures that width, height and the media bus pixel code are equal on both source
and sink of the link. Subdev drivers are also free to use this function to
perform the checks mentioned above in addition to their own checks.
+Subdev registration
+~~~~~~~~~~~~~~~~~~~
+
There are currently two ways to register subdevices with the V4L2 core. The
first (traditional) possibility is to have subdevices registered by bridge
drivers. This can be done when the bridge driver has the complete information
@@ -157,7 +157,10 @@ below.
Using one or the other registration method only affects the probing process, the
run-time bridge-subdevice interaction is in both cases the same.
-In the synchronous case a device (bridge) driver needs to register the
+Registering synchronous sub-devices
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the **synchronous** case a device (bridge) driver needs to register the
:c:type:`v4l2_subdev` with the v4l2_device:
:c:func:`v4l2_device_register_subdev <v4l2_device_register_subdev>`
@@ -175,11 +178,125 @@ You can unregister a sub-device using:
:c:func:`v4l2_device_unregister_subdev <v4l2_device_unregister_subdev>`
(:c:type:`sd <v4l2_subdev>`).
-
Afterwards the subdev module can be unloaded and
:c:type:`sd <v4l2_subdev>`->dev == ``NULL``.
-You can call an ops function either directly:
+.. _media-registering-async-subdevs:
+
+Registering asynchronous sub-devices
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the **asynchronous** case subdevice probing can be invoked independently of
+the bridge driver availability. The subdevice driver then has to verify whether
+all the requirements for a successful probing are satisfied. This can include a
+check for a master clock availability. If any of the conditions aren't satisfied
+the driver might decide to return ``-EPROBE_DEFER`` to request further reprobing
+attempts. Once all conditions are met the subdevice shall be registered using
+the :c:func:`v4l2_async_register_subdev` function. Unregistration is
+performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
+registered this way are stored in a global list of subdevices, ready to be
+picked up by bridge drivers.
+
+Drivers must complete all initialization of the sub-device before
+registering it using :c:func:`v4l2_async_register_subdev`, including
+enabling runtime PM. This is because the sub-device becomes accessible
+as soon as it gets registered.
+
+Asynchronous sub-device notifiers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Bridge drivers in turn have to register a notifier object. This is performed
+using the :c:func:`v4l2_async_nf_register` call. To unregister the notifier the
+driver has to call :c:func:`v4l2_async_nf_unregister`. Before releasing memory
+of an unregister notifier, it must be cleaned up by calling
+:c:func:`v4l2_async_nf_cleanup`.
+
+Before registering the notifier, bridge drivers must do two things: first, the
+notifier must be initialized using the :c:func:`v4l2_async_nf_init`. Second,
+bridge drivers can then begin to form a list of async connection descriptors
+that the bridge device needs for its
+operation. :c:func:`v4l2_async_nf_add_fwnode`,
+:c:func:`v4l2_async_nf_add_fwnode_remote` and :c:func:`v4l2_async_nf_add_i2c`
+
+Async connection descriptors describe connections to external sub-devices the
+drivers for which are not yet probed. Based on an async connection, a media data
+or ancillary link may be created when the related sub-device becomes
+available. There may be one or more async connections to a given sub-device but
+this is not known at the time of adding the connections to the notifier. Async
+connections are bound as matching async sub-devices are found, one by one.
+
+Asynchronous sub-device notifier for sub-devices
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A driver that registers an asynchronous sub-device may also register an
+asynchronous notifier. This is called an asynchronous sub-device notifier and the
+process is similar to that of a bridge driver apart from that the notifier is
+initialised using :c:func:`v4l2_async_subdev_nf_init` instead. A sub-device
+notifier may complete only after the V4L2 device becomes available, i.e. there's
+a path via async sub-devices and notifiers to a notifier that is not an
+asynchronous sub-device notifier.
+
+Asynchronous sub-device registration helper for camera sensor drivers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:c:func:`v4l2_async_register_subdev_sensor` is a helper function for sensor
+drivers registering their own async connection, but it also registers a notifier
+and further registers async connections for lens and flash devices found in
+firmware. The notifier for the sub-device is unregistered and cleaned up with
+the async sub-device, using :c:func:`v4l2_async_unregister_subdev`.
+
+Asynchronous sub-device notifier example
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These functions allocate an async connection descriptor which is of type struct
+:c:type:`v4l2_async_connection` embedded in a driver-specific struct. The &struct
+:c:type:`v4l2_async_connection` shall be the first member of this struct:
+
+.. code-block:: c
+
+ struct my_async_connection {
+ struct v4l2_async_connection asc;
+ ...
+ };
+
+ struct my_async_connection *my_asc;
+ struct fwnode_handle *ep;
+
+ ...
+
+ my_asc = v4l2_async_nf_add_fwnode_remote(&notifier, ep,
+ struct my_async_connection);
+ fwnode_handle_put(ep);
+
+ if (IS_ERR(my_asc))
+ return PTR_ERR(my_asc);
+
+Asynchronous sub-device notifier callbacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The V4L2 core will then use these connection descriptors to match asynchronously
+registered subdevices to them. If a match is detected the ``.bound()`` notifier
+callback is called. After all connections have been bound the .complete()
+callback is called. When a connection is removed from the system the
+``.unbind()`` method is called. All three callbacks are optional.
+
+Drivers can store any type of custom data in their driver-specific
+:c:type:`v4l2_async_connection` wrapper. If any of that data requires special
+handling when the structure is freed, drivers must implement the ``.destroy()``
+notifier callback. The framework will call it right before freeing the
+:c:type:`v4l2_async_connection`.
+
+Calling subdev operations
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The advantage of using :c:type:`v4l2_subdev` is that it is a generic struct and
+does not contain any knowledge about the underlying hardware. So a driver might
+contain several subdevs that use an I2C bus, but also a subdev that is
+controlled through GPIO pins. This distinction is only relevant when setting
+up the device, but once the subdev is registered it is completely transparent.
+
+Once the subdev has been registered you can call an ops function either
+directly:
.. code-block:: c
@@ -191,7 +308,7 @@ but it is better and easier to use this macro:
err = v4l2_subdev_call(sd, core, g_std, &norm);
-The macro will to the right ``NULL`` pointer checks and returns ``-ENODEV``
+The macro will do the right ``NULL`` pointer checks and returns ``-ENODEV``
if :c:type:`sd <v4l2_subdev>` is ``NULL``, ``-ENOIOCTLCMD`` if either
:c:type:`sd <v4l2_subdev>`->core or :c:type:`sd <v4l2_subdev>`->core->g_std is ``NULL``, or the actual result of the
:c:type:`sd <v4l2_subdev>`->ops->core->g_std ops.
@@ -232,46 +349,6 @@ it can call ``v4l2_subdev_notify(sd, notification, arg)``. This macro checks
whether there is a ``notify()`` callback defined and returns ``-ENODEV`` if not.
Otherwise the result of the ``notify()`` call is returned.
-The advantage of using :c:type:`v4l2_subdev` is that it is a generic struct and
-does not contain any knowledge about the underlying hardware. So a driver might
-contain several subdevs that use an I2C bus, but also a subdev that is
-controlled through GPIO pins. This distinction is only relevant when setting
-up the device, but once the subdev is registered it is completely transparent.
-
-In the asynchronous case subdevice probing can be invoked independently of the
-bridge driver availability. The subdevice driver then has to verify whether all
-the requirements for a successful probing are satisfied. This can include a
-check for a master clock availability. If any of the conditions aren't satisfied
-the driver might decide to return ``-EPROBE_DEFER`` to request further reprobing
-attempts. Once all conditions are met the subdevice shall be registered using
-the :c:func:`v4l2_async_register_subdev` function. Unregistration is
-performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
-registered this way are stored in a global list of subdevices, ready to be
-picked up by bridge drivers.
-
-Bridge drivers in turn have to register a notifier object. This is
-performed using the :c:func:`v4l2_async_notifier_register` call. To
-unregister the notifier the driver has to call
-:c:func:`v4l2_async_notifier_unregister`. The former of the two functions
-takes two arguments: a pointer to struct :c:type:`v4l2_device` and a
-pointer to struct :c:type:`v4l2_async_notifier`.
-
-Before registering the notifier, bridge drivers must do two things:
-first, the notifier must be initialized using the
-:c:func:`v4l2_async_notifier_init`. Second, bridge drivers can then
-begin to form a list of subdevice descriptors that the bridge device
-needs for its operation. Subdevice descriptors are added to the notifier
-using the :c:func:`v4l2_async_notifier_add_subdev` call. This function
-takes two arguments: a pointer to struct :c:type:`v4l2_async_notifier`,
-and a pointer to the subdevice descripter, which is of type struct
-:c:type:`v4l2_async_subdev`.
-
-The V4L2 core will then use these descriptors to match asynchronously
-registered subdevices to them. If a match is detected the ``.bound()``
-notifier callback is called. After all subdevices have been located the
-.complete() callback is called. When a subdevice is removed from the
-system the .unbind() method is called. All three callbacks are optional.
-
V4L2 sub-device userspace API
-----------------------------
@@ -281,7 +358,7 @@ response to video node operations. This hides the complexity of the underlying
hardware from applications. For complex devices, finer-grained control of the
device than what the video nodes offer may be required. In those cases, bridge
drivers that implement :ref:`the media controller API <media_controller>` may
-opt for making the subdevice operations directly accessible from userpace.
+opt for making the subdevice operations directly accessible from userspace.
Device nodes named ``v4l-subdev``\ *X* can be created in ``/dev`` to access
sub-devices directly. If a sub-device supports direct userspace configuration
@@ -484,9 +561,84 @@ The :c:func:`v4l2_i2c_new_subdev` function will call
:c:type:`i2c_board_info` structure using the ``client_type`` and the
``addr`` to fill it.
+Centrally managed subdev active state
+-------------------------------------
+
+Traditionally V4L2 subdev drivers maintained internal state for the active
+device configuration. This is often implemented as e.g. an array of struct
+v4l2_mbus_framefmt, one entry for each pad, and similarly for crop and compose
+rectangles.
+
+In addition to the active configuration, each subdev file handle has a struct
+v4l2_subdev_state, managed by the V4L2 core, which contains the try
+configuration.
+
+To simplify the subdev drivers the V4L2 subdev API now optionally supports a
+centrally managed active configuration represented by
+:c:type:`v4l2_subdev_state`. One instance of state, which contains the active
+device configuration, is stored in the sub-device itself as part of
+the :c:type:`v4l2_subdev` structure, while the core associates a try state to
+each open file handle, to store the try configuration related to that file
+handle.
+
+Sub-device drivers can opt-in and use state to manage their active configuration
+by initializing the subdevice state with a call to v4l2_subdev_init_finalize()
+before registering the sub-device. They must also call v4l2_subdev_cleanup()
+to release all the allocated resources before unregistering the sub-device.
+The core automatically allocates and initializes a state for each open file
+handle to store the try configurations and frees it when closing the file
+handle.
+
+V4L2 sub-device operations that use both the :ref:`ACTIVE and TRY formats
+<v4l2-subdev-format-whence>` receive the correct state to operate on through
+the 'state' parameter. The state must be locked and unlocked by the
+caller by calling :c:func:`v4l2_subdev_lock_state()` and
+:c:func:`v4l2_subdev_unlock_state()`. The caller can do so by calling the subdev
+operation through the :c:func:`v4l2_subdev_call_state_active()` macro.
+
+Operations that do not receive a state parameter implicitly operate on the
+subdevice active state, which drivers can exclusively access by
+calling :c:func:`v4l2_subdev_lock_and_get_active_state()`. The sub-device active
+state must equally be released by calling :c:func:`v4l2_subdev_unlock_state()`.
+
+Drivers must never manually access the state stored in the :c:type:`v4l2_subdev`
+or in the file handle without going through the designated helpers.
+
+While the V4L2 core passes the correct try or active state to the subdevice
+operations, many existing device drivers pass a NULL state when calling
+operations with :c:func:`v4l2_subdev_call()`. This legacy construct causes
+issues with subdevice drivers that let the V4L2 core manage the active state,
+as they expect to receive the appropriate state as a parameter. To help the
+conversion of subdevice drivers to a managed active state without having to
+convert all callers at the same time, an additional wrapper layer has been
+added to v4l2_subdev_call(), which handles the NULL case by getting and locking
+the callee's active state with :c:func:`v4l2_subdev_lock_and_get_active_state()`,
+and unlocking the state after the call.
+
+The whole subdev state is in reality split into three parts: the
+v4l2_subdev_state, subdev controls and subdev driver's internal state. In the
+future these parts should be combined into a single state. For the time being
+we need a way to handle the locking for these parts. This can be accomplished
+by sharing a lock. The v4l2_ctrl_handler already supports this via its 'lock'
+pointer and the same model is used with states. The driver can do the following
+before calling v4l2_subdev_init_finalize():
+
+.. code-block:: c
+
+ sd->ctrl_handler->lock = &priv->mutex;
+ sd->state_lock = &priv->mutex;
+
+This shares the driver's private mutex between the controls and the states.
+
+Streams, multiplexed media pads and internal routing
+----------------------------------------------------
+
+A subdevice driver can implement support for multiplexed streams by setting
+the V4L2_SUBDEV_FL_STREAMS subdev flag and implementing support for
+centrally managed subdev active state, routing and stream based
+configuration.
+
V4L2 sub-device functions and data structures
---------------------------------------------
.. kernel-doc:: include/media/v4l2-subdev.h
-
-.. kernel-doc:: include/media/v4l2-async.h
diff --git a/Documentation/driver-api/media/v4l2-videobuf.rst b/Documentation/driver-api/media/v4l2-videobuf.rst
deleted file mode 100644
index 4b1d84eefeb8..000000000000
--- a/Documentation/driver-api/media/v4l2-videobuf.rst
+++ /dev/null
@@ -1,403 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-.. _vb_framework:
-
-Videobuf Framework
-==================
-
-Author: Jonathan Corbet <corbet@lwn.net>
-
-Current as of 2.6.33
-
-.. note::
-
- The videobuf framework was deprecated in favor of videobuf2. Shouldn't
- be used on new drivers.
-
-Introduction
-------------
-
-The videobuf layer functions as a sort of glue layer between a V4L2 driver
-and user space. It handles the allocation and management of buffers for
-the storage of video frames. There is a set of functions which can be used
-to implement many of the standard POSIX I/O system calls, including read(),
-poll(), and, happily, mmap(). Another set of functions can be used to
-implement the bulk of the V4L2 ioctl() calls related to streaming I/O,
-including buffer allocation, queueing and dequeueing, and streaming
-control. Using videobuf imposes a few design decisions on the driver
-author, but the payback comes in the form of reduced code in the driver and
-a consistent implementation of the V4L2 user-space API.
-
-Buffer types
-------------
-
-Not all video devices use the same kind of buffers. In fact, there are (at
-least) three common variations:
-
- - Buffers which are scattered in both the physical and (kernel) virtual
- address spaces. (Almost) all user-space buffers are like this, but it
- makes great sense to allocate kernel-space buffers this way as well when
- it is possible. Unfortunately, it is not always possible; working with
- this kind of buffer normally requires hardware which can do
- scatter/gather DMA operations.
-
- - Buffers which are physically scattered, but which are virtually
- contiguous; buffers allocated with vmalloc(), in other words. These
- buffers are just as hard to use for DMA operations, but they can be
- useful in situations where DMA is not available but virtually-contiguous
- buffers are convenient.
-
- - Buffers which are physically contiguous. Allocation of this kind of
- buffer can be unreliable on fragmented systems, but simpler DMA
- controllers cannot deal with anything else.
-
-Videobuf can work with all three types of buffers, but the driver author
-must pick one at the outset and design the driver around that decision.
-
-[It's worth noting that there's a fourth kind of buffer: "overlay" buffers
-which are located within the system's video memory. The overlay
-functionality is considered to be deprecated for most use, but it still
-shows up occasionally in system-on-chip drivers where the performance
-benefits merit the use of this technique. Overlay buffers can be handled
-as a form of scattered buffer, but there are very few implementations in
-the kernel and a description of this technique is currently beyond the
-scope of this document.]
-
-Data structures, callbacks, and initialization
-----------------------------------------------
-
-Depending on which type of buffers are being used, the driver should
-include one of the following files:
-
-.. code-block:: none
-
- <media/videobuf-dma-sg.h> /* Physically scattered */
- <media/videobuf-vmalloc.h> /* vmalloc() buffers */
- <media/videobuf-dma-contig.h> /* Physically contiguous */
-
-The driver's data structure describing a V4L2 device should include a
-struct videobuf_queue instance for the management of the buffer queue,
-along with a list_head for the queue of available buffers. There will also
-need to be an interrupt-safe spinlock which is used to protect (at least)
-the queue.
-
-The next step is to write four simple callbacks to help videobuf deal with
-the management of buffers:
-
-.. code-block:: none
-
- 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);
- };
-
-buf_setup() is called early in the I/O process, when streaming is being
-initiated; its purpose is to tell videobuf about the I/O stream. The count
-parameter will be a suggested number of buffers to use; the driver should
-check it for rationality and adjust it if need be. As a practical rule, a
-minimum of two buffers are needed for proper streaming, and there is
-usually a maximum (which cannot exceed 32) which makes sense for each
-device. The size parameter should be set to the expected (maximum) size
-for each frame of data.
-
-Each buffer (in the form of a struct videobuf_buffer pointer) will be
-passed to buf_prepare(), which should set the buffer's size, width, height,
-and field fields properly. If the buffer's state field is
-VIDEOBUF_NEEDS_INIT, the driver should pass it to:
-
-.. code-block:: none
-
- int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
- struct v4l2_framebuffer *fbuf);
-
-Among other things, this call will usually allocate memory for the buffer.
-Finally, the buf_prepare() function should set the buffer's state to
-VIDEOBUF_PREPARED.
-
-When a buffer is queued for I/O, it is passed to buf_queue(), which should
-put it onto the driver's list of available buffers and set its state to
-VIDEOBUF_QUEUED. Note that this function is called with the queue spinlock
-held; if it tries to acquire it as well things will come to a screeching
-halt. Yes, this is the voice of experience. Note also that videobuf may
-wait on the first buffer in the queue; placing other buffers in front of it
-could again gum up the works. So use list_add_tail() to enqueue buffers.
-
-Finally, buf_release() is called when a buffer is no longer intended to be
-used. The driver should ensure that there is no I/O active on the buffer,
-then pass it to the appropriate free routine(s):
-
-.. code-block:: none
-
- /* Scatter/gather drivers */
- int videobuf_dma_unmap(struct videobuf_queue *q,
- struct videobuf_dmabuf *dma);
- int videobuf_dma_free(struct videobuf_dmabuf *dma);
-
- /* vmalloc drivers */
- void videobuf_vmalloc_free (struct videobuf_buffer *buf);
-
- /* Contiguous drivers */
- void videobuf_dma_contig_free(struct videobuf_queue *q,
- struct videobuf_buffer *buf);
-
-One way to ensure that a buffer is no longer under I/O is to pass it to:
-
-.. code-block:: none
-
- int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
-
-Here, vb is the buffer, non_blocking indicates whether non-blocking I/O
-should be used (it should be zero in the buf_release() case), and intr
-controls whether an interruptible wait is used.
-
-File operations
----------------
-
-At this point, much of the work is done; much of the rest is slipping
-videobuf calls into the implementation of the other driver callbacks. The
-first step is in the open() function, which must initialize the
-videobuf queue. The function to use depends on the type of buffer used:
-
-.. code-block:: none
-
- void videobuf_queue_sg_init(struct videobuf_queue *q,
- 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);
-
- void videobuf_queue_vmalloc_init(struct videobuf_queue *q,
- 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);
-
- void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
- 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);
-
-In each case, the parameters are the same: q is the queue structure for the
-device, ops is the set of callbacks as described above, dev is the device
-structure for this video device, irqlock is an interrupt-safe spinlock to
-protect access to the data structures, type is the buffer type used by the
-device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field
-describes which field is being captured (often V4L2_FIELD_NONE for
-progressive devices), msize is the size of any containing structure used
-around struct videobuf_buffer, and priv is a private data pointer which
-shows up in the priv_data field of struct videobuf_queue. Note that these
-are void functions which, evidently, are immune to failure.
-
-V4L2 capture drivers can be written to support either of two APIs: the
-read() system call and the rather more complicated streaming mechanism. As
-a general rule, it is necessary to support both to ensure that all
-applications have a chance of working with the device. Videobuf makes it
-easy to do that with the same code. To implement read(), the driver need
-only make a call to one of:
-
-.. code-block:: none
-
- ssize_t videobuf_read_one(struct videobuf_queue *q,
- char __user *data, size_t count,
- loff_t *ppos, int nonblocking);
-
- ssize_t videobuf_read_stream(struct videobuf_queue *q,
- char __user *data, size_t count,
- loff_t *ppos, int vbihack, int nonblocking);
-
-Either one of these functions will read frame data into data, returning the
-amount actually read; the difference is that videobuf_read_one() will only
-read a single frame, while videobuf_read_stream() will read multiple frames
-if they are needed to satisfy the count requested by the application. A
-typical driver read() implementation will start the capture engine, call
-one of the above functions, then stop the engine before returning (though a
-smarter implementation might leave the engine running for a little while in
-anticipation of another read() call happening in the near future).
-
-The poll() function can usually be implemented with a direct call to:
-
-.. code-block:: none
-
- unsigned int videobuf_poll_stream(struct file *file,
- struct videobuf_queue *q,
- poll_table *wait);
-
-Note that the actual wait queue eventually used will be the one associated
-with the first available buffer.
-
-When streaming I/O is done to kernel-space buffers, the driver must support
-the mmap() system call to enable user space to access the data. In many
-V4L2 drivers, the often-complex mmap() implementation simplifies to a
-single call to:
-
-.. code-block:: none
-
- int videobuf_mmap_mapper(struct videobuf_queue *q,
- struct vm_area_struct *vma);
-
-Everything else is handled by the videobuf code.
-
-The release() function requires two separate videobuf calls:
-
-.. code-block:: none
-
- void videobuf_stop(struct videobuf_queue *q);
- int videobuf_mmap_free(struct videobuf_queue *q);
-
-The call to videobuf_stop() terminates any I/O in progress - though it is
-still up to the driver to stop the capture engine. The call to
-videobuf_mmap_free() will ensure that all buffers have been unmapped; if
-so, they will all be passed to the buf_release() callback. If buffers
-remain mapped, videobuf_mmap_free() returns an error code instead. The
-purpose is clearly to cause the closing of the file descriptor to fail if
-buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully
-ignores its return value.
-
-ioctl() operations
-------------------
-
-The V4L2 API includes a very long list of driver callbacks to respond to
-the many ioctl() commands made available to user space. A number of these
-- those associated with streaming I/O - turn almost directly into videobuf
-calls. The relevant helper functions are:
-
-.. code-block:: none
-
- 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);
-
-So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's
-vidioc_reqbufs() callback which, in turn, usually only needs to locate the
-proper struct videobuf_queue pointer and pass it to videobuf_reqbufs().
-These support functions can replace a great deal of buffer management
-boilerplate in a lot of V4L2 drivers.
-
-The vidioc_streamon() and vidioc_streamoff() functions will be a bit more
-complex, of course, since they will also need to deal with starting and
-stopping the capture engine.
-
-Buffer allocation
------------------
-
-Thus far, we have talked about buffers, but have not looked at how they are
-allocated. The scatter/gather case is the most complex on this front. For
-allocation, the driver can leave buffer allocation entirely up to the
-videobuf layer; in this case, buffers will be allocated as anonymous
-user-space pages and will be very scattered indeed. If the application is
-using user-space buffers, no allocation is needed; the videobuf layer will
-take care of calling get_user_pages() and filling in the scatterlist array.
-
-If the driver needs to do its own memory allocation, it should be done in
-the vidioc_reqbufs() function, *after* calling videobuf_reqbufs(). The
-first step is a call to:
-
-.. code-block:: none
-
- struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
-
-The returned videobuf_dmabuf structure (defined in
-<media/videobuf-dma-sg.h>) includes a couple of relevant fields:
-
-.. code-block:: none
-
- struct scatterlist *sglist;
- int sglen;
-
-The driver must allocate an appropriately-sized scatterlist array and
-populate it with pointers to the pieces of the allocated buffer; sglen
-should be set to the length of the array.
-
-Drivers using the vmalloc() method need not (and cannot) concern themselves
-with buffer allocation at all; videobuf will handle those details. The
-same is normally true of contiguous-DMA drivers as well; videobuf will
-allocate the buffers (with dma_alloc_coherent()) when it sees fit. That
-means that these drivers may be trying to do high-order allocations at any
-time, an operation which is not always guaranteed to work. Some drivers
-play tricks by allocating DMA space at system boot time; videobuf does not
-currently play well with those drivers.
-
-As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer,
-as long as that buffer is physically contiguous. Normal user-space
-allocations will not meet that criterion, but buffers obtained from other
-kernel drivers, or those contained within huge pages, will work with these
-drivers.
-
-Filling the buffers
--------------------
-
-The final part of a videobuf implementation has no direct callback - it's
-the portion of the code which actually puts frame data into the buffers,
-usually in response to interrupts from the device. For all types of
-drivers, this process works approximately as follows:
-
- - Obtain the next available buffer and make sure that somebody is actually
- waiting for it.
-
- - Get a pointer to the memory and put video data there.
-
- - Mark the buffer as done and wake up the process waiting for it.
-
-Step (1) above is done by looking at the driver-managed list_head structure
-- the one which is filled in the buf_queue() callback. Because starting
-the engine and enqueueing buffers are done in separate steps, it's possible
-for the engine to be running without any buffers available - in the
-vmalloc() case especially. So the driver should be prepared for the list
-to be empty. It is equally possible that nobody is yet interested in the
-buffer; the driver should not remove it from the list or fill it until a
-process is waiting on it. That test can be done by examining the buffer's
-done field (a wait_queue_head_t structure) with waitqueue_active().
-
-A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for
-DMA; that ensures that the videobuf layer will not try to do anything with
-it while the device is transferring data.
-
-For scatter/gather drivers, the needed memory pointers will be found in the
-scatterlist structure described above. Drivers using the vmalloc() method
-can get a memory pointer with:
-
-.. code-block:: none
-
- void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
-
-For contiguous DMA drivers, the function to use is:
-
-.. code-block:: none
-
- dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
-
-The contiguous DMA API goes out of its way to hide the kernel-space address
-of the DMA buffer from drivers.
-
-The final step is to set the size field of the relevant videobuf_buffer
-structure to the actual size of the captured image, set state to
-VIDEOBUF_DONE, then call wake_up() on the done queue. At this point, the
-buffer is owned by the videobuf layer and the driver should not touch it
-again.
-
-Developers who are interested in more information can go into the relevant
-header files; there are a few low-level functions declared there which have
-not been talked about here. Note also that all of these calls are exported
-GPL-only, so they will not be available to non-GPL kernel modules.