mirror of https://gitee.com/openkylin/linux.git
media updates for v5.3-rc1
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAl0kcloACgkQCF8+vY7k 4RU0Mg//c0BK1VjPfh45k3HxDvvoQnaTlQjo1ApvEBa64TR10/JxXi9U+QuhY1H1 QEOjJJrLe3OdWrcBwFT5s15cBdRKn6jB8s67FgN7CFA8IzG4xBjOovOP4MXYXztz TjNlkLwWkkwiQ4C99HInSsmI36ZbnEI3PloJXMrEBnsXQIazjRzMeJ3DKZggSSkN jhedASDgnHgSun0rCFh0mN8k2kiMUZ/XxVIqiCuWT1AzyycoHp+HXm9YilnxD7q0 43X6v4HtxrfJMQWQ8z3Pxb4McHc1j3L8S7Mgu9oSf7oJb12grsDxokytUCnmhFz8 gvNgx3D2OTQk2nrQlxcfgrbqMs2KXLkXIiqg/dZ35hpNfXIOxiOx77zqqIsg2WHr j4qaDcw+TNQU1eUIm0dIcPFi82EMOjAUqHRrvsg94EbBQ1dUniE4GCkCHFU+2TLz YIaWXv/WmavrWTydsoIKqbBBOR9OY9+PDjkxgHsSVPSZ9sAskcPQ5MJdkatoZcu/ glZJD8HEe/w1vi1Ob3ZsXU7KzNWAhIkWvtEWsxAuFGzr8uNfwmzM2a5giNLIV94b W+ZYhQT363uliVSOPFRjqqkVliC/HmV2lcNVzlVymWgeKhRj8fI5JqrDhpLz0XD+ 9Rn90mweCzCSw7/fj/keP9mEnMce4XdkkDB/Pyf+dIMiLMOczoU= =ABgl -----END PGP SIGNATURE----- Merge tag 'media/v5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - new Atmel microship ISC driver - coda has gained support for mpeg2 and mpeg4 - cxusb gained support for analog TV - rockchip staging driver was split into two separate staging drivers - added a new staging driver for Allegro DVT video IP core - added a new staging driver for Amlogic Meson video decoder - lots of improvements and cleanups * tag 'media/v5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (398 commits) media: allegro: use new v4l2_m2m_ioctl_try_encoder_cmd funcs media: doc-rst: Fix typos media: radio-raremono: change devm_k*alloc to k*alloc media: stv0297: fix frequency range limit media: rc: Prefer KEY_NUMERIC_* for number buttons on remotes media: dvb_frontend: split dvb_frontend_handle_ioctl function media: mceusb: disable "nonsensical irdata" messages media: rc: remove redundant dev_err message media: cec-notifier: add new notifier functions media: cec: add struct cec_connector_info support media: cec-notifier: rename variables, check kstrdup and n->conn_name media: MAINTAINERS: Add maintainers for Media Controller media: staging: media: tegra-vde: Defer dmabuf's unmapping media: staging: media: tegra-vde: Add IOMMU support media: hdpvr: fix locking and a missing msleep media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() media: atmel: atmel-isc: fix i386 build error media: v4l2-ctrl: Move compound control initialization media: hantro: Use vb2_get_buffer media: pci: cx88: Change the type of 'missed' to u64 ...
This commit is contained in:
commit
ed63b9c873
|
@ -1,6 +1,6 @@
|
|||
What: /sys/kernel/debug/cec/*/error-inj
|
||||
Date: March 2018
|
||||
Contact: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
Contact: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
Description:
|
||||
|
||||
The CEC Framework allows for CEC error injection commands through
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
Device-tree bindings for the Allegro DVT video IP codecs present in the Xilinx
|
||||
ZynqMP SoC. The IP core may either be a H.264/H.265 encoder or H.264/H.265
|
||||
decoder ip core.
|
||||
|
||||
Each actual codec engines is controlled by a microcontroller (MCU). Host
|
||||
software uses a provided mailbox interface to communicate with the MCU. The
|
||||
MCU share an interrupt.
|
||||
|
||||
Required properties:
|
||||
- compatible: value should be one of the following
|
||||
"allegro,al5e-1.1", "allegro,al5e": encoder IP core
|
||||
"allegro,al5d-1.1", "allegro,al5d": decoder IP core
|
||||
- reg: base and length of the memory mapped register region and base and
|
||||
length of the memory mapped sram
|
||||
- reg-names: must include "regs" and "sram"
|
||||
- interrupts: shared interrupt from the MCUs to the processing system
|
||||
- clocks: must contain an entry for each entry in clock-names
|
||||
- clock-names: must include "core_clk", "mcu_clk", "m_axi_core_aclk",
|
||||
"m_axi_mcu_aclk", "s_axi_lite_aclk"
|
||||
|
||||
Example:
|
||||
al5e: video-codec@a0009000 {
|
||||
compatible = "allegro,al5e-1.1", "allegro,al5e";
|
||||
reg = <0 0xa0009000 0 0x1000>,
|
||||
<0 0xa0000000 0 0x8000>;
|
||||
reg-names = "regs", "sram";
|
||||
interrupts = <0 96 4>;
|
||||
clocks = <&xlnx_vcu 0>, <&xlnx_vcu 1>,
|
||||
<&clkc 71>, <&clkc 71>, <&clkc 71>;
|
||||
clock-names = "core_clk", "mcu_clk", "m_axi_core_aclk",
|
||||
"m_axi_mcu_aclk", "s_axi_lite_aclk"
|
||||
};
|
||||
al5d: video-codec@a0029000 {
|
||||
compatible = "allegro,al5d-1.1", "allegro,al5d";
|
||||
reg = <0 0xa0029000 0 0x1000>,
|
||||
<0 0xa0020000 0 0x8000>;
|
||||
reg-names = "regs", "sram";
|
||||
interrupts = <0 96 4>;
|
||||
clocks = <&xlnx_vcu 2>, <&xlnx_vcu 3>,
|
||||
<&clkc 71>, <&clkc 71>, <&clkc 71>;
|
||||
clock-names = "core_clk", "mcu_clk", "m_axi_core_aclk",
|
||||
"m_axi_mcu_aclk", "s_axi_lite_aclk"
|
||||
};
|
|
@ -0,0 +1,71 @@
|
|||
Amlogic Video Decoder
|
||||
================================
|
||||
|
||||
The video decoding IP lies within the DOS memory region,
|
||||
except for the hardware bitstream parser that makes use of an undocumented
|
||||
region.
|
||||
|
||||
It makes use of the following blocks:
|
||||
|
||||
- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks
|
||||
then feed from this VIFIFO.
|
||||
- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, MJPEG, H.263, H.264, VC-1.
|
||||
- VDEC_HEVC can decode HEVC and VP9.
|
||||
|
||||
Both VDEC_1 and VDEC_HEVC share the "vdec" IRQ and as such cannot run
|
||||
concurrently.
|
||||
|
||||
Device Tree Bindings:
|
||||
---------------------
|
||||
|
||||
VDEC: Video Decoder
|
||||
--------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: value should be different for each SoC family as :
|
||||
- GXBB (S905) : "amlogic,gxbb-vdec"
|
||||
- GXL (S905X, S905D) : "amlogic,gxl-vdec"
|
||||
- GXM (S912) : "amlogic,gxm-vdec"
|
||||
- reg: base address and size of he following memory-mapped regions :
|
||||
- dos
|
||||
- esparser
|
||||
- reg-names: should contain the names of the previous memory regions
|
||||
- interrupts: should contain the following IRQs:
|
||||
- vdec
|
||||
- esparser
|
||||
- interrupt-names: should contain the names of the previous interrupts
|
||||
- amlogic,ao-sysctrl: should point to the AOBUS sysctrl node
|
||||
- amlogic,canvas: should point to a canvas provider node
|
||||
- clocks: should contain the following clocks :
|
||||
- dos_parser
|
||||
- dos
|
||||
- vdec_1
|
||||
- vdec_hevc
|
||||
- clock-names: should contain the names of the previous clocks
|
||||
- resets: should contain the parser reset
|
||||
- reset-names: should be "esparser"
|
||||
|
||||
Example:
|
||||
|
||||
vdec: video-decoder@c8820000 {
|
||||
compatible = "amlogic,gxbb-vdec";
|
||||
reg = <0x0 0xc8820000 0x0 0x10000>,
|
||||
<0x0 0xc110a580 0x0 0xe4>;
|
||||
reg-names = "dos", "esparser";
|
||||
|
||||
interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "vdec", "esparser";
|
||||
|
||||
amlogic,ao-sysctrl = <&sysctrl_AO>;
|
||||
amlogic,canvas = <&canvas>;
|
||||
|
||||
clocks = <&clkc CLKID_DOS_PARSER>,
|
||||
<&clkc CLKID_DOS>,
|
||||
<&clkc CLKID_VDEC_1>,
|
||||
<&clkc CLKID_VDEC_HEVC>;
|
||||
clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
|
||||
|
||||
resets = <&reset RESET_PARSER>;
|
||||
reset-names = "esparser";
|
||||
};
|
|
@ -14,8 +14,7 @@ Required properties:
|
|||
- interrupts : should contain CSI interrupt;
|
||||
- clocks : list of clock specifiers, see
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt for details;
|
||||
- clock-names : must contain "axi", "mclk" and "dcic" entries, matching
|
||||
entries in the clock property;
|
||||
- clock-names : must contain "mclk";
|
||||
|
||||
The device node shall contain one 'port' child node with one child 'endpoint'
|
||||
node, according to the bindings defined in:
|
||||
|
@ -32,10 +31,8 @@ example:
|
|||
compatible = "fsl,imx7-csi";
|
||||
reg = <0x30710000 0x10000>;
|
||||
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX7D_CLK_DUMMY>,
|
||||
<&clks IMX7D_CSI_MCLK_ROOT_CLK>,
|
||||
<&clks IMX7D_CLK_DUMMY>;
|
||||
clock-names = "axi", "mclk", "dcic";
|
||||
clocks = <&clks IMX7D_CSI_MCLK_ROOT_CLK>;
|
||||
clock-names = "mclk";
|
||||
|
||||
port {
|
||||
csi_from_csi_mux: endpoint {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
Marvell MMP2 camera host interface
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "marvell,mmp2-ccic".
|
||||
- reg: Register base and size.
|
||||
- interrupts: The interrupt number.
|
||||
- #clock-cells: Must be 0.
|
||||
|
||||
Optional properties:
|
||||
- clocks: Reference to the input clock as specified by
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt.
|
||||
- clock-names: Names of the clocks used; "axi" for the AXI bus interface,
|
||||
"func" for the peripheral clock and "phy" for the parallel
|
||||
video bus interface.
|
||||
- clock-output-names: Optional clock source for sensors. Shall be "mclk".
|
||||
|
||||
Required subnodes:
|
||||
- port: The parallel bus interface port with a single endpoint linked to
|
||||
the sensor's endpoint as described in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
Required endpoint properties:
|
||||
- bus-type: data bus type, <5> or <6> for Parallel or Bt.656 respectively
|
||||
- pclk-sample: pixel clock polarity
|
||||
- hsync-active: horizontal synchronization polarity (only required for
|
||||
parallel bus)
|
||||
- vsync-active: vertical synchronization polarity (only required for
|
||||
parallel bus)
|
||||
|
||||
Example:
|
||||
|
||||
camera0: camera@d420a000 {
|
||||
compatible = "marvell,mmp2-ccic";
|
||||
reg = <0xd420a000 0x800>;
|
||||
interrupts = <42>;
|
||||
clocks = <&soc_clocks MMP2_CLK_CCIC0>;
|
||||
clock-names = "axi";
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "mclk";
|
||||
|
||||
port {
|
||||
camera0_0: endpoint {
|
||||
remote-endpoint = <&ov7670_0>;
|
||||
bus-type = <5>; /* Parallel */
|
||||
hsync-active = <1>; /* Active high */
|
||||
vsync-active = <1>; /* Active high */
|
||||
pclk-sample = <0>; /* Falling */
|
||||
};
|
||||
};
|
||||
};
|
|
@ -6,6 +6,7 @@ Allwinner V3s SoC features a CSI module(CSI1) with parallel interface.
|
|||
Required properties:
|
||||
- compatible: value must be one of:
|
||||
* "allwinner,sun6i-a31-csi"
|
||||
* "allwinner,sun8i-a83t-csi"
|
||||
* "allwinner,sun8i-h3-csi"
|
||||
* "allwinner,sun8i-v3s-csi"
|
||||
* "allwinner,sun50i-a64-csi"
|
||||
|
|
|
@ -49,6 +49,8 @@ patternProperties:
|
|||
description: Aeroflex Gaisler AB
|
||||
"^al,.*":
|
||||
description: Annapurna Labs
|
||||
"^allegro,.*":
|
||||
description: Allegro DVT
|
||||
"^allo,.*":
|
||||
description: Allo.com
|
||||
"^allwinner,.*":
|
||||
|
|
|
@ -11,12 +11,12 @@ Digital TV devices are implemented by several different drivers:
|
|||
|
||||
- Frontend drivers that are usually implemented as two separate drivers:
|
||||
|
||||
- A tuner driver that implements the logic with commands the part of the
|
||||
hardware with is responsible to tune into a digital TV transponder or
|
||||
- A tuner driver that implements the logic which commands the part of
|
||||
the hardware responsible for tuning into a digital TV transponder or
|
||||
physical channel. The output of a tuner is usually a baseband or
|
||||
Intermediate Frequency (IF) signal;
|
||||
|
||||
- A demodulator driver (a.k.a "demod") that implements the logic with
|
||||
- A demodulator driver (a.k.a "demod") that implements the logic which
|
||||
commands the digital TV decoding hardware. The output of a demod is
|
||||
a digital stream, with multiple audio, video and data channels typically
|
||||
multiplexed using MPEG Transport Stream [#f1]_.
|
||||
|
|
|
@ -26,8 +26,9 @@ The control framework was created in order to implement all the rules of the
|
|||
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 v4l2_device
|
||||
for V4L2 drivers and struct v4l2_subdev for sub-device drivers.
|
||||
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
|
||||
sub-device drivers.
|
||||
|
||||
|
||||
Objects in the framework
|
||||
|
@ -35,12 +36,13 @@ Objects in the framework
|
|||
|
||||
There are two main objects:
|
||||
|
||||
The v4l2_ctrl object describes the control properties and keeps track of the
|
||||
control's value (both the current value and the proposed new value).
|
||||
The :c:type:`v4l2_ctrl` object describes the control properties and keeps
|
||||
track of the control's value (both the current value and the proposed new
|
||||
value).
|
||||
|
||||
v4l2_ctrl_handler is the object that keeps track of controls. It maintains a
|
||||
list of v4l2_ctrl objects that it owns and another list of references to
|
||||
controls, possibly to controls owned by other handlers.
|
||||
:c:type:`v4l2_ctrl_handler` is the object that keeps track of controls. It
|
||||
maintains a list of v4l2_ctrl objects that it owns and another list of
|
||||
references to controls, possibly to controls owned by other handlers.
|
||||
|
||||
|
||||
Basic usage for V4L2 and sub-device drivers
|
||||
|
@ -48,33 +50,15 @@ Basic usage for V4L2 and sub-device drivers
|
|||
|
||||
1) Prepare the driver:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
||||
1.1) Add the handler to your driver's top-level struct:
|
||||
|
||||
.. code-block:: none
|
||||
For V4L2 drivers:
|
||||
|
||||
struct foo_dev {
|
||||
...
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
...
|
||||
};
|
||||
|
||||
struct foo_dev *foo;
|
||||
|
||||
1.2) Initialize the handler:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
|
||||
|
||||
The second argument is a hint telling the function how many controls this
|
||||
handler is expected to handle. It will allocate a hashtable based on this
|
||||
information. It is a hint only.
|
||||
|
||||
1.3) Hook the control handler into the driver:
|
||||
|
||||
1.3.1) For V4L2 drivers do this:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct foo_dev {
|
||||
...
|
||||
|
@ -84,18 +68,9 @@ information. It is a hint only.
|
|||
...
|
||||
};
|
||||
|
||||
foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
|
||||
For sub-device drivers:
|
||||
|
||||
Where foo->v4l2_dev is of type struct v4l2_device.
|
||||
|
||||
Finally, remove all control functions from your v4l2_ioctl_ops (if any):
|
||||
vidioc_queryctrl, vidioc_query_ext_ctrl, vidioc_querymenu, vidioc_g_ctrl,
|
||||
vidioc_s_ctrl, vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls.
|
||||
Those are now no longer needed.
|
||||
|
||||
1.3.2) For sub-device drivers do this:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct foo_dev {
|
||||
...
|
||||
|
@ -105,39 +80,60 @@ Those are now no longer needed.
|
|||
...
|
||||
};
|
||||
|
||||
foo->sd.ctrl_handler = &foo->ctrl_handler;
|
||||
1.2) Initialize the handler:
|
||||
|
||||
Where foo->sd is of type struct v4l2_subdev.
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls);
|
||||
|
||||
The second argument is a hint telling the function how many controls this
|
||||
handler is expected to handle. It will allocate a hashtable based on this
|
||||
information. It is a hint only.
|
||||
|
||||
1.3) Hook the control handler into the driver:
|
||||
|
||||
For V4L2 drivers:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler;
|
||||
|
||||
For sub-device drivers:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
foo->sd.ctrl_handler = &foo->ctrl_handler;
|
||||
|
||||
1.4) Clean up the handler at the end:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_handler_free(&foo->ctrl_handler);
|
||||
|
||||
|
||||
2) Add controls:
|
||||
|
||||
You add non-menu controls by calling v4l2_ctrl_new_std:
|
||||
You add non-menu controls by calling :c:func:`v4l2_ctrl_new_std`:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 min, s32 max, u32 step, s32 def);
|
||||
|
||||
Menu and integer menu controls are added by calling v4l2_ctrl_new_std_menu:
|
||||
Menu and integer menu controls are added by calling
|
||||
:c:func:`v4l2_ctrl_new_std_menu`:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 max, s32 skip_mask, s32 def);
|
||||
|
||||
Menu controls with a driver specific menu are added by calling
|
||||
v4l2_ctrl_new_std_menu_items:
|
||||
:c:func:`v4l2_ctrl_new_std_menu_items`:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(
|
||||
struct v4l2_ctrl_handler *hdl,
|
||||
|
@ -145,17 +141,18 @@ v4l2_ctrl_new_std_menu_items:
|
|||
s32 skip_mask, s32 def, const char * const *qmenu);
|
||||
|
||||
Integer menu controls with a driver specific menu can be added by calling
|
||||
v4l2_ctrl_new_int_menu:
|
||||
:c:func:`v4l2_ctrl_new_int_menu`:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
|
||||
const struct v4l2_ctrl_ops *ops,
|
||||
u32 id, s32 max, s32 def, const s64 *qmenu_int);
|
||||
|
||||
These functions are typically called right after the v4l2_ctrl_handler_init:
|
||||
These functions are typically called right after the
|
||||
:c:func:`v4l2_ctrl_handler_init`:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static const s64 exp_bias_qmenu[] = {
|
||||
-2, -1, 0, 1, 2
|
||||
|
@ -192,33 +189,34 @@ These functions are typically called right after the v4l2_ctrl_handler_init:
|
|||
return err;
|
||||
}
|
||||
|
||||
The v4l2_ctrl_new_std function returns the v4l2_ctrl pointer to the new
|
||||
control, but if you do not need to access the pointer outside the control ops,
|
||||
then there is no need to store it.
|
||||
The :c:func:`v4l2_ctrl_new_std` function returns the v4l2_ctrl pointer to
|
||||
the new control, but if you do not need to access the pointer outside the
|
||||
control ops, then there is no need to store it.
|
||||
|
||||
The v4l2_ctrl_new_std function will fill in most fields based on the control
|
||||
ID except for the min, max, step and default values. These are passed in the
|
||||
last four arguments. These values are driver specific while control attributes
|
||||
like type, name, flags are all global. The control's current value will be set
|
||||
to the default value.
|
||||
The :c:func:`v4l2_ctrl_new_std` function will fill in most fields based on
|
||||
the control ID except for the min, max, step and default values. These are
|
||||
passed in the last four arguments. These values are driver specific while
|
||||
control attributes like type, name, flags are all global. The control's
|
||||
current value will be set to the default value.
|
||||
|
||||
The v4l2_ctrl_new_std_menu function is very similar but it is used for menu
|
||||
controls. There is no min argument since that is always 0 for menu controls,
|
||||
and instead of a step there is a skip_mask argument: if bit X is 1, then menu
|
||||
item X is skipped.
|
||||
The :c:func:`v4l2_ctrl_new_std_menu` function is very similar but it is
|
||||
used for menu controls. There is no min argument since that is always 0 for
|
||||
menu controls, and instead of a step there is a skip_mask argument: if bit
|
||||
X is 1, then menu item X is skipped.
|
||||
|
||||
The v4l2_ctrl_new_int_menu function creates a new standard integer menu
|
||||
control with driver-specific items in the menu. It differs from
|
||||
v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and takes
|
||||
as the last argument an array of signed 64-bit integers that form an exact
|
||||
menu item list.
|
||||
The :c:func:`v4l2_ctrl_new_int_menu` function creates a new standard
|
||||
integer menu control with driver-specific items in the menu. It differs
|
||||
from v4l2_ctrl_new_std_menu in that it doesn't have the mask argument and
|
||||
takes as the last argument an array of signed 64-bit integers that form an
|
||||
exact menu item list.
|
||||
|
||||
The v4l2_ctrl_new_std_menu_items function is very similar to
|
||||
v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the driver
|
||||
specific menu for an otherwise standard menu control. A good example for this
|
||||
control is the test pattern control for capture/display/sensors devices that
|
||||
have the capability to generate test patterns. These test patterns are hardware
|
||||
specific, so the contents of the menu will vary from device to device.
|
||||
The :c:func:`v4l2_ctrl_new_std_menu_items` function is very similar to
|
||||
v4l2_ctrl_new_std_menu but takes an extra parameter qmenu, which is the
|
||||
driver specific menu for an otherwise standard menu control. A good example
|
||||
for this control is the test pattern control for capture/display/sensors
|
||||
devices that have the capability to generate test patterns. These test
|
||||
patterns are hardware specific, so the contents of the menu will vary from
|
||||
device to device.
|
||||
|
||||
Note that if something fails, the function will return NULL or an error and
|
||||
set ctrl_handler->error to the error code. If ctrl_handler->error was already
|
||||
|
@ -233,7 +231,7 @@ a bit faster that way.
|
|||
|
||||
3) Optionally force initial control setup:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_handler_setup(&foo->ctrl_handler);
|
||||
|
||||
|
@ -242,9 +240,9 @@ initializes the hardware to the default control values. It is recommended
|
|||
that you do this as this ensures that both the internal data structures and
|
||||
the hardware are in sync.
|
||||
|
||||
4) Finally: implement the v4l2_ctrl_ops
|
||||
4) Finally: implement the :c:type:`v4l2_ctrl_ops`
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static const struct v4l2_ctrl_ops foo_ctrl_ops = {
|
||||
.s_ctrl = foo_s_ctrl,
|
||||
|
@ -252,7 +250,7 @@ the hardware are in sync.
|
|||
|
||||
Usually all you need is s_ctrl:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
|
@ -305,7 +303,7 @@ Accessing Control Values
|
|||
The following union is used inside the control framework to access control
|
||||
values:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
union v4l2_ctrl_ptr {
|
||||
s32 *p_s32;
|
||||
|
@ -317,7 +315,7 @@ values:
|
|||
The v4l2_ctrl struct contains these fields that can be used to access both
|
||||
current and new values:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
s32 val;
|
||||
struct {
|
||||
|
@ -330,7 +328,7 @@ current and new values:
|
|||
|
||||
If the control has a simple s32 type type, then:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
&ctrl->val == ctrl->p_new.p_s32
|
||||
&ctrl->cur.val == ctrl->p_cur.p_s32
|
||||
|
@ -354,7 +352,7 @@ exception is for controls that return a volatile register such as a signal
|
|||
strength read-out that changes continuously. In that case you will need to
|
||||
implement g_volatile_ctrl like this:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
|
@ -372,7 +370,7 @@ changes.
|
|||
|
||||
To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...);
|
||||
if (ctrl)
|
||||
|
@ -393,7 +391,7 @@ not to introduce deadlocks.
|
|||
Outside of the control ops you have to go through to helper functions to get
|
||||
or set a single control value safely in your driver:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
|
||||
int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
|
||||
|
@ -404,7 +402,7 @@ will result in a deadlock since these helpers lock the handler as well.
|
|||
|
||||
You can also take the handler lock yourself:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
mutex_lock(&state->ctrl_handler.lock);
|
||||
pr_info("String value is '%s'\n", ctrl1->p_cur.p_char);
|
||||
|
@ -417,7 +415,7 @@ Menu Controls
|
|||
|
||||
The v4l2_ctrl struct contains this union:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
union {
|
||||
u32 step;
|
||||
|
@ -445,7 +443,7 @@ Custom Controls
|
|||
|
||||
Driver specific controls can be created using v4l2_ctrl_new_custom():
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static const struct v4l2_ctrl_config ctrl_filter = {
|
||||
.ops = &ctrl_custom_ops,
|
||||
|
@ -499,7 +497,7 @@ By default all controls are independent from the others. But in more
|
|||
complex scenarios you can get dependencies from one control to another.
|
||||
In that case you need to 'cluster' them:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct foo {
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
@ -523,7 +521,7 @@ composite control. Similar to how a 'struct' works in C.
|
|||
So when s_ctrl is called with V4L2_CID_AUDIO_VOLUME as argument, you should set
|
||||
all two controls belonging to the audio_cluster:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static int foo_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
|
@ -545,7 +543,7 @@ all two controls belonging to the audio_cluster:
|
|||
|
||||
In the example above the following are equivalent for the VOLUME case:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME]
|
||||
ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE]
|
||||
|
@ -553,7 +551,7 @@ In the example above the following are equivalent for the VOLUME case:
|
|||
In practice using cluster arrays like this becomes very tiresome. So instead
|
||||
the following equivalent method is used:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct {
|
||||
/* audio cluster */
|
||||
|
@ -565,7 +563,7 @@ The anonymous struct is used to clearly 'cluster' these two control pointers,
|
|||
but it serves no other purpose. The effect is the same as creating an
|
||||
array with two control pointers. So you can just do:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
state->volume = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
|
||||
state->mute = v4l2_ctrl_new_std(&state->ctrl_handler, ...);
|
||||
|
@ -621,7 +619,7 @@ changing that control affects the control flags of the manual controls.
|
|||
In order to simplify this a special variation of v4l2_ctrl_cluster was
|
||||
introduced:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
|
||||
u8 manual_val, bool set_volatile);
|
||||
|
@ -676,7 +674,7 @@ of another handler (e.g. for a video device node), then you should first add
|
|||
the controls to the first handler, add the other controls to the second
|
||||
handler and finally add the first handler to the second. For example:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...);
|
||||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
|
@ -690,7 +688,7 @@ all controls.
|
|||
|
||||
Or you can add specific controls to a handler:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...);
|
||||
|
@ -699,7 +697,7 @@ Or you can add specific controls to a handler:
|
|||
What you should not do is make two identical controls for two handlers.
|
||||
For example:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...);
|
||||
|
@ -720,7 +718,7 @@ not own. For example, if you have to find a volume control from a subdev.
|
|||
|
||||
You can do that by calling v4l2_ctrl_find:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl *volume;
|
||||
|
||||
|
@ -729,7 +727,7 @@ You can do that by calling v4l2_ctrl_find:
|
|||
Since v4l2_ctrl_find will lock the handler you have to be careful where you
|
||||
use it. For example, this is not a good idea:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
||||
|
@ -738,7 +736,7 @@ use it. For example, this is not a good idea:
|
|||
|
||||
...and in video_ops.s_ctrl:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST);
|
||||
|
@ -760,7 +758,7 @@ not when it is used in consumer-level hardware. In that case you want to keep
|
|||
those low-level controls local to the subdev. You can do this by simply
|
||||
setting the 'is_private' flag of the control to 1:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
static const struct v4l2_ctrl_config ctrl_private = {
|
||||
.ops = &ctrl_custom_ops,
|
||||
|
@ -797,7 +795,7 @@ Sometimes the platform or bridge driver needs to be notified when a control
|
|||
from a sub-device driver changes. You can set a notify callback by calling
|
||||
this function:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: c
|
||||
|
||||
void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl,
|
||||
void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv);
|
||||
|
|
|
@ -39,7 +39,7 @@ Revision and Copyright
|
|||
**********************
|
||||
Authors:
|
||||
|
||||
- Verkuil, Hans <hans.verkuil@cisco.com>
|
||||
- Verkuil, Hans <hverkuil-cisco@xs4all.nl>
|
||||
|
||||
- Initial version.
|
||||
|
||||
|
|
|
@ -294,7 +294,8 @@ EINVAL
|
|||
The requested mode is invalid.
|
||||
|
||||
EPERM
|
||||
Monitor mode is requested without having root permissions
|
||||
Monitor mode is requested, but the process does have the ``CAP_NET_ADMIN``
|
||||
capability.
|
||||
|
||||
EBUSY
|
||||
Someone else is already an exclusive follower or initiator.
|
||||
|
|
|
@ -223,6 +223,18 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
|
|||
result of the :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>`, and once via
|
||||
:ref:`ioctl CEC_RECEIVE <CEC_RECEIVE>`.
|
||||
|
||||
* .. _`CEC-MSG-FL-RAW`:
|
||||
|
||||
- ``CEC_MSG_FL_RAW``
|
||||
- 2
|
||||
- Normally CEC messages are validated before transmitting them. If this
|
||||
flag is set when :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` is called,
|
||||
then no validation takes place and the message is transmitted as-is.
|
||||
This is useful when debugging CEC issues.
|
||||
This flag is only allowed if the process has the ``CAP_SYS_RAWIO``
|
||||
capability. If that is not set, then the ``EPERM`` error code is
|
||||
returned.
|
||||
|
||||
|
||||
.. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{11.0cm}|
|
||||
|
||||
|
@ -358,7 +370,8 @@ ENOTTY
|
|||
|
||||
EPERM
|
||||
The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
|
||||
has never been called.
|
||||
has never been called, or ``CEC_MSG_FL_RAW`` was used from a process that
|
||||
did not have the ``CAP_SYS_RAWIO`` capability.
|
||||
|
||||
ENONET
|
||||
The CEC adapter is not configured, i.e. :ref:`ioctl CEC_ADAP_S_LOG_ADDRS <CEC_ADAP_S_LOG_ADDRS>`
|
||||
|
|
|
@ -84,6 +84,11 @@ returned during the enumeration process.
|
|||
- Pointer to a links array allocated by the application. Ignored if
|
||||
NULL.
|
||||
|
||||
* - __u32
|
||||
- ``reserved[4]``
|
||||
- Reserved for future extensions. Drivers and applications must set
|
||||
the array to zero.
|
||||
|
||||
|
||||
.. c:type:: media_pad_desc
|
||||
|
||||
|
@ -135,7 +140,7 @@ returned during the enumeration process.
|
|||
- Link flags, see :ref:`media-link-flag` for more details.
|
||||
|
||||
* - __u32
|
||||
- ``reserved[4]``
|
||||
- ``reserved[2]``
|
||||
- Reserved for future extensions. Drivers and applications must set
|
||||
the array to zero.
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 3
|
||||
|
||||
- ``KEY_0``
|
||||
- ``KEY_NUMERIC_0``
|
||||
|
||||
- Keyboard digit 0
|
||||
|
||||
|
@ -62,7 +62,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 4
|
||||
|
||||
- ``KEY_1``
|
||||
- ``KEY_NUMERIC_1``
|
||||
|
||||
- Keyboard digit 1
|
||||
|
||||
|
@ -70,7 +70,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 5
|
||||
|
||||
- ``KEY_2``
|
||||
- ``KEY_NUMERIC_2``
|
||||
|
||||
- Keyboard digit 2
|
||||
|
||||
|
@ -78,7 +78,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 6
|
||||
|
||||
- ``KEY_3``
|
||||
- ``KEY_NUMERIC_3``
|
||||
|
||||
- Keyboard digit 3
|
||||
|
||||
|
@ -86,7 +86,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 7
|
||||
|
||||
- ``KEY_4``
|
||||
- ``KEY_NUMERIC_4``
|
||||
|
||||
- Keyboard digit 4
|
||||
|
||||
|
@ -94,7 +94,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 8
|
||||
|
||||
- ``KEY_5``
|
||||
- ``KEY_NUMERIC_5``
|
||||
|
||||
- Keyboard digit 5
|
||||
|
||||
|
@ -102,7 +102,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 9
|
||||
|
||||
- ``KEY_6``
|
||||
- ``KEY_NUMERIC_6``
|
||||
|
||||
- Keyboard digit 6
|
||||
|
||||
|
@ -110,7 +110,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 10
|
||||
|
||||
- ``KEY_7``
|
||||
- ``KEY_NUMERIC_7``
|
||||
|
||||
- Keyboard digit 7
|
||||
|
||||
|
@ -118,7 +118,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 11
|
||||
|
||||
- ``KEY_8``
|
||||
- ``KEY_NUMERIC_8``
|
||||
|
||||
- Keyboard digit 8
|
||||
|
||||
|
@ -126,7 +126,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- .. row 12
|
||||
|
||||
- ``KEY_9``
|
||||
- ``KEY_NUMERIC_9``
|
||||
|
||||
- Keyboard digit 9
|
||||
|
||||
|
@ -196,7 +196,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- ``KEY_PAUSE``
|
||||
|
||||
- Pause sroweam
|
||||
- Pause stream
|
||||
|
||||
- PAUSE / FREEZE
|
||||
|
||||
|
@ -220,7 +220,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- ``KEY_STOP``
|
||||
|
||||
- Stop sroweam
|
||||
- Stop stream
|
||||
|
||||
- STOP
|
||||
|
||||
|
@ -228,7 +228,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- ``KEY_RECORD``
|
||||
|
||||
- Start/stop recording sroweam
|
||||
- Start/stop recording stream
|
||||
|
||||
- CAPTURE / REC / RECORD/PAUSE
|
||||
|
||||
|
@ -577,7 +577,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- ``KEY_CLEAR``
|
||||
|
||||
- Stop sroweam and return to default input video/audio
|
||||
- Stop stream and return to default input video/audio
|
||||
|
||||
- CLEAR / RESET / BOSS KEY
|
||||
|
||||
|
@ -593,7 +593,7 @@ the remote via /dev/input/event devices.
|
|||
|
||||
- ``KEY_FAVORITES``
|
||||
|
||||
- Open the favorites sroweam window
|
||||
- Open the favorites stream window
|
||||
|
||||
- TV WALL / Favorites
|
||||
|
||||
|
|
|
@ -122,6 +122,15 @@ ITU BT.1119
|
|||
|
||||
:author: International Telecommunication Union (http://www.itu.ch)
|
||||
|
||||
.. _h264:
|
||||
|
||||
ITU-T Rec. H.264 Specification (04/2017 Edition)
|
||||
================================================
|
||||
|
||||
:title: ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
|
||||
|
||||
:author: International Telecommunication Union (http://www.itu.ch)
|
||||
|
||||
.. _jfif:
|
||||
|
||||
JFIF
|
||||
|
|
|
@ -759,6 +759,32 @@ enum v4l2_mpeg_video_h264_level -
|
|||
|
||||
|
||||
|
||||
.. _v4l2-mpeg-video-mpeg2-level:
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL``
|
||||
(enum)
|
||||
|
||||
enum v4l2_mpeg_video_mpeg2_level -
|
||||
The level information for the MPEG2 elementary stream. Applicable to
|
||||
MPEG2 codecs. Possible values are:
|
||||
|
||||
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW``
|
||||
- Low Level (LL)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN``
|
||||
- Main Level (ML)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440``
|
||||
- High-1440 Level (H-14)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH``
|
||||
- High Level (HL)
|
||||
|
||||
|
||||
|
||||
.. _v4l2-mpeg-video-mpeg4-level:
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL``
|
||||
|
@ -845,6 +871,36 @@ enum v4l2_mpeg_video_h264_profile -
|
|||
|
||||
|
||||
|
||||
.. _v4l2-mpeg-video-mpeg2-profile:
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE``
|
||||
(enum)
|
||||
|
||||
enum v4l2_mpeg_video_mpeg2_profile -
|
||||
The profile information for MPEG2. Applicable to MPEG2 codecs.
|
||||
Possible values are:
|
||||
|
||||
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE``
|
||||
- Simple profile (SP)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN``
|
||||
- Main profile (MP)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE``
|
||||
- SNR Scalable profile (SNR)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE``
|
||||
- Spatially Scalable profile (Spt)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH``
|
||||
- High profile (HP)
|
||||
* - ``V4L2_MPEG_VIDEO_MPEG2_PROFILE_MULTIVIEW``
|
||||
- Multi-view profile (MVP)
|
||||
|
||||
|
||||
|
||||
.. _v4l2-mpeg-video-mpeg4-profile:
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE``
|
||||
|
@ -1395,6 +1451,575 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
|
|||
- Layer number
|
||||
|
||||
|
||||
.. _v4l2-mpeg-h264:
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
|
||||
Specifies the sequence parameter set (as extracted from the
|
||||
bitstream) for the associated H264 slice data. This includes the
|
||||
necessary parameters for configuring a stateless hardware decoding
|
||||
pipeline for H264. The bitstream parameters are defined according
|
||||
to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
|
||||
Semantics". For further documentation, refer to the above
|
||||
specification, unless there is an explicit comment stating
|
||||
otherwise.
|
||||
|
||||
.. note::
|
||||
|
||||
This compound control is not yet part of the public kernel API and
|
||||
it is expected to change.
|
||||
|
||||
.. c:type:: v4l2_ctrl_h264_sps
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_ctrl_h264_sps
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u8
|
||||
- ``profile_idc``
|
||||
-
|
||||
* - __u8
|
||||
- ``constraint_set_flags``
|
||||
- See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
|
||||
* - __u8
|
||||
- ``level_idc``
|
||||
-
|
||||
* - __u8
|
||||
- ``seq_parameter_set_id``
|
||||
-
|
||||
* - __u8
|
||||
- ``chroma_format_idc``
|
||||
-
|
||||
* - __u8
|
||||
- ``bit_depth_luma_minus8``
|
||||
-
|
||||
* - __u8
|
||||
- ``bit_depth_chroma_minus8``
|
||||
-
|
||||
* - __u8
|
||||
- ``log2_max_frame_num_minus4``
|
||||
-
|
||||
* - __u8
|
||||
- ``pic_order_cnt_type``
|
||||
-
|
||||
* - __u8
|
||||
- ``log2_max_pic_order_cnt_lsb_minus4``
|
||||
-
|
||||
* - __u8
|
||||
- ``max_num_ref_frames``
|
||||
-
|
||||
* - __u8
|
||||
- ``num_ref_frames_in_pic_order_cnt_cycle``
|
||||
-
|
||||
* - __s32
|
||||
- ``offset_for_ref_frame[255]``
|
||||
-
|
||||
* - __s32
|
||||
- ``offset_for_non_ref_pic``
|
||||
-
|
||||
* - __s32
|
||||
- ``offset_for_top_to_bottom_field``
|
||||
-
|
||||
* - __u16
|
||||
- ``pic_width_in_mbs_minus1``
|
||||
-
|
||||
* - __u16
|
||||
- ``pic_height_in_map_units_minus1``
|
||||
-
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
|
||||
|
||||
.. _h264_sps_constraints_set_flags:
|
||||
|
||||
``Sequence Parameter Set Constraints Set Flags``
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
|
||||
- 0x00000001
|
||||
-
|
||||
* - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
|
||||
- 0x00000002
|
||||
-
|
||||
* - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
|
||||
- 0x00000004
|
||||
-
|
||||
* - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
|
||||
- 0x00000008
|
||||
-
|
||||
* - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
|
||||
- 0x00000010
|
||||
-
|
||||
* - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
|
||||
- 0x00000020
|
||||
-
|
||||
|
||||
.. _h264_sps_flags:
|
||||
|
||||
``Sequence Parameter Set Flags``
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
|
||||
- 0x00000001
|
||||
-
|
||||
* - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
|
||||
- 0x00000002
|
||||
-
|
||||
* - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
|
||||
- 0x00000004
|
||||
-
|
||||
* - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
|
||||
- 0x00000008
|
||||
-
|
||||
* - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
|
||||
- 0x00000010
|
||||
-
|
||||
* - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
|
||||
- 0x00000020
|
||||
-
|
||||
* - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
|
||||
- 0x00000040
|
||||
-
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
|
||||
Specifies the picture parameter set (as extracted from the
|
||||
bitstream) for the associated H264 slice data. This includes the
|
||||
necessary parameters for configuring a stateless hardware decoding
|
||||
pipeline for H264. The bitstream parameters are defined according
|
||||
to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
|
||||
Semantics". For further documentation, refer to the above
|
||||
specification, unless there is an explicit comment stating
|
||||
otherwise.
|
||||
|
||||
.. note::
|
||||
|
||||
This compound control is not yet part of the public kernel API and
|
||||
it is expected to change.
|
||||
|
||||
.. c:type:: v4l2_ctrl_h264_pps
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_ctrl_h264_pps
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u8
|
||||
- ``pic_parameter_set_id``
|
||||
-
|
||||
* - __u8
|
||||
- ``seq_parameter_set_id``
|
||||
-
|
||||
* - __u8
|
||||
- ``num_slice_groups_minus1``
|
||||
-
|
||||
* - __u8
|
||||
- ``num_ref_idx_l0_default_active_minus1``
|
||||
-
|
||||
* - __u8
|
||||
- ``num_ref_idx_l1_default_active_minus1``
|
||||
-
|
||||
* - __u8
|
||||
- ``weighted_bipred_idc``
|
||||
-
|
||||
* - __s8
|
||||
- ``pic_init_qp_minus26``
|
||||
-
|
||||
* - __s8
|
||||
- ``pic_init_qs_minus26``
|
||||
-
|
||||
* - __s8
|
||||
- ``chroma_qp_index_offset``
|
||||
-
|
||||
* - __s8
|
||||
- ``second_chroma_qp_index_offset``
|
||||
-
|
||||
* - __u16
|
||||
- ``flags``
|
||||
- See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
|
||||
|
||||
.. _h264_pps_flags:
|
||||
|
||||
``Picture Parameter Set Flags``
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
|
||||
- 0x00000001
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
|
||||
- 0x00000002
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
|
||||
- 0x00000004
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
|
||||
- 0x00000008
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
|
||||
- 0x00000010
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
|
||||
- 0x00000020
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
|
||||
- 0x00000040
|
||||
-
|
||||
* - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
|
||||
- 0x00000080
|
||||
-
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
|
||||
Specifies the scaling matrix (as extracted from the bitstream) for
|
||||
the associated H264 slice data. The bitstream parameters are
|
||||
defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
|
||||
List Semantics". For further documentation, refer to the above
|
||||
specification, unless there is an explicit comment stating
|
||||
otherwise.
|
||||
|
||||
.. note::
|
||||
|
||||
This compound control is not yet part of the public kernel API and
|
||||
it is expected to change.
|
||||
|
||||
.. c:type:: v4l2_ctrl_h264_scaling_matrix
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u8
|
||||
- ``scaling_list_4x4[6][16]``
|
||||
-
|
||||
* - __u8
|
||||
- ``scaling_list_8x8[6][64]``
|
||||
-
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
|
||||
Specifies the slice parameters (as extracted from the bitstream)
|
||||
for the associated H264 slice data. This includes the necessary
|
||||
parameters for configuring a stateless hardware decoding pipeline
|
||||
for H264. The bitstream parameters are defined according to
|
||||
:ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
|
||||
documentation, refer to the above specification, unless there is
|
||||
an explicit comment stating otherwise.
|
||||
|
||||
.. note::
|
||||
|
||||
This compound control is not yet part of the public kernel API
|
||||
and it is expected to change.
|
||||
|
||||
This structure is expected to be passed as an array, with one
|
||||
entry for each slice included in the bitstream buffer.
|
||||
|
||||
.. c:type:: v4l2_ctrl_h264_slice_params
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_ctrl_h264_slice_params
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u32
|
||||
- ``size``
|
||||
-
|
||||
* - __u32
|
||||
- ``header_bit_size``
|
||||
-
|
||||
* - __u16
|
||||
- ``first_mb_in_slice``
|
||||
-
|
||||
* - __u8
|
||||
- ``slice_type``
|
||||
-
|
||||
* - __u8
|
||||
- ``pic_parameter_set_id``
|
||||
-
|
||||
* - __u8
|
||||
- ``colour_plane_id``
|
||||
-
|
||||
* - __u8
|
||||
- ``redundant_pic_cnt``
|
||||
-
|
||||
* - __u16
|
||||
- ``frame_num``
|
||||
-
|
||||
* - __u16
|
||||
- ``idr_pic_id``
|
||||
-
|
||||
* - __u16
|
||||
- ``pic_order_cnt_lsb``
|
||||
-
|
||||
* - __s32
|
||||
- ``delta_pic_order_cnt_bottom``
|
||||
-
|
||||
* - __s32
|
||||
- ``delta_pic_order_cnt0``
|
||||
-
|
||||
* - __s32
|
||||
- ``delta_pic_order_cnt1``
|
||||
-
|
||||
* - struct :c:type:`v4l2_h264_pred_weight_table`
|
||||
- ``pred_weight_table``
|
||||
-
|
||||
* - __u32
|
||||
- ``dec_ref_pic_marking_bit_size``
|
||||
-
|
||||
* - __u32
|
||||
- ``pic_order_cnt_bit_size``
|
||||
-
|
||||
* - __u8
|
||||
- ``cabac_init_idc``
|
||||
-
|
||||
* - __s8
|
||||
- ``slice_qp_delta``
|
||||
-
|
||||
* - __s8
|
||||
- ``slice_qs_delta``
|
||||
-
|
||||
* - __u8
|
||||
- ``disable_deblocking_filter_idc``
|
||||
-
|
||||
* - __s8
|
||||
- ``slice_alpha_c0_offset_div2``
|
||||
-
|
||||
* - __s8
|
||||
- ``slice_beta_offset_div2``
|
||||
-
|
||||
* - __u8
|
||||
- ``num_ref_idx_l0_active_minus1``
|
||||
-
|
||||
* - __u8
|
||||
- ``num_ref_idx_l1_active_minus1``
|
||||
-
|
||||
* - __u32
|
||||
- ``slice_group_change_cycle``
|
||||
-
|
||||
* - __u8
|
||||
- ``ref_pic_list0[32]``
|
||||
- Reference picture list after applying the per-slice modifications
|
||||
* - __u8
|
||||
- ``ref_pic_list1[32]``
|
||||
- Reference picture list after applying the per-slice modifications
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- See :ref:`Slice Parameter Flags <h264_slice_flags>`
|
||||
|
||||
.. _h264_slice_flags:
|
||||
|
||||
``Slice Parameter Set Flags``
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
|
||||
- 0x00000001
|
||||
-
|
||||
* - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
|
||||
- 0x00000002
|
||||
-
|
||||
* - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
|
||||
- 0x00000004
|
||||
-
|
||||
* - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
|
||||
- 0x00000008
|
||||
-
|
||||
|
||||
``Prediction Weight Table``
|
||||
|
||||
The bitstream parameters are defined according to :ref:`h264`,
|
||||
section 7.4.3.2 "Prediction Weight Table Semantics". For further
|
||||
documentation, refer to the above specification, unless there is
|
||||
an explicit comment stating otherwise.
|
||||
|
||||
.. c:type:: v4l2_h264_pred_weight_table
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_h264_pred_weight_table
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u16
|
||||
- ``luma_log2_weight_denom``
|
||||
-
|
||||
* - __u16
|
||||
- ``chroma_log2_weight_denom``
|
||||
-
|
||||
* - struct :c:type:`v4l2_h264_weight_factors`
|
||||
- ``weight_factors[2]``
|
||||
- The weight factors at index 0 are the weight factors for the reference
|
||||
list 0, the one at index 1 for the reference list 1.
|
||||
|
||||
.. c:type:: v4l2_h264_weight_factors
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_h264_weight_factors
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __s16
|
||||
- ``luma_weight[32]``
|
||||
-
|
||||
* - __s16
|
||||
- ``luma_offset[32]``
|
||||
-
|
||||
* - __s16
|
||||
- ``chroma_weight[32][2]``
|
||||
-
|
||||
* - __s16
|
||||
- ``chroma_offset[32][2]``
|
||||
-
|
||||
|
||||
``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
|
||||
Specifies the decode parameters (as extracted from the bitstream)
|
||||
for the associated H264 slice data. This includes the necessary
|
||||
parameters for configuring a stateless hardware decoding pipeline
|
||||
for H264. The bitstream parameters are defined according to
|
||||
:ref:`h264`. For further documentation, refer to the above
|
||||
specification, unless there is an explicit comment stating
|
||||
otherwise.
|
||||
|
||||
.. note::
|
||||
|
||||
This compound control is not yet part of the public kernel API and
|
||||
it is expected to change.
|
||||
|
||||
.. c:type:: v4l2_ctrl_h264_decode_params
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_ctrl_h264_decode_params
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - struct :c:type:`v4l2_h264_dpb_entry`
|
||||
- ``dpb[16]``
|
||||
-
|
||||
* - __u16
|
||||
- ``num_slices``
|
||||
- Number of slices needed to decode the current frame
|
||||
* - __u16
|
||||
- ``nal_ref_idc``
|
||||
- NAL reference ID value coming from the NAL Unit header
|
||||
* - __u8
|
||||
- ``ref_pic_list_p0[32]``
|
||||
- Backward reference list used by P-frames in the original bitstream order
|
||||
* - __u8
|
||||
- ``ref_pic_list_b0[32]``
|
||||
- Backward reference list used by B-frames in the original bitstream order
|
||||
* - __u8
|
||||
- ``ref_pic_list_b1[32]``
|
||||
- Forward reference list used by B-frames in the original bitstream order
|
||||
* - __s32
|
||||
- ``top_field_order_cnt``
|
||||
- Picture Order Count for the coded top field
|
||||
* - __s32
|
||||
- ``bottom_field_order_cnt``
|
||||
- Picture Order Count for the coded bottom field
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
|
||||
|
||||
.. _h264_decode_params_flags:
|
||||
|
||||
``Decode Parameters Flags``
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
|
||||
- 0x00000001
|
||||
- That picture is an IDR picture
|
||||
|
||||
.. c:type:: v4l2_h264_dpb_entry
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table:: struct v4l2_h264_dpb_entry
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u64
|
||||
- ``reference_ts``
|
||||
- Timestamp of the V4L2 capture buffer to use as reference, used
|
||||
with B-coded and P-coded frames. The timestamp refers to the
|
||||
``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
|
||||
:c:func:`v4l2_timeval_to_ns()` function to convert the struct
|
||||
:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
|
||||
* - __u16
|
||||
- ``frame_num``
|
||||
-
|
||||
* - __u16
|
||||
- ``pic_num``
|
||||
-
|
||||
* - __s32
|
||||
- ``top_field_order_cnt``
|
||||
-
|
||||
* - __s32
|
||||
- ``bottom_field_order_cnt``
|
||||
-
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- See :ref:`DPB Entry Flags <h264_dpb_flags>`
|
||||
|
||||
.. _h264_dpb_flags:
|
||||
|
||||
``DPB Entries Flags``
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
|
||||
- 0x00000001
|
||||
- The DPB entry is valid and should be considered
|
||||
* - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
|
||||
- 0x00000002
|
||||
- The DPB entry is currently being used as a reference frame
|
||||
* - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
|
||||
- 0x00000004
|
||||
- The DPB entry is a long term reference frame
|
||||
|
||||
.. _v4l2-mpeg-mpeg2:
|
||||
|
||||
|
|
|
@ -85,20 +85,17 @@ be able to see such compound controls. In other words, these controls
|
|||
with compound types should only be used programmatically.
|
||||
|
||||
Since such compound controls need to expose more information about
|
||||
themselves than is possible with
|
||||
:ref:`VIDIOC_QUERYCTRL` the
|
||||
:ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
|
||||
particular, this ioctl gives the dimensions of the N-dimensional array
|
||||
if this control consists of more than one element.
|
||||
themselves than is possible with :ref:`VIDIOC_QUERYCTRL <VIDIOC_QUERYCTRL>`
|
||||
the :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
|
||||
particular, this ioctl gives the dimensions of the N-dimensional array if
|
||||
this control consists of more than one element.
|
||||
|
||||
.. note::
|
||||
|
||||
#. It is important to realize that due to the flexibility of controls it is
|
||||
necessary to check whether the control you want to set actually is
|
||||
supported in the driver and what the valid range of values is. So use
|
||||
the :ref:`VIDIOC_QUERYCTRL` (or :ref:`VIDIOC_QUERY_EXT_CTRL
|
||||
<VIDIOC_QUERYCTRL>`) and :ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>`
|
||||
ioctls to check this.
|
||||
:ref:`VIDIOC_QUERYCTRL` to check this.
|
||||
|
||||
#. It is possible that some of the menu indices in a control of
|
||||
type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU``
|
||||
|
@ -144,7 +141,7 @@ control class is found:
|
|||
while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) {
|
||||
if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG)
|
||||
break;
|
||||
/* ... */
|
||||
/* ... */
|
||||
qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ determined by the video standard. Hence the distinction between temporal
|
|||
and spatial order of fields. The diagrams below should make this
|
||||
clearer.
|
||||
|
||||
In V4L it is assumed that all video cameras transmit fields on the media
|
||||
bus in the same order they were captured, so if the top field was
|
||||
captured first (is the older field), the top field is also transmitted
|
||||
first on the bus.
|
||||
|
||||
All video capture and output devices must report the current field
|
||||
order. Some drivers may permit the selection of a different order, to
|
||||
this end applications initialize the ``field`` field of struct
|
||||
|
@ -101,10 +106,10 @@ enum v4l2_field
|
|||
* - ``V4L2_FIELD_INTERLACED``
|
||||
- 4
|
||||
- Images contain both fields, interleaved line by line. The temporal
|
||||
order of the fields (whether the top or bottom field is first
|
||||
transmitted) depends on the current video standard. M/NTSC
|
||||
transmits the bottom field first, all other standards the top
|
||||
field first.
|
||||
order of the fields (whether the top or bottom field is older)
|
||||
depends on the current video standard. In M/NTSC the bottom
|
||||
field is the older field. In all other standards the top field
|
||||
is the older field.
|
||||
* - ``V4L2_FIELD_SEQ_TB``
|
||||
- 5
|
||||
- Images contain both fields, the top field lines are stored first
|
||||
|
@ -135,11 +140,11 @@ enum v4l2_field
|
|||
* - ``V4L2_FIELD_INTERLACED_TB``
|
||||
- 8
|
||||
- Images contain both fields, interleaved line by line, top field
|
||||
first. The top field is transmitted first.
|
||||
first. The top field is the older field.
|
||||
* - ``V4L2_FIELD_INTERLACED_BT``
|
||||
- 9
|
||||
- Images contain both fields, interleaved line by line, top field
|
||||
first. The bottom field is transmitted first.
|
||||
first. The bottom field is the older field.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,31 @@ Compressed Formats
|
|||
- ``V4L2_PIX_FMT_H264_MVC``
|
||||
- 'M264'
|
||||
- H264 MVC video elementary stream.
|
||||
* .. _V4L2-PIX-FMT-H264-SLICE-RAW:
|
||||
|
||||
- ``V4L2_PIX_FMT_H264_SLICE_RAW``
|
||||
- 'S264'
|
||||
- H264 parsed slice data, without the start code and as
|
||||
extracted from the H264 bitstream. This format is adapted for
|
||||
stateless video decoders that implement an H264 pipeline
|
||||
(using the :ref:`mem2mem` and :ref:`media-request-api`).
|
||||
Metadata associated with the frame to decode are required to
|
||||
be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
|
||||
``V4L2_CID_MPEG_VIDEO_H264_PPS``,
|
||||
``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
|
||||
``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
|
||||
``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls. See the
|
||||
:ref:`associated Codec Control IDs <v4l2-mpeg-h264>`. Exactly
|
||||
one output and one capture buffer must be provided for use
|
||||
with this pixel format. The output buffer must contain the
|
||||
appropriate number of macroblocks to decode a full
|
||||
corresponding frame to the matching capture buffer.
|
||||
|
||||
.. note::
|
||||
|
||||
This format is not yet part of the public kernel API and it
|
||||
is expected to change.
|
||||
|
||||
* .. _V4L2-PIX-FMT-H263:
|
||||
|
||||
- ``V4L2_PIX_FMT_H263``
|
||||
|
|
|
@ -31,7 +31,20 @@ describing all planes of that format.
|
|||
|
||||
* - __u32
|
||||
- ``sizeimage``
|
||||
- Maximum size in bytes required for image data in this plane.
|
||||
- Maximum size in bytes required for image data in this plane,
|
||||
set by the driver. When the image consists of variable length
|
||||
compressed data this is the number of bytes required by the
|
||||
codec to support the worst-case compression scenario.
|
||||
|
||||
The driver will set the value for uncompressed images.
|
||||
|
||||
Clients are allowed to set the sizeimage field for variable length
|
||||
compressed data flagged with ``V4L2_FMT_FLAG_COMPRESSED`` at
|
||||
:ref:`VIDIOC_ENUM_FMT`, but the driver may ignore it and set the
|
||||
value itself, or it may modify the provided value based on
|
||||
alignment requirements or minimum/maximum size requirements.
|
||||
If the client wants to leave this to the driver, then it should
|
||||
set sizeimage to 0.
|
||||
* - __u32
|
||||
- ``bytesperline``
|
||||
- Distance in bytes between the leftmost pixels in two adjacent
|
||||
|
|
|
@ -89,7 +89,18 @@ Single-planar format structure
|
|||
- Size in bytes of the buffer to hold a complete image, set by the
|
||||
driver. Usually this is ``bytesperline`` times ``height``. When
|
||||
the image consists of variable length compressed data this is the
|
||||
maximum number of bytes required to hold an image.
|
||||
number of bytes required by the codec to support the worst-case
|
||||
compression scenario.
|
||||
|
||||
The driver will set the value for uncompressed images.
|
||||
|
||||
Clients are allowed to set the sizeimage field for variable length
|
||||
compressed data flagged with ``V4L2_FMT_FLAG_COMPRESSED`` at
|
||||
:ref:`VIDIOC_ENUM_FMT`, but the driver may ignore it and set the
|
||||
value itself, or it may modify the provided value based on
|
||||
alignment requirements or minimum/maximum size requirements.
|
||||
If the client wants to leave this to the driver, then it should
|
||||
set sizeimage to 0.
|
||||
* - __u32
|
||||
- ``colorspace``
|
||||
- Image colorspace, from enum :c:type:`v4l2_colorspace`.
|
||||
|
|
|
@ -139,6 +139,14 @@ may continue as normal, but should be aware that data in the dequeued
|
|||
buffer might be corrupted. When using the multi-planar API, the planes
|
||||
array must be passed in as well.
|
||||
|
||||
If the application sets the ``memory`` field to ``V4L2_MEMORY_DMABUF`` to
|
||||
dequeue a :ref:`DMABUF <dmabuf>` buffer, the driver fills the ``m.fd`` field
|
||||
with a file descriptor numerically the same as the one given to ``VIDIOC_QBUF``
|
||||
when the buffer was enqueued. No new file descriptor is created at dequeue time
|
||||
and the value is only for the application convenience. When the multi-planar
|
||||
API is used the ``m.fd`` fields of the passed array of struct
|
||||
:c:type:`v4l2_plane` are filled instead.
|
||||
|
||||
By default ``VIDIOC_DQBUF`` blocks when no buffer is in the outgoing
|
||||
queue. When the ``O_NONBLOCK`` flag was given to the
|
||||
:ref:`open() <func-open>` function, ``VIDIOC_DQBUF`` returns
|
||||
|
|
|
@ -443,6 +443,36 @@ See also the examples in :ref:`control`.
|
|||
- n/a
|
||||
- A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
|
||||
quantization matrices for stateless video decoders.
|
||||
* - ``V4L2_CTRL_TYPE_H264_SPS``
|
||||
- n/a
|
||||
- n/a
|
||||
- n/a
|
||||
- A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
|
||||
sequence parameters for stateless video decoders.
|
||||
* - ``V4L2_CTRL_TYPE_H264_PPS``
|
||||
- n/a
|
||||
- n/a
|
||||
- n/a
|
||||
- A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
|
||||
picture parameters for stateless video decoders.
|
||||
* - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
|
||||
- n/a
|
||||
- n/a
|
||||
- n/a
|
||||
- A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
|
||||
scaling matrices for stateless video decoders.
|
||||
* - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
|
||||
- n/a
|
||||
- n/a
|
||||
- n/a
|
||||
- A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
|
||||
slice parameters for stateless video decoders.
|
||||
* - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
|
||||
- n/a
|
||||
- n/a
|
||||
- n/a
|
||||
- A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
|
||||
decode parameters for stateless video decoders.
|
||||
|
||||
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
|
||||
|
||||
|
|
|
@ -64,5 +64,6 @@ For more details see the file COPYING in the source distribution of Linux.
|
|||
si476x
|
||||
soc-camera
|
||||
uvcvideo
|
||||
vimc
|
||||
vivid
|
||||
zr364xx
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
digraph board {
|
||||
rankdir=TB
|
||||
n00000001 [label="{{} | Sensor A\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000001:port0 -> n00000005:port0 [style=bold]
|
||||
n00000001:port0 -> n0000000b [style=bold]
|
||||
n00000003 [label="{{} | Sensor B\n/dev/v4l-subdev1 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000003:port0 -> n00000008:port0 [style=bold]
|
||||
n00000003:port0 -> n0000000f [style=bold]
|
||||
n00000005 [label="{{<port0> 0} | Debayer A\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000005:port1 -> n00000017:port0
|
||||
n00000008 [label="{{<port0> 0} | Debayer B\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000008:port1 -> n00000017:port0 [style=dashed]
|
||||
n0000000b [label="Raw Capture 0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
|
||||
n0000000f [label="Raw Capture 1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
|
||||
n00000013 [label="RGB/YUV Input\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
|
||||
n00000013 -> n00000017:port0 [style=dashed]
|
||||
n00000017 [label="{{<port0> 0} | Scaler\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000017:port1 -> n0000001a [style=bold]
|
||||
n0000001a [label="RGB/YUV Capture\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
The Virtual Media Controller Driver (vimc)
|
||||
==========================================
|
||||
|
||||
The vimc driver emulates complex video hardware using the V4L2 API and the Media
|
||||
API. It has a capture device and three subdevices: sensor, debayer and scaler.
|
||||
|
||||
Topology
|
||||
--------
|
||||
|
||||
The topology is hardcoded, although you could modify it in vimc-core and
|
||||
recompile the driver to achieve your own topology. This is the default topology:
|
||||
|
||||
.. _vimc_topology_graph:
|
||||
|
||||
.. kernel-figure:: vimc.dot
|
||||
:alt: vimc.dot
|
||||
:align: center
|
||||
|
||||
Media pipeline graph on vimc
|
||||
|
||||
Configuring the topology
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each subdevice will come with its default configuration (pixelformat, height,
|
||||
width, ...). One needs to configure the topology in order to match the
|
||||
configuration on each linked subdevice to stream frames through the pipeline.
|
||||
If the configuration doesn't match, the stream will fail. The ``v4l-utils``
|
||||
package is a bundle of user-space applications, that comes with ``media-ctl`` and
|
||||
``v4l2-ctl`` that can be used to configure the vimc configuration. This sequence
|
||||
of commands fits for the default topology:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
media-ctl -d platform:vimc -V '"Sensor A":0[fmt:SBGGR8_1X8/640x480]'
|
||||
media-ctl -d platform:vimc -V '"Debayer A":0[fmt:SBGGR8_1X8/640x480]'
|
||||
media-ctl -d platform:vimc -V '"Sensor B":0[fmt:SBGGR8_1X8/640x480]'
|
||||
media-ctl -d platform:vimc -V '"Debayer B":0[fmt:SBGGR8_1X8/640x480]'
|
||||
v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
|
||||
v4l2-ctl -z platform:vimc -d "Raw Capture 0" -v pixelformat=BA81
|
||||
v4l2-ctl -z platform:vimc -d "Raw Capture 1" -v pixelformat=BA81
|
||||
|
||||
Subdevices
|
||||
----------
|
||||
|
||||
Subdevices define the behavior of an entity in the topology. Depending on the
|
||||
subdevice, the entity can have multiple pads of type source or sink.
|
||||
|
||||
vimc-sensor:
|
||||
Generates images in several formats using video test pattern generator.
|
||||
Exposes:
|
||||
|
||||
* 1 Pad source
|
||||
|
||||
vimc-debayer:
|
||||
Transforms images in bayer format into a non-bayer format.
|
||||
Exposes:
|
||||
|
||||
* 1 Pad sink
|
||||
* 1 Pad source
|
||||
|
||||
vimc-scaler:
|
||||
Scale up the image by a factor of 3. E.g.: a 640x480 image becomes a
|
||||
1920x1440 image. (this value can be configured, see at
|
||||
`Module options`_).
|
||||
Exposes:
|
||||
|
||||
* 1 Pad sink
|
||||
* 1 Pad source
|
||||
|
||||
vimc-capture:
|
||||
Exposes node /dev/videoX to allow userspace to capture the stream.
|
||||
Exposes:
|
||||
|
||||
* 1 Pad sink
|
||||
* 1 Pad source
|
||||
|
||||
Module options
|
||||
---------------
|
||||
|
||||
Vimc has a few module parameters to configure the driver. You should pass
|
||||
those arguments to each subdevice, not to the vimc module. For example::
|
||||
|
||||
vimc_subdevice.param=value
|
||||
|
||||
* ``vimc_scaler.sca_mult=<unsigned int>``
|
||||
|
||||
Image size multiplier factor to be used to multiply both width and
|
||||
height, so the image size will be ``sca_mult^2`` bigger than the
|
||||
original one. Currently, only supports scaling up (the default value
|
||||
is 3).
|
||||
|
||||
* ``vimc_debayer.deb_mean_win_size=<unsigned int>``
|
||||
|
||||
Window size to calculate the mean. Note: the window size needs to be an
|
||||
odd number, as the main pixel stays in the center of the window,
|
||||
otherwise the next odd number is considered (the default value is 3).
|
|
@ -941,6 +941,11 @@ Digital Video Controls
|
|||
affects the reported colorspace since DVI_D outputs will always use
|
||||
sRGB.
|
||||
|
||||
- Display Present:
|
||||
|
||||
sets the presence of a "display" on the HDMI output. This affects
|
||||
the tx_edid_present, tx_hotplug and tx_rxsense controls.
|
||||
|
||||
|
||||
FM Radio Receiver Controls
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -136,6 +136,11 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
|
|||
replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
|
||||
replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
|
||||
|
||||
# V4L2 capability defines
|
||||
replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
|
||||
|
|
57
MAINTAINERS
57
MAINTAINERS
|
@ -668,6 +668,13 @@ S: Maintained
|
|||
F: Documentation/i2c/busses/i2c-ali1563
|
||||
F: drivers/i2c/busses/i2c-ali1563.c
|
||||
|
||||
ALLEGRO DVT VIDEO IP CORE DRIVER
|
||||
M: Michael Tretter <m.tretter@pengutronix.de>
|
||||
R: Pengutronix Kernel Team <kernel@pengutronix.de>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/staging/media/allegro-dvt/
|
||||
|
||||
ALLWINNER SECURITY SYSTEM
|
||||
M: Corentin Labbe <clabbe.montjoie@gmail.com>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
|
@ -910,7 +917,7 @@ F: drivers/iio/adc/ad7768-1.c
|
|||
F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt
|
||||
|
||||
ANALOG DEVICES INC AD9389B DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/ad9389b*
|
||||
|
@ -942,19 +949,19 @@ S: Maintained
|
|||
F: drivers/media/i2c/adv748x/*
|
||||
|
||||
ANALOG DEVICES INC ADV7511 DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/adv7511*
|
||||
|
||||
ANALOG DEVICES INC ADV7604 DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/adv7604*
|
||||
|
||||
ANALOG DEVICES INC ADV7842 DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/adv7842*
|
||||
|
@ -2350,7 +2357,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
|||
S: Maintained
|
||||
|
||||
ARM/TEGRA HDMI CEC SUBSYSTEM SUPPORT
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-tegra@vger.kernel.org
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -3685,7 +3692,7 @@ F: drivers/crypto/ccree/
|
|||
W: https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family
|
||||
|
||||
CEC FRAMEWORK
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
W: http://linuxtv.org
|
||||
|
@ -3702,7 +3709,7 @@ F: Documentation/devicetree/bindings/media/cec.txt
|
|||
F: Documentation/ABI/testing/debugfs-cec-error-inj
|
||||
|
||||
CEC GPIO DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
W: http://linuxtv.org
|
||||
|
@ -3986,7 +3993,7 @@ S: Supported
|
|||
F: drivers/platform/x86/classmate-laptop.c
|
||||
|
||||
COBALT MEDIA DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
W: https://linuxtv.org
|
||||
|
@ -6748,7 +6755,7 @@ F: drivers/gnss/
|
|||
F: include/linux/gnss.h
|
||||
|
||||
GO7007 MPEG CODEC
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/usb/go7007/
|
||||
|
@ -9681,6 +9688,17 @@ L: linux-iio@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/iio/dac/cio-dac.c
|
||||
|
||||
MEDIA CONTROLLER FRAMEWORK
|
||||
M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
W: https://www.linuxtv.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Supported
|
||||
F: drivers/media/mc/
|
||||
F: include/media/media-*.h
|
||||
F: include/uapi/linux/media.h
|
||||
|
||||
MEDIA DRIVERS FOR ASCOT2E
|
||||
M: Sergey Kozlov <serjk@netup.ru>
|
||||
M: Abylay Ospan <aospan@netup.ru>
|
||||
|
@ -10257,7 +10275,7 @@ F: drivers/watchdog/menz69_wdt.c
|
|||
|
||||
MESON AO CEC DRIVER FOR AMLOGIC SOCS
|
||||
M: Neil Armstrong <narmstrong@baylibre.com>
|
||||
L: linux-media@lists.freedesktop.org
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-amlogic@lists.infradead.org
|
||||
W: http://linux-meson.com/
|
||||
S: Supported
|
||||
|
@ -10273,6 +10291,14 @@ S: Maintained
|
|||
F: drivers/mtd/nand/raw/meson_*
|
||||
F: Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
|
||||
|
||||
MESON VIDEO DECODER DRIVER FOR AMLOGIC SOCS
|
||||
M: Maxime Jourdan <mjourdan@baylibre.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-amlogic@lists.infradead.org
|
||||
S: Supported
|
||||
F: drivers/staging/media/meson/vdec/
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
||||
METHODE UDPU SUPPORT
|
||||
M: Vladimir Vid <vladimir.vid@sartura.hr>
|
||||
S: Maintained
|
||||
|
@ -10326,7 +10352,9 @@ MICROCHIP ISC DRIVER
|
|||
M: Eugen Hristev <eugen.hristev@microchip.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/media/platform/atmel/atmel-isc.c
|
||||
F: drivers/media/platform/atmel/atmel-sama5d2-isc.c
|
||||
F: drivers/media/platform/atmel/atmel-isc.h
|
||||
F: drivers/media/platform/atmel/atmel-isc-base.c
|
||||
F: drivers/media/platform/atmel/atmel-isc-regs.h
|
||||
F: Documentation/devicetree/bindings/media/atmel-isc.txt
|
||||
|
||||
|
@ -13542,11 +13570,11 @@ S: Maintained
|
|||
F: drivers/media/platform/rockchip/rga/
|
||||
F: Documentation/devicetree/bindings/media/rockchip-rga.txt
|
||||
|
||||
ROCKCHIP VPU CODEC DRIVER
|
||||
HANTRO VPU CODEC DRIVER
|
||||
M: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/staging/media/platform/rockchip/vpu/
|
||||
F: drivers/staging/media/platform/hantro/
|
||||
F: Documentation/devicetree/bindings/media/rockchip-vpu.txt
|
||||
|
||||
ROCKER DRIVER
|
||||
|
@ -16746,7 +16774,7 @@ S: Maintained
|
|||
F: drivers/net/ethernet/via/via-velocity.*
|
||||
|
||||
VICODEC VIRTUAL CODEC DRIVER
|
||||
M: Hans Verkuil <hans.verkuil@cisco.com>
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
W: https://linuxtv.org
|
||||
|
@ -16769,6 +16797,7 @@ VIDEOBUF2 FRAMEWORK
|
|||
M: Pawel Osciak <pawel@osciak.com>
|
||||
M: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
R: Tomasz Figa <tfiga@chromium.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/common/videobuf2/*
|
||||
|
|
|
@ -929,10 +929,6 @@ static int sur40_vidioc_querycap(struct file *file, void *priv,
|
|||
strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
|
||||
strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
|
||||
usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
|
||||
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1162,6 +1158,8 @@ static const struct video_device sur40_video_device = {
|
|||
.fops = &sur40_video_fops,
|
||||
.ioctl_ops = &sur40_video_ioctl_ops,
|
||||
.release = video_device_release_empty,
|
||||
.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING,
|
||||
};
|
||||
|
||||
/* USB-specific object needed to register this driver with the USB subsystem. */
|
||||
|
|
|
@ -89,40 +89,7 @@ config MEDIA_CEC_SUPPORT
|
|||
|
||||
source "drivers/media/cec/Kconfig"
|
||||
|
||||
#
|
||||
# Media controller
|
||||
# Selectable only for webcam/grabbers, as other drivers don't use it
|
||||
#
|
||||
|
||||
config MEDIA_CONTROLLER
|
||||
bool "Media Controller API"
|
||||
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
|
||||
help
|
||||
Enable the media controller API used to query media devices internal
|
||||
topology and configure it dynamically.
|
||||
|
||||
This API is mostly used by camera interfaces in embedded platforms.
|
||||
|
||||
config MEDIA_CONTROLLER_DVB
|
||||
bool "Enable Media controller for DVB (EXPERIMENTAL)"
|
||||
depends on MEDIA_CONTROLLER && DVB_CORE
|
||||
help
|
||||
Enable the media controller API support for DVB.
|
||||
|
||||
This is currently experimental.
|
||||
|
||||
config MEDIA_CONTROLLER_REQUEST_API
|
||||
bool "Enable Media controller Request API (EXPERIMENTAL)"
|
||||
depends on MEDIA_CONTROLLER && STAGING_MEDIA
|
||||
default n
|
||||
help
|
||||
DO NOT ENABLE THIS OPTION UNLESS YOU KNOW WHAT YOU'RE DOING.
|
||||
|
||||
This option enables the Request API for the Media controller and V4L2
|
||||
interfaces. It is currently needed by a few stateless codec drivers.
|
||||
|
||||
There is currently no intention to provide API or ABI stability for
|
||||
this new API as of yet.
|
||||
source "drivers/media/mc/Kconfig"
|
||||
|
||||
#
|
||||
# Video4Linux support
|
||||
|
@ -164,7 +131,6 @@ config DVB_MMAP
|
|||
depends on DVB_CORE
|
||||
depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
|
||||
select VIDEOBUF2_VMALLOC
|
||||
default n
|
||||
help
|
||||
This option enables DVB experimental memory-mapped API, which
|
||||
reduces the number of context switches to read DVB buffers, as
|
||||
|
@ -190,7 +156,6 @@ config DVB_NET
|
|||
config TTPCI_EEPROM
|
||||
tristate
|
||||
depends on I2C
|
||||
default n
|
||||
|
||||
source "drivers/media/dvb-core/Kconfig"
|
||||
|
||||
|
|
|
@ -3,15 +3,6 @@
|
|||
# Makefile for the kernel multimedia device drivers.
|
||||
#
|
||||
|
||||
media-objs := media-device.o media-devnode.o media-entity.o \
|
||||
media-request.o
|
||||
|
||||
ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
|
||||
ifeq ($(CONFIG_USB),y)
|
||||
media-objs += media-dev-allocator.o
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# I2C drivers should come before other drivers, otherwise they'll fail
|
||||
# when compiled as builtin drivers
|
||||
|
@ -20,10 +11,10 @@ obj-y += i2c/ tuners/
|
|||
obj-$(CONFIG_DVB_CORE) += dvb-frontends/
|
||||
|
||||
#
|
||||
# Now, let's link-in the media core
|
||||
# Now, let's link-in the media controller core
|
||||
#
|
||||
ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
|
||||
obj-$(CONFIG_MEDIA_SUPPORT) += media.o
|
||||
obj-$(CONFIG_MEDIA_SUPPORT) += mc/
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_VIDEO_DEV) += v4l2-core/
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_file.h>
|
||||
|
||||
#include "cec-priv.h"
|
||||
|
||||
|
@ -75,6 +78,16 @@ u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
|
||||
|
||||
void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
|
||||
const struct drm_connector *connector)
|
||||
{
|
||||
memset(conn_info, 0, sizeof(*conn_info));
|
||||
conn_info->type = CEC_CONNECTOR_TYPE_DRM;
|
||||
conn_info->drm.card_no = connector->dev->primary->index;
|
||||
conn_info->drm.connector_id = connector->base.id;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_fill_conn_info_from_drm);
|
||||
|
||||
/*
|
||||
* Queue a new event for this filehandle. If ts == 0, then set it
|
||||
* to the current time.
|
||||
|
@ -720,6 +733,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
struct cec_fh *fh, bool block)
|
||||
{
|
||||
struct cec_data *data;
|
||||
bool is_raw = msg_is_raw(msg);
|
||||
|
||||
msg->rx_ts = 0;
|
||||
msg->tx_ts = 0;
|
||||
|
@ -735,15 +749,10 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
/* Make sure the timeout isn't 0. */
|
||||
msg->timeout = 1000;
|
||||
}
|
||||
if (msg->timeout)
|
||||
msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS;
|
||||
else
|
||||
msg->flags = 0;
|
||||
msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW;
|
||||
|
||||
if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
|
||||
msg->msg[2] = adap->phys_addr >> 8;
|
||||
msg->msg[3] = adap->phys_addr & 0xff;
|
||||
}
|
||||
if (!msg->timeout)
|
||||
msg->flags &= ~CEC_MSG_FL_REPLY_TO_FOLLOWERS;
|
||||
|
||||
/* Sanity checks */
|
||||
if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) {
|
||||
|
@ -765,44 +774,80 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
dprintk(1, "%s: can't reply to poll msg\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (msg->len == 1) {
|
||||
if (cec_msg_destination(msg) == 0xf) {
|
||||
dprintk(1, "%s: invalid poll message\n", __func__);
|
||||
|
||||
if (is_raw) {
|
||||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
} else {
|
||||
/* A CDC-Only device can only send CDC messages */
|
||||
if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
|
||||
(msg->len == 1 || msg->msg[1] != CEC_MSG_CDC_MESSAGE)) {
|
||||
dprintk(1, "%s: not a CDC message\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
|
||||
/*
|
||||
* If the destination is a logical address our adapter
|
||||
* has already claimed, then just NACK this.
|
||||
* It depends on the hardware what it will do with a
|
||||
* POLL to itself (some OK this), so it is just as
|
||||
* easy to handle it here so the behavior will be
|
||||
* consistent.
|
||||
*/
|
||||
msg->tx_ts = ktime_get_ns();
|
||||
msg->tx_status = CEC_TX_STATUS_NACK |
|
||||
CEC_TX_STATUS_MAX_RETRIES;
|
||||
msg->tx_nack_cnt = 1;
|
||||
msg->sequence = ++adap->sequence;
|
||||
if (!msg->sequence)
|
||||
|
||||
if (msg->len >= 4 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
|
||||
msg->msg[2] = adap->phys_addr >> 8;
|
||||
msg->msg[3] = adap->phys_addr & 0xff;
|
||||
}
|
||||
|
||||
if (msg->len == 1) {
|
||||
if (cec_msg_destination(msg) == 0xf) {
|
||||
dprintk(1, "%s: invalid poll message\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
|
||||
/*
|
||||
* If the destination is a logical address our
|
||||
* adapter has already claimed, then just NACK
|
||||
* this. It depends on the hardware what it will
|
||||
* do with a POLL to itself (some OK this), so
|
||||
* it is just as easy to handle it here so the
|
||||
* behavior will be consistent.
|
||||
*/
|
||||
msg->tx_ts = ktime_get_ns();
|
||||
msg->tx_status = CEC_TX_STATUS_NACK |
|
||||
CEC_TX_STATUS_MAX_RETRIES;
|
||||
msg->tx_nack_cnt = 1;
|
||||
msg->sequence = ++adap->sequence;
|
||||
return 0;
|
||||
if (!msg->sequence)
|
||||
msg->sequence = ++adap->sequence;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
|
||||
cec_has_log_addr(adap, cec_msg_destination(msg))) {
|
||||
dprintk(1, "%s: destination is the adapter itself\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (msg->len > 1 && adap->is_configured &&
|
||||
!cec_has_log_addr(adap, cec_msg_initiator(msg))) {
|
||||
dprintk(1, "%s: initiator has unknown logical address %d\n",
|
||||
__func__, cec_msg_initiator(msg));
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* Special case: allow Ping and IMAGE/TEXT_VIEW_ON to be
|
||||
* transmitted to a TV, even if the adapter is unconfigured.
|
||||
* This makes it possible to detect or wake up displays that
|
||||
* pull down the HPD when in standby.
|
||||
*/
|
||||
if (!adap->is_configured && !adap->is_configuring &&
|
||||
(msg->len > 2 ||
|
||||
cec_msg_destination(msg) != CEC_LOG_ADDR_TV ||
|
||||
(msg->len == 2 && msg->msg[1] != CEC_MSG_IMAGE_VIEW_ON &&
|
||||
msg->msg[1] != CEC_MSG_TEXT_VIEW_ON))) {
|
||||
dprintk(1, "%s: adapter is unconfigured\n", __func__);
|
||||
return -ENONET;
|
||||
}
|
||||
}
|
||||
if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
|
||||
cec_has_log_addr(adap, cec_msg_destination(msg))) {
|
||||
dprintk(1, "%s: destination is the adapter itself\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (msg->len > 1 && adap->is_configured &&
|
||||
!cec_has_log_addr(adap, cec_msg_initiator(msg))) {
|
||||
dprintk(1, "%s: initiator has unknown logical address %d\n",
|
||||
__func__, cec_msg_initiator(msg));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!adap->is_configured && !adap->is_configuring) {
|
||||
if (adap->needs_hpd || msg->msg[0] != 0xf0) {
|
||||
dprintk(1, "%s: adapter is unconfigured\n", __func__);
|
||||
if (adap->needs_hpd) {
|
||||
dprintk(1, "%s: adapter is unconfigured and needs HPD\n",
|
||||
__func__);
|
||||
return -ENONET;
|
||||
}
|
||||
if (msg->reply) {
|
||||
|
@ -1566,6 +1611,22 @@ void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
|
||||
|
||||
void cec_s_conn_info(struct cec_adapter *adap,
|
||||
const struct cec_connector_info *conn_info)
|
||||
{
|
||||
if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
|
||||
return;
|
||||
|
||||
mutex_lock(&adap->lock);
|
||||
if (conn_info)
|
||||
adap->conn_info = *conn_info;
|
||||
else
|
||||
memset(&adap->conn_info, 0, sizeof(adap->conn_info));
|
||||
cec_post_state_event(adap);
|
||||
mutex_unlock(&adap->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_s_conn_info);
|
||||
|
||||
/*
|
||||
* Called from either the ioctl or a driver to set the logical addresses.
|
||||
*
|
||||
|
|
|
@ -198,19 +198,11 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
|
|||
if (copy_from_user(&msg, parg, sizeof(msg)))
|
||||
return -EFAULT;
|
||||
|
||||
/* A CDC-Only device can only send CDC messages */
|
||||
if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
|
||||
(msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&adap->lock);
|
||||
if (adap->log_addrs.num_log_addrs == 0)
|
||||
err = -EPERM;
|
||||
else if (adap->is_configuring)
|
||||
err = -ENONET;
|
||||
else if (!adap->is_configured &&
|
||||
(adap->needs_hpd || msg.msg[0] != 0xf0))
|
||||
err = -ENONET;
|
||||
else if (cec_is_busy(adap, fh))
|
||||
err = -EBUSY;
|
||||
else
|
||||
|
|
|
@ -128,13 +128,14 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
|
|||
devnode->cdev.owner = owner;
|
||||
kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
|
||||
|
||||
devnode->registered = true;
|
||||
ret = cdev_device_add(&devnode->cdev, &devnode->dev);
|
||||
if (ret) {
|
||||
devnode->registered = false;
|
||||
pr_err("%s: cdev_device_add failed\n", __func__);
|
||||
goto clr_bit;
|
||||
}
|
||||
|
||||
devnode->registered = true;
|
||||
return 0;
|
||||
|
||||
clr_bit:
|
||||
|
@ -256,6 +257,11 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
|
|||
struct cec_adapter *adap;
|
||||
int res;
|
||||
|
||||
/*
|
||||
* Disable this capability until the connector info public API
|
||||
* is ready.
|
||||
*/
|
||||
caps &= ~CEC_CAP_CONNECTOR_INFO;
|
||||
#ifndef CONFIG_MEDIA_CEC_RC
|
||||
caps &= ~CEC_CAP_RC;
|
||||
#endif
|
||||
|
|
|
@ -21,8 +21,9 @@ struct cec_notifier {
|
|||
struct mutex lock;
|
||||
struct list_head head;
|
||||
struct kref kref;
|
||||
struct device *dev;
|
||||
const char *conn;
|
||||
struct device *hdmi_dev;
|
||||
struct cec_connector_info conn_info;
|
||||
const char *conn_name;
|
||||
struct cec_adapter *cec_adap;
|
||||
void (*callback)(struct cec_adapter *adap, u16 pa);
|
||||
|
||||
|
@ -32,14 +33,16 @@ struct cec_notifier {
|
|||
static LIST_HEAD(cec_notifiers);
|
||||
static DEFINE_MUTEX(cec_notifiers_lock);
|
||||
|
||||
struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)
|
||||
struct cec_notifier *
|
||||
cec_notifier_get_conn(struct device *hdmi_dev, const char *conn_name)
|
||||
{
|
||||
struct cec_notifier *n;
|
||||
|
||||
mutex_lock(&cec_notifiers_lock);
|
||||
list_for_each_entry(n, &cec_notifiers, head) {
|
||||
if (n->dev == dev &&
|
||||
(!conn || !strcmp(n->conn, conn))) {
|
||||
if (n->hdmi_dev == hdmi_dev &&
|
||||
(!conn_name ||
|
||||
(n->conn_name && !strcmp(n->conn_name, conn_name)))) {
|
||||
kref_get(&n->kref);
|
||||
mutex_unlock(&cec_notifiers_lock);
|
||||
return n;
|
||||
|
@ -48,10 +51,17 @@ struct cec_notifier *cec_notifier_get_conn(struct device *dev, const char *conn)
|
|||
n = kzalloc(sizeof(*n), GFP_KERNEL);
|
||||
if (!n)
|
||||
goto unlock;
|
||||
n->dev = dev;
|
||||
if (conn)
|
||||
n->conn = kstrdup(conn, GFP_KERNEL);
|
||||
n->hdmi_dev = hdmi_dev;
|
||||
if (conn_name) {
|
||||
n->conn_name = kstrdup(conn_name, GFP_KERNEL);
|
||||
if (!n->conn_name) {
|
||||
kfree(n);
|
||||
n = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
n->phys_addr = CEC_PHYS_ADDR_INVALID;
|
||||
|
||||
mutex_init(&n->lock);
|
||||
kref_init(&n->kref);
|
||||
list_add_tail(&n->head, &cec_notifiers);
|
||||
|
@ -67,7 +77,7 @@ static void cec_notifier_release(struct kref *kref)
|
|||
container_of(kref, struct cec_notifier, kref);
|
||||
|
||||
list_del(&n->head);
|
||||
kfree(n->conn);
|
||||
kfree(n->conn_name);
|
||||
kfree(n);
|
||||
}
|
||||
|
||||
|
@ -79,6 +89,84 @@ void cec_notifier_put(struct cec_notifier *n)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_put);
|
||||
|
||||
struct cec_notifier *
|
||||
cec_notifier_conn_register(struct device *hdmi_dev, const char *conn_name,
|
||||
const struct cec_connector_info *conn_info)
|
||||
{
|
||||
struct cec_notifier *n = cec_notifier_get_conn(hdmi_dev, conn_name);
|
||||
|
||||
if (!n)
|
||||
return n;
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
n->phys_addr = CEC_PHYS_ADDR_INVALID;
|
||||
if (conn_info)
|
||||
n->conn_info = *conn_info;
|
||||
else
|
||||
memset(&n->conn_info, 0, sizeof(n->conn_info));
|
||||
if (n->cec_adap) {
|
||||
cec_phys_addr_invalidate(n->cec_adap);
|
||||
cec_s_conn_info(n->cec_adap, conn_info);
|
||||
}
|
||||
mutex_unlock(&n->lock);
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_conn_register);
|
||||
|
||||
void cec_notifier_conn_unregister(struct cec_notifier *n)
|
||||
{
|
||||
if (!n)
|
||||
return;
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
memset(&n->conn_info, 0, sizeof(n->conn_info));
|
||||
n->phys_addr = CEC_PHYS_ADDR_INVALID;
|
||||
if (n->cec_adap) {
|
||||
cec_phys_addr_invalidate(n->cec_adap);
|
||||
cec_s_conn_info(n->cec_adap, NULL);
|
||||
}
|
||||
mutex_unlock(&n->lock);
|
||||
cec_notifier_put(n);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_conn_unregister);
|
||||
|
||||
struct cec_notifier *
|
||||
cec_notifier_cec_adap_register(struct device *hdmi_dev, const char *conn_name,
|
||||
struct cec_adapter *adap)
|
||||
{
|
||||
struct cec_notifier *n;
|
||||
|
||||
if (WARN_ON(!adap))
|
||||
return NULL;
|
||||
|
||||
n = cec_notifier_get_conn(hdmi_dev, conn_name);
|
||||
if (!n)
|
||||
return n;
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
n->cec_adap = adap;
|
||||
adap->conn_info = n->conn_info;
|
||||
adap->notifier = n;
|
||||
cec_s_phys_addr(adap, n->phys_addr, false);
|
||||
mutex_unlock(&n->lock);
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_register);
|
||||
|
||||
void cec_notifier_cec_adap_unregister(struct cec_notifier *n)
|
||||
{
|
||||
if (!n)
|
||||
return;
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
n->cec_adap->notifier = NULL;
|
||||
n->cec_adap = NULL;
|
||||
n->callback = NULL;
|
||||
mutex_unlock(&n->lock);
|
||||
cec_notifier_put(n);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_cec_adap_unregister);
|
||||
|
||||
void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
|
||||
{
|
||||
if (n == NULL)
|
||||
|
@ -88,6 +176,8 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
|
|||
n->phys_addr = pa;
|
||||
if (n->callback)
|
||||
n->callback(n->cec_adap, n->phys_addr);
|
||||
else if (n->cec_adap)
|
||||
cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
|
||||
mutex_unlock(&n->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
|
||||
|
@ -122,6 +212,10 @@ EXPORT_SYMBOL_GPL(cec_notifier_register);
|
|||
|
||||
void cec_notifier_unregister(struct cec_notifier *n)
|
||||
{
|
||||
/* Do nothing unless cec_notifier_register was called first */
|
||||
if (!n->callback)
|
||||
return;
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
n->callback = NULL;
|
||||
mutex_unlock(&n->lock);
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
/* devnode to cec_adapter */
|
||||
#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode)
|
||||
|
||||
static inline bool msg_is_raw(const struct cec_msg *msg)
|
||||
{
|
||||
return msg->flags & CEC_MSG_FL_RAW;
|
||||
}
|
||||
|
||||
/* cec-core.c */
|
||||
extern int cec_debug;
|
||||
int cec_get_device(struct cec_devnode *devnode);
|
||||
|
|
|
@ -608,6 +608,15 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
|
|||
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
|
||||
vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
|
||||
strscpy(vfd->name, name, sizeof(vfd->name));
|
||||
vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
||||
vfd->device_caps |= dev->ext_vv_data->capabilities;
|
||||
if (type == VFL_TYPE_GRABBER)
|
||||
vfd->device_caps &=
|
||||
~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
|
||||
else
|
||||
vfd->device_caps &=
|
||||
~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
|
||||
video_set_drvdata(vfd, dev);
|
||||
|
||||
err = video_register_device(vfd, type, -1);
|
||||
|
|
|
@ -448,25 +448,15 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
|
|||
|
||||
static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
|
||||
strscpy((char *)cap->driver, "saa7146 v4l2", sizeof(cap->driver));
|
||||
strscpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
|
||||
sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
|
||||
cap->device_caps =
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_VIDEO_OVERLAY |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING;
|
||||
cap->device_caps |= dev->ext_vv_data->capabilities;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||
if (vdev->vfl_type == VFL_TYPE_GRABBER)
|
||||
cap->device_caps &=
|
||||
~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
|
||||
else
|
||||
cap->device_caps &=
|
||||
~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
|
||||
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_DEVICE_CAPS;
|
||||
cap->capabilities |= dev->ext_vv_data->capabilities;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,8 +205,13 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
|
|||
* NOTE: mmapped areas should be page aligned
|
||||
*/
|
||||
for (plane = 0; plane < vb->num_planes; ++plane) {
|
||||
/* Memops alloc requires size to be page aligned. */
|
||||
unsigned long size = PAGE_ALIGN(vb->planes[plane].length);
|
||||
|
||||
/* Did it wrap around? */
|
||||
if (size < vb->planes[plane].length)
|
||||
goto free;
|
||||
|
||||
mem_priv = call_ptr_memop(vb, alloc,
|
||||
q->alloc_devs[plane] ? : q->dev,
|
||||
q->dma_attrs, size, q->dma_dir, q->gfp_flags);
|
||||
|
|
|
@ -475,8 +475,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
|
|||
buf->dma_dir = dma_dir;
|
||||
|
||||
offset = lower_32_bits(offset_in_page(vaddr));
|
||||
vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE ||
|
||||
dma_dir == DMA_BIDIRECTIONAL);
|
||||
vec = vb2_create_framevec(vaddr, size);
|
||||
if (IS_ERR(vec)) {
|
||||
ret = PTR_ERR(vec);
|
||||
goto fail_buf;
|
||||
|
|
|
@ -59,7 +59,7 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
|
|||
gfp_t gfp_flags)
|
||||
{
|
||||
unsigned int last_page = 0;
|
||||
int size = buf->size;
|
||||
unsigned long size = buf->size;
|
||||
|
||||
while (size > 0) {
|
||||
struct page *pages;
|
||||
|
@ -239,8 +239,7 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
|
|||
buf->offset = vaddr & ~PAGE_MASK;
|
||||
buf->size = size;
|
||||
buf->dma_sgt = &buf->sg_table;
|
||||
vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE ||
|
||||
dma_dir == DMA_BIDIRECTIONAL);
|
||||
vec = vb2_create_framevec(vaddr, size);
|
||||
if (IS_ERR(vec))
|
||||
goto userptr_fail_pfnvec;
|
||||
buf->vec = vec;
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
* vb2_create_framevec() - map virtual addresses to pfns
|
||||
* @start: Virtual user address where we start mapping
|
||||
* @length: Length of a range to map
|
||||
* @write: Should we map for writing into the area
|
||||
*
|
||||
* This function allocates and fills in a vector with pfns corresponding to
|
||||
* virtual address range passed in arguments. If pfns have corresponding pages,
|
||||
|
@ -35,17 +34,13 @@
|
|||
* failure. Returned vector needs to be freed via vb2_destroy_pfnvec().
|
||||
*/
|
||||
struct frame_vector *vb2_create_framevec(unsigned long start,
|
||||
unsigned long length,
|
||||
bool write)
|
||||
unsigned long length)
|
||||
{
|
||||
int ret;
|
||||
unsigned long first, last;
|
||||
unsigned long nr;
|
||||
struct frame_vector *vec;
|
||||
unsigned int flags = FOLL_FORCE;
|
||||
|
||||
if (write)
|
||||
flags |= FOLL_WRITE;
|
||||
unsigned int flags = FOLL_FORCE | FOLL_WRITE;
|
||||
|
||||
first = start >> PAGE_SHIFT;
|
||||
last = (start + length - 1) >> PAGE_SHIFT;
|
||||
|
|
|
@ -563,11 +563,6 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
|
|||
b->flags |= V4L2_BUF_FLAG_REQUEST_FD;
|
||||
b->request_fd = vbuf->request_fd;
|
||||
}
|
||||
|
||||
if (!q->is_output &&
|
||||
b->flags & V4L2_BUF_FLAG_DONE &&
|
||||
b->flags & V4L2_BUF_FLAG_LAST)
|
||||
q->last_buffer_dequeued = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -786,6 +781,11 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
|
|||
|
||||
ret = vb2_core_dqbuf(q, NULL, b, nonblocking);
|
||||
|
||||
if (!q->is_output &&
|
||||
b->flags & V4L2_BUF_FLAG_DONE &&
|
||||
b->flags & V4L2_BUF_FLAG_LAST)
|
||||
q->last_buffer_dequeued = true;
|
||||
|
||||
/*
|
||||
* After calling the VIDIOC_DQBUF V4L2_BUF_FLAG_DONE must be
|
||||
* cleared.
|
||||
|
|
|
@ -87,8 +87,7 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr,
|
|||
buf->dma_dir = dma_dir;
|
||||
offset = vaddr & ~PAGE_MASK;
|
||||
buf->size = size;
|
||||
vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE ||
|
||||
dma_dir == DMA_BIDIRECTIONAL);
|
||||
vec = vb2_create_framevec(vaddr, size);
|
||||
if (IS_ERR(vec)) {
|
||||
ret = PTR_ERR(vec);
|
||||
goto fail_pfnvec_create;
|
||||
|
|
|
@ -19,7 +19,6 @@ config DVB_MAX_ADAPTERS
|
|||
config DVB_DYNAMIC_MINORS
|
||||
bool "Dynamic DVB minor allocation"
|
||||
depends on DVB_CORE
|
||||
default n
|
||||
help
|
||||
If you say Y here, the DVB subsystem will use dynamic minor
|
||||
allocation for any device that uses the DVB major number.
|
||||
|
@ -32,7 +31,6 @@ config DVB_DYNAMIC_MINORS
|
|||
config DVB_DEMUX_SECTION_LOSS_LOG
|
||||
bool "Enable DVB demux section packet loss log"
|
||||
depends on DVB_CORE
|
||||
default n
|
||||
help
|
||||
Enable extra log messages meant to detect packet loss
|
||||
inside the Kernel.
|
||||
|
@ -45,7 +43,6 @@ config DVB_DEMUX_SECTION_LOSS_LOG
|
|||
config DVB_ULE_DEBUG
|
||||
bool "Enable DVB net ULE packet debug messages"
|
||||
depends on DVB_CORE
|
||||
default n
|
||||
help
|
||||
Enable extra log messages meant to detect problems while
|
||||
handling DVB network ULE packet loss inside the Kernel.
|
||||
|
|
|
@ -2311,6 +2311,78 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
|
||||
struct dtv_properties *tvps)
|
||||
{
|
||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||
struct dtv_property *tvp = NULL;
|
||||
struct dtv_frontend_properties getp;
|
||||
int i, err;
|
||||
|
||||
memcpy(&getp, &fe->dtv_property_cache, sizeof(getp));
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n",
|
||||
__func__, tvps->num);
|
||||
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n",
|
||||
__func__, tvps->props);
|
||||
|
||||
/*
|
||||
* Put an arbitrary limit on the number of messages that can
|
||||
* be sent at once
|
||||
*/
|
||||
if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS)
|
||||
return -EINVAL;
|
||||
|
||||
tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
|
||||
/*
|
||||
* Let's use our own copy of property cache, in order to
|
||||
* avoid mangling with DTV zigzag logic, as drivers might
|
||||
* return crap, if they don't check if the data is available
|
||||
* before updating the properties cache.
|
||||
*/
|
||||
if (fepriv->state != FESTATE_IDLE) {
|
||||
err = dtv_get_frontend(fe, &getp, NULL);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
err = dtv_property_process_get(fe, &getp,
|
||||
tvp + i, file);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *)tvps->props, tvp,
|
||||
tvps->num * sizeof(struct dtv_property))) {
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
out:
|
||||
kfree(tvp);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dvb_get_frontend(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *p_out)
|
||||
{
|
||||
struct dtv_frontend_properties getp;
|
||||
|
||||
/*
|
||||
* Let's use our own copy of property cache, in order to
|
||||
* avoid mangling with DTV zigzag logic, as drivers might
|
||||
* return crap, if they don't check if the data is available
|
||||
* before updating the properties cache.
|
||||
*/
|
||||
memcpy(&getp, &fe->dtv_property_cache, sizeof(getp));
|
||||
|
||||
return dtv_get_frontend(fe, &getp, p_out);
|
||||
}
|
||||
|
||||
static int dvb_frontend_handle_ioctl(struct file *file,
|
||||
unsigned int cmd, void *parg)
|
||||
{
|
||||
|
@ -2356,58 +2428,9 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
|||
err = 0;
|
||||
break;
|
||||
}
|
||||
case FE_GET_PROPERTY: {
|
||||
struct dtv_properties *tvps = parg;
|
||||
struct dtv_property *tvp = NULL;
|
||||
struct dtv_frontend_properties getp = fe->dtv_property_cache;
|
||||
|
||||
dev_dbg(fe->dvb->device, "%s: properties.num = %d\n",
|
||||
__func__, tvps->num);
|
||||
dev_dbg(fe->dvb->device, "%s: properties.props = %p\n",
|
||||
__func__, tvps->props);
|
||||
|
||||
/*
|
||||
* Put an arbitrary limit on the number of messages that can
|
||||
* be sent at once
|
||||
*/
|
||||
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
||||
return -EINVAL;
|
||||
|
||||
tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
|
||||
/*
|
||||
* Let's use our own copy of property cache, in order to
|
||||
* avoid mangling with DTV zigzag logic, as drivers might
|
||||
* return crap, if they don't check if the data is available
|
||||
* before updating the properties cache.
|
||||
*/
|
||||
if (fepriv->state != FESTATE_IDLE) {
|
||||
err = dtv_get_frontend(fe, &getp, NULL);
|
||||
if (err < 0) {
|
||||
kfree(tvp);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
err = dtv_property_process_get(fe, &getp,
|
||||
tvp + i, file);
|
||||
if (err < 0) {
|
||||
kfree(tvp);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *)tvps->props, tvp,
|
||||
tvps->num * sizeof(struct dtv_property))) {
|
||||
kfree(tvp);
|
||||
return -EFAULT;
|
||||
}
|
||||
kfree(tvp);
|
||||
err = 0;
|
||||
case FE_GET_PROPERTY:
|
||||
err = dvb_get_property(fe, file, parg);
|
||||
break;
|
||||
}
|
||||
|
||||
case FE_GET_INFO: {
|
||||
struct dvb_frontend_info *info = parg;
|
||||
|
@ -2545,7 +2568,6 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
|||
fepriv->tune_mode_flags = (unsigned long)parg;
|
||||
err = 0;
|
||||
break;
|
||||
|
||||
/* DEPRECATED dish control ioctls */
|
||||
|
||||
case FE_DISHNETWORK_SEND_LEGACY_CMD:
|
||||
|
@ -2664,22 +2686,14 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
|||
break;
|
||||
err = dtv_set_frontend(fe);
|
||||
break;
|
||||
|
||||
case FE_GET_EVENT:
|
||||
err = dvb_frontend_get_event(fe, parg, file->f_flags);
|
||||
break;
|
||||
|
||||
case FE_GET_FRONTEND: {
|
||||
struct dtv_frontend_properties getp = fe->dtv_property_cache;
|
||||
|
||||
/*
|
||||
* Let's use our own copy of property cache, in order to
|
||||
* avoid mangling with DTV zigzag logic, as drivers might
|
||||
* return crap, if they don't check if the data is available
|
||||
* before updating the properties cache.
|
||||
*/
|
||||
err = dtv_get_frontend(fe, &getp, parg);
|
||||
case FE_GET_FRONTEND:
|
||||
err = dvb_get_frontend(fe, parg);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
menu "Customise DVB Frontends"
|
||||
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
|
||||
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
|
||||
|
||||
comment "Multistandard (satellite) frontends"
|
||||
depends on DVB_CORE
|
||||
|
@ -945,5 +945,4 @@ comment "Tools to develop new frontends"
|
|||
config DVB_DUMMY_FE
|
||||
tristate "Dummy frontend driver"
|
||||
depends on DVB_CORE
|
||||
default n
|
||||
endmenu
|
||||
|
|
|
@ -428,9 +428,6 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
|
|||
strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
|
||||
strscpy(cap->card, dev->vdev.name, sizeof(cap->card));
|
||||
usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
|
||||
cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1242,6 +1239,8 @@ static struct video_device rtl2832_sdr_template = {
|
|||
.release = video_device_release_empty,
|
||||
.fops = &rtl2832_sdr_fops,
|
||||
.ioctl_ops = &rtl2832_sdr_ioctl_ops,
|
||||
.device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_TUNER,
|
||||
};
|
||||
|
||||
static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
|
|
|
@ -674,8 +674,11 @@ static const struct dvb_frontend_ops si2168_ops = {
|
|||
.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
|
||||
.info = {
|
||||
.name = "Silicon Labs Si2168",
|
||||
.symbol_rate_min = 1000000,
|
||||
.symbol_rate_max = 7200000,
|
||||
.frequency_min_hz = 48 * MHz,
|
||||
.frequency_max_hz = 870 * MHz,
|
||||
.frequency_stepsize_hz = 62500,
|
||||
.symbol_rate_min = 1000000,
|
||||
.symbol_rate_max = 7200000,
|
||||
.caps = FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
|
|
|
@ -682,7 +682,7 @@ static const struct dvb_frontend_ops stv0297_ops = {
|
|||
.delsys = { SYS_DVBC_ANNEX_A },
|
||||
.info = {
|
||||
.name = "ST STV0297 DVB-C",
|
||||
.frequency_min_hz = 470 * MHz,
|
||||
.frequency_min_hz = 47 * MHz,
|
||||
.frequency_max_hz = 862 * MHz,
|
||||
.frequency_stepsize_hz = 62500,
|
||||
.symbol_rate_min = 870000,
|
||||
|
|
|
@ -4889,6 +4889,66 @@ static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
|
|||
return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
|
||||
}
|
||||
|
||||
static int stv090x_setup_compound(struct stv090x_state *state)
|
||||
{
|
||||
struct stv090x_dev *temp_int;
|
||||
|
||||
temp_int = find_dev(state->i2c,
|
||||
state->config->address);
|
||||
|
||||
if (temp_int && state->demod_mode == STV090x_DUAL) {
|
||||
state->internal = temp_int->internal;
|
||||
state->internal->num_used++;
|
||||
dprintk(FE_INFO, 1, "Found Internal Structure!");
|
||||
} else {
|
||||
state->internal = kmalloc(sizeof(*state->internal), GFP_KERNEL);
|
||||
if (!state->internal)
|
||||
goto error;
|
||||
temp_int = append_internal(state->internal);
|
||||
if (!temp_int) {
|
||||
kfree(state->internal);
|
||||
goto error;
|
||||
}
|
||||
state->internal->num_used = 1;
|
||||
state->internal->mclk = 0;
|
||||
state->internal->dev_ver = 0;
|
||||
state->internal->i2c_adap = state->i2c;
|
||||
state->internal->i2c_addr = state->config->address;
|
||||
dprintk(FE_INFO, 1, "Create New Internal Structure!");
|
||||
|
||||
mutex_init(&state->internal->demod_lock);
|
||||
mutex_init(&state->internal->tuner_lock);
|
||||
|
||||
if (stv090x_setup(&state->frontend) < 0) {
|
||||
dprintk(FE_ERROR, 1, "Error setting up device");
|
||||
goto err_remove;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->internal->dev_ver >= 0x30)
|
||||
state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM;
|
||||
|
||||
/* workaround for stuck DiSEqC output */
|
||||
if (state->config->diseqc_envelope_mode)
|
||||
stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
|
||||
|
||||
state->config->set_gpio = stv090x_set_gpio;
|
||||
|
||||
dprintk(FE_ERROR, 1, "Probing %s demodulator(%d) Cut=0x%02x",
|
||||
state->device == STV0900 ? "STV0900" : "STV0903",
|
||||
state->config->demod,
|
||||
state->internal->dev_ver);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -ENOMEM;
|
||||
err_remove:
|
||||
remove_dev(state->internal);
|
||||
kfree(state->internal);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static const struct dvb_frontend_ops stv090x_ops = {
|
||||
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
|
||||
.info = {
|
||||
|
@ -4921,16 +4981,74 @@ static const struct dvb_frontend_ops stv090x_ops = {
|
|||
.read_snr = stv090x_read_cnr,
|
||||
};
|
||||
|
||||
static struct dvb_frontend *stv090x_get_dvb_frontend(struct i2c_client *client)
|
||||
{
|
||||
struct stv090x_state *state = i2c_get_clientdata(client);
|
||||
|
||||
dev_dbg(&client->dev, "\n");
|
||||
|
||||
return &state->frontend;
|
||||
}
|
||||
|
||||
static int stv090x_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct stv090x_config *config = client->dev.platform_data;
|
||||
|
||||
struct stv090x_state *state = NULL;
|
||||
|
||||
state = kzalloc(sizeof(*state), GFP_KERNEL);
|
||||
if (!state) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
state->verbose = &verbose;
|
||||
state->config = config;
|
||||
state->i2c = client->adapter;
|
||||
state->frontend.ops = stv090x_ops;
|
||||
state->frontend.demodulator_priv = state;
|
||||
state->demod = config->demod;
|
||||
/* Single or Dual mode */
|
||||
state->demod_mode = config->demod_mode;
|
||||
state->device = config->device;
|
||||
/* default */
|
||||
state->rolloff = STV090x_RO_35;
|
||||
|
||||
ret = stv090x_setup_compound(state);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
i2c_set_clientdata(client, state);
|
||||
|
||||
/* setup callbacks */
|
||||
config->get_dvb_frontend = stv090x_get_dvb_frontend;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
kfree(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stv090x_remove(struct i2c_client *client)
|
||||
{
|
||||
struct stv090x_state *state = i2c_get_clientdata(client);
|
||||
|
||||
stv090x_release(&state->frontend);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod)
|
||||
{
|
||||
int ret = 0;
|
||||
struct stv090x_state *state = NULL;
|
||||
struct stv090x_dev *temp_int;
|
||||
|
||||
state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
state = kzalloc(sizeof(*state), GFP_KERNEL);
|
||||
if (!state)
|
||||
goto error;
|
||||
|
||||
state->verbose = &verbose;
|
||||
|
@ -4939,67 +5057,42 @@ struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
|
|||
state->frontend.ops = stv090x_ops;
|
||||
state->frontend.demodulator_priv = state;
|
||||
state->demod = demod;
|
||||
state->demod_mode = config->demod_mode; /* Single or Dual mode */
|
||||
/* Single or Dual mode */
|
||||
state->demod_mode = config->demod_mode;
|
||||
state->device = config->device;
|
||||
state->rolloff = STV090x_RO_35; /* default */
|
||||
/* default */
|
||||
state->rolloff = STV090x_RO_35;
|
||||
|
||||
temp_int = find_dev(state->i2c,
|
||||
state->config->address);
|
||||
|
||||
if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) {
|
||||
state->internal = temp_int->internal;
|
||||
state->internal->num_used++;
|
||||
dprintk(FE_INFO, 1, "Found Internal Structure!");
|
||||
} else {
|
||||
state->internal = kmalloc(sizeof(struct stv090x_internal),
|
||||
GFP_KERNEL);
|
||||
if (!state->internal)
|
||||
goto error;
|
||||
temp_int = append_internal(state->internal);
|
||||
if (!temp_int) {
|
||||
kfree(state->internal);
|
||||
goto error;
|
||||
}
|
||||
state->internal->num_used = 1;
|
||||
state->internal->mclk = 0;
|
||||
state->internal->dev_ver = 0;
|
||||
state->internal->i2c_adap = state->i2c;
|
||||
state->internal->i2c_addr = state->config->address;
|
||||
dprintk(FE_INFO, 1, "Create New Internal Structure!");
|
||||
|
||||
mutex_init(&state->internal->demod_lock);
|
||||
mutex_init(&state->internal->tuner_lock);
|
||||
|
||||
if (stv090x_setup(&state->frontend) < 0) {
|
||||
dprintk(FE_ERROR, 1, "Error setting up device");
|
||||
goto err_remove;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->internal->dev_ver >= 0x30)
|
||||
state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM;
|
||||
|
||||
/* workaround for stuck DiSEqC output */
|
||||
if (config->diseqc_envelope_mode)
|
||||
stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
|
||||
|
||||
config->set_gpio = stv090x_set_gpio;
|
||||
|
||||
dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
|
||||
state->device == STV0900 ? "STV0900" : "STV0903",
|
||||
demod,
|
||||
state->internal->dev_ver);
|
||||
ret = stv090x_setup_compound(state);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
return &state->frontend;
|
||||
|
||||
err_remove:
|
||||
remove_dev(state->internal);
|
||||
kfree(state->internal);
|
||||
error:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(stv090x_attach);
|
||||
|
||||
static const struct i2c_device_id stv090x_id_table[] = {
|
||||
{"stv090x", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, stv090x_id_table);
|
||||
|
||||
static struct i2c_driver stv090x_driver = {
|
||||
.driver = {
|
||||
.name = "stv090x",
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = stv090x_probe,
|
||||
.remove = stv090x_remove,
|
||||
.id_table = stv090x_id_table,
|
||||
};
|
||||
|
||||
module_i2c_driver(stv090x_driver);
|
||||
|
||||
MODULE_PARM_DESC(verbose, "Set Verbosity level");
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
|
||||
|
|
|
@ -57,6 +57,7 @@ struct stv090x_config {
|
|||
enum stv090x_device device;
|
||||
enum stv090x_mode demod_mode;
|
||||
enum stv090x_clkmode clk_mode;
|
||||
enum stv090x_demodulator demod;
|
||||
|
||||
u32 xtal; /* default: 8000000 */
|
||||
u8 address; /* default: 0x68 */
|
||||
|
@ -93,6 +94,8 @@ struct stv090x_config {
|
|||
/* dir = 0 -> output, dir = 1 -> input/open-drain */
|
||||
int (*set_gpio)(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
u8 xor_value);
|
||||
|
||||
struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *i2c);
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DVB_STV090x)
|
||||
|
|
|
@ -237,7 +237,7 @@ struct stv090x_state {
|
|||
struct stv090x_internal *internal;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
const struct stv090x_config *config;
|
||||
struct stv090x_config *config;
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
u32 *verbose; /* Cached module verbosity */
|
||||
|
|
|
@ -333,6 +333,41 @@ static void stv6110x_release(struct dvb_frontend *fe)
|
|||
kfree(stv6110x);
|
||||
}
|
||||
|
||||
static void st6110x_init_regs(struct stv6110x_state *stv6110x)
|
||||
{
|
||||
u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
|
||||
|
||||
memcpy(stv6110x->regs, default_regs, 8);
|
||||
}
|
||||
|
||||
static void stv6110x_setup_divider(struct stv6110x_state *stv6110x)
|
||||
{
|
||||
switch (stv6110x->config->clk_div) {
|
||||
default:
|
||||
case 1:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2],
|
||||
CTRL2_CO_DIV,
|
||||
0);
|
||||
break;
|
||||
case 2:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2],
|
||||
CTRL2_CO_DIV,
|
||||
1);
|
||||
break;
|
||||
case 4:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2],
|
||||
CTRL2_CO_DIV,
|
||||
2);
|
||||
break;
|
||||
case 8:
|
||||
case 0:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2],
|
||||
CTRL2_CO_DIV,
|
||||
3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dvb_tuner_ops stv6110x_ops = {
|
||||
.info = {
|
||||
.name = "STV6110(A) Silicon Tuner",
|
||||
|
@ -342,7 +377,7 @@ static const struct dvb_tuner_ops stv6110x_ops = {
|
|||
.release = stv6110x_release
|
||||
};
|
||||
|
||||
static const struct stv6110x_devctl stv6110x_ctl = {
|
||||
static struct stv6110x_devctl stv6110x_ctl = {
|
||||
.tuner_init = stv6110x_init,
|
||||
.tuner_sleep = stv6110x_sleep,
|
||||
.tuner_set_mode = stv6110x_set_mode,
|
||||
|
@ -356,48 +391,104 @@ static const struct stv6110x_devctl stv6110x_ctl = {
|
|||
.tuner_get_status = stv6110x_get_status,
|
||||
};
|
||||
|
||||
static void stv6110x_set_frontend_opts(struct stv6110x_state *stv6110x)
|
||||
{
|
||||
stv6110x->frontend->tuner_priv = stv6110x;
|
||||
stv6110x->frontend->ops.tuner_ops = stv6110x_ops;
|
||||
}
|
||||
|
||||
static struct stv6110x_devctl *stv6110x_get_devctl(struct i2c_client *client)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = i2c_get_clientdata(client);
|
||||
|
||||
dev_dbg(&client->dev, "\n");
|
||||
|
||||
return stv6110x->devctl;
|
||||
}
|
||||
|
||||
static int stv6110x_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct stv6110x_config *config = client->dev.platform_data;
|
||||
|
||||
struct stv6110x_state *stv6110x;
|
||||
|
||||
stv6110x = kzalloc(sizeof(*stv6110x), GFP_KERNEL);
|
||||
if (!stv6110x)
|
||||
return -ENOMEM;
|
||||
|
||||
stv6110x->frontend = config->frontend;
|
||||
stv6110x->i2c = client->adapter;
|
||||
stv6110x->config = config;
|
||||
stv6110x->devctl = &stv6110x_ctl;
|
||||
|
||||
st6110x_init_regs(stv6110x);
|
||||
stv6110x_setup_divider(stv6110x);
|
||||
stv6110x_set_frontend_opts(stv6110x);
|
||||
|
||||
dev_info(&stv6110x->i2c->dev, "Probed STV6110x\n");
|
||||
|
||||
i2c_set_clientdata(client, stv6110x);
|
||||
|
||||
/* setup callbacks */
|
||||
config->get_devctl = stv6110x_get_devctl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_remove(struct i2c_client *client)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = i2c_get_clientdata(client);
|
||||
|
||||
stv6110x_release(stv6110x->frontend);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
|
||||
const struct stv6110x_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct stv6110x_state *stv6110x;
|
||||
u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
|
||||
|
||||
stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
|
||||
stv6110x = kzalloc(sizeof(*stv6110x), GFP_KERNEL);
|
||||
if (!stv6110x)
|
||||
return NULL;
|
||||
|
||||
stv6110x->frontend = fe;
|
||||
stv6110x->i2c = i2c;
|
||||
stv6110x->config = config;
|
||||
stv6110x->devctl = &stv6110x_ctl;
|
||||
memcpy(stv6110x->regs, default_regs, 8);
|
||||
|
||||
/* setup divider */
|
||||
switch (stv6110x->config->clk_div) {
|
||||
default:
|
||||
case 1:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
|
||||
break;
|
||||
case 2:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
|
||||
break;
|
||||
case 4:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
|
||||
break;
|
||||
case 8:
|
||||
case 0:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
|
||||
break;
|
||||
}
|
||||
st6110x_init_regs(stv6110x);
|
||||
stv6110x_setup_divider(stv6110x);
|
||||
stv6110x_set_frontend_opts(stv6110x);
|
||||
|
||||
fe->tuner_priv = stv6110x;
|
||||
fe->ops.tuner_ops = stv6110x_ops;
|
||||
|
||||
printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
|
||||
dev_info(&stv6110x->i2c->dev, "Attaching STV6110x\n");
|
||||
return stv6110x->devctl;
|
||||
}
|
||||
EXPORT_SYMBOL(stv6110x_attach);
|
||||
|
||||
static const struct i2c_device_id stv6110x_id_table[] = {
|
||||
{"stv6110x", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, stv6110x_id_table);
|
||||
|
||||
static struct i2c_driver stv6110x_driver = {
|
||||
.driver = {
|
||||
.name = "stv6110x",
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = stv6110x_probe,
|
||||
.remove = stv6110x_remove,
|
||||
.id_table = stv6110x_id_table,
|
||||
};
|
||||
|
||||
module_i2c_driver(stv6110x_driver);
|
||||
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_DESCRIPTION("STV6110x Silicon tuner");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -15,6 +15,9 @@ struct stv6110x_config {
|
|||
u8 addr;
|
||||
u32 refclk;
|
||||
u8 clk_div; /* divisor value for the output clock */
|
||||
struct dvb_frontend *frontend;
|
||||
|
||||
struct stv6110x_devctl* (*get_devctl)(struct i2c_client *i2c);
|
||||
};
|
||||
|
||||
enum tuner_mode {
|
||||
|
|
|
@ -54,11 +54,12 @@
|
|||
#define REFCLOCK_MHz (stv6110x->config->refclk / 1000000)
|
||||
|
||||
struct stv6110x_state {
|
||||
struct dvb_frontend *frontend;
|
||||
struct i2c_adapter *i2c;
|
||||
const struct stv6110x_config *config;
|
||||
u8 regs[8];
|
||||
|
||||
const struct stv6110x_devctl *devctl;
|
||||
struct stv6110x_devctl *devctl;
|
||||
};
|
||||
|
||||
#endif /* __STV6110x_PRIV_H */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
if VIDEO_V4L2
|
||||
|
||||
config VIDEO_IR_I2C
|
||||
tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT
|
||||
tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT || EXPERT
|
||||
depends on I2C && RC_CORE
|
||||
default y
|
||||
help
|
||||
|
@ -23,7 +23,7 @@ config VIDEO_IR_I2C
|
|||
#
|
||||
|
||||
menu "I2C Encoders, decoders, sensors and other helper chips"
|
||||
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
|
||||
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
|
||||
|
||||
comment "Audio decoders, processors and mixers"
|
||||
|
||||
|
@ -511,6 +511,7 @@ config VIDEO_ADV7393
|
|||
config VIDEO_ADV7511
|
||||
tristate "Analog Devices ADV7511 encoder"
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on DRM_I2C_ADV7511=n || COMPILE_TEST
|
||||
select HDMI
|
||||
help
|
||||
Support for the Analog Devices ADV7511 video encoder.
|
||||
|
|
|
@ -35,7 +35,7 @@ obj-$(CONFIG_VIDEO_ADV748X) += adv748x/
|
|||
obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
|
||||
obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
|
||||
obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o
|
||||
obj-$(CONFIG_VIDEO_ADV7511) += adv7511.o
|
||||
obj-$(CONFIG_VIDEO_ADV7511) += adv7511-v4l2.o
|
||||
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
|
||||
obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
|
||||
obj-$(CONFIG_VIDEO_BT819) += bt819.o
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
* Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is named adv7511-v4l2.c so it doesn't conflict with the Analog
|
||||
* Device ADV7511 (config fragment CONFIG_DRM_I2C_ADV7511).
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
|
@ -229,7 +229,7 @@ static const struct v4l2_subdev_ops ak881x_subdev_ops = {
|
|||
static int ak881x_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
struct ak881x *ak881x;
|
||||
u8 ifmode, data;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,6 @@
|
|||
#ifndef _CX25840_CORE_H_
|
||||
#define _CX25840_CORE_H_
|
||||
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
@ -44,10 +43,15 @@ enum cx25840_media_pads {
|
|||
* @mute: audio mute V4L2 control (non-cx2583x devices only)
|
||||
* @pvr150_workaround: whether we enable workaround for Hauppauge PVR150
|
||||
* hardware bug (audio dropping out)
|
||||
* @generic_mode: whether we disable ivtv-specific hacks
|
||||
* this mode gets turned on when the bridge driver calls
|
||||
* cx25840 subdevice init core op
|
||||
* @radio: set if we are currently in the radio mode, otherwise
|
||||
* the current mode is non-radio (that is, video)
|
||||
* @std: currently set video standard
|
||||
* @vid_input: currently set video input
|
||||
* @vid_config: currently set video output configuration
|
||||
* only used in the generic mode
|
||||
* @aud_input: currently set audio input
|
||||
* @audclk_freq: currently set audio sample rate
|
||||
* @audmode: currently set audio mode (when in non-radio mode)
|
||||
|
@ -74,9 +78,11 @@ struct cx25840_state {
|
|||
struct v4l2_ctrl *mute;
|
||||
};
|
||||
int pvr150_workaround;
|
||||
bool generic_mode;
|
||||
int radio;
|
||||
v4l2_std_id std;
|
||||
enum cx25840_video_input vid_input;
|
||||
u32 vid_config;
|
||||
enum cx25840_audio_input aud_input;
|
||||
u32 audclk_freq;
|
||||
int audmode;
|
||||
|
@ -84,7 +90,7 @@ struct cx25840_state {
|
|||
enum cx25840_model id;
|
||||
u32 rev;
|
||||
int is_initialized;
|
||||
unsigned vbi_regs_offset;
|
||||
unsigned int vbi_regs_offset;
|
||||
wait_queue_head_t fw_wait;
|
||||
struct work_struct fw_work;
|
||||
struct cx25840_ir_state *ir_state;
|
||||
|
@ -109,6 +115,14 @@ static inline bool is_cx2583x(struct cx25840_state *state)
|
|||
state->id == CX25837;
|
||||
}
|
||||
|
||||
static inline bool is_cx2584x(struct cx25840_state *state)
|
||||
{
|
||||
return state->id == CX25840 ||
|
||||
state->id == CX25841 ||
|
||||
state->id == CX25842 ||
|
||||
state->id == CX25843;
|
||||
}
|
||||
|
||||
static inline bool is_cx231xx(struct cx25840_state *state)
|
||||
{
|
||||
return state->id == CX2310X_AV;
|
||||
|
@ -142,7 +156,8 @@ int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
|
|||
int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
|
||||
u8 cx25840_read(struct i2c_client *client, u16 addr);
|
||||
u32 cx25840_read4(struct i2c_client *client, u16 addr);
|
||||
int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value);
|
||||
int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned int mask,
|
||||
u8 value);
|
||||
int cx25840_and_or4(struct i2c_client *client, u16 addr, u32 and_mask,
|
||||
u32 or_value);
|
||||
void cx25840_std_setup(struct i2c_client *client);
|
||||
|
@ -161,9 +176,12 @@ extern const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops;
|
|||
/* ----------------------------------------------------------------------- */
|
||||
/* cx25850-vbi.c */
|
||||
int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt);
|
||||
int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
|
||||
int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt);
|
||||
int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
|
||||
int cx25840_s_sliced_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_sliced_vbi_format *fmt);
|
||||
int cx25840_g_sliced_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_sliced_vbi_format *fmt);
|
||||
int cx25840_decode_vbi_line(struct v4l2_subdev *sd,
|
||||
struct v4l2_decode_vbi_line *vbi);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* cx25850-ir.c */
|
||||
|
|
|
@ -86,6 +86,7 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
|
|||
memset(svbi->service_lines, 0, sizeof(svbi->service_lines));
|
||||
svbi->service_set = 0;
|
||||
/* we're done if raw VBI is active */
|
||||
/* TODO: this will have to be changed for generic_mode VBI */
|
||||
if ((cx25840_read(client, 0x404) & 0x10) == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -128,6 +129,7 @@ int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
|
|||
cx25840_write(client, 0x54f, vbi_offset);
|
||||
else
|
||||
cx25840_write(client, 0x47f, vbi_offset);
|
||||
/* TODO: this will have to be changed for generic_mode VBI */
|
||||
cx25840_write(client, 0x404, 0x2e);
|
||||
return 0;
|
||||
}
|
||||
|
@ -148,6 +150,7 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
|
|||
cx25840_std_setup(client);
|
||||
|
||||
/* Sliced VBI */
|
||||
/* TODO: this will have to be changed for generic_mode VBI */
|
||||
cx25840_write(client, 0x404, 0x32); /* Ancillary data */
|
||||
cx25840_write(client, 0x406, 0x13);
|
||||
if (is_cx23888(state))
|
||||
|
@ -202,6 +205,7 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
|
|||
}
|
||||
|
||||
cx25840_write(client, state->vbi_regs_offset + 0x43c, 0x16);
|
||||
/* TODO: this will have to be changed for generic_mode VBI */
|
||||
if (is_cx23888(state))
|
||||
cx25840_write(client, 0x428, is_pal ? 0x2a : 0x22);
|
||||
else
|
||||
|
|
|
@ -1111,6 +1111,6 @@ static struct i2c_driver imx214_i2c_driver = {
|
|||
|
||||
module_i2c_driver(imx214_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Sony IMX214 Camera drier");
|
||||
MODULE_DESCRIPTION("Sony IMX214 Camera driver");
|
||||
MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -730,7 +730,7 @@ static int mt9m001_probe(struct i2c_client *client,
|
|||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct mt9m001 *mt9m001;
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/log2.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/v4l2-mediabus.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
|
@ -240,6 +241,7 @@ struct mt9m111 {
|
|||
int power_count;
|
||||
const struct mt9m111_datafmt *fmt;
|
||||
int lastpage; /* PageMap cache value */
|
||||
struct regulator *regulator;
|
||||
bool is_streaming;
|
||||
/* user point of view - 0: falling 1: rising edge */
|
||||
unsigned int pclk_sample:1;
|
||||
|
@ -979,11 +981,23 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regulator_enable(mt9m111->regulator);
|
||||
if (ret < 0)
|
||||
goto out_clk_disable;
|
||||
|
||||
ret = mt9m111_resume(mt9m111);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
|
||||
v4l2_clk_disable(mt9m111->clk);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto out_regulator_disable;
|
||||
|
||||
return 0;
|
||||
|
||||
out_regulator_disable:
|
||||
regulator_disable(mt9m111->regulator);
|
||||
|
||||
out_clk_disable:
|
||||
v4l2_clk_disable(mt9m111->clk);
|
||||
|
||||
dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -991,6 +1005,7 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111)
|
|||
static void mt9m111_power_off(struct mt9m111 *mt9m111)
|
||||
{
|
||||
mt9m111_suspend(mt9m111);
|
||||
regulator_disable(mt9m111->regulator);
|
||||
v4l2_clk_disable(mt9m111->clk);
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1247,7 @@ static int mt9m111_probe(struct i2c_client *client,
|
|||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct mt9m111 *mt9m111;
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
|
@ -1245,14 +1260,23 @@ static int mt9m111_probe(struct i2c_client *client,
|
|||
if (!mt9m111)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mt9m111_probe_fw(client, mt9m111);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (dev_fwnode(&client->dev)) {
|
||||
ret = mt9m111_probe_fw(client, mt9m111);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
|
||||
if (IS_ERR(mt9m111->clk))
|
||||
return PTR_ERR(mt9m111->clk);
|
||||
|
||||
mt9m111->regulator = devm_regulator_get(&client->dev, "vdd");
|
||||
if (IS_ERR(mt9m111->regulator)) {
|
||||
dev_err(&client->dev, "regulator not found: %ld\n",
|
||||
PTR_ERR(mt9m111->regulator));
|
||||
return PTR_ERR(mt9m111->regulator);
|
||||
}
|
||||
|
||||
/* Default HIGHPOWER context */
|
||||
mt9m111->ctx = &context_b;
|
||||
|
||||
|
|
|
@ -1031,7 +1031,7 @@ static int mt9p031_probe(struct i2c_client *client,
|
|||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
struct mt9p031 *mt9p031;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
|
|
@ -1224,7 +1224,7 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
ov13858->exposure->minimum,
|
||||
max, ov13858->exposure->step, max);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Applying V4L2 control value only happens
|
||||
|
@ -1262,7 +1262,7 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
"ctrl(id:0x%x,val:0x%x) is not handled\n",
|
||||
ctrl->id, ctrl->val);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
|
||||
|
|
|
@ -1194,7 +1194,7 @@ static int ov2640_probe(struct i2c_client *client,
|
|||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct ov2640_priv *priv;
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
|
|
|
@ -576,7 +576,7 @@ static int ov2685_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
__func__, ctrl->id, ctrl->val);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
|
||||
|
|
|
@ -1143,7 +1143,7 @@ static int ov5695_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
|
||||
__func__, ctrl->id, ctrl->val);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
|
||||
|
|
|
@ -1006,7 +1006,6 @@ static int ov6650_probe(struct i2c_client *client,
|
|||
priv->colorspace = V4L2_COLORSPACE_JPEG;
|
||||
|
||||
priv->subdev.internal_ops = &ov6650_internal_ops;
|
||||
priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
|
||||
ret = v4l2_async_register_subdev(&priv->subdev);
|
||||
if (ret)
|
||||
|
|
|
@ -532,7 +532,7 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
|
||||
struct regmap *regmap = ov7740->regmap;
|
||||
int ret;
|
||||
u8 val = 0;
|
||||
u8 val;
|
||||
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
@ -551,6 +551,7 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
ret = ov7740_set_contrast(regmap, ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_VFLIP:
|
||||
val = ctrl->val ? REG0C_IMG_FLIP : 0x00;
|
||||
ret = regmap_update_bits(regmap, REG_REG0C,
|
||||
REG0C_IMG_FLIP, val);
|
||||
break;
|
||||
|
@ -561,16 +562,16 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
break;
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
if (!ctrl->val)
|
||||
return ov7740_set_gain(regmap, ov7740->gain->val);
|
||||
|
||||
ret = ov7740_set_autogain(regmap, ctrl->val);
|
||||
ret = ov7740_set_gain(regmap, ov7740->gain->val);
|
||||
else
|
||||
ret = ov7740_set_autogain(regmap, ctrl->val);
|
||||
break;
|
||||
|
||||
case V4L2_CID_EXPOSURE_AUTO:
|
||||
if (ctrl->val == V4L2_EXPOSURE_MANUAL)
|
||||
return ov7740_set_exp(regmap, ov7740->exposure->val);
|
||||
|
||||
ret = ov7740_set_autoexp(regmap, ctrl->val);
|
||||
ret = ov7740_set_exp(regmap, ov7740->exposure->val);
|
||||
else
|
||||
ret = ov7740_set_autoexp(regmap, ctrl->val);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
@ -785,7 +786,11 @@ static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
|
|||
|
||||
fsize++;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(ov7740_framesizes)) {
|
||||
fsize = &ov7740_framesizes[0];
|
||||
fmt->width = fsize->width;
|
||||
fmt->height = fsize->height;
|
||||
}
|
||||
if (ret_frmsize != NULL)
|
||||
*ret_frmsize = fsize;
|
||||
|
||||
|
@ -1007,8 +1012,6 @@ static int ov7740_init_controls(struct ov7740 *ov7740)
|
|||
|
||||
ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
|
||||
V4L2_CID_GAIN, 0, 1023, 1, 500);
|
||||
if (ov7740->gain)
|
||||
ov7740->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
||||
|
||||
ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
|
||||
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
|
||||
|
@ -1026,7 +1029,6 @@ static int ov7740_init_controls(struct ov7740 *ov7740)
|
|||
v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
|
||||
v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
|
||||
V4L2_EXPOSURE_MANUAL, true);
|
||||
v4l2_ctrl_cluster(2, &ov7740->hflip);
|
||||
|
||||
if (ctrl_hdlr->error) {
|
||||
ret = ctrl_hdlr->error;
|
||||
|
|
|
@ -195,11 +195,11 @@ static const struct ov8856_reg mode_3280x2464_regs[] = {
|
|||
{0x3800, 0x00},
|
||||
{0x3801, 0x00},
|
||||
{0x3802, 0x00},
|
||||
{0x3803, 0x07},
|
||||
{0x3803, 0x06},
|
||||
{0x3804, 0x0c},
|
||||
{0x3805, 0xdf},
|
||||
{0x3806, 0x09},
|
||||
{0x3807, 0xa6},
|
||||
{0x3807, 0xa7},
|
||||
{0x3808, 0x0c},
|
||||
{0x3809, 0xd0},
|
||||
{0x380a, 0x09},
|
||||
|
@ -211,7 +211,7 @@ static const struct ov8856_reg mode_3280x2464_regs[] = {
|
|||
{0x3810, 0x00},
|
||||
{0x3811, 0x00},
|
||||
{0x3812, 0x00},
|
||||
{0x3813, 0x00},
|
||||
{0x3813, 0x01},
|
||||
{0x3814, 0x01},
|
||||
{0x3815, 0x01},
|
||||
{0x3816, 0x00},
|
||||
|
@ -385,11 +385,11 @@ static const struct ov8856_reg mode_1640x1232_regs[] = {
|
|||
{0x3800, 0x00},
|
||||
{0x3801, 0x00},
|
||||
{0x3802, 0x00},
|
||||
{0x3803, 0x07},
|
||||
{0x3803, 0x06},
|
||||
{0x3804, 0x0c},
|
||||
{0x3805, 0xdf},
|
||||
{0x3806, 0x09},
|
||||
{0x3807, 0xa6},
|
||||
{0x3807, 0xa7},
|
||||
{0x3808, 0x06},
|
||||
{0x3809, 0x68},
|
||||
{0x380a, 0x04},
|
||||
|
@ -401,7 +401,7 @@ static const struct ov8856_reg mode_1640x1232_regs[] = {
|
|||
{0x3810, 0x00},
|
||||
{0x3811, 0x00},
|
||||
{0x3812, 0x00},
|
||||
{0x3813, 0x00},
|
||||
{0x3813, 0x01},
|
||||
{0x3814, 0x03},
|
||||
{0x3815, 0x01},
|
||||
{0x3816, 0x00},
|
||||
|
|
|
@ -691,14 +691,14 @@ static int ov9640_probe(struct i2c_client *client,
|
|||
|
||||
priv->gpio_power = devm_gpiod_get(&client->dev, "Camera power",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR_OR_NULL(priv->gpio_power)) {
|
||||
if (IS_ERR(priv->gpio_power)) {
|
||||
ret = PTR_ERR(priv->gpio_power);
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->gpio_reset = devm_gpiod_get(&client->dev, "Camera reset",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR_OR_NULL(priv->gpio_reset)) {
|
||||
if (IS_ERR(priv->gpio_reset)) {
|
||||
ret = PTR_ERR(priv->gpio_reset);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor)
|
|||
return rval;
|
||||
|
||||
/* Wait for 1 ms + one line => 2 ms is likely enough */
|
||||
usleep_range(2000, 2000);
|
||||
usleep_range(2000, 2050);
|
||||
|
||||
/* Restore it */
|
||||
rval = smiapp_write_8(sensor, 0x3205, 0x00);
|
||||
|
|
|
@ -61,7 +61,10 @@ static const u32 mipid02_supported_fmt_codes[] = {
|
|||
MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10,
|
||||
MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SGBRG12_1X12,
|
||||
MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SRGGB12_1X12,
|
||||
MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_BGR888_1X24
|
||||
MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_BGR888_1X24,
|
||||
MEDIA_BUS_FMT_RGB565_2X8_LE, MEDIA_BUS_FMT_RGB565_2X8_BE,
|
||||
MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_UYVY8_2X8,
|
||||
MEDIA_BUS_FMT_JPEG_1X8
|
||||
};
|
||||
|
||||
/* regulator supplies */
|
||||
|
@ -99,6 +102,7 @@ struct mipid02_dev {
|
|||
u8 data_lane1_reg1;
|
||||
u8 mode_reg1;
|
||||
u8 mode_reg2;
|
||||
u8 data_selection_ctrl;
|
||||
u8 data_id_rreg;
|
||||
u8 pix_width_ctrl;
|
||||
u8 pix_width_ctrl_emb;
|
||||
|
@ -128,6 +132,10 @@ static int bpp_from_code(__u32 code)
|
|||
case MEDIA_BUS_FMT_SRGGB12_1X12:
|
||||
return 12;
|
||||
case MEDIA_BUS_FMT_UYVY8_1X16:
|
||||
case MEDIA_BUS_FMT_YUYV8_2X8:
|
||||
case MEDIA_BUS_FMT_UYVY8_2X8:
|
||||
case MEDIA_BUS_FMT_RGB565_2X8_LE:
|
||||
case MEDIA_BUS_FMT_RGB565_2X8_BE:
|
||||
return 16;
|
||||
case MEDIA_BUS_FMT_BGR888_1X24:
|
||||
return 24;
|
||||
|
@ -155,9 +163,14 @@ static u8 data_type_from_code(__u32 code)
|
|||
case MEDIA_BUS_FMT_SRGGB12_1X12:
|
||||
return 0x2c;
|
||||
case MEDIA_BUS_FMT_UYVY8_1X16:
|
||||
case MEDIA_BUS_FMT_YUYV8_2X8:
|
||||
case MEDIA_BUS_FMT_UYVY8_2X8:
|
||||
return 0x1e;
|
||||
case MEDIA_BUS_FMT_BGR888_1X24:
|
||||
return 0x24;
|
||||
case MEDIA_BUS_FMT_RGB565_2X8_LE:
|
||||
case MEDIA_BUS_FMT_RGB565_2X8_BE:
|
||||
return 0x22;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -331,6 +344,25 @@ static int mipid02_detect(struct mipid02_dev *bridge)
|
|||
return mipid02_read_reg(bridge, MIPID02_CLK_LANE_WR_REG1, ®);
|
||||
}
|
||||
|
||||
static u32 mipid02_get_link_freq_from_cid_link_freq(struct mipid02_dev *bridge,
|
||||
struct v4l2_subdev *subdev)
|
||||
{
|
||||
struct v4l2_querymenu qm = {.id = V4L2_CID_LINK_FREQ, };
|
||||
struct v4l2_ctrl *ctrl;
|
||||
int ret;
|
||||
|
||||
ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_LINK_FREQ);
|
||||
if (!ctrl)
|
||||
return 0;
|
||||
qm.index = v4l2_ctrl_g_ctrl(ctrl);
|
||||
|
||||
ret = v4l2_querymenu(subdev->ctrl_handler, &qm);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return qm.value;
|
||||
}
|
||||
|
||||
static u32 mipid02_get_link_freq_from_cid_pixel_rate(struct mipid02_dev *bridge,
|
||||
struct v4l2_subdev *subdev)
|
||||
{
|
||||
|
@ -358,10 +390,14 @@ static int mipid02_configure_from_rx_speed(struct mipid02_dev *bridge)
|
|||
struct v4l2_subdev *subdev = bridge->s_subdev;
|
||||
u32 link_freq;
|
||||
|
||||
link_freq = mipid02_get_link_freq_from_cid_pixel_rate(bridge, subdev);
|
||||
link_freq = mipid02_get_link_freq_from_cid_link_freq(bridge, subdev);
|
||||
if (!link_freq) {
|
||||
dev_err(&client->dev, "Failed to detect link frequency");
|
||||
return -EINVAL;
|
||||
link_freq = mipid02_get_link_freq_from_cid_pixel_rate(bridge,
|
||||
subdev);
|
||||
if (!link_freq) {
|
||||
dev_err(&client->dev, "Failed to get link frequency");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(&client->dev, "detect link_freq = %d Hz", link_freq);
|
||||
|
@ -452,6 +488,7 @@ static int mipid02_configure_from_tx(struct mipid02_dev *bridge)
|
|||
{
|
||||
struct v4l2_fwnode_endpoint *ep = &bridge->tx;
|
||||
|
||||
bridge->r.data_selection_ctrl = SELECTION_MANUAL_WIDTH;
|
||||
bridge->r.pix_width_ctrl = ep->bus.parallel.bus_width;
|
||||
bridge->r.pix_width_ctrl_emb = ep->bus.parallel.bus_width;
|
||||
if (ep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
|
||||
|
@ -467,10 +504,15 @@ static int mipid02_configure_from_code(struct mipid02_dev *bridge)
|
|||
u8 data_type;
|
||||
|
||||
bridge->r.data_id_rreg = 0;
|
||||
data_type = data_type_from_code(bridge->fmt.code);
|
||||
if (!data_type)
|
||||
return -EINVAL;
|
||||
bridge->r.data_id_rreg = data_type;
|
||||
|
||||
if (bridge->fmt.code != MEDIA_BUS_FMT_JPEG_1X8) {
|
||||
bridge->r.data_selection_ctrl |= SELECTION_MANUAL_DATA;
|
||||
|
||||
data_type = data_type_from_code(bridge->fmt.code);
|
||||
if (!data_type)
|
||||
return -EINVAL;
|
||||
bridge->r.data_id_rreg = data_type;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -554,7 +596,7 @@ static int mipid02_stream_enable(struct mipid02_dev *bridge)
|
|||
if (ret)
|
||||
goto error;
|
||||
ret = mipid02_write_reg(bridge, MIPID02_DATA_SELECTION_CTRL,
|
||||
SELECTION_MANUAL_DATA | SELECTION_MANUAL_WIDTH);
|
||||
bridge->r.data_selection_ctrl);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* For the STS-Thompson TDA7432 audio processor chip
|
||||
*
|
||||
|
@ -9,7 +10,7 @@
|
|||
*
|
||||
* Copyright (c) 2000 Eric Sandeen <eric_sandeen@bigfoot.com>
|
||||
* Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org>
|
||||
* This code is placed under the terms of the GNU General Public License
|
||||
*
|
||||
* Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu)
|
||||
* Which was based on tda8425.c by Greg Alexander (c) 1998
|
||||
*
|
||||
|
|
|
@ -934,8 +934,7 @@ static int tw9910_probe(struct i2c_client *client,
|
|||
{
|
||||
struct tw9910_priv *priv;
|
||||
struct tw9910_video_info *info;
|
||||
struct i2c_adapter *adapter =
|
||||
to_i2c_adapter(client->dev.parent);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int ret;
|
||||
|
||||
if (!client->dev.platform_data) {
|
||||
|
|
|
@ -190,12 +190,8 @@ static int mlx90640_setup(struct video_i2c_data *data)
|
|||
unsigned int n, idx;
|
||||
|
||||
for (n = 0; n < data->chip->num_frame_intervals - 1; n++) {
|
||||
if (data->frame_interval.numerator
|
||||
!= data->chip->frame_intervals[n].numerator)
|
||||
continue;
|
||||
|
||||
if (data->frame_interval.denominator
|
||||
== data->chip->frame_intervals[n].denominator)
|
||||
if (V4L2_FRACT_COMPARE(data->frame_interval, ==,
|
||||
data->chip->frame_intervals[n]))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Media controller
|
||||
# Selectable only for webcam/grabbers, as other drivers don't use it
|
||||
#
|
||||
|
||||
config MEDIA_CONTROLLER
|
||||
bool "Media Controller API"
|
||||
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
|
||||
help
|
||||
Enable the media controller API used to query media devices internal
|
||||
topology and configure it dynamically.
|
||||
|
||||
This API is mostly used by camera interfaces in embedded platforms.
|
||||
|
||||
config MEDIA_CONTROLLER_DVB
|
||||
bool "Enable Media controller for DVB (EXPERIMENTAL)"
|
||||
depends on MEDIA_CONTROLLER && DVB_CORE
|
||||
help
|
||||
Enable the media controller API support for DVB.
|
||||
|
||||
This is currently experimental.
|
||||
|
||||
config MEDIA_CONTROLLER_REQUEST_API
|
||||
bool "Enable Media controller Request API (EXPERIMENTAL)"
|
||||
depends on MEDIA_CONTROLLER && STAGING_MEDIA
|
||||
help
|
||||
DO NOT ENABLE THIS OPTION UNLESS YOU KNOW WHAT YOU'RE DOING.
|
||||
|
||||
This option enables the Request API for the Media controller and V4L2
|
||||
interfaces. It is currently needed by a few stateless codec drivers.
|
||||
|
||||
There is currently no intention to provide API or ABI stability for
|
||||
this new API as of yet.
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
mc-objs := mc-device.o mc-devnode.o mc-entity.o \
|
||||
mc-request.o
|
||||
|
||||
ifeq ($(CONFIG_USB),y)
|
||||
mc-objs += mc-dev-allocator.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_MEDIA_SUPPORT) += mc.o
|
|
@ -494,6 +494,7 @@ static long media_device_enum_links32(struct media_device *mdev,
|
|||
{
|
||||
struct media_links_enum links;
|
||||
compat_uptr_t pads_ptr, links_ptr;
|
||||
int ret;
|
||||
|
||||
memset(&links, 0, sizeof(links));
|
||||
|
||||
|
@ -505,7 +506,14 @@ static long media_device_enum_links32(struct media_device *mdev,
|
|||
links.pads = compat_ptr(pads_ptr);
|
||||
links.links = compat_ptr(links_ptr);
|
||||
|
||||
return media_device_enum_links(mdev, &links);
|
||||
ret = media_device_enum_links(mdev, &links);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (copy_to_user(ulinks->reserved, links.reserved,
|
||||
sizeof(ulinks->reserved)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MEDIA_IOC_ENUM_LINKS32 _IOWR('|', 0x02, struct media_links_enum32)
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Handlers for board audio hooks, split from bttv-cards
|
||||
*
|
||||
* Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org>
|
||||
* This code is placed under the terms of the GNU General Public License
|
||||
*/
|
||||
|
||||
#include "bttv-audio-hook.h"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Handlers for board audio hooks, split from bttv-cards
|
||||
*
|
||||
* Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org>
|
||||
|
|
|
@ -2453,7 +2453,6 @@ static int bttv_s_fmt_vid_overlay(struct file *file, void *priv,
|
|||
static int bttv_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct bttv_fh *fh = priv;
|
||||
struct bttv *btv = fh->btv;
|
||||
|
||||
|
@ -2464,17 +2463,17 @@ static int bttv_querycap(struct file *file, void *priv,
|
|||
strscpy(cap->card, btv->video_dev.name, sizeof(cap->card));
|
||||
snprintf(cap->bus_info, sizeof(cap->bus_info),
|
||||
"PCI:%s", pci_name(btv->c.pci));
|
||||
cap->capabilities =
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_DEVICE_CAPS;
|
||||
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
|
||||
if (no_overlay <= 0)
|
||||
cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
|
||||
if (video_is_registered(&btv->vbi_dev))
|
||||
cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
|
||||
if (video_is_registered(&btv->radio_dev))
|
||||
if (video_is_registered(&btv->radio_dev)) {
|
||||
cap->capabilities |= V4L2_CAP_RADIO;
|
||||
if (btv->has_tea575x)
|
||||
cap->capabilities |= V4L2_CAP_HW_FREQ_SEEK;
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to lock here: those vars are initialized during board
|
||||
|
@ -2484,27 +2483,6 @@ static int bttv_querycap(struct file *file, void *priv,
|
|||
cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
|
||||
if (btv->tuner_type != TUNER_ABSENT)
|
||||
cap->capabilities |= V4L2_CAP_TUNER;
|
||||
if (vdev->vfl_type == VFL_TYPE_GRABBER)
|
||||
cap->device_caps = cap->capabilities &
|
||||
(V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_VIDEO_OVERLAY |
|
||||
V4L2_CAP_TUNER);
|
||||
else if (vdev->vfl_type == VFL_TYPE_VBI)
|
||||
cap->device_caps = cap->capabilities &
|
||||
(V4L2_CAP_VBI_CAPTURE |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_TUNER);
|
||||
else {
|
||||
cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
|
||||
if (btv->has_saa6588)
|
||||
cap->device_caps |= V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_RDS_CAPTURE;
|
||||
if (btv->has_tea575x)
|
||||
cap->device_caps |= V4L2_CAP_HW_FREQ_SEEK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3939,6 +3917,12 @@ static int bttv_register_video(struct bttv *btv)
|
|||
|
||||
/* video */
|
||||
vdev_init(btv, &btv->video_dev, &bttv_video_template, "video");
|
||||
btv->video_dev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
||||
if (btv->tuner_type != TUNER_ABSENT)
|
||||
btv->video_dev.device_caps |= V4L2_CAP_TUNER;
|
||||
if (no_overlay <= 0)
|
||||
btv->video_dev.device_caps |= V4L2_CAP_VIDEO_OVERLAY;
|
||||
|
||||
if (video_register_device(&btv->video_dev, VFL_TYPE_GRABBER,
|
||||
video_nr[btv->c.nr]) < 0)
|
||||
|
@ -3953,6 +3937,10 @@ static int bttv_register_video(struct bttv *btv)
|
|||
|
||||
/* vbi */
|
||||
vdev_init(btv, &btv->vbi_dev, &bttv_video_template, "vbi");
|
||||
btv->vbi_dev.device_caps = V4L2_CAP_VBI_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING | V4L2_CAP_TUNER;
|
||||
if (btv->tuner_type != TUNER_ABSENT)
|
||||
btv->vbi_dev.device_caps |= V4L2_CAP_TUNER;
|
||||
|
||||
if (video_register_device(&btv->vbi_dev, VFL_TYPE_VBI,
|
||||
vbi_nr[btv->c.nr]) < 0)
|
||||
|
@ -3964,6 +3952,12 @@ static int bttv_register_video(struct bttv *btv)
|
|||
return 0;
|
||||
/* radio */
|
||||
vdev_init(btv, &btv->radio_dev, &radio_template, "radio");
|
||||
btv->radio_dev.device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER;
|
||||
if (btv->has_saa6588)
|
||||
btv->radio_dev.device_caps |= V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_RDS_CAPTURE;
|
||||
if (btv->has_tea575x)
|
||||
btv->radio_dev.device_caps |= V4L2_CAP_HW_FREQ_SEEK;
|
||||
btv->radio_dev.ctrl_handler = &btv->radio_ctrl_handler;
|
||||
if (video_register_device(&btv->radio_dev, VFL_TYPE_RADIO,
|
||||
radio_nr[btv->c.nr]) < 0)
|
||||
|
|
|
@ -3,7 +3,7 @@ config VIDEO_COBALT
|
|||
tristate "Cisco Cobalt support"
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on PCI_MSI && MTD_COMPLEX_MAPPINGS
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
depends on (GPIOLIB && DRM_I2C_ADV7511=n) || COMPILE_TEST
|
||||
depends on SND
|
||||
depends on MTD
|
||||
select I2C_ALGOBIT
|
||||
|
|
|
@ -483,13 +483,8 @@ static int cobalt_querycap(struct file *file, void *priv_fh,
|
|||
strscpy(vcap->card, "cobalt", sizeof(vcap->card));
|
||||
snprintf(vcap->bus_info, sizeof(vcap->bus_info),
|
||||
"PCIe:%s", pci_name(cobalt->pci_dev));
|
||||
vcap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
||||
if (s->is_output)
|
||||
vcap->device_caps |= V4L2_CAP_VIDEO_OUTPUT;
|
||||
else
|
||||
vcap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
|
||||
vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS |
|
||||
V4L2_CAP_VIDEO_CAPTURE;
|
||||
vcap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_DEVICE_CAPS;
|
||||
if (cobalt->have_hsma_tx)
|
||||
vcap->capabilities |= V4L2_CAP_VIDEO_OUTPUT;
|
||||
return 0;
|
||||
|
@ -1274,6 +1269,11 @@ static int cobalt_node_register(struct cobalt *cobalt, int node)
|
|||
q->lock = &s->lock;
|
||||
q->dev = &cobalt->pci_dev->dev;
|
||||
vdev->queue = q;
|
||||
vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
||||
if (s->is_output)
|
||||
vdev->device_caps |= V4L2_CAP_VIDEO_OUTPUT;
|
||||
else
|
||||
vdev->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
|
||||
|
||||
video_set_drvdata(vdev, s);
|
||||
ret = vb2_queue_init(q);
|
||||
|
|
|
@ -385,16 +385,13 @@ static int cx18_querycap(struct file *file, void *fh,
|
|||
struct v4l2_capability *vcap)
|
||||
{
|
||||
struct cx18_open_id *id = fh2id(fh);
|
||||
struct cx18_stream *s = video_drvdata(file);
|
||||
struct cx18 *cx = id->cx;
|
||||
|
||||
strscpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
|
||||
strscpy(vcap->card, cx->card_name, sizeof(vcap->card));
|
||||
snprintf(vcap->bus_info, sizeof(vcap->bus_info),
|
||||
"PCI:%s", pci_name(cx->pci_dev));
|
||||
vcap->capabilities = cx->v4l2_cap; /* capabilities */
|
||||
vcap->device_caps = s->v4l2_dev_caps; /* device capabilities */
|
||||
vcap->capabilities |= V4L2_CAP_DEVICE_CAPS;
|
||||
vcap->capabilities = cx->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -411,6 +411,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
|
|||
return 0;
|
||||
|
||||
num = s->video_dev.num;
|
||||
s->video_dev.device_caps = s->v4l2_dev_caps; /* device capabilities */
|
||||
/* card number + user defined offset + device offset */
|
||||
if (type != CX18_ENC_STREAM_TYPE_MPG) {
|
||||
struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
|
||||
|
|
|
@ -1324,12 +1324,11 @@ static int vidioc_querycap(struct file *file, void *priv,
|
|||
strscpy(cap->card, cx23885_boards[tsport->dev->board].name,
|
||||
sizeof(cap->card));
|
||||
sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
|
||||
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING;
|
||||
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING | V4L2_CAP_VBI_CAPTURE |
|
||||
V4L2_CAP_AUDIO | V4L2_CAP_DEVICE_CAPS;
|
||||
if (dev->tuner_type != TUNER_ABSENT)
|
||||
cap->device_caps |= V4L2_CAP_TUNER;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_VBI_CAPTURE |
|
||||
V4L2_CAP_AUDIO | V4L2_CAP_DEVICE_CAPS;
|
||||
cap->capabilities |= V4L2_CAP_TUNER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1542,6 +1541,10 @@ int cx23885_417_register(struct cx23885_dev *dev)
|
|||
video_set_drvdata(dev->v4l_device, dev);
|
||||
dev->v4l_device->lock = &dev->lock;
|
||||
dev->v4l_device->queue = q;
|
||||
dev->v4l_device->device_caps = V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
||||
if (dev->tuner_type != TUNER_ABSENT)
|
||||
dev->v4l_device->device_caps |= V4L2_CAP_TUNER;
|
||||
err = video_register_device(dev->v4l_device,
|
||||
VFL_TYPE_GRABBER, -1);
|
||||
if (err < 0) {
|
||||
|
|
|
@ -2647,8 +2647,6 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
|
|||
dev->pci_bus,
|
||||
dev->pci_slot);
|
||||
|
||||
err = -ENODEV;
|
||||
|
||||
/* dvb stuff */
|
||||
/* We have to init the queue for each frontend on a port. */
|
||||
pr_info("%s: cx23885 based dvb card\n", dev->name);
|
||||
|
|
|
@ -627,21 +627,17 @@ static int vidioc_querycap(struct file *file, void *priv,
|
|||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct cx23885_dev *dev = video_drvdata(file);
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
|
||||
strscpy(cap->driver, "cx23885", sizeof(cap->driver));
|
||||
strscpy(cap->card, cx23885_boards[dev->board].name,
|
||||
sizeof(cap->card));
|
||||
sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
|
||||
cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO;
|
||||
cap->capabilities = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE |
|
||||
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
|
||||
V4L2_CAP_DEVICE_CAPS;
|
||||
if (dev->tuner_type != TUNER_ABSENT)
|
||||
cap->device_caps |= V4L2_CAP_TUNER;
|
||||
if (vdev->vfl_type == VFL_TYPE_VBI)
|
||||
cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
|
||||
else
|
||||
cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_VBI_CAPTURE |
|
||||
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_DEVICE_CAPS;
|
||||
cap->capabilities |= V4L2_CAP_TUNER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1306,6 +1302,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
|
|||
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
|
||||
&cx23885_video_template, "video");
|
||||
dev->video_dev->queue = &dev->vb2_vidq;
|
||||
dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE;
|
||||
if (dev->tuner_type != TUNER_ABSENT)
|
||||
dev->video_dev->device_caps |= V4L2_CAP_TUNER;
|
||||
err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
|
||||
video_nr[dev->nr]);
|
||||
if (err < 0) {
|
||||
|
@ -1320,6 +1320,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
|
|||
dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
|
||||
&cx23885_vbi_template, "vbi");
|
||||
dev->vbi_dev->queue = &dev->vb2_vbiq;
|
||||
dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE;
|
||||
if (dev->tuner_type != TUNER_ABSENT)
|
||||
dev->vbi_dev->device_caps |= V4L2_CAP_TUNER;
|
||||
err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
|
||||
vbi_nr[dev->nr]);
|
||||
if (err < 0) {
|
||||
|
|
|
@ -426,18 +426,13 @@ static int cx25821_vidioc_querycap(struct file *file, void *priv,
|
|||
{
|
||||
struct cx25821_channel *chan = video_drvdata(file);
|
||||
struct cx25821_dev *dev = chan->dev;
|
||||
const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
|
||||
const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE;
|
||||
|
||||
strscpy(cap->driver, "cx25821", sizeof(cap->driver));
|
||||
strscpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
|
||||
sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
|
||||
if (chan->id >= VID_CHANNEL_NUM)
|
||||
cap->device_caps = cap_output;
|
||||
else
|
||||
cap->device_caps = cap_input;
|
||||
cap->capabilities = cap_input | cap_output | V4L2_CAP_DEVICE_CAPS;
|
||||
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_DEVICE_CAPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -624,6 +619,8 @@ static const struct video_device cx25821_video_device = {
|
|||
.minor = -1,
|
||||
.ioctl_ops = &video_ioctl_ops,
|
||||
.tvnorms = CX25821_NORMS,
|
||||
.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING,
|
||||
};
|
||||
|
||||
static const struct v4l2_file_operations video_out_fops = {
|
||||
|
@ -657,6 +654,7 @@ static const struct video_device cx25821_video_out_device = {
|
|||
.minor = -1,
|
||||
.ioctl_ops = &video_out_ioctl_ops,
|
||||
.tvnorms = CX25821_NORMS,
|
||||
.device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE,
|
||||
};
|
||||
|
||||
void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
|
||||
|
|
|
@ -95,7 +95,7 @@ MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
|
|||
MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
|
||||
MODULE_AUTHOR("Ricardo Cerqueira");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION(CX88_VERSION);
|
||||
|
||||
MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}");
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue