media updates for v4.13-rc1
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJZXN2xAAoJEAhfPr2O5OEV9jgP/02n4XamK8Y4wZdY7FjyAg66 IMYoz9J6VUWkKRVfGmtifmR5PWBW4XE4t6G3ksVnlMUP4XunEXec2gLmFkVsWSDz gpsK8C1E3RskzeY7dRqbIldoM+oiPYYcMNMQl+WpFs7JZyjlANEbkUSPZvjcUIlP s6U0bnBoFU35q0zoBcamvyuguIxjVceVYfpgXKHYYhPunzcvlJe4wQE1gOsMN1Pc /ncr3KFz5H6WsdcUGXAz/0z0tj6pPUWiUFQwAo0TaefON22tPpdn6J/2srtfA0Xc Vjlkh5DTT96dcTPQgGsYMuMaeB209I4dYtn3aBj/8UCBUjfAo3u9j9mHp0fReT8D CVsQQsAxxj+bHhXlRnCJL7w1X6kFnXnsWD3/EQU4r6zC6adj/7tNFqlkh2d8lL/k QMIUmhHe5bln/aQI52hDKV43AgujlrdCFxmMu9fblc8slMSyfOk6fc/2AuTLTXXX R+j2rp6HRVetlK+6IkmXcFfs3LCgSiLp9qXxYgKrNh1wbqBFb+0yXPnpf3N6pTRH AGSEvGWD5XUVEIuRq10A5XEEdHdgqLBcovEiu7nqoPKNfVVSt9kXnHqPUjlvqw/7 kIFO31Ah/q0XGhyTZLwiOXL34vBxy6VRt8afS+eZ6hhjmxZ97tHJNvnu5mDcVxzF AyMrURPJiEhR0xfkIudo =RtxO -----END PGP SIGNATURE----- Merge tag 'media/v4.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - addition of fwnode support at V4L2 core - addition of a few more SDR formats - new imx driver to support i.MX6 cameras - new driver for Qualcon venus codecs - new I2C sensor drivers: dw9714, max2175, ov13858, ov5640 - new CEC driver: stm32-cec - some improvements to DVB frontend documentation and a few fixups - several driver improvements and fixups * tag 'media/v4.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (361 commits) [media] media: entity: Catch unbalanced media_pipeline_stop calls [media] media/uapi/v4l: clarify cropcap/crop/selection behavior [media] v4l2-ioctl/exynos: fix G/S_SELECTION's type handling [media] vimc: sen: Declare vimc_sen_video_ops as static [media] vimc: sca: Add scaler [media] vimc: deb: Add debayer filter [media] vimc: Subdevices as modules [media] vimc: cap: Support several image formats [media] vimc: sen: Support several image formats [media] vimc: common: Add vimc_colorimetry_clamp [media] vimc: common: Add vimc_link_validate [media] vimc: common: Add vimc_pipeline_s_stream helper [media] vimc: common: Add vimc_ent_sd_* helper [media] vimc: Move common code from the core [media] vimc: sen: Integrate the tpg on the sensor [media] media: i2c: ov772x: Force use of SCCB protocol [media] dvb uapi docs: enums are passed by value, not reference [media] dvb: don't use 'time_t' in event ioctl [media] media: venus: enable building with COMPILE_TEST [media] af9013: refactor power control ...
This commit is contained in:
commit
0b49ce5a40
|
@ -0,0 +1,8 @@
|
|||
Common bindings for HDMI CEC adapters
|
||||
|
||||
- hdmi-phandle: phandle to the HDMI controller.
|
||||
|
||||
- needs-hpd: if present the CEC support is only available when the HPD
|
||||
is high. Some boards only let the CEC pin through if the HPD is high,
|
||||
for example if there is a level converter that uses the HPD to power
|
||||
up or down.
|
|
@ -6,6 +6,8 @@ digital interfaces like MIPI CSI-2 or parallel video.
|
|||
Required Properties :
|
||||
- compatible : value must be one of
|
||||
"adi,adv7180"
|
||||
"adi,adv7180cp"
|
||||
"adi,adv7180st"
|
||||
"adi,adv7182"
|
||||
"adi,adv7280"
|
||||
"adi,adv7280-m"
|
||||
|
@ -15,6 +17,19 @@ Required Properties :
|
|||
"adi,adv7282"
|
||||
"adi,adv7282-m"
|
||||
|
||||
Device nodes of "adi,adv7180cp" and "adi,adv7180st" must contain one
|
||||
'port' child node per device input and output port, in accordance with the
|
||||
video interface bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The port
|
||||
nodes are numbered as follows.
|
||||
|
||||
Port adv7180cp adv7180st
|
||||
-------------------------------------------------------------------
|
||||
Input 0-2 0-5
|
||||
Output 3 6
|
||||
|
||||
The digital output port node must contain at least one endpoint.
|
||||
|
||||
Optional Properties :
|
||||
- powerdown-gpios: reference to the GPIO connected to the powerdown pin,
|
||||
if any.
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
Maxim Integrated MAX2175 RF to Bits tuner
|
||||
-----------------------------------------
|
||||
|
||||
The MAX2175 IC is an advanced analog/digital hybrid-radio receiver with
|
||||
RF to Bits® front-end designed for software-defined radio solutions.
|
||||
|
||||
Required properties:
|
||||
--------------------
|
||||
- compatible: "maxim,max2175" for MAX2175 RF-to-bits tuner.
|
||||
- clocks: clock specifier.
|
||||
- port: child port node corresponding to the I2S output, in accordance with
|
||||
the video interface bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The port
|
||||
node must contain at least one endpoint.
|
||||
|
||||
Optional properties:
|
||||
--------------------
|
||||
- maxim,master : phandle to the master tuner if it is a slave. This
|
||||
is used to define two tuners in diversity mode
|
||||
(1 master, 1 slave). By default each tuner is an
|
||||
individual master.
|
||||
- maxim,refout-load : load capacitance value (in picofarads) on reference
|
||||
output drive level. The possible load values are:
|
||||
0 (default - refout disabled)
|
||||
10
|
||||
20
|
||||
30
|
||||
40
|
||||
60
|
||||
70
|
||||
- maxim,am-hiz-filter : empty property indicates the AM Hi-Z filter is used
|
||||
in this hardware for AM antenna input.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
Board specific DTS file
|
||||
|
||||
/* Fixed XTAL clock node */
|
||||
maxim_xtal: clock {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <36864000>;
|
||||
};
|
||||
|
||||
/* A tuner device instance under i2c bus */
|
||||
max2175_0: tuner@60 {
|
||||
compatible = "maxim,max2175";
|
||||
reg = <0x60>;
|
||||
clocks = <&maxim_xtal>;
|
||||
maxim,refout-load = <10>;
|
||||
|
||||
port {
|
||||
max2175_0_ep: endpoint {
|
||||
remote-endpoint = <&slave_rx_device>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
* Omnivision OV5640 MIPI CSI-2 sensor
|
||||
|
||||
Required Properties:
|
||||
- compatible: should be "ovti,ov5640"
|
||||
- clocks: reference to the xclk input clock.
|
||||
- clock-names: should be "xclk".
|
||||
- DOVDD-supply: Digital I/O voltage supply, 1.8 volts
|
||||
- AVDD-supply: Analog voltage supply, 2.8 volts
|
||||
- DVDD-supply: Digital core voltage supply, 1.5 volts
|
||||
|
||||
Optional Properties:
|
||||
- reset-gpios: reference to the GPIO connected to the reset pin, if any.
|
||||
This is an active low signal to the OV5640.
|
||||
- powerdown-gpios: reference to the GPIO connected to the powerdown pin,
|
||||
if any. This is an active high signal to the OV5640.
|
||||
|
||||
The device node must contain one 'port' child node for its digital output
|
||||
video port, in accordance with the video interface bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
Example:
|
||||
|
||||
&i2c1 {
|
||||
ov5640: camera@3c {
|
||||
compatible = "ovti,ov5640";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_ov5640>;
|
||||
reg = <0x3c>;
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
clock-names = "xclk";
|
||||
DOVDD-supply = <&vgen4_reg>; /* 1.8v */
|
||||
AVDD-supply = <&vgen3_reg>; /* 2.8v */
|
||||
DVDD-supply = <&vgen2_reg>; /* 1.5v */
|
||||
powerdown-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
ov5640_to_mipi_csi2: endpoint {
|
||||
remote-endpoint = <&mipi_csi2_from_ov5640>;
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
Freescale i.MX Media Video Device
|
||||
=================================
|
||||
|
||||
Video Media Controller node
|
||||
---------------------------
|
||||
|
||||
This is the media controller node for video capture support. It is a
|
||||
virtual device that lists the camera serial interface nodes that the
|
||||
media device will control.
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,imx-capture-subsystem";
|
||||
- ports : Should contain a list of phandles pointing to camera
|
||||
sensor interface ports of IPU devices
|
||||
|
||||
example:
|
||||
|
||||
capture-subsystem {
|
||||
compatible = "fsl,imx-capture-subsystem";
|
||||
ports = <&ipu1_csi0>, <&ipu1_csi1>;
|
||||
};
|
||||
|
||||
|
||||
mipi_csi2 node
|
||||
--------------
|
||||
|
||||
This is the device node for the MIPI CSI-2 Receiver core in the i.MX
|
||||
SoC. This is a Synopsys Designware MIPI CSI-2 host controller core
|
||||
combined with a D-PHY core mixed into the same register block. In
|
||||
addition this device consists of an i.MX-specific "CSI2IPU gasket"
|
||||
glue logic, also controlled from the same register block. The CSI2IPU
|
||||
gasket demultiplexes the four virtual channel streams from the host
|
||||
controller's 32-bit output image bus onto four 16-bit parallel busses
|
||||
to the i.MX IPU CSIs.
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,imx6-mipi-csi2";
|
||||
- reg : physical base address and length of the register set;
|
||||
- clocks : the MIPI CSI-2 receiver requires three clocks: hsi_tx
|
||||
(the D-PHY clock), video_27m (D-PHY PLL reference
|
||||
clock), and eim_podf;
|
||||
- clock-names : must contain "dphy", "ref", "pix";
|
||||
- port@* : five port nodes must exist, containing endpoints
|
||||
connecting to the source and sink devices according to
|
||||
of_graph bindings. The first port is an input port,
|
||||
connecting with a MIPI CSI-2 source, and ports 1
|
||||
through 4 are output ports connecting with parallel
|
||||
bus sink endpoint nodes and correspond to the four
|
||||
MIPI CSI-2 virtual channel outputs.
|
||||
|
||||
Optional properties:
|
||||
- interrupts : must contain two level-triggered interrupts,
|
||||
in order: 100 and 101;
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Media Data Path is used for scaling and color space conversion.
|
||||
|
||||
Required properties (controller (parent) node):
|
||||
Required properties (controller node):
|
||||
- compatible: "mediatek,mt8173-mdp"
|
||||
- mediatek,vpu: the node of video processor unit, see
|
||||
Documentation/devicetree/bindings/media/mediatek-vpu.txt for details.
|
||||
|
@ -32,21 +32,16 @@ Required properties (DMA function blocks, child node):
|
|||
for details.
|
||||
|
||||
Example:
|
||||
mdp {
|
||||
compatible = "mediatek,mt8173-mdp";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
mediatek,vpu = <&vpu>;
|
||||
|
||||
mdp_rdma0: rdma@14001000 {
|
||||
compatible = "mediatek,mt8173-mdp-rdma";
|
||||
"mediatek,mt8173-mdp";
|
||||
reg = <0 0x14001000 0 0x1000>;
|
||||
clocks = <&mmsys CLK_MM_MDP_RDMA0>,
|
||||
<&mmsys CLK_MM_MUTEX_32K>;
|
||||
power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
|
||||
iommus = <&iommu M4U_PORT_MDP_RDMA0>;
|
||||
mediatek,larb = <&larb0>;
|
||||
mediatek,vpu = <&vpu>;
|
||||
};
|
||||
|
||||
mdp_rdma1: rdma@14002000 {
|
||||
|
@ -106,4 +101,3 @@ mdp {
|
|||
iommus = <&iommu M4U_PORT_MDP_WROT1>;
|
||||
mediatek,larb = <&larb4>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
* Qualcomm Venus video encoder/decoder accelerators
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: Value should contain one of:
|
||||
- "qcom,msm8916-venus"
|
||||
- "qcom,msm8996-venus"
|
||||
- reg:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Register base address and length of the register map.
|
||||
- interrupts:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Should contain interrupt line number.
|
||||
- clocks:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A List of phandle and clock specifier pairs as listed
|
||||
in clock-names property.
|
||||
- clock-names:
|
||||
Usage: required for msm8916
|
||||
Value type: <stringlist>
|
||||
Definition: Should contain the following entries:
|
||||
- "core" Core video accelerator clock
|
||||
- "iface" Video accelerator AHB clock
|
||||
- "bus" Video accelerator AXI clock
|
||||
- clock-names:
|
||||
Usage: required for msm8996
|
||||
Value type: <stringlist>
|
||||
Definition: Should contain the following entries:
|
||||
- "core" Core video accelerator clock
|
||||
- "iface" Video accelerator AHB clock
|
||||
- "bus" Video accelerator AXI clock
|
||||
- "mbus" Video MAXI clock
|
||||
- power-domains:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A phandle and power domain specifier pairs to the
|
||||
power domain which is responsible for collapsing
|
||||
and restoring power to the peripheral.
|
||||
- iommus:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A list of phandle and IOMMU specifier pairs.
|
||||
- memory-region:
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: reference to the reserved-memory for the firmware
|
||||
memory region.
|
||||
|
||||
* Subnodes
|
||||
The Venus video-codec node must contain two subnodes representing
|
||||
video-decoder and video-encoder.
|
||||
|
||||
Every of video-encoder or video-decoder subnode should have:
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: Value should contain "venus-decoder" or "venus-encoder"
|
||||
- clocks:
|
||||
Usage: required for msm8996
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A List of phandle and clock specifier pairs as listed
|
||||
in clock-names property.
|
||||
- clock-names:
|
||||
Usage: required for msm8996
|
||||
Value type: <stringlist>
|
||||
Definition: Should contain the following entries:
|
||||
- "core" Subcore video accelerator clock
|
||||
|
||||
- power-domains:
|
||||
Usage: required for msm8996
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: A phandle and power domain specifier pairs to the
|
||||
power domain which is responsible for collapsing
|
||||
and restoring power to the subcore.
|
||||
|
||||
* An Example
|
||||
video-codec@1d00000 {
|
||||
compatible = "qcom,msm8916-venus";
|
||||
reg = <0x01d00000 0xff000>;
|
||||
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>,
|
||||
<&gcc GCC_VENUS0_AHB_CLK>,
|
||||
<&gcc GCC_VENUS0_AXI_CLK>;
|
||||
clock-names = "core", "iface", "bus";
|
||||
power-domains = <&gcc VENUS_GDSC>;
|
||||
iommus = <&apps_iommu 5>;
|
||||
memory-region = <&venus_mem>;
|
||||
|
||||
video-decoder {
|
||||
compatible = "venus-decoder";
|
||||
clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
|
||||
clock-names = "core";
|
||||
power-domains = <&mmcc VENUS_CORE0_GDSC>;
|
||||
};
|
||||
|
||||
video-encoder {
|
||||
compatible = "venus-encoder";
|
||||
clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
|
||||
clock-names = "core";
|
||||
power-domains = <&mmcc VENUS_CORE1_GDSC>;
|
||||
};
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
Renesas RCar Video Input driver (rcar_vin)
|
||||
------------------------------------------
|
||||
Renesas R-Car Video Input driver (rcar_vin)
|
||||
-------------------------------------------
|
||||
|
||||
The rcar_vin device provides video input capabilities for the Renesas R-Car
|
||||
family of devices. The current blocks are always slaves and suppot one input
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
Renesas R-Car Gen3 Digital Radio Interface controller (DRIF)
|
||||
------------------------------------------------------------
|
||||
|
||||
R-Car Gen3 DRIF is a SPI like receive only slave device. A general
|
||||
representation of DRIF interfacing with a master device is shown below.
|
||||
|
||||
+---------------------+ +---------------------+
|
||||
| |-----SCK------->|CLK |
|
||||
| Master |-----SS-------->|SYNC DRIFn (slave) |
|
||||
| |-----SD0------->|D0 |
|
||||
| |-----SD1------->|D1 |
|
||||
+---------------------+ +---------------------+
|
||||
|
||||
As per datasheet, each DRIF channel (drifn) is made up of two internal
|
||||
channels (drifn0 & drifn1). These two internal channels share the common
|
||||
CLK & SYNC. Each internal channel has its own dedicated resources like
|
||||
irq, dma channels, address space & clock. This internal split is not
|
||||
visible to the external master device.
|
||||
|
||||
The device tree model represents each internal channel as a separate node.
|
||||
The internal channels sharing the CLK & SYNC are tied together by their
|
||||
phandles using a property called "renesas,bonding". For the rest of
|
||||
the documentation, unless explicitly stated, the word channel implies an
|
||||
internal channel.
|
||||
|
||||
When both internal channels are enabled they need to be managed together
|
||||
as one (i.e.) they cannot operate alone as independent devices. Out of the
|
||||
two, one of them needs to act as a primary device that accepts common
|
||||
properties of both the internal channels. This channel is identified by a
|
||||
property called "renesas,primary-bond".
|
||||
|
||||
To summarize,
|
||||
- When both the internal channels that are bonded together are enabled,
|
||||
the zeroth channel is selected as primary-bond. This channels accepts
|
||||
properties common to all the members of the bond.
|
||||
- When only one of the bonded channels need to be enabled, the property
|
||||
"renesas,bonding" or "renesas,primary-bond" will have no effect. That
|
||||
enabled channel can act alone as any other independent device.
|
||||
|
||||
Required properties of an internal channel:
|
||||
-------------------------------------------
|
||||
- compatible: "renesas,r8a7795-drif" if DRIF controller is a part of R8A7795 SoC.
|
||||
"renesas,rcar-gen3-drif" for a generic R-Car Gen3 compatible device.
|
||||
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first
|
||||
followed by the generic version.
|
||||
|
||||
- reg: offset and length of that channel.
|
||||
- interrupts: associated with that channel.
|
||||
- clocks: phandle and clock specifier of that channel.
|
||||
- clock-names: clock input name string: "fck".
|
||||
- dmas: phandles to the DMA channels.
|
||||
- dma-names: names of the DMA channel: "rx".
|
||||
- renesas,bonding: phandle to the other channel.
|
||||
|
||||
Optional properties of an internal channel:
|
||||
-------------------------------------------
|
||||
- power-domains: phandle to the respective power domain.
|
||||
|
||||
Required properties of an internal channel when:
|
||||
- It is the only enabled channel of the bond (or)
|
||||
- If it acts as primary among enabled bonds
|
||||
--------------------------------------------------------
|
||||
- pinctrl-0: pin control group to be used for this channel.
|
||||
- pinctrl-names: must be "default".
|
||||
- renesas,primary-bond: empty property indicating the channel acts as primary
|
||||
among the bonded channels.
|
||||
- port: child port node corresponding to the data input, in accordance with
|
||||
the video interface bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt. The port
|
||||
node must contain at least one endpoint.
|
||||
|
||||
Optional endpoint property:
|
||||
---------------------------
|
||||
- sync-active: Indicates sync signal polarity, 0/1 for low/high respectively.
|
||||
This property maps to SYNCAC bit in the hardware manual. The
|
||||
default is 1 (active high).
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
(1) Both internal channels enabled:
|
||||
-----------------------------------
|
||||
|
||||
When interfacing with a third party tuner device with two data pins as shown
|
||||
below.
|
||||
|
||||
+---------------------+ +---------------------+
|
||||
| |-----SCK------->|CLK |
|
||||
| Master |-----SS-------->|SYNC DRIFn (slave) |
|
||||
| |-----SD0------->|D0 |
|
||||
| |-----SD1------->|D1 |
|
||||
+---------------------+ +---------------------+
|
||||
|
||||
drif00: rif@e6f40000 {
|
||||
compatible = "renesas,r8a7795-drif",
|
||||
"renesas,rcar-gen3-drif";
|
||||
reg = <0 0xe6f40000 0 0x64>;
|
||||
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 515>;
|
||||
clock-names = "fck";
|
||||
dmas = <&dmac1 0x20>, <&dmac2 0x20>;
|
||||
dma-names = "rx", "rx";
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
renesas,bonding = <&drif01>;
|
||||
renesas,primary-bond;
|
||||
pinctrl-0 = <&drif0_pins>;
|
||||
pinctrl-names = "default";
|
||||
port {
|
||||
drif0_ep: endpoint {
|
||||
remote-endpoint = <&tuner_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
drif01: rif@e6f50000 {
|
||||
compatible = "renesas,r8a7795-drif",
|
||||
"renesas,rcar-gen3-drif";
|
||||
reg = <0 0xe6f50000 0 0x64>;
|
||||
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 514>;
|
||||
clock-names = "fck";
|
||||
dmas = <&dmac1 0x22>, <&dmac2 0x22>;
|
||||
dma-names = "rx", "rx";
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
renesas,bonding = <&drif00>;
|
||||
};
|
||||
|
||||
|
||||
(2) Internal channel 1 alone is enabled:
|
||||
----------------------------------------
|
||||
|
||||
When interfacing with a third party tuner device with one data pin as shown
|
||||
below.
|
||||
|
||||
+---------------------+ +---------------------+
|
||||
| |-----SCK------->|CLK |
|
||||
| Master |-----SS-------->|SYNC DRIFn (slave) |
|
||||
| | |D0 (unused) |
|
||||
| |-----SD-------->|D1 |
|
||||
+---------------------+ +---------------------+
|
||||
|
||||
drif00: rif@e6f40000 {
|
||||
compatible = "renesas,r8a7795-drif",
|
||||
"renesas,rcar-gen3-drif";
|
||||
reg = <0 0xe6f40000 0 0x64>;
|
||||
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 515>;
|
||||
clock-names = "fck";
|
||||
dmas = <&dmac1 0x20>, <&dmac2 0x20>;
|
||||
dma-names = "rx", "rx";
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
renesas,bonding = <&drif01>;
|
||||
};
|
||||
|
||||
drif01: rif@e6f50000 {
|
||||
compatible = "renesas,r8a7795-drif",
|
||||
"renesas,rcar-gen3-drif";
|
||||
reg = <0 0xe6f50000 0 0x64>;
|
||||
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 514>;
|
||||
clock-names = "fck";
|
||||
dmas = <&dmac1 0x22>, <&dmac2 0x22>;
|
||||
dma-names = "rx", "rx";
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
renesas,bonding = <&drif00>;
|
||||
pinctrl-0 = <&drif0_pins>;
|
||||
pinctrl-names = "default";
|
||||
port {
|
||||
drif0_ep: endpoint {
|
||||
remote-endpoint = <&tuner_ep>;
|
||||
sync-active = <0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -15,7 +15,11 @@ Required properties:
|
|||
- clock-names : from common clock binding: must contain "hdmicec",
|
||||
corresponding to entry in the clocks property.
|
||||
- samsung,syscon-phandle - phandle to the PMU system controller
|
||||
- hdmi-phandle - phandle to the HDMI controller
|
||||
- hdmi-phandle - phandle to the HDMI controller, see also cec.txt.
|
||||
|
||||
Optional:
|
||||
- needs-hpd : if present the CEC support is only available when the HPD
|
||||
is high. See cec.txt for more details.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
STMicroelectronics STM32 CEC driver
|
||||
|
||||
Required properties:
|
||||
- compatible : value should be "st,stm32-cec"
|
||||
- reg : Physical base address of the IP registers and length of memory
|
||||
mapped region.
|
||||
- clocks : from common clock binding: handle to CEC clocks
|
||||
- clock-names : from common clock binding: must be "cec" and "hdmi-cec".
|
||||
- interrupts : CEC interrupt number to the CPU.
|
||||
|
||||
Example for stm32f746:
|
||||
|
||||
cec: cec@40006c00 {
|
||||
compatible = "st,stm32-cec";
|
||||
reg = <0x40006C00 0x400>;
|
||||
interrupts = <94>;
|
||||
clocks = <&rcc 0 STM32F7_APB1_CLOCK(CEC)>, <&rcc 1 CLK_HDMI_CEC>;
|
||||
clock-names = "cec", "hdmi-cec";
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
STMicroelectronics STM32 Digital Camera Memory Interface (DCMI)
|
||||
|
||||
Required properties:
|
||||
- compatible: "st,stm32-dcmi"
|
||||
- reg: physical base address and length of the registers set for the device
|
||||
- interrupts: should contain IRQ line for the DCMI
|
||||
- resets: reference to a reset controller,
|
||||
see Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
|
||||
- clocks: list of clock specifiers, corresponding to entries in
|
||||
the clock-names property
|
||||
- clock-names: must contain "mclk", which is the DCMI peripherial clock
|
||||
- pinctrl: the pincontrol settings to configure muxing properly
|
||||
for pins that connect to DCMI device.
|
||||
See Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt.
|
||||
- dmas: phandle to DMA controller node,
|
||||
see Documentation/devicetree/bindings/dma/stm32-dma.txt
|
||||
- dma-names: must contain "tx", which is the transmit channel from DCMI to DMA
|
||||
|
||||
DCMI supports a single port node with parallel bus. It should contain one
|
||||
'port' child node with child 'endpoint' node. Please refer to the bindings
|
||||
defined in Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
Example:
|
||||
|
||||
dcmi: dcmi@50050000 {
|
||||
compatible = "st,stm32-dcmi";
|
||||
reg = <0x50050000 0x400>;
|
||||
interrupts = <78>;
|
||||
resets = <&rcc STM32F4_AHB2_RESET(DCMI)>;
|
||||
clocks = <&rcc 0 STM32F4_AHB2_CLOCK(DCMI)>;
|
||||
clock-names = "mclk";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&dcmi_pins>;
|
||||
dmas = <&dma2 1 1 0x414 0x3>;
|
||||
dma-names = "tx";
|
||||
port {
|
||||
dcmi_0: endpoint {
|
||||
remote-endpoint = <...>;
|
||||
bus-width = <8>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
pclk-sample = <1>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -9,7 +9,7 @@ Required properties:
|
|||
- pinctrl-names: Contains only one value - "default"
|
||||
- pinctrl-0: Specifies the pin control groups used for CEC hardware.
|
||||
- resets: Reference to a reset controller
|
||||
- hdmi-phandle: Phandle to the HDMI controller
|
||||
- hdmi-phandle: Phandle to the HDMI controller, see also cec.txt.
|
||||
|
||||
Example for STIH407:
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
Video Multiplexer
|
||||
=================
|
||||
|
||||
Video multiplexers allow to select between multiple input ports. Video received
|
||||
on the active input port is passed through to the output port. Muxes described
|
||||
by this binding are controlled by a multiplexer controller that is described by
|
||||
the bindings in Documentation/devicetree/bindings/mux/mux-controller.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "video-mux"
|
||||
- mux-controls : mux controller node to use for operating the mux
|
||||
- #address-cells: should be <1>
|
||||
- #size-cells: should be <0>
|
||||
- port@*: at least three port nodes containing endpoints connecting to the
|
||||
source and sink devices according to of_graph bindings. The last port is
|
||||
the output port, all others are inputs.
|
||||
|
||||
Optionally, #address-cells, #size-cells, and port nodes can be grouped under a
|
||||
ports node as described in Documentation/devicetree/bindings/graph.txt.
|
||||
|
||||
Example:
|
||||
|
||||
mux: mux-controller {
|
||||
compatible = "gpio-mux";
|
||||
#mux-control-cells = <0>;
|
||||
|
||||
mux-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
video-mux {
|
||||
compatible = "video-mux";
|
||||
mux-controls = <&mux>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
mux_in0: endpoint {
|
||||
remote-endpoint = <&video_source0_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
mux_in1: endpoint {
|
||||
remote-endpoint = <&video_source1_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
|
||||
mux_out: endpoint {
|
||||
remote-endpoint = <&capture_interface_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -30,6 +30,7 @@ Electricity
|
|||
-micro-ohms : micro Ohms
|
||||
-microwatt-hours: micro Watt-hours
|
||||
-microvolt : micro volts
|
||||
-picofarads : picofarads
|
||||
|
||||
Temperature
|
||||
----------------------------------------
|
||||
|
|
|
@ -194,6 +194,11 @@ When a transmit finished (successfully or otherwise):
|
|||
void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
|
||||
u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
|
||||
|
||||
or:
|
||||
|
||||
.. c:function::
|
||||
void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
|
||||
|
||||
The status can be one of:
|
||||
|
||||
CEC_TX_STATUS_OK:
|
||||
|
@ -231,6 +236,11 @@ to 1, if the hardware does support retry then either set these counters to
|
|||
0 if the hardware provides no feedback of which errors occurred and how many
|
||||
times, or fill in the correct values as reported by the hardware.
|
||||
|
||||
The cec_transmit_attempt_done() function is a helper for cases where the
|
||||
hardware never retries, so the transmit is always for just a single
|
||||
attempt. It will call cec_transmit_done() in turn, filling in 1 for the
|
||||
count argument corresponding to the status. Or all 0 if the status was OK.
|
||||
|
||||
When a CEC message was received:
|
||||
|
||||
.. c:function::
|
||||
|
@ -306,6 +316,14 @@ then the CEC adapter will be disabled. If you change a valid physical address
|
|||
to another valid physical address, then this function will first set the
|
||||
address to CEC_PHYS_ADDR_INVALID before enabling the new physical address.
|
||||
|
||||
.. c:function::
|
||||
void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
|
||||
const struct edid *edid);
|
||||
|
||||
A helper function that extracts the physical address from the edid struct
|
||||
and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID
|
||||
if the EDID did not contain a physical address or edid was a NULL pointer.
|
||||
|
||||
.. c:function::
|
||||
int cec_s_log_addrs(struct cec_adapter *adap,
|
||||
struct cec_log_addrs *log_addrs, bool block);
|
||||
|
|
|
@ -19,7 +19,7 @@ Video4Linux devices
|
|||
v4l2-mc
|
||||
v4l2-mediabus
|
||||
v4l2-mem2mem
|
||||
v4l2-of
|
||||
v4l2-fwnode
|
||||
v4l2-rect
|
||||
v4l2-tuner
|
||||
v4l2-common
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
V4L2 fwnode kAPI
|
||||
^^^^^^^^^^^^^^^^
|
||||
.. kernel-doc:: include/media/v4l2-fwnode.h
|
|
@ -1,3 +0,0 @@
|
|||
V4L2 Open Firmware kAPI
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. kernel-doc:: include/media/v4l2-of.h
|
|
@ -113,6 +113,14 @@ returns the information to the application. The ioctl never fails.
|
|||
- 0x00000020
|
||||
- The CEC hardware can monitor all messages, not just directed and
|
||||
broadcast messages.
|
||||
* .. _`CEC-CAP-NEEDS-HPD`:
|
||||
|
||||
- ``CEC_CAP_NEEDS_HPD``
|
||||
- 0x00000040
|
||||
- The CEC hardware is only active if the HDMI Hotplug Detect pin is
|
||||
high. This makes it impossible to use CEC to wake up displays that
|
||||
set the HPD pin low when in standby mode, but keep the CEC bus
|
||||
alive.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ FE_DISEQC_SEND_BURST - Sends a 22KHz tone burst for 2x1 mini DiSEqC satellite se
|
|||
Synopsis
|
||||
========
|
||||
|
||||
.. c:function:: int ioctl( int fd, FE_DISEQC_SEND_BURST, enum fe_sec_mini_cmd *tone )
|
||||
.. c:function:: int ioctl( int fd, FE_DISEQC_SEND_BURST, enum fe_sec_mini_cmd tone )
|
||||
:name: FE_DISEQC_SEND_BURST
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ Arguments
|
|||
File descriptor returned by :ref:`open() <frontend_f_open>`.
|
||||
|
||||
``tone``
|
||||
pointer to enum :c:type:`fe_sec_mini_cmd`
|
||||
an integer enumered value described at :c:type:`fe_sec_mini_cmd`
|
||||
|
||||
|
||||
Description
|
||||
|
|
|
@ -15,7 +15,7 @@ FE_SET_TONE - Sets/resets the generation of the continuous 22kHz tone.
|
|||
Synopsis
|
||||
========
|
||||
|
||||
.. c:function:: int ioctl( int fd, FE_SET_TONE, enum fe_sec_tone_mode *tone )
|
||||
.. c:function:: int ioctl( int fd, FE_SET_TONE, enum fe_sec_tone_mode tone )
|
||||
:name: FE_SET_TONE
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ Arguments
|
|||
File descriptor returned by :ref:`open() <frontend_f_open>`.
|
||||
|
||||
``tone``
|
||||
pointer to enum :c:type:`fe_sec_tone_mode`
|
||||
an integer enumered value described at :c:type:`fe_sec_tone_mode`
|
||||
|
||||
|
||||
Description
|
||||
|
|
|
@ -15,7 +15,7 @@ FE_SET_VOLTAGE - Allow setting the DC level sent to the antenna subsystem.
|
|||
Synopsis
|
||||
========
|
||||
|
||||
.. c:function:: int ioctl( int fd, FE_SET_VOLTAGE, enum fe_sec_voltage *voltage )
|
||||
.. c:function:: int ioctl( int fd, FE_SET_VOLTAGE, enum fe_sec_voltage voltage )
|
||||
:name: FE_SET_VOLTAGE
|
||||
|
||||
|
||||
|
@ -26,10 +26,7 @@ Arguments
|
|||
File descriptor returned by :ref:`open() <frontend_f_open>`.
|
||||
|
||||
``voltage``
|
||||
pointer to enum :c:type:`fe_sec_voltage`
|
||||
|
||||
Valid values are described at enum
|
||||
:c:type:`fe_sec_voltage`.
|
||||
an integer enumered value described at :c:type:`fe_sec_voltage`
|
||||
|
||||
|
||||
Description
|
||||
|
|
|
@ -241,7 +241,7 @@ desired arrays with the media graph elements.
|
|||
|
||||
.. c:type:: media_v2_intf_devnode
|
||||
|
||||
.. flat-table:: struct media_v2_interface
|
||||
.. flat-table:: struct media_v2_intf_devnode
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 2 8
|
||||
|
@ -312,7 +312,7 @@ desired arrays with the media graph elements.
|
|||
|
||||
.. c:type:: media_v2_link
|
||||
|
||||
.. flat-table:: struct media_v2_pad
|
||||
.. flat-table:: struct media_v2_link
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 2 8
|
||||
|
@ -324,7 +324,7 @@ desired arrays with the media graph elements.
|
|||
|
||||
- ``id``
|
||||
|
||||
- Unique ID for the pad.
|
||||
- Unique ID for the link.
|
||||
|
||||
- .. row 2
|
||||
|
||||
|
@ -334,7 +334,7 @@ desired arrays with the media graph elements.
|
|||
|
||||
- On pad to pad links: unique ID for the source pad.
|
||||
|
||||
On interface to entity links: unique ID for the interface.
|
||||
On interface to entity links: unique ID for the entity.
|
||||
|
||||
- .. row 3
|
||||
|
||||
|
|
|
@ -299,6 +299,27 @@ Types and flags used to represent the media graph elements
|
|||
received on its sink pad and outputs the statistics data on
|
||||
its source pad.
|
||||
|
||||
- .. row 29
|
||||
|
||||
.. _MEDIA-ENT-F-VID-MUX:
|
||||
|
||||
- ``MEDIA_ENT_F_VID_MUX``
|
||||
|
||||
- Video multiplexer. An entity capable of multiplexing must have at
|
||||
least two sink pads and one source pad, and must pass the video
|
||||
frame(s) received from the active sink pad to the source pad.
|
||||
|
||||
- .. row 30
|
||||
|
||||
.. _MEDIA-ENT-F-VID-IF-BRIDGE:
|
||||
|
||||
- ``MEDIA_ENT_F_VID_IF_BRIDGE``
|
||||
|
||||
- Video interface bridge. A video interface bridge entity must have at
|
||||
least one sink pad and at least one source pad. It receives video
|
||||
frames on its sink pad from an input video bus of one type (HDMI, eDP,
|
||||
MIPI CSI-2, ...), and outputs them on its source pad to an output
|
||||
video bus of another type (eDP, MIPI CSI-2, parallel, ...).
|
||||
|
||||
.. tabularcolumns:: |p{5.5cm}|p{12.0cm}|
|
||||
|
||||
|
|
|
@ -137,6 +137,12 @@ Control IDs
|
|||
``V4L2_CID_GAIN`` ``(integer)``
|
||||
Gain control.
|
||||
|
||||
Primarily used to control gain on e.g. TV tuners but also on
|
||||
webcams. Most devices control only digital gain with this control
|
||||
but on some this could include analogue gain as well. Devices that
|
||||
recognise the difference between digital and analogue gain use
|
||||
controls ``V4L2_CID_DIGITAL_GAIN`` and ``V4L2_CID_ANALOGUE_GAIN``.
|
||||
|
||||
``V4L2_CID_HFLIP`` ``(boolean)``
|
||||
Mirror the picture horizontally.
|
||||
|
||||
|
|
|
@ -2019,7 +2019,7 @@ enum v4l2_exposure_auto_type -
|
|||
dynamically vary the frame rate. By default this feature is disabled
|
||||
(0) and the frame rate must remain constant.
|
||||
|
||||
``V4L2_CID_EXPOSURE_BIAS (integer menu)``
|
||||
``V4L2_CID_AUTO_EXPOSURE_BIAS (integer menu)``
|
||||
Determines the automatic exposure compensation, it is effective only
|
||||
when ``V4L2_CID_EXPOSURE_AUTO`` control is set to ``AUTO``,
|
||||
``SHUTTER_PRIORITY`` or ``APERTURE_PRIORITY``. It is expressed in
|
||||
|
@ -3021,6 +3021,13 @@ Image Process Control IDs
|
|||
The video deinterlacing mode (such as Bob, Weave, ...). The menu items are
|
||||
driver specific and are documented in :ref:`v4l-drivers`.
|
||||
|
||||
``V4L2_CID_DIGITAL_GAIN (integer)``
|
||||
Digital gain is the value by which all colour components
|
||||
are multiplied by. Typically the digital gain applied is the
|
||||
control value divided by e.g. 0x100, meaning that to get no
|
||||
digital gain the control value needs to be 0x100. The no-gain
|
||||
configuration is also typically the default.
|
||||
|
||||
|
||||
.. _dv-controls:
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
.. -*- coding: utf-8; mode: rst -*-
|
||||
|
||||
.. _V4L2-SDR-FMT-PCU16BE:
|
||||
|
||||
******************************
|
||||
V4L2_SDR_FMT_PCU16BE ('PC16')
|
||||
******************************
|
||||
|
||||
Planar complex unsigned 16-bit big endian IQ sample
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
This format contains a sequence of complex number samples. Each complex
|
||||
number consist of two parts called In-phase and Quadrature (IQ). Both I
|
||||
and Q are represented as a 16 bit unsigned big endian number stored in
|
||||
32 bit space. The remaining unused bits within the 32 bit space will be
|
||||
padded with 0. I value starts first and Q value starts at an offset
|
||||
equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
|
||||
the 16 bits, bit 15:2 (14 bit) is data and bit 1:0 (2 bit) can be any
|
||||
value.
|
||||
|
||||
**Byte Order.**
|
||||
Each cell is one byte.
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 0
|
||||
|
||||
* - Offset:
|
||||
- Byte B0
|
||||
- Byte B1
|
||||
- Byte B2
|
||||
- Byte B3
|
||||
* - start + 0:
|
||||
- I'\ :sub:`0[13:6]`
|
||||
- I'\ :sub:`0[5:0]; B1[1:0]=pad`
|
||||
- pad
|
||||
- pad
|
||||
* - start + 4:
|
||||
- I'\ :sub:`1[13:6]`
|
||||
- I'\ :sub:`1[5:0]; B1[1:0]=pad`
|
||||
- pad
|
||||
- pad
|
||||
* - ...
|
||||
* - start + offset:
|
||||
- Q'\ :sub:`0[13:6]`
|
||||
- Q'\ :sub:`0[5:0]; B1[1:0]=pad`
|
||||
- pad
|
||||
- pad
|
||||
* - start + offset + 4:
|
||||
- Q'\ :sub:`1[13:6]`
|
||||
- Q'\ :sub:`1[5:0]; B1[1:0]=pad`
|
||||
- pad
|
||||
- pad
|
|
@ -0,0 +1,55 @@
|
|||
.. -*- coding: utf-8; mode: rst -*-
|
||||
|
||||
.. _V4L2-SDR-FMT-PCU18BE:
|
||||
|
||||
******************************
|
||||
V4L2_SDR_FMT_PCU18BE ('PC18')
|
||||
******************************
|
||||
|
||||
Planar complex unsigned 18-bit big endian IQ sample
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
This format contains a sequence of complex number samples. Each complex
|
||||
number consist of two parts called In-phase and Quadrature (IQ). Both I
|
||||
and Q are represented as a 18 bit unsigned big endian number stored in
|
||||
32 bit space. The remaining unused bits within the 32 bit space will be
|
||||
padded with 0. I value starts first and Q value starts at an offset
|
||||
equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
|
||||
the 18 bits, bit 17:2 (16 bit) is data and bit 1:0 (2 bit) can be any
|
||||
value.
|
||||
|
||||
**Byte Order.**
|
||||
Each cell is one byte.
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 0
|
||||
|
||||
* - Offset:
|
||||
- Byte B0
|
||||
- Byte B1
|
||||
- Byte B2
|
||||
- Byte B3
|
||||
* - start + 0:
|
||||
- I'\ :sub:`0[17:10]`
|
||||
- I'\ :sub:`0[9:2]`
|
||||
- I'\ :sub:`0[1:0]; B2[5:0]=pad`
|
||||
- pad
|
||||
* - start + 4:
|
||||
- I'\ :sub:`1[17:10]`
|
||||
- I'\ :sub:`1[9:2]`
|
||||
- I'\ :sub:`1[1:0]; B2[5:0]=pad`
|
||||
- pad
|
||||
* - ...
|
||||
* - start + offset:
|
||||
- Q'\ :sub:`0[17:10]`
|
||||
- Q'\ :sub:`0[9:2]`
|
||||
- Q'\ :sub:`0[1:0]; B2[5:0]=pad`
|
||||
- pad
|
||||
* - start + offset + 4:
|
||||
- Q'\ :sub:`1[17:10]`
|
||||
- Q'\ :sub:`1[9:2]`
|
||||
- Q'\ :sub:`1[1:0]; B2[5:0]=pad`
|
||||
- pad
|
|
@ -0,0 +1,54 @@
|
|||
.. -*- coding: utf-8; mode: rst -*-
|
||||
.. _V4L2-SDR-FMT-PCU20BE:
|
||||
|
||||
******************************
|
||||
V4L2_SDR_FMT_PCU20BE ('PC20')
|
||||
******************************
|
||||
|
||||
Planar complex unsigned 20-bit big endian IQ sample
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
This format contains a sequence of complex number samples. Each complex
|
||||
number consist of two parts called In-phase and Quadrature (IQ). Both I
|
||||
and Q are represented as a 20 bit unsigned big endian number stored in
|
||||
32 bit space. The remaining unused bits within the 32 bit space will be
|
||||
padded with 0. I value starts first and Q value starts at an offset
|
||||
equalling half of the buffer size (i.e.) offset = buffersize/2. Out of
|
||||
the 20 bits, bit 19:2 (18 bit) is data and bit 1:0 (2 bit) can be any
|
||||
value.
|
||||
|
||||
**Byte Order.**
|
||||
Each cell is one byte.
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 0
|
||||
|
||||
* - Offset:
|
||||
- Byte B0
|
||||
- Byte B1
|
||||
- Byte B2
|
||||
- Byte B3
|
||||
* - start + 0:
|
||||
- I'\ :sub:`0[19:12]`
|
||||
- I'\ :sub:`0[11:4]`
|
||||
- I'\ :sub:`0[3:0]; B2[3:0]=pad`
|
||||
- pad
|
||||
* - start + 4:
|
||||
- I'\ :sub:`1[19:12]`
|
||||
- I'\ :sub:`1[11:4]`
|
||||
- I'\ :sub:`1[3:0]; B2[3:0]=pad`
|
||||
- pad
|
||||
* - ...
|
||||
* - start + offset:
|
||||
- Q'\ :sub:`0[19:12]`
|
||||
- Q'\ :sub:`0[11:4]`
|
||||
- Q'\ :sub:`0[3:0]; B2[3:0]=pad`
|
||||
- pad
|
||||
* - start + offset + 4:
|
||||
- Q'\ :sub:`1[19:12]`
|
||||
- Q'\ :sub:`1[11:4]`
|
||||
- Q'\ :sub:`1[3:0]; B2[3:0]=pad`
|
||||
- pad
|
|
@ -17,3 +17,6 @@ These formats are used for :ref:`SDR <sdr>` interface only.
|
|||
pixfmt-sdr-cs08
|
||||
pixfmt-sdr-cs14le
|
||||
pixfmt-sdr-ru12le
|
||||
pixfmt-sdr-pcu16be
|
||||
pixfmt-sdr-pcu18be
|
||||
pixfmt-sdr-pcu20be
|
||||
|
|
|
@ -39,17 +39,10 @@ structure. Drivers fill the rest of the structure. The results are
|
|||
constant except when switching the video standard. Remember this switch
|
||||
can occur implicit when switching the video input or output.
|
||||
|
||||
Do not use the multiplanar buffer types. Use
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and use
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.
|
||||
|
||||
This ioctl must be implemented for video capture or output devices that
|
||||
support cropping and/or scaling and/or have non-square pixels, and for
|
||||
overlay devices.
|
||||
|
||||
|
||||
.. c:type:: v4l2_cropcap
|
||||
|
||||
.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
|
||||
|
@ -62,9 +55,9 @@ overlay devices.
|
|||
* - __u32
|
||||
- ``type``
|
||||
- Type of the data stream, set by the application. Only these types
|
||||
are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``,
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT`` and
|
||||
``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type`.
|
||||
are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
|
||||
``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note above.
|
||||
* - struct :ref:`v4l2_rect <v4l2-rect-crop>`
|
||||
- ``bounds``
|
||||
- Defines the window within capturing or output is possible, this
|
||||
|
@ -90,6 +83,16 @@ overlay devices.
|
|||
``pixelaspect`` to 1/1. Other common values are 54/59 for PAL and
|
||||
SECAM, 11/10 for NTSC sampled according to [:ref:`itu601`].
|
||||
|
||||
.. note::
|
||||
Unfortunately in the case of multiplanar buffer types
|
||||
(``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
|
||||
this API was messed up with regards to how the :c:type:`v4l2_cropcap` ``type`` field
|
||||
should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
|
||||
other drivers only accepted a non-multiplanar buffer type (i.e. without the
|
||||
``_MPLANE`` at the end).
|
||||
|
||||
Starting with kernel 4.13 both variations are allowed.
|
||||
|
||||
|
||||
|
||||
.. _v4l2-rect-crop:
|
||||
|
|
|
@ -45,12 +45,6 @@ and struct :c:type:`v4l2_rect` substructure named ``c`` of a
|
|||
v4l2_crop structure and call the :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctl with a pointer
|
||||
to this structure.
|
||||
|
||||
Do not use the multiplanar buffer types. Use
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and use
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``.
|
||||
|
||||
The driver first adjusts the requested dimensions against hardware
|
||||
limits, i. e. the bounds given by the capture/output window, and it
|
||||
rounds to the closest possible values of horizontal and vertical offset,
|
||||
|
@ -87,14 +81,24 @@ When cropping is not supported then no parameters are changed and
|
|||
* - __u32
|
||||
- ``type``
|
||||
- Type of the data stream, set by the application. Only these types
|
||||
are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``,
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT`` and
|
||||
``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type`.
|
||||
are valid here: ``V4L2_BUF_TYPE_VIDEO_CAPTURE``, ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``,
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT``, ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE`` and
|
||||
``V4L2_BUF_TYPE_VIDEO_OVERLAY``. See :c:type:`v4l2_buf_type` and the note above.
|
||||
* - struct :c:type:`v4l2_rect`
|
||||
- ``c``
|
||||
- Cropping rectangle. The same co-ordinate system as for struct
|
||||
:c:type:`v4l2_cropcap` ``bounds`` is used.
|
||||
|
||||
.. note::
|
||||
Unfortunately in the case of multiplanar buffer types
|
||||
(``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
|
||||
this API was messed up with regards to how the :c:type:`v4l2_crop` ``type`` field
|
||||
should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
|
||||
other drivers only accepted a non-multiplanar buffer type (i.e. without the
|
||||
``_MPLANE`` at the end).
|
||||
|
||||
Starting with kernel 4.13 both variations are allowed.
|
||||
|
||||
|
||||
Return Value
|
||||
============
|
||||
|
|
|
@ -42,11 +42,7 @@ The ioctls are used to query and configure selection rectangles.
|
|||
|
||||
To query the cropping (composing) rectangle set struct
|
||||
:c:type:`v4l2_selection` ``type`` field to the
|
||||
respective buffer type. Do not use the multiplanar buffer types. Use
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and use
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``. The next step is setting the
|
||||
respective buffer type. The next step is setting the
|
||||
value of struct :c:type:`v4l2_selection` ``target``
|
||||
field to ``V4L2_SEL_TGT_CROP`` (``V4L2_SEL_TGT_COMPOSE``). Please refer
|
||||
to table :ref:`v4l2-selections-common` or :ref:`selection-api` for
|
||||
|
@ -64,11 +60,7 @@ pixels.
|
|||
|
||||
To change the cropping (composing) rectangle set the struct
|
||||
:c:type:`v4l2_selection` ``type`` field to the
|
||||
respective buffer type. Do not use multiplanar buffers. Use
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``. Use
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT`` instead of
|
||||
``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``. The next step is setting the
|
||||
respective buffer type. The next step is setting the
|
||||
value of struct :c:type:`v4l2_selection` ``target`` to
|
||||
``V4L2_SEL_TGT_CROP`` (``V4L2_SEL_TGT_COMPOSE``). Please refer to table
|
||||
:ref:`v4l2-selections-common` or :ref:`selection-api` for additional
|
||||
|
@ -169,6 +161,16 @@ Selection targets and flags are documented in
|
|||
- Reserved fields for future use. Drivers and applications must zero
|
||||
this array.
|
||||
|
||||
.. note::
|
||||
Unfortunately in the case of multiplanar buffer types
|
||||
(``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE`` and ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``)
|
||||
this API was messed up with regards to how the :c:type:`v4l2_selection` ``type`` field
|
||||
should be filled in. Some drivers only accepted the ``_MPLANE`` buffer type while
|
||||
other drivers only accepted a non-multiplanar buffer type (i.e. without the
|
||||
``_MPLANE`` at the end).
|
||||
|
||||
Starting with kernel 4.13 both variations are allowed.
|
||||
|
||||
|
||||
Return Value
|
||||
============
|
||||
|
|
|
@ -0,0 +1,614 @@
|
|||
i.MX Video Capture Driver
|
||||
=========================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The Freescale i.MX5/6 contains an Image Processing Unit (IPU), which
|
||||
handles the flow of image frames to and from capture devices and
|
||||
display devices.
|
||||
|
||||
For image capture, the IPU contains the following internal subunits:
|
||||
|
||||
- Image DMA Controller (IDMAC)
|
||||
- Camera Serial Interface (CSI)
|
||||
- Image Converter (IC)
|
||||
- Sensor Multi-FIFO Controller (SMFC)
|
||||
- Image Rotator (IRT)
|
||||
- Video De-Interlacing or Combining Block (VDIC)
|
||||
|
||||
The IDMAC is the DMA controller for transfer of image frames to and from
|
||||
memory. Various dedicated DMA channels exist for both video capture and
|
||||
display paths. During transfer, the IDMAC is also capable of vertical
|
||||
image flip, 8x8 block transfer (see IRT description), pixel component
|
||||
re-ordering (for example UYVY to YUYV) within the same colorspace, and
|
||||
even packed <--> planar conversion. It can also perform a simple
|
||||
de-interlacing by interleaving even and odd lines during transfer
|
||||
(without motion compensation which requires the VDIC).
|
||||
|
||||
The CSI is the backend capture unit that interfaces directly with
|
||||
camera sensors over Parallel, BT.656/1120, and MIPI CSI-2 busses.
|
||||
|
||||
The IC handles color-space conversion, resizing (downscaling and
|
||||
upscaling), horizontal flip, and 90/270 degree rotation operations.
|
||||
|
||||
There are three independent "tasks" within the IC that can carry out
|
||||
conversions concurrently: pre-process encoding, pre-process viewfinder,
|
||||
and post-processing. Within each task, conversions are split into three
|
||||
sections: downsizing section, main section (upsizing, flip, colorspace
|
||||
conversion, and graphics plane combining), and rotation section.
|
||||
|
||||
The IPU time-shares the IC task operations. The time-slice granularity
|
||||
is one burst of eight pixels in the downsizing section, one image line
|
||||
in the main processing section, one image frame in the rotation section.
|
||||
|
||||
The SMFC is composed of four independent FIFOs that each can transfer
|
||||
captured frames from sensors directly to memory concurrently via four
|
||||
IDMAC channels.
|
||||
|
||||
The IRT carries out 90 and 270 degree image rotation operations. The
|
||||
rotation operation is carried out on 8x8 pixel blocks at a time. This
|
||||
operation is supported by the IDMAC which handles the 8x8 block transfer
|
||||
along with block reordering, in coordination with vertical flip.
|
||||
|
||||
The VDIC handles the conversion of interlaced video to progressive, with
|
||||
support for different motion compensation modes (low, medium, and high
|
||||
motion). The deinterlaced output frames from the VDIC can be sent to the
|
||||
IC pre-process viewfinder task for further conversions. The VDIC also
|
||||
contains a Combiner that combines two image planes, with alpha blending
|
||||
and color keying.
|
||||
|
||||
In addition to the IPU internal subunits, there are also two units
|
||||
outside the IPU that are also involved in video capture on i.MX:
|
||||
|
||||
- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
|
||||
interface. This is a Synopsys DesignWare core.
|
||||
- Two video multiplexers for selecting among multiple sensor inputs
|
||||
to send to a CSI.
|
||||
|
||||
For more info, refer to the latest versions of the i.MX5/6 reference
|
||||
manuals [#f1]_ and [#f2]_.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
Some of the features of this driver include:
|
||||
|
||||
- Many different pipelines can be configured via media controller API,
|
||||
that correspond to the hardware video capture pipelines supported in
|
||||
the i.MX.
|
||||
|
||||
- Supports parallel, BT.565, and MIPI CSI-2 interfaces.
|
||||
|
||||
- Concurrent independent streams, by configuring pipelines to multiple
|
||||
video capture interfaces using independent entities.
|
||||
|
||||
- Scaling, color-space conversion, horizontal and vertical flip, and
|
||||
image rotation via IC task subdevs.
|
||||
|
||||
- Many pixel formats supported (RGB, packed and planar YUV, partial
|
||||
planar YUV).
|
||||
|
||||
- The VDIC subdev supports motion compensated de-interlacing, with three
|
||||
motion compensation modes: low, medium, and high motion. Pipelines are
|
||||
defined that allow sending frames to the VDIC subdev directly from the
|
||||
CSI. There is also support in the future for sending frames to the
|
||||
VDIC from memory buffers via a output/mem2mem devices.
|
||||
|
||||
- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
|
||||
problems with the ADV718x video decoders.
|
||||
|
||||
|
||||
Entities
|
||||
--------
|
||||
|
||||
imx6-mipi-csi2
|
||||
--------------
|
||||
|
||||
This is the MIPI CSI-2 receiver entity. It has one sink pad to receive
|
||||
the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has
|
||||
four source pads, corresponding to the four MIPI CSI-2 demuxed virtual
|
||||
channel outputs. Multpiple source pads can be enabled to independently
|
||||
stream from multiple virtual channels.
|
||||
|
||||
This entity actually consists of two sub-blocks. One is the MIPI CSI-2
|
||||
core. This is a Synopsys Designware MIPI CSI-2 core. The other sub-block
|
||||
is a "CSI-2 to IPU gasket". The gasket acts as a demultiplexer of the
|
||||
four virtual channels streams, providing four separate parallel buses
|
||||
containing each virtual channel that are routed to CSIs or video
|
||||
multiplexers as described below.
|
||||
|
||||
On i.MX6 solo/dual-lite, all four virtual channel buses are routed to
|
||||
two video multiplexers. Both CSI0 and CSI1 can receive any virtual
|
||||
channel, as selected by the video multiplexers.
|
||||
|
||||
On i.MX6 Quad, virtual channel 0 is routed to IPU1-CSI0 (after selected
|
||||
by a video mux), virtual channels 1 and 2 are hard-wired to IPU1-CSI1
|
||||
and IPU2-CSI0, respectively, and virtual channel 3 is routed to
|
||||
IPU2-CSI1 (again selected by a video mux).
|
||||
|
||||
ipuX_csiY_mux
|
||||
-------------
|
||||
|
||||
These are the video multiplexers. They have two or more sink pads to
|
||||
select from either camera sensors with a parallel interface, or from
|
||||
MIPI CSI-2 virtual channels from imx6-mipi-csi2 entity. They have a
|
||||
single source pad that routes to a CSI (ipuX_csiY entities).
|
||||
|
||||
On i.MX6 solo/dual-lite, there are two video mux entities. One sits
|
||||
in front of IPU1-CSI0 to select between a parallel sensor and any of
|
||||
the four MIPI CSI-2 virtual channels (a total of five sink pads). The
|
||||
other mux sits in front of IPU1-CSI1, and again has five sink pads to
|
||||
select between a parallel sensor and any of the four MIPI CSI-2 virtual
|
||||
channels.
|
||||
|
||||
On i.MX6 Quad, there are two video mux entities. One sits in front of
|
||||
IPU1-CSI0 to select between a parallel sensor and MIPI CSI-2 virtual
|
||||
channel 0 (two sink pads). The other mux sits in front of IPU2-CSI1 to
|
||||
select between a parallel sensor and MIPI CSI-2 virtual channel 3 (two
|
||||
sink pads).
|
||||
|
||||
ipuX_csiY
|
||||
---------
|
||||
|
||||
These are the CSI entities. They have a single sink pad receiving from
|
||||
either a video mux or from a MIPI CSI-2 virtual channel as described
|
||||
above.
|
||||
|
||||
This entity has two source pads. The first source pad can link directly
|
||||
to the ipuX_vdic entity or the ipuX_ic_prp entity, using hardware links
|
||||
that require no IDMAC memory buffer transfer.
|
||||
|
||||
When the direct source pad is routed to the ipuX_ic_prp entity, frames
|
||||
from the CSI can be processed by one or both of the IC pre-processing
|
||||
tasks.
|
||||
|
||||
When the direct source pad is routed to the ipuX_vdic entity, the VDIC
|
||||
will carry out motion-compensated de-interlace using "high motion" mode
|
||||
(see description of ipuX_vdic entity).
|
||||
|
||||
The second source pad sends video frames directly to memory buffers
|
||||
via the SMFC and an IDMAC channel, bypassing IC pre-processing. This
|
||||
source pad is routed to a capture device node, with a node name of the
|
||||
format "ipuX_csiY capture".
|
||||
|
||||
Note that since the IDMAC source pad makes use of an IDMAC channel, it
|
||||
can do pixel reordering within the same colorspace. For example, the
|
||||
sink pad can take UYVY2X8, but the IDMAC source pad can output YUYV2X8.
|
||||
If the sink pad is receiving YUV, the output at the capture device can
|
||||
also be converted to a planar YUV format such as YUV420.
|
||||
|
||||
It will also perform simple de-interlace without motion compensation,
|
||||
which is activated if the sink pad's field type is an interlaced type,
|
||||
and the IDMAC source pad field type is set to none.
|
||||
|
||||
This subdev can generate the following event when enabling the second
|
||||
IDMAC source pad:
|
||||
|
||||
- V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR
|
||||
|
||||
The user application can subscribe to this event from the ipuX_csiY
|
||||
subdev node. This event is generated by the Frame Interval Monitor
|
||||
(see below for more on the FIM).
|
||||
|
||||
Cropping in ipuX_csiY
|
||||
---------------------
|
||||
|
||||
The CSI supports cropping the incoming raw sensor frames. This is
|
||||
implemented in the ipuX_csiY entities at the sink pad, using the
|
||||
crop selection subdev API.
|
||||
|
||||
The CSI also supports fixed divide-by-two downscaling indepently in
|
||||
width and height. This is implemented in the ipuX_csiY entities at
|
||||
the sink pad, using the compose selection subdev API.
|
||||
|
||||
The output rectangle at the ipuX_csiY source pad is the same as
|
||||
the compose rectangle at the sink pad. So the source pad rectangle
|
||||
cannot be negotiated, it must be set using the compose selection
|
||||
API at sink pad (if /2 downscale is desired, otherwise source pad
|
||||
rectangle is equal to incoming rectangle).
|
||||
|
||||
To give an example of crop and /2 downscale, this will crop a
|
||||
1280x960 input frame to 640x480, and then /2 downscale in both
|
||||
dimensions to 320x240 (assumes ipu1_csi0 is linked to ipu1_csi0_mux):
|
||||
|
||||
media-ctl -V "'ipu1_csi0_mux':2[fmt:UYVY2X8/1280x960]"
|
||||
media-ctl -V "'ipu1_csi0':0[crop:(0,0)/640x480]"
|
||||
media-ctl -V "'ipu1_csi0':0[compose:(0,0)/320x240]"
|
||||
|
||||
Frame Skipping in ipuX_csiY
|
||||
---------------------------
|
||||
|
||||
The CSI supports frame rate decimation, via frame skipping. Frame
|
||||
rate decimation is specified by setting the frame intervals at
|
||||
sink and source pads. The ipuX_csiY entity then applies the best
|
||||
frame skip setting to the CSI to achieve the desired frame rate
|
||||
at the source pad.
|
||||
|
||||
The following example reduces an assumed incoming 60 Hz frame
|
||||
rate by half at the IDMAC output source pad:
|
||||
|
||||
media-ctl -V "'ipu1_csi0':0[fmt:UYVY2X8/640x480@1/60]"
|
||||
media-ctl -V "'ipu1_csi0':2[fmt:UYVY2X8/640x480@1/30]"
|
||||
|
||||
Frame Interval Monitor in ipuX_csiY
|
||||
-----------------------------------
|
||||
|
||||
The adv718x decoders can occasionally send corrupt fields during
|
||||
NTSC/PAL signal re-sync (too little or too many video lines). When
|
||||
this happens, the IPU triggers a mechanism to re-establish vertical
|
||||
sync by adding 1 dummy line every frame, which causes a rolling effect
|
||||
from image to image, and can last a long time before a stable image is
|
||||
recovered. Or sometimes the mechanism doesn't work at all, causing a
|
||||
permanent split image (one frame contains lines from two consecutive
|
||||
captured images).
|
||||
|
||||
From experiment it was found that during image rolling, the frame
|
||||
intervals (elapsed time between two EOF's) drop below the nominal
|
||||
value for the current standard, by about one frame time (60 usec),
|
||||
and remain at that value until rolling stops.
|
||||
|
||||
While the reason for this observation isn't known (the IPU dummy
|
||||
line mechanism should show an increase in the intervals by 1 line
|
||||
time every frame, not a fixed value), we can use it to detect the
|
||||
corrupt fields using a frame interval monitor. If the FIM detects a
|
||||
bad frame interval, the ipuX_csiY subdev will send the event
|
||||
V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR. Userland can register with
|
||||
the FIM event notification on the ipuX_csiY subdev device node.
|
||||
Userland can issue a streaming restart when this event is received
|
||||
to correct the rolling/split image.
|
||||
|
||||
The ipuX_csiY subdev includes custom controls to tweak some dials for
|
||||
FIM. If one of these controls is changed during streaming, the FIM will
|
||||
be reset and will continue at the new settings.
|
||||
|
||||
- V4L2_CID_IMX_FIM_ENABLE
|
||||
|
||||
Enable/disable the FIM.
|
||||
|
||||
- V4L2_CID_IMX_FIM_NUM
|
||||
|
||||
How many frame interval measurements to average before comparing against
|
||||
the nominal frame interval reported by the sensor. This can reduce noise
|
||||
caused by interrupt latency.
|
||||
|
||||
- V4L2_CID_IMX_FIM_TOLERANCE_MIN
|
||||
|
||||
If the averaged intervals fall outside nominal by this amount, in
|
||||
microseconds, the V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR event is sent.
|
||||
|
||||
- V4L2_CID_IMX_FIM_TOLERANCE_MAX
|
||||
|
||||
If any intervals are higher than this value, those samples are
|
||||
discarded and do not enter into the average. This can be used to
|
||||
discard really high interval errors that might be due to interrupt
|
||||
latency from high system load.
|
||||
|
||||
- V4L2_CID_IMX_FIM_NUM_SKIP
|
||||
|
||||
How many frames to skip after a FIM reset or stream restart before
|
||||
FIM begins to average intervals.
|
||||
|
||||
- V4L2_CID_IMX_FIM_ICAP_CHANNEL
|
||||
- V4L2_CID_IMX_FIM_ICAP_EDGE
|
||||
|
||||
These controls will configure an input capture channel as the method
|
||||
for measuring frame intervals. This is superior to the default method
|
||||
of measuring frame intervals via EOF interrupt, since it is not subject
|
||||
to uncertainty errors introduced by interrupt latency.
|
||||
|
||||
Input capture requires hardware support. A VSYNC signal must be routed
|
||||
to one of the i.MX6 input capture channel pads.
|
||||
|
||||
V4L2_CID_IMX_FIM_ICAP_CHANNEL configures which i.MX6 input capture
|
||||
channel to use. This must be 0 or 1.
|
||||
|
||||
V4L2_CID_IMX_FIM_ICAP_EDGE configures which signal edge will trigger
|
||||
input capture events. By default the input capture method is disabled
|
||||
with a value of IRQ_TYPE_NONE. Set this control to IRQ_TYPE_EDGE_RISING,
|
||||
IRQ_TYPE_EDGE_FALLING, or IRQ_TYPE_EDGE_BOTH to enable input capture,
|
||||
triggered on the given signal edge(s).
|
||||
|
||||
When input capture is disabled, frame intervals will be measured via
|
||||
EOF interrupt.
|
||||
|
||||
|
||||
ipuX_vdic
|
||||
---------
|
||||
|
||||
The VDIC carries out motion compensated de-interlacing, with three
|
||||
motion compensation modes: low, medium, and high motion. The mode is
|
||||
specified with the menu control V4L2_CID_DEINTERLACING_MODE. It has
|
||||
two sink pads and a single source pad.
|
||||
|
||||
The direct sink pad receives from an ipuX_csiY direct pad. With this
|
||||
link the VDIC can only operate in high motion mode.
|
||||
|
||||
When the IDMAC sink pad is activated, it receives from an output
|
||||
or mem2mem device node. With this pipeline, it can also operate
|
||||
in low and medium modes, because these modes require receiving
|
||||
frames from memory buffers. Note that an output or mem2mem device
|
||||
is not implemented yet, so this sink pad currently has no links.
|
||||
|
||||
The source pad routes to the IC pre-processing entity ipuX_ic_prp.
|
||||
|
||||
ipuX_ic_prp
|
||||
-----------
|
||||
|
||||
This is the IC pre-processing entity. It acts as a router, routing
|
||||
data from its sink pad to one or both of its source pads.
|
||||
|
||||
It has a single sink pad. The sink pad can receive from the ipuX_csiY
|
||||
direct pad, or from ipuX_vdic.
|
||||
|
||||
This entity has two source pads. One source pad routes to the
|
||||
pre-process encode task entity (ipuX_ic_prpenc), the other to the
|
||||
pre-process viewfinder task entity (ipuX_ic_prpvf). Both source pads
|
||||
can be activated at the same time if the sink pad is receiving from
|
||||
ipuX_csiY. Only the source pad to the pre-process viewfinder task entity
|
||||
can be activated if the sink pad is receiving from ipuX_vdic (frames
|
||||
from the VDIC can only be processed by the pre-process viewfinder task).
|
||||
|
||||
ipuX_ic_prpenc
|
||||
--------------
|
||||
|
||||
This is the IC pre-processing encode entity. It has a single sink
|
||||
pad from ipuX_ic_prp, and a single source pad. The source pad is
|
||||
routed to a capture device node, with a node name of the format
|
||||
"ipuX_ic_prpenc capture".
|
||||
|
||||
This entity performs the IC pre-process encode task operations:
|
||||
color-space conversion, resizing (downscaling and upscaling),
|
||||
horizontal and vertical flip, and 90/270 degree rotation. Flip
|
||||
and rotation are provided via standard V4L2 controls.
|
||||
|
||||
Like the ipuX_csiY IDMAC source, it can also perform simple de-interlace
|
||||
without motion compensation, and pixel reordering.
|
||||
|
||||
ipuX_ic_prpvf
|
||||
-------------
|
||||
|
||||
This is the IC pre-processing viewfinder entity. It has a single sink
|
||||
pad from ipuX_ic_prp, and a single source pad. The source pad is routed
|
||||
to a capture device node, with a node name of the format
|
||||
"ipuX_ic_prpvf capture".
|
||||
|
||||
It is identical in operation to ipuX_ic_prpenc, with the same resizing
|
||||
and CSC operations and flip/rotation controls. It will receive and
|
||||
process de-interlaced frames from the ipuX_vdic if ipuX_ic_prp is
|
||||
receiving from ipuX_vdic.
|
||||
|
||||
Like the ipuX_csiY IDMAC source, it can perform simple de-interlace
|
||||
without motion compensation. However, note that if the ipuX_vdic is
|
||||
included in the pipeline (ipuX_ic_prp is receiving from ipuX_vdic),
|
||||
it's not possible to use simple de-interlace in ipuX_ic_prpvf, since
|
||||
the ipuX_vdic has already carried out de-interlacing (with motion
|
||||
compensation) and therefore the field type output from ipuX_ic_prp can
|
||||
only be none.
|
||||
|
||||
Capture Pipelines
|
||||
-----------------
|
||||
|
||||
The following describe the various use-cases supported by the pipelines.
|
||||
|
||||
The links shown do not include the backend sensor, video mux, or mipi
|
||||
csi-2 receiver links. This depends on the type of sensor interface
|
||||
(parallel or mipi csi-2). So these pipelines begin with:
|
||||
|
||||
sensor -> ipuX_csiY_mux -> ...
|
||||
|
||||
for parallel sensors, or:
|
||||
|
||||
sensor -> imx6-mipi-csi2 -> (ipuX_csiY_mux) -> ...
|
||||
|
||||
for mipi csi-2 sensors. The imx6-mipi-csi2 receiver may need to route
|
||||
to the video mux (ipuX_csiY_mux) before sending to the CSI, depending
|
||||
on the mipi csi-2 virtual channel, hence ipuX_csiY_mux is shown in
|
||||
parenthesis.
|
||||
|
||||
Unprocessed Video Capture:
|
||||
--------------------------
|
||||
|
||||
Send frames directly from sensor to camera device interface node, with
|
||||
no conversions, via ipuX_csiY IDMAC source pad:
|
||||
|
||||
-> ipuX_csiY:2 -> ipuX_csiY capture
|
||||
|
||||
IC Direct Conversions:
|
||||
----------------------
|
||||
|
||||
This pipeline uses the preprocess encode entity to route frames directly
|
||||
from the CSI to the IC, to carry out scaling up to 1024x1024 resolution,
|
||||
CSC, flipping, and image rotation:
|
||||
|
||||
-> ipuX_csiY:1 -> 0:ipuX_ic_prp:1 -> 0:ipuX_ic_prpenc:1 ->
|
||||
ipuX_ic_prpenc capture
|
||||
|
||||
Motion Compensated De-interlace:
|
||||
--------------------------------
|
||||
|
||||
This pipeline routes frames from the CSI direct pad to the VDIC entity to
|
||||
support motion-compensated de-interlacing (high motion mode only),
|
||||
scaling up to 1024x1024, CSC, flip, and rotation:
|
||||
|
||||
-> ipuX_csiY:1 -> 0:ipuX_vdic:2 -> 0:ipuX_ic_prp:2 ->
|
||||
0:ipuX_ic_prpvf:1 -> ipuX_ic_prpvf capture
|
||||
|
||||
|
||||
Usage Notes
|
||||
-----------
|
||||
|
||||
To aid in configuration and for backward compatibility with V4L2
|
||||
applications that access controls only from video device nodes, the
|
||||
capture device interfaces inherit controls from the active entities
|
||||
in the current pipeline, so controls can be accessed either directly
|
||||
from the subdev or from the active capture device interface. For
|
||||
example, the FIM controls are available either from the ipuX_csiY
|
||||
subdevs or from the active capture device.
|
||||
|
||||
The following are specific usage notes for the Sabre* reference
|
||||
boards:
|
||||
|
||||
|
||||
SabreLite with OV5642 and OV5640
|
||||
--------------------------------
|
||||
|
||||
This platform requires the OmniVision OV5642 module with a parallel
|
||||
camera interface, and the OV5640 module with a MIPI CSI-2
|
||||
interface. Both modules are available from Boundary Devices:
|
||||
|
||||
https://boundarydevices.com/product/nit6x_5mp
|
||||
https://boundarydevices.com/product/nit6x_5mp_mipi
|
||||
|
||||
Note that if only one camera module is available, the other sensor
|
||||
node can be disabled in the device tree.
|
||||
|
||||
The OV5642 module is connected to the parallel bus input on the i.MX
|
||||
internal video mux to IPU1 CSI0. It's i2c bus connects to i2c bus 2.
|
||||
|
||||
The MIPI CSI-2 OV5640 module is connected to the i.MX internal MIPI CSI-2
|
||||
receiver, and the four virtual channel outputs from the receiver are
|
||||
routed as follows: vc0 to the IPU1 CSI0 mux, vc1 directly to IPU1 CSI1,
|
||||
vc2 directly to IPU2 CSI0, and vc3 to the IPU2 CSI1 mux. The OV5640 is
|
||||
also connected to i2c bus 2 on the SabreLite, therefore the OV5642 and
|
||||
OV5640 must not share the same i2c slave address.
|
||||
|
||||
The following basic example configures unprocessed video capture
|
||||
pipelines for both sensors. The OV5642 is routed to ipu1_csi0, and
|
||||
the OV5640, transmitting on MIPI CSI-2 virtual channel 1 (which is
|
||||
imx6-mipi-csi2 pad 2), is routed to ipu1_csi1. Both sensors are
|
||||
configured to output 640x480, and the OV5642 outputs YUYV2X8, the
|
||||
OV5640 UYVY2X8:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
# Setup links for OV5642
|
||||
media-ctl -l "'ov5642 1-0042':0 -> 'ipu1_csi0_mux':1[1]"
|
||||
media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
|
||||
media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
|
||||
# Setup links for OV5640
|
||||
media-ctl -l "'ov5640 1-0040':0 -> 'imx6-mipi-csi2':0[1]"
|
||||
media-ctl -l "'imx6-mipi-csi2':2 -> 'ipu1_csi1':0[1]"
|
||||
media-ctl -l "'ipu1_csi1':2 -> 'ipu1_csi1 capture':0[1]"
|
||||
# Configure pads for OV5642 pipeline
|
||||
media-ctl -V "'ov5642 1-0042':0 [fmt:YUYV2X8/640x480 field:none]"
|
||||
media-ctl -V "'ipu1_csi0_mux':2 [fmt:YUYV2X8/640x480 field:none]"
|
||||
media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/640x480 field:none]"
|
||||
# Configure pads for OV5640 pipeline
|
||||
media-ctl -V "'ov5640 1-0040':0 [fmt:UYVY2X8/640x480 field:none]"
|
||||
media-ctl -V "'imx6-mipi-csi2':2 [fmt:UYVY2X8/640x480 field:none]"
|
||||
media-ctl -V "'ipu1_csi1':2 [fmt:AYUV32/640x480 field:none]"
|
||||
|
||||
Streaming can then begin independently on the capture device nodes
|
||||
"ipu1_csi0 capture" and "ipu1_csi1 capture". The v4l2-ctl tool can
|
||||
be used to select any supported YUV pixelformat on the capture device
|
||||
nodes, including planar.
|
||||
|
||||
SabreAuto with ADV7180 decoder
|
||||
------------------------------
|
||||
|
||||
On the SabreAuto, an on-board ADV7180 SD decoder is connected to the
|
||||
parallel bus input on the internal video mux to IPU1 CSI0.
|
||||
|
||||
The following example configures a pipeline to capture from the ADV7180
|
||||
video decoder, assuming NTSC 720x480 input signals, with Motion
|
||||
Compensated de-interlacing. Pad field types assume the adv7180 outputs
|
||||
"interlaced". $outputfmt can be any format supported by the ipu1_ic_prpvf
|
||||
entity at its output pad:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
# Setup links
|
||||
media-ctl -l "'adv7180 3-0021':0 -> 'ipu1_csi0_mux':1[1]"
|
||||
media-ctl -l "'ipu1_csi0_mux':2 -> 'ipu1_csi0':0[1]"
|
||||
media-ctl -l "'ipu1_csi0':1 -> 'ipu1_vdic':0[1]"
|
||||
media-ctl -l "'ipu1_vdic':2 -> 'ipu1_ic_prp':0[1]"
|
||||
media-ctl -l "'ipu1_ic_prp':2 -> 'ipu1_ic_prpvf':0[1]"
|
||||
media-ctl -l "'ipu1_ic_prpvf':1 -> 'ipu1_ic_prpvf capture':0[1]"
|
||||
# Configure pads
|
||||
media-ctl -V "'adv7180 3-0021':0 [fmt:UYVY2X8/720x480]"
|
||||
media-ctl -V "'ipu1_csi0_mux':2 [fmt:UYVY2X8/720x480 field:interlaced]"
|
||||
media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x480 field:interlaced]"
|
||||
media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x480 field:none]"
|
||||
media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x480 field:none]"
|
||||
media-ctl -V "'ipu1_ic_prpvf':1 [fmt:$outputfmt field:none]"
|
||||
|
||||
Streaming can then begin on the capture device node at
|
||||
"ipu1_ic_prpvf capture". The v4l2-ctl tool can be used to select any
|
||||
supported YUV or RGB pixelformat on the capture device node.
|
||||
|
||||
This platform accepts Composite Video analog inputs to the ADV7180 on
|
||||
Ain1 (connector J42).
|
||||
|
||||
SabreSD with MIPI CSI-2 OV5640
|
||||
------------------------------
|
||||
|
||||
Similarly to SabreLite, the SabreSD supports a parallel interface
|
||||
OV5642 module on IPU1 CSI0, and a MIPI CSI-2 OV5640 module. The OV5642
|
||||
connects to i2c bus 1 and the OV5640 to i2c bus 2.
|
||||
|
||||
The device tree for SabreSD includes OF graphs for both the parallel
|
||||
OV5642 and the MIPI CSI-2 OV5640, but as of this writing only the MIPI
|
||||
CSI-2 OV5640 has been tested, so the OV5642 node is currently disabled.
|
||||
The OV5640 module connects to MIPI connector J5 (sorry I don't have the
|
||||
compatible module part number or URL).
|
||||
|
||||
The following example configures a direct conversion pipeline to capture
|
||||
from the OV5640, transmitting on MIPI CSI-2 virtual channel 1. $sensorfmt
|
||||
can be any format supported by the OV5640. $sensordim is the frame
|
||||
dimension part of $sensorfmt (minus the mbus pixel code). $outputfmt can
|
||||
be any format supported by the ipu1_ic_prpenc entity at its output pad:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
# Setup links
|
||||
media-ctl -l "'ov5640 1-003c':0 -> 'imx6-mipi-csi2':0[1]"
|
||||
media-ctl -l "'imx6-mipi-csi2':2 -> 'ipu1_csi1':0[1]"
|
||||
media-ctl -l "'ipu1_csi1':1 -> 'ipu1_ic_prp':0[1]"
|
||||
media-ctl -l "'ipu1_ic_prp':1 -> 'ipu1_ic_prpenc':0[1]"
|
||||
media-ctl -l "'ipu1_ic_prpenc':1 -> 'ipu1_ic_prpenc capture':0[1]"
|
||||
# Configure pads
|
||||
media-ctl -V "'ov5640 1-003c':0 [fmt:$sensorfmt field:none]"
|
||||
media-ctl -V "'imx6-mipi-csi2':2 [fmt:$sensorfmt field:none]"
|
||||
media-ctl -V "'ipu1_csi1':1 [fmt:AYUV32/$sensordim field:none]"
|
||||
media-ctl -V "'ipu1_ic_prp':1 [fmt:AYUV32/$sensordim field:none]"
|
||||
media-ctl -V "'ipu1_ic_prpenc':1 [fmt:$outputfmt field:none]"
|
||||
|
||||
Streaming can then begin on "ipu1_ic_prpenc capture" node. The v4l2-ctl
|
||||
tool can be used to select any supported YUV or RGB pixelformat on the
|
||||
capture device node.
|
||||
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
1. When using 90 or 270 degree rotation control at capture resolutions
|
||||
near the IC resizer limit of 1024x1024, and combined with planar
|
||||
pixel formats (YUV420, YUV422p), frame capture will often fail with
|
||||
no end-of-frame interrupts from the IDMAC channel. To work around
|
||||
this, use lower resolution and/or packed formats (YUYV, RGB3, etc.)
|
||||
when 90 or 270 rotations are needed.
|
||||
|
||||
|
||||
File list
|
||||
---------
|
||||
|
||||
drivers/staging/media/imx/
|
||||
include/media/imx.h
|
||||
include/linux/imx-media.h
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
.. [#f1] http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6DQRM.pdf
|
||||
.. [#f2] http://www.nxp.com/assets/documents/data/en/reference-manuals/IMX6SDLRM.pdf
|
||||
|
||||
|
||||
Authors
|
||||
-------
|
||||
Steve Longerbeam <steve_longerbeam@mentor.com>
|
||||
Philipp Zabel <kernel@pengutronix.de>
|
||||
Russell King <linux@armlinux.org.uk>
|
||||
|
||||
Copyright (C) 2012-2017 Mentor Graphics Inc.
|
|
@ -42,6 +42,7 @@ For more details see the file COPYING in the source distribution of Linux.
|
|||
davinci-vpbe
|
||||
fimc
|
||||
ivtv
|
||||
max2175
|
||||
meye
|
||||
omap3isp
|
||||
omap4_camera
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
Maxim Integrated MAX2175 RF to bits tuner driver
|
||||
================================================
|
||||
|
||||
The MAX2175 driver implements the following driver-specific controls:
|
||||
|
||||
``V4L2_CID_MAX2175_I2S_ENABLE``
|
||||
-------------------------------
|
||||
Enable/Disable I2S output of the tuner. This is a private control
|
||||
that can be accessed only using the subdev interface.
|
||||
Refer to Documentation/media/kapi/v4l2-controls for more details.
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 4
|
||||
|
||||
* - ``(0)``
|
||||
- I2S output is disabled.
|
||||
* - ``(1)``
|
||||
- I2S output is enabled.
|
||||
|
||||
``V4L2_CID_MAX2175_HSLS``
|
||||
-------------------------
|
||||
The high-side/low-side (HSLS) control of the tuner for a given band.
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 4
|
||||
|
||||
* - ``(0)``
|
||||
- The LO frequency position is below the desired frequency.
|
||||
* - ``(1)``
|
||||
- The LO frequency position is above the desired frequency.
|
||||
|
||||
``V4L2_CID_MAX2175_RX_MODE (menu)``
|
||||
-----------------------------------
|
||||
The Rx mode controls a number of preset parameters of the tuner like
|
||||
sample clock (sck), sampling rate etc. These multiple settings are
|
||||
provided under one single label called Rx mode in the datasheet. The
|
||||
list below shows the supported modes with a brief description.
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 4
|
||||
|
||||
* - ``"Europe modes"``
|
||||
* - ``"FM 1.2" (0)``
|
||||
- This configures FM band with a sample rate of 0.512 million
|
||||
samples/sec with a 10.24 MHz sck.
|
||||
* - ``"DAB 1.2" (1)``
|
||||
- This configures VHF band with a sample rate of 2.048 million
|
||||
samples/sec with a 32.768 MHz sck.
|
||||
|
||||
* - ``"North America modes"``
|
||||
* - ``"FM 1.0" (0)``
|
||||
- This configures FM band with a sample rate of 0.7441875 million
|
||||
samples/sec with a 14.88375 MHz sck.
|
||||
* - ``"DAB 1.2" (1)``
|
||||
- This configures FM band with a sample rate of 0.372 million
|
||||
samples/sec with a 7.441875 MHz sck.
|
78
MAINTAINERS
78
MAINTAINERS
|
@ -1802,11 +1802,12 @@ F: arch/arm/plat-samsung/s5p-dev-mfc.c
|
|||
F: drivers/media/platform/s5p-mfc/
|
||||
|
||||
ARM/SAMSUNG S5P SERIES HDMI CEC SUBSYSTEM SUPPORT
|
||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
L: linux-arm-kernel@lists.infradead.org
|
||||
M: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/staging/media/platform/s5p-cec/
|
||||
F: drivers/media/platform/s5p-cec/
|
||||
F: Documentation/devicetree/bindings/media/s5p-cec.txt
|
||||
|
||||
ARM/SAMSUNG S5P SERIES JPEG CODEC SUPPORT
|
||||
M: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
|
@ -3174,6 +3175,7 @@ F: include/media/cec.h
|
|||
F: include/media/cec-notifier.h
|
||||
F: include/uapi/linux/cec.h
|
||||
F: include/uapi/linux/cec-funcs.h
|
||||
F: Documentation/devicetree/bindings/media/cec.txt
|
||||
|
||||
CELL BROADBAND ENGINE ARCHITECTURE
|
||||
M: Arnd Bergmann <arnd@arndb.de>
|
||||
|
@ -4734,6 +4736,13 @@ S: Maintained
|
|||
F: drivers/media/usb/dvb-usb-v2/dvb_usb*
|
||||
F: drivers/media/usb/dvb-usb-v2/usb_urb.c
|
||||
|
||||
DONGWOON DW9714 LENS VOICE COIL DRIVER
|
||||
M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/dw9714.c
|
||||
|
||||
DYNAMIC DEBUG
|
||||
M: Jason Baron <jbaron@akamai.com>
|
||||
S: Maintained
|
||||
|
@ -8101,6 +8110,16 @@ S: Maintained
|
|||
F: Documentation/hwmon/max20751
|
||||
F: drivers/hwmon/max20751.c
|
||||
|
||||
MAX2175 SDR TUNER DRIVER
|
||||
M: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/max2175.txt
|
||||
F: Documentation/media/v4l-drivers/max2175.rst
|
||||
F: drivers/media/i2c/max2175*
|
||||
F: include/uapi/linux/max2175.h
|
||||
|
||||
MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
|
||||
L: linux-hwmon@vger.kernel.org
|
||||
S: Orphan
|
||||
|
@ -8181,6 +8200,27 @@ L: linux-iio@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/iio/dac/cio-dac.c
|
||||
|
||||
MEDIA DRIVERS FOR RENESAS - DRIF
|
||||
M: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/media/renesas,drif.txt
|
||||
F: drivers/media/platform/rcar_drif.c
|
||||
|
||||
MEDIA DRIVERS FOR FREESCALE IMX
|
||||
M: Steve Longerbeam <slongerbeam@gmail.com>
|
||||
M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/imx.txt
|
||||
F: Documentation/media/v4l-drivers/imx.rst
|
||||
F: drivers/staging/media/imx/
|
||||
F: include/linux/imx-media.h
|
||||
F: include/media/imx.h
|
||||
|
||||
MEDIA DRIVERS FOR RENESAS - FCP
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -9548,6 +9588,13 @@ M: Harald Welte <laforge@gnumonks.org>
|
|||
S: Maintained
|
||||
F: drivers/char/pcmcia/cm4040_cs.*
|
||||
|
||||
OMNIVISION OV5640 SENSOR DRIVER
|
||||
M: Steve Longerbeam <slongerbeam@gmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/ov5640.c
|
||||
|
||||
OMNIVISION OV5647 SENSOR DRIVER
|
||||
M: Ramiro Oliveira <roliveir@synopsys.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -9563,6 +9610,13 @@ S: Maintained
|
|||
F: drivers/media/i2c/ov7670.c
|
||||
F: Documentation/devicetree/bindings/media/i2c/ov7670.txt
|
||||
|
||||
OMNIVISION OV13858 SENSOR DRIVER
|
||||
M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/ov13858.c
|
||||
|
||||
ONENAND FLASH DRIVER
|
||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
L: linux-mtd@lists.infradead.org
|
||||
|
@ -10714,6 +10768,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel.g
|
|||
S: Supported
|
||||
F: arch/hexagon/
|
||||
|
||||
QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
|
||||
M: Stanimir Varbanov <stanimir.varbanov@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/platform/qcom/venus/
|
||||
|
||||
QUALCOMM WCN36XX WIRELESS DRIVER
|
||||
M: Eugene Krasnikov <k.eugene.e@gmail.com>
|
||||
L: wcn36xx@lists.infradead.org
|
||||
|
@ -12118,8 +12180,9 @@ F: drivers/leds/leds-net48xx.c
|
|||
|
||||
SOFTLOGIC 6x10 MPEG CODEC
|
||||
M: Bluecherry Maintainers <maintainers@bluecherrydvr.com>
|
||||
M: Anton Sviridenko <anton@corp.bluecherry.net>
|
||||
M: Andrey Utkin <andrey.utkin@corp.bluecherry.net>
|
||||
M: Andrey Utkin <andrey.krieger.utkin@gmail.com>
|
||||
M: Andrey Utkin <andrey_utkin@fastmail.com>
|
||||
M: Ismael Luceno <ismael@iodev.co.uk>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
|
@ -13067,6 +13130,7 @@ F: Documentation/media/v4l-drivers/tm6000*
|
|||
|
||||
TW5864 VIDEO4LINUX DRIVER
|
||||
M: Bluecherry Maintainers <maintainers@bluecherrydvr.com>
|
||||
M: Anton Sviridenko <anton@corp.bluecherry.net>
|
||||
M: Andrey Utkin <andrey.utkin@corp.bluecherry.net>
|
||||
M: Andrey Utkin <andrey_utkin@fastmail.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -13692,6 +13756,12 @@ S: Maintained
|
|||
F: drivers/media/v4l2-core/videobuf2-*
|
||||
F: include/media/videobuf2-*
|
||||
|
||||
VIDEO MULTIPLEXER DRIVER
|
||||
M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/platform/video-mux.c
|
||||
|
||||
VIRTIO AND VHOST VSOCK DRIVER
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
|
|
|
@ -503,8 +503,9 @@ static int aat1290_led_probe(struct platform_device *pdev)
|
|||
aat1290_init_v4l2_flash_config(led, &led_cfg, &v4l2_sd_cfg);
|
||||
|
||||
/* Create V4L2 Flash subdev. */
|
||||
led->v4l2_flash = v4l2_flash_init(dev, sub_node, fled_cdev, NULL,
|
||||
&v4l2_flash_ops, &v4l2_sd_cfg);
|
||||
led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
|
||||
fled_cdev, NULL, &v4l2_flash_ops,
|
||||
&v4l2_sd_cfg);
|
||||
if (IS_ERR(led->v4l2_flash)) {
|
||||
ret = PTR_ERR(led->v4l2_flash);
|
||||
goto error_v4l2_flash_init;
|
||||
|
|
|
@ -930,8 +930,9 @@ static int max77693_register_led(struct max77693_sub_led *sub_led,
|
|||
max77693_init_v4l2_flash_config(sub_led, led_cfg, &v4l2_sd_cfg);
|
||||
|
||||
/* Register in the V4L2 subsystem. */
|
||||
sub_led->v4l2_flash = v4l2_flash_init(dev, sub_node, fled_cdev, NULL,
|
||||
&v4l2_flash_ops, &v4l2_sd_cfg);
|
||||
sub_led->v4l2_flash = v4l2_flash_init(dev, of_fwnode_handle(sub_node),
|
||||
fled_cdev, NULL, &v4l2_flash_ops,
|
||||
&v4l2_sd_cfg);
|
||||
if (IS_ERR(sub_led->v4l2_flash)) {
|
||||
ret = PTR_ERR(sub_led->v4l2_flash);
|
||||
goto err_v4l2_flash_init;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include "cec-priv.h"
|
||||
|
||||
static void cec_fill_msg_report_features(struct cec_adapter *adap,
|
||||
|
@ -366,6 +368,8 @@ int cec_thread_func(void *_adap)
|
|||
* transmit should be canceled.
|
||||
*/
|
||||
err = wait_event_interruptible_timeout(adap->kthread_waitq,
|
||||
(adap->needs_hpd &&
|
||||
(!adap->is_configured && !adap->is_configuring)) ||
|
||||
kthread_should_stop() ||
|
||||
(!adap->transmitting &&
|
||||
!list_empty(&adap->transmit_queue)),
|
||||
|
@ -381,7 +385,9 @@ int cec_thread_func(void *_adap)
|
|||
|
||||
mutex_lock(&adap->lock);
|
||||
|
||||
if (kthread_should_stop()) {
|
||||
if ((adap->needs_hpd &&
|
||||
(!adap->is_configured && !adap->is_configuring)) ||
|
||||
kthread_should_stop()) {
|
||||
cec_flush(adap);
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -392,7 +398,7 @@ int cec_thread_func(void *_adap)
|
|||
* happen and is an indication of a faulty CEC adapter
|
||||
* driver, or the CEC bus is in some weird state.
|
||||
*/
|
||||
dprintk(0, "message %*ph timed out!\n",
|
||||
dprintk(0, "%s: message %*ph timed out!\n", __func__,
|
||||
adap->transmitting->msg.len,
|
||||
adap->transmitting->msg.msg);
|
||||
/* Just give up on this. */
|
||||
|
@ -468,7 +474,7 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
|
|||
struct cec_msg *msg;
|
||||
u64 ts = ktime_get_ns();
|
||||
|
||||
dprintk(2, "cec_transmit_done %02x\n", status);
|
||||
dprintk(2, "%s: status %02x\n", __func__, status);
|
||||
mutex_lock(&adap->lock);
|
||||
data = adap->transmitting;
|
||||
if (!data) {
|
||||
|
@ -477,7 +483,8 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
|
|||
* unplugged while the transmit is ongoing. Ignore this
|
||||
* transmit in that case.
|
||||
*/
|
||||
dprintk(1, "cec_transmit_done without an ongoing transmit!\n");
|
||||
dprintk(1, "%s was called without an ongoing transmit!\n",
|
||||
__func__);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
|
@ -504,6 +511,12 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
|
|||
!(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) {
|
||||
/* Retry this message */
|
||||
data->attempts--;
|
||||
if (msg->timeout)
|
||||
dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n",
|
||||
msg->len, msg->msg, data->attempts, msg->reply);
|
||||
else
|
||||
dprintk(2, "retransmit: %*ph (attempts: %d)\n",
|
||||
msg->len, msg->msg, data->attempts);
|
||||
/* Add the message in front of the transmit queue */
|
||||
list_add(&data->list, &adap->transmit_queue);
|
||||
adap->transmit_queue_sz++;
|
||||
|
@ -544,6 +557,32 @@ unlock:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cec_transmit_done);
|
||||
|
||||
void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status)
|
||||
{
|
||||
switch (status) {
|
||||
case CEC_TX_STATUS_OK:
|
||||
cec_transmit_done(adap, status, 0, 0, 0, 0);
|
||||
return;
|
||||
case CEC_TX_STATUS_ARB_LOST:
|
||||
cec_transmit_done(adap, status, 1, 0, 0, 0);
|
||||
return;
|
||||
case CEC_TX_STATUS_NACK:
|
||||
cec_transmit_done(adap, status, 0, 1, 0, 0);
|
||||
return;
|
||||
case CEC_TX_STATUS_LOW_DRIVE:
|
||||
cec_transmit_done(adap, status, 0, 0, 1, 0);
|
||||
return;
|
||||
case CEC_TX_STATUS_ERROR:
|
||||
cec_transmit_done(adap, status, 0, 0, 0, 1);
|
||||
return;
|
||||
default:
|
||||
/* Should never happen */
|
||||
WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_transmit_attempt_done);
|
||||
|
||||
/*
|
||||
* Called when waiting for a reply times out.
|
||||
*/
|
||||
|
@ -647,7 +686,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
return -EINVAL;
|
||||
}
|
||||
if (!adap->is_configured && !adap->is_configuring) {
|
||||
if (msg->msg[0] != 0xf0) {
|
||||
if (adap->needs_hpd || msg->msg[0] != 0xf0) {
|
||||
dprintk(1, "%s: adapter is unconfigured\n", __func__);
|
||||
return -ENONET;
|
||||
}
|
||||
|
@ -911,7 +950,7 @@ void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg)
|
|||
memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len);
|
||||
|
||||
mutex_lock(&adap->lock);
|
||||
dprintk(2, "cec_received_msg: %*ph\n", msg->len, msg->msg);
|
||||
dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
|
||||
|
||||
/* Check if this message was for us (directed or broadcast). */
|
||||
if (!cec_msg_is_broadcast(msg))
|
||||
|
@ -1112,9 +1151,6 @@ static int cec_config_log_addr(struct cec_adapter *adap,
|
|||
las->log_addr[idx] = log_addr;
|
||||
las->log_addr_mask |= 1 << log_addr;
|
||||
adap->phys_addrs[log_addr] = adap->phys_addr;
|
||||
|
||||
dprintk(2, "claimed addr %d (%d)\n", log_addr,
|
||||
las->primary_device_type[idx]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1162,9 @@ static int cec_config_log_addr(struct cec_adapter *adap,
|
|||
*/
|
||||
static void cec_adap_unconfigure(struct cec_adapter *adap)
|
||||
{
|
||||
WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
|
||||
if (!adap->needs_hpd ||
|
||||
adap->phys_addr != CEC_PHYS_ADDR_INVALID)
|
||||
WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID));
|
||||
adap->log_addrs.log_addr_mask = 0;
|
||||
adap->is_configuring = false;
|
||||
adap->is_configured = false;
|
||||
|
@ -1300,7 +1338,7 @@ configured:
|
|||
/* Report Physical Address */
|
||||
cec_msg_report_physical_addr(&msg, adap->phys_addr,
|
||||
las->primary_device_type[i]);
|
||||
dprintk(2, "config: la %d pa %x.%x.%x.%x\n",
|
||||
dprintk(1, "config: la %d pa %x.%x.%x.%x\n",
|
||||
las->log_addr[i],
|
||||
cec_phys_addr_exp(adap->phys_addr));
|
||||
cec_transmit_msg_fh(adap, &msg, NULL, false);
|
||||
|
@ -1355,6 +1393,8 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
|||
if (phys_addr == adap->phys_addr || adap->devnode.unregistered)
|
||||
return;
|
||||
|
||||
dprintk(1, "new physical address %x.%x.%x.%x\n",
|
||||
cec_phys_addr_exp(phys_addr));
|
||||
if (phys_addr == CEC_PHYS_ADDR_INVALID ||
|
||||
adap->phys_addr != CEC_PHYS_ADDR_INVALID) {
|
||||
adap->phys_addr = CEC_PHYS_ADDR_INVALID;
|
||||
|
@ -1364,7 +1404,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
|||
if (adap->monitor_all_cnt)
|
||||
WARN_ON(call_op(adap, adap_monitor_all_enable, false));
|
||||
mutex_lock(&adap->devnode.lock);
|
||||
if (list_empty(&adap->devnode.fhs))
|
||||
if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
|
||||
WARN_ON(adap->ops->adap_enable(adap, false));
|
||||
mutex_unlock(&adap->devnode.lock);
|
||||
if (phys_addr == CEC_PHYS_ADDR_INVALID)
|
||||
|
@ -1372,7 +1412,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
|||
}
|
||||
|
||||
mutex_lock(&adap->devnode.lock);
|
||||
if (list_empty(&adap->devnode.fhs) &&
|
||||
if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
|
||||
adap->ops->adap_enable(adap, true)) {
|
||||
mutex_unlock(&adap->devnode.lock);
|
||||
return;
|
||||
|
@ -1380,7 +1420,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
|||
|
||||
if (adap->monitor_all_cnt &&
|
||||
call_op(adap, adap_monitor_all_enable, true)) {
|
||||
if (list_empty(&adap->devnode.fhs))
|
||||
if (adap->needs_hpd || list_empty(&adap->devnode.fhs))
|
||||
WARN_ON(adap->ops->adap_enable(adap, false));
|
||||
mutex_unlock(&adap->devnode.lock);
|
||||
return;
|
||||
|
@ -1404,6 +1444,18 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(cec_s_phys_addr);
|
||||
|
||||
void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
|
||||
const struct edid *edid)
|
||||
{
|
||||
u16 pa = CEC_PHYS_ADDR_INVALID;
|
||||
|
||||
if (edid && edid->extensions)
|
||||
pa = cec_get_edid_phys_addr((const u8 *)edid,
|
||||
EDID_LENGTH * (edid->extensions + 1), NULL);
|
||||
cec_s_phys_addr(adap, pa, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
|
||||
|
||||
/*
|
||||
* Called from either the ioctl or a driver to set the logical addresses.
|
||||
*
|
||||
|
@ -1534,12 +1586,12 @@ int __cec_s_log_addrs(struct cec_adapter *adap,
|
|||
if (log_addrs->num_log_addrs == 2) {
|
||||
if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_AUDIOSYSTEM) |
|
||||
(1 << CEC_LOG_ADDR_TYPE_TV)))) {
|
||||
dprintk(1, "Two LAs is only allowed for audiosystem and TV\n");
|
||||
dprintk(1, "two LAs is only allowed for audiosystem and TV\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!(type_mask & ((1 << CEC_LOG_ADDR_TYPE_PLAYBACK) |
|
||||
(1 << CEC_LOG_ADDR_TYPE_RECORD)))) {
|
||||
dprintk(1, "An audiosystem/TV can only be combined with record or playback\n");
|
||||
dprintk(1, "an audiosystem/TV can only be combined with record or playback\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -1653,7 +1705,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
bool from_unregistered = init_laddr == 0xf;
|
||||
struct cec_msg tx_cec_msg = { };
|
||||
|
||||
dprintk(1, "cec_receive_notify: %*ph\n", msg->len, msg->msg);
|
||||
dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
|
||||
|
||||
/* If this is a CDC-Only device, then ignore any non-CDC messages */
|
||||
if (cec_is_cdc_only(&adap->log_addrs) &&
|
||||
|
@ -1722,7 +1774,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
|
|||
|
||||
if (!from_unregistered)
|
||||
adap->phys_addrs[init_laddr] = pa;
|
||||
dprintk(1, "Reported physical address %x.%x.%x.%x for logical address %d\n",
|
||||
dprintk(1, "reported physical address %x.%x.%x.%x for logical address %d\n",
|
||||
cec_phys_addr_exp(pa), init_laddr);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -202,7 +202,8 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
|
|||
err = -EPERM;
|
||||
else if (adap->is_configuring)
|
||||
err = -ENONET;
|
||||
else if (!adap->is_configured && msg.msg[0] != 0xf0)
|
||||
else if (!adap->is_configured &&
|
||||
(adap->needs_hpd || msg.msg[0] != 0xf0))
|
||||
err = -ENONET;
|
||||
else if (cec_is_busy(adap, fh))
|
||||
err = -EBUSY;
|
||||
|
@ -515,6 +516,7 @@ static int cec_open(struct inode *inode, struct file *filp)
|
|||
|
||||
mutex_lock(&devnode->lock);
|
||||
if (list_empty(&devnode->fhs) &&
|
||||
!adap->needs_hpd &&
|
||||
adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
|
||||
err = adap->ops->adap_enable(adap, true);
|
||||
if (err) {
|
||||
|
@ -559,6 +561,7 @@ static int cec_release(struct inode *inode, struct file *filp)
|
|||
mutex_lock(&devnode->lock);
|
||||
list_del(&fh->list);
|
||||
if (list_empty(&devnode->fhs) &&
|
||||
!adap->needs_hpd &&
|
||||
adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
|
||||
WARN_ON(adap->ops->adap_enable(adap, false));
|
||||
}
|
||||
|
|
|
@ -230,6 +230,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
|
|||
adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
|
||||
adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE;
|
||||
adap->capabilities = caps;
|
||||
adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD;
|
||||
adap->available_log_addrs = available_las;
|
||||
adap->sequence = 0;
|
||||
adap->ops = ops;
|
||||
|
|
|
@ -193,8 +193,10 @@ static void dvb_ca_private_put(struct dvb_ca_private *ca)
|
|||
}
|
||||
|
||||
static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
|
||||
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
|
||||
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
|
||||
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
|
||||
u8 *ebuf, int ecount);
|
||||
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
||||
u8 *ebuf, int ecount);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -206,7 +208,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * e
|
|||
* @nlen: Number of bytes in needle.
|
||||
* @return Pointer into haystack needle was found at, or NULL if not found.
|
||||
*/
|
||||
static char *findstr(char * haystack, int hlen, char * needle, int nlen)
|
||||
static char *findstr(char *haystack, int hlen, char *needle, int nlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -390,7 +392,8 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
|
|||
* @return 0 on success, nonzero on error.
|
||||
*/
|
||||
static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
|
||||
int *address, int *tupleType, int *tupleLength, u8 * tuple)
|
||||
int *address, int *tupleType,
|
||||
int *tupleLength, u8 *tuple)
|
||||
{
|
||||
int i;
|
||||
int _tupleType;
|
||||
|
@ -621,7 +624,8 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
|
|||
*
|
||||
* @return Number of bytes read, or < 0 on error
|
||||
*/
|
||||
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount)
|
||||
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
|
||||
u8 *ebuf, int ecount)
|
||||
{
|
||||
int bytes_read;
|
||||
int status;
|
||||
|
@ -745,7 +749,8 @@ exit:
|
|||
*
|
||||
* @return Number of bytes written, or < 0 on error.
|
||||
*/
|
||||
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * buf, int bytes_write)
|
||||
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
||||
u8 *buf, int bytes_write)
|
||||
{
|
||||
int status;
|
||||
int i;
|
||||
|
@ -840,7 +845,6 @@ exit:
|
|||
exitnowrite:
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
|
||||
|
||||
|
||||
|
||||
|
@ -849,7 +853,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
|
|||
|
||||
|
||||
/**
|
||||
* dvb_ca_en50221_camready_irq - A CAM has been removed => shut it down.
|
||||
* dvb_ca_en50221_slot_shutdown - A CAM has been removed => shut it down.
|
||||
*
|
||||
* @ca: CA instance.
|
||||
* @slot: Slot to shut down.
|
||||
|
@ -870,11 +874,10 @@ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
|
|||
/* success */
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
|
||||
|
||||
|
||||
/**
|
||||
* dvb_ca_en50221_camready_irq - A CAMCHANGE IRQ has occurred.
|
||||
* dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
|
||||
*
|
||||
* @ca: CA instance.
|
||||
* @slot: Slot concerned.
|
||||
|
@ -899,7 +902,7 @@ void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int ch
|
|||
atomic_inc(&ca->slot_info[slot].camchange_count);
|
||||
dvb_ca_en50221_thread_wakeup(ca);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
|
||||
EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -919,10 +922,11 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
|
|||
dvb_ca_en50221_thread_wakeup(ca);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
|
||||
|
||||
|
||||
/**
|
||||
* An FR or DA IRQ has occurred.
|
||||
* dvb_ca_en50221_frda_irq - An FR or DA IRQ has occurred.
|
||||
*
|
||||
* @ca: CA instance.
|
||||
* @slot: Slot concerned.
|
||||
|
@ -949,7 +953,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
|
||||
|
||||
|
||||
/* ******************************************************************************** */
|
||||
|
@ -1345,7 +1349,8 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
|
|||
* @return Number of bytes read, or <0 on error.
|
||||
*/
|
||||
static ssize_t dvb_ca_en50221_io_write(struct file *file,
|
||||
const char __user * buf, size_t count, loff_t * ppos)
|
||||
const char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct dvb_ca_private *ca = dvbdev->priv;
|
||||
|
@ -1485,8 +1490,8 @@ nextslot:
|
|||
*
|
||||
* @return Number of bytes read, or <0 on error.
|
||||
*/
|
||||
static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
|
||||
size_t count, loff_t * ppos)
|
||||
static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct dvb_ca_private *ca = dvbdev->priv;
|
||||
|
@ -1664,7 +1669,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
|
|||
*
|
||||
* @return Standard poll mask.
|
||||
*/
|
||||
static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
|
||||
static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct dvb_ca_private *ca = dvbdev->priv;
|
||||
|
|
|
@ -436,6 +436,7 @@ config DVB_TDA10048
|
|||
config DVB_AF9013
|
||||
tristate "Afatech AF9013 demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
select REGMAP
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,29 +23,27 @@
|
|||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
/* AF9013/5 GPIOs (mostly guessed)
|
||||
demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
|
||||
demod#1-gpio#1 - xtal setting (?)
|
||||
demod#1-gpio#3 - tuner#1
|
||||
demod#2-gpio#0 - tuner#2
|
||||
demod#2-gpio#1 - xtal setting (?)
|
||||
*/
|
||||
/*
|
||||
* I2C address: 0x1c, 0x1d
|
||||
*/
|
||||
|
||||
struct af9013_config {
|
||||
/**
|
||||
* struct af9013_platform_data - Platform data for the af9013 driver
|
||||
* @clk: Clock frequency.
|
||||
* @tuner: Used tuner model.
|
||||
* @if_frequency: IF frequency.
|
||||
* @ts_mode: TS mode.
|
||||
* @ts_output_pin: TS output pin.
|
||||
* @spec_inv: Input spectrum inverted.
|
||||
* @api_version: Firmware API version.
|
||||
* @gpio: GPIOs.
|
||||
* @get_dvb_frontend: Get DVB frontend callback.
|
||||
*/
|
||||
struct af9013_platform_data {
|
||||
/*
|
||||
* I2C address
|
||||
*/
|
||||
u8 i2c_addr;
|
||||
|
||||
/*
|
||||
* clock
|
||||
* 20480000, 25000000, 28000000, 28800000
|
||||
*/
|
||||
u32 clock;
|
||||
|
||||
/*
|
||||
* tuner
|
||||
*/
|
||||
u32 clk;
|
||||
#define AF9013_TUNER_MXL5003D 3 /* MaxLinear */
|
||||
#define AF9013_TUNER_MXL5005D 13 /* MaxLinear */
|
||||
#define AF9013_TUNER_MXL5005R 30 /* MaxLinear */
|
||||
|
@ -60,33 +58,14 @@ struct af9013_config {
|
|||
#define AF9013_TUNER_MXL5007T 177 /* MaxLinear */
|
||||
#define AF9013_TUNER_TDA18218 179 /* NXP */
|
||||
u8 tuner;
|
||||
|
||||
/*
|
||||
* IF frequency
|
||||
*/
|
||||
u32 if_frequency;
|
||||
|
||||
/*
|
||||
* TS settings
|
||||
*/
|
||||
#define AF9013_TS_USB 0
|
||||
#define AF9013_TS_PARALLEL 1
|
||||
#define AF9013_TS_SERIAL 2
|
||||
u8 ts_mode:2;
|
||||
|
||||
/*
|
||||
* input spectrum inversion
|
||||
*/
|
||||
#define AF9013_TS_MODE_USB 0
|
||||
#define AF9013_TS_MODE_PARALLEL 1
|
||||
#define AF9013_TS_MODE_SERIAL 2
|
||||
u8 ts_mode;
|
||||
u8 ts_output_pin;
|
||||
bool spec_inv;
|
||||
|
||||
/*
|
||||
* firmware API version
|
||||
*/
|
||||
u8 api_version[4];
|
||||
|
||||
/*
|
||||
* GPIOs
|
||||
*/
|
||||
#define AF9013_GPIO_ON (1 << 0)
|
||||
#define AF9013_GPIO_EN (1 << 1)
|
||||
#define AF9013_GPIO_O (1 << 2)
|
||||
|
@ -96,8 +75,29 @@ struct af9013_config {
|
|||
#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN)
|
||||
#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
|
||||
u8 gpio[4];
|
||||
|
||||
struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
|
||||
|
||||
/* private: For legacy media attach wrapper. Do not set value. */
|
||||
bool attach_in_use;
|
||||
u8 i2c_addr;
|
||||
u32 clock;
|
||||
};
|
||||
|
||||
#define af9013_config af9013_platform_data
|
||||
#define AF9013_TS_USB AF9013_TS_MODE_USB
|
||||
#define AF9013_TS_PARALLEL AF9013_TS_MODE_PARALLEL
|
||||
#define AF9013_TS_SERIAL AF9013_TS_MODE_SERIAL
|
||||
|
||||
/*
|
||||
* AF9013/5 GPIOs (mostly guessed)
|
||||
* demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
|
||||
* demod#1-gpio#1 - xtal setting (?)
|
||||
* demod#1-gpio#3 - tuner#1
|
||||
* demod#2-gpio#0 - tuner#2
|
||||
* demod#2-gpio#1 - xtal setting (?)
|
||||
*/
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DVB_AF9013)
|
||||
extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "dvb_frontend.h"
|
||||
#include "af9013.h"
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define AF9013_FIRMWARE "dvb-fe-af9013.fw"
|
||||
|
||||
|
|
|
@ -234,6 +234,7 @@ int au8522_init(struct dvb_frontend *fe)
|
|||
chip, so that when it gets powered back up it won't think
|
||||
that it is already tuned */
|
||||
state->current_frequency = 0;
|
||||
state->current_modulation = VSB_8;
|
||||
|
||||
au8522_writereg(state, 0xa4, 1 << 5);
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
/* Developer notes:
|
||||
*
|
||||
* VBI support is not yet working
|
||||
* Enough is implemented here for CVBS and S-Video inputs, but the actual
|
||||
* analog demodulator code isn't implemented (not needed for xc5000 since it
|
||||
* has its own demodulator and outputs CVBS)
|
||||
|
@ -179,42 +178,6 @@ static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
|
|||
return container_of(sd, struct au8522_state, sd);
|
||||
}
|
||||
|
||||
static void setup_vbi(struct au8522_state *state, int aud_input)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* These are set to zero regardless of what mode we're in */
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
|
||||
0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
|
||||
0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
|
||||
0x00);
|
||||
|
||||
/* Setup the VBI registers */
|
||||
for (i = 0x30; i < 0x60; i++)
|
||||
au8522_writereg(state, i, 0x40);
|
||||
|
||||
/* For some reason, every register is 0x40 except register 0x44
|
||||
(confirmed via the HVR-950q USB capture) */
|
||||
au8522_writereg(state, 0x44, 0x60);
|
||||
|
||||
/* Enable VBI (we always do this regardless of whether the user is
|
||||
viewing closed caption info) */
|
||||
au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
|
||||
AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
|
||||
|
||||
}
|
||||
|
||||
static void setup_decoder_defaults(struct au8522_state *state, bool is_svideo)
|
||||
{
|
||||
int i;
|
||||
|
@ -317,8 +280,6 @@ static void setup_decoder_defaults(struct au8522_state *state, bool is_svideo)
|
|||
AU8522_TOREGAAGC_REG0E5H_CVBS);
|
||||
au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
|
||||
|
||||
setup_vbi(state, 0);
|
||||
|
||||
if (is_svideo) {
|
||||
/* Despite what the table says, for the HVR-950q we still need
|
||||
to be in CVBS mode for the S-Video input (reason unknown). */
|
||||
|
@ -456,30 +417,29 @@ static void set_audio_input(struct au8522_state *state)
|
|||
lpfilter_coef[i].reg_val[0]);
|
||||
}
|
||||
|
||||
/* Setup audio */
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
|
||||
au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
|
||||
au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
|
||||
msleep(150);
|
||||
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
|
||||
msleep(10);
|
||||
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
|
||||
AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
|
||||
msleep(50);
|
||||
/* Set the volume */
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
|
||||
msleep(80);
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
|
||||
au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
|
||||
|
||||
/* Not sure what this does */
|
||||
au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
|
||||
|
||||
/* Setup the audio mode to stereo DBX */
|
||||
au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
|
||||
msleep(70);
|
||||
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
|
||||
|
||||
/* Start the audio processing module */
|
||||
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
|
||||
|
||||
/* Set the audio frequency to 48 KHz */
|
||||
au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
|
||||
|
||||
/* Set the I2S parameters (WS, LSB, mode, sample rate */
|
||||
au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
|
||||
|
||||
/* Enable the I2S output */
|
||||
au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -663,10 +623,12 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
|
|||
int val = 0;
|
||||
struct au8522_state *state = to_state(sd);
|
||||
u8 lock_status;
|
||||
u8 pll_status;
|
||||
|
||||
/* Interrogate the decoder to see if we are getting a real signal */
|
||||
lock_status = au8522_readreg(state, 0x00);
|
||||
if (lock_status == 0xa2)
|
||||
pll_status = au8522_readreg(state, 0x7e);
|
||||
if ((lock_status == 0xa2) && (pll_status & 0x10))
|
||||
vt->signal = 0xffff;
|
||||
else
|
||||
vt->signal = 0x00;
|
||||
|
|
|
@ -271,9 +271,9 @@ static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
|
|||
return -EINVAL;
|
||||
}
|
||||
dprintk("%s() %s MHz\n", __func__, ifmhz);
|
||||
au8522_writereg(state, 0x80b5, r0b5);
|
||||
au8522_writereg(state, 0x80b6, r0b6);
|
||||
au8522_writereg(state, 0x80b7, r0b7);
|
||||
au8522_writereg(state, 0x00b5, r0b5);
|
||||
au8522_writereg(state, 0x00b6, r0b6);
|
||||
au8522_writereg(state, 0x00b7, r0b7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -283,33 +283,32 @@ static struct {
|
|||
u16 reg;
|
||||
u16 data;
|
||||
} VSB_mod_tab[] = {
|
||||
{ 0x8090, 0x84 },
|
||||
{ 0x4092, 0x11 },
|
||||
{ 0x0090, 0x84 },
|
||||
{ 0x2005, 0x00 },
|
||||
{ 0x8091, 0x80 },
|
||||
{ 0x80a3, 0x0c },
|
||||
{ 0x80a4, 0xe8 },
|
||||
{ 0x8081, 0xc4 },
|
||||
{ 0x80a5, 0x40 },
|
||||
{ 0x80a7, 0x40 },
|
||||
{ 0x80a6, 0x67 },
|
||||
{ 0x8262, 0x20 },
|
||||
{ 0x821c, 0x30 },
|
||||
{ 0x80d8, 0x1a },
|
||||
{ 0x8227, 0xa0 },
|
||||
{ 0x8121, 0xff },
|
||||
{ 0x80a8, 0xf0 },
|
||||
{ 0x80a9, 0x05 },
|
||||
{ 0x80aa, 0x77 },
|
||||
{ 0x80ab, 0xf0 },
|
||||
{ 0x80ac, 0x05 },
|
||||
{ 0x80ad, 0x77 },
|
||||
{ 0x80ae, 0x41 },
|
||||
{ 0x80af, 0x66 },
|
||||
{ 0x821b, 0xcc },
|
||||
{ 0x821d, 0x80 },
|
||||
{ 0x80a4, 0xe8 },
|
||||
{ 0x8231, 0x13 },
|
||||
{ 0x0091, 0x80 },
|
||||
{ 0x00a3, 0x0c },
|
||||
{ 0x00a4, 0xe8 },
|
||||
{ 0x0081, 0xc4 },
|
||||
{ 0x00a5, 0x40 },
|
||||
{ 0x00a7, 0x40 },
|
||||
{ 0x00a6, 0x67 },
|
||||
{ 0x0262, 0x20 },
|
||||
{ 0x021c, 0x30 },
|
||||
{ 0x00d8, 0x1a },
|
||||
{ 0x0227, 0xa0 },
|
||||
{ 0x0121, 0xff },
|
||||
{ 0x00a8, 0xf0 },
|
||||
{ 0x00a9, 0x05 },
|
||||
{ 0x00aa, 0x77 },
|
||||
{ 0x00ab, 0xf0 },
|
||||
{ 0x00ac, 0x05 },
|
||||
{ 0x00ad, 0x77 },
|
||||
{ 0x00ae, 0x41 },
|
||||
{ 0x00af, 0x66 },
|
||||
{ 0x021b, 0xcc },
|
||||
{ 0x021d, 0x80 },
|
||||
{ 0x00a4, 0xe8 },
|
||||
{ 0x0231, 0x13 },
|
||||
};
|
||||
|
||||
/* QAM64 Modulation table */
|
||||
|
@ -396,78 +395,78 @@ static struct {
|
|||
u16 reg;
|
||||
u16 data;
|
||||
} QAM256_mod_tab[] = {
|
||||
{ 0x80a3, 0x09 },
|
||||
{ 0x80a4, 0x00 },
|
||||
{ 0x8081, 0xc4 },
|
||||
{ 0x80a5, 0x40 },
|
||||
{ 0x80aa, 0x77 },
|
||||
{ 0x80ad, 0x77 },
|
||||
{ 0x80a6, 0x67 },
|
||||
{ 0x8262, 0x20 },
|
||||
{ 0x821c, 0x30 },
|
||||
{ 0x80b8, 0x3e },
|
||||
{ 0x80b9, 0xf0 },
|
||||
{ 0x80ba, 0x01 },
|
||||
{ 0x80bb, 0x18 },
|
||||
{ 0x80bc, 0x50 },
|
||||
{ 0x80bd, 0x00 },
|
||||
{ 0x80be, 0xea },
|
||||
{ 0x80bf, 0xef },
|
||||
{ 0x80c0, 0xfc },
|
||||
{ 0x80c1, 0xbd },
|
||||
{ 0x80c2, 0x1f },
|
||||
{ 0x80c3, 0xfc },
|
||||
{ 0x80c4, 0xdd },
|
||||
{ 0x80c5, 0xaf },
|
||||
{ 0x80c6, 0x00 },
|
||||
{ 0x80c7, 0x38 },
|
||||
{ 0x80c8, 0x30 },
|
||||
{ 0x80c9, 0x05 },
|
||||
{ 0x80ca, 0x4a },
|
||||
{ 0x80cb, 0xd0 },
|
||||
{ 0x80cc, 0x01 },
|
||||
{ 0x80cd, 0xd9 },
|
||||
{ 0x80ce, 0x6f },
|
||||
{ 0x80cf, 0xf9 },
|
||||
{ 0x80d0, 0x70 },
|
||||
{ 0x80d1, 0xdf },
|
||||
{ 0x80d2, 0xf7 },
|
||||
{ 0x80d3, 0xc2 },
|
||||
{ 0x80d4, 0xdf },
|
||||
{ 0x80d5, 0x02 },
|
||||
{ 0x80d6, 0x9a },
|
||||
{ 0x80d7, 0xd0 },
|
||||
{ 0x8250, 0x0d },
|
||||
{ 0x8251, 0xcd },
|
||||
{ 0x8252, 0xe0 },
|
||||
{ 0x8253, 0x05 },
|
||||
{ 0x8254, 0xa7 },
|
||||
{ 0x8255, 0xff },
|
||||
{ 0x8256, 0xed },
|
||||
{ 0x8257, 0x5b },
|
||||
{ 0x8258, 0xae },
|
||||
{ 0x8259, 0xe6 },
|
||||
{ 0x825a, 0x3d },
|
||||
{ 0x825b, 0x0f },
|
||||
{ 0x825c, 0x0d },
|
||||
{ 0x825d, 0xea },
|
||||
{ 0x825e, 0xf2 },
|
||||
{ 0x825f, 0x51 },
|
||||
{ 0x8260, 0xf5 },
|
||||
{ 0x8261, 0x06 },
|
||||
{ 0x821a, 0x00 },
|
||||
{ 0x8546, 0x40 },
|
||||
{ 0x8210, 0x26 },
|
||||
{ 0x8211, 0xf6 },
|
||||
{ 0x8212, 0x84 },
|
||||
{ 0x8213, 0x02 },
|
||||
{ 0x8502, 0x01 },
|
||||
{ 0x8121, 0x04 },
|
||||
{ 0x8122, 0x04 },
|
||||
{ 0x852e, 0x10 },
|
||||
{ 0x80a4, 0xca },
|
||||
{ 0x80a7, 0x40 },
|
||||
{ 0x8526, 0x01 },
|
||||
{ 0x00a3, 0x09 },
|
||||
{ 0x00a4, 0x00 },
|
||||
{ 0x0081, 0xc4 },
|
||||
{ 0x00a5, 0x40 },
|
||||
{ 0x00aa, 0x77 },
|
||||
{ 0x00ad, 0x77 },
|
||||
{ 0x00a6, 0x67 },
|
||||
{ 0x0262, 0x20 },
|
||||
{ 0x021c, 0x30 },
|
||||
{ 0x00b8, 0x3e },
|
||||
{ 0x00b9, 0xf0 },
|
||||
{ 0x00ba, 0x01 },
|
||||
{ 0x00bb, 0x18 },
|
||||
{ 0x00bc, 0x50 },
|
||||
{ 0x00bd, 0x00 },
|
||||
{ 0x00be, 0xea },
|
||||
{ 0x00bf, 0xef },
|
||||
{ 0x00c0, 0xfc },
|
||||
{ 0x00c1, 0xbd },
|
||||
{ 0x00c2, 0x1f },
|
||||
{ 0x00c3, 0xfc },
|
||||
{ 0x00c4, 0xdd },
|
||||
{ 0x00c5, 0xaf },
|
||||
{ 0x00c6, 0x00 },
|
||||
{ 0x00c7, 0x38 },
|
||||
{ 0x00c8, 0x30 },
|
||||
{ 0x00c9, 0x05 },
|
||||
{ 0x00ca, 0x4a },
|
||||
{ 0x00cb, 0xd0 },
|
||||
{ 0x00cc, 0x01 },
|
||||
{ 0x00cd, 0xd9 },
|
||||
{ 0x00ce, 0x6f },
|
||||
{ 0x00cf, 0xf9 },
|
||||
{ 0x00d0, 0x70 },
|
||||
{ 0x00d1, 0xdf },
|
||||
{ 0x00d2, 0xf7 },
|
||||
{ 0x00d3, 0xc2 },
|
||||
{ 0x00d4, 0xdf },
|
||||
{ 0x00d5, 0x02 },
|
||||
{ 0x00d6, 0x9a },
|
||||
{ 0x00d7, 0xd0 },
|
||||
{ 0x0250, 0x0d },
|
||||
{ 0x0251, 0xcd },
|
||||
{ 0x0252, 0xe0 },
|
||||
{ 0x0253, 0x05 },
|
||||
{ 0x0254, 0xa7 },
|
||||
{ 0x0255, 0xff },
|
||||
{ 0x0256, 0xed },
|
||||
{ 0x0257, 0x5b },
|
||||
{ 0x0258, 0xae },
|
||||
{ 0x0259, 0xe6 },
|
||||
{ 0x025a, 0x3d },
|
||||
{ 0x025b, 0x0f },
|
||||
{ 0x025c, 0x0d },
|
||||
{ 0x025d, 0xea },
|
||||
{ 0x025e, 0xf2 },
|
||||
{ 0x025f, 0x51 },
|
||||
{ 0x0260, 0xf5 },
|
||||
{ 0x0261, 0x06 },
|
||||
{ 0x021a, 0x00 },
|
||||
{ 0x0546, 0x40 },
|
||||
{ 0x0210, 0x26 },
|
||||
{ 0x0211, 0xf6 },
|
||||
{ 0x0212, 0x84 },
|
||||
{ 0x0213, 0x02 },
|
||||
{ 0x0502, 0x01 },
|
||||
{ 0x0121, 0x04 },
|
||||
{ 0x0122, 0x04 },
|
||||
{ 0x052e, 0x10 },
|
||||
{ 0x00a4, 0xca },
|
||||
{ 0x00a7, 0x40 },
|
||||
{ 0x0526, 0x01 },
|
||||
};
|
||||
|
||||
static struct {
|
||||
|
@ -654,12 +653,12 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
|
|||
|
||||
if (state->current_modulation == VSB_8) {
|
||||
dprintk("%s() Checking VSB_8\n", __func__);
|
||||
reg = au8522_readreg(state, 0x4088);
|
||||
reg = au8522_readreg(state, 0x0088);
|
||||
if ((reg & 0x03) == 0x03)
|
||||
*status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
|
||||
} else {
|
||||
dprintk("%s() Checking QAM\n", __func__);
|
||||
reg = au8522_readreg(state, 0x4541);
|
||||
reg = au8522_readreg(state, 0x0541);
|
||||
if (reg & 0x80)
|
||||
*status |= FE_HAS_VITERBI;
|
||||
if (reg & 0x20)
|
||||
|
@ -745,17 +744,17 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
if (state->current_modulation == QAM_256)
|
||||
ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
|
||||
ARRAY_SIZE(qam256_mse2snr_tab),
|
||||
au8522_readreg(state, 0x4522),
|
||||
au8522_readreg(state, 0x0522),
|
||||
snr);
|
||||
else if (state->current_modulation == QAM_64)
|
||||
ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
|
||||
ARRAY_SIZE(qam64_mse2snr_tab),
|
||||
au8522_readreg(state, 0x4522),
|
||||
au8522_readreg(state, 0x0522),
|
||||
snr);
|
||||
else /* VSB_8 */
|
||||
ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
|
||||
ARRAY_SIZE(vsb_mse2snr_tab),
|
||||
au8522_readreg(state, 0x4311),
|
||||
au8522_readreg(state, 0x0311),
|
||||
snr);
|
||||
|
||||
if (state->config.led_cfg)
|
||||
|
@ -804,9 +803,9 @@ static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
|||
struct au8522_state *state = fe->demodulator_priv;
|
||||
|
||||
if (state->current_modulation == VSB_8)
|
||||
*ucblocks = au8522_readreg(state, 0x4087);
|
||||
*ucblocks = au8522_readreg(state, 0x0087);
|
||||
else
|
||||
*ucblocks = au8522_readreg(state, 0x4543);
|
||||
*ucblocks = au8522_readreg(state, 0x0543);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -538,6 +538,7 @@ static int bcm3510_set_frontend(struct dvb_frontend *fe)
|
|||
cmd.ACQUIRE0.MODE = 0x9;
|
||||
cmd.ACQUIRE1.SYM_RATE = 0x0;
|
||||
cmd.ACQUIRE1.IF_FREQ = 0x0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -772,7 +773,8 @@ static int bcm3510_init(struct dvb_frontend* fe)
|
|||
deb_info("attempting to download firmware\n");
|
||||
if ((ret = bcm3510_init_cold(st)) < 0)
|
||||
return ret;
|
||||
case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
|
||||
/* fall-through */
|
||||
case JDEC_EEPROM_LOAD_WAIT:
|
||||
deb_info("firmware is loaded\n");
|
||||
bcm3510_check_firmware_version(st);
|
||||
break;
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#define MAX_WRITE_REGSIZE 16
|
||||
#define LOG2_E_100X 144
|
||||
|
||||
#define INTLOG10X100(x) ((u32) (((u64) intlog10(x) * 100) >> 24))
|
||||
|
||||
/* DVB-C constellation */
|
||||
enum sony_dvbc_constellation_t {
|
||||
SONY_DVBC_CONSTELLATION_16QAM,
|
||||
|
@ -65,6 +67,7 @@ struct cxd2841er_priv {
|
|||
u8 system;
|
||||
enum cxd2841er_xtal xtal;
|
||||
enum fe_caps caps;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
static const struct cxd2841er_cnr_data s_cn_data[] = {
|
||||
|
@ -201,11 +204,6 @@ static const struct cxd2841er_cnr_data s2_cn_data[] = {
|
|||
{ 0x0016, 19700 }, { 0x0015, 19900 }, { 0x0014, 20000 },
|
||||
};
|
||||
|
||||
#define MAKE_IFFREQ_CONFIG(iffreq) ((u32)(((iffreq)/41.0)*16777216.0 + 0.5))
|
||||
#define MAKE_IFFREQ_CONFIG_XTAL(xtal, iffreq) ((xtal == SONY_XTAL_24000) ? \
|
||||
(u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \
|
||||
(u32)(((iffreq)/41.0)*16777216.0 + 0.5))
|
||||
|
||||
static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv);
|
||||
static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv);
|
||||
|
||||
|
@ -214,10 +212,8 @@ static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv,
|
|||
const u8 *data, u32 len)
|
||||
{
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"cxd2841er: I2C %s addr %02x reg 0x%02x size %d\n",
|
||||
(write == 0 ? "read" : "write"), addr, reg, len);
|
||||
print_hex_dump_bytes("cxd2841er: I2C data: ",
|
||||
DUMP_PREFIX_OFFSET, data, len);
|
||||
"cxd2841er: I2C %s addr %02x reg 0x%02x size %d data %*ph\n",
|
||||
(write == 0 ? "read" : "write"), addr, reg, len, len, data);
|
||||
}
|
||||
|
||||
static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
|
||||
|
@ -284,17 +280,8 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
|
|||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(priv->i2c, &msg[0], 1);
|
||||
if (ret >= 0 && ret != 1)
|
||||
ret = -EIO;
|
||||
if (ret < 0) {
|
||||
dev_warn(&priv->i2c->dev,
|
||||
"%s: i2c rw failed=%d addr=%02x reg=%02x\n",
|
||||
KBUILD_MODNAME, ret, i2c_addr, reg);
|
||||
return ret;
|
||||
}
|
||||
ret = i2c_transfer(priv->i2c, &msg[1], 1);
|
||||
if (ret >= 0 && ret != 1)
|
||||
ret = i2c_transfer(priv->i2c, msg, 2);
|
||||
if (ret >= 0 && ret != 2)
|
||||
ret = -EIO;
|
||||
if (ret < 0) {
|
||||
dev_warn(&priv->i2c->dev,
|
||||
|
@ -327,6 +314,49 @@ static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv,
|
|||
return cxd2841er_write_reg(priv, addr, reg, data);
|
||||
}
|
||||
|
||||
static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz)
|
||||
{
|
||||
u64 tmp;
|
||||
|
||||
tmp = (u64) ifhz * 16777216;
|
||||
do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000));
|
||||
|
||||
return (u32) tmp;
|
||||
}
|
||||
|
||||
static u32 cxd2841er_calc_iffreq(u32 ifhz)
|
||||
{
|
||||
return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
|
||||
}
|
||||
|
||||
static int cxd2841er_get_if_hz(struct cxd2841er_priv *priv, u32 def_hz)
|
||||
{
|
||||
u32 hz;
|
||||
|
||||
if (priv->frontend.ops.tuner_ops.get_if_frequency
|
||||
&& (priv->flags & CXD2841ER_AUTO_IFHZ))
|
||||
priv->frontend.ops.tuner_ops.get_if_frequency(
|
||||
&priv->frontend, &hz);
|
||||
else
|
||||
hz = def_hz;
|
||||
|
||||
return hz;
|
||||
}
|
||||
|
||||
static int cxd2841er_tuner_set(struct dvb_frontend *fe)
|
||||
{
|
||||
struct cxd2841er_priv *priv = fe->demodulator_priv;
|
||||
|
||||
if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
|
||||
u32 symbol_rate)
|
||||
{
|
||||
|
@ -882,6 +912,18 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
|
|||
dev_dbg(&priv->i2c->dev, "%s(): ser_ts=0x%02x rate_ctrl_off=0x%02x in_off=0x%02x\n",
|
||||
__func__, serial_ts, ts_rate_ctrl_off, ts_in_off);
|
||||
|
||||
/*
|
||||
* slave Bank Addr Bit default Name
|
||||
* <SLV-T> 00h C4h [1:0] 2'b?? OSERCKMODE
|
||||
*/
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
|
||||
((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
|
||||
/*
|
||||
* slave Bank Addr Bit default Name
|
||||
* <SLV-T> 00h D1h [1:0] 2'b?? OSERDUTYMODE
|
||||
*/
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd1,
|
||||
((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
|
||||
/*
|
||||
* slave Bank Addr Bit default Name
|
||||
* <SLV-T> 00h D9h [7:0] 8'h08 OTSCKPERIOD
|
||||
|
@ -897,7 +939,8 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
|
|||
* slave Bank Addr Bit default Name
|
||||
* <SLV-T> 00h 33h [1:0] 2'b01 OREG_CKSEL_TSIF
|
||||
*/
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33, 0x00, 0x03);
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33,
|
||||
((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
|
||||
/*
|
||||
* Enable TS IF Clock
|
||||
* slave Bank Addr Bit default Name
|
||||
|
@ -1421,11 +1464,11 @@ static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
|
|||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum));
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data));
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
|
||||
if (!pktnum[0] && !pktnum[1]) {
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s(): no valid BER data\n", __func__);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1435,7 +1478,6 @@ static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
|
|||
dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n",
|
||||
__func__, *bit_error, *bit_count);
|
||||
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1645,6 +1687,8 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
|
|||
* <SLV-T> A1h 12h [7:0] ICPM_QUICKCNDT[7:0]
|
||||
*/
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
|
||||
if (data[0] & 0x01) {
|
||||
value = ((u32)(data[1] & 0x1F) << 8) | (u32)(data[2] & 0xFF);
|
||||
min_index = 0;
|
||||
|
@ -1687,11 +1731,9 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
|
|||
} else {
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s(): no data available\n", __func__);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
done:
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
*snr = res;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1720,12 +1762,12 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
|
|||
cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
|
||||
qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
|
||||
reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
|
||||
if (reg == 0) {
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s(): reg value out of range\n", __func__);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1746,11 +1788,9 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
|
|||
*snr = -88 * (int32_t)sony_log(reg) + 86999;
|
||||
break;
|
||||
default:
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1769,17 +1809,17 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
|
|||
cxd2841er_freeze_regs(priv);
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
|
||||
reg = ((u32)data[0] << 8) | (u32)data[1];
|
||||
if (reg == 0) {
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s(): reg value out of range\n", __func__);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
if (reg > 4996)
|
||||
reg = 4996;
|
||||
*snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500;
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
*snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(5350 - reg)) + 285);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1798,18 +1838,17 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
|
|||
cxd2841er_freeze_regs(priv);
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
|
||||
reg = ((u32)data[0] << 8) | (u32)data[1];
|
||||
if (reg == 0) {
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s(): reg value out of range\n", __func__);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
if (reg > 10876)
|
||||
reg = 10876;
|
||||
*snr = 10000 * ((intlog10(reg) -
|
||||
intlog10(12600 - reg)) >> 24) + 32000;
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
*snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(12600 - reg)) + 320);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1829,15 +1868,15 @@ static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
|
|||
cxd2841er_freeze_regs(priv);
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
|
||||
cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
|
||||
reg = ((u32)data[0] << 8) | (u32)data[1];
|
||||
if (reg == 0) {
|
||||
dev_dbg(&priv->i2c->dev,
|
||||
"%s(): reg value out of range\n", __func__);
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
*snr = 10000 * (intlog10(reg) >> 24) - 9031;
|
||||
cxd2841er_unfreeze_regs(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2136,7 +2175,7 @@ static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv,
|
|||
static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
|
||||
u32 bandwidth)
|
||||
{
|
||||
u32 iffreq;
|
||||
u32 iffreq, ifhz;
|
||||
u8 data[MAX_WRITE_REGSIZE];
|
||||
|
||||
const uint8_t nominalRate8bw[3][5] = {
|
||||
|
@ -2239,10 +2278,12 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef8bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4800000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2267,10 +2308,12 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef7bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4200000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2295,10 +2338,12 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef6bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3600000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2323,10 +2368,12 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef5bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3600000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2351,10 +2398,12 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef17bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.50);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3500000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2373,7 +2422,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
|
|||
struct cxd2841er_priv *priv, u32 bandwidth)
|
||||
{
|
||||
u8 data[MAX_WRITE_REGSIZE];
|
||||
u32 iffreq;
|
||||
u32 iffreq, ifhz;
|
||||
u8 nominalRate8bw[3][5] = {
|
||||
/* TRCG Nominal Rate [37:0] */
|
||||
{0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
|
||||
|
@ -2450,10 +2499,12 @@ static int cxd2841er_sleep_tc_to_active_t_band(
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef8bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4800000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2485,10 +2536,12 @@ static int cxd2841er_sleep_tc_to_active_t_band(
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef7bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4200000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2520,10 +2573,12 @@ static int cxd2841er_sleep_tc_to_active_t_band(
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef6bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3600000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2555,10 +2610,12 @@ static int cxd2841er_sleep_tc_to_active_t_band(
|
|||
/* Group delay equaliser settings for
|
||||
* ASCOT2D, ASCOT2E and ASCOT3 tuners
|
||||
*/
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef5bw[priv->xtal], 14);
|
||||
/* <IF freq setting> */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3600000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2591,7 +2648,7 @@ static int cxd2841er_sleep_tc_to_active_t_band(
|
|||
static int cxd2841er_sleep_tc_to_active_i_band(
|
||||
struct cxd2841er_priv *priv, u32 bandwidth)
|
||||
{
|
||||
u32 iffreq;
|
||||
u32 iffreq, ifhz;
|
||||
u8 data[3];
|
||||
|
||||
/* TRCG Nominal Rate */
|
||||
|
@ -2656,11 +2713,13 @@ static int cxd2841er_sleep_tc_to_active_i_band(
|
|||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0x9F, nominalRate8bw[priv->xtal], 5);
|
||||
/* Group delay equaliser settings for ASCOT tuners optimized */
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef8bw[priv->xtal], 14);
|
||||
|
||||
/* IF freq setting */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.75);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4750000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2685,11 +2744,13 @@ static int cxd2841er_sleep_tc_to_active_i_band(
|
|||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0x9F, nominalRate7bw[priv->xtal], 5);
|
||||
/* Group delay equaliser settings for ASCOT tuners optimized */
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef7bw[priv->xtal], 14);
|
||||
|
||||
/* IF freq setting */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.15);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4150000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2714,11 +2775,13 @@ static int cxd2841er_sleep_tc_to_active_i_band(
|
|||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0x9F, nominalRate6bw[priv->xtal], 5);
|
||||
/* Group delay equaliser settings for ASCOT tuners optimized */
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(priv, I2C_SLVT,
|
||||
0xA6, itbCoef6bw[priv->xtal], 14);
|
||||
|
||||
/* IF freq setting */
|
||||
iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.55);
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3550000);
|
||||
iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
|
||||
data[0] = (u8) ((iffreq >> 16) & 0xff);
|
||||
data[1] = (u8)((iffreq >> 8) & 0xff);
|
||||
data[2] = (u8)(iffreq & 0xff);
|
||||
|
@ -2761,7 +2824,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
|
|||
0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
|
||||
0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 };
|
||||
u8 b10_b6[3];
|
||||
u32 iffreq;
|
||||
u32 iffreq, ifhz;
|
||||
|
||||
if (bandwidth != 6000000 &&
|
||||
bandwidth != 7000000 &&
|
||||
|
@ -2776,16 +2839,20 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
|
|||
switch (bandwidth) {
|
||||
case 8000000:
|
||||
case 7000000:
|
||||
cxd2841er_write_regs(
|
||||
priv, I2C_SLVT, 0xa6,
|
||||
bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
|
||||
iffreq = MAKE_IFFREQ_CONFIG(4.9);
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(
|
||||
priv, I2C_SLVT, 0xa6,
|
||||
bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
|
||||
ifhz = cxd2841er_get_if_hz(priv, 4900000);
|
||||
iffreq = cxd2841er_calc_iffreq(ifhz);
|
||||
break;
|
||||
case 6000000:
|
||||
cxd2841er_write_regs(
|
||||
priv, I2C_SLVT, 0xa6,
|
||||
bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
|
||||
iffreq = MAKE_IFFREQ_CONFIG(3.7);
|
||||
if (priv->flags & CXD2841ER_ASCOT)
|
||||
cxd2841er_write_regs(
|
||||
priv, I2C_SLVT, 0xa6,
|
||||
bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
|
||||
ifhz = cxd2841er_get_if_hz(priv, 3700000);
|
||||
iffreq = cxd2841er_calc_iffreq(ifhz);
|
||||
break;
|
||||
default:
|
||||
dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
|
||||
|
@ -2872,8 +2939,9 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
|
|||
cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
|
||||
/* Set SLV-T Bank : 0x10 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
|
||||
/* ASCOT setting ON */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
|
||||
/* ASCOT setting */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
|
||||
((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
|
||||
/* Set SLV-T Bank : 0x18 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18);
|
||||
/* Pre-RS BER moniter setting */
|
||||
|
@ -2950,8 +3018,9 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
|
|||
cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
|
||||
/* Set SLV-T Bank : 0x10 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
|
||||
/* ASCOT setting ON */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
|
||||
/* ASCOT setting */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
|
||||
((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
|
||||
/* Set SLV-T Bank : 0x20 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
|
||||
/* Acquisition optimization setting */
|
||||
|
@ -3088,8 +3157,9 @@ static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
|
|||
cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
|
||||
/* Enable ADC 4 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
|
||||
/* ASCOT setting ON */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
|
||||
/* ASCOT setting */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
|
||||
((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
|
||||
/* FEC Auto Recovery setting */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01);
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01);
|
||||
|
@ -3173,8 +3243,9 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
|
|||
cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x48);
|
||||
/* Set SLV-T Bank : 0x10 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
|
||||
/* ASCOT setting ON */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
|
||||
/* ASCOT setting */
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
|
||||
((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
|
||||
/* Set SLV-T Bank : 0x40 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
|
||||
/* Demod setting */
|
||||
|
@ -3236,6 +3307,10 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
|
|||
__func__,
|
||||
(p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"),
|
||||
p->frequency, symbol_rate, priv->xtal);
|
||||
|
||||
if (priv->flags & CXD2841ER_EARLY_TUNE)
|
||||
cxd2841er_tuner_set(fe);
|
||||
|
||||
switch (priv->state) {
|
||||
case STATE_SLEEP_S:
|
||||
ret = cxd2841er_sleep_s_to_active_s(
|
||||
|
@ -3254,12 +3329,10 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
|
|||
dev_dbg(&priv->i2c->dev, "%s(): tune failed\n", __func__);
|
||||
goto done;
|
||||
}
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (!(priv->flags & CXD2841ER_EARLY_TUNE))
|
||||
cxd2841er_tuner_set(fe);
|
||||
|
||||
cxd2841er_tune_done(priv);
|
||||
timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
|
||||
for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) {
|
||||
|
@ -3298,6 +3371,10 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
|
|||
|
||||
dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n",
|
||||
__func__, p->delivery_system, p->bandwidth_hz);
|
||||
|
||||
if (priv->flags & CXD2841ER_EARLY_TUNE)
|
||||
cxd2841er_tuner_set(fe);
|
||||
|
||||
if (p->delivery_system == SYS_DVBT) {
|
||||
priv->system = SYS_DVBT;
|
||||
switch (priv->state) {
|
||||
|
@ -3379,13 +3456,15 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
|
|||
}
|
||||
if (ret)
|
||||
goto done;
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (!(priv->flags & CXD2841ER_EARLY_TUNE))
|
||||
cxd2841er_tuner_set(fe);
|
||||
|
||||
cxd2841er_tune_done(priv);
|
||||
|
||||
if (priv->flags & CXD2841ER_NO_WAIT_LOCK)
|
||||
goto done;
|
||||
|
||||
timeout = 2500;
|
||||
while (timeout > 0) {
|
||||
ret = cxd2841er_read_status_tc(fe, &status);
|
||||
|
@ -3705,14 +3784,20 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
|
|||
dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n",
|
||||
__func__, p->bandwidth_hz);
|
||||
cxd2841er_shutdown_to_sleep_tc(priv);
|
||||
/* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */
|
||||
/* SONY_DEMOD_CONFIG_IFAGCNEG = 1 (0 for NO_AGCNEG */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb, 0x40, 0x40);
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb,
|
||||
((priv->flags & CXD2841ER_NO_AGCNEG) ? 0x00 : 0x40), 0x40);
|
||||
/* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50);
|
||||
/* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */
|
||||
cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x80);
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
|
||||
((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80);
|
||||
|
||||
/* clear TSCFG bits 3+4 */
|
||||
if (priv->flags & CXD2841ER_TSBITS)
|
||||
cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x18);
|
||||
|
||||
cxd2841er_init_stats(fe);
|
||||
|
||||
|
@ -3740,6 +3825,7 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
|
|||
priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1;
|
||||
priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1;
|
||||
priv->xtal = cfg->xtal;
|
||||
priv->flags = cfg->flags;
|
||||
priv->frontend.demodulator_priv = priv;
|
||||
dev_info(&priv->i2c->dev,
|
||||
"%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n",
|
||||
|
@ -3747,16 +3833,39 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
|
|||
priv->i2c_addr_slvx, priv->i2c_addr_slvt);
|
||||
chip_id = cxd2841er_chip_id(priv);
|
||||
switch (chip_id) {
|
||||
case CXD2837ER_CHIP_ID:
|
||||
snprintf(cxd2841er_t_c_ops.info.name, 128,
|
||||
"Sony CXD2837ER DVB-T/T2/C demodulator");
|
||||
name = "CXD2837ER";
|
||||
type = "C/T/T2";
|
||||
break;
|
||||
case CXD2838ER_CHIP_ID:
|
||||
snprintf(cxd2841er_t_c_ops.info.name, 128,
|
||||
"Sony CXD2838ER ISDB-T demodulator");
|
||||
cxd2841er_t_c_ops.delsys[0] = SYS_ISDBT;
|
||||
cxd2841er_t_c_ops.delsys[1] = SYS_UNDEFINED;
|
||||
cxd2841er_t_c_ops.delsys[2] = SYS_UNDEFINED;
|
||||
name = "CXD2838ER";
|
||||
type = "ISDB-T";
|
||||
break;
|
||||
case CXD2841ER_CHIP_ID:
|
||||
snprintf(cxd2841er_t_c_ops.info.name, 128,
|
||||
"Sony CXD2841ER DVB-T/T2/C demodulator");
|
||||
name = "CXD2841ER";
|
||||
type = "T/T2/C/ISDB-T";
|
||||
break;
|
||||
case CXD2843ER_CHIP_ID:
|
||||
snprintf(cxd2841er_t_c_ops.info.name, 128,
|
||||
"Sony CXD2843ER DVB-T/T2/C/C2 demodulator");
|
||||
name = "CXD2843ER";
|
||||
type = "C/C2/T/T2";
|
||||
break;
|
||||
case CXD2854ER_CHIP_ID:
|
||||
snprintf(cxd2841er_t_c_ops.info.name, 128,
|
||||
"Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator");
|
||||
cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT;
|
||||
name = "CXD2854ER";
|
||||
type = "C/C2/T/T2/ISDB-T";
|
||||
break;
|
||||
default:
|
||||
dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n",
|
||||
|
@ -3776,7 +3885,6 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
|
|||
memcpy(&priv->frontend.ops,
|
||||
&cxd2841er_t_c_ops,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
type = "T/T2/C/ISDB-T";
|
||||
}
|
||||
|
||||
dev_info(&priv->i2c->dev,
|
||||
|
|
|
@ -24,6 +24,15 @@
|
|||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#define CXD2841ER_USE_GATECTRL 1 /* bit 0 */
|
||||
#define CXD2841ER_AUTO_IFHZ 2 /* bit 1 */
|
||||
#define CXD2841ER_TS_SERIAL 4 /* bit 2 */
|
||||
#define CXD2841ER_ASCOT 8 /* bit 3 */
|
||||
#define CXD2841ER_EARLY_TUNE 16 /* bit 4 */
|
||||
#define CXD2841ER_NO_WAIT_LOCK 32 /* bit 5 */
|
||||
#define CXD2841ER_NO_AGCNEG 64 /* bit 6 */
|
||||
#define CXD2841ER_TSBITS 128 /* bit 7 */
|
||||
|
||||
enum cxd2841er_xtal {
|
||||
SONY_XTAL_20500, /* 20.5 MHz */
|
||||
SONY_XTAL_24000, /* 24 MHz */
|
||||
|
@ -33,6 +42,7 @@ enum cxd2841er_xtal {
|
|||
struct cxd2841er_config {
|
||||
u8 i2c_addr;
|
||||
enum cxd2841er_xtal xtal;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DVB_CXD2841ER)
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
#define I2C_SLVX 0
|
||||
#define I2C_SLVT 1
|
||||
|
||||
#define CXD2837ER_CHIP_ID 0xb1
|
||||
#define CXD2838ER_CHIP_ID 0xb0
|
||||
#define CXD2841ER_CHIP_ID 0xa7
|
||||
#define CXD2843ER_CHIP_ID 0xa4
|
||||
#define CXD2854ER_CHIP_ID 0xc1
|
||||
|
||||
#define CXD2841ER_DVBS_POLLING_INVL 10
|
||||
|
|
|
@ -279,10 +279,10 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p
|
|||
if (state->version != SOC7090)
|
||||
reg_1280 &= ~((1 << 11));
|
||||
reg_1280 &= ~(1 << 6);
|
||||
/* fall through wanted to enable the interfaces */
|
||||
|
||||
/* fall-through */
|
||||
case DIB7000P_POWER_INTERFACE_ONLY:
|
||||
/* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
|
||||
case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
|
||||
/* TODO power up either SDIO or I2C */
|
||||
if (state->version == SOC7090)
|
||||
reg_1280 &= ~((1 << 7) | (1 << 5));
|
||||
else
|
||||
|
|
|
@ -2837,7 +2837,8 @@ ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_o
|
|||
/* coef = 188/204 */
|
||||
max_bit_rate =
|
||||
(ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
|
||||
/* pass through b/c Annex A/c need following settings */
|
||||
/* pass through as b/c Annex A/c need following settings */
|
||||
/* fall-through */
|
||||
case DRX_STANDARD_ITU_B:
|
||||
rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
|
||||
if (rc != 0) {
|
||||
|
@ -4776,9 +4777,9 @@ set_frequency(struct drx_demod_instance *demod,
|
|||
No need to account for mirroring on RF
|
||||
*/
|
||||
switch (ext_attr->standard) {
|
||||
case DRX_STANDARD_ITU_A: /* fallthrough */
|
||||
case DRX_STANDARD_ITU_C: /* fallthrough */
|
||||
case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
|
||||
case DRX_STANDARD_ITU_A:
|
||||
case DRX_STANDARD_ITU_C:
|
||||
case DRX_STANDARD_PAL_SECAM_LP:
|
||||
case DRX_STANDARD_8VSB:
|
||||
select_pos_image = true;
|
||||
break;
|
||||
|
@ -4787,11 +4788,12 @@ set_frequency(struct drx_demod_instance *demod,
|
|||
Sound carrier is already 3Mhz above centre frequency due
|
||||
to tuner setting so now add an extra shift of 1MHz... */
|
||||
fm_frequency_shift = 1000;
|
||||
case DRX_STANDARD_ITU_B: /* fallthrough */
|
||||
case DRX_STANDARD_NTSC: /* fallthrough */
|
||||
case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
|
||||
case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
|
||||
case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
|
||||
/*fall through */
|
||||
case DRX_STANDARD_ITU_B:
|
||||
case DRX_STANDARD_NTSC:
|
||||
case DRX_STANDARD_PAL_SECAM_BG:
|
||||
case DRX_STANDARD_PAL_SECAM_DK:
|
||||
case DRX_STANDARD_PAL_SECAM_I:
|
||||
case DRX_STANDARD_PAL_SECAM_L:
|
||||
select_pos_image = false;
|
||||
break;
|
||||
|
|
|
@ -1517,12 +1517,14 @@ static int SetDeviceTypeId(struct drxd_state *state)
|
|||
switch (deviceId) {
|
||||
case 4:
|
||||
state->diversity = 1;
|
||||
/* fall through */
|
||||
case 3:
|
||||
case 7:
|
||||
state->PGA = 1;
|
||||
break;
|
||||
case 6:
|
||||
state->diversity = 1;
|
||||
/* fall through */
|
||||
case 5:
|
||||
case 8:
|
||||
break;
|
||||
|
@ -1969,7 +1971,8 @@ static int DRX_Start(struct drxd_state *state, s32 off)
|
|||
switch (p->transmission_mode) {
|
||||
default: /* Not set, detect it automatically */
|
||||
operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
|
||||
/* fall through , try first guess DRX_FFTMODE_8K */
|
||||
/* try first guess DRX_FFTMODE_8K */
|
||||
/* fall through */
|
||||
case TRANSMISSION_MODE_8K:
|
||||
transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
|
||||
if (state->type_A) {
|
||||
|
@ -2143,8 +2146,8 @@ static int DRX_Start(struct drxd_state *state, s32 off)
|
|||
switch (p->modulation) {
|
||||
default:
|
||||
operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
|
||||
/* fall through , try first guess
|
||||
DRX_CONSTELLATION_QAM64 */
|
||||
/* try first guess DRX_CONSTELLATION_QAM64 */
|
||||
/* fall through */
|
||||
case QAM_64:
|
||||
transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
|
||||
if (state->type_A) {
|
||||
|
@ -2280,6 +2283,7 @@ static int DRX_Start(struct drxd_state *state, s32 off)
|
|||
break;
|
||||
default:
|
||||
operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
|
||||
/* fall through */
|
||||
case FEC_2_3:
|
||||
transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
|
||||
if (state->type_A) {
|
||||
|
|
|
@ -3271,10 +3271,12 @@ static int dvbt_sc_command(struct drxk_state *state,
|
|||
case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
|
||||
status |= write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
|
||||
/* All commands using 1 parameters */
|
||||
/* fall through */
|
||||
case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
|
||||
case OFDM_SC_RA_RAM_CMD_USER_IO:
|
||||
status |= write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
|
||||
/* All commands using 0 parameters */
|
||||
/* fall through */
|
||||
case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
|
||||
case OFDM_SC_RA_RAM_CMD_NULL:
|
||||
/* Write command */
|
||||
|
@ -3782,7 +3784,8 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
|
|||
case TRANSMISSION_MODE_AUTO:
|
||||
default:
|
||||
operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
|
||||
/* fall through , try first guess DRX_FFTMODE_8K */
|
||||
/* try first guess DRX_FFTMODE_8K */
|
||||
/* fall through */
|
||||
case TRANSMISSION_MODE_8K:
|
||||
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
|
||||
break;
|
||||
|
@ -3796,7 +3799,8 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
|
|||
default:
|
||||
case GUARD_INTERVAL_AUTO:
|
||||
operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
|
||||
/* fall through , try first guess DRX_GUARD_1DIV4 */
|
||||
/* try first guess DRX_GUARD_1DIV4 */
|
||||
/* fall through */
|
||||
case GUARD_INTERVAL_1_4:
|
||||
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
|
||||
break;
|
||||
|
@ -3817,9 +3821,9 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
|
|||
case HIERARCHY_NONE:
|
||||
default:
|
||||
operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
|
||||
/* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
|
||||
/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
|
||||
/* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
|
||||
/* break; */
|
||||
/* fall through */
|
||||
case HIERARCHY_1:
|
||||
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
|
||||
break;
|
||||
|
@ -3837,7 +3841,8 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
|
|||
case QAM_AUTO:
|
||||
default:
|
||||
operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
|
||||
/* fall through , try first guess DRX_CONSTELLATION_QAM64 */
|
||||
/* try first guess DRX_CONSTELLATION_QAM64 */
|
||||
/* fall through */
|
||||
case QAM_64:
|
||||
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
|
||||
break;
|
||||
|
@ -3880,7 +3885,8 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
|
|||
case FEC_AUTO:
|
||||
default:
|
||||
operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
|
||||
/* fall through , try first guess DRX_CODERATE_2DIV3 */
|
||||
/* try first guess DRX_CODERATE_2DIV3 */
|
||||
/* fall through */
|
||||
case FEC_2_3:
|
||||
transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
|
||||
break;
|
||||
|
@ -3914,7 +3920,7 @@ static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
|
|||
switch (state->props.bandwidth_hz) {
|
||||
case 0:
|
||||
state->props.bandwidth_hz = 8000000;
|
||||
/* fall though */
|
||||
/* fall through */
|
||||
case 8000000:
|
||||
bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
|
||||
status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
|
||||
|
|
|
@ -211,6 +211,7 @@ static int mt352_set_parameters(struct dvb_frontend *fe)
|
|||
if (op->hierarchy == HIERARCHY_AUTO ||
|
||||
op->hierarchy == HIERARCHY_NONE)
|
||||
break;
|
||||
/* fall through */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -493,8 +493,8 @@ start:
|
|||
switch (reg&0xff) {
|
||||
case 0x06:
|
||||
if (reg & 0x1000) usK = 3 << 24;
|
||||
/* Fall through to QAM64 case */
|
||||
case 0x43:
|
||||
/* fall through */
|
||||
case 0x43: /* QAM64 */
|
||||
c = 150204167;
|
||||
break;
|
||||
case 0x45:
|
||||
|
|
|
@ -51,7 +51,7 @@ static int debug;
|
|||
#define dprintk(arg...) do { \
|
||||
if (debug) \
|
||||
printk(arg); \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/* Register values to initialise the demod, defaults to VSB */
|
||||
static struct init_tab {
|
||||
|
@ -410,7 +410,7 @@ static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
|
|||
default:
|
||||
dprintk("%s(%d KHz) Invalid, defaulting to 5380\n",
|
||||
__func__, KHz);
|
||||
/* no break, need to continue */
|
||||
/* fall through */
|
||||
case 5380:
|
||||
case 44000:
|
||||
s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,6 +25,9 @@
|
|||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
#define STV0367_ICSPEED_53125 53125000
|
||||
#define STV0367_ICSPEED_58000 58000000
|
||||
|
||||
struct stv0367_config {
|
||||
u8 demod_address;
|
||||
u32 xtal;
|
||||
|
@ -41,6 +44,9 @@ dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
|
|||
extern struct
|
||||
dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
extern struct
|
||||
dvb_frontend *stv0367ddb_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct
|
||||
dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
|
||||
|
@ -56,6 +62,13 @@ dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
|
|||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
static inline struct
|
||||
dvb_frontend *stv0367ddb_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2639,8 +2639,6 @@
|
|||
#define R367TER_DEBUG_LT9 0xf405
|
||||
#define F367TER_F_DEBUG_LT9 0xf40500ff
|
||||
|
||||
#define STV0367TER_NBREGS 445
|
||||
|
||||
/* ID */
|
||||
#define R367CAB_ID 0xf000
|
||||
#define F367CAB_IDENTIFICATIONREGISTER 0xf00000ff
|
||||
|
@ -3605,6 +3603,4 @@
|
|||
#define R367CAB_T_O_ID_3 0xf4d3
|
||||
#define F367CAB_TS_ID_I_H 0xf4d300ff
|
||||
|
||||
#define STV0367CAB_NBREGS 187
|
||||
|
||||
#endif
|
||||
|
|
|
@ -211,7 +211,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe)
|
|||
break;
|
||||
default:
|
||||
c->bandwidth_hz = 8000000;
|
||||
/* fall though */
|
||||
/* fall through */
|
||||
case 8000000:
|
||||
zl10353_single_write(fe, MCLK_RATIO, 0x75);
|
||||
zl10353_single_write(fe, 0x64, 0x36);
|
||||
|
@ -268,6 +268,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe)
|
|||
if (c->hierarchy == HIERARCHY_AUTO ||
|
||||
c->hierarchy == HIERARCHY_NONE)
|
||||
break;
|
||||
/* fall through */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -209,6 +209,7 @@ config VIDEO_ADV7604
|
|||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
select HDMI
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
Support for the Analog Devices ADV7604 video decoder.
|
||||
|
||||
|
@ -302,6 +303,16 @@ config VIDEO_AD5820
|
|||
This is a driver for the AD5820 camera lens voice coil.
|
||||
It is used for example in Nokia N900 (RX-51).
|
||||
|
||||
config VIDEO_DW9714
|
||||
tristate "DW9714 lens voice coil support"
|
||||
depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
|
||||
depends on VIDEO_V4L2_SUBDEV_API
|
||||
---help---
|
||||
This is a driver for the DW9714 camera lens voice coil.
|
||||
DW9714 is a 10 bit DAC with 120mA output current sink
|
||||
capability. This is designed for linear control of
|
||||
voice coil motors, controlled via I2C serial interface.
|
||||
|
||||
config VIDEO_SAA7110
|
||||
tristate "Philips SAA7110 video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
|
@ -324,6 +335,7 @@ config VIDEO_TC358743
|
|||
tristate "Toshiba TC358743 decoder"
|
||||
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
select HDMI
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge.
|
||||
|
||||
|
@ -333,6 +345,7 @@ config VIDEO_TC358743
|
|||
config VIDEO_TVP514X
|
||||
tristate "Texas Instruments TVP514x video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the TI TVP5146/47
|
||||
decoder. It is currently working with the TI OMAP3 camera
|
||||
|
@ -344,6 +357,7 @@ config VIDEO_TVP514X
|
|||
config VIDEO_TVP5150
|
||||
tristate "Texas Instruments TVP5150 video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
Support for the Texas Instruments TVP5150 video decoder.
|
||||
|
||||
|
@ -353,6 +367,7 @@ config VIDEO_TVP5150
|
|||
config VIDEO_TVP7002
|
||||
tristate "Texas Instruments TVP7002 video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
Support for the Texas Instruments TVP7002 video decoder.
|
||||
|
||||
|
@ -535,6 +550,7 @@ config VIDEO_OV2659
|
|||
tristate "OmniVision OV2659 sensor support"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the OmniVision
|
||||
OV2659 camera.
|
||||
|
@ -542,11 +558,22 @@ config VIDEO_OV2659
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov2659.
|
||||
|
||||
config VIDEO_OV5640
|
||||
tristate "OmniVision OV5640 sensor support"
|
||||
depends on OF
|
||||
depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the Omnivision
|
||||
OV5640 camera sensor with a MIPI CSI-2 interface.
|
||||
|
||||
config VIDEO_OV5645
|
||||
tristate "OmniVision OV5645 sensor support"
|
||||
depends on OF
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the OmniVision
|
||||
OV5645 camera.
|
||||
|
@ -558,6 +585,7 @@ config VIDEO_OV5647
|
|||
tristate "OmniVision OV5647 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the OmniVision
|
||||
OV5647 camera.
|
||||
|
@ -592,6 +620,14 @@ config VIDEO_OV9650
|
|||
This is a V4L2 sensor-level driver for the Omnivision
|
||||
OV9650 and OV9652 camera sensors.
|
||||
|
||||
config VIDEO_OV13858
|
||||
tristate "OmniVision OV13858 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the OmniVision
|
||||
OV13858 camera.
|
||||
|
||||
config VIDEO_VS6624
|
||||
tristate "ST VS6624 sensor support"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
|
@ -650,6 +686,7 @@ config VIDEO_MT9V032
|
|||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select REGMAP_I2C
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the Micron
|
||||
MT9V032 752x480 CMOS sensor.
|
||||
|
@ -697,6 +734,7 @@ config VIDEO_S5K4ECGX
|
|||
config VIDEO_S5K5BAF
|
||||
tristate "Samsung S5K5BAF sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a V4L2 sensor-level driver for Samsung S5K5BAF 2M
|
||||
camera sensor with an embedded SoC image signal processor.
|
||||
|
@ -707,6 +745,7 @@ source "drivers/media/i2c/et8ek8/Kconfig"
|
|||
config VIDEO_S5C73M3
|
||||
tristate "Samsung S5C73M3 sensor support"
|
||||
depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a V4L2 sensor-level driver for Samsung S5C73M3
|
||||
8 Mpixel camera.
|
||||
|
@ -785,6 +824,18 @@ config VIDEO_SAA6752HS
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called saa6752hs.
|
||||
|
||||
comment "SDR tuner chips"
|
||||
|
||||
config SDR_MAX2175
|
||||
tristate "Maxim 2175 RF to Bits tuner"
|
||||
depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C
|
||||
---help---
|
||||
Support for Maxim 2175 tuner. It is an advanced analog/digital
|
||||
radio receiver with RF-to-Bits front-end designed for SDR solutions.
|
||||
|
||||
To compile this driver as a module, choose M here; the
|
||||
module will be called max2175.
|
||||
|
||||
comment "Miscellaneous helper chips"
|
||||
|
||||
config VIDEO_THS7303
|
||||
|
|
|
@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
|
|||
obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
|
||||
obj-$(CONFIG_VIDEO_SAA6752HS) += saa6752hs.o
|
||||
obj-$(CONFIG_VIDEO_AD5820) += ad5820.o
|
||||
obj-$(CONFIG_VIDEO_DW9714) += dw9714.o
|
||||
obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
|
||||
obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
|
||||
obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
|
||||
|
@ -58,11 +59,13 @@ obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
|
|||
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
|
||||
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
|
||||
obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
|
||||
obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
|
||||
obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
|
||||
obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
|
||||
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
|
||||
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
|
||||
obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
|
||||
obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
|
||||
obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
|
||||
obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o
|
||||
obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o
|
||||
|
@ -86,3 +89,5 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
|
|||
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
|
||||
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
|
||||
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
|
||||
|
||||
obj-$(CONFIG_SDR_MAX2175) += max2175.o
|
||||
|
|
|
@ -341,7 +341,7 @@ static int ad5820_remove(struct i2c_client *client)
|
|||
struct v4l2_subdev *subdev = i2c_get_clientdata(client);
|
||||
struct ad5820_device *coil = to_ad5820_device(subdev);
|
||||
|
||||
v4l2_device_unregister_subdev(&coil->subdev);
|
||||
v4l2_async_unregister_subdev(&coil->subdev);
|
||||
v4l2_ctrl_handler_free(&coil->ctrls);
|
||||
media_entity_cleanup(&coil->subdev.entity);
|
||||
mutex_destroy(&coil->power_lock);
|
||||
|
|
|
@ -1452,6 +1452,8 @@ static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
|
|||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id adv7180_of_id[] = {
|
||||
{ .compatible = "adi,adv7180", },
|
||||
{ .compatible = "adi,adv7180cp", },
|
||||
{ .compatible = "adi,adv7180st", },
|
||||
{ .compatible = "adi,adv7182", },
|
||||
{ .compatible = "adi,adv7280", },
|
||||
{ .compatible = "adi,adv7280-m", },
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/v4l2-dv-timings.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
@ -45,7 +46,7 @@
|
|||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-dv-timings.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
|
@ -3069,7 +3070,7 @@ MODULE_DEVICE_TABLE(of, adv76xx_of_id);
|
|||
|
||||
static int adv76xx_parse_dt(struct adv76xx_state *state)
|
||||
{
|
||||
struct v4l2_of_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct device_node *endpoint;
|
||||
struct device_node *np;
|
||||
unsigned int flags;
|
||||
|
@ -3083,7 +3084,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
|
|||
if (!endpoint)
|
||||
return -EINVAL;
|
||||
|
||||
ret = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
|
||||
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg);
|
||||
if (ret) {
|
||||
of_node_put(endpoint);
|
||||
return ret;
|
||||
|
|
|
@ -294,8 +294,8 @@ static int as3645a_read_fault(struct as3645a *flash)
|
|||
dev_dbg(&client->dev, "Inductor Peak limit fault\n");
|
||||
|
||||
if (rval & AS_FAULT_INFO_INDICATOR_LED)
|
||||
dev_dbg(&client->dev, "Indicator LED fault: "
|
||||
"Short circuit or open loop\n");
|
||||
dev_dbg(&client->dev,
|
||||
"Indicator LED fault: Short circuit or open loop\n");
|
||||
|
||||
dev_dbg(&client->dev, "%u connected LEDs\n",
|
||||
rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1);
|
||||
|
@ -310,8 +310,8 @@ static int as3645a_read_fault(struct as3645a *flash)
|
|||
dev_dbg(&client->dev, "Short circuit fault\n");
|
||||
|
||||
if (rval & AS_FAULT_INFO_OVER_VOLTAGE)
|
||||
dev_dbg(&client->dev, "Over voltage fault: "
|
||||
"Indicates missing capacitor or open connection\n");
|
||||
dev_dbg(&client->dev,
|
||||
"Over voltage fault: Indicates missing capacitor or open connection\n");
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
@ -583,8 +583,8 @@ static int as3645a_registered(struct v4l2_subdev *sd)
|
|||
|
||||
/* Verify the chip model and version. */
|
||||
if (model != 0x01 || rfu != 0x00) {
|
||||
dev_err(&client->dev, "AS3645A not detected "
|
||||
"(model %d rfu %d)\n", model, rfu);
|
||||
dev_err(&client->dev,
|
||||
"AS3645A not detected (model %d rfu %d)\n", model, rfu);
|
||||
rval = -ENODEV;
|
||||
goto power_off;
|
||||
}
|
||||
|
|
|
@ -416,11 +416,13 @@ static void cx25840_initialize(struct i2c_client *client)
|
|||
INIT_WORK(&state->fw_work, cx25840_work_handler);
|
||||
init_waitqueue_head(&state->fw_wait);
|
||||
q = create_singlethread_workqueue("cx25840_fw");
|
||||
prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
queue_work(q, &state->fw_work);
|
||||
schedule();
|
||||
finish_wait(&state->fw_wait, &wait);
|
||||
destroy_workqueue(q);
|
||||
if (q) {
|
||||
prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
queue_work(q, &state->fw_work);
|
||||
schedule();
|
||||
finish_wait(&state->fw_wait, &wait);
|
||||
destroy_workqueue(q);
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
cx25840_write(client, 0x115, 0x8c);
|
||||
|
@ -630,11 +632,13 @@ static void cx23885_initialize(struct i2c_client *client)
|
|||
INIT_WORK(&state->fw_work, cx25840_work_handler);
|
||||
init_waitqueue_head(&state->fw_wait);
|
||||
q = create_singlethread_workqueue("cx25840_fw");
|
||||
prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
queue_work(q, &state->fw_work);
|
||||
schedule();
|
||||
finish_wait(&state->fw_wait, &wait);
|
||||
destroy_workqueue(q);
|
||||
if (q) {
|
||||
prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
queue_work(q, &state->fw_work);
|
||||
schedule();
|
||||
finish_wait(&state->fw_wait, &wait);
|
||||
destroy_workqueue(q);
|
||||
}
|
||||
|
||||
/* Call the cx23888 specific std setup func, we no longer rely on
|
||||
* the generic cx24840 func.
|
||||
|
@ -748,11 +752,13 @@ static void cx231xx_initialize(struct i2c_client *client)
|
|||
INIT_WORK(&state->fw_work, cx25840_work_handler);
|
||||
init_waitqueue_head(&state->fw_wait);
|
||||
q = create_singlethread_workqueue("cx25840_fw");
|
||||
prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
queue_work(q, &state->fw_work);
|
||||
schedule();
|
||||
finish_wait(&state->fw_wait, &wait);
|
||||
destroy_workqueue(q);
|
||||
if (q) {
|
||||
prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
queue_work(q, &state->fw_work);
|
||||
schedule();
|
||||
finish_wait(&state->fw_wait, &wait);
|
||||
destroy_workqueue(q);
|
||||
}
|
||||
|
||||
cx25840_std_setup(client);
|
||||
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (c) 2015--2017 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
|
||||
#define DW9714_NAME "dw9714"
|
||||
#define DW9714_MAX_FOCUS_POS 1023
|
||||
/*
|
||||
* This acts as the minimum granularity of lens movement.
|
||||
* Keep this value power of 2, so the control steps can be
|
||||
* uniformly adjusted for gradual lens movement, with desired
|
||||
* number of control steps.
|
||||
*/
|
||||
#define DW9714_CTRL_STEPS 16
|
||||
#define DW9714_CTRL_DELAY_US 1000
|
||||
/*
|
||||
* S[3:2] = 0x00, codes per step for "Linear Slope Control"
|
||||
* S[1:0] = 0x00, step period
|
||||
*/
|
||||
#define DW9714_DEFAULT_S 0x0
|
||||
#define DW9714_VAL(data, s) ((data) << 4 | (s))
|
||||
|
||||
/* dw9714 device structure */
|
||||
struct dw9714_device {
|
||||
struct i2c_client *client;
|
||||
struct v4l2_ctrl_handler ctrls_vcm;
|
||||
struct v4l2_subdev sd;
|
||||
u16 current_val;
|
||||
};
|
||||
|
||||
static inline struct dw9714_device *to_dw9714_vcm(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return container_of(ctrl->handler, struct dw9714_device, ctrls_vcm);
|
||||
}
|
||||
|
||||
static inline struct dw9714_device *sd_to_dw9714_vcm(struct v4l2_subdev *subdev)
|
||||
{
|
||||
return container_of(subdev, struct dw9714_device, sd);
|
||||
}
|
||||
|
||||
static int dw9714_i2c_write(struct i2c_client *client, u16 data)
|
||||
{
|
||||
int ret;
|
||||
u16 val = cpu_to_be16(data);
|
||||
|
||||
ret = i2c_master_send(client, (const char *)&val, sizeof(val));
|
||||
if (ret != sizeof(val)) {
|
||||
dev_err(&client->dev, "I2C write fail\n");
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw9714_t_focus_vcm(struct dw9714_device *dw9714_dev, u16 val)
|
||||
{
|
||||
struct i2c_client *client = dw9714_dev->client;
|
||||
|
||||
dw9714_dev->current_val = val;
|
||||
|
||||
return dw9714_i2c_write(client, DW9714_VAL(val, DW9714_DEFAULT_S));
|
||||
}
|
||||
|
||||
static int dw9714_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct dw9714_device *dev_vcm = to_dw9714_vcm(ctrl);
|
||||
|
||||
if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
|
||||
return dw9714_t_focus_vcm(dev_vcm, ctrl->val);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops dw9714_vcm_ctrl_ops = {
|
||||
.s_ctrl = dw9714_set_ctrl,
|
||||
};
|
||||
|
||||
static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
|
||||
struct device *dev = &dw9714_dev->client->dev;
|
||||
int rval;
|
||||
|
||||
rval = pm_runtime_get_sync(dev);
|
||||
if (rval < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
return rval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw9714_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
|
||||
struct device *dev = &dw9714_dev->client->dev;
|
||||
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops dw9714_int_ops = {
|
||||
.open = dw9714_open,
|
||||
.close = dw9714_close,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops dw9714_ops = { };
|
||||
|
||||
static void dw9714_subdev_cleanup(struct dw9714_device *dw9714_dev)
|
||||
{
|
||||
v4l2_async_unregister_subdev(&dw9714_dev->sd);
|
||||
v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
|
||||
media_entity_cleanup(&dw9714_dev->sd.entity);
|
||||
}
|
||||
|
||||
static int dw9714_init_controls(struct dw9714_device *dev_vcm)
|
||||
{
|
||||
struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
|
||||
const struct v4l2_ctrl_ops *ops = &dw9714_vcm_ctrl_ops;
|
||||
struct i2c_client *client = dev_vcm->client;
|
||||
|
||||
v4l2_ctrl_handler_init(hdl, 1);
|
||||
|
||||
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
|
||||
0, DW9714_MAX_FOCUS_POS, DW9714_CTRL_STEPS, 0);
|
||||
|
||||
if (hdl->error)
|
||||
dev_err(&client->dev, "%s fail error: 0x%x\n",
|
||||
__func__, hdl->error);
|
||||
dev_vcm->sd.ctrl_handler = hdl;
|
||||
return hdl->error;
|
||||
}
|
||||
|
||||
static int dw9714_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *devid)
|
||||
{
|
||||
struct dw9714_device *dw9714_dev;
|
||||
int rval;
|
||||
|
||||
dw9714_dev = devm_kzalloc(&client->dev, sizeof(*dw9714_dev),
|
||||
GFP_KERNEL);
|
||||
if (dw9714_dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
dw9714_dev->client = client;
|
||||
|
||||
v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
|
||||
dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
dw9714_dev->sd.internal_ops = &dw9714_int_ops;
|
||||
|
||||
rval = dw9714_init_controls(dw9714_dev);
|
||||
if (rval)
|
||||
goto err_cleanup;
|
||||
|
||||
rval = media_entity_pads_init(&dw9714_dev->sd.entity, 0, NULL);
|
||||
if (rval < 0)
|
||||
goto err_cleanup;
|
||||
|
||||
dw9714_dev->sd.entity.function = MEDIA_ENT_F_LENS;
|
||||
|
||||
rval = v4l2_async_register_subdev(&dw9714_dev->sd);
|
||||
if (rval < 0)
|
||||
goto err_cleanup;
|
||||
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup:
|
||||
dw9714_subdev_cleanup(dw9714_dev);
|
||||
dev_err(&client->dev, "Probe failed: %d\n", rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int dw9714_remove(struct i2c_client *client)
|
||||
{
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
dw9714_subdev_cleanup(dw9714_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the vcm position, so it consumes least current
|
||||
* The lens position is gradually moved in units of DW9714_CTRL_STEPS,
|
||||
* to make the movements smoothly.
|
||||
*/
|
||||
static int __maybe_unused dw9714_vcm_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
|
||||
int ret, val;
|
||||
|
||||
for (val = dw9714_dev->current_val & ~(DW9714_CTRL_STEPS - 1);
|
||||
val >= 0; val -= DW9714_CTRL_STEPS) {
|
||||
ret = dw9714_i2c_write(client,
|
||||
DW9714_VAL(val, DW9714_DEFAULT_S));
|
||||
if (ret)
|
||||
dev_err_once(dev, "%s I2C failure: %d", __func__, ret);
|
||||
usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the vcm position to the value set by the user
|
||||
* through v4l2_ctrl_ops s_ctrl handler
|
||||
* The lens position is gradually moved in units of DW9714_CTRL_STEPS,
|
||||
* to make the movements smoothly.
|
||||
*/
|
||||
static int __maybe_unused dw9714_vcm_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
|
||||
int ret, val;
|
||||
|
||||
for (val = dw9714_dev->current_val % DW9714_CTRL_STEPS;
|
||||
val < dw9714_dev->current_val + DW9714_CTRL_STEPS - 1;
|
||||
val += DW9714_CTRL_STEPS) {
|
||||
ret = dw9714_i2c_write(client,
|
||||
DW9714_VAL(val, DW9714_DEFAULT_S));
|
||||
if (ret)
|
||||
dev_err_ratelimited(dev, "%s I2C failure: %d",
|
||||
__func__, ret);
|
||||
usleep_range(DW9714_CTRL_DELAY_US, DW9714_CTRL_DELAY_US + 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id dw9714_acpi_match[] = {
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, dw9714_acpi_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id dw9714_id_table[] = {
|
||||
{DW9714_NAME, 0},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, dw9714_id_table);
|
||||
|
||||
static const struct dev_pm_ops dw9714_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(dw9714_vcm_suspend, dw9714_vcm_resume)
|
||||
SET_RUNTIME_PM_OPS(dw9714_vcm_suspend, dw9714_vcm_resume, NULL)
|
||||
};
|
||||
|
||||
static struct i2c_driver dw9714_i2c_driver = {
|
||||
.driver = {
|
||||
.name = DW9714_NAME,
|
||||
.pm = &dw9714_pm_ops,
|
||||
.acpi_match_table = ACPI_PTR(dw9714_acpi_match),
|
||||
},
|
||||
.probe = dw9714_probe,
|
||||
.remove = dw9714_remove,
|
||||
.id_table = dw9714_id_table,
|
||||
};
|
||||
|
||||
module_i2c_driver(dw9714_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
|
||||
MODULE_AUTHOR("Jian Xu Zheng <jian.xu.zheng@intel.com>");
|
||||
MODULE_AUTHOR("Yuning Pu <yuning.pu@intel.com>");
|
||||
MODULE_AUTHOR("Jouni Ukkonen <jouni.ukkonen@intel.com>");
|
||||
MODULE_AUTHOR("Tommi Franttila <tommi.franttila@intel.com>");
|
||||
MODULE_DESCRIPTION("DW9714 VCM driver");
|
||||
MODULE_LICENSE("GPL v2");
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Maxim Integrated MAX2175 RF to Bits tuner driver
|
||||
*
|
||||
* This driver & most of the hard coded values are based on the reference
|
||||
* application delivered by Maxim for this device.
|
||||
*
|
||||
* Copyright (C) 2016 Maxim Integrated Products
|
||||
* Copyright (C) 2017 Renesas Electronics Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MAX2175_H__
|
||||
#define __MAX2175_H__
|
||||
|
||||
#define MAX2175_EU_XTAL_FREQ 36864000 /* In Hz */
|
||||
#define MAX2175_NA_XTAL_FREQ 40186125 /* In Hz */
|
||||
|
||||
enum max2175_region {
|
||||
MAX2175_REGION_EU = 0, /* Europe */
|
||||
MAX2175_REGION_NA, /* North America */
|
||||
};
|
||||
|
||||
enum max2175_band {
|
||||
MAX2175_BAND_AM = 0,
|
||||
MAX2175_BAND_FM,
|
||||
MAX2175_BAND_VHF,
|
||||
MAX2175_BAND_L,
|
||||
};
|
||||
|
||||
enum max2175_eu_mode {
|
||||
/* EU modes */
|
||||
MAX2175_EU_FM_1_2 = 0,
|
||||
MAX2175_DAB_1_2,
|
||||
|
||||
/*
|
||||
* Other possible modes to add in future
|
||||
* MAX2175_DAB_1_0,
|
||||
* MAX2175_DAB_1_3,
|
||||
* MAX2175_EU_FM_2_2,
|
||||
* MAX2175_EU_FMHD_4_0,
|
||||
* MAX2175_EU_AM_1_0,
|
||||
* MAX2175_EU_AM_2_2,
|
||||
*/
|
||||
};
|
||||
|
||||
enum max2175_na_mode {
|
||||
/* NA modes */
|
||||
MAX2175_NA_FM_1_0 = 0,
|
||||
MAX2175_NA_FM_2_0,
|
||||
|
||||
/*
|
||||
* Other possible modes to add in future
|
||||
* MAX2175_NA_FMHD_1_0,
|
||||
* MAX2175_NA_FMHD_1_2,
|
||||
* MAX2175_NA_AM_1_0,
|
||||
* MAX2175_NA_AM_1_2,
|
||||
*/
|
||||
};
|
||||
|
||||
/* Supported I2S modes */
|
||||
enum {
|
||||
MAX2175_I2S_MODE0 = 0,
|
||||
MAX2175_I2S_MODE1,
|
||||
MAX2175_I2S_MODE2,
|
||||
MAX2175_I2S_MODE3,
|
||||
MAX2175_I2S_MODE4,
|
||||
};
|
||||
|
||||
/* Coefficient table groups */
|
||||
enum {
|
||||
MAX2175_CH_MSEL = 0,
|
||||
MAX2175_EQ_MSEL,
|
||||
MAX2175_AA_MSEL,
|
||||
};
|
||||
|
||||
/* HSLS LO injection polarity */
|
||||
enum {
|
||||
MAX2175_LO_BELOW_DESIRED = 0,
|
||||
MAX2175_LO_ABOVE_DESIRED,
|
||||
};
|
||||
|
||||
/* Channel FSM modes */
|
||||
enum max2175_csm_mode {
|
||||
MAX2175_LOAD_TO_BUFFER = 0,
|
||||
MAX2175_PRESET_TUNE,
|
||||
MAX2175_SEARCH,
|
||||
MAX2175_AF_UPDATE,
|
||||
MAX2175_JUMP_FAST_TUNE,
|
||||
MAX2175_CHECK,
|
||||
MAX2175_LOAD_AND_SWAP,
|
||||
MAX2175_END,
|
||||
MAX2175_BUFFER_PLUS_PRESET_TUNE,
|
||||
MAX2175_BUFFER_PLUS_SEARCH,
|
||||
MAX2175_BUFFER_PLUS_AF_UPDATE,
|
||||
MAX2175_BUFFER_PLUS_JUMP_FAST_TUNE,
|
||||
MAX2175_BUFFER_PLUS_CHECK,
|
||||
MAX2175_BUFFER_PLUS_LOAD_AND_SWAP,
|
||||
MAX2175_NO_ACTION
|
||||
};
|
||||
|
||||
#endif /* __MAX2175_H__ */
|
|
@ -655,6 +655,7 @@ restart:
|
|||
break;
|
||||
case 0: /* 4.5 */
|
||||
state->detected_std = V4L2_STD_MN;
|
||||
/* fall-through */
|
||||
default:
|
||||
no_second:
|
||||
state->second = msp3400c_carrier_detect_main[max1].cdo;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/log2.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
@ -28,7 +29,7 @@
|
|||
#include <media/i2c/mt9v032.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
|
||||
/* The first four rows are black rows. The active area spans 753x481 pixels. */
|
||||
|
@ -979,7 +980,7 @@ static struct mt9v032_platform_data *
|
|||
mt9v032_get_pdata(struct i2c_client *client)
|
||||
{
|
||||
struct mt9v032_platform_data *pdata = NULL;
|
||||
struct v4l2_of_endpoint endpoint;
|
||||
struct v4l2_fwnode_endpoint endpoint;
|
||||
struct device_node *np;
|
||||
struct property *prop;
|
||||
|
||||
|
@ -990,7 +991,7 @@ mt9v032_get_pdata(struct i2c_client *client)
|
|||
if (!np)
|
||||
return NULL;
|
||||
|
||||
if (v4l2_of_parse_endpoint(np, &endpoint) < 0)
|
||||
if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &endpoint) < 0)
|
||||
goto done;
|
||||
|
||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,9 +42,9 @@
|
|||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-image-sizes.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
|
||||
#define DRIVER_NAME "ov2659"
|
||||
|
@ -1308,7 +1308,8 @@ static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = {
|
|||
static int ov2659_detect(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
u8 pid, ver;
|
||||
u8 pid = 0;
|
||||
u8 ver = 0;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&client->dev, "%s:\n", __func__);
|
||||
|
@ -1346,7 +1347,7 @@ static struct ov2659_platform_data *
|
|||
ov2659_get_pdata(struct i2c_client *client)
|
||||
{
|
||||
struct ov2659_platform_data *pdata;
|
||||
struct v4l2_of_endpoint *bus_cfg;
|
||||
struct v4l2_fwnode_endpoint *bus_cfg;
|
||||
struct device_node *endpoint;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
|
||||
|
@ -1356,7 +1357,7 @@ ov2659_get_pdata(struct i2c_client *client)
|
|||
if (!endpoint)
|
||||
return NULL;
|
||||
|
||||
bus_cfg = v4l2_of_alloc_parse_endpoint(endpoint);
|
||||
bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint));
|
||||
if (IS_ERR(bus_cfg)) {
|
||||
pdata = NULL;
|
||||
goto done;
|
||||
|
@ -1376,7 +1377,7 @@ ov2659_get_pdata(struct i2c_client *client)
|
|||
pdata->link_frequency = bus_cfg->link_frequencies[0];
|
||||
|
||||
done:
|
||||
v4l2_of_free_endpoint(bus_cfg);
|
||||
v4l2_fwnode_endpoint_free(bus_cfg);
|
||||
of_node_put(endpoint);
|
||||
return pdata;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,7 +39,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
|
||||
#define OV5645_VOLTAGE_ANALOG 2800000
|
||||
|
@ -87,7 +87,7 @@ struct ov5645 {
|
|||
struct device *dev;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_of_endpoint ep;
|
||||
struct v4l2_fwnode_endpoint ep;
|
||||
struct v4l2_mbus_framefmt fmt;
|
||||
struct v4l2_rect crop;
|
||||
struct clk *xclk;
|
||||
|
@ -1102,7 +1102,8 @@ static int ov5645_probe(struct i2c_client *client,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = v4l2_of_parse_endpoint(endpoint, &ov5645->ep);
|
||||
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
|
||||
&ov5645->ep);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "parsing endpoint node failed\n");
|
||||
return ret;
|
||||
|
|
|
@ -25,12 +25,13 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-image-sizes.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/v4l2-of.h>
|
||||
|
||||
#define SENSOR_NAME "ov5647"
|
||||
|
||||
|
@ -510,7 +511,7 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
|
|||
|
||||
static int ov5647_parse_dt(struct device_node *np)
|
||||
{
|
||||
struct v4l2_of_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct device_node *ep;
|
||||
|
||||
int ret;
|
||||
|
@ -519,7 +520,7 @@ static int ov5647_parse_dt(struct device_node *np)
|
|||
if (!ep)
|
||||
return -EINVAL;
|
||||
|
||||
ret = v4l2_of_parse_endpoint(ep, &bus_cfg);
|
||||
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
|
||||
|
||||
of_node_put(ep);
|
||||
return ret;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/media.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -35,7 +36,7 @@
|
|||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/i2c/s5c73m3.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
#include "s5c73m3.h"
|
||||
|
||||
|
@ -1602,7 +1603,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
|
|||
const struct s5c73m3_platform_data *pdata = dev->platform_data;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct device_node *node_ep;
|
||||
struct v4l2_of_endpoint ep;
|
||||
struct v4l2_fwnode_endpoint ep;
|
||||
int ret;
|
||||
|
||||
if (!node) {
|
||||
|
@ -1639,7 +1640,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ret = v4l2_of_parse_endpoint(node_ep, &ep);
|
||||
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
|
||||
of_node_put(node_ep);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
|
@ -1841,7 +1841,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
|
|||
{
|
||||
struct device_node *node = dev->of_node;
|
||||
struct device_node *node_ep;
|
||||
struct v4l2_of_endpoint ep;
|
||||
struct v4l2_fwnode_endpoint ep;
|
||||
int ret;
|
||||
|
||||
if (!node) {
|
||||
|
@ -1868,7 +1868,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = v4l2_of_parse_endpoint(node_ep, &ep);
|
||||
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node_ep), &ep);
|
||||
of_node_put(node_ep);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -838,7 +838,7 @@ static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
|
|||
|
||||
if (s5k6aa->s_power)
|
||||
ret = s5k6aa->s_power(1);
|
||||
usleep_range(4000, 4000);
|
||||
usleep_range(4000, 5000);
|
||||
|
||||
if (s5k6aa_gpio_deassert(s5k6aa, RST))
|
||||
msleep(20);
|
||||
|
|
|
@ -3,5 +3,6 @@ config VIDEO_SMIAPP
|
|||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select VIDEO_SMIAPP_PLL
|
||||
select V4L2_FWNODE
|
||||
---help---
|
||||
This is a generic driver for SMIA++/SMIA camera modules.
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smiapp.h>
|
||||
#include <linux/v4l2-mediabus.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-of.h>
|
||||
|
||||
#include "smiapp.h"
|
||||
|
||||
|
@ -2784,19 +2785,20 @@ static int __maybe_unused smiapp_resume(struct device *dev)
|
|||
static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
|
||||
{
|
||||
struct smiapp_hwconfig *hwcfg;
|
||||
struct v4l2_of_endpoint *bus_cfg;
|
||||
struct device_node *ep;
|
||||
struct v4l2_fwnode_endpoint *bus_cfg;
|
||||
struct fwnode_handle *ep;
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
int i;
|
||||
int rval;
|
||||
|
||||
if (!dev->of_node)
|
||||
if (!fwnode)
|
||||
return dev->platform_data;
|
||||
|
||||
ep = of_graph_get_next_endpoint(dev->of_node, NULL);
|
||||
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
|
||||
if (!ep)
|
||||
return NULL;
|
||||
|
||||
bus_cfg = v4l2_of_alloc_parse_endpoint(ep);
|
||||
bus_cfg = v4l2_fwnode_endpoint_alloc_parse(ep);
|
||||
if (IS_ERR(bus_cfg))
|
||||
goto out_err;
|
||||
|
||||
|
@ -2817,11 +2819,10 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
|
|||
dev_dbg(dev, "lanes %u\n", hwcfg->lanes);
|
||||
|
||||
/* NVM size is not mandatory */
|
||||
of_property_read_u32(dev->of_node, "nokia,nvm-size",
|
||||
&hwcfg->nvm_size);
|
||||
fwnode_property_read_u32(fwnode, "nokia,nvm-size", &hwcfg->nvm_size);
|
||||
|
||||
rval = of_property_read_u32(dev->of_node, "clock-frequency",
|
||||
&hwcfg->ext_clk);
|
||||
rval = fwnode_property_read_u32(fwnode, "clock-frequency",
|
||||
&hwcfg->ext_clk);
|
||||
if (rval) {
|
||||
dev_warn(dev, "can't get clock-frequency\n");
|
||||
goto out_err;
|
||||
|
@ -2846,13 +2847,13 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
|
|||
dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]);
|
||||
}
|
||||
|
||||
v4l2_of_free_endpoint(bus_cfg);
|
||||
of_node_put(ep);
|
||||
v4l2_fwnode_endpoint_free(bus_cfg);
|
||||
fwnode_handle_put(ep);
|
||||
return hwcfg;
|
||||
|
||||
out_err:
|
||||
v4l2_of_free_endpoint(bus_cfg);
|
||||
of_node_put(ep);
|
||||
v4l2_fwnode_endpoint_free(bus_cfg);
|
||||
fwnode_handle_put(ep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -709,6 +709,7 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
|
|||
switch (mf->code) {
|
||||
case MEDIA_BUS_FMT_Y10_1X10:
|
||||
mf->code = MEDIA_BUS_FMT_Y8_1X8;
|
||||
/* fall through */
|
||||
case MEDIA_BUS_FMT_Y8_1X8:
|
||||
case MEDIA_BUS_FMT_YVYU8_2X8:
|
||||
case MEDIA_BUS_FMT_YUYV8_2X8:
|
||||
|
@ -718,6 +719,7 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
|
|||
break;
|
||||
default:
|
||||
mf->code = MEDIA_BUS_FMT_SBGGR8_1X8;
|
||||
/* fall through */
|
||||
case MEDIA_BUS_FMT_SBGGR8_1X8:
|
||||
mf->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
break;
|
||||
|
|
|
@ -1047,11 +1047,13 @@ static int ov772x_probe(struct i2c_client *client,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
I2C_FUNC_PROTOCOL_MANGLING)) {
|
||||
dev_err(&adapter->dev,
|
||||
"I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n");
|
||||
"I2C-Adapter doesn't support SMBUS_BYTE_DATA or PROTOCOL_MANGLING\n");
|
||||
return -EIO;
|
||||
}
|
||||
client->flags |= I2C_CLIENT_SCCB;
|
||||
|
||||
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/v4l2-dv-timings.h>
|
||||
|
@ -41,7 +43,7 @@
|
|||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/i2c/tc358743.h>
|
||||
|
||||
#include "tc358743_regs.h"
|
||||
|
@ -61,6 +63,8 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
#define I2C_MAX_XFER_SIZE (EDID_BLOCK_SIZE + 2)
|
||||
|
||||
#define POLL_INTERVAL_MS 1000
|
||||
|
||||
static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
|
||||
.type = V4L2_DV_BT_656_1120,
|
||||
/* keep this initialization for compatibility with GCC < 4.4.6 */
|
||||
|
@ -76,7 +80,7 @@ static const struct v4l2_dv_timings_cap tc358743_timings_cap = {
|
|||
|
||||
struct tc358743_state {
|
||||
struct tc358743_platform_data pdata;
|
||||
struct v4l2_of_bus_mipi_csi2 bus;
|
||||
struct v4l2_fwnode_bus_mipi_csi2 bus;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
|
@ -91,6 +95,9 @@ struct tc358743_state {
|
|||
|
||||
struct delayed_work delayed_work_enable_hotplug;
|
||||
|
||||
struct timer_list timer;
|
||||
struct work_struct work_i2c_poll;
|
||||
|
||||
/* edid */
|
||||
u8 edid_blocks_written;
|
||||
|
||||
|
@ -1296,7 +1303,6 @@ static int tc358743_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
|
|||
tc358743_csi_err_int_handler(sd, handled);
|
||||
|
||||
i2c_wr16(sd, INTSTATUS, MASK_CSI_INT);
|
||||
intstatus &= ~MASK_CSI_INT;
|
||||
}
|
||||
|
||||
intstatus = i2c_rd16(sd, INTSTATUS);
|
||||
|
@ -1319,6 +1325,24 @@ static irqreturn_t tc358743_irq_handler(int irq, void *dev_id)
|
|||
return handled ? IRQ_HANDLED : IRQ_NONE;
|
||||
}
|
||||
|
||||
static void tc358743_irq_poll_timer(unsigned long arg)
|
||||
{
|
||||
struct tc358743_state *state = (struct tc358743_state *)arg;
|
||||
|
||||
schedule_work(&state->work_i2c_poll);
|
||||
|
||||
mod_timer(&state->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
|
||||
}
|
||||
|
||||
static void tc358743_work_i2c_poll(struct work_struct *work)
|
||||
{
|
||||
struct tc358743_state *state = container_of(work,
|
||||
struct tc358743_state, work_i2c_poll);
|
||||
bool handled;
|
||||
|
||||
tc358743_isr(&state->sd, 0, &handled);
|
||||
}
|
||||
|
||||
static int tc358743_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
struct v4l2_event_subscription *sub)
|
||||
{
|
||||
|
@ -1473,6 +1497,23 @@ static int tc358743_s_stream(struct v4l2_subdev *sd, int enable)
|
|||
|
||||
/* --------------- PAD OPS --------------- */
|
||||
|
||||
static int tc358743_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
{
|
||||
switch (code->index) {
|
||||
case 0:
|
||||
code->code = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
break;
|
||||
case 1:
|
||||
code->code = MEDIA_BUS_FMT_UYVY8_1X16;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tc358743_get_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_format *format)
|
||||
|
@ -1642,6 +1683,7 @@ static const struct v4l2_subdev_video_ops tc358743_video_ops = {
|
|||
};
|
||||
|
||||
static const struct v4l2_subdev_pad_ops tc358743_pad_ops = {
|
||||
.enum_mbus_code = tc358743_enum_mbus_code,
|
||||
.set_fmt = tc358743_set_fmt,
|
||||
.get_fmt = tc358743_get_fmt,
|
||||
.get_edid = tc358743_g_edid,
|
||||
|
@ -1695,7 +1737,7 @@ static void tc358743_gpio_reset(struct tc358743_state *state)
|
|||
static int tc358743_probe_of(struct tc358743_state *state)
|
||||
{
|
||||
struct device *dev = &state->i2c_client->dev;
|
||||
struct v4l2_of_endpoint *endpoint;
|
||||
struct v4l2_fwnode_endpoint *endpoint;
|
||||
struct device_node *ep;
|
||||
struct clk *refclk;
|
||||
u32 bps_pr_lane;
|
||||
|
@ -1715,7 +1757,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
endpoint = v4l2_of_alloc_parse_endpoint(ep);
|
||||
endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
|
||||
if (IS_ERR(endpoint)) {
|
||||
dev_err(dev, "failed to parse endpoint\n");
|
||||
return PTR_ERR(endpoint);
|
||||
|
@ -1730,7 +1772,11 @@ static int tc358743_probe_of(struct tc358743_state *state)
|
|||
|
||||
state->bus = endpoint->bus.mipi_csi2;
|
||||
|
||||
clk_prepare_enable(refclk);
|
||||
ret = clk_prepare_enable(refclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed! to enable clock\n");
|
||||
goto free_endpoint;
|
||||
}
|
||||
|
||||
state->pdata.refclk_hz = clk_get_rate(refclk);
|
||||
state->pdata.ddc5v_delay = DDC5V_DELAY_100_MS;
|
||||
|
@ -1803,7 +1849,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
|
|||
disable_clk:
|
||||
clk_disable_unprepare(refclk);
|
||||
free_endpoint:
|
||||
v4l2_of_free_endpoint(endpoint);
|
||||
v4l2_fwnode_endpoint_free(endpoint);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
@ -1887,6 +1933,8 @@ static int tc358743_probe(struct i2c_client *client,
|
|||
if (err < 0)
|
||||
goto err_hdl;
|
||||
|
||||
state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
|
||||
sd->dev = &client->dev;
|
||||
err = v4l2_async_register_subdev(sd);
|
||||
if (err < 0)
|
||||
|
@ -1901,7 +1949,6 @@ static int tc358743_probe(struct i2c_client *client,
|
|||
|
||||
tc358743_s_dv_timings(sd, &default_timing);
|
||||
|
||||
state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
tc358743_set_csi_color_space(sd);
|
||||
|
||||
tc358743_init_interrupts(sd);
|
||||
|
@ -1914,6 +1961,14 @@ static int tc358743_probe(struct i2c_client *client,
|
|||
"tc358743", state);
|
||||
if (err)
|
||||
goto err_work_queues;
|
||||
} else {
|
||||
INIT_WORK(&state->work_i2c_poll,
|
||||
tc358743_work_i2c_poll);
|
||||
state->timer.data = (unsigned long)state;
|
||||
state->timer.function = tc358743_irq_poll_timer;
|
||||
state->timer.expires = jiffies +
|
||||
msecs_to_jiffies(POLL_INTERVAL_MS);
|
||||
add_timer(&state->timer);
|
||||
}
|
||||
|
||||
tc358743_enable_interrupts(sd, tx_5v_power_present(sd));
|
||||
|
@ -1929,6 +1984,8 @@ static int tc358743_probe(struct i2c_client *client,
|
|||
return 0;
|
||||
|
||||
err_work_queues:
|
||||
if (!state->i2c_client->irq)
|
||||
flush_work(&state->work_i2c_poll);
|
||||
cancel_delayed_work(&state->delayed_work_enable_hotplug);
|
||||
mutex_destroy(&state->confctl_mutex);
|
||||
err_hdl:
|
||||
|
@ -1942,6 +1999,10 @@ static int tc358743_remove(struct i2c_client *client)
|
|||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct tc358743_state *state = to_state(sd);
|
||||
|
||||
if (!state->i2c_client->irq) {
|
||||
del_timer_sync(&state->timer);
|
||||
flush_work(&state->work_i2c_poll);
|
||||
}
|
||||
cancel_delayed_work(&state->delayed_work_enable_hotplug);
|
||||
v4l2_async_unregister_subdev(sd);
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/i2c/tvp514x.h>
|
||||
#include <media/media-entity.h>
|
||||
|
@ -998,7 +998,7 @@ static struct tvp514x_platform_data *
|
|||
tvp514x_get_pdata(struct i2c_client *client)
|
||||
{
|
||||
struct tvp514x_platform_data *pdata = NULL;
|
||||
struct v4l2_of_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct device_node *endpoint;
|
||||
unsigned int flags;
|
||||
|
||||
|
@ -1009,7 +1009,7 @@ tvp514x_get_pdata(struct i2c_client *client)
|
|||
if (!endpoint)
|
||||
return NULL;
|
||||
|
||||
if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
|
||||
if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
|
||||
goto done;
|
||||
|
||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <media/v4l2-async.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <media/v4l2-mc.h>
|
||||
|
||||
#include "tvp5150_reg.h"
|
||||
|
@ -1358,7 +1359,7 @@ static int tvp5150_init(struct i2c_client *c)
|
|||
|
||||
static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
|
||||
{
|
||||
struct v4l2_of_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct device_node *ep;
|
||||
#ifdef CONFIG_MEDIA_CONTROLLER
|
||||
struct device_node *connectors, *child;
|
||||
|
@ -1373,7 +1374,7 @@ static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np)
|
|||
if (!ep)
|
||||
return -EINVAL;
|
||||
|
||||
ret = v4l2_of_parse_endpoint(ep, &bus_cfg);
|
||||
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-of.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
#include "tvp7002_reg.h"
|
||||
|
||||
|
@ -889,7 +889,7 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
|
|||
static struct tvp7002_config *
|
||||
tvp7002_get_pdata(struct i2c_client *client)
|
||||
{
|
||||
struct v4l2_of_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct tvp7002_config *pdata = NULL;
|
||||
struct device_node *endpoint;
|
||||
unsigned int flags;
|
||||
|
@ -901,7 +901,7 @@ tvp7002_get_pdata(struct i2c_client *client)
|
|||
if (!endpoint)
|
||||
return NULL;
|
||||
|
||||
if (v4l2_of_parse_endpoint(endpoint, &bus_cfg))
|
||||
if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg))
|
||||
goto done;
|
||||
|
||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/media-entity.h>
|
||||
#include <media/media-device.h>
|
||||
|
@ -386,6 +387,41 @@ struct media_entity *media_graph_walk_next(struct media_graph *graph)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(media_graph_walk_next);
|
||||
|
||||
int media_entity_get_fwnode_pad(struct media_entity *entity,
|
||||
struct fwnode_handle *fwnode,
|
||||
unsigned long direction_flags)
|
||||
{
|
||||
struct fwnode_endpoint endpoint;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (!entity->ops || !entity->ops->get_fwnode_pad) {
|
||||
for (i = 0; i < entity->num_pads; i++) {
|
||||
if (entity->pads[i].flags & direction_flags)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ret = fwnode_graph_parse_endpoint(fwnode, &endpoint);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = entity->ops->get_fwnode_pad(&endpoint);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret >= entity->num_pads)
|
||||
return -ENXIO;
|
||||
|
||||
if (!(entity->pads[ret].flags & direction_flags))
|
||||
return -ENXIO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_entity_get_fwnode_pad);
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Pipeline management
|
||||
*/
|
||||
|
@ -530,8 +566,13 @@ void __media_pipeline_stop(struct media_entity *entity)
|
|||
struct media_graph *graph = &entity->pipe->graph;
|
||||
struct media_pipeline *pipe = entity->pipe;
|
||||
|
||||
/*
|
||||
* If the following check fails, the driver has performed an
|
||||
* unbalanced call to media_pipeline_stop()
|
||||
*/
|
||||
if (WARN_ON(!pipe))
|
||||
return;
|
||||
|
||||
WARN_ON(!pipe->streaming_count);
|
||||
media_graph_walk_start(graph, entity);
|
||||
|
||||
while ((entity = media_graph_walk_next(graph))) {
|
||||
|
|
|
@ -637,6 +637,7 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct
|
|||
goto free_mem_and_exit;
|
||||
}
|
||||
dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
|
||||
break;
|
||||
default:
|
||||
result = -EOPNOTSUPP;
|
||||
}
|
||||
|
|
|
@ -205,6 +205,8 @@ void cobalt_pcie_status_show(struct cobalt *cobalt)
|
|||
|
||||
offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
|
||||
bus_offset = pci_find_capability(pci_bus_dev, PCI_CAP_ID_EXP);
|
||||
if (!offset || !bus_offset)
|
||||
return;
|
||||
|
||||
/* Device */
|
||||
pci_read_config_dword(pci_dev, offset + PCI_EXP_DEVCAP, &capa);
|
||||
|
|
|
@ -257,14 +257,16 @@ static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
|
|||
{
|
||||
struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
|
||||
unsigned long flags;
|
||||
unsigned char *dma_area = NULL;
|
||||
|
||||
spin_lock_irqsave(&cxsc->slock, flags);
|
||||
if (substream->runtime->dma_area) {
|
||||
dprintk("freeing pcm capture region\n");
|
||||
vfree(substream->runtime->dma_area);
|
||||
dma_area = substream->runtime->dma_area;
|
||||
substream->runtime->dma_area = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&cxsc->slock, flags);
|
||||
vfree(dma_area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ static int yuan_mpc718_mt352_reqfw(struct cx18_stream *stream,
|
|||
}
|
||||
|
||||
if (ret) {
|
||||
CX18_ERR("The MPC718 board variant with the MT352 DVB-Tdemodualtor will not work without it\n");
|
||||
CX18_ERR("The MPC718 board variant with the MT352 DVB-T demodulator will not work without it\n");
|
||||
CX18_ERR("Run 'linux/Documentation/dvb/get_dvb_firmware mpc718' if you need the firmware\n");
|
||||
}
|
||||
return ret;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue