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:
Linus Torvalds 2017-07-06 11:15:19 -07:00
commit 0b49ce5a40
348 changed files with 40498 additions and 5130 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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>;
};
};
};

View File

@ -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>;
};
};
};
};

View File

@ -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;

View File

@ -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>;
};
};

View File

@ -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>;
};
};

View File

@ -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

View File

@ -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>;
};
};
};

View File

@ -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:

View File

@ -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";
};

View File

@ -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>;
};
};
};

View File

@ -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:

View File

@ -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>;
};
};
};
};

View File

@ -30,6 +30,7 @@ Electricity
-micro-ohms : micro Ohms
-microwatt-hours: micro Watt-hours
-microvolt : micro volts
-picofarads : picofarads
Temperature
----------------------------------------

View File

@ -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);

View File

@ -19,7 +19,7 @@ Video4Linux devices
v4l2-mc
v4l2-mediabus
v4l2-mem2mem
v4l2-of
v4l2-fwnode
v4l2-rect
v4l2-tuner
v4l2-common

View File

@ -0,0 +1,3 @@
V4L2 fwnode kAPI
^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-fwnode.h

View File

@ -1,3 +0,0 @@
V4L2 Open Firmware kAPI
^^^^^^^^^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-of.h

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}|

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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
============

View File

@ -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
============

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 @@ void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
}
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 @@ static int cec_config_thread_func(void *arg)
/* 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;
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb
*
* @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 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
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 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
*
* @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;

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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,

View File

@ -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;
}

View File

@ -493,8 +493,8 @@ static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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", },

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

291
drivers/media/i2c/dw9714.c Normal file
View File

@ -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");

1453
drivers/media/i2c/max2175.c Normal file

File diff suppressed because it is too large Load Diff

109
drivers/media/i2c/max2175.h Normal file
View File

@ -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__ */

View File

@ -655,6 +655,7 @@ int msp3400c_thread(void *data)
break;
case 0: /* 4.5 */
state->detected_std = V4L2_STD_MN;
/* fall-through */
default:
no_second:
state->second = msp3400c_carrier_detect_main[max1].cdo;

View File

@ -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);

1816
drivers/media/i2c/ov13858.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

2344
drivers/media/i2c/ov5640.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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))) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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