mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
media updates for v5.6-rc1
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAl40SYEACgkQCF8+vY7k 4RU4TQ/8CgWj2+0uMRyIGpggB7B82vBPRqfHr4DIcZzbLSkdDkeDtrEfM5058cUc y3NpW9djmcqDMPvOZKFAkb03Bd+mtv89kI72RBTT2mVwCfySYa02K63RqgDg2aFU FScPUXlwB8hmZG6BpDlMiykJY1SVyhpb9R2f/7scgJ0ZKVwkKRMmLC5/I5A1IbFX WpoqNzRmT07bZJyDdm5RkzxHdM1EP0flMsqWJb3O2aWqeAw9u9+issk+Uv+cMGR+ 70+pmE/6qeurQjS9OHRhrSkf4HjybeByATfgSnONqNrWBtQXgBrHI2TjmT2NvNqV kWfsprM1GNPhsLveG6JYKGSNwZK6BHxuUULIjXAr1ocRrae2jVZ7/SZkAvnvzO3v hnb2HwgMBkQSctcl4EJDJeLIc1HgIKbZ7D/mFj7N9Mk3Kn7AqcLNHBv+GMunCPFl yXNq23ELfxC1HpmQPVhXNM/UaaO5MZCSvOD3MDObcjrxtv4b2bovi6ACDUTgGUNL sDozTurG2p1VeGupUnzia62gfb0/fjZ2WBk7RRp8E2K4/93YNEeMA9wgF0E8b4YQ SDQcDF1EtsAPF3msiXBC5FSFG42Ly7Ry04fl0v4lAle/0bPamEdQJ2CMVa1ux2Kp MRxI39CbRqtoIUbpKzTeInh/FvDDU22TimBKc5sg9d29Hk6y+Yk= =sGdY -----END PGP SIGNATURE----- Merge tag 'media/v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - New staging driver for Rockship ISPv1 unit - New staging driver for Rockchip MIPI Synopsys DPHY RX0 - y2038 fixes at V4L2 API (backward-compatible) - A dvb core fix when receiving invalid EIT sections - Some clang-specific warnings got fixed - Added support for touch V4L2 interface at vivid - Several drivers were converted to use the new i2c_new_scanned_device() kAPI - Added sm1 support at meson's vdec driver - Several other driver cleanups, fixes and improvements * tag 'media/v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (207 commits) media: staging/intel-ipu3: remove TODO item about acronyms media: v4l2-fwnode: Print the node name while parsing endpoints media: Revert "media: staging/intel-ipu3: make imgu use fixed running mode" media: mt9v111: constify copied structure media: platform: VIDEO_MEDIATEK_JPEG can also depend on MTK_IOMMU media: uvcvideo: Add a quirk to force GEO GC6500 Camera bits-per-pixel value media: uvcvideo: Avoid cyclic entity chains due to malformed USB descriptors media: hantro: fix post-processing NULL pointer dereference media: rcar-vin: Use correct pixel format when aligning format media: MAINTAINERS: add entry for Rockchip ISP1 driver media: staging: rkisp1: add TODO file for staging media: staging: rkisp1: add document for rkisp1 meta buffer format media: staging: rkisp1: add output device for parameters media: staging: rkisp1: add capture device for statistics media: staging: rkisp1: add user space ABI definitions media: staging: rkisp1: add streaming paths media: staging: rkisp1: add Rockchip ISP1 base driver media: staging: phy-rockchip-dphy-rx0: add Rockchip MIPI Synopsys DPHY RX0 driver media: staging: dt-bindings: add Rockchip MIPI RX D-PHY RX0 yaml bindings media: staging: dt-bindings: add Rockchip ISP1 yaml bindings ...
This commit is contained in:
commit
846de71bed
@ -16,7 +16,15 @@ description: |-
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: allwinner,sun7i-a20-csi0
|
||||
oneOf:
|
||||
- const: allwinner,sun4i-a10-csi1
|
||||
- const: allwinner,sun7i-a20-csi0
|
||||
- items:
|
||||
- const: allwinner,sun7i-a20-csi1
|
||||
- const: allwinner,sun4i-a10-csi1
|
||||
- items:
|
||||
- const: allwinner,sun8i-r40-csi0
|
||||
- const: allwinner,sun7i-a20-csi0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -25,12 +33,16 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- description: The CSI interface clock
|
||||
- description: The CSI ISP clock
|
||||
- description: The CSI DRAM clock
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: bus
|
||||
- const: isp
|
||||
|
141
Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
Normal file
141
Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
Normal file
@ -0,0 +1,141 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright 2019 BayLibre, SAS
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/media/amlogic,gx-vdec.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Amlogic Video Decoder
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <narmstrong@baylibre.com>
|
||||
- Maxime Jourdan <mjourdan@baylibre.com>
|
||||
|
||||
description: |
|
||||
The video decoding IP lies within the DOS memory region,
|
||||
except for the hardware bitstream parser that makes use of an undocumented
|
||||
region.
|
||||
|
||||
It makes use of the following blocks:
|
||||
- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks
|
||||
then feed from this VIFIFO.
|
||||
- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, MJPEG, H.263, H.264, VC-1.
|
||||
- VDEC_HEVC can decode HEVC and VP9.
|
||||
|
||||
Both VDEC_1 and VDEC_HEVC share the "vdec" IRQ and as such cannot run
|
||||
concurrently.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,gxbb-vdec # GXBB (S905)
|
||||
- amlogic,gxl-vdec # GXL (S905X, S905D)
|
||||
- amlogic,gxm-vdec # GXM (S912)
|
||||
- const: amlogic,gx-vdec
|
||||
- enum:
|
||||
- amlogic,g12a-vdec # G12A (S905X2, S905D2)
|
||||
- amlogic,sm1-vdec # SM1 (S905X3, S905D3)
|
||||
|
||||
interrupts:
|
||||
minItems: 2
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: vdec
|
||||
- const: esparser
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: dos
|
||||
- const: esparser
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: esparser
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 4
|
||||
maxItems: 5
|
||||
items:
|
||||
- const: dos_parser
|
||||
- const: dos
|
||||
- const: vdec_1
|
||||
- const: vdec_hevc
|
||||
- const: vdec_hevcf
|
||||
|
||||
amlogic,ao-sysctrl:
|
||||
description: should point to the AOBUS sysctrl node
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
amlogic,canvas:
|
||||
description: should point to a canvas provider node
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,gx-vdec
|
||||
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
maxItems: 4
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,g12a-vdec
|
||||
- amlogic,sm1-vdec
|
||||
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
minItems: 5
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- amlogic,ao-sysctrl
|
||||
- amlogic,canvas
|
||||
|
||||
examples:
|
||||
- |
|
||||
vdec: video-decoder@c8820000 {
|
||||
compatible = "amlogic,gxl-vdec", "amlogic,gx-vdec";
|
||||
reg = <0xc8820000 0x10000>, <0xc110a580 0xe4>;
|
||||
reg-names = "dos", "esparser";
|
||||
interrupts = <44>, <32>;
|
||||
interrupt-names = "vdec", "esparser";
|
||||
clocks = <&clk_dos_parser> ,<&clk_dos>, <&clk_vdec_1>, <&clk_vdec_hevc>;
|
||||
clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
|
||||
resets = <&reset_parser>;
|
||||
reset-names = "esparser";
|
||||
amlogic,ao-sysctrl = <&sysctrl_AO>;
|
||||
amlogic,canvas = <&canvas>;
|
||||
};
|
@ -1,72 +0,0 @@
|
||||
Amlogic Video Decoder
|
||||
================================
|
||||
|
||||
The video decoding IP lies within the DOS memory region,
|
||||
except for the hardware bitstream parser that makes use of an undocumented
|
||||
region.
|
||||
|
||||
It makes use of the following blocks:
|
||||
|
||||
- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks
|
||||
then feed from this VIFIFO.
|
||||
- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, MJPEG, H.263, H.264, VC-1.
|
||||
- VDEC_HEVC can decode HEVC and VP9.
|
||||
|
||||
Both VDEC_1 and VDEC_HEVC share the "vdec" IRQ and as such cannot run
|
||||
concurrently.
|
||||
|
||||
Device Tree Bindings:
|
||||
---------------------
|
||||
|
||||
VDEC: Video Decoder
|
||||
--------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: value should be different for each SoC family as :
|
||||
- GXBB (S905) : "amlogic,gxbb-vdec"
|
||||
- GXL (S905X, S905D) : "amlogic,gxl-vdec"
|
||||
- GXM (S912) : "amlogic,gxm-vdec"
|
||||
followed by the common "amlogic,gx-vdec"
|
||||
- reg: base address and size of he following memory-mapped regions :
|
||||
- dos
|
||||
- esparser
|
||||
- reg-names: should contain the names of the previous memory regions
|
||||
- interrupts: should contain the following IRQs:
|
||||
- vdec
|
||||
- esparser
|
||||
- interrupt-names: should contain the names of the previous interrupts
|
||||
- amlogic,ao-sysctrl: should point to the AOBUS sysctrl node
|
||||
- amlogic,canvas: should point to a canvas provider node
|
||||
- clocks: should contain the following clocks :
|
||||
- dos_parser
|
||||
- dos
|
||||
- vdec_1
|
||||
- vdec_hevc
|
||||
- clock-names: should contain the names of the previous clocks
|
||||
- resets: should contain the parser reset
|
||||
- reset-names: should be "esparser"
|
||||
|
||||
Example:
|
||||
|
||||
vdec: video-codec@c8820000 {
|
||||
compatible = "amlogic,gxbb-vdec", "amlogic,gx-vdec";
|
||||
reg = <0x0 0xc8820000 0x0 0x10000>,
|
||||
<0x0 0xc110a580 0x0 0xe4>;
|
||||
reg-names = "dos", "esparser";
|
||||
|
||||
interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "vdec", "esparser";
|
||||
|
||||
amlogic,ao-sysctrl = <&sysctrl_AO>;
|
||||
amlogic,canvas = <&canvas>;
|
||||
|
||||
clocks = <&clkc CLKID_DOS_PARSER>,
|
||||
<&clkc CLKID_DOS>,
|
||||
<&clkc CLKID_VDEC_1>,
|
||||
<&clkc CLKID_VDEC_HEVC>;
|
||||
clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
|
||||
|
||||
resets = <&reset RESET_PARSER>;
|
||||
reset-names = "esparser";
|
||||
};
|
@ -1,7 +1,8 @@
|
||||
Device-Tree bindings for hix5hd2 ir IP
|
||||
|
||||
Required properties:
|
||||
- compatible: Should contain "hisilicon,hix5hd2-ir".
|
||||
- compatible: Should contain "hisilicon,hix5hd2-ir", or:
|
||||
- "hisilicon,hi3796cv300-ir" for Hi3796CV300 IR device.
|
||||
- reg: Base physical address of the controller and length of memory
|
||||
mapped region.
|
||||
- interrupts: interrupt-specifier for the sole interrupt generated by
|
||||
|
@ -13,6 +13,7 @@ on Gen3 and RZ/G2 platforms to a CSI-2 receiver.
|
||||
- "renesas,vin-r8a7743" for the R8A7743 device
|
||||
- "renesas,vin-r8a7744" for the R8A7744 device
|
||||
- "renesas,vin-r8a7745" for the R8A7745 device
|
||||
- "renesas,vin-r8a77470" for the R8A77470 device
|
||||
- "renesas,vin-r8a774a1" for the R8A774A1 device
|
||||
- "renesas,vin-r8a774b1" for the R8A774B1 device
|
||||
- "renesas,vin-r8a774c0" for the R8A774C0 device
|
||||
@ -41,9 +42,6 @@ on Gen3 and RZ/G2 platforms to a CSI-2 receiver.
|
||||
- interrupts: the interrupt for the device
|
||||
- clocks: Reference to the parent clock
|
||||
|
||||
Additionally, an alias named vinX will need to be created to specify
|
||||
which video input device this is.
|
||||
|
||||
The per-board settings for Gen2 and RZ/G1 platforms:
|
||||
|
||||
- port - sub-node describing a single endpoint connected to the VIN
|
||||
|
202
Documentation/devicetree/bindings/media/ti,cal.yaml
Normal file
202
Documentation/devicetree/bindings/media/ti,cal.yaml
Normal file
@ -0,0 +1,202 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/ti,cal.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments DRA72x CAMERA ADAPTATION LAYER (CAL) Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Benoit Parrot <bparrot@ti.com>
|
||||
|
||||
description: |-
|
||||
The Camera Adaptation Layer (CAL) is a key component for image capture
|
||||
applications. The capture module provides the system interface and the
|
||||
processing capability to connect CSI2 image-sensor modules to the
|
||||
DRA72x device.
|
||||
|
||||
CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes
|
||||
should contain a 'port' child node with child 'endpoint' node. Please
|
||||
refer to the bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
# for DRA72 controllers
|
||||
- ti,dra72-cal
|
||||
# for DRA72 controllers pre ES2.0
|
||||
- ti,dra72-pre-es2-cal
|
||||
# for DRA76 controllers
|
||||
- ti,dra76-cal
|
||||
# for AM654 controllers
|
||||
- ti,am654-cal
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: The CAL main register region
|
||||
- description: The RX Core0 (DPHY0) register region
|
||||
- description: The RX Core1 (DPHY1) register region
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: cal_top
|
||||
- const: cal_rx_core0
|
||||
- const: cal_rx_core1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
ti,camerrx-control:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle-array"
|
||||
description:
|
||||
phandle to the device control module and offset to the
|
||||
control_camerarx_core register
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: fck
|
||||
|
||||
power-domains:
|
||||
description:
|
||||
List of phandle and PM domain specifier as documented in
|
||||
Documentation/devicetree/bindings/power/power_domain.txt
|
||||
maxItems: 1
|
||||
|
||||
# See ./video-interfaces.txt for details
|
||||
ports:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
const: 0
|
||||
description: CSI2 Port #0
|
||||
|
||||
patternProperties:
|
||||
endpoint:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
clock-lanes:
|
||||
maxItems: 1
|
||||
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
remote-endpoint: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
port@1:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
const: 1
|
||||
description: CSI2 Port #1
|
||||
|
||||
patternProperties:
|
||||
endpoint:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
clock-lanes:
|
||||
maxItems: 1
|
||||
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
remote-endpoint: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- port@0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- ti,camerrx-control
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
cal: cal@4845b000 {
|
||||
compatible = "ti,dra72-cal";
|
||||
reg = <0x4845B000 0x400>,
|
||||
<0x4845B800 0x40>,
|
||||
<0x4845B900 0x40>;
|
||||
reg-names = "cal_top",
|
||||
"cal_rx_core0",
|
||||
"cal_rx_core1";
|
||||
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
ti,camerrx-control = <&scm_conf 0xE94>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csi2_0: port@0 {
|
||||
reg = <0>;
|
||||
csi2_phy0: endpoint {
|
||||
remote-endpoint = <&csi2_cam0>;
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
i2c5: i2c@4807c000 {
|
||||
clock-frequency = <400000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera-sensor@3c {
|
||||
compatible = "ovti,ov5640";
|
||||
reg = <0x3c>;
|
||||
|
||||
clocks = <&clk_ov5640_fixed>;
|
||||
clock-names = "xclk";
|
||||
|
||||
port {
|
||||
csi2_cam0: endpoint {
|
||||
remote-endpoint = <&csi2_phy0>;
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1,72 +0,0 @@
|
||||
Texas Instruments DRA72x CAMERA ADAPTATION LAYER (CAL)
|
||||
------------------------------------------------------
|
||||
|
||||
The Camera Adaptation Layer (CAL) is a key component for image capture
|
||||
applications. The capture module provides the system interface and the
|
||||
processing capability to connect CSI2 image-sensor modules to the
|
||||
DRA72x device.
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "ti,dra72-cal"
|
||||
- reg: CAL Top level, Receiver Core #0, Receiver Core #1 and Camera RX
|
||||
control address space
|
||||
- reg-names: cal_top, cal_rx_core0, cal_rx_core1, and camerrx_control
|
||||
registers
|
||||
- interrupts: should contain IRQ line for the CAL;
|
||||
|
||||
CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes
|
||||
should contain a 'port' child node with child 'endpoint' node. Please
|
||||
refer to the bindings defined in
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
|
||||
Example:
|
||||
cal: cal@4845b000 {
|
||||
compatible = "ti,dra72-cal";
|
||||
ti,hwmods = "cal";
|
||||
reg = <0x4845B000 0x400>,
|
||||
<0x4845B800 0x40>,
|
||||
<0x4845B900 0x40>,
|
||||
<0x4A002e94 0x4>;
|
||||
reg-names = "cal_top",
|
||||
"cal_rx_core0",
|
||||
"cal_rx_core1",
|
||||
"camerrx_control";
|
||||
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
csi2_0: port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
slave-mode;
|
||||
remote-endpoint = <&ar0330_1>;
|
||||
};
|
||||
};
|
||||
csi2_1: port@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
i2c5: i2c@4807c000 {
|
||||
ar0330@10 {
|
||||
compatible = "ti,ar0330";
|
||||
reg = <0x10>;
|
||||
|
||||
port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ar0330_1: endpoint {
|
||||
reg = <0>;
|
||||
clock-lanes = <1>;
|
||||
data-lanes = <0 2 3 4>;
|
||||
remote-endpoint = <&csi2_0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -15,8 +15,8 @@ The header file for this API is named ``dvb_frontend.h`` and located in
|
||||
Demodulator driver
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The demodulator driver is responsible to talk with the decoding part of the
|
||||
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with
|
||||
The demodulator driver is responsible for talking with the decoding part of the
|
||||
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
|
||||
tells what type of digital TV standards are supported, and points to a
|
||||
series of functions that allow the DVB core to command the hardware via
|
||||
the code under ``include/media/dvb_frontend.c``.
|
||||
@ -120,7 +120,7 @@ Satellite TV reception is::
|
||||
|
||||
.. |delta| unicode:: U+00394
|
||||
|
||||
The ``include/media/dvb_frontend.c`` has a kernel thread with is
|
||||
The ``include/media/dvb_frontend.c`` has a kernel thread which is
|
||||
responsible for tuning the device. It supports multiple algorithms to
|
||||
detect a channel, as defined at enum :c:func:`dvbfe_algo`.
|
||||
|
||||
@ -220,11 +220,11 @@ Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
|
||||
- As the gain is visible through the set of registers that adjust the gain,
|
||||
typically, this statistics is always available [#f3]_.
|
||||
|
||||
- Drivers should try to make it available all the times, as this statistics
|
||||
- Drivers should try to make it available all the times, as these statistics
|
||||
can be used when adjusting an antenna position and to check for troubles
|
||||
at the cabling.
|
||||
|
||||
.. [#f3] On a few devices, the gain keeps floating if no carrier.
|
||||
.. [#f3] On a few devices, the gain keeps floating if there is no carrier.
|
||||
On such devices, strength report should check first if carrier is
|
||||
detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
|
||||
and otherwise return the lowest possible value.
|
||||
@ -232,7 +232,7 @@ Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
|
||||
Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
|
||||
- Signal to Noise ratio for the main carrier.
|
||||
|
||||
- Signal to Noise measurement depends on the device. On some hardware, is
|
||||
- Signal to Noise measurement depends on the device. On some hardware, it is
|
||||
available when the main carrier is detected. On those hardware, CNR
|
||||
measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
|
||||
see :c:type:`fe_status`).
|
||||
@ -323,8 +323,8 @@ A typical example of the logic that handle status and statistics is::
|
||||
.read_status = foo_get_status_and_stats,
|
||||
};
|
||||
|
||||
Statistics collect
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Statistics collection
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
On almost all frontend hardware, the bit and byte counts are stored by
|
||||
the hardware after a certain amount of time or after the total bit/block
|
||||
|
@ -177,7 +177,7 @@ Available follower modes are:
|
||||
- ``CEC_MODE_MONITOR``
|
||||
- 0xe0
|
||||
- Put the file descriptor into monitor mode. Can only be used in
|
||||
combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,i
|
||||
combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
|
||||
otherwise the ``EINVAL`` error code will be returned.
|
||||
In monitor mode all messages this CEC
|
||||
device transmits and all messages it receives (both broadcast
|
||||
|
@ -81,7 +81,7 @@ for this ioctl call.
|
||||
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
|
||||
#define VIDEO_EVENT_DECODER_STOPPED 3
|
||||
#define VIDEO_EVENT_VSYNC 4
|
||||
__kernel_time_t timestamp;
|
||||
long timestamp;
|
||||
union {
|
||||
video_size_t size;
|
||||
unsigned int frame_rate; /* in frames per 1000sec */
|
||||
|
@ -170,7 +170,7 @@ VIDEO_GET_EVENT call.
|
||||
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
|
||||
#define VIDEO_EVENT_DECODER_STOPPED 3
|
||||
#define VIDEO_EVENT_VSYNC 4
|
||||
__kernel_time_t timestamp;
|
||||
long timestamp;
|
||||
union {
|
||||
video_size_t size;
|
||||
unsigned int frame_rate; /* in frames per 1000sec */
|
||||
|
@ -55,8 +55,7 @@ please make a proposal on the linux-media mailing list.
|
||||
|
||||
- ``V4L2_PIX_FMT_HM12``
|
||||
- 'HM12'
|
||||
- YUV 4:2:0 format used by the IVTV driver,
|
||||
`http://www.ivtvdriver.org/ <http://www.ivtvdriver.org/>`__
|
||||
- YUV 4:2:0 format used by the IVTV driver.
|
||||
|
||||
The format is documented in the kernel sources in the file
|
||||
``Documentation/media/v4l-drivers/cx2341x.rst``
|
||||
|
@ -13,7 +13,7 @@
|
||||
.. _v4l2-pix-fmt-sgrbg12p:
|
||||
|
||||
*******************************************************************************************************************************
|
||||
V4L2_PIX_FMT_SRGGB12P ('pRAA'), V4L2_PIX_FMT_SGRBG12P ('pgAA'), V4L2_PIX_FMT_SGBRG12P ('pGAA'), V4L2_PIX_FMT_SBGGR12P ('pBAA'),
|
||||
V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC'),
|
||||
*******************************************************************************************************************************
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
.. _v4l2-pix-fmt-sgrbg14p:
|
||||
|
||||
*******************************************************************************************************************************
|
||||
V4L2_PIX_FMT_SRGGB14P ('pRCC'), V4L2_PIX_FMT_SGRBG14P ('pgCC'), V4L2_PIX_FMT_SGBRG14P ('pGCC'), V4L2_PIX_FMT_SBGGR14P ('pBCC'),
|
||||
V4L2_PIX_FMT_SRGGB14P ('pREE'), V4L2_PIX_FMT_SGRBG14P ('pgEE'), V4L2_PIX_FMT_SGBRG14P ('pGEE'), V4L2_PIX_FMT_SBGGR14P ('pBEE'),
|
||||
*******************************************************************************************************************************
|
||||
|
||||
*man V4L2_PIX_FMT_SRGGB14P(2)*
|
||||
|
@ -15,7 +15,7 @@ V4L2_TCH_FMT_DELTA_TD16 ('TD16')
|
||||
|
||||
*man V4L2_TCH_FMT_DELTA_TD16(2)*
|
||||
|
||||
16-bit signed Touch Delta
|
||||
16-bit signed little endian Touch Delta
|
||||
|
||||
|
||||
Description
|
||||
@ -37,38 +37,38 @@ Each cell is one byte.
|
||||
:widths: 2 1 1 1 1 1 1 1 1
|
||||
|
||||
* - start + 0:
|
||||
- D'\ :sub:`00high`
|
||||
- D'\ :sub:`00low`
|
||||
- D'\ :sub:`01high`
|
||||
- D'\ :sub:`00high`
|
||||
- D'\ :sub:`01low`
|
||||
- D'\ :sub:`02high`
|
||||
- D'\ :sub:`01high`
|
||||
- D'\ :sub:`02low`
|
||||
- D'\ :sub:`03high`
|
||||
- D'\ :sub:`02high`
|
||||
- D'\ :sub:`03low`
|
||||
- D'\ :sub:`03high`
|
||||
* - start + 8:
|
||||
- D'\ :sub:`10high`
|
||||
- D'\ :sub:`10low`
|
||||
- D'\ :sub:`11high`
|
||||
- D'\ :sub:`10high`
|
||||
- D'\ :sub:`11low`
|
||||
- D'\ :sub:`12high`
|
||||
- D'\ :sub:`11high`
|
||||
- D'\ :sub:`12low`
|
||||
- D'\ :sub:`13high`
|
||||
- D'\ :sub:`12high`
|
||||
- D'\ :sub:`13low`
|
||||
- D'\ :sub:`13high`
|
||||
* - start + 16:
|
||||
- D'\ :sub:`20high`
|
||||
- D'\ :sub:`20low`
|
||||
- D'\ :sub:`21high`
|
||||
- D'\ :sub:`20high`
|
||||
- D'\ :sub:`21low`
|
||||
- D'\ :sub:`22high`
|
||||
- D'\ :sub:`21high`
|
||||
- D'\ :sub:`22low`
|
||||
- D'\ :sub:`23high`
|
||||
- D'\ :sub:`22high`
|
||||
- D'\ :sub:`23low`
|
||||
- D'\ :sub:`23high`
|
||||
* - start + 24:
|
||||
- D'\ :sub:`30high`
|
||||
- D'\ :sub:`30low`
|
||||
- D'\ :sub:`31high`
|
||||
- D'\ :sub:`30high`
|
||||
- D'\ :sub:`31low`
|
||||
- D'\ :sub:`32high`
|
||||
- D'\ :sub:`31high`
|
||||
- D'\ :sub:`32low`
|
||||
- D'\ :sub:`33high`
|
||||
- D'\ :sub:`32high`
|
||||
- D'\ :sub:`33low`
|
||||
- D'\ :sub:`33high`
|
||||
|
@ -15,7 +15,7 @@ V4L2_TCH_FMT_TU16 ('TU16')
|
||||
|
||||
*man V4L2_TCH_FMT_TU16(2)*
|
||||
|
||||
16-bit unsigned raw touch data
|
||||
16-bit unsigned little endian raw touch data
|
||||
|
||||
|
||||
Description
|
||||
@ -36,38 +36,38 @@ Each cell is one byte.
|
||||
:widths: 2 1 1 1 1 1 1 1 1
|
||||
|
||||
* - start + 0:
|
||||
- R'\ :sub:`00high`
|
||||
- R'\ :sub:`00low`
|
||||
- R'\ :sub:`01high`
|
||||
- R'\ :sub:`00high`
|
||||
- R'\ :sub:`01low`
|
||||
- R'\ :sub:`02high`
|
||||
- R'\ :sub:`01high`
|
||||
- R'\ :sub:`02low`
|
||||
- R'\ :sub:`03high`
|
||||
- R'\ :sub:`02high`
|
||||
- R'\ :sub:`03low`
|
||||
- R'\ :sub:`03high`
|
||||
* - start + 8:
|
||||
- R'\ :sub:`10high`
|
||||
- R'\ :sub:`10low`
|
||||
- R'\ :sub:`11high`
|
||||
- R'\ :sub:`10high`
|
||||
- R'\ :sub:`11low`
|
||||
- R'\ :sub:`12high`
|
||||
- R'\ :sub:`11high`
|
||||
- R'\ :sub:`12low`
|
||||
- R'\ :sub:`13high`
|
||||
- R'\ :sub:`12high`
|
||||
- R'\ :sub:`13low`
|
||||
- R'\ :sub:`13high`
|
||||
* - start + 16:
|
||||
- R'\ :sub:`20high`
|
||||
- R'\ :sub:`20low`
|
||||
- R'\ :sub:`21high`
|
||||
- R'\ :sub:`20high`
|
||||
- R'\ :sub:`21low`
|
||||
- R'\ :sub:`22high`
|
||||
- R'\ :sub:`21high`
|
||||
- R'\ :sub:`22low`
|
||||
- R'\ :sub:`23high`
|
||||
- R'\ :sub:`22high`
|
||||
- R'\ :sub:`23low`
|
||||
- R'\ :sub:`23high`
|
||||
* - start + 24:
|
||||
- R'\ :sub:`30high`
|
||||
- R'\ :sub:`30low`
|
||||
- R'\ :sub:`31high`
|
||||
- R'\ :sub:`30high`
|
||||
- R'\ :sub:`31low`
|
||||
- R'\ :sub:`32high`
|
||||
- R'\ :sub:`31high`
|
||||
- R'\ :sub:`32low`
|
||||
- R'\ :sub:`33high`
|
||||
- R'\ :sub:`32high`
|
||||
- R'\ :sub:`33low`
|
||||
- R'\ :sub:`33high`
|
||||
|
@ -44,7 +44,9 @@ To enumerate image formats applications initialize the ``type`` and
|
||||
the :ref:`VIDIOC_ENUM_FMT` ioctl with a pointer to this structure. Drivers
|
||||
fill the rest of the structure or return an ``EINVAL`` error code. All
|
||||
formats are enumerable by beginning at index zero and incrementing by
|
||||
one until ``EINVAL`` is returned.
|
||||
one until ``EINVAL`` is returned. If applicable, drivers shall return
|
||||
formats in preference order, where preferred formats are returned before
|
||||
(that is, with lower ``index`` value) less-preferred formats.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -279,7 +279,7 @@ EBUSY
|
||||
then it will set this flag to signal this to the application.
|
||||
* - ``V4L2_DV_FL_HALF_LINE``
|
||||
- Specific to interlaced formats: if set, then the vertical
|
||||
backporch of field 1 (aka the odd field) is really one half-line
|
||||
frontporch of field 1 (aka the odd field) is really one half-line
|
||||
longer and the vertical backporch of field 2 (aka the even field)
|
||||
is really one half-line shorter, so each field has exactly the
|
||||
same number of half-lines. Whether half-lines can be detected or
|
||||
|
@ -1,39 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
The cx18 driver
|
||||
===============
|
||||
|
||||
.. note::
|
||||
|
||||
This documentation is outdated.
|
||||
|
||||
Some notes regarding the cx18 driver for the Conexant CX23418 MPEG
|
||||
encoder chip:
|
||||
|
||||
1) Currently supported are:
|
||||
|
||||
- Hauppauge HVR-1600
|
||||
- Compro VideoMate H900
|
||||
- Yuan MPC718
|
||||
- Conexant Raptor PAL/SECAM devkit
|
||||
|
||||
2) Some people have problems getting the i2c bus to work.
|
||||
The symptom is that the eeprom cannot be read and the card is
|
||||
unusable. This is probably fixed, but if you have problems
|
||||
then post to the video4linux or ivtv-users mailing list.
|
||||
|
||||
3) VBI (raw or sliced) has not yet been implemented.
|
||||
|
||||
4) MPEG indexing is not yet implemented.
|
||||
|
||||
5) The driver is still a bit rough around the edges, this should
|
||||
improve over time.
|
||||
|
||||
|
||||
Firmware:
|
||||
|
||||
You can obtain the firmware files here:
|
||||
|
||||
http://dl.ivtvdriver.org/ivtv/firmware/cx18-firmware.tar.gz
|
||||
|
||||
Untar and copy the .fw files to your firmware directory.
|
@ -38,7 +38,6 @@ For more details see the file COPYING in the source distribution of Linux.
|
||||
bttv
|
||||
cafe_ccic
|
||||
cpia2
|
||||
cx18
|
||||
cx2341x
|
||||
cx88
|
||||
davinci-vpbe
|
||||
|
16
MAINTAINERS
16
MAINTAINERS
@ -4478,13 +4478,10 @@ F: drivers/net/wireless/st/cw1200/
|
||||
|
||||
CX18 VIDEO4LINUX DRIVER
|
||||
M: Andy Walls <awalls@md.metrocast.net>
|
||||
L: ivtv-devel@ivtvdriver.org (subscribers-only)
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
W: https://linuxtv.org
|
||||
W: http://www.ivtvdriver.org/index.php/Cx18
|
||||
S: Maintained
|
||||
F: Documentation/media/v4l-drivers/cx18*
|
||||
F: drivers/media/pci/cx18/
|
||||
F: include/uapi/linux/ivtv*
|
||||
|
||||
@ -8200,8 +8197,7 @@ F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt
|
||||
F: drivers/auxdisplay/img-ascii-lcd.c
|
||||
|
||||
IMGTEC IR DECODER DRIVER
|
||||
M: James Hogan <jhogan@kernel.org>
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/media/rc/img-ir/
|
||||
|
||||
IMON SOUNDGRAPH USB IR RECEIVER
|
||||
@ -8946,10 +8942,9 @@ F: drivers/media/tuners/it913x*
|
||||
|
||||
IVTV VIDEO4LINUX DRIVER
|
||||
M: Andy Walls <awalls@md.metrocast.net>
|
||||
L: ivtv-devel@ivtvdriver.org (subscribers-only)
|
||||
L: linux-media@vger.kernel.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
W: http://www.ivtvdriver.org
|
||||
W: https://linuxtv.org
|
||||
S: Maintained
|
||||
F: Documentation/media/v4l-drivers/ivtv*
|
||||
F: drivers/media/pci/ivtv/
|
||||
@ -14297,6 +14292,12 @@ F: drivers/hid/hid-roccat*
|
||||
F: include/linux/hid-roccat*
|
||||
F: Documentation/ABI/*/sysfs-driver-hid-roccat*
|
||||
|
||||
ROCKCHIP ISP V1 DRIVER
|
||||
M: Helen Koike <helen.koike@collabora.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/staging/media/rkisp1/
|
||||
|
||||
ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
|
||||
M: Jacob Chen <jacob-chen@iotwrt.com>
|
||||
M: Ezequiel Garcia <ezequiel@collabora.com>
|
||||
@ -16737,6 +16738,7 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
S: Maintained
|
||||
F: drivers/media/platform/ti-vpe/
|
||||
F: Documentation/devicetree/bindings/media/ti,vpe.yaml
|
||||
Documentation/devicetree/bindings/media/ti,cal.yaml
|
||||
|
||||
TI WILINK WIRELESS DRIVERS
|
||||
L: linux-wireless@vger.kernel.org
|
||||
|
@ -183,24 +183,6 @@ static void cec_devnode_unregister(struct cec_adapter *adap)
|
||||
put_device(&devnode->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CEC_NOTIFIER
|
||||
static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
|
||||
{
|
||||
cec_s_phys_addr(adap, pa, false);
|
||||
}
|
||||
|
||||
void cec_register_cec_notifier(struct cec_adapter *adap,
|
||||
struct cec_notifier *notifier)
|
||||
{
|
||||
if (WARN_ON(!cec_is_registered(adap)))
|
||||
return;
|
||||
|
||||
adap->notifier = notifier;
|
||||
cec_notifier_register(adap->notifier, adap, cec_cec_notify);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_register_cec_notifier);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static ssize_t cec_error_inj_write(struct file *file,
|
||||
const char __user *ubuf, size_t count, loff_t *ppos)
|
||||
@ -416,8 +398,7 @@ void cec_unregister_adapter(struct cec_adapter *adap)
|
||||
#endif
|
||||
debugfs_remove_recursive(adap->cec_dir);
|
||||
#ifdef CONFIG_CEC_NOTIFIER
|
||||
if (adap->notifier)
|
||||
cec_notifier_unregister(adap->notifier);
|
||||
cec_notifier_cec_adap_unregister(adap->notifier, adap);
|
||||
#endif
|
||||
cec_devnode_unregister(adap);
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ struct cec_notifier {
|
||||
struct cec_connector_info conn_info;
|
||||
const char *conn_name;
|
||||
struct cec_adapter *cec_adap;
|
||||
void (*callback)(struct cec_adapter *adap, u16 pa);
|
||||
|
||||
u16 phys_addr;
|
||||
};
|
||||
@ -81,13 +80,12 @@ static void cec_notifier_release(struct kref *kref)
|
||||
kfree(n);
|
||||
}
|
||||
|
||||
void cec_notifier_put(struct cec_notifier *n)
|
||||
static void cec_notifier_put(struct cec_notifier *n)
|
||||
{
|
||||
mutex_lock(&cec_notifiers_lock);
|
||||
kref_put(&n->kref, cec_notifier_release);
|
||||
mutex_unlock(&cec_notifiers_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_put);
|
||||
|
||||
struct cec_notifier *
|
||||
cec_notifier_conn_register(struct device *hdmi_dev, const char *conn_name,
|
||||
@ -162,7 +160,6 @@ void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
|
||||
mutex_lock(&n->lock);
|
||||
adap->notifier = NULL;
|
||||
n->cec_adap = NULL;
|
||||
n->callback = NULL;
|
||||
mutex_unlock(&n->lock);
|
||||
cec_notifier_put(n);
|
||||
}
|
||||
@ -175,9 +172,7 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
n->phys_addr = pa;
|
||||
if (n->callback)
|
||||
n->callback(n->cec_adap, n->phys_addr);
|
||||
else if (n->cec_adap)
|
||||
if (n->cec_adap)
|
||||
cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
|
||||
mutex_unlock(&n->lock);
|
||||
}
|
||||
@ -198,34 +193,6 @@ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr_from_edid);
|
||||
|
||||
void cec_notifier_register(struct cec_notifier *n,
|
||||
struct cec_adapter *adap,
|
||||
void (*callback)(struct cec_adapter *adap, u16 pa))
|
||||
{
|
||||
kref_get(&n->kref);
|
||||
mutex_lock(&n->lock);
|
||||
n->cec_adap = adap;
|
||||
n->callback = callback;
|
||||
n->callback(adap, n->phys_addr);
|
||||
mutex_unlock(&n->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_register);
|
||||
|
||||
void cec_notifier_unregister(struct cec_notifier *n)
|
||||
{
|
||||
/* Do nothing unless cec_notifier_register was called first */
|
||||
if (!n->callback)
|
||||
return;
|
||||
|
||||
mutex_lock(&n->lock);
|
||||
n->callback = NULL;
|
||||
n->cec_adap->notifier = NULL;
|
||||
n->cec_adap = NULL;
|
||||
mutex_unlock(&n->lock);
|
||||
cec_notifier_put(n);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_notifier_unregister);
|
||||
|
||||
struct device *cec_notifier_parse_hdmi_phandle(struct device *dev)
|
||||
{
|
||||
struct platform_device *hdmi_pdev;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define _CEC_PRIV_H
|
||||
|
||||
#include <linux/cec-funcs.h>
|
||||
#include <media/cec.h>
|
||||
#include <media/cec-notifier.h>
|
||||
|
||||
#define dprintk(lvl, fmt, arg...) \
|
||||
do { \
|
||||
|
@ -345,7 +345,8 @@ static int video_begin(struct saa7146_fh *fh)
|
||||
|
||||
fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
||||
if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
|
||||
resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
|
||||
@ -398,7 +399,8 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
|
||||
|
||||
fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
||||
if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
|
||||
resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
|
||||
|
@ -146,7 +146,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const void *pb)
|
||||
* and the timecode field and flag if needed.
|
||||
*/
|
||||
if (q->copy_timestamp)
|
||||
vb->timestamp = v4l2_timeval_to_ns(&b->timestamp);
|
||||
vb->timestamp = v4l2_buffer_get_timestamp(b);
|
||||
vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
|
||||
if (b->flags & V4L2_BUF_FLAG_TIMECODE)
|
||||
vbuf->timecode = b->timecode;
|
||||
@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
|
||||
|
||||
b->flags = vbuf->flags;
|
||||
b->field = vbuf->field;
|
||||
b->timestamp = ns_to_timeval(vb->timestamp);
|
||||
v4l2_buffer_set_timestamp(b, vb->timestamp);
|
||||
b->timecode = vbuf->timecode;
|
||||
b->sequence = vbuf->sequence;
|
||||
b->reserved2 = 0;
|
||||
|
@ -971,6 +971,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
|
||||
dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
|
||||
dvbdmxfeed->feed.sec.secbufp = 0;
|
||||
dvbdmxfeed->feed.sec.seclen = 0;
|
||||
dvbdmxfeed->pusi_seen = false;
|
||||
|
||||
if (!dvbdmx->start_feed) {
|
||||
mutex_unlock(&dvbdmx->mutex);
|
||||
|
@ -983,8 +983,8 @@ struct i2c_client *dvb_module_probe(const char *module_name,
|
||||
board_info->addr = addr;
|
||||
board_info->platform_data = platform_data;
|
||||
request_module(module_name);
|
||||
client = i2c_new_device(adap, board_info);
|
||||
if (client == NULL || client->dev.driver == NULL) {
|
||||
client = i2c_new_client_device(adap, board_info);
|
||||
if (!i2c_client_has_driver(client)) {
|
||||
kfree(board_info);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -290,7 +290,8 @@ static int as102_fe_get_frontend(struct dvb_frontend *fe,
|
||||
}
|
||||
|
||||
static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *settings) {
|
||||
struct dvb_frontend_tune_settings *settings)
|
||||
{
|
||||
|
||||
settings->min_delay_ms = 1000;
|
||||
|
||||
|
@ -562,7 +562,7 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd,
|
||||
{
|
||||
struct au8522_state *state = to_state(sd);
|
||||
|
||||
switch(input) {
|
||||
switch (input) {
|
||||
case AU8522_COMPOSITE_CH1:
|
||||
case AU8522_SVIDEO_CH13:
|
||||
case AU8522_COMPOSITE_CH4_SIF:
|
||||
|
@ -530,8 +530,8 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config,
|
||||
strscpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);
|
||||
board_info.addr = config->i2c_address;
|
||||
board_info.platform_data = &pdata;
|
||||
client = i2c_new_device(adapter, &board_info);
|
||||
if (!client || !client->dev.driver)
|
||||
client = i2c_new_client_device(adapter, &board_info);
|
||||
if (!i2c_client_has_driver(client))
|
||||
return NULL;
|
||||
|
||||
return pdata.get_dvb_frontend(client);
|
||||
|
@ -189,7 +189,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
|
||||
|
||||
adc = dib0070_read_reg(state, 0x19);
|
||||
|
||||
dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV\n", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
|
||||
dprintk("CAPTRIM=%d; ADC = %hd (ADC) & %dmV\n", state->captrim,
|
||||
adc, (u32)adc * (u32)1800 / (u32)1024);
|
||||
|
||||
if (adc >= 400) {
|
||||
adc -= 400;
|
||||
@ -200,7 +201,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
|
||||
}
|
||||
|
||||
if (adc < state->adc_diff) {
|
||||
dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)\n", state->captrim, adc, state->adc_diff);
|
||||
dprintk("CAPTRIM=%d is closer to target (%hd/%hd)\n",
|
||||
state->captrim, adc, state->adc_diff);
|
||||
state->adc_diff = adc;
|
||||
state->fcaptrim = state->captrim;
|
||||
}
|
||||
@ -364,7 +366,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe)
|
||||
}
|
||||
|
||||
if (*tune_state == CT_TUNER_START) {
|
||||
dprintk("Tuning for Band: %hd (%d kHz)\n", band, freq);
|
||||
dprintk("Tuning for Band: %d (%d kHz)\n", band, freq);
|
||||
if (state->current_rf != freq) {
|
||||
u8 REFDIV;
|
||||
u32 FBDiv, Rest, FREF, VCOF_kHz;
|
||||
@ -442,12 +444,17 @@ static int dib0070_tune_digital(struct dvb_frontend *fe)
|
||||
dib0070_write_reg(state, 0x20,
|
||||
0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
|
||||
|
||||
dprintk("REFDIV: %hd, FREF: %d\n", REFDIV, FREF);
|
||||
dprintk("REFDIV: %u, FREF: %d\n", REFDIV, FREF);
|
||||
dprintk("FBDIV: %d, Rest: %d\n", FBDiv, Rest);
|
||||
dprintk("Num: %hd, Den: %hd, SD: %hd\n", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
|
||||
dprintk("HFDIV code: %hd\n", state->current_tune_table_index->hfdiv);
|
||||
dprintk("VCO = %hd\n", state->current_tune_table_index->vco_band);
|
||||
dprintk("VCOF: ((%hd*%d) << 1))\n", state->current_tune_table_index->vco_multi, freq);
|
||||
dprintk("Num: %u, Den: %u, SD: %d\n", (u16)Rest, Den,
|
||||
(state->lo4 >> 12) & 0x1);
|
||||
dprintk("HFDIV code: %u\n",
|
||||
state->current_tune_table_index->hfdiv);
|
||||
dprintk("VCO = %u\n",
|
||||
state->current_tune_table_index->vco_band);
|
||||
dprintk("VCOF: ((%u*%d) << 1))\n",
|
||||
state->current_tune_table_index->vco_multi,
|
||||
freq);
|
||||
|
||||
*tune_state = CT_TUNER_STEP_0;
|
||||
} else { /* we are already tuned to this frequency - the configuration is correct */
|
||||
|
@ -1748,7 +1748,8 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
|
||||
}
|
||||
|
||||
dib0090_set_trim(state);
|
||||
dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd\n", state->dc->addr, state->adc_diff, state->step);
|
||||
dprintk("BB Offset Cal, BBreg=%u,Offset=%d,Value Set=%d\n",
|
||||
state->dc->addr, state->adc_diff, state->step);
|
||||
|
||||
state->dc++;
|
||||
if (state->dc->addr == 0) /* done */
|
||||
|
@ -808,7 +808,7 @@ static int dib7000m_agc_startup(struct dvb_frontend *demod)
|
||||
|
||||
dib7000m_restart_agc(state);
|
||||
|
||||
dprintk("SPLIT %p: %hd\n", demod, agc_split);
|
||||
dprintk("SPLIT %p: %u\n", demod, agc_split);
|
||||
|
||||
(*agc_state)++;
|
||||
ret = 5;
|
||||
|
@ -915,7 +915,7 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
|
||||
|
||||
dib7000p_restart_agc(state);
|
||||
|
||||
dprintk("SPLIT %p: %hd\n", demod, agc_split);
|
||||
dprintk("SPLIT %p: %u\n", demod, agc_split);
|
||||
|
||||
(*agc_state)++;
|
||||
ret = 5;
|
||||
|
@ -31,25 +31,26 @@ static int dvb_dummy_fe_read_status(struct dvb_frontend *fe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
|
||||
static int dvb_dummy_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
*ber = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
|
||||
static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend *fe,
|
||||
u16 *strength)
|
||||
{
|
||||
*strength = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
|
||||
static int dvb_dummy_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
*snr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
|
||||
static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
{
|
||||
*ucblocks = 0;
|
||||
return 0;
|
||||
@ -77,12 +78,12 @@ static int dvb_dummy_fe_set_frontend(struct dvb_frontend *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
|
||||
static int dvb_dummy_fe_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dvb_dummy_fe_init(struct dvb_frontend* fe)
|
||||
static int dvb_dummy_fe_init(struct dvb_frontend *fe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -99,17 +100,18 @@ static int dvb_dummy_fe_set_voltage(struct dvb_frontend *fe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dvb_dummy_fe_release(struct dvb_frontend* fe)
|
||||
static void dvb_dummy_fe_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dvb_dummy_fe_state* state = fe->demodulator_priv;
|
||||
struct dvb_dummy_fe_state *state = fe->demodulator_priv;
|
||||
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
|
||||
|
||||
struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
|
||||
struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
|
||||
{
|
||||
struct dvb_dummy_fe_state* state = NULL;
|
||||
struct dvb_dummy_fe_state *state = NULL;
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
|
||||
@ -117,16 +119,20 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
|
||||
return NULL;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
|
||||
memcpy(&state->frontend.ops,
|
||||
&dvb_dummy_fe_ofdm_ops,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
|
||||
state->frontend.demodulator_priv = state;
|
||||
return &state->frontend;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
|
||||
|
||||
static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
|
||||
|
||||
struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
|
||||
{
|
||||
struct dvb_dummy_fe_state* state = NULL;
|
||||
struct dvb_dummy_fe_state *state = NULL;
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
|
||||
@ -134,16 +140,20 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
|
||||
return NULL;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
|
||||
memcpy(&state->frontend.ops,
|
||||
&dvb_dummy_fe_qpsk_ops,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
|
||||
state->frontend.demodulator_priv = state;
|
||||
return &state->frontend;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
|
||||
|
||||
static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
|
||||
|
||||
struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
|
||||
{
|
||||
struct dvb_dummy_fe_state* state = NULL;
|
||||
struct dvb_dummy_fe_state *state = NULL;
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
|
||||
@ -151,10 +161,14 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
|
||||
return NULL;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
|
||||
memcpy(&state->frontend.ops,
|
||||
&dvb_dummy_fe_qam_ops,
|
||||
sizeof(struct dvb_frontend_ops));
|
||||
|
||||
state->frontend.demodulator_priv = state;
|
||||
return &state->frontend;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
|
||||
|
||||
static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
|
||||
.delsys = { SYS_DVBT },
|
||||
@ -163,10 +177,18 @@ static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
|
||||
.frequency_min_hz = 0,
|
||||
.frequency_max_hz = 863250 * kHz,
|
||||
.frequency_stepsize_hz = 62500,
|
||||
.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
|
||||
FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
|
||||
.caps = FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_4_5 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_6_7 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_8_9 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QAM_16 |
|
||||
FE_CAN_QAM_64 |
|
||||
FE_CAN_QAM_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO |
|
||||
FE_CAN_HIERARCHY_AUTO,
|
||||
@ -194,11 +216,16 @@ static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
|
||||
.frequency_min_hz = 51 * MHz,
|
||||
.frequency_max_hz = 858 * MHz,
|
||||
.frequency_stepsize_hz = 62500,
|
||||
.symbol_rate_min = (57840000 / 2) / 64, /* SACLK/64 == (XIN/2)/64 */
|
||||
/* symbol_rate_min: SACLK/64 == (XIN/2)/64 */
|
||||
.symbol_rate_min = (57840000 / 2) / 64,
|
||||
.symbol_rate_max = (57840000 / 2) / 4, /* SACLK/4 */
|
||||
.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
|
||||
FE_CAN_QAM_128 | FE_CAN_QAM_256 |
|
||||
FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
|
||||
.caps = FE_CAN_QAM_16 |
|
||||
FE_CAN_QAM_32 |
|
||||
FE_CAN_QAM_64 |
|
||||
FE_CAN_QAM_128 |
|
||||
FE_CAN_QAM_256 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_INVERSION_AUTO
|
||||
},
|
||||
|
||||
.release = dvb_dummy_fe_release,
|
||||
@ -227,8 +254,12 @@ static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
|
||||
.symbol_rate_min = 1000000,
|
||||
.symbol_rate_max = 45000000,
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_FEC_1_2 |
|
||||
FE_CAN_FEC_2_3 |
|
||||
FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 |
|
||||
FE_CAN_FEC_7_8 |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK
|
||||
},
|
||||
|
||||
@ -253,7 +284,3 @@ static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
|
||||
MODULE_DESCRIPTION("DVB DUMMY Frontend");
|
||||
MODULE_AUTHOR("Emard");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
|
||||
EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
|
||||
EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
|
||||
|
@ -12,23 +12,23 @@
|
||||
#include <media/dvb_frontend.h>
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DVB_DUMMY_FE)
|
||||
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
|
||||
extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
|
||||
extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
|
||||
struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void);
|
||||
struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void);
|
||||
struct dvb_frontend *dvb_dummy_fe_qam_attach(void);
|
||||
#else
|
||||
static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_DVB_DUMMY_FE */
|
||||
|
@ -922,8 +922,8 @@ struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config,
|
||||
strscpy(board_info.type, "lgdt330x", sizeof(board_info.type));
|
||||
board_info.addr = demod_address;
|
||||
board_info.platform_data = &config;
|
||||
client = i2c_new_device(i2c, &board_info);
|
||||
if (!client || !client->dev.driver)
|
||||
client = i2c_new_client_device(i2c, &board_info);
|
||||
if (!i2c_client_has_driver(client))
|
||||
return NULL;
|
||||
|
||||
return lgdt330x_get_dvb_frontend(client);
|
||||
|
@ -1277,8 +1277,8 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
|
||||
strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
|
||||
board_info.addr = cfg->i2c_addr;
|
||||
board_info.platform_data = &pdata;
|
||||
client = i2c_new_device(i2c, &board_info);
|
||||
if (!client || !client->dev.driver)
|
||||
client = i2c_new_client_device(i2c, &board_info);
|
||||
if (!i2c_client_has_driver(client))
|
||||
return NULL;
|
||||
|
||||
*tuner_i2c_adapter = pdata.get_i2c_adapter(client);
|
||||
|
@ -519,8 +519,8 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
|
||||
strscpy(board_info.type, "ts2020", I2C_NAME_SIZE);
|
||||
board_info.addr = config->tuner_address;
|
||||
board_info.platform_data = &pdata;
|
||||
client = i2c_new_device(i2c, &board_info);
|
||||
if (!client || !client->dev.driver)
|
||||
client = i2c_new_client_device(i2c, &board_info);
|
||||
if (!i2c_client_has_driver(client))
|
||||
return NULL;
|
||||
|
||||
return fe;
|
||||
|
@ -394,10 +394,10 @@ int adv748x_write_block(struct adv748x_state *state, int client_page,
|
||||
|
||||
#define io_read(s, r) adv748x_read(s, ADV748X_PAGE_IO, r)
|
||||
#define io_write(s, r, v) adv748x_write(s, ADV748X_PAGE_IO, r, v)
|
||||
#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~m) | v)
|
||||
#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~(m)) | (v))
|
||||
|
||||
#define hdmi_read(s, r) adv748x_read(s, ADV748X_PAGE_HDMI, r)
|
||||
#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, r+1)) & m)
|
||||
#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, (r)+1)) & (m))
|
||||
#define hdmi_write(s, r, v) adv748x_write(s, ADV748X_PAGE_HDMI, r, v)
|
||||
|
||||
#define repeater_read(s, r) adv748x_read(s, ADV748X_PAGE_REPEATER, r)
|
||||
@ -405,11 +405,11 @@ int adv748x_write_block(struct adv748x_state *state, int client_page,
|
||||
|
||||
#define sdp_read(s, r) adv748x_read(s, ADV748X_PAGE_SDP, r)
|
||||
#define sdp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_SDP, r, v)
|
||||
#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~m) | v)
|
||||
#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~(m)) | (v))
|
||||
|
||||
#define cp_read(s, r) adv748x_read(s, ADV748X_PAGE_CP, r)
|
||||
#define cp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_CP, r, v)
|
||||
#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~m) | v)
|
||||
#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~(m)) | (v))
|
||||
|
||||
#define tx_read(t, r) adv748x_read(t->state, t->page, r)
|
||||
#define tx_write(t, r, v) adv748x_write(t->state, t->page, r, v)
|
||||
|
@ -1503,23 +1503,14 @@ static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
|
||||
|
||||
static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
|
||||
{
|
||||
unsigned int freq;
|
||||
int a, b;
|
||||
|
||||
a = hdmi_read(sd, 0x06);
|
||||
b = hdmi_read(sd, 0x3b);
|
||||
if (a < 0 || b < 0)
|
||||
return 0;
|
||||
freq = a * 1000000 + ((b & 0x30) >> 4) * 250000;
|
||||
|
||||
if (is_hdmi(sd)) {
|
||||
/* adjust for deep color mode */
|
||||
unsigned bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
|
||||
|
||||
freq = freq * 8 / bits_per_channel;
|
||||
}
|
||||
|
||||
return freq;
|
||||
return a * 1000000 + ((b & 0x30) >> 4) * 250000;
|
||||
}
|
||||
|
||||
static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
|
||||
@ -1530,9 +1521,28 @@ static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
|
||||
b = hdmi_read(sd, 0x52);
|
||||
if (a < 0 || b < 0)
|
||||
return 0;
|
||||
|
||||
return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128;
|
||||
}
|
||||
|
||||
static unsigned int adv76xx_read_hdmi_pixelclock(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv76xx_state *state = to_state(sd);
|
||||
const struct adv76xx_chip_info *info = state->info;
|
||||
unsigned int freq, bits_per_channel, pixelrepetition;
|
||||
|
||||
freq = info->read_hdmi_pixelclock(sd);
|
||||
if (is_hdmi(sd)) {
|
||||
/* adjust for deep color mode and pixel repetition */
|
||||
bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
|
||||
pixelrepetition = (hdmi_read(sd, 0x05) & 0x0f) + 1;
|
||||
|
||||
freq = freq * 8 / bits_per_channel / pixelrepetition;
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
static int adv76xx_query_dv_timings(struct v4l2_subdev *sd,
|
||||
struct v4l2_dv_timings *timings)
|
||||
{
|
||||
@ -1579,7 +1589,7 @@ static int adv76xx_query_dv_timings(struct v4l2_subdev *sd,
|
||||
|
||||
bt->width = w;
|
||||
bt->height = h;
|
||||
bt->pixelclock = info->read_hdmi_pixelclock(sd);
|
||||
bt->pixelclock = adv76xx_read_hdmi_pixelclock(sd);
|
||||
bt->hfrontporch = hdmi_read16(sd, 0x20, info->hfrontporch_mask);
|
||||
bt->hsync = hdmi_read16(sd, 0x22, info->hsync_mask);
|
||||
bt->hbackporch = hdmi_read16(sd, 0x24, info->hbackporch_mask);
|
||||
|
@ -428,10 +428,12 @@ static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
{
|
||||
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
|
||||
|
||||
if (code->index > 0)
|
||||
return -EINVAL;
|
||||
|
||||
code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
|
||||
code->code = mt9v032->format.code;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -439,7 +441,11 @@ static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
|
||||
struct v4l2_subdev_pad_config *cfg,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
{
|
||||
if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
|
||||
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
|
||||
|
||||
if (fse->index >= 3)
|
||||
return -EINVAL;
|
||||
if (mt9v032->format.code != fse->code)
|
||||
return -EINVAL;
|
||||
|
||||
fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index);
|
||||
|
@ -103,7 +103,7 @@
|
||||
#define MT9V111_MAX_CLKIN 27000000
|
||||
|
||||
/* The default sensor configuration at startup time. */
|
||||
static struct v4l2_mbus_framefmt mt9v111_def_fmt = {
|
||||
static const struct v4l2_mbus_framefmt mt9v111_def_fmt = {
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
.code = MEDIA_BUS_FMT_UYVY8_2X8,
|
||||
|
@ -189,6 +189,7 @@ struct ov5640_mode_info {
|
||||
u32 vtot;
|
||||
const struct reg_value *reg_data;
|
||||
u32 reg_data_size;
|
||||
u32 max_fps;
|
||||
};
|
||||
|
||||
struct ov5640_ctrls {
|
||||
@ -544,6 +545,7 @@ static const struct ov5640_mode_info ov5640_mode_init_data = {
|
||||
0, SUBSAMPLING, 640, 1896, 480, 984,
|
||||
ov5640_init_setting_30fps_VGA,
|
||||
ARRAY_SIZE(ov5640_init_setting_30fps_VGA),
|
||||
OV5640_30_FPS,
|
||||
};
|
||||
|
||||
static const struct ov5640_mode_info
|
||||
@ -551,39 +553,48 @@ ov5640_mode_data[OV5640_NUM_MODES] = {
|
||||
{OV5640_MODE_QCIF_176_144, SUBSAMPLING,
|
||||
176, 1896, 144, 984,
|
||||
ov5640_setting_QCIF_176_144,
|
||||
ARRAY_SIZE(ov5640_setting_QCIF_176_144)},
|
||||
ARRAY_SIZE(ov5640_setting_QCIF_176_144),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_QVGA_320_240, SUBSAMPLING,
|
||||
320, 1896, 240, 984,
|
||||
ov5640_setting_QVGA_320_240,
|
||||
ARRAY_SIZE(ov5640_setting_QVGA_320_240)},
|
||||
ARRAY_SIZE(ov5640_setting_QVGA_320_240),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_VGA_640_480, SUBSAMPLING,
|
||||
640, 1896, 480, 1080,
|
||||
ov5640_setting_VGA_640_480,
|
||||
ARRAY_SIZE(ov5640_setting_VGA_640_480)},
|
||||
ARRAY_SIZE(ov5640_setting_VGA_640_480),
|
||||
OV5640_60_FPS},
|
||||
{OV5640_MODE_NTSC_720_480, SUBSAMPLING,
|
||||
720, 1896, 480, 984,
|
||||
ov5640_setting_NTSC_720_480,
|
||||
ARRAY_SIZE(ov5640_setting_NTSC_720_480)},
|
||||
ARRAY_SIZE(ov5640_setting_NTSC_720_480),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_PAL_720_576, SUBSAMPLING,
|
||||
720, 1896, 576, 984,
|
||||
ov5640_setting_PAL_720_576,
|
||||
ARRAY_SIZE(ov5640_setting_PAL_720_576)},
|
||||
ARRAY_SIZE(ov5640_setting_PAL_720_576),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_XGA_1024_768, SUBSAMPLING,
|
||||
1024, 1896, 768, 1080,
|
||||
ov5640_setting_XGA_1024_768,
|
||||
ARRAY_SIZE(ov5640_setting_XGA_1024_768)},
|
||||
ARRAY_SIZE(ov5640_setting_XGA_1024_768),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_720P_1280_720, SUBSAMPLING,
|
||||
1280, 1892, 720, 740,
|
||||
ov5640_setting_720P_1280_720,
|
||||
ARRAY_SIZE(ov5640_setting_720P_1280_720)},
|
||||
ARRAY_SIZE(ov5640_setting_720P_1280_720),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_1080P_1920_1080, SCALING,
|
||||
1920, 2500, 1080, 1120,
|
||||
ov5640_setting_1080P_1920_1080,
|
||||
ARRAY_SIZE(ov5640_setting_1080P_1920_1080)},
|
||||
ARRAY_SIZE(ov5640_setting_1080P_1920_1080),
|
||||
OV5640_30_FPS},
|
||||
{OV5640_MODE_QSXGA_2592_1944, SCALING,
|
||||
2592, 2844, 1944, 1968,
|
||||
ov5640_setting_QSXGA_2592_1944,
|
||||
ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944)},
|
||||
ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944),
|
||||
OV5640_15_FPS},
|
||||
};
|
||||
|
||||
static int ov5640_init_slave_id(struct ov5640_dev *sensor)
|
||||
@ -874,7 +885,7 @@ static unsigned long ov5640_calc_sys_clk(struct ov5640_dev *sensor,
|
||||
* We have reached the maximum allowed PLL1 output,
|
||||
* increase sysdiv.
|
||||
*/
|
||||
if (!rate)
|
||||
if (!_rate)
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -1606,14 +1617,8 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
|
||||
(!nearest && (mode->hact != width || mode->vact != height)))
|
||||
return NULL;
|
||||
|
||||
/* Only 640x480 can operate at 60fps (for now) */
|
||||
if (fr == OV5640_60_FPS &&
|
||||
!(mode->hact == 640 && mode->vact == 480))
|
||||
return NULL;
|
||||
|
||||
/* 2592x1944 only works at 15fps max */
|
||||
if ((mode->hact == 2592 && mode->vact == 1944) &&
|
||||
fr > OV5640_15_FPS)
|
||||
/* Check to see if the current mode exceeds the max frame rate */
|
||||
if (ov5640_framerates[fr] > ov5640_framerates[mode->max_fps])
|
||||
return NULL;
|
||||
|
||||
return mode;
|
||||
|
@ -413,21 +413,14 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
struct smiapp_sensor *sensor =
|
||||
container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
|
||||
->sensor;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||
int pm_status;
|
||||
u32 orient = 0;
|
||||
unsigned int i;
|
||||
int exposure;
|
||||
int rval;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_ANALOGUE_GAIN:
|
||||
return smiapp_write(
|
||||
sensor,
|
||||
SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
|
||||
|
||||
case V4L2_CID_EXPOSURE:
|
||||
return smiapp_write(
|
||||
sensor,
|
||||
SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
|
||||
|
||||
case V4L2_CID_HFLIP:
|
||||
case V4L2_CID_VFLIP:
|
||||
if (sensor->streaming)
|
||||
@ -440,15 +433,10 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
|
||||
|
||||
orient ^= sensor->hvflip_inv_mask;
|
||||
rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
|
||||
orient);
|
||||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
smiapp_update_mbus_formats(sensor);
|
||||
|
||||
return 0;
|
||||
|
||||
break;
|
||||
case V4L2_CID_VBLANK:
|
||||
exposure = sensor->exposure->val;
|
||||
|
||||
@ -461,59 +449,105 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
return rval;
|
||||
}
|
||||
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
|
||||
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
|
||||
+ ctrl->val);
|
||||
|
||||
case V4L2_CID_HBLANK:
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
|
||||
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
|
||||
+ ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_LINK_FREQ:
|
||||
if (sensor->streaming)
|
||||
return -EBUSY;
|
||||
|
||||
return smiapp_pll_update(sensor);
|
||||
|
||||
case V4L2_CID_TEST_PATTERN: {
|
||||
unsigned int i;
|
||||
rval = smiapp_pll_update(sensor);
|
||||
if (rval)
|
||||
return rval;
|
||||
|
||||
return 0;
|
||||
case V4L2_CID_TEST_PATTERN:
|
||||
for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
|
||||
v4l2_ctrl_activate(
|
||||
sensor->test_data[i],
|
||||
ctrl->val ==
|
||||
V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
|
||||
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
|
||||
break;
|
||||
}
|
||||
|
||||
case V4L2_CID_TEST_PATTERN_RED:
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
|
||||
|
||||
case V4L2_CID_TEST_PATTERN_GREENR:
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
|
||||
|
||||
case V4L2_CID_TEST_PATTERN_BLUE:
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
|
||||
|
||||
case V4L2_CID_TEST_PATTERN_GREENB:
|
||||
return smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
|
||||
|
||||
case V4L2_CID_PIXEL_RATE:
|
||||
/* For v4l2_ctrl_s_ctrl_int64() used internally. */
|
||||
pm_runtime_get_noresume(&client->dev);
|
||||
pm_status = pm_runtime_get_if_in_use(&client->dev);
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
if (!pm_status)
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_ANALOGUE_GAIN:
|
||||
rval = smiapp_write(
|
||||
sensor,
|
||||
SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_EXPOSURE:
|
||||
rval = smiapp_write(
|
||||
sensor,
|
||||
SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_HFLIP:
|
||||
case V4L2_CID_VFLIP:
|
||||
rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
|
||||
orient);
|
||||
|
||||
break;
|
||||
case V4L2_CID_VBLANK:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
|
||||
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
|
||||
+ ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_HBLANK:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
|
||||
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
|
||||
+ ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_TEST_PATTERN:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_TEST_PATTERN_RED:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_TEST_PATTERN_GREENR:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_TEST_PATTERN_BLUE:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_TEST_PATTERN_GREENB:
|
||||
rval = smiapp_write(
|
||||
sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
|
||||
|
||||
break;
|
||||
case V4L2_CID_PIXEL_RATE:
|
||||
/* For v4l2_ctrl_s_ctrl_int64() used internally. */
|
||||
rval = 0;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
rval = -EINVAL;
|
||||
}
|
||||
|
||||
if (pm_status > 0) {
|
||||
pm_runtime_mark_last_busy(&client->dev);
|
||||
pm_runtime_put_autosuspend(&client->dev);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
|
||||
@ -1184,10 +1218,6 @@ static int smiapp_power_on(struct device *dev)
|
||||
sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
|
||||
usleep_range(sleep, sleep);
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
|
||||
sensor->active = true;
|
||||
|
||||
/*
|
||||
* Failures to respond to the address change command have been noticed.
|
||||
* Those failures seem to be caused by the sensor requiring a longer
|
||||
@ -1270,24 +1300,9 @@ static int smiapp_power_on(struct device *dev)
|
||||
goto out_cci_addr_fail;
|
||||
}
|
||||
|
||||
/* Are we still initialising...? If not, proceed with control setup. */
|
||||
if (sensor->pixel_array) {
|
||||
rval = __v4l2_ctrl_handler_setup(
|
||||
&sensor->pixel_array->ctrl_handler);
|
||||
if (rval)
|
||||
goto out_cci_addr_fail;
|
||||
|
||||
rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
|
||||
if (rval)
|
||||
goto out_cci_addr_fail;
|
||||
}
|
||||
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
out_cci_addr_fail:
|
||||
mutex_unlock(&sensor->mutex);
|
||||
gpiod_set_value(sensor->xshutdown, 0);
|
||||
clk_disable_unprepare(sensor->ext_clk);
|
||||
|
||||
@ -1305,8 +1320,6 @@ static int smiapp_power_off(struct device *dev)
|
||||
struct smiapp_sensor *sensor =
|
||||
container_of(ssd, struct smiapp_sensor, ssds[0]);
|
||||
|
||||
mutex_lock(&sensor->mutex);
|
||||
|
||||
/*
|
||||
* Currently power/clock to lens are enable/disabled separately
|
||||
* but they are essentially the same signals. So if the sensor is
|
||||
@ -1319,10 +1332,6 @@ static int smiapp_power_off(struct device *dev)
|
||||
SMIAPP_REG_U8_SOFTWARE_RESET,
|
||||
SMIAPP_SOFTWARE_RESET);
|
||||
|
||||
sensor->active = false;
|
||||
|
||||
mutex_unlock(&sensor->mutex);
|
||||
|
||||
gpiod_set_value(sensor->xshutdown, 0);
|
||||
clk_disable_unprepare(sensor->ext_clk);
|
||||
usleep_range(5000, 5000);
|
||||
@ -1507,6 +1516,30 @@ out:
|
||||
* V4L2 subdev video operations
|
||||
*/
|
||||
|
||||
static int smiapp_pm_get_init(struct smiapp_sensor *sensor)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||
int rval;
|
||||
|
||||
rval = pm_runtime_get_sync(&client->dev);
|
||||
if (rval < 0) {
|
||||
if (rval != -EBUSY && rval != -EAGAIN)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
|
||||
return rval;
|
||||
} else if (!rval) {
|
||||
rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
|
||||
ctrl_handler);
|
||||
if (rval)
|
||||
return rval;
|
||||
|
||||
return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
|
||||
{
|
||||
struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
|
||||
@ -1516,22 +1549,23 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
|
||||
if (sensor->streaming == enable)
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
rval = pm_runtime_get_sync(&client->dev);
|
||||
if (rval < 0) {
|
||||
if (rval != -EBUSY && rval != -EAGAIN)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_put(&client->dev);
|
||||
return rval;
|
||||
if (!enable) {
|
||||
smiapp_stop_streaming(sensor);
|
||||
sensor->streaming = false;
|
||||
pm_runtime_mark_last_busy(&client->dev);
|
||||
pm_runtime_put_autosuspend(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rval = smiapp_pm_get_init(sensor);
|
||||
if (rval)
|
||||
return rval;
|
||||
|
||||
sensor->streaming = true;
|
||||
|
||||
rval = smiapp_start_streaming(sensor);
|
||||
if (rval < 0)
|
||||
sensor->streaming = false;
|
||||
} else {
|
||||
rval = smiapp_stop_streaming(sensor);
|
||||
if (rval < 0) {
|
||||
sensor->streaming = false;
|
||||
pm_runtime_mark_last_busy(&client->dev);
|
||||
pm_runtime_put_autosuspend(&client->dev);
|
||||
@ -2291,13 +2325,9 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
|
||||
if (!sensor->dev_init_done)
|
||||
return -EBUSY;
|
||||
|
||||
rval = pm_runtime_get_sync(&client->dev);
|
||||
if (rval < 0) {
|
||||
if (rval != -EBUSY && rval != -EAGAIN)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
rval = smiapp_pm_get_init(sensor);
|
||||
if (rval < 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rval = smiapp_read_nvm(sensor, buf, PAGE_SIZE);
|
||||
if (rval < 0) {
|
||||
|
@ -223,9 +223,6 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
|
||||
len != SMIAPP_REG_32BIT) || flags)
|
||||
return -EINVAL;
|
||||
|
||||
if (!sensor->active)
|
||||
return 0;
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = 0; /* Write */
|
||||
msg.len = 2 + len;
|
||||
|
@ -198,7 +198,6 @@ struct smiapp_sensor {
|
||||
|
||||
u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
|
||||
u8 frame_skip;
|
||||
bool active; /* is the sensor powered on? */
|
||||
u16 embedded_start; /* embedded data start line */
|
||||
u16 embedded_end;
|
||||
u16 image_start; /* image data start line */
|
||||
|
@ -386,7 +386,7 @@ void init_bttv_i2c_ir(struct bttv *btv)
|
||||
|
||||
if (btv->init_data.name) {
|
||||
info.platform_data = &btv->init_data;
|
||||
i2c_dev = i2c_new_device(&btv->c.i2c_adap, &info);
|
||||
i2c_dev = i2c_new_client_device(&btv->c.i2c_adap, &info);
|
||||
} else {
|
||||
/*
|
||||
* The external IR receiver is at i2c address 0x34 (0x35 for
|
||||
@ -396,9 +396,9 @@ void init_bttv_i2c_ir(struct bttv *btv)
|
||||
* internal.
|
||||
* That's why we probe 0x1a (~0x34) first. CB
|
||||
*/
|
||||
i2c_dev = i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL);
|
||||
i2c_dev = i2c_new_scanned_device(&btv->c.i2c_adap, &info, addr_list, NULL);
|
||||
}
|
||||
if (NULL == i2c_dev)
|
||||
if (IS_ERR(i2c_dev))
|
||||
return;
|
||||
|
||||
#if defined(CONFIG_MODULES) && defined(MODULE)
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <media/v4l2-device.h>
|
||||
@ -238,54 +237,6 @@ static int snd_cobalt_pcm_capture_close(struct snd_pcm_substream *substream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cobalt_pcm_ioctl(struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
return snd_pcm_lib_ioctl(substream, cmd, arg);
|
||||
}
|
||||
|
||||
|
||||
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
|
||||
size_t size)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = subs->runtime;
|
||||
|
||||
dprintk("Allocating vbuffer\n");
|
||||
if (runtime->dma_area) {
|
||||
if (runtime->dma_bytes > size)
|
||||
return 0;
|
||||
|
||||
vfree(runtime->dma_area);
|
||||
}
|
||||
runtime->dma_area = vmalloc(size);
|
||||
if (!runtime->dma_area)
|
||||
return -ENOMEM;
|
||||
|
||||
runtime->dma_bytes = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cobalt_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
dprintk("%s called\n", __func__);
|
||||
|
||||
return snd_pcm_alloc_vmalloc_buffer(substream,
|
||||
params_buffer_bytes(params));
|
||||
}
|
||||
|
||||
static int snd_cobalt_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if (substream->runtime->dma_area) {
|
||||
dprintk("freeing pcm capture region\n");
|
||||
vfree(substream->runtime->dma_area);
|
||||
substream->runtime->dma_area = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cobalt_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream);
|
||||
@ -490,36 +441,20 @@ snd_pcm_uframes_t snd_cobalt_pcm_pb_pointer(struct snd_pcm_substream *substream)
|
||||
substream->runtime->buffer_size;
|
||||
}
|
||||
|
||||
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
|
||||
unsigned long offset)
|
||||
{
|
||||
void *pageptr = subs->runtime->dma_area + offset;
|
||||
|
||||
return vmalloc_to_page(pageptr);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops snd_cobalt_pcm_capture_ops = {
|
||||
.open = snd_cobalt_pcm_capture_open,
|
||||
.close = snd_cobalt_pcm_capture_close,
|
||||
.ioctl = snd_cobalt_pcm_ioctl,
|
||||
.hw_params = snd_cobalt_pcm_hw_params,
|
||||
.hw_free = snd_cobalt_pcm_hw_free,
|
||||
.prepare = snd_cobalt_pcm_prepare,
|
||||
.trigger = snd_cobalt_pcm_trigger,
|
||||
.pointer = snd_cobalt_pcm_pointer,
|
||||
.page = snd_pcm_get_vmalloc_page,
|
||||
};
|
||||
|
||||
static const struct snd_pcm_ops snd_cobalt_pcm_playback_ops = {
|
||||
.open = snd_cobalt_pcm_playback_open,
|
||||
.close = snd_cobalt_pcm_playback_close,
|
||||
.ioctl = snd_cobalt_pcm_ioctl,
|
||||
.hw_params = snd_cobalt_pcm_hw_params,
|
||||
.hw_free = snd_cobalt_pcm_hw_free,
|
||||
.prepare = snd_cobalt_pcm_pb_prepare,
|
||||
.trigger = snd_cobalt_pcm_pb_trigger,
|
||||
.pointer = snd_cobalt_pcm_pb_pointer,
|
||||
.page = snd_pcm_get_vmalloc_page,
|
||||
};
|
||||
|
||||
int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
|
||||
@ -555,6 +490,8 @@ int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
|
||||
|
||||
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
|
||||
&snd_cobalt_pcm_capture_ops);
|
||||
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC,
|
||||
NULL, 0, 0);
|
||||
sp->info_flags = 0;
|
||||
sp->private_data = cobsc;
|
||||
strscpy(sp->name, "cobalt", sizeof(sp->name));
|
||||
@ -579,6 +516,8 @@ int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
|
||||
|
||||
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
&snd_cobalt_pcm_playback_ops);
|
||||
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC,
|
||||
NULL, 0, 0);
|
||||
sp->info_flags = 0;
|
||||
sp->private_data = cobsc;
|
||||
strscpy(sp->name, "cobalt", sizeof(sp->name));
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <media/v4l2-device.h>
|
||||
|
||||
@ -201,67 +200,6 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
|
||||
int ret;
|
||||
|
||||
snd_cx18_lock(cxsc);
|
||||
ret = snd_pcm_lib_ioctl(substream, cmd, arg);
|
||||
snd_cx18_unlock(cxsc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
|
||||
size_t size)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = subs->runtime;
|
||||
|
||||
dprintk("Allocating vbuffer\n");
|
||||
if (runtime->dma_area) {
|
||||
if (runtime->dma_bytes > size)
|
||||
return 0;
|
||||
|
||||
vfree(runtime->dma_area);
|
||||
}
|
||||
runtime->dma_area = vmalloc(size);
|
||||
if (!runtime->dma_area)
|
||||
return -ENOMEM;
|
||||
|
||||
runtime->dma_bytes = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
dprintk("%s called\n", __func__);
|
||||
|
||||
return snd_pcm_alloc_vmalloc_buffer(substream,
|
||||
params_buffer_bytes(params));
|
||||
}
|
||||
|
||||
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");
|
||||
dma_area = substream->runtime->dma_area;
|
||||
substream->runtime->dma_area = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&cxsc->slock, flags);
|
||||
vfree(dma_area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
|
||||
@ -291,24 +229,12 @@ snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
return hwptr_done;
|
||||
}
|
||||
|
||||
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
|
||||
unsigned long offset)
|
||||
{
|
||||
void *pageptr = subs->runtime->dma_area + offset;
|
||||
|
||||
return vmalloc_to_page(pageptr);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
|
||||
.open = snd_cx18_pcm_capture_open,
|
||||
.close = snd_cx18_pcm_capture_close,
|
||||
.ioctl = snd_cx18_pcm_ioctl,
|
||||
.hw_params = snd_cx18_pcm_hw_params,
|
||||
.hw_free = snd_cx18_pcm_hw_free,
|
||||
.prepare = snd_cx18_pcm_prepare,
|
||||
.trigger = snd_cx18_pcm_trigger,
|
||||
.pointer = snd_cx18_pcm_pointer,
|
||||
.page = snd_pcm_get_vmalloc_page,
|
||||
};
|
||||
|
||||
int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
|
||||
@ -334,6 +260,7 @@ int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
|
||||
|
||||
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
|
||||
&snd_cx18_pcm_capture_ops);
|
||||
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
|
||||
sp->info_flags = 0;
|
||||
sp->private_data = cxsc;
|
||||
strscpy(sp->name, cx->card_name, sizeof(sp->name));
|
||||
|
@ -245,7 +245,7 @@ static const struct cx18_card cx18_card_mpc718 = {
|
||||
.type = CX18_CARD_YUAN_MPC718,
|
||||
.name = "Yuan MPC718 MiniPCI DVB-T/Analog",
|
||||
.comment = "Experimenters needed for device to work well.\n"
|
||||
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
|
||||
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
|
||||
.v4l2_capabilities = CX18_CAP_ENCODER,
|
||||
.hw_audio_ctrl = CX18_HW_418_AV,
|
||||
.hw_muxer = CX18_HW_GPIO_MUX,
|
||||
@ -305,7 +305,7 @@ static const struct cx18_card cx18_card_gotview_dvd3 = {
|
||||
.type = CX18_CARD_GOTVIEW_PCI_DVD3,
|
||||
.name = "GoTView PCI DVD3 Hybrid",
|
||||
.comment = "Experimenters needed for device to work well.\n"
|
||||
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
|
||||
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
|
||||
.v4l2_capabilities = CX18_CAP_ENCODER,
|
||||
.hw_audio_ctrl = CX18_HW_418_AV,
|
||||
.hw_muxer = CX18_HW_GPIO_MUX,
|
||||
@ -419,7 +419,7 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
|
||||
.type = CX18_CARD_TOSHIBA_QOSMIO_DVBT,
|
||||
.name = "Toshiba Qosmio DVB-T/Analog",
|
||||
.comment = "Experimenters and photos needed for device to work well.\n"
|
||||
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
|
||||
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
|
||||
.v4l2_capabilities = CX18_CAP_ENCODER,
|
||||
.hw_audio_ctrl = CX18_HW_418_AV,
|
||||
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
|
||||
@ -462,7 +462,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
|
||||
.type = CX18_CARD_LEADTEK_PVR2100,
|
||||
.name = "Leadtek WinFast PVR2100",
|
||||
.comment = "Experimenters and photos needed for device to work well.\n"
|
||||
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
|
||||
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
|
||||
.v4l2_capabilities = CX18_CAP_ENCODER,
|
||||
.hw_audio_ctrl = CX18_HW_418_AV,
|
||||
.hw_muxer = CX18_HW_GPIO_MUX,
|
||||
|
@ -676,7 +676,7 @@ done:
|
||||
cx->pci_dev->subsystem_device);
|
||||
CX18_ERR("Defaulting to %s card\n", cx->card->name);
|
||||
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
|
||||
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
|
||||
CX18_ERR("card you have to the linux-media mailinglist (www.linuxtv.org)\n");
|
||||
CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
|
||||
}
|
||||
cx->v4l2_cap = cx->card->v4l2_capabilities;
|
||||
|
@ -88,7 +88,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
|
||||
break;
|
||||
}
|
||||
|
||||
return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
|
||||
return IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL)) ?
|
||||
-1 : 0;
|
||||
}
|
||||
|
||||
|
@ -495,7 +495,6 @@ static struct page *snd_cx23885_page(struct snd_pcm_substream *substream,
|
||||
static const struct snd_pcm_ops snd_cx23885_pcm_ops = {
|
||||
.open = snd_cx23885_pcm_open,
|
||||
.close = snd_cx23885_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_cx23885_hw_params,
|
||||
.hw_free = snd_cx23885_hw_free,
|
||||
.prepare = snd_cx23885_prepare,
|
||||
|
@ -801,6 +801,25 @@ struct cx23885_board cx23885_boards[] = {
|
||||
.name = "Hauppauge WinTV-Starburst2",
|
||||
.portb = CX23885_MPEG_DVB,
|
||||
},
|
||||
[CX23885_BOARD_AVERMEDIA_CE310B] = {
|
||||
.name = "AVerMedia CE310B",
|
||||
.porta = CX23885_ANALOG_VIDEO,
|
||||
.force_bff = 1,
|
||||
.input = {{
|
||||
.type = CX23885_VMUX_COMPOSITE1,
|
||||
.vmux = CX25840_VIN1_CH1 |
|
||||
CX25840_NONE_CH2 |
|
||||
CX25840_NONE0_CH3,
|
||||
.amux = CX25840_AUDIO7,
|
||||
}, {
|
||||
.type = CX23885_VMUX_SVIDEO,
|
||||
.vmux = CX25840_VIN8_CH1 |
|
||||
CX25840_NONE_CH2 |
|
||||
CX25840_VIN7_CH3 |
|
||||
CX25840_SVIDEO_ON,
|
||||
.amux = CX25840_AUDIO7,
|
||||
} },
|
||||
},
|
||||
};
|
||||
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
|
||||
|
||||
@ -1124,6 +1143,10 @@ struct cx23885_subid cx23885_subids[] = {
|
||||
.subvendor = 0x0070,
|
||||
.subdevice = 0xf02a,
|
||||
.card = CX23885_BOARD_HAUPPAUGE_STARBURST2,
|
||||
}, {
|
||||
.subvendor = 0x1461,
|
||||
.subdevice = 0x3100,
|
||||
.card = CX23885_BOARD_AVERMEDIA_CE310B,
|
||||
},
|
||||
};
|
||||
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
|
||||
@ -2348,6 +2371,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
|
||||
case CX23885_BOARD_DVBSKY_T982:
|
||||
case CX23885_BOARD_VIEWCAST_260E:
|
||||
case CX23885_BOARD_VIEWCAST_460E:
|
||||
case CX23885_BOARD_AVERMEDIA_CE310B:
|
||||
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
|
||||
&dev->i2c_bus[2].i2c_adap,
|
||||
"cx25840", 0x88 >> 1, NULL);
|
||||
|
@ -1159,8 +1159,8 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port)
|
||||
info.addr = 0x40;
|
||||
info.platform_data = &sp2_config;
|
||||
request_module(info.type);
|
||||
client_ci = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (client_ci == NULL || client_ci->dev.driver == NULL)
|
||||
client_ci = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_ci))
|
||||
return -ENODEV;
|
||||
if (!try_module_get(client_ci->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_ci);
|
||||
@ -1826,8 +1826,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x05;
|
||||
info.platform_data = &tda10071_pdata;
|
||||
request_module("tda10071");
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -1843,8 +1843,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x0b;
|
||||
info.platform_data = &a8293_pdata;
|
||||
request_module("a8293");
|
||||
client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!client_sec || !client_sec->dev.driver)
|
||||
client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_sec))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_sec->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_sec);
|
||||
@ -1864,9 +1864,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x64;
|
||||
info.platform_data = &si2165_pdata;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (client_demod == NULL ||
|
||||
client_demod->dev.driver == NULL)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -1898,8 +1897,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x05;
|
||||
info.platform_data = &tda10071_pdata;
|
||||
request_module("tda10071");
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -1915,8 +1914,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x0b;
|
||||
info.platform_data = &a8293_pdata;
|
||||
request_module("a8293");
|
||||
client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!client_sec || !client_sec->dev.driver)
|
||||
client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_sec))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_sec->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_sec);
|
||||
@ -1948,9 +1947,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &ts2020_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (client_tuner == NULL ||
|
||||
client_tuner->dev.driver == NULL)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_tuner);
|
||||
@ -1985,9 +1983,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x64;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (client_demod == NULL ||
|
||||
client_demod->dev.driver == NULL)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2004,9 +2001,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (client_tuner == NULL ||
|
||||
client_tuner->dev.driver == NULL)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
@ -2032,8 +2028,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x64;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&i2c_bus2->i2c_adap, &info);
|
||||
if (client_demod == NULL || client_demod->dev.driver == NULL)
|
||||
client_demod = i2c_new_client_device(&i2c_bus2->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2050,9 +2046,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (client_tuner == NULL ||
|
||||
client_tuner->dev.driver == NULL)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_tuner);
|
||||
@ -2080,8 +2075,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &ts2020_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (client_tuner == NULL || client_tuner->dev.driver == NULL)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_tuner);
|
||||
@ -2129,8 +2124,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x68;
|
||||
info.platform_data = &m88ds3103_pdata;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (client_demod == NULL || client_demod->dev.driver == NULL)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2149,8 +2144,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &ts2020_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (client_tuner == NULL || client_tuner->dev.driver == NULL)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_tuner);
|
||||
@ -2194,8 +2189,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x64;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (client_demod == NULL || client_demod->dev.driver == NULL)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2212,9 +2207,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (client_tuner == NULL ||
|
||||
client_tuner->dev.driver == NULL)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_tuner);
|
||||
@ -2245,8 +2239,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x0b;
|
||||
info.platform_data = &a8293_pdata;
|
||||
request_module("a8293");
|
||||
client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!client_sec || !client_sec->dev.driver)
|
||||
client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_sec))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_sec->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_sec);
|
||||
@ -2262,8 +2256,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x21;
|
||||
info.platform_data = &m88rs6000t_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(adapter, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver)
|
||||
client_tuner = i2c_new_client_device(adapter, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_tuner);
|
||||
@ -2287,8 +2281,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x64;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module("%s", info.type);
|
||||
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2305,8 +2299,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(&i2c_bus2->i2c_adap, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&i2c_bus2->i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
port->i2c_client_demod = NULL;
|
||||
@ -2340,8 +2334,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x64;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module("%s", info.type);
|
||||
client_demod = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2358,8 +2352,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
port->i2c_client_demod = NULL;
|
||||
@ -2387,8 +2381,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x66;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module("%s", info.type);
|
||||
client_demod = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
i2c_unregister_device(client_demod);
|
||||
@ -2405,8 +2399,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x62;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
port->i2c_client_demod = NULL;
|
||||
@ -2447,8 +2441,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
port->i2c_client_demod = NULL;
|
||||
@ -2483,8 +2477,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x62;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
port->i2c_client_demod = NULL;
|
||||
@ -2523,8 +2517,8 @@ static int dvb_register(struct cx23885_tsport *port)
|
||||
info.addr = 0x60;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module("%s", info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!client_tuner || !client_tuner->dev.driver)
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner))
|
||||
goto frontend_detach;
|
||||
|
||||
if (!try_module_get(client_tuner->dev.driver->owner)) {
|
||||
|
@ -337,7 +337,7 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
|
||||
strscpy(info.type, "ir_video", I2C_NAME_SIZE);
|
||||
/* Use quick read command for probe, some IR chips don't
|
||||
* support writes */
|
||||
i2c_new_probed_device(&bus->i2c_adap, &info, addr_list,
|
||||
i2c_new_scanned_device(&bus->i2c_adap, &info, addr_list,
|
||||
i2c_probe_func_quick_read);
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
|
||||
(dev->board == CX23885_BOARD_MYGICA_X8507) ||
|
||||
(dev->board == CX23885_BOARD_AVERMEDIA_HC81R) ||
|
||||
(dev->board == CX23885_BOARD_VIEWCAST_260E) ||
|
||||
(dev->board == CX23885_BOARD_VIEWCAST_460E)) {
|
||||
(dev->board == CX23885_BOARD_VIEWCAST_460E) ||
|
||||
(dev->board == CX23885_BOARD_AVERMEDIA_CE310B)) {
|
||||
/* Configure audio routing */
|
||||
v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
|
||||
INPUT(input)->amux, 0, 0);
|
||||
|
@ -101,6 +101,7 @@
|
||||
#define CX23885_BOARD_HAUPPAUGE_STARBURST2 59
|
||||
#define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885 60
|
||||
#define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885 61
|
||||
#define CX23885_BOARD_AVERMEDIA_CE310B 62
|
||||
|
||||
#define GPIO_0 0x00000001
|
||||
#define GPIO_1 0x00000002
|
||||
|
@ -639,7 +639,6 @@ static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
|
||||
static const struct snd_pcm_ops snd_cx25821_pcm_ops = {
|
||||
.open = snd_cx25821_pcm_open,
|
||||
.close = snd_cx25821_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_cx25821_hw_params,
|
||||
.hw_free = snd_cx25821_hw_free,
|
||||
.prepare = snd_cx25821_prepare,
|
||||
|
@ -585,7 +585,6 @@ static struct page *snd_cx88_page(struct snd_pcm_substream *substream,
|
||||
static const struct snd_pcm_ops snd_cx88_pcm_ops = {
|
||||
.open = snd_cx88_pcm_open,
|
||||
.close = snd_cx88_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_cx88_hw_params,
|
||||
.hw_free = snd_cx88_hw_free,
|
||||
.prepare = snd_cx88_prepare,
|
||||
|
@ -613,7 +613,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't call i2c_new_probed_device() because it uses
|
||||
* We can't call i2c_new_scanned_device() because it uses
|
||||
* quick writes for probing and at least some RC receiver
|
||||
* devices only reply to reads.
|
||||
* Also, Hauppauge XVR needs to be specified, as address 0x71
|
||||
|
@ -24,7 +24,7 @@ config VIDEO_IVTV
|
||||
PCI personal video recorder devices.
|
||||
|
||||
This is used in devices such as the Hauppauge PVR-150/250/350/500
|
||||
cards. There is a driver homepage at <http://www.ivtvdriver.org>.
|
||||
cards.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ivtv.
|
||||
@ -67,8 +67,7 @@ config VIDEO_FB_IVTV
|
||||
This is a framebuffer driver for the Conexant cx23415 MPEG
|
||||
encoder/decoder.
|
||||
|
||||
This is used in the Hauppauge PVR-350 card. There is a driver
|
||||
homepage at <http://www.ivtvdriver.org>.
|
||||
This is used in the Hauppauge PVR-350 card.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ivtvfb.
|
||||
|
@ -16,8 +16,6 @@
|
||||
#include "ivtv-alsa.h"
|
||||
#include "ivtv-alsa-pcm.h"
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
|
||||
@ -206,67 +204,6 @@ static int snd_ivtv_pcm_capture_close(struct snd_pcm_substream *substream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ivtv_pcm_ioctl(struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void *arg)
|
||||
{
|
||||
struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
|
||||
int ret;
|
||||
|
||||
snd_ivtv_lock(itvsc);
|
||||
ret = snd_pcm_lib_ioctl(substream, cmd, arg);
|
||||
snd_ivtv_unlock(itvsc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
|
||||
size_t size)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = subs->runtime;
|
||||
|
||||
dprintk("Allocating vbuffer\n");
|
||||
if (runtime->dma_area) {
|
||||
if (runtime->dma_bytes > size)
|
||||
return 0;
|
||||
|
||||
vfree(runtime->dma_area);
|
||||
}
|
||||
runtime->dma_area = vmalloc(size);
|
||||
if (!runtime->dma_area)
|
||||
return -ENOMEM;
|
||||
|
||||
runtime->dma_bytes = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ivtv_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
dprintk("%s called\n", __func__);
|
||||
|
||||
return snd_pcm_alloc_vmalloc_buffer(substream,
|
||||
params_buffer_bytes(params));
|
||||
}
|
||||
|
||||
static int snd_ivtv_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
|
||||
unsigned long flags;
|
||||
unsigned char *dma_area = NULL;
|
||||
|
||||
spin_lock_irqsave(&itvsc->slock, flags);
|
||||
if (substream->runtime->dma_area) {
|
||||
dprintk("freeing pcm capture region\n");
|
||||
dma_area = substream->runtime->dma_area;
|
||||
substream->runtime->dma_area = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&itvsc->slock, flags);
|
||||
vfree(dma_area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ivtv_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
|
||||
@ -296,24 +233,12 @@ snd_pcm_uframes_t snd_ivtv_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
return hwptr_done;
|
||||
}
|
||||
|
||||
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
|
||||
unsigned long offset)
|
||||
{
|
||||
void *pageptr = subs->runtime->dma_area + offset;
|
||||
|
||||
return vmalloc_to_page(pageptr);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_ops snd_ivtv_pcm_capture_ops = {
|
||||
.open = snd_ivtv_pcm_capture_open,
|
||||
.close = snd_ivtv_pcm_capture_close,
|
||||
.ioctl = snd_ivtv_pcm_ioctl,
|
||||
.hw_params = snd_ivtv_pcm_hw_params,
|
||||
.hw_free = snd_ivtv_pcm_hw_free,
|
||||
.prepare = snd_ivtv_pcm_prepare,
|
||||
.trigger = snd_ivtv_pcm_trigger,
|
||||
.pointer = snd_ivtv_pcm_pointer,
|
||||
.page = snd_pcm_get_vmalloc_page,
|
||||
};
|
||||
|
||||
int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
|
||||
@ -339,6 +264,7 @@ int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
|
||||
|
||||
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
|
||||
&snd_ivtv_pcm_capture_ops);
|
||||
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
|
||||
sp->info_flags = 0;
|
||||
sp->private_data = itvsc;
|
||||
strscpy(sp->name, itv->card_name, sizeof(sp->name));
|
||||
|
@ -23,7 +23,6 @@
|
||||
* Driver for the Conexant CX23415/CX23416 chip.
|
||||
* Author: Kevin Thayer (nufan_wfk at yahoo.com)
|
||||
* License: GPL
|
||||
* http://www.ivtvdriver.org
|
||||
*
|
||||
* -----
|
||||
* MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
|
||||
@ -723,7 +722,7 @@ done:
|
||||
IVTV_ERR(" %s based\n", chipname);
|
||||
IVTV_ERR("Defaulting to %s card\n", itv->card->name);
|
||||
IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
|
||||
IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
|
||||
IVTV_ERR("card you have to the linux-media mailinglist (www.linuxtv.org)\n");
|
||||
IVTV_ERR("Prefix your subject line with [UNKNOWN IVTV CARD].\n");
|
||||
}
|
||||
itv->v4l2_cap = itv->card->v4l2_capabilities;
|
||||
|
@ -28,7 +28,6 @@
|
||||
* Driver for the cx23415/6 chip.
|
||||
* Author: Kevin Thayer (nufan_wfk at yahoo.com)
|
||||
* License: GPL
|
||||
* http://www.ivtvdriver.org
|
||||
*
|
||||
* -----
|
||||
* MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
|
||||
|
@ -208,12 +208,12 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
|
||||
info.platform_data = init_data;
|
||||
strscpy(info.type, type, I2C_NAME_SIZE);
|
||||
|
||||
return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
|
||||
return IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL)) ?
|
||||
-1 : 0;
|
||||
}
|
||||
|
||||
/* Instantiate the IR receiver device using probing -- undesirable */
|
||||
struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
|
||||
void ivtv_i2c_new_ir_legacy(struct ivtv *itv)
|
||||
{
|
||||
struct i2c_board_info info;
|
||||
/*
|
||||
@ -235,7 +235,7 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
|
||||
|
||||
memset(&info, 0, sizeof(struct i2c_board_info));
|
||||
strscpy(info.type, "ir_video", I2C_NAME_SIZE);
|
||||
return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL);
|
||||
i2c_new_scanned_device(&itv->i2c_adap, &info, addr_list, NULL);
|
||||
}
|
||||
|
||||
int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef IVTV_I2C_H
|
||||
#define IVTV_I2C_H
|
||||
|
||||
struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
|
||||
void ivtv_i2c_new_ir_legacy(struct ivtv *itv);
|
||||
int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
|
||||
struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
|
||||
|
||||
|
@ -1266,7 +1266,7 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
buf->flags |= V4L2_BUF_FLAG_DONE;
|
||||
|
||||
buf->field = V4L2_FIELD_NONE;
|
||||
buf->timestamp = ns_to_timeval(meye.grab_buffer[index].ts);
|
||||
v4l2_buffer_set_timestamp(buf, meye.grab_buffer[index].ts);
|
||||
buf->sequence = meye.grab_buffer[index].sequence;
|
||||
buf->memory = V4L2_MEMORY_MMAP;
|
||||
buf->m.offset = index * gbufsize;
|
||||
@ -1332,7 +1332,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
buf->bytesused = meye.grab_buffer[reqnr].size;
|
||||
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||
buf->field = V4L2_FIELD_NONE;
|
||||
buf->timestamp = ns_to_timeval(meye.grab_buffer[reqnr].ts);
|
||||
v4l2_buffer_set_timestamp(buf, meye.grab_buffer[reqnr].ts);
|
||||
buf->sequence = meye.grab_buffer[reqnr].sequence;
|
||||
buf->memory = V4L2_MEMORY_MMAP;
|
||||
buf->m.offset = reqnr * gbufsize;
|
||||
|
@ -865,7 +865,6 @@ static struct page *snd_card_saa7134_page(struct snd_pcm_substream *substream,
|
||||
static const struct snd_pcm_ops snd_card_saa7134_capture_ops = {
|
||||
.open = snd_card_saa7134_capture_open,
|
||||
.close = snd_card_saa7134_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_card_saa7134_hw_params,
|
||||
.hw_free = snd_card_saa7134_hw_free,
|
||||
.prepare = snd_card_saa7134_capture_prepare,
|
||||
|
@ -116,8 +116,8 @@ static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter,
|
||||
|
||||
request_module(bi.type);
|
||||
|
||||
tuner = i2c_new_device(adapter, &bi);
|
||||
if (tuner == NULL || tuner->dev.driver == NULL)
|
||||
tuner = i2c_new_client_device(adapter, &bi);
|
||||
if (!i2c_client_has_driver(tuner))
|
||||
return -ENODEV;
|
||||
|
||||
if (!try_module_get(tuner->dev.driver->owner)) {
|
||||
@ -637,9 +637,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
|
||||
info.addr = 0xc8 >> 1;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap,
|
||||
&info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&dev->i2c_bus[2].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
@ -657,9 +656,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
|
||||
info.addr = 0xc0 >> 1;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[0].i2c_adap,
|
||||
&info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
goto frontend_detach;
|
||||
@ -682,9 +680,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
|
||||
info.addr = 0xcc >> 1;
|
||||
info.platform_data = &si2168_config;
|
||||
request_module(info.type);
|
||||
client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap,
|
||||
&info);
|
||||
if (!client_demod || !client_demod->dev.driver)
|
||||
client_demod = i2c_new_client_device(&dev->i2c_bus[2].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_demod))
|
||||
goto frontend_detach;
|
||||
|
||||
if (!try_module_get(client_demod->dev.driver->owner)) {
|
||||
@ -702,9 +699,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
|
||||
info.addr = 0xc0 >> 1;
|
||||
info.platform_data = &si2157_config;
|
||||
request_module(info.type);
|
||||
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap,
|
||||
&info);
|
||||
if (!client_tuner || !client_tuner->dev.driver) {
|
||||
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
|
||||
if (!i2c_client_has_driver(client_tuner)) {
|
||||
module_put(client_demod->dev.driver->owner);
|
||||
i2c_unregister_device(client_demod);
|
||||
goto frontend_detach;
|
||||
|
@ -484,8 +484,8 @@ static struct i2c_client *smi_add_i2c_client(struct i2c_adapter *adapter,
|
||||
struct i2c_client *client;
|
||||
|
||||
request_module(info->type);
|
||||
client = i2c_new_device(adapter, info);
|
||||
if (client == NULL || client->dev.driver == NULL)
|
||||
client = i2c_new_client_device(adapter, info);
|
||||
if (!i2c_client_has_driver(client))
|
||||
goto err_add_i2c_client;
|
||||
|
||||
if (!try_module_get(client->dev.driver->owner)) {
|
||||
|
@ -97,17 +97,6 @@ void solo_g723_isr(struct solo_dev *solo_dev)
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_solo_hw_params(struct snd_pcm_substream *ss,
|
||||
struct snd_pcm_hw_params *hw_params)
|
||||
{
|
||||
return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
|
||||
}
|
||||
|
||||
static int snd_solo_hw_free(struct snd_pcm_substream *ss)
|
||||
{
|
||||
return snd_pcm_lib_free_pages(ss);
|
||||
}
|
||||
|
||||
static const struct snd_pcm_hardware snd_solo_pcm_hw = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
@ -270,9 +259,6 @@ static int snd_solo_pcm_copy_kernel(struct snd_pcm_substream *ss, int channel,
|
||||
static const struct snd_pcm_ops snd_solo_pcm_ops = {
|
||||
.open = snd_solo_pcm_open,
|
||||
.close = snd_solo_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_solo_hw_params,
|
||||
.hw_free = snd_solo_hw_free,
|
||||
.prepare = snd_solo_pcm_prepare,
|
||||
.trigger = snd_solo_pcm_trigger,
|
||||
.pointer = snd_solo_pcm_pointer,
|
||||
@ -351,7 +337,7 @@ static int solo_snd_pcm_init(struct solo_dev *solo_dev)
|
||||
ss; ss = ss->next, i++)
|
||||
sprintf(ss->name, "Camera #%d Audio", i);
|
||||
|
||||
snd_pcm_lib_preallocate_pages_for_all(pcm,
|
||||
snd_pcm_set_managed_buffer_all(pcm,
|
||||
SNDRV_DMA_TYPE_CONTINUOUS,
|
||||
NULL,
|
||||
G723_PERIOD_BYTES * PERIODS,
|
||||
|
@ -78,17 +78,6 @@ void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests,
|
||||
}
|
||||
}
|
||||
|
||||
static int tw686x_pcm_hw_params(struct snd_pcm_substream *ss,
|
||||
struct snd_pcm_hw_params *hw_params)
|
||||
{
|
||||
return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
|
||||
}
|
||||
|
||||
static int tw686x_pcm_hw_free(struct snd_pcm_substream *ss)
|
||||
{
|
||||
return snd_pcm_lib_free_pages(ss);
|
||||
}
|
||||
|
||||
/*
|
||||
* Audio parameters are global and shared among all
|
||||
* capture channels. The driver prevents changes to
|
||||
@ -269,9 +258,6 @@ static snd_pcm_uframes_t tw686x_pcm_pointer(struct snd_pcm_substream *ss)
|
||||
static const struct snd_pcm_ops tw686x_pcm_ops = {
|
||||
.open = tw686x_pcm_open,
|
||||
.close = tw686x_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = tw686x_pcm_hw_params,
|
||||
.hw_free = tw686x_pcm_hw_free,
|
||||
.prepare = tw686x_pcm_prepare,
|
||||
.trigger = tw686x_pcm_trigger,
|
||||
.pointer = tw686x_pcm_pointer,
|
||||
@ -298,7 +284,7 @@ static int tw686x_snd_pcm_init(struct tw686x_dev *dev)
|
||||
ss; ss = ss->next, i++)
|
||||
snprintf(ss->name, sizeof(ss->name), "vch%u audio", i);
|
||||
|
||||
snd_pcm_lib_preallocate_pages_for_all(pcm,
|
||||
snd_pcm_set_managed_buffer_all(pcm,
|
||||
SNDRV_DMA_TYPE_DEV,
|
||||
&dev->pci_dev->dev,
|
||||
TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,
|
||||
|
@ -151,7 +151,7 @@ source "drivers/media/platform/sunxi/Kconfig"
|
||||
config VIDEO_TI_CAL
|
||||
tristate "TI CAL (Camera Adaptation Layer) driver"
|
||||
depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on SOC_DRA7XX || COMPILE_TEST
|
||||
depends on SOC_DRA7XX || ARCH_K3 || COMPILE_TEST
|
||||
select VIDEOBUF2_DMA_CONTIG
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
@ -200,7 +200,7 @@ config VIDEO_IMX_PXP
|
||||
|
||||
config VIDEO_MEDIATEK_JPEG
|
||||
tristate "Mediatek JPEG Codec driver"
|
||||
depends on MTK_IOMMU_V1 || COMPILE_TEST
|
||||
depends on MTK_IOMMU_V1 || MTK_IOMMU || COMPILE_TEST
|
||||
depends on VIDEO_DEV && VIDEO_V4L2
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
select VIDEOBUF2_DMA_CONTIG
|
||||
|
@ -73,6 +73,9 @@ const struct isc_format controller_formats[] = {
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_GREY,
|
||||
},
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_Y10,
|
||||
},
|
||||
};
|
||||
|
||||
/* This is a list of formats that the ISC can receive as *input* */
|
||||
@ -164,6 +167,12 @@ struct isc_format formats_list[] = {
|
||||
.mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE,
|
||||
.pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
|
||||
},
|
||||
{
|
||||
.fourcc = V4L2_PIX_FMT_Y10,
|
||||
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
|
||||
.pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/* Gamma table with gamma 1/2.2 */
|
||||
@ -211,6 +220,10 @@ const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = {
|
||||
#define ISC_IS_FORMAT_RAW(mbus_code) \
|
||||
(((mbus_code) & 0xf000) == 0x3000)
|
||||
|
||||
#define ISC_IS_FORMAT_GREY(mbus_code) \
|
||||
(((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \
|
||||
(((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))
|
||||
|
||||
static inline void isc_update_awb_ctrls(struct isc_device *isc)
|
||||
{
|
||||
struct isc_ctrls *ctrls = &isc->ctrls;
|
||||
@ -1003,6 +1016,7 @@ static int isc_try_validate_formats(struct isc_device *isc)
|
||||
rgb = true;
|
||||
break;
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
ret = 0;
|
||||
grey = true;
|
||||
break;
|
||||
@ -1010,34 +1024,29 @@ static int isc_try_validate_formats(struct isc_device *isc)
|
||||
/* any other different formats are not supported */
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* we cannot output RAW/Grey if we do not receive RAW */
|
||||
if ((bayer || grey) &&
|
||||
!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
|
||||
return -EINVAL;
|
||||
|
||||
v4l2_dbg(1, debug, &isc->v4l2_dev,
|
||||
"Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
|
||||
rgb, yuv, grey, bayer);
|
||||
|
||||
/* we cannot output RAW if we do not receive RAW */
|
||||
if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
|
||||
return -EINVAL;
|
||||
|
||||
/* we cannot output GREY if we do not receive RAW/GREY */
|
||||
if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
|
||||
!ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
|
||||
return -EINVAL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configures the RLP and DMA modules, depending on the output format
|
||||
* configured for the ISC.
|
||||
* If direct_dump == true, just dump raw data 8 bits.
|
||||
* If direct_dump == true, just dump raw data 8/16 bits depending on format.
|
||||
*/
|
||||
static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump)
|
||||
{
|
||||
if (direct_dump) {
|
||||
isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
|
||||
isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
|
||||
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
|
||||
isc->try_config.bpp = 16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (isc->try_config.fourcc) {
|
||||
case V4L2_PIX_FMT_SBGGR8:
|
||||
case V4L2_PIX_FMT_SGBRG8:
|
||||
@ -1115,9 +1124,23 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump)
|
||||
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
|
||||
isc->try_config.bpp = 8;
|
||||
break;
|
||||
case V4L2_PIX_FMT_Y10:
|
||||
isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10;
|
||||
isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
|
||||
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
|
||||
isc->try_config.bpp = 16;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (direct_dump) {
|
||||
isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
|
||||
isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
|
||||
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1187,13 +1210,44 @@ static int isc_try_configure_pipeline(struct isc_device *isc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void isc_try_fse(struct isc_device *isc,
|
||||
struct v4l2_subdev_pad_config *pad_cfg)
|
||||
{
|
||||
int ret;
|
||||
struct v4l2_subdev_frame_size_enum fse = {};
|
||||
|
||||
/*
|
||||
* If we do not know yet which format the subdev is using, we cannot
|
||||
* do anything.
|
||||
*/
|
||||
if (!isc->try_config.sd_format)
|
||||
return;
|
||||
|
||||
fse.code = isc->try_config.sd_format->mbus_code;
|
||||
fse.which = V4L2_SUBDEV_FORMAT_TRY;
|
||||
|
||||
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
|
||||
pad_cfg, &fse);
|
||||
/*
|
||||
* Attempt to obtain format size from subdev. If not available,
|
||||
* just use the maximum ISC can receive.
|
||||
*/
|
||||
if (ret) {
|
||||
pad_cfg->try_crop.width = ISC_MAX_SUPPORT_WIDTH;
|
||||
pad_cfg->try_crop.height = ISC_MAX_SUPPORT_HEIGHT;
|
||||
} else {
|
||||
pad_cfg->try_crop.width = fse.max_width;
|
||||
pad_cfg->try_crop.height = fse.max_height;
|
||||
}
|
||||
}
|
||||
|
||||
static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
|
||||
u32 *code)
|
||||
{
|
||||
int i;
|
||||
struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
|
||||
struct v4l2_pix_format *pixfmt = &f->fmt.pix;
|
||||
struct v4l2_subdev_pad_config pad_cfg;
|
||||
struct v4l2_subdev_pad_config pad_cfg = {};
|
||||
struct v4l2_subdev_format format = {
|
||||
.which = V4L2_SUBDEV_FORMAT_TRY,
|
||||
};
|
||||
@ -1290,6 +1344,9 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
|
||||
if (ret)
|
||||
goto isc_try_fmt_err;
|
||||
|
||||
/* Obtain frame sizes if possible to have crop requirements ready */
|
||||
isc_try_fse(isc, &pad_cfg);
|
||||
|
||||
v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
|
||||
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
|
||||
&pad_cfg, &format);
|
||||
@ -1414,6 +1471,7 @@ static int isc_enum_framesizes(struct file *file, void *fh,
|
||||
{
|
||||
struct isc_device *isc = video_drvdata(file);
|
||||
struct v4l2_subdev_frame_size_enum fse = {
|
||||
.code = isc->config.sd_format->mbus_code,
|
||||
.index = fsize->index,
|
||||
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
|
||||
};
|
||||
@ -1436,8 +1494,6 @@ static int isc_enum_framesizes(struct file *file, void *fh,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fse.code = isc->config.sd_format->mbus_code;
|
||||
|
||||
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
|
||||
fsize->discrete.width = fse.max_width;
|
||||
fsize->discrete.height = fse.max_height;
|
||||
@ -1450,6 +1506,7 @@ static int isc_enum_frameintervals(struct file *file, void *fh,
|
||||
{
|
||||
struct isc_device *isc = video_drvdata(file);
|
||||
struct v4l2_subdev_frame_interval_enum fie = {
|
||||
.code = isc->config.sd_format->mbus_code,
|
||||
.index = fival->index,
|
||||
.width = fival->width,
|
||||
.height = fival->height,
|
||||
@ -1474,7 +1531,6 @@ static int isc_enum_frameintervals(struct file *file, void *fh,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fie.code = isc->config.sd_format->mbus_code;
|
||||
fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
|
||||
fival->discrete = fie.interval;
|
||||
|
||||
|
@ -148,7 +148,8 @@ static void configure_geometry(struct atmel_isi *isi)
|
||||
u32 fourcc = isi->current_fmt->fourcc;
|
||||
|
||||
isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
|
||||
fourcc == V4L2_PIX_FMT_RGB32;
|
||||
fourcc == V4L2_PIX_FMT_RGB32 ||
|
||||
fourcc == V4L2_PIX_FMT_Y16;
|
||||
|
||||
/* According to sensor's output format to set cfg2 */
|
||||
cfg2 = isi->current_fmt->swap;
|
||||
@ -554,12 +555,36 @@ static const struct isi_format *find_format_by_fourcc(struct atmel_isi *isi,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void isi_try_fse(struct atmel_isi *isi, const struct isi_format *isi_fmt,
|
||||
struct v4l2_subdev_pad_config *pad_cfg)
|
||||
{
|
||||
int ret;
|
||||
struct v4l2_subdev_frame_size_enum fse = {
|
||||
.code = isi_fmt->mbus_code,
|
||||
.which = V4L2_SUBDEV_FORMAT_TRY,
|
||||
};
|
||||
|
||||
ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
|
||||
pad_cfg, &fse);
|
||||
/*
|
||||
* Attempt to obtain format size from subdev. If not available,
|
||||
* just use the maximum ISI can receive.
|
||||
*/
|
||||
if (ret) {
|
||||
pad_cfg->try_crop.width = MAX_SUPPORT_WIDTH;
|
||||
pad_cfg->try_crop.height = MAX_SUPPORT_HEIGHT;
|
||||
} else {
|
||||
pad_cfg->try_crop.width = fse.max_width;
|
||||
pad_cfg->try_crop.height = fse.max_height;
|
||||
}
|
||||
}
|
||||
|
||||
static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
|
||||
const struct isi_format **current_fmt)
|
||||
{
|
||||
const struct isi_format *isi_fmt;
|
||||
struct v4l2_pix_format *pixfmt = &f->fmt.pix;
|
||||
struct v4l2_subdev_pad_config pad_cfg;
|
||||
struct v4l2_subdev_pad_config pad_cfg = {};
|
||||
struct v4l2_subdev_format format = {
|
||||
.which = V4L2_SUBDEV_FORMAT_TRY,
|
||||
};
|
||||
@ -576,6 +601,9 @@ static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
|
||||
pixfmt->height = clamp(pixfmt->height, 0U, MAX_SUPPORT_HEIGHT);
|
||||
|
||||
v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
|
||||
|
||||
isi_try_fse(isi, isi_fmt, &pad_cfg);
|
||||
|
||||
ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
|
||||
&pad_cfg, &format);
|
||||
if (ret < 0)
|
||||
@ -990,6 +1018,16 @@ static const struct isi_format isi_formats[] = {
|
||||
.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
|
||||
.bpp = 2,
|
||||
.swap = ISI_CFG2_YCC_SWAP_MODE_1,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_GREY,
|
||||
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
|
||||
.bpp = 1,
|
||||
.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
|
||||
}, {
|
||||
.fourcc = V4L2_PIX_FMT_Y16,
|
||||
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
|
||||
.bpp = 2,
|
||||
.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -62,6 +62,8 @@
|
||||
#define ISI_CFG1_THMASK_BEATS_16 (2 << 13)
|
||||
|
||||
/* Bitfields in CFG2 */
|
||||
#define ISI_CFG2_GS_MODE_2_PIXEL (0 << 11)
|
||||
#define ISI_CFG2_GS_MODE_1_PIXEL (1 << 11)
|
||||
#define ISI_CFG2_GRAYSCALE (1 << 13)
|
||||
#define ISI_CFG2_COL_SPACE_YCbCr (0 << 15)
|
||||
#define ISI_CFG2_COL_SPACE_RGB (1 << 15)
|
||||
|
@ -1629,6 +1629,9 @@ static void coda_finish_encode(struct coda_ctx *ctx)
|
||||
struct coda_dev *dev = ctx->dev;
|
||||
u32 wr_ptr, start_ptr;
|
||||
|
||||
if (ctx->aborting)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Lock to make sure that an encoder stop command running in parallel
|
||||
* will either already have marked src_buf as last, or it will wake up
|
||||
@ -2165,16 +2168,21 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
|
||||
} else {
|
||||
if (dev->devtype->product == CODA_960) {
|
||||
/*
|
||||
* The CODA960 seems to have an internal list of
|
||||
* buffers with 64 entries that includes the
|
||||
* registered frame buffers as well as the rotator
|
||||
* buffer output.
|
||||
*
|
||||
* ROT_INDEX needs to be < 0x40, but >
|
||||
* ctx->num_internal_frames.
|
||||
* It was previously assumed that the CODA960 has an
|
||||
* internal list of 64 buffer entries that contains
|
||||
* both the registered internal frame buffers as well
|
||||
* as the rotator buffer output, and that the ROT_INDEX
|
||||
* register must be set to a value between the last
|
||||
* internal frame buffers' index and 64.
|
||||
* At least on firmware version 3.1.1 it turns out that
|
||||
* setting ROT_INDEX to any value >= 32 causes CODA
|
||||
* hangups that it can not recover from with the SRC VPU
|
||||
* reset.
|
||||
* It does appear to work however, to just set it to a
|
||||
* fixed value in the [ctx->num_internal_frames, 31]
|
||||
* range, for example CODA_MAX_FRAMEBUFFERS.
|
||||
*/
|
||||
coda_write(dev,
|
||||
CODA_MAX_FRAMEBUFFERS + dst_buf->vb2_buf.index,
|
||||
coda_write(dev, CODA_MAX_FRAMEBUFFERS,
|
||||
CODA9_CMD_DEC_PIC_ROT_INDEX);
|
||||
|
||||
reg_addr = CODA9_CMD_DEC_PIC_ROT_ADDR_Y;
|
||||
@ -2266,6 +2274,9 @@ static void coda_finish_decode(struct coda_ctx *ctx)
|
||||
int err_vdoa = 0;
|
||||
u32 val;
|
||||
|
||||
if (ctx->aborting)
|
||||
return;
|
||||
|
||||
/* Update kfifo out pointer from coda bitstream read pointer */
|
||||
coda_kfifo_sync_from_device(ctx);
|
||||
|
||||
|
@ -155,6 +155,7 @@ static const struct coda_codec coda7_codecs[] = {
|
||||
static const struct coda_codec coda9_codecs[] = {
|
||||
CODA_CODEC(CODA9_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1920, 1088),
|
||||
CODA_CODEC(CODA9_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1920, 1088),
|
||||
CODA_CODEC(CODA9_MODE_ENCODE_MJPG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_JPEG, 8192, 8192),
|
||||
CODA_CODEC(CODA9_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1088),
|
||||
CODA_CODEC(CODA9_MODE_DECODE_MP2, V4L2_PIX_FMT_MPEG2, V4L2_PIX_FMT_YUV420, 1920, 1088),
|
||||
CODA_CODEC(CODA9_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1088),
|
||||
@ -235,6 +236,22 @@ static const struct coda_video_device coda_bit_jpeg_decoder = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct coda_video_device coda9_jpeg_encoder = {
|
||||
.name = "coda-jpeg-encoder",
|
||||
.type = CODA_INST_ENCODER,
|
||||
.ops = &coda9_jpeg_encode_ops,
|
||||
.direct = true,
|
||||
.src_formats = {
|
||||
V4L2_PIX_FMT_NV12,
|
||||
V4L2_PIX_FMT_YUV420,
|
||||
V4L2_PIX_FMT_YVU420,
|
||||
V4L2_PIX_FMT_YUV422P,
|
||||
},
|
||||
.dst_formats = {
|
||||
V4L2_PIX_FMT_JPEG,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct coda_video_device *codadx6_video_devices[] = {
|
||||
&coda_bit_encoder,
|
||||
};
|
||||
@ -252,6 +269,7 @@ static const struct coda_video_device *coda7_video_devices[] = {
|
||||
};
|
||||
|
||||
static const struct coda_video_device *coda9_video_devices[] = {
|
||||
&coda9_jpeg_encoder,
|
||||
&coda_bit_encoder,
|
||||
&coda_bit_decoder,
|
||||
};
|
||||
@ -721,7 +739,8 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
|
||||
ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
|
||||
break;
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
if (!disable_tiling && ctx->dev->devtype->product == CODA_960) {
|
||||
if (!disable_tiling && ctx->use_bit &&
|
||||
ctx->dev->devtype->product == CODA_960) {
|
||||
ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
|
||||
break;
|
||||
}
|
||||
@ -1421,7 +1440,7 @@ static void coda_pic_run_work(struct work_struct *work)
|
||||
|
||||
if (ctx->ops->run_timeout)
|
||||
ctx->ops->run_timeout(ctx);
|
||||
} else if (!ctx->aborting) {
|
||||
} else {
|
||||
ctx->ops->finish_run(ctx);
|
||||
}
|
||||
|
||||
@ -1787,7 +1806,7 @@ static void coda_buf_queue(struct vb2_buffer *vb)
|
||||
coda_queue_source_change_event(ctx);
|
||||
}
|
||||
} else {
|
||||
if (ctx->inst_type == CODA_INST_ENCODER &&
|
||||
if ((ctx->inst_type == CODA_INST_ENCODER || !ctx->use_bit) &&
|
||||
vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
|
||||
vbuf->sequence = ctx->qsequence++;
|
||||
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
|
||||
@ -2984,10 +3003,8 @@ static int coda_probe(struct platform_device *pdev)
|
||||
irq = platform_get_irq_byname(pdev, "bit");
|
||||
if (irq < 0)
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to get irq resource\n");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, coda_irq_handler, 0,
|
||||
dev_name(&pdev->dev), dev);
|
||||
@ -2996,6 +3013,22 @@ static int coda_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* JPEG IRQ */
|
||||
if (dev->devtype->product == CODA_960) {
|
||||
irq = platform_get_irq_byname(pdev, "jpeg");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
coda9_jpeg_irq_handler,
|
||||
IRQF_ONESHOT, CODA_NAME " jpeg",
|
||||
dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to request jpeg irq\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dev->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev,
|
||||
NULL);
|
||||
if (IS_ERR(dev->rstc)) {
|
||||
|
@ -5,46 +5,68 @@
|
||||
* Copyright (C) 2014 Philipp Zabel, Pengutronix
|
||||
*/
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/swab.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-fh.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/videobuf2-dma-contig.h>
|
||||
|
||||
#include "coda.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define SOI_MARKER 0xffd8
|
||||
#define DRI_MARKER 0xffdd
|
||||
#define DQT_MARKER 0xffdb
|
||||
#define DHT_MARKER 0xffc4
|
||||
#define SOF_MARKER 0xffc0
|
||||
#define EOI_MARKER 0xffd9
|
||||
|
||||
enum {
|
||||
CODA9_JPEG_FORMAT_420,
|
||||
CODA9_JPEG_FORMAT_422,
|
||||
CODA9_JPEG_FORMAT_224,
|
||||
CODA9_JPEG_FORMAT_444,
|
||||
CODA9_JPEG_FORMAT_400,
|
||||
};
|
||||
|
||||
#define CODA9_JPEG_ENC_HUFF_DATA_SIZE (256 + 256 + 16 + 16)
|
||||
|
||||
/*
|
||||
* Typical Huffman tables for 8-bit precision luminance and
|
||||
* chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3
|
||||
*/
|
||||
|
||||
static const unsigned char luma_dc_bits[16] = {
|
||||
static const unsigned char luma_dc[16 + 12] = {
|
||||
/* bits */
|
||||
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const unsigned char luma_dc_value[12] = {
|
||||
/* values */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b,
|
||||
};
|
||||
|
||||
static const unsigned char chroma_dc_bits[16] = {
|
||||
static const unsigned char chroma_dc[16 + 12] = {
|
||||
/* bits */
|
||||
0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const unsigned char chroma_dc_value[12] = {
|
||||
/* values */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b,
|
||||
};
|
||||
|
||||
static const unsigned char luma_ac_bits[16] = {
|
||||
static const unsigned char luma_ac[16 + 162 + 2] = {
|
||||
/* bits */
|
||||
0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
|
||||
0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
|
||||
};
|
||||
|
||||
static const unsigned char luma_ac_value[162 + 2] = {
|
||||
/* values */
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
|
||||
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
|
||||
@ -68,12 +90,11 @@ static const unsigned char luma_ac_value[162 + 2] = {
|
||||
0xf9, 0xfa, /* padded to 32-bit */
|
||||
};
|
||||
|
||||
static const unsigned char chroma_ac_bits[16] = {
|
||||
static const unsigned char chroma_ac[16 + 162 + 2] = {
|
||||
/* bits */
|
||||
0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
|
||||
0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
|
||||
};
|
||||
|
||||
static const unsigned char chroma_ac_value[162 + 2] = {
|
||||
/* values */
|
||||
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
|
||||
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
|
||||
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
|
||||
@ -124,6 +145,38 @@ static unsigned char chroma_q[64] = {
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
};
|
||||
|
||||
static const unsigned char width_align[] = {
|
||||
[CODA9_JPEG_FORMAT_420] = 16,
|
||||
[CODA9_JPEG_FORMAT_422] = 16,
|
||||
[CODA9_JPEG_FORMAT_224] = 8,
|
||||
[CODA9_JPEG_FORMAT_444] = 8,
|
||||
[CODA9_JPEG_FORMAT_400] = 8,
|
||||
};
|
||||
|
||||
static const unsigned char height_align[] = {
|
||||
[CODA9_JPEG_FORMAT_420] = 16,
|
||||
[CODA9_JPEG_FORMAT_422] = 8,
|
||||
[CODA9_JPEG_FORMAT_224] = 16,
|
||||
[CODA9_JPEG_FORMAT_444] = 8,
|
||||
[CODA9_JPEG_FORMAT_400] = 8,
|
||||
};
|
||||
|
||||
static int coda9_jpeg_chroma_format(u32 pixfmt)
|
||||
{
|
||||
switch (pixfmt) {
|
||||
case V4L2_PIX_FMT_YUV420:
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
return CODA9_JPEG_FORMAT_420;
|
||||
case V4L2_PIX_FMT_YUV422P:
|
||||
return CODA9_JPEG_FORMAT_422;
|
||||
case V4L2_PIX_FMT_YUV444:
|
||||
return CODA9_JPEG_FORMAT_444;
|
||||
case V4L2_PIX_FMT_GREY:
|
||||
return CODA9_JPEG_FORMAT_400;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct coda_memcpy_desc {
|
||||
int offset;
|
||||
const void *src;
|
||||
@ -148,14 +201,10 @@ int coda_jpeg_write_tables(struct coda_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
static const struct coda_memcpy_desc huff[8] = {
|
||||
{ 0, luma_dc_bits, sizeof(luma_dc_bits) },
|
||||
{ 16, luma_dc_value, sizeof(luma_dc_value) },
|
||||
{ 32, luma_ac_bits, sizeof(luma_ac_bits) },
|
||||
{ 48, luma_ac_value, sizeof(luma_ac_value) },
|
||||
{ 216, chroma_dc_bits, sizeof(chroma_dc_bits) },
|
||||
{ 232, chroma_dc_value, sizeof(chroma_dc_value) },
|
||||
{ 248, chroma_ac_bits, sizeof(chroma_ac_bits) },
|
||||
{ 264, chroma_ac_value, sizeof(chroma_ac_value) },
|
||||
{ 0, luma_dc, sizeof(luma_dc) },
|
||||
{ 32, luma_ac, sizeof(luma_ac) },
|
||||
{ 216, chroma_dc, sizeof(chroma_dc) },
|
||||
{ 248, chroma_ac, sizeof(chroma_ac) },
|
||||
};
|
||||
struct coda_memcpy_desc qmat[3] = {
|
||||
{ 512, ctx->params.jpeg_qmat_tab[0], 64 },
|
||||
@ -198,6 +247,379 @@ bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
|
||||
return false;
|
||||
}
|
||||
|
||||
static const int bus_req_num[] = {
|
||||
[CODA9_JPEG_FORMAT_420] = 2,
|
||||
[CODA9_JPEG_FORMAT_422] = 3,
|
||||
[CODA9_JPEG_FORMAT_224] = 3,
|
||||
[CODA9_JPEG_FORMAT_444] = 4,
|
||||
[CODA9_JPEG_FORMAT_400] = 4,
|
||||
};
|
||||
|
||||
#define MCU_INFO(mcu_block_num, comp_num, comp0_info, comp1_info, comp2_info) \
|
||||
(((mcu_block_num) << CODA9_JPEG_MCU_BLOCK_NUM_OFFSET) | \
|
||||
((comp_num) << CODA9_JPEG_COMP_NUM_OFFSET) | \
|
||||
((comp0_info) << CODA9_JPEG_COMP0_INFO_OFFSET) | \
|
||||
((comp1_info) << CODA9_JPEG_COMP1_INFO_OFFSET) | \
|
||||
((comp2_info) << CODA9_JPEG_COMP2_INFO_OFFSET))
|
||||
|
||||
static const u32 mcu_info[] = {
|
||||
[CODA9_JPEG_FORMAT_420] = MCU_INFO(6, 3, 10, 5, 5),
|
||||
[CODA9_JPEG_FORMAT_422] = MCU_INFO(4, 3, 9, 5, 5),
|
||||
[CODA9_JPEG_FORMAT_224] = MCU_INFO(4, 3, 6, 5, 5),
|
||||
[CODA9_JPEG_FORMAT_444] = MCU_INFO(3, 3, 5, 5, 5),
|
||||
[CODA9_JPEG_FORMAT_400] = MCU_INFO(1, 1, 5, 0, 0),
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert Huffman table specifcations to tables of codes and code lengths.
|
||||
* For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
|
||||
*
|
||||
* [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
|
||||
*/
|
||||
static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num,
|
||||
int *ehufsi, int *ehufco)
|
||||
{
|
||||
int i, j, k, lastk, si, code, maxsymbol;
|
||||
const u8 *bits, *huffval;
|
||||
struct {
|
||||
int size[256];
|
||||
int code[256];
|
||||
} *huff;
|
||||
static const unsigned char *huff_tabs[4] = {
|
||||
luma_dc, luma_ac, chroma_dc, chroma_ac,
|
||||
};
|
||||
int ret = -EINVAL;
|
||||
|
||||
huff = kzalloc(sizeof(*huff), GFP_KERNEL);
|
||||
if (!huff)
|
||||
return -ENOMEM;
|
||||
|
||||
bits = huff_tabs[tab_num];
|
||||
huffval = huff_tabs[tab_num] + 16;
|
||||
|
||||
maxsymbol = tab_num & 1 ? 256 : 16;
|
||||
|
||||
/* Figure C.1 - Generation of table of Huffman code sizes */
|
||||
k = 0;
|
||||
for (i = 1; i <= 16; i++) {
|
||||
j = bits[i - 1];
|
||||
if (k + j > maxsymbol)
|
||||
goto out;
|
||||
while (j--)
|
||||
huff->size[k++] = i;
|
||||
}
|
||||
lastk = k;
|
||||
|
||||
/* Figure C.2 - Generation of table of Huffman codes */
|
||||
k = 0;
|
||||
code = 0;
|
||||
si = huff->size[0];
|
||||
while (k < lastk) {
|
||||
while (huff->size[k] == si) {
|
||||
huff->code[k++] = code;
|
||||
code++;
|
||||
}
|
||||
if (code >= (1 << si))
|
||||
goto out;
|
||||
code <<= 1;
|
||||
si++;
|
||||
}
|
||||
|
||||
/* Figure C.3 - Ordering procedure for encoding procedure code tables */
|
||||
for (k = 0; k < lastk; k++) {
|
||||
i = huffval[k];
|
||||
if (i >= maxsymbol || ehufsi[i])
|
||||
goto out;
|
||||
ehufco[i] = huff->code[k];
|
||||
ehufsi[i] = huff->size[k];
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(huff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DC_TABLE_INDEX0 0
|
||||
#define AC_TABLE_INDEX0 1
|
||||
#define DC_TABLE_INDEX1 2
|
||||
#define AC_TABLE_INDEX1 3
|
||||
|
||||
static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx)
|
||||
{
|
||||
struct {
|
||||
int size[4][256];
|
||||
int code[4][256];
|
||||
} *huff;
|
||||
u32 *huff_data;
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
huff = kzalloc(sizeof(*huff), GFP_KERNEL);
|
||||
if (!huff)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Generate all four (luma/chroma DC/AC) code/size lookup tables */
|
||||
for (i = 0; i < 4; i++) {
|
||||
ret = coda9_jpeg_gen_enc_huff_tab(ctx, i, huff->size[i],
|
||||
huff->code[i]);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ctx->params.jpeg_huff_data) {
|
||||
ctx->params.jpeg_huff_data =
|
||||
kzalloc(sizeof(u32) * CODA9_JPEG_ENC_HUFF_DATA_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (!ctx->params.jpeg_huff_data) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
huff_data = ctx->params.jpeg_huff_data;
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
/* Store Huffman lookup tables in AC0, AC1, DC0, DC1 order */
|
||||
int t = (j == 0) ? AC_TABLE_INDEX0 :
|
||||
(j == 1) ? AC_TABLE_INDEX1 :
|
||||
(j == 2) ? DC_TABLE_INDEX0 :
|
||||
DC_TABLE_INDEX1;
|
||||
/* DC tables only have 16 entries */
|
||||
int len = (j < 2) ? 256 : 16;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (huff->size[t][i] == 0 && huff->code[t][i] == 0)
|
||||
*(huff_data++) = 0;
|
||||
else
|
||||
*(huff_data++) =
|
||||
((huff->size[t][i] - 1) << 16) |
|
||||
huff->code[t][i];
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(huff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void coda9_jpeg_write_huff_tab(struct coda_ctx *ctx)
|
||||
{
|
||||
struct coda_dev *dev = ctx->dev;
|
||||
u32 *huff_data = ctx->params.jpeg_huff_data;
|
||||
int i;
|
||||
|
||||
/* Write Huffman size/code lookup tables in AC0, AC1, DC0, DC1 order */
|
||||
coda_write(dev, 0x3, CODA9_REG_JPEG_HUFF_CTRL);
|
||||
for (i = 0; i < CODA9_JPEG_ENC_HUFF_DATA_SIZE; i++)
|
||||
coda_write(dev, *(huff_data++), CODA9_REG_JPEG_HUFF_DATA);
|
||||
coda_write(dev, 0x0, CODA9_REG_JPEG_HUFF_CTRL);
|
||||
}
|
||||
|
||||
static inline void coda9_jpeg_write_qmat_quotients(struct coda_dev *dev,
|
||||
u8 *qmat, int index)
|
||||
{
|
||||
int i;
|
||||
|
||||
coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
|
||||
for (i = 0; i < 64; i++)
|
||||
coda_write(dev, 0x80000 / qmat[i], CODA9_REG_JPEG_QMAT_DATA);
|
||||
coda_write(dev, index, CODA9_REG_JPEG_QMAT_CTRL);
|
||||
}
|
||||
|
||||
static void coda9_jpeg_load_qmat_tab(struct coda_ctx *ctx)
|
||||
{
|
||||
struct coda_dev *dev = ctx->dev;
|
||||
u8 *luma_tab;
|
||||
u8 *chroma_tab;
|
||||
|
||||
luma_tab = ctx->params.jpeg_qmat_tab[0];
|
||||
if (!luma_tab)
|
||||
luma_tab = luma_q;
|
||||
|
||||
chroma_tab = ctx->params.jpeg_qmat_tab[1];
|
||||
if (!chroma_tab)
|
||||
chroma_tab = chroma_q;
|
||||
|
||||
coda9_jpeg_write_qmat_quotients(dev, luma_tab, 0x00);
|
||||
coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x40);
|
||||
coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x80);
|
||||
}
|
||||
|
||||
struct coda_jpeg_stream {
|
||||
u8 *curr;
|
||||
u8 *end;
|
||||
};
|
||||
|
||||
static inline int coda_jpeg_put_byte(u8 byte, struct coda_jpeg_stream *stream)
|
||||
{
|
||||
if (stream->curr >= stream->end)
|
||||
return -EINVAL;
|
||||
|
||||
*stream->curr++ = byte;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int coda_jpeg_put_word(u16 word, struct coda_jpeg_stream *stream)
|
||||
{
|
||||
if (stream->curr + sizeof(__be16) > stream->end)
|
||||
return -EINVAL;
|
||||
|
||||
put_unaligned_be16(word, stream->curr);
|
||||
stream->curr += sizeof(__be16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coda_jpeg_put_table(u16 marker, u8 index, const u8 *table,
|
||||
size_t len, struct coda_jpeg_stream *stream)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
ret = coda_jpeg_put_word(marker, stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_word(3 + len, stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_byte(index, stream);
|
||||
for (i = 0; i < len && ret == 0; i++)
|
||||
ret = coda_jpeg_put_byte(table[i], stream);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int coda_jpeg_define_quantization_table(struct coda_ctx *ctx, u8 index,
|
||||
struct coda_jpeg_stream *stream)
|
||||
{
|
||||
return coda_jpeg_put_table(DQT_MARKER, index,
|
||||
ctx->params.jpeg_qmat_tab[index], 64,
|
||||
stream);
|
||||
}
|
||||
|
||||
static int coda_jpeg_define_huffman_table(u8 index, const u8 *table, size_t len,
|
||||
struct coda_jpeg_stream *stream)
|
||||
{
|
||||
return coda_jpeg_put_table(DHT_MARKER, index, table, len, stream);
|
||||
}
|
||||
|
||||
static int coda9_jpeg_encode_header(struct coda_ctx *ctx, int len, u8 *buf)
|
||||
{
|
||||
struct coda_jpeg_stream stream = { buf, buf + len };
|
||||
struct coda_q_data *q_data_src;
|
||||
int chroma_format, comp_num;
|
||||
int i, ret, pad;
|
||||
|
||||
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
||||
chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
|
||||
if (chroma_format < 0)
|
||||
return 0;
|
||||
|
||||
/* Start Of Image */
|
||||
ret = coda_jpeg_put_word(SOI_MARKER, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Define Restart Interval */
|
||||
if (ctx->params.jpeg_restart_interval) {
|
||||
ret = coda_jpeg_put_word(DRI_MARKER, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_word(4, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_word(ctx->params.jpeg_restart_interval,
|
||||
&stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Define Quantization Tables */
|
||||
ret = coda_jpeg_define_quantization_table(ctx, 0x00, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (chroma_format != CODA9_JPEG_FORMAT_400) {
|
||||
ret = coda_jpeg_define_quantization_table(ctx, 0x01, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Define Huffman Tables */
|
||||
ret = coda_jpeg_define_huffman_table(0x00, luma_dc, 16 + 12, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_define_huffman_table(0x10, luma_ac, 16 + 162, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (chroma_format != CODA9_JPEG_FORMAT_400) {
|
||||
ret = coda_jpeg_define_huffman_table(0x01, chroma_dc, 16 + 12,
|
||||
&stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_define_huffman_table(0x11, chroma_ac, 16 + 162,
|
||||
&stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start Of Frame */
|
||||
ret = coda_jpeg_put_word(SOF_MARKER, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
comp_num = (chroma_format == CODA9_JPEG_FORMAT_400) ? 1 : 3;
|
||||
ret = coda_jpeg_put_word(8 + comp_num * 3, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_byte(0x08, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_word(q_data_src->height, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_word(q_data_src->width, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_byte(comp_num, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
for (i = 0; i < comp_num; i++) {
|
||||
static unsigned char subsampling[5][3] = {
|
||||
[CODA9_JPEG_FORMAT_420] = { 0x22, 0x11, 0x11 },
|
||||
[CODA9_JPEG_FORMAT_422] = { 0x21, 0x11, 0x11 },
|
||||
[CODA9_JPEG_FORMAT_224] = { 0x12, 0x11, 0x11 },
|
||||
[CODA9_JPEG_FORMAT_444] = { 0x11, 0x11, 0x11 },
|
||||
[CODA9_JPEG_FORMAT_400] = { 0x11 },
|
||||
};
|
||||
|
||||
/* Component identifier, matches SOS */
|
||||
ret = coda_jpeg_put_byte(i + 1, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = coda_jpeg_put_byte(subsampling[chroma_format][i],
|
||||
&stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Chroma table index */
|
||||
ret = coda_jpeg_put_byte((i == 0) ? 0 : 1, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Pad to multiple of 8 bytes */
|
||||
pad = (stream.curr - buf) % 8;
|
||||
if (pad) {
|
||||
pad = 8 - pad;
|
||||
while (pad--) {
|
||||
ret = coda_jpeg_put_byte(0x00, &stream);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return stream.curr - buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scale quantization table using nonlinear scaling factor
|
||||
* u8 qtab[64], scale [50,190]
|
||||
@ -247,3 +669,279 @@ void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality)
|
||||
coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Encoder context operations
|
||||
*/
|
||||
|
||||
static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
|
||||
{
|
||||
struct coda_dev *dev = ctx->dev;
|
||||
int ret;
|
||||
|
||||
ret = coda9_jpeg_load_huff_tab(ctx);
|
||||
if (ret < 0) {
|
||||
v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
|
||||
return ret;
|
||||
}
|
||||
if (!ctx->params.jpeg_qmat_tab[0])
|
||||
ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
|
||||
if (!ctx->params.jpeg_qmat_tab[1])
|
||||
ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
|
||||
coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
|
||||
{
|
||||
struct coda_q_data *q_data_src;
|
||||
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
||||
struct coda_dev *dev = ctx->dev;
|
||||
u32 start_addr, end_addr;
|
||||
u16 aligned_width, aligned_height;
|
||||
bool chroma_interleave;
|
||||
int chroma_format;
|
||||
int header_len;
|
||||
int ret;
|
||||
ktime_t timeout;
|
||||
|
||||
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
|
||||
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
|
||||
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
||||
|
||||
if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
|
||||
vb2_set_plane_payload(&src_buf->vb2_buf, 0,
|
||||
vb2_plane_size(&src_buf->vb2_buf, 0));
|
||||
|
||||
src_buf->sequence = ctx->osequence;
|
||||
dst_buf->sequence = ctx->osequence;
|
||||
ctx->osequence++;
|
||||
|
||||
src_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
|
||||
src_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
|
||||
|
||||
coda_set_gdi_regs(ctx);
|
||||
|
||||
start_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
|
||||
end_addr = start_addr + vb2_plane_size(&dst_buf->vb2_buf, 0);
|
||||
|
||||
chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
|
||||
if (chroma_format < 0)
|
||||
return chroma_format;
|
||||
|
||||
/* Round image dimensions to multiple of MCU size */
|
||||
aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
|
||||
aligned_height = round_up(q_data_src->height,
|
||||
height_align[chroma_format]);
|
||||
if (aligned_width != q_data_src->bytesperline) {
|
||||
v4l2_err(&dev->v4l2_dev, "wrong stride: %d instead of %d\n",
|
||||
aligned_width, q_data_src->bytesperline);
|
||||
}
|
||||
|
||||
header_len =
|
||||
coda9_jpeg_encode_header(ctx,
|
||||
vb2_plane_size(&dst_buf->vb2_buf, 0),
|
||||
vb2_plane_vaddr(&dst_buf->vb2_buf, 0));
|
||||
if (header_len < 0)
|
||||
return header_len;
|
||||
|
||||
coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_BAS_ADDR);
|
||||
coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_END_ADDR);
|
||||
coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_WR_PTR);
|
||||
coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_RD_PTR);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_BBC_CUR_POS);
|
||||
/* 64 words per 256-byte page */
|
||||
coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
|
||||
coda_write(dev, start_addr, CODA9_REG_JPEG_BBC_EXT_ADDR);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_BBC_INT_ADDR);
|
||||
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_BBC_STRM_CTRL);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
|
||||
coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
|
||||
coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
|
||||
coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
|
||||
|
||||
chroma_interleave = (q_data_src->fourcc == V4L2_PIX_FMT_NV12);
|
||||
coda_write(dev, CODA9_JPEG_PIC_CTRL_TC_DIRECTION |
|
||||
CODA9_JPEG_PIC_CTRL_ENCODER_EN, CODA9_REG_JPEG_PIC_CTRL);
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
|
||||
coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
|
||||
coda_write(dev, ctx->params.jpeg_restart_interval,
|
||||
CODA9_REG_JPEG_RST_INTVAL);
|
||||
coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
|
||||
|
||||
coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
|
||||
|
||||
coda9_jpeg_write_huff_tab(ctx);
|
||||
coda9_jpeg_load_qmat_tab(ctx);
|
||||
|
||||
if (ctx->params.rot_mode & CODA_ROT_90) {
|
||||
aligned_width = aligned_height;
|
||||
aligned_height = q_data_src->bytesperline;
|
||||
if (chroma_format == CODA9_JPEG_FORMAT_422)
|
||||
chroma_format = CODA9_JPEG_FORMAT_224;
|
||||
else if (chroma_format == CODA9_JPEG_FORMAT_224)
|
||||
chroma_format = CODA9_JPEG_FORMAT_422;
|
||||
}
|
||||
/* These need to be multiples of MCU size */
|
||||
coda_write(dev, aligned_width << 16 | aligned_height,
|
||||
CODA9_REG_JPEG_PIC_SIZE);
|
||||
coda_write(dev, ctx->params.rot_mode ?
|
||||
(CODA_ROT_MIR_ENABLE | ctx->params.rot_mode) : 0,
|
||||
CODA9_REG_JPEG_ROT_INFO);
|
||||
|
||||
coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
|
||||
|
||||
coda_write(dev, 1, CODA9_GDI_CONTROL);
|
||||
timeout = ktime_add_us(ktime_get(), 100000);
|
||||
do {
|
||||
ret = coda_read(dev, CODA9_GDI_STATUS);
|
||||
if (ktime_compare(ktime_get(), timeout) > 0) {
|
||||
v4l2_err(&dev->v4l2_dev, "timeout waiting for GDI\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
} while (!ret);
|
||||
|
||||
coda_write(dev, (chroma_format << 17) | (chroma_interleave << 16) |
|
||||
q_data_src->bytesperline, CODA9_GDI_INFO_CONTROL);
|
||||
/* The content of this register seems to be irrelevant: */
|
||||
coda_write(dev, aligned_width << 16 | aligned_height,
|
||||
CODA9_GDI_INFO_PIC_SIZE);
|
||||
|
||||
coda_write_base(ctx, q_data_src, src_buf, CODA9_GDI_INFO_BASE_Y);
|
||||
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
|
||||
coda_write(dev, 0, CODA9_GDI_CONTROL);
|
||||
coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
|
||||
|
||||
coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
|
||||
coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
|
||||
|
||||
trace_coda_jpeg_run(ctx, src_buf);
|
||||
|
||||
coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
|
||||
{
|
||||
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
||||
struct coda_dev *dev = ctx->dev;
|
||||
u32 wr_ptr, start_ptr;
|
||||
u32 err_mb;
|
||||
|
||||
if (ctx->aborting) {
|
||||
coda_write(ctx->dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock to make sure that an encoder stop command running in parallel
|
||||
* will either already have marked src_buf as last, or it will wake up
|
||||
* the capture queue after the buffers are returned.
|
||||
*/
|
||||
mutex_lock(&ctx->wakeup_mutex);
|
||||
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
|
||||
dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
|
||||
|
||||
trace_coda_jpeg_done(ctx, dst_buf);
|
||||
|
||||
/*
|
||||
* Set plane payload to the number of bytes written out
|
||||
* by the JPEG processing unit
|
||||
*/
|
||||
start_ptr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
|
||||
wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
|
||||
vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr);
|
||||
|
||||
err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
|
||||
if (err_mb)
|
||||
coda_dbg(1, ctx, "ERRMB: 0x%x\n", err_mb);
|
||||
|
||||
coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
|
||||
|
||||
dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
|
||||
dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
|
||||
dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
|
||||
|
||||
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
|
||||
|
||||
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
|
||||
coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
|
||||
VB2_BUF_STATE_DONE);
|
||||
mutex_unlock(&ctx->wakeup_mutex);
|
||||
|
||||
coda_dbg(1, ctx, "job finished: encoded frame (%u)%s\n",
|
||||
dst_buf->sequence,
|
||||
(dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
|
||||
}
|
||||
|
||||
static void coda9_jpeg_release(struct coda_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ctx->params.jpeg_qmat_tab[0] == luma_q)
|
||||
ctx->params.jpeg_qmat_tab[0] = NULL;
|
||||
if (ctx->params.jpeg_qmat_tab[1] == chroma_q)
|
||||
ctx->params.jpeg_qmat_tab[1] = NULL;
|
||||
for (i = 0; i < 3; i++)
|
||||
kfree(ctx->params.jpeg_qmat_tab[i]);
|
||||
kfree(ctx->params.jpeg_huff_data);
|
||||
}
|
||||
|
||||
const struct coda_context_ops coda9_jpeg_encode_ops = {
|
||||
.queue_init = coda_encoder_queue_init,
|
||||
.start_streaming = coda9_jpeg_start_encoding,
|
||||
.prepare_run = coda9_jpeg_prepare_encode,
|
||||
.finish_run = coda9_jpeg_finish_encode,
|
||||
.release = coda9_jpeg_release,
|
||||
};
|
||||
|
||||
irqreturn_t coda9_jpeg_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct coda_dev *dev = data;
|
||||
struct coda_ctx *ctx;
|
||||
int status;
|
||||
int err_mb;
|
||||
|
||||
status = coda_read(dev, CODA9_REG_JPEG_PIC_STATUS);
|
||||
if (status == 0)
|
||||
return IRQ_HANDLED;
|
||||
coda_write(dev, status, CODA9_REG_JPEG_PIC_STATUS);
|
||||
|
||||
if (status & CODA9_JPEG_STATUS_OVERFLOW)
|
||||
v4l2_err(&dev->v4l2_dev, "JPEG overflow\n");
|
||||
|
||||
if (status & CODA9_JPEG_STATUS_BBC_INT)
|
||||
v4l2_err(&dev->v4l2_dev, "JPEG BBC interrupt\n");
|
||||
|
||||
if (status & CODA9_JPEG_STATUS_ERROR) {
|
||||
v4l2_err(&dev->v4l2_dev, "JPEG error\n");
|
||||
|
||||
err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
|
||||
if (err_mb) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"ERRMB: 0x%x: rst idx %d, mcu pos (%d,%d)\n",
|
||||
err_mb, err_mb >> 24, (err_mb >> 12) & 0xfff,
|
||||
err_mb & 0xfff);
|
||||
}
|
||||
}
|
||||
|
||||
ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
|
||||
if (!ctx) {
|
||||
v4l2_err(&dev->v4l2_dev,
|
||||
"Instance released before the end of transaction\n");
|
||||
mutex_unlock(&dev->coda_mutex);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
complete(&ctx->completion);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -126,6 +126,7 @@ struct coda_params {
|
||||
u8 jpeg_quality;
|
||||
u8 jpeg_restart_interval;
|
||||
u8 *jpeg_qmat_tab[3];
|
||||
u32 *jpeg_huff_data;
|
||||
int codec_mode;
|
||||
int codec_mode_aux;
|
||||
enum v4l2_mpeg_video_multi_slice_mode slice_mode;
|
||||
@ -366,7 +367,9 @@ void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality);
|
||||
|
||||
extern const struct coda_context_ops coda_bit_encode_ops;
|
||||
extern const struct coda_context_ops coda_bit_decode_ops;
|
||||
extern const struct coda_context_ops coda9_jpeg_encode_ops;
|
||||
|
||||
irqreturn_t coda_irq_handler(int irq, void *data);
|
||||
irqreturn_t coda9_jpeg_irq_handler(int irq, void *data);
|
||||
|
||||
#endif /* __CODA_H__ */
|
||||
|
@ -451,12 +451,21 @@
|
||||
#define CODA9_CMD_FIRMWARE_CODE_REV 0x1c4
|
||||
|
||||
#define CODA9_GDMA_BASE 0x1000
|
||||
#define CODA9_GDI_CONTROL (CODA9_GDMA_BASE + 0x034)
|
||||
#define CODA9_GDI_PIC_INIT_HOST (CODA9_GDMA_BASE + 0x038)
|
||||
#define CODA9_GDI_STATUS (CODA9_GDMA_BASE + 0x080)
|
||||
#define CODA9_GDI_WPROT_ERR_CLR (CODA9_GDMA_BASE + 0x0a0)
|
||||
#define CODA9_GDI_WPROT_RGN_EN (CODA9_GDMA_BASE + 0x0ac)
|
||||
|
||||
#define CODA9_GDI_BUS_CTRL (CODA9_GDMA_BASE + 0x0f0)
|
||||
#define CODA9_GDI_BUS_STATUS (CODA9_GDMA_BASE + 0x0f4)
|
||||
|
||||
#define CODA9_GDI_INFO_CONTROL (CODA9_GDMA_BASE + 0x400)
|
||||
#define CODA9_GDI_INFO_PIC_SIZE (CODA9_GDMA_BASE + 0x404)
|
||||
#define CODA9_GDI_INFO_BASE_Y (CODA9_GDMA_BASE + 0x408)
|
||||
#define CODA9_GDI_INFO_BASE_CB (CODA9_GDMA_BASE + 0x40c)
|
||||
#define CODA9_GDI_INFO_BASE_CR (CODA9_GDMA_BASE + 0x410)
|
||||
|
||||
#define CODA9_GDI_XY2_CAS_0 (CODA9_GDMA_BASE + 0x800)
|
||||
#define CODA9_GDI_XY2_CAS_F (CODA9_GDMA_BASE + 0x83c)
|
||||
|
||||
@ -477,4 +486,78 @@
|
||||
#define CODA9_GDI_RBC2_AXI_1F (CODA9_GDMA_BASE + 0x91c)
|
||||
#define CODA9_GDI_TILEDBUF_BASE (CODA9_GDMA_BASE + 0x920)
|
||||
|
||||
#define CODA9_JPEG_BASE 0x3000
|
||||
#define CODA9_REG_JPEG_PIC_START (CODA9_JPEG_BASE + 0x000)
|
||||
#define CODA9_REG_JPEG_PIC_STATUS (CODA9_JPEG_BASE + 0x004)
|
||||
#define CODA9_JPEG_STATUS_OVERFLOW BIT(3)
|
||||
#define CODA9_JPEG_STATUS_BBC_INT BIT(2)
|
||||
#define CODA9_JPEG_STATUS_ERROR BIT(1)
|
||||
#define CODA9_JPEG_STATUS_DONE BIT(0)
|
||||
#define CODA9_REG_JPEG_PIC_ERRMB (CODA9_JPEG_BASE + 0x008)
|
||||
#define CODA9_JPEG_ERRMB_RESTART_IDX_MASK (0xf << 24)
|
||||
#define CODA9_JPEG_ERRMB_MCU_POS_X_MASK (0xfff << 12)
|
||||
#define CODA9_JPEG_ERRMB_MCU_POS_Y_MASK 0xfff
|
||||
#define CODA9_REG_JPEG_PIC_CTRL (CODA9_JPEG_BASE + 0x010)
|
||||
#define CODA9_JPEG_PIC_CTRL_USER_HUFFMAN_EN BIT(6)
|
||||
#define CODA9_JPEG_PIC_CTRL_TC_DIRECTION BIT(4)
|
||||
#define CODA9_JPEG_PIC_CTRL_ENCODER_EN BIT(3)
|
||||
#define CODA9_REG_JPEG_PIC_SIZE (CODA9_JPEG_BASE + 0x014)
|
||||
#define CODA9_REG_JPEG_MCU_INFO (CODA9_JPEG_BASE + 0x018)
|
||||
#define CODA9_JPEG_MCU_BLOCK_NUM_OFFSET 16
|
||||
#define CODA9_JPEG_COMP_NUM_OFFSET 12
|
||||
#define CODA9_JPEG_COMP0_INFO_OFFSET 8
|
||||
#define CODA9_JPEG_COMP1_INFO_OFFSET 4
|
||||
#define CODA9_JPEG_COMP2_INFO_OFFSET 0
|
||||
#define CODA9_REG_JPEG_ROT_INFO (CODA9_JPEG_BASE + 0x01c)
|
||||
#define CODA9_JPEG_ROT_MIR_ENABLE BIT(4)
|
||||
#define CODA9_JPEG_ROT_MIR_MODE_MASK 0xf
|
||||
#define CODA9_REG_JPEG_SCL_INFO (CODA9_JPEG_BASE + 0x020)
|
||||
#define CODA9_JPEG_SCL_ENABLE BIT(4)
|
||||
#define CODA9_JPEG_SCL_HOR_MODE_MASK (0x3 << 2)
|
||||
#define CODA9_JPEG_SCL_VER_MODE_MASK (0x3 << 0)
|
||||
#define CODA9_REG_JPEG_IF_INFO (CODA9_JPEG_BASE + 0x024)
|
||||
#define CODA9_JPEG_SENS_IF_CLR BIT(1)
|
||||
#define CODA9_JPEG_DISP_IF_CLR BIT(0)
|
||||
#define CODA9_REG_JPEG_OP_INFO (CODA9_JPEG_BASE + 0x02c)
|
||||
#define CODA9_JPEG_BUS_REQ_NUM_OFFSET 0
|
||||
#define CODA9_JPEG_BUS_REQ_NUM_MASK 0x7
|
||||
#define CODA9_REG_JPEG_DPB_CONFIG (CODA9_JPEG_BASE + 0x030)
|
||||
#define CODA9_REG_JPEG_DPB_BASE00 (CODA9_JPEG_BASE + 0x040)
|
||||
#define CODA9_REG_JPEG_HUFF_CTRL (CODA9_JPEG_BASE + 0x080)
|
||||
#define CODA9_REG_JPEG_HUFF_ADDR (CODA9_JPEG_BASE + 0x084)
|
||||
#define CODA9_REG_JPEG_HUFF_DATA (CODA9_JPEG_BASE + 0x088)
|
||||
#define CODA9_REG_JPEG_QMAT_CTRL (CODA9_JPEG_BASE + 0x090)
|
||||
#define CODA9_REG_JPEG_QMAT_ADDR (CODA9_JPEG_BASE + 0x094)
|
||||
#define CODA9_REG_JPEG_QMAT_DATA (CODA9_JPEG_BASE + 0x098)
|
||||
#define CODA9_REG_JPEG_RST_INTVAL (CODA9_JPEG_BASE + 0x0b0)
|
||||
#define CODA9_REG_JPEG_RST_INDEX (CODA9_JPEG_BASE + 0x0b4)
|
||||
#define CODA9_REG_JPEG_RST_COUNT (CODA9_JPEG_BASE + 0x0b8)
|
||||
#define CODA9_REG_JPEG_DPCM_DIFF_Y (CODA9_JPEG_BASE + 0x0f0)
|
||||
#define CODA9_REG_JPEG_DPCM_DIFF_CB (CODA9_JPEG_BASE + 0x0f4)
|
||||
#define CODA9_REG_JPEG_DPCM_DIFF_CR (CODA9_JPEG_BASE + 0x0f8)
|
||||
#define CODA9_REG_JPEG_GBU_CTRL (CODA9_JPEG_BASE + 0x100)
|
||||
#define CODA9_REG_JPEG_GBU_BT_PTR (CODA9_JPEG_BASE + 0x110)
|
||||
#define CODA9_REG_JPEG_GBU_WD_PTR (CODA9_JPEG_BASE + 0x114)
|
||||
#define CODA9_REG_JPEG_GBU_TT_CNT (CODA9_JPEG_BASE + 0x118)
|
||||
#define CODA9_REG_JPEG_GBU_BBSR (CODA9_JPEG_BASE + 0x140)
|
||||
#define CODA9_REG_JPEG_GBU_BBER (CODA9_JPEG_BASE + 0x144)
|
||||
#define CODA9_REG_JPEG_GBU_BBIR (CODA9_JPEG_BASE + 0x148)
|
||||
#define CODA9_REG_JPEG_GBU_BBHR (CODA9_JPEG_BASE + 0x14c)
|
||||
#define CODA9_REG_JPEG_GBU_BCNT (CODA9_JPEG_BASE + 0x158)
|
||||
#define CODA9_REG_JPEG_GBU_FF_RPTR (CODA9_JPEG_BASE + 0x160)
|
||||
#define CODA9_REG_JPEG_GBU_FF_WPTR (CODA9_JPEG_BASE + 0x164)
|
||||
#define CODA9_REG_JPEG_BBC_END_ADDR (CODA9_JPEG_BASE + 0x208)
|
||||
#define CODA9_REG_JPEG_BBC_WR_PTR (CODA9_JPEG_BASE + 0x20c)
|
||||
#define CODA9_REG_JPEG_BBC_RD_PTR (CODA9_JPEG_BASE + 0x210)
|
||||
#define CODA9_REG_JPEG_BBC_EXT_ADDR (CODA9_JPEG_BASE + 0x214)
|
||||
#define CODA9_REG_JPEG_BBC_INT_ADDR (CODA9_JPEG_BASE + 0x218)
|
||||
#define CODA9_REG_JPEG_BBC_DATA_CNT (CODA9_JPEG_BASE + 0x21c)
|
||||
#define CODA9_REG_JPEG_BBC_COMMAND (CODA9_JPEG_BASE + 0x220)
|
||||
#define CODA9_REG_JPEG_BBC_BUSY (CODA9_JPEG_BASE + 0x224)
|
||||
#define CODA9_REG_JPEG_BBC_CTRL (CODA9_JPEG_BASE + 0x228)
|
||||
#define CODA9_REG_JPEG_BBC_CUR_POS (CODA9_JPEG_BASE + 0x22c)
|
||||
#define CODA9_REG_JPEG_BBC_BAS_ADDR (CODA9_JPEG_BASE + 0x230)
|
||||
#define CODA9_REG_JPEG_BBC_STRM_CTRL (CODA9_JPEG_BASE + 0x234)
|
||||
#define CODA9_REG_JPEG_BBC_FLUSH_CMD (CODA9_JPEG_BASE + 0x238)
|
||||
|
||||
#endif
|
||||
|
@ -154,6 +154,16 @@ DEFINE_EVENT(coda_buf_meta_class, coda_dec_rot_done,
|
||||
TP_ARGS(ctx, buf, meta)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(coda_buf_class, coda_jpeg_run,
|
||||
TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
|
||||
TP_ARGS(ctx, buf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(coda_buf_class, coda_jpeg_done,
|
||||
TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
|
||||
TP_ARGS(ctx, buf)
|
||||
);
|
||||
|
||||
#endif /* __CODA_TRACE_H__ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
@ -168,21 +168,22 @@ int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev)
|
||||
int ret = 0;
|
||||
printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
|
||||
|
||||
BUG_ON(!dev->hw_ops.open);
|
||||
BUG_ON(!dev->hw_ops.enable);
|
||||
BUG_ON(!dev->hw_ops.set_hw_if_params);
|
||||
BUG_ON(!dev->hw_ops.configure);
|
||||
BUG_ON(!dev->hw_ops.set_buftype);
|
||||
BUG_ON(!dev->hw_ops.get_buftype);
|
||||
BUG_ON(!dev->hw_ops.enum_pix);
|
||||
BUG_ON(!dev->hw_ops.set_frame_format);
|
||||
BUG_ON(!dev->hw_ops.get_frame_format);
|
||||
BUG_ON(!dev->hw_ops.get_pixel_format);
|
||||
BUG_ON(!dev->hw_ops.set_pixel_format);
|
||||
BUG_ON(!dev->hw_ops.set_image_window);
|
||||
BUG_ON(!dev->hw_ops.get_image_window);
|
||||
BUG_ON(!dev->hw_ops.get_line_length);
|
||||
BUG_ON(!dev->hw_ops.getfid);
|
||||
if (!dev->hw_ops.open ||
|
||||
!dev->hw_ops.enable ||
|
||||
!dev->hw_ops.set_hw_if_params ||
|
||||
!dev->hw_ops.configure ||
|
||||
!dev->hw_ops.set_buftype ||
|
||||
!dev->hw_ops.get_buftype ||
|
||||
!dev->hw_ops.enum_pix ||
|
||||
!dev->hw_ops.set_frame_format ||
|
||||
!dev->hw_ops.get_frame_format ||
|
||||
!dev->hw_ops.get_pixel_format ||
|
||||
!dev->hw_ops.set_pixel_format ||
|
||||
!dev->hw_ops.set_image_window ||
|
||||
!dev->hw_ops.get_image_window ||
|
||||
!dev->hw_ops.get_line_length ||
|
||||
!dev->hw_ops.getfid)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ccdc_lock);
|
||||
if (!ccdc_cfg) {
|
||||
|
@ -229,6 +229,9 @@ static int mtk_mdp_remove(struct platform_device *pdev)
|
||||
mtk_mdp_unregister_m2m_device(mdp);
|
||||
v4l2_device_unregister(&mdp->v4l2_dev);
|
||||
|
||||
flush_workqueue(mdp->wdt_wq);
|
||||
destroy_workqueue(mdp->wdt_wq);
|
||||
|
||||
flush_workqueue(mdp->job_wq);
|
||||
destroy_workqueue(mdp->job_wq);
|
||||
|
||||
|
@ -104,6 +104,7 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
{
|
||||
struct vdec_fb *disp_frame_buffer = NULL;
|
||||
struct mtk_video_dec_buf *dstbuf;
|
||||
struct vb2_v4l2_buffer *vb;
|
||||
|
||||
mtk_v4l2_debug(3, "[%d]", ctx->id);
|
||||
if (vdec_if_get_param(ctx,
|
||||
@ -121,25 +122,26 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
|
||||
dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf,
|
||||
frame_buffer);
|
||||
vb = &dstbuf->m2m_buf.vb;
|
||||
mutex_lock(&ctx->lock);
|
||||
if (dstbuf->used) {
|
||||
vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0,
|
||||
vb2_set_plane_payload(&vb->vb2_buf, 0,
|
||||
ctx->picinfo.fb_sz[0]);
|
||||
if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
|
||||
vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1,
|
||||
vb2_set_plane_payload(&vb->vb2_buf, 1,
|
||||
ctx->picinfo.fb_sz[1]);
|
||||
|
||||
mtk_v4l2_debug(2,
|
||||
"[%d]status=%x queue id=%d to done_list %d",
|
||||
ctx->id, disp_frame_buffer->status,
|
||||
dstbuf->vb.vb2_buf.index,
|
||||
vb->vb2_buf.index,
|
||||
dstbuf->queued_in_vb2);
|
||||
|
||||
v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
|
||||
v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
|
||||
ctx->decoded_frame_cnt++;
|
||||
}
|
||||
mutex_unlock(&ctx->lock);
|
||||
return &dstbuf->vb.vb2_buf;
|
||||
return &vb->vb2_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -154,6 +156,7 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
{
|
||||
struct mtk_video_dec_buf *dstbuf;
|
||||
struct vdec_fb *free_frame_buffer = NULL;
|
||||
struct vb2_v4l2_buffer *vb;
|
||||
|
||||
if (vdec_if_get_param(ctx,
|
||||
GET_PARAM_FREE_FRAME_BUFFER,
|
||||
@ -171,6 +174,7 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
|
||||
dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf,
|
||||
frame_buffer);
|
||||
vb = &dstbuf->m2m_buf.vb;
|
||||
|
||||
mutex_lock(&ctx->lock);
|
||||
if (dstbuf->used) {
|
||||
@ -187,9 +191,9 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
mtk_v4l2_debug(2,
|
||||
"[%d]status=%x queue id=%d to rdy_queue %d",
|
||||
ctx->id, free_frame_buffer->status,
|
||||
dstbuf->vb.vb2_buf.index,
|
||||
vb->vb2_buf.index,
|
||||
dstbuf->queued_in_vb2);
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
|
||||
} else if ((dstbuf->queued_in_vb2 == false) &&
|
||||
(dstbuf->queued_in_v4l2 == true)) {
|
||||
/*
|
||||
@ -205,8 +209,8 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
mtk_v4l2_debug(2,
|
||||
"[%d]status=%x queue id=%d to rdy_queue",
|
||||
ctx->id, free_frame_buffer->status,
|
||||
dstbuf->vb.vb2_buf.index);
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
|
||||
vb->vb2_buf.index);
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
|
||||
dstbuf->queued_in_vb2 = true;
|
||||
} else {
|
||||
/*
|
||||
@ -219,14 +223,14 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
*/
|
||||
mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d",
|
||||
ctx->id, free_frame_buffer->status,
|
||||
dstbuf->vb.vb2_buf.index,
|
||||
vb->vb2_buf.index,
|
||||
dstbuf->queued_in_vb2,
|
||||
dstbuf->queued_in_v4l2);
|
||||
}
|
||||
dstbuf->used = false;
|
||||
}
|
||||
mutex_unlock(&ctx->lock);
|
||||
return &dstbuf->vb.vb2_buf;
|
||||
return &vb->vb2_buf;
|
||||
}
|
||||
|
||||
static void clean_display_buffer(struct mtk_vcodec_ctx *ctx)
|
||||
@ -365,8 +369,10 @@ static void mtk_vdec_worker(struct work_struct *work)
|
||||
return;
|
||||
}
|
||||
|
||||
src_buf_info = container_of(src_buf, struct mtk_video_dec_buf, vb);
|
||||
dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf, vb);
|
||||
src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
|
||||
m2m_buf.vb);
|
||||
dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf,
|
||||
m2m_buf.vb);
|
||||
|
||||
pfb = &dst_buf_info->frame_buffer;
|
||||
pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
|
||||
@ -397,11 +403,11 @@ static void mtk_vdec_worker(struct work_struct *work)
|
||||
|
||||
vdec_if_decode(ctx, NULL, NULL, &res_chg);
|
||||
clean_display_buffer(ctx);
|
||||
vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 0, 0);
|
||||
vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
|
||||
if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
|
||||
vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 1, 0);
|
||||
vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
|
||||
dst_buf->flags |= V4L2_BUF_FLAG_LAST;
|
||||
v4l2_m2m_buf_done(&dst_buf_info->vb, VB2_BUF_STATE_DONE);
|
||||
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
|
||||
clean_free_buffer(ctx);
|
||||
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
|
||||
return;
|
||||
@ -417,10 +423,8 @@ static void mtk_vdec_worker(struct work_struct *work)
|
||||
}
|
||||
mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
|
||||
ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
|
||||
dst_buf_info->vb.vb2_buf.timestamp
|
||||
= src_buf_info->vb.vb2_buf.timestamp;
|
||||
dst_buf_info->vb.timecode
|
||||
= src_buf_info->vb.timecode;
|
||||
dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
|
||||
dst_buf->timecode = src_buf->timecode;
|
||||
mutex_lock(&ctx->lock);
|
||||
dst_buf_info->used = true;
|
||||
mutex_unlock(&ctx->lock);
|
||||
@ -434,7 +438,7 @@ static void mtk_vdec_worker(struct work_struct *work)
|
||||
ctx->id,
|
||||
src_buf->vb2_buf.index,
|
||||
buf.size,
|
||||
src_buf_info->vb.vb2_buf.timestamp,
|
||||
src_buf->vb2_buf.timestamp,
|
||||
dst_buf->vb2_buf.index,
|
||||
ret, res_chg);
|
||||
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
|
||||
@ -443,14 +447,14 @@ static void mtk_vdec_worker(struct work_struct *work)
|
||||
src_buf_info->error = true;
|
||||
mutex_unlock(&ctx->lock);
|
||||
}
|
||||
v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
|
||||
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
|
||||
} else if (res_chg == false) {
|
||||
/*
|
||||
* we only return src buffer with VB2_BUF_STATE_DONE
|
||||
* when decode success without resolution change
|
||||
*/
|
||||
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
|
||||
v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
|
||||
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
|
||||
}
|
||||
|
||||
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
|
||||
@ -522,7 +526,8 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
|
||||
mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
|
||||
return 0;
|
||||
}
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx,
|
||||
&ctx->empty_flush_buf->m2m_buf.vb);
|
||||
v4l2_m2m_try_schedule(ctx->m2m_ctx);
|
||||
break;
|
||||
|
||||
@ -1148,7 +1153,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
|
||||
*/
|
||||
if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
vb2_v4l2 = to_vb2_v4l2_buffer(vb);
|
||||
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
|
||||
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
|
||||
m2m_buf.vb);
|
||||
mutex_lock(&ctx->lock);
|
||||
if (buf->used == false) {
|
||||
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
|
||||
@ -1175,7 +1181,7 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
|
||||
mtk_v4l2_err("No src buffer");
|
||||
return;
|
||||
}
|
||||
buf = container_of(src_buf, struct mtk_video_dec_buf, vb);
|
||||
buf = container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
|
||||
if (buf->lastframe) {
|
||||
/* This shouldn't happen. Just in case. */
|
||||
mtk_v4l2_err("Invalid flush buffer.");
|
||||
@ -1256,7 +1262,7 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
|
||||
bool buf_error;
|
||||
|
||||
vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
|
||||
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
|
||||
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
|
||||
mutex_lock(&ctx->lock);
|
||||
if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
buf->queued_in_v4l2 = false;
|
||||
@ -1276,7 +1282,7 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
|
||||
struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
|
||||
struct vb2_v4l2_buffer, vb2_buf);
|
||||
struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
|
||||
struct mtk_video_dec_buf, vb);
|
||||
struct mtk_video_dec_buf, m2m_buf.vb);
|
||||
|
||||
if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
buf->used = false;
|
||||
@ -1309,7 +1315,7 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
|
||||
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||
while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
|
||||
struct mtk_video_dec_buf *buf_info = container_of(
|
||||
src_buf, struct mtk_video_dec_buf, vb);
|
||||
src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
|
||||
if (!buf_info->lastframe)
|
||||
v4l2_m2m_buf_done(src_buf,
|
||||
VB2_BUF_STATE_ERROR);
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define _MTK_VCODEC_DEC_H_
|
||||
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/videobuf2-v4l2.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
|
||||
#define VCODEC_CAPABILITY_4K_DISABLED 0x10
|
||||
#define VCODEC_DEC_4K_CODED_WIDTH 4096U
|
||||
@ -33,7 +33,7 @@ struct vdec_fb {
|
||||
|
||||
/**
|
||||
* struct mtk_video_dec_buf - Private data related to each VB2 buffer.
|
||||
* @b: VB2 buffer
|
||||
* @m2m_buf: M2M buffer
|
||||
* @list: link list
|
||||
* @used: Capture buffer contain decoded frame data and keep in
|
||||
* codec data structure
|
||||
@ -47,8 +47,7 @@ struct vdec_fb {
|
||||
* Note : These status information help us track and debug buffer state
|
||||
*/
|
||||
struct mtk_video_dec_buf {
|
||||
struct vb2_v4l2_buffer vb;
|
||||
struct list_head list;
|
||||
struct v4l2_m2m_buffer m2m_buf;
|
||||
|
||||
bool used;
|
||||
bool queued_in_vb2;
|
||||
|
@ -137,7 +137,7 @@ static int fops_vcodec_open(struct file *file)
|
||||
}
|
||||
src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
|
||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
||||
ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
|
||||
ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq;
|
||||
ctx->empty_flush_buf->lastframe = true;
|
||||
mtk_vcodec_dec_set_default_params(ctx);
|
||||
|
||||
|
@ -332,14 +332,12 @@ static int vidioc_try_fmt(struct v4l2_format *f,
|
||||
|
||||
pix_fmt_mp->num_planes = fmt->num_planes;
|
||||
pix_fmt_mp->plane_fmt[0].sizeimage =
|
||||
pix_fmt_mp->width * pix_fmt_mp->height +
|
||||
((ALIGN(pix_fmt_mp->width, 16) * 2) * 16);
|
||||
pix_fmt_mp->width * pix_fmt_mp->height;
|
||||
pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
|
||||
|
||||
if (pix_fmt_mp->num_planes == 2) {
|
||||
pix_fmt_mp->plane_fmt[1].sizeimage =
|
||||
(pix_fmt_mp->width * pix_fmt_mp->height) / 2 +
|
||||
(ALIGN(pix_fmt_mp->width, 16) * 16);
|
||||
(pix_fmt_mp->width * pix_fmt_mp->height) / 2;
|
||||
pix_fmt_mp->plane_fmt[2].sizeimage = 0;
|
||||
pix_fmt_mp->plane_fmt[1].bytesperline =
|
||||
pix_fmt_mp->width;
|
||||
@ -347,8 +345,7 @@ static int vidioc_try_fmt(struct v4l2_format *f,
|
||||
} else if (pix_fmt_mp->num_planes == 3) {
|
||||
pix_fmt_mp->plane_fmt[1].sizeimage =
|
||||
pix_fmt_mp->plane_fmt[2].sizeimage =
|
||||
(pix_fmt_mp->width * pix_fmt_mp->height) / 4 +
|
||||
((ALIGN(pix_fmt_mp->width, 16) / 2) * 16);
|
||||
(pix_fmt_mp->width * pix_fmt_mp->height) / 4;
|
||||
pix_fmt_mp->plane_fmt[1].bytesperline =
|
||||
pix_fmt_mp->plane_fmt[2].bytesperline =
|
||||
pix_fmt_mp->width / 2;
|
||||
@ -798,13 +795,14 @@ static void vb2ops_venc_buf_queue(struct vb2_buffer *vb)
|
||||
container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
|
||||
|
||||
struct mtk_video_enc_buf *mtk_buf =
|
||||
container_of(vb2_v4l2, struct mtk_video_enc_buf, vb);
|
||||
container_of(vb2_v4l2, struct mtk_video_enc_buf,
|
||||
m2m_buf.vb);
|
||||
|
||||
if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
|
||||
(ctx->param_change != MTK_ENCODE_PARAM_NONE)) {
|
||||
mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
|
||||
ctx->id,
|
||||
mtk_buf->vb.vb2_buf.index,
|
||||
vb2_v4l2->vb2_buf.index,
|
||||
ctx->param_change);
|
||||
mtk_buf->param_change = ctx->param_change;
|
||||
mtk_buf->enc_params = ctx->enc_params;
|
||||
@ -986,7 +984,8 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
|
||||
struct venc_enc_param enc_prm;
|
||||
struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
|
||||
struct mtk_video_enc_buf *mtk_buf =
|
||||
container_of(vb2_v4l2, struct mtk_video_enc_buf, vb);
|
||||
container_of(vb2_v4l2, struct mtk_video_enc_buf,
|
||||
m2m_buf.vb);
|
||||
|
||||
int ret = 0;
|
||||
|
||||
@ -998,7 +997,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
|
||||
enc_prm.bitrate = mtk_buf->enc_params.bitrate;
|
||||
mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
|
||||
ctx->id,
|
||||
mtk_buf->vb.vb2_buf.index,
|
||||
vb2_v4l2->vb2_buf.index,
|
||||
enc_prm.bitrate);
|
||||
ret |= venc_if_set_param(ctx,
|
||||
VENC_SET_PARAM_ADJUST_BITRATE,
|
||||
@ -1009,7 +1008,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
|
||||
mtk_buf->enc_params.framerate_denom;
|
||||
mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
|
||||
ctx->id,
|
||||
mtk_buf->vb.vb2_buf.index,
|
||||
vb2_v4l2->vb2_buf.index,
|
||||
enc_prm.frm_rate);
|
||||
ret |= venc_if_set_param(ctx,
|
||||
VENC_SET_PARAM_ADJUST_FRAMERATE,
|
||||
@ -1026,7 +1025,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
|
||||
if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) {
|
||||
mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
|
||||
ctx->id,
|
||||
mtk_buf->vb.vb2_buf.index,
|
||||
vb2_v4l2->vb2_buf.index,
|
||||
mtk_buf->enc_params.force_intra);
|
||||
if (mtk_buf->enc_params.force_intra)
|
||||
ret |= venc_if_set_param(ctx,
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define _MTK_VCODEC_ENC_H_
|
||||
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/videobuf2-v4l2.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
|
||||
#define MTK_VENC_IRQ_STATUS_SPS 0x1
|
||||
#define MTK_VENC_IRQ_STATUS_PPS 0x2
|
||||
@ -23,15 +23,15 @@
|
||||
|
||||
/**
|
||||
* struct mtk_video_enc_buf - Private data related to each VB2 buffer.
|
||||
* @vb: Pointer to related VB2 buffer.
|
||||
* @m2m_buf: M2M buffer
|
||||
* @list: list that buffer link to
|
||||
* @param_change: Types of encode parameter change before encoding this
|
||||
* buffer
|
||||
* @enc_params: Encode parameters changed before encode this buffer
|
||||
*/
|
||||
struct mtk_video_enc_buf {
|
||||
struct vb2_v4l2_buffer vb;
|
||||
struct list_head list;
|
||||
struct v4l2_m2m_buffer m2m_buf;
|
||||
|
||||
u32 param_change;
|
||||
struct mtk_enc_params enc_params;
|
||||
};
|
||||
|
@ -810,6 +810,10 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
|
||||
|
||||
ret = v4l2_subdev_call(subdev, video, s_stream, 0);
|
||||
|
||||
/* Stop at the first external sub-device. */
|
||||
if (subdev->dev != isp->dev)
|
||||
break;
|
||||
|
||||
if (subdev == &isp->isp_res.subdev)
|
||||
ret |= isp_pipeline_wait(isp, isp_pipeline_wait_resizer);
|
||||
else if (subdev == &isp->isp_prev.subdev)
|
||||
@ -837,10 +841,6 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
|
||||
&subdev->entity);
|
||||
failure = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Stop at the first external sub-device. */
|
||||
if (subdev->dev != isp->dev)
|
||||
break;
|
||||
}
|
||||
|
||||
return failure;
|
||||
|
@ -1607,6 +1607,11 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't restart CCDC if we're just about to stop streaming. */
|
||||
if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
|
||||
ccdc->stopping & CCDC_STOP_REQUEST)
|
||||
return 0;
|
||||
|
||||
if (!ccdc_has_all_fields(ccdc))
|
||||
return 1;
|
||||
|
||||
@ -1661,16 +1666,15 @@ static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
|
||||
spin_unlock_irqrestore(&ccdc->lock, flags);
|
||||
}
|
||||
|
||||
if (ccdc->output & CCDC_OUTPUT_MEMORY)
|
||||
restart = ccdc_isr_buffer(ccdc);
|
||||
|
||||
spin_lock_irqsave(&ccdc->lock, flags);
|
||||
|
||||
if (ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
|
||||
spin_unlock_irqrestore(&ccdc->lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ccdc->output & CCDC_OUTPUT_MEMORY)
|
||||
restart = ccdc_isr_buffer(ccdc);
|
||||
|
||||
if (!ccdc->shadow_update)
|
||||
ccdc_apply_controls(ccdc);
|
||||
spin_unlock_irqrestore(&ccdc->lock, flags);
|
||||
|
@ -2530,6 +2530,7 @@ exit_free_v4l2dev:
|
||||
v4l2_device_unregister(&pcdev->v4l2_dev);
|
||||
exit_deactivate:
|
||||
pxa_camera_deactivate(pcdev);
|
||||
tasklet_kill(&pcdev->task_eof);
|
||||
exit_free_dma:
|
||||
dma_release_channel(pcdev->dma_chans[2]);
|
||||
exit_free_dma_u:
|
||||
@ -2544,6 +2545,7 @@ static int pxa_camera_remove(struct platform_device *pdev)
|
||||
struct pxa_camera_dev *pcdev = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
pxa_camera_deactivate(pcdev);
|
||||
tasklet_kill(&pcdev->task_eof);
|
||||
dma_release_channel(pcdev->dma_chans[0]);
|
||||
dma_release_channel(pcdev->dma_chans[1]);
|
||||
dma_release_channel(pcdev->dma_chans[2]);
|
||||
|
@ -144,7 +144,7 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
|
||||
}
|
||||
|
||||
/* HW limit width to a multiple of 32 (2^5) for NV12/16 else 2 (2^1) */
|
||||
switch (vin->format.pixelformat) {
|
||||
switch (pix->pixelformat) {
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
case V4L2_PIX_FMT_NV16:
|
||||
walign = 5;
|
||||
|
@ -14,8 +14,8 @@
|
||||
#define MAX_SRC_WIDTH 2048
|
||||
|
||||
/* Reset & boot poll config */
|
||||
#define POLL_RST_MAX 50
|
||||
#define POLL_RST_DELAY_MS 20
|
||||
#define POLL_RST_MAX 500
|
||||
#define POLL_RST_DELAY_MS 2
|
||||
|
||||
enum bdisp_target_plan {
|
||||
BDISP_RGB,
|
||||
@ -382,7 +382,7 @@ int bdisp_hw_reset(struct bdisp_dev *bdisp)
|
||||
for (i = 0; i < POLL_RST_MAX; i++) {
|
||||
if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE)
|
||||
break;
|
||||
msleep(POLL_RST_DELAY_MS);
|
||||
udelay(POLL_RST_DELAY_MS * 1000);
|
||||
}
|
||||
if (i == POLL_RST_MAX)
|
||||
dev_err(bdisp->dev, "Reset timeout\n");
|
||||
|
@ -1274,6 +1274,8 @@ static int bdisp_remove(struct platform_device *pdev)
|
||||
if (!IS_ERR(bdisp->clock))
|
||||
clk_unprepare(bdisp->clock);
|
||||
|
||||
destroy_workqueue(bdisp->work_queue);
|
||||
|
||||
dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
|
||||
|
||||
return 0;
|
||||
@ -1317,20 +1319,22 @@ static int bdisp_probe(struct platform_device *pdev)
|
||||
bdisp->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(bdisp->regs)) {
|
||||
dev_err(dev, "failed to get regs\n");
|
||||
return PTR_ERR(bdisp->regs);
|
||||
ret = PTR_ERR(bdisp->regs);
|
||||
goto err_wq;
|
||||
}
|
||||
|
||||
bdisp->clock = devm_clk_get(dev, BDISP_NAME);
|
||||
if (IS_ERR(bdisp->clock)) {
|
||||
dev_err(dev, "failed to get clock\n");
|
||||
return PTR_ERR(bdisp->clock);
|
||||
ret = PTR_ERR(bdisp->clock);
|
||||
goto err_wq;
|
||||
}
|
||||
|
||||
ret = clk_prepare(bdisp->clock);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "clock prepare failed\n");
|
||||
bdisp->clock = ERR_PTR(-EINVAL);
|
||||
return ret;
|
||||
goto err_wq;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
@ -1402,7 +1406,8 @@ err_v4l2:
|
||||
err_clk:
|
||||
if (!IS_ERR(bdisp->clock))
|
||||
clk_unprepare(bdisp->clock);
|
||||
|
||||
err_wq:
|
||||
destroy_workqueue(bdisp->work_queue);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -170,8 +170,9 @@ int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
|
||||
|
||||
/* attach tuner */
|
||||
request_module("tda18212");
|
||||
client = i2c_new_device(tsin->i2c_adapter, &tda18212_info);
|
||||
if (!client || !client->dev.driver) {
|
||||
client = i2c_new_client_device(tsin->i2c_adapter,
|
||||
&tda18212_info);
|
||||
if (!i2c_client_has_driver(client)) {
|
||||
dvb_frontend_detach(*fe);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@ -28,6 +29,12 @@
|
||||
|
||||
#include "sun4i_csi.h"
|
||||
|
||||
struct sun4i_csi_traits {
|
||||
unsigned int channels;
|
||||
unsigned int max_width;
|
||||
bool has_isp;
|
||||
};
|
||||
|
||||
static const struct media_entity_operations sun4i_csi_video_entity_ops = {
|
||||
.link_validate = v4l2_subdev_link_validate,
|
||||
};
|
||||
@ -155,6 +162,31 @@ static int sun4i_csi_probe(struct platform_device *pdev)
|
||||
subdev = &csi->subdev;
|
||||
vdev = &csi->vdev;
|
||||
|
||||
csi->traits = of_device_get_match_data(&pdev->dev);
|
||||
if (!csi->traits)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* On Allwinner SoCs, some high memory bandwidth devices do DMA
|
||||
* directly over the memory bus (called MBUS), instead of the
|
||||
* system bus. The memory bus has a different addressing scheme
|
||||
* without the DRAM starting offset.
|
||||
*
|
||||
* In some cases this can be described by an interconnect in
|
||||
* the device tree. In other cases where the hardware is not
|
||||
* fully understood and the interconnect is left out of the
|
||||
* device tree, fall back to a default offset.
|
||||
*/
|
||||
if (of_find_property(csi->dev->of_node, "interconnects", NULL)) {
|
||||
ret = of_dma_configure(csi->dev, csi->dev->of_node, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
#ifdef PHYS_PFN_OFFSET
|
||||
csi->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
|
||||
#endif
|
||||
}
|
||||
|
||||
csi->mdev.dev = csi->dev;
|
||||
strscpy(csi->mdev.model, "Allwinner Video Capture Device",
|
||||
sizeof(csi->mdev.model));
|
||||
@ -177,11 +209,13 @@ static int sun4i_csi_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(csi->bus_clk);
|
||||
}
|
||||
|
||||
if (csi->traits->has_isp) {
|
||||
csi->isp_clk = devm_clk_get(&pdev->dev, "isp");
|
||||
if (IS_ERR(csi->isp_clk)) {
|
||||
dev_err(&pdev->dev, "Couldn't get our ISP clock\n");
|
||||
return PTR_ERR(csi->isp_clk);
|
||||
}
|
||||
}
|
||||
|
||||
csi->ram_clk = devm_clk_get(&pdev->dev, "ram");
|
||||
if (IS_ERR(csi->ram_clk)) {
|
||||
@ -258,8 +292,21 @@ static int sun4i_csi_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sun4i_csi_traits sun4i_a10_csi1_traits = {
|
||||
.channels = 1,
|
||||
.max_width = 24,
|
||||
.has_isp = false,
|
||||
};
|
||||
|
||||
static const struct sun4i_csi_traits sun7i_a20_csi0_traits = {
|
||||
.channels = 4,
|
||||
.max_width = 16,
|
||||
.has_isp = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id sun4i_csi_of_match[] = {
|
||||
{ .compatible = "allwinner,sun7i-a20-csi0" },
|
||||
{ .compatible = "allwinner,sun4i-a10-csi1", .data = &sun4i_a10_csi1_traits },
|
||||
{ .compatible = "allwinner,sun7i-a20-csi0", .data = &sun7i_a20_csi0_traits },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_csi_of_match);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user