media updates for v5.15-rc1
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmEvK4gACgkQCF8+vY7k 4RUn3Q//YocYb+1s6K+nX2LFFGv5wKgMuqcjJbnuex43/z1dQ+B3T5/RiMmndOvw xZwcCQJFI0c42kfDapdCunfICgYDzqncnUZ5V7pO3efeeuN3j6t3EAMxQKD0gR5A RmFHe/aJpkRANoEWiA4vFKDNWy1cmi6zQDQ8njK1LUb4euwqxrH5mMJSSpObZU/p 4/mV5no2CjhvE3k/JPGqh6zJ8WZtptbcf8E6e9fwTsS91nIfbO1/FqudeOleS3fU 4BYv7zjx/fQsNHpkJZoNNTlZcZGzA1QcWHne4cem+5yudJO2AgRHKC0LnEyhfn19 Q8xw23yB9TP2/mq0QAjc4r6XfJJd18UGp/rI9LP2K6+YjAqX067+TVIfQXswpcui oLDWwGXKtOT7tA5Mrk9XeocpQ6yMUJlCg/JUfpTwJDSaJdEFgAfxVSCsJLLoBT3/ I8AkfcvBeybwUXgZDaYpDdeE2CBWXvYzdXGzWkiQlZ/jIC35cjRcfWjoUvXIAw8K QRDT71VAR67HwufmjkayyDCB0szx+u3xskPdoIAsbtoZCfzgzF+14Z+dAPGQ5YF1 /+UdiNF5lTRMlTR6Xlz5Zckfix0NV002FeHorSoHD/E9jlLwvd3s+sv/1XSzFBQN 9Be5hsEJZpE7uuygLzZ09yj4g0wHlWPTkcOuOTyrH+y0IFU5PI4= =PQpb -----END PGP SIGNATURE----- Merge tag 'media/v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - new sensor drivers: imx335, imx412, ov9282 - new IR transmitter driver: meson-ir-tx - handro driver gained support for H.264 for Rockchip VDPU2 - imx gained support for i.MX8MQ - ti-vpe has gained support for other SoC variants - lots of cleanups, fixes, board additions and doc improvements * tag 'media/v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (195 commits) media: venus: venc: add support for V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM control media: venus: venc: Add support for intra-refresh period media: v4l2-ctrls: Add intra-refresh period control media: docs: ext-ctrls-codec: Document cyclic intra-refresh zero control value media: venus: helper: do not set constrained parameters for UBWC media: venus: venc: Fix potential null pointer dereference on pointer fmt media: venus: hfi: fix return value check in sys_get_prop_image_version() media: tegra-cec: Handle errors of clk_prepare_enable() media: cec-pin: rename timer overrun variables media: TDA1997x: report -ENOLINK after disconnecting HDMI source media: TDA1997x: fix tda1997x_query_dv_timings() return value media: Fix cosmetic error in TDA1997x driver media: v4l2-dv-timings.c: fix wrong condition in two for-loops media: imx: add a driver for i.MX8MQ mipi csi rx phy and controller media: dt-bindings: media: document the nxp,imx8mq-mipi-csi2 receiver phy and controller media: imx: imx7_mipi_csis: convert some switch cases to the default media: imx: imx7-media-csi: Fix buffer return upon stream start failure media: imx: imx7-media-csi: Don't set PIXEL_BIT in CSICR1 media: imx: imx7-media-csi: Set TWO_8BIT_SENSOR for >= 10-bit formats media: dt-bindings: media: nxp,imx7-csi: Add i.MX8MM support ...
This commit is contained in:
commit
835d31d319
@ -0,0 +1,60 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: "http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#"
|
||||||
|
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||||
|
|
||||||
|
title: Amlogic Meson IR transmitter
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Viktor Prutyanov <viktor.prutyanov@phystech.edu>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Some Amlogic SoCs such as A311D and T950D4 have IR transmitter
|
||||||
|
(also called blaster) controller onboard. It is capable of
|
||||||
|
sending IR signals with arbitrary carrier frequency and duty cycle.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
oneOf:
|
||||||
|
- const: amlogic,meson-ir-tx
|
||||||
|
- items:
|
||||||
|
- const: amlogic,meson-g12a-ir-tx
|
||||||
|
- const: amlogic,meson-ir-tx
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: sysclk
|
||||||
|
- const: xtal
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- interrupts
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/clock/g12a-clkc.h>
|
||||||
|
|
||||||
|
ir@ff80014c {
|
||||||
|
compatible = "amlogic,meson-g12a-ir-tx", "amlogic,meson-ir-tx";
|
||||||
|
reg = <0xff80014c 0x10>;
|
||||||
|
interrupts = <0 198 IRQ_TYPE_EDGE_RISING>;
|
||||||
|
clocks = <&clkc CLKID_CLK81>, <&xtal>;
|
||||||
|
clock-names = "sysclk", "xtal";
|
||||||
|
};
|
@ -35,6 +35,14 @@ properties:
|
|||||||
powerdown-gpios:
|
powerdown-gpios:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
|
||||||
|
reset-gpios:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
adv,force-bt656-4:
|
||||||
|
description:
|
||||||
|
Indicates that the output is a BT.656-4 compatible stream.
|
||||||
|
type: boolean
|
||||||
|
|
||||||
port:
|
port:
|
||||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||||
unevaluatedProperties: false
|
unevaluatedProperties: false
|
||||||
|
91
Documentation/devicetree/bindings/media/i2c/ovti,ov9282.yaml
Normal file
91
Documentation/devicetree/bindings/media/i2c/ovti,ov9282.yaml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
# Copyright (C) 2021 Intel Corporation
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/media/i2c/ovti,ov9282.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: OmniVision OV9282 Sensor
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Paul J. Murphy <paul.j.murphy@intel.com>
|
||||||
|
- Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||||
|
|
||||||
|
description:
|
||||||
|
OV9282 sensor is an OmniVision black & white CMOS active pixel digital image
|
||||||
|
sensor with an active array size of 1296H x 816V. It is programmable through
|
||||||
|
I2C interface. The I2C client address is fixed to 0x60/0x70 as per sensor data
|
||||||
|
sheet. Image data is sent through MIPI CSI-2.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: ovti,ov9282
|
||||||
|
reg:
|
||||||
|
description: I2C address
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
assigned-clocks: true
|
||||||
|
assigned-clock-parents: true
|
||||||
|
assigned-clock-rates: true
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
description: Clock frequency from 6 to 27MHz
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
reset-gpios:
|
||||||
|
description: Reference to the GPIO connected to the XCLR pin, if any.
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
port:
|
||||||
|
additionalProperties: false
|
||||||
|
$ref: /schemas/graph.yaml#/properties/port
|
||||||
|
|
||||||
|
properties:
|
||||||
|
endpoint:
|
||||||
|
$ref: /schemas/media/video-interfaces.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
properties:
|
||||||
|
data-lanes: true
|
||||||
|
link-frequencies: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- data-lanes
|
||||||
|
- link-frequencies
|
||||||
|
|
||||||
|
required:
|
||||||
|
- endpoint
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- clocks
|
||||||
|
- port
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
i2c0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
camera@60 {
|
||||||
|
compatible = "ovti,ov9282";
|
||||||
|
reg = <0x60>;
|
||||||
|
clocks = <&ov9282_clk>;
|
||||||
|
|
||||||
|
assigned-clocks = <&ov9282_clk>;
|
||||||
|
assigned-clock-parents = <&ov9282_clk_parent>;
|
||||||
|
assigned-clock-rates = <24000000>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
ov9282: endpoint {
|
||||||
|
remote-endpoint = <&cam>;
|
||||||
|
data-lanes = <1 2>;
|
||||||
|
link-frequencies = /bits/ 64 <800000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
...
|
91
Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
Normal file
91
Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
# Copyright (C) 2021 Intel Corporation
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/media/i2c/sony,imx335.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Sony IMX335 Sensor
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Paul J. Murphy <paul.j.murphy@intel.com>
|
||||||
|
- Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||||
|
|
||||||
|
description:
|
||||||
|
IMX335 sensor is a Sony CMOS active pixel digital image sensor with an active
|
||||||
|
array size of 2592H x 1944V. It is programmable through I2C interface. The
|
||||||
|
I2C client address is fixed to 0x1a as per sensor data sheet. Image data is
|
||||||
|
sent through MIPI CSI-2.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: sony,imx335
|
||||||
|
reg:
|
||||||
|
description: I2C address
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
assigned-clocks: true
|
||||||
|
assigned-clock-parents: true
|
||||||
|
assigned-clock-rates: true
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
description: Clock frequency from 6 to 27 MHz, 37.125MHz, 74.25MHz
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
reset-gpios:
|
||||||
|
description: Reference to the GPIO connected to the XCLR pin, if any.
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
port:
|
||||||
|
additionalProperties: false
|
||||||
|
$ref: /schemas/graph.yaml#/properties/port
|
||||||
|
|
||||||
|
properties:
|
||||||
|
endpoint:
|
||||||
|
$ref: /schemas/media/video-interfaces.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
properties:
|
||||||
|
data-lanes: true
|
||||||
|
link-frequencies: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- data-lanes
|
||||||
|
- link-frequencies
|
||||||
|
|
||||||
|
required:
|
||||||
|
- endpoint
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- clocks
|
||||||
|
- port
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
i2c0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
camera@1a {
|
||||||
|
compatible = "sony,imx335";
|
||||||
|
reg = <0x1a>;
|
||||||
|
clocks = <&imx335_clk>;
|
||||||
|
|
||||||
|
assigned-clocks = <&imx335_clk>;
|
||||||
|
assigned-clock-parents = <&imx335_clk_parent>;
|
||||||
|
assigned-clock-rates = <24000000>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
imx335: endpoint {
|
||||||
|
remote-endpoint = <&cam>;
|
||||||
|
data-lanes = <1 2 3 4>;
|
||||||
|
link-frequencies = /bits/ 64 <594000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
...
|
91
Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
Normal file
91
Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
# Copyright (C) 2021 Intel Corporation
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/media/i2c/sony,imx412.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Sony IMX412 Sensor
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Paul J. Murphy <paul.j.murphy@intel.com>
|
||||||
|
- Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||||
|
|
||||||
|
description:
|
||||||
|
IMX412 sensor is a Sony CMOS active pixel digital image sensor with an active
|
||||||
|
array size of 4072H x 3176V. It is programmable through I2C interface. The
|
||||||
|
I2C client address is fixed to 0x1a as per sensor data sheet. Image data is
|
||||||
|
sent through MIPI CSI-2.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: sony,imx412
|
||||||
|
reg:
|
||||||
|
description: I2C address
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
assigned-clocks: true
|
||||||
|
assigned-clock-parents: true
|
||||||
|
assigned-clock-rates: true
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
description: Clock frequency 6MHz, 12MHz, 18MHz, 24MHz or 27MHz
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
reset-gpios:
|
||||||
|
description: Reference to the GPIO connected to the XCLR pin, if any.
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
port:
|
||||||
|
additionalProperties: false
|
||||||
|
$ref: /schemas/graph.yaml#/properties/port
|
||||||
|
|
||||||
|
properties:
|
||||||
|
endpoint:
|
||||||
|
$ref: /schemas/media/video-interfaces.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
properties:
|
||||||
|
data-lanes: true
|
||||||
|
link-frequencies: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- data-lanes
|
||||||
|
- link-frequencies
|
||||||
|
|
||||||
|
required:
|
||||||
|
- endpoint
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- clocks
|
||||||
|
- port
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
i2c0 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
camera@1a {
|
||||||
|
compatible = "sony,imx412";
|
||||||
|
reg = <0x1a>;
|
||||||
|
clocks = <&imx412_clk>;
|
||||||
|
|
||||||
|
assigned-clocks = <&imx412_clk>;
|
||||||
|
assigned-clock-parents = <&imx412_clk_parent>;
|
||||||
|
assigned-clock-rates = <24000000>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
imx412: endpoint {
|
||||||
|
remote-endpoint = <&cam>;
|
||||||
|
data-lanes = <1 2 3 4>;
|
||||||
|
link-frequencies = /bits/ 64 <600000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
...
|
@ -4,7 +4,7 @@
|
|||||||
$id: http://devicetree.org/schemas/media/nxp,imx7-csi.yaml#
|
$id: http://devicetree.org/schemas/media/nxp,imx7-csi.yaml#
|
||||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
title: i.MX7 CMOS Sensor Interface
|
title: i.MX7 and i.MX8 CSI bridge (CMOS Sensor Interface)
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Rui Miguel Silva <rmfrfs@gmail.com>
|
- Rui Miguel Silva <rmfrfs@gmail.com>
|
||||||
@ -15,9 +15,13 @@ description: |
|
|||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
enum:
|
oneOf:
|
||||||
- fsl,imx7-csi
|
- enum:
|
||||||
- fsl,imx6ul-csi
|
- fsl,imx7-csi
|
||||||
|
- fsl,imx6ul-csi
|
||||||
|
- items:
|
||||||
|
- const: fsl,imx8mm-csi
|
||||||
|
- const: fsl,imx7-csi
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
@ -0,0 +1,174 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/media/nxp,imx8mq-mipi-csi2.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: NXP i.MX8MQ MIPI CSI-2 receiver
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Martin Kepplinger <martin.kepplinger@puri.sm>
|
||||||
|
|
||||||
|
description: |-
|
||||||
|
This binding covers the CSI-2 RX PHY and host controller included in the
|
||||||
|
NXP i.MX8MQ SoC. It handles the sensor/image input and process for all the
|
||||||
|
input imaging devices.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- fsl,imx8mq-mipi-csi2
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: core is the RX Controller Core Clock input. This clock
|
||||||
|
must be exactly equal to or faster than the receive
|
||||||
|
byteclock from the RX DPHY.
|
||||||
|
- description: esc is the Rx Escape Clock. This must be the same escape
|
||||||
|
clock that the RX DPHY receives.
|
||||||
|
- description: ui is the pixel clock (phy_ref up to 333Mhz).
|
||||||
|
See the reference manual for details.
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: core
|
||||||
|
- const: esc
|
||||||
|
- const: ui
|
||||||
|
|
||||||
|
power-domains:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
resets:
|
||||||
|
items:
|
||||||
|
- description: CORE_RESET reset register bit definition
|
||||||
|
- description: PHY_REF_RESET reset register bit definition
|
||||||
|
- description: ESC_RESET reset register bit definition
|
||||||
|
|
||||||
|
fsl,mipi-phy-gpr:
|
||||||
|
description: |
|
||||||
|
The phandle to the imx8mq syscon iomux-gpr with the register
|
||||||
|
for setting RX_ENABLE for the mipi receiver.
|
||||||
|
|
||||||
|
The format should be as follows:
|
||||||
|
<gpr req_gpr>
|
||||||
|
gpr is the phandle to general purpose register node.
|
||||||
|
req_gpr is the gpr register offset of RX_ENABLE for the mipi phy.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||||
|
items:
|
||||||
|
items:
|
||||||
|
- description: The 'gpr' is the phandle to general purpose register node.
|
||||||
|
- description: The 'req_gpr' is the gpr register offset containing
|
||||||
|
CSI2_1_RX_ENABLE or CSI2_2_RX_ENABLE respectively.
|
||||||
|
maximum: 0xff
|
||||||
|
|
||||||
|
interconnects:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interconnect-names:
|
||||||
|
const: dram
|
||||||
|
|
||||||
|
ports:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
|
|
||||||
|
properties:
|
||||||
|
port@0:
|
||||||
|
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||||
|
unevaluatedProperties: false
|
||||||
|
description:
|
||||||
|
Input port node, single endpoint describing the CSI-2 transmitter.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
endpoint:
|
||||||
|
$ref: video-interfaces.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
properties:
|
||||||
|
data-lanes:
|
||||||
|
items:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 4
|
||||||
|
items:
|
||||||
|
- const: 1
|
||||||
|
- const: 2
|
||||||
|
- const: 3
|
||||||
|
- const: 4
|
||||||
|
|
||||||
|
required:
|
||||||
|
- data-lanes
|
||||||
|
|
||||||
|
port@1:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/port
|
||||||
|
description:
|
||||||
|
Output port node
|
||||||
|
|
||||||
|
required:
|
||||||
|
- port@0
|
||||||
|
- port@1
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
- power-domains
|
||||||
|
- resets
|
||||||
|
- fsl,mipi-phy-gpr
|
||||||
|
- ports
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/imx8mq-clock.h>
|
||||||
|
#include <dt-bindings/interconnect/imx8mq.h>
|
||||||
|
#include <dt-bindings/reset/imx8mq-reset.h>
|
||||||
|
|
||||||
|
csi@30a70000 {
|
||||||
|
compatible = "fsl,imx8mq-mipi-csi2";
|
||||||
|
reg = <0x30a70000 0x1000>;
|
||||||
|
clocks = <&clk IMX8MQ_CLK_CSI1_CORE>,
|
||||||
|
<&clk IMX8MQ_CLK_CSI1_ESC>,
|
||||||
|
<&clk IMX8MQ_CLK_CSI1_PHY_REF>;
|
||||||
|
clock-names = "core", "esc", "ui";
|
||||||
|
assigned-clocks = <&clk IMX8MQ_CLK_CSI1_CORE>,
|
||||||
|
<&clk IMX8MQ_CLK_CSI1_PHY_REF>,
|
||||||
|
<&clk IMX8MQ_CLK_CSI1_ESC>;
|
||||||
|
assigned-clock-rates = <266000000>, <200000000>, <66000000>;
|
||||||
|
assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_266M>,
|
||||||
|
<&clk IMX8MQ_SYS2_PLL_1000M>,
|
||||||
|
<&clk IMX8MQ_SYS1_PLL_800M>;
|
||||||
|
power-domains = <&pgc_mipi_csi1>;
|
||||||
|
resets = <&src IMX8MQ_RESET_MIPI_CSI1_CORE_RESET>,
|
||||||
|
<&src IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET>,
|
||||||
|
<&src IMX8MQ_RESET_MIPI_CSI1_ESC_RESET>;
|
||||||
|
fsl,mipi-phy-gpr = <&iomuxc_gpr 0x88>;
|
||||||
|
interconnects = <&noc IMX8MQ_ICM_CSI1 &noc IMX8MQ_ICS_DRAM>;
|
||||||
|
interconnect-names = "dram";
|
||||||
|
|
||||||
|
ports {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
port@0 {
|
||||||
|
reg = <0>;
|
||||||
|
|
||||||
|
imx8mm_mipi_csi_in: endpoint {
|
||||||
|
remote-endpoint = <&imx477_out>;
|
||||||
|
data-lanes = <1 2 3 4>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
port@1 {
|
||||||
|
reg = <1>;
|
||||||
|
|
||||||
|
imx8mm_mipi_csi_out: endpoint {
|
||||||
|
remote-endpoint = <&csi_in>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
@ -22,6 +22,7 @@ properties:
|
|||||||
- rockchip,rk3288-vpu
|
- rockchip,rk3288-vpu
|
||||||
- rockchip,rk3328-vpu
|
- rockchip,rk3328-vpu
|
||||||
- rockchip,rk3399-vpu
|
- rockchip,rk3399-vpu
|
||||||
|
- rockchip,px30-vpu
|
||||||
- items:
|
- items:
|
||||||
- const: rockchip,rk3188-vpu
|
- const: rockchip,rk3188-vpu
|
||||||
- const: rockchip,rk3066-vpu
|
- const: rockchip,rk3066-vpu
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
Writing camera sensor drivers
|
Writing camera sensor drivers
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
CSI-2
|
CSI-2 and parallel (BT.601 and BT.656) busses
|
||||||
-----
|
---------------------------------------------
|
||||||
|
|
||||||
Please see what is written on :ref:`MIPI_CSI_2`.
|
Please see :ref:`transmitter-receiver`.
|
||||||
|
|
||||||
Handling clocks
|
Handling clocks
|
||||||
---------------
|
---------------
|
||||||
@ -26,15 +26,16 @@ user.
|
|||||||
ACPI
|
ACPI
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
Read the "clock-frequency" _DSD property to denote the frequency. The driver can
|
Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
|
||||||
rely on this frequency being used.
|
can rely on this frequency being used.
|
||||||
|
|
||||||
Devicetree
|
Devicetree
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
The currently preferred way to achieve this is using "assigned-clock-rates"
|
The currently preferred way to achieve this is using ``assigned-clocks``,
|
||||||
property. See Documentation/devicetree/bindings/clock/clock-bindings.txt for
|
``assigned-clock-parents`` and ``assigned-clock-rates`` properties. See
|
||||||
more information. The driver then gets the frequency using clk_get_rate().
|
``Documentation/devicetree/bindings/clock/clock-bindings.txt`` for more
|
||||||
|
information. The driver then gets the frequency using ``clk_get_rate()``.
|
||||||
|
|
||||||
This approach has the drawback that there's no guarantee that the frequency
|
This approach has the drawback that there's no guarantee that the frequency
|
||||||
hasn't been modified directly or indirectly by another driver, or supported by
|
hasn't been modified directly or indirectly by another driver, or supported by
|
||||||
@ -55,7 +56,7 @@ processing pipeline as one or more sub-devices with different cropping and
|
|||||||
scaling configurations. The output size of the device is the result of a series
|
scaling configurations. The output size of the device is the result of a series
|
||||||
of cropping and scaling operations from the device's pixel array's size.
|
of cropping and scaling operations from the device's pixel array's size.
|
||||||
|
|
||||||
An example of such a driver is the smiapp driver (see drivers/media/i2c/smiapp).
|
An example of such a driver is the CCS driver (see ``drivers/media/i2c/ccs``).
|
||||||
|
|
||||||
Register list based drivers
|
Register list based drivers
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -67,7 +68,7 @@ level are independent. How a driver picks such configuration is based on the
|
|||||||
format set on a source pad at the end of the device's internal pipeline.
|
format set on a source pad at the end of the device's internal pipeline.
|
||||||
|
|
||||||
Most sensor drivers are implemented this way, see e.g.
|
Most sensor drivers are implemented this way, see e.g.
|
||||||
drivers/media/i2c/imx319.c for an example.
|
``drivers/media/i2c/imx319.c`` for an example.
|
||||||
|
|
||||||
Frame interval configuration
|
Frame interval configuration
|
||||||
----------------------------
|
----------------------------
|
||||||
@ -94,9 +95,10 @@ large variety of devices beyond camera sensors. Devices that have no analogue
|
|||||||
crop, use the full source image size, i.e. pixel array size.
|
crop, use the full source image size, i.e. pixel array size.
|
||||||
|
|
||||||
Horizontal and vertical blanking are specified by ``V4L2_CID_HBLANK`` and
|
Horizontal and vertical blanking are specified by ``V4L2_CID_HBLANK`` and
|
||||||
``V4L2_CID_VBLANK``, respectively. The unit of these controls are lines. The
|
``V4L2_CID_VBLANK``, respectively. The unit of the ``V4L2_CID_HBLANK`` control
|
||||||
pixel rate is specified by ``V4L2_CID_PIXEL_RATE`` in the same sub-device. The
|
is pixels and the unit of the ``V4L2_CID_VBLANK`` is lines. The pixel rate in
|
||||||
unit of that control is Hz.
|
the sensor's **pixel array** is specified by ``V4L2_CID_PIXEL_RATE`` in the same
|
||||||
|
sub-device. The unit of that control is pixels per second.
|
||||||
|
|
||||||
Register list based drivers need to implement read-only sub-device nodes for the
|
Register list based drivers need to implement read-only sub-device nodes for the
|
||||||
purpose. Devices that are not register list based need these to configure the
|
purpose. Devices that are not register list based need these to configure the
|
||||||
@ -125,14 +127,14 @@ general, the device must be powered on at least when its registers are being
|
|||||||
accessed and when it is streaming.
|
accessed and when it is streaming.
|
||||||
|
|
||||||
Existing camera sensor drivers may rely on the old
|
Existing camera sensor drivers may rely on the old
|
||||||
:c:type:`v4l2_subdev_core_ops`->s_power() callback for bridge or ISP drivers to
|
struct v4l2_subdev_core_ops->s_power() callback for bridge or ISP drivers to
|
||||||
manage their power state. This is however **deprecated**. If you feel you need
|
manage their power state. This is however **deprecated**. If you feel you need
|
||||||
to begin calling an s_power from an ISP or a bridge driver, instead please add
|
to begin calling an s_power from an ISP or a bridge driver, instead please add
|
||||||
runtime PM support to the sensor driver you are using. Likewise, new drivers
|
runtime PM support to the sensor driver you are using. Likewise, new drivers
|
||||||
should not use s_power.
|
should not use s_power.
|
||||||
|
|
||||||
Please see examples in e.g. ``drivers/media/i2c/ov8856.c`` and
|
Please see examples in e.g. ``drivers/media/i2c/ov8856.c`` and
|
||||||
``drivers/media/i2c/smiapp/smiapp-core.c``. The two drivers work in both ACPI
|
``drivers/media/i2c/ccs/ccs-core.c``. The two drivers work in both ACPI
|
||||||
and DT based systems.
|
and DT based systems.
|
||||||
|
|
||||||
Control framework
|
Control framework
|
||||||
@ -149,16 +151,3 @@ used to obtain device's power state after the power state transition:
|
|||||||
The function returns a non-zero value if it succeeded getting the power count or
|
The function returns a non-zero value if it succeeded getting the power count or
|
||||||
runtime PM was disabled, in either of which cases the driver may proceed to
|
runtime PM was disabled, in either of which cases the driver may proceed to
|
||||||
access the device.
|
access the device.
|
||||||
|
|
||||||
Controls
|
|
||||||
--------
|
|
||||||
|
|
||||||
For camera sensors that are connected to a bus where transmitter and receiver
|
|
||||||
require common configuration set by drivers, such as CSI-2 or parallel (BT.601
|
|
||||||
or BT.656) bus, the ``V4L2_CID_LINK_FREQ`` control is mandatory on transmitter
|
|
||||||
drivers. Receiver drivers can use the ``V4L2_CID_LINK_FREQ`` to query the
|
|
||||||
frequency used on the bus.
|
|
||||||
|
|
||||||
The transmitter drivers should also implement ``V4L2_CID_PIXEL_RATE`` control in
|
|
||||||
order to tell the maximum pixel rate to the receiver. This is required on raw
|
|
||||||
camera sensors.
|
|
||||||
|
@ -130,9 +130,12 @@ To enable/disable the hardware::
|
|||||||
int (*adap_enable)(struct cec_adapter *adap, bool enable);
|
int (*adap_enable)(struct cec_adapter *adap, bool enable);
|
||||||
|
|
||||||
This callback enables or disables the CEC hardware. Enabling the CEC hardware
|
This callback enables or disables the CEC hardware. Enabling the CEC hardware
|
||||||
means powering it up in a state where no logical addresses are claimed. This
|
means powering it up in a state where no logical addresses are claimed. The
|
||||||
op assumes that the physical address (adap->phys_addr) is valid when enable is
|
physical address will always be valid if CEC_CAP_NEEDS_HPD is set. If that
|
||||||
true and will not change while the CEC adapter remains enabled. The initial
|
capability is not set, then the physical address can change while the CEC
|
||||||
|
hardware is enabled. CEC drivers should not set CEC_CAP_NEEDS_HPD unless
|
||||||
|
the hardware design requires that as this will make it impossible to wake
|
||||||
|
up displays that pull the HPD low when in standby mode. The initial
|
||||||
state of the CEC adapter after calling cec_allocate_adapter() is disabled.
|
state of the CEC adapter after calling cec_allocate_adapter() is disabled.
|
||||||
|
|
||||||
Note that adap_enable must return 0 if enable is false.
|
Note that adap_enable must return 0 if enable is false.
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
.. SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
.. _MIPI_CSI_2:
|
|
||||||
|
|
||||||
MIPI CSI-2
|
|
||||||
==========
|
|
||||||
|
|
||||||
CSI-2 is a data bus intended for transferring images from cameras to
|
|
||||||
the host SoC. It is defined by the `MIPI alliance`_.
|
|
||||||
|
|
||||||
.. _`MIPI alliance`: http://www.mipi.org/
|
|
||||||
|
|
||||||
Media bus formats
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
See :ref:`v4l2-mbus-pixelcode` for details on which media bus formats should
|
|
||||||
be used for CSI-2 interfaces.
|
|
||||||
|
|
||||||
Transmitter drivers
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
CSI-2 transmitter, such as a sensor or a TV tuner, drivers need to
|
|
||||||
provide the CSI-2 receiver with information on the CSI-2 bus
|
|
||||||
configuration. These include the V4L2_CID_LINK_FREQ and
|
|
||||||
V4L2_CID_PIXEL_RATE controls and
|
|
||||||
(:c:type:`v4l2_subdev_video_ops`->s_stream() callback). These
|
|
||||||
interface elements must be present on the sub-device represents the
|
|
||||||
CSI-2 transmitter.
|
|
||||||
|
|
||||||
The V4L2_CID_LINK_FREQ control is used to tell the receiver driver the
|
|
||||||
frequency (and not the symbol rate) of the link. The V4L2_CID_PIXEL_RATE
|
|
||||||
control may be used by the receiver to obtain the pixel rate the transmitter
|
|
||||||
uses. The :c:type:`v4l2_subdev_video_ops`->s_stream() callback provides an
|
|
||||||
ability to start and stop the stream.
|
|
||||||
|
|
||||||
The value of the V4L2_CID_PIXEL_RATE is calculated as follows::
|
|
||||||
|
|
||||||
pixel_rate = link_freq * 2 * nr_of_lanes * 16 / k / bits_per_sample
|
|
||||||
|
|
||||||
where
|
|
||||||
|
|
||||||
.. list-table:: variables in pixel rate calculation
|
|
||||||
:header-rows: 1
|
|
||||||
|
|
||||||
* - variable or constant
|
|
||||||
- description
|
|
||||||
* - link_freq
|
|
||||||
- The value of the V4L2_CID_LINK_FREQ integer64 menu item.
|
|
||||||
* - nr_of_lanes
|
|
||||||
- Number of data lanes used on the CSI-2 link. This can
|
|
||||||
be obtained from the OF endpoint configuration.
|
|
||||||
* - 2
|
|
||||||
- Two bits are transferred per clock cycle per lane.
|
|
||||||
* - bits_per_sample
|
|
||||||
- Number of bits per sample.
|
|
||||||
* - k
|
|
||||||
- 16 for D-PHY and 7 for C-PHY
|
|
||||||
|
|
||||||
The transmitter drivers must, if possible, configure the CSI-2
|
|
||||||
transmitter to *LP-11 mode* whenever the transmitter is powered on but
|
|
||||||
not active, and maintain *LP-11 mode* until stream on. Only at stream
|
|
||||||
on should the transmitter activate the clock on the clock lane and
|
|
||||||
transition to *HS mode*.
|
|
||||||
|
|
||||||
Some transmitters do this automatically but some have to be explicitly
|
|
||||||
programmed to do so, and some are unable to do so altogether due to
|
|
||||||
hardware constraints.
|
|
||||||
|
|
||||||
Stopping the transmitter
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
A transmitter stops sending the stream of images as a result of
|
|
||||||
calling the ``.s_stream()`` callback. Some transmitters may stop the
|
|
||||||
stream at a frame boundary whereas others stop immediately,
|
|
||||||
effectively leaving the current frame unfinished. The receiver driver
|
|
||||||
should not make assumptions either way, but function properly in both
|
|
||||||
cases.
|
|
||||||
|
|
||||||
Receiver drivers
|
|
||||||
----------------
|
|
||||||
|
|
||||||
Before the receiver driver may enable the CSI-2 transmitter by using
|
|
||||||
the :c:type:`v4l2_subdev_video_ops`->s_stream(), it must have powered
|
|
||||||
the transmitter up by using the
|
|
||||||
:c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
|
|
||||||
place either indirectly by using :c:func:`v4l2_pipeline_pm_get` or
|
|
||||||
directly.
|
|
||||||
|
|
||||||
Formats
|
|
||||||
-------
|
|
||||||
|
|
||||||
The media bus pixel codes document parallel formats. Should the pixel data be
|
|
||||||
transported over a serial bus, the media bus pixel code that describes a
|
|
||||||
parallel format that transfers a sample on a single clock cycle is used.
|
|
@ -37,7 +37,7 @@ Documentation/userspace-api/media/index.rst
|
|||||||
rc-core
|
rc-core
|
||||||
mc-core
|
mc-core
|
||||||
cec-core
|
cec-core
|
||||||
csi2
|
tx-rx
|
||||||
camera-sensor
|
camera-sensor
|
||||||
|
|
||||||
drivers/index
|
drivers/index
|
||||||
|
133
Documentation/driver-api/media/tx-rx.rst
Normal file
133
Documentation/driver-api/media/tx-rx.rst
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
.. _transmitter-receiver:
|
||||||
|
|
||||||
|
Pixel data transmitter and receiver drivers
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
V4L2 supports various devices that transmit and receive pixel data. Examples of
|
||||||
|
these devices include a camera sensor, a TV tuner and a parallel or a CSI-2
|
||||||
|
receiver in an SoC.
|
||||||
|
|
||||||
|
Bus types
|
||||||
|
---------
|
||||||
|
|
||||||
|
The following busses are the most common. This section discusses these two only.
|
||||||
|
|
||||||
|
MIPI CSI-2
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
CSI-2 is a data bus intended for transferring images from cameras to
|
||||||
|
the host SoC. It is defined by the `MIPI alliance`_.
|
||||||
|
|
||||||
|
.. _`MIPI alliance`: https://www.mipi.org/
|
||||||
|
|
||||||
|
Parallel
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
`BT.601`_ and `BT.656`_ are the most common parallel busses.
|
||||||
|
|
||||||
|
.. _`BT.601`: https://en.wikipedia.org/wiki/Rec._601
|
||||||
|
.. _`BT.656`: https://en.wikipedia.org/wiki/ITU-R_BT.656
|
||||||
|
|
||||||
|
Transmitter drivers
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Transmitter drivers generally need to provide the receiver drivers with the
|
||||||
|
configuration of the transmitter. What is required depends on the type of the
|
||||||
|
bus. These are common for both busses.
|
||||||
|
|
||||||
|
Media bus pixel code
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
See :ref:`v4l2-mbus-pixelcode`.
|
||||||
|
|
||||||
|
Link frequency
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The :ref:`V4L2_CID_LINK_FREQ <v4l2-cid-link-freq>` control is used to tell the
|
||||||
|
receiver the frequency of the bus (i.e. it is not the same as the symbol rate).
|
||||||
|
|
||||||
|
``.s_stream()`` callback
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The struct struct v4l2_subdev_video_ops->s_stream() callback is used by the
|
||||||
|
receiver driver to control the transmitter driver's streaming state.
|
||||||
|
|
||||||
|
|
||||||
|
CSI-2 transmitter drivers
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Pixel rate
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
The pixel rate on the bus is calculated as follows::
|
||||||
|
|
||||||
|
pixel_rate = link_freq * 2 * nr_of_lanes * 16 / k / bits_per_sample
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
.. list-table:: variables in pixel rate calculation
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - variable or constant
|
||||||
|
- description
|
||||||
|
* - link_freq
|
||||||
|
- The value of the ``V4L2_CID_LINK_FREQ`` integer64 menu item.
|
||||||
|
* - nr_of_lanes
|
||||||
|
- Number of data lanes used on the CSI-2 link. This can
|
||||||
|
be obtained from the OF endpoint configuration.
|
||||||
|
* - 2
|
||||||
|
- Data is transferred on both rising and falling edge of the signal.
|
||||||
|
* - bits_per_sample
|
||||||
|
- Number of bits per sample.
|
||||||
|
* - k
|
||||||
|
- 16 for D-PHY and 7 for C-PHY
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The pixel rate calculated this way is **not** the same thing as the
|
||||||
|
pixel rate on the camera sensor's pixel array which is indicated by the
|
||||||
|
:ref:`V4L2_CID_PIXEL_RATE <v4l2-cid-pixel-rate>` control.
|
||||||
|
|
||||||
|
LP-11 and LP-111 modes
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
As part of transitioning to high speed mode, a CSI-2 transmitter typically
|
||||||
|
briefly sets the bus to LP-11 or LP-111 state, depending on the PHY. This period
|
||||||
|
may be as short as 100 µs, during which the receiver observes this state and
|
||||||
|
proceeds its own part of high speed mode transition.
|
||||||
|
|
||||||
|
Most receivers are capable of autonomously handling this once the software has
|
||||||
|
configured them to do so, but there are receivers which require software
|
||||||
|
involvement in observing LP-11 or LP-111 state. 100 µs is a brief period to hit
|
||||||
|
in software, especially when there is no interrupt telling something is
|
||||||
|
happening.
|
||||||
|
|
||||||
|
One way to address this is to configure the transmitter side explicitly to LP-11
|
||||||
|
or LP-111 mode, which requires support from the transmitter hardware. This is
|
||||||
|
not universally available. Many devices return to this state once streaming is
|
||||||
|
stopped while the state after power-on is LP-00 or LP-000.
|
||||||
|
|
||||||
|
The ``.pre_streamon()`` callback may be used to prepare a transmitter for
|
||||||
|
transitioning to streaming state, but not yet start streaming. Similarly, the
|
||||||
|
``.post_streamoff()`` callback is used to undo what was done by the
|
||||||
|
``.pre_streamon()`` callback. The caller of ``.pre_streamon()`` is thus required
|
||||||
|
to call ``.post_streamoff()`` for each successful call of ``.pre_streamon()``.
|
||||||
|
|
||||||
|
In the context of CSI-2, the ``.pre_streamon()`` callback is used to transition
|
||||||
|
the transmitter to the LP-11 or LP-111 mode. This also requires powering on the
|
||||||
|
device, so this should be only done when it is needed.
|
||||||
|
|
||||||
|
Receiver drivers that do not need explicit LP-11 or LP-111 mode setup are waived
|
||||||
|
from calling the two callbacks.
|
||||||
|
|
||||||
|
Stopping the transmitter
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A transmitter stops sending the stream of images as a result of
|
||||||
|
calling the ``.s_stream()`` callback. Some transmitters may stop the
|
||||||
|
stream at a frame boundary whereas others stop immediately,
|
||||||
|
effectively leaving the current frame unfinished. The receiver driver
|
||||||
|
should not make assumptions either way, but function properly in both
|
||||||
|
cases.
|
@ -140,7 +140,7 @@ ignore define CEC_OP_REC_SEQ_TUESDAY
|
|||||||
ignore define CEC_OP_REC_SEQ_WEDNESDAY
|
ignore define CEC_OP_REC_SEQ_WEDNESDAY
|
||||||
ignore define CEC_OP_REC_SEQ_THURSDAY
|
ignore define CEC_OP_REC_SEQ_THURSDAY
|
||||||
ignore define CEC_OP_REC_SEQ_FRIDAY
|
ignore define CEC_OP_REC_SEQ_FRIDAY
|
||||||
ignore define CEC_OP_REC_SEQ_SATERDAY
|
ignore define CEC_OP_REC_SEQ_SATURDAY
|
||||||
ignore define CEC_OP_REC_SEQ_ONCE_ONLY
|
ignore define CEC_OP_REC_SEQ_ONCE_ONLY
|
||||||
|
|
||||||
ignore define CEC_MSG_CLEAR_DIGITAL_TIMER
|
ignore define CEC_MSG_CLEAR_DIGITAL_TIMER
|
||||||
|
@ -1174,7 +1174,24 @@ enum v4l2_mpeg_video_h264_entropy_mode -
|
|||||||
Cyclic intra macroblock refresh. This is the number of continuous
|
Cyclic intra macroblock refresh. This is the number of continuous
|
||||||
macroblocks refreshed every frame. Each frame a successive set of
|
macroblocks refreshed every frame. Each frame a successive set of
|
||||||
macroblocks is refreshed until the cycle completes and starts from
|
macroblocks is refreshed until the cycle completes and starts from
|
||||||
the top of the frame. Applicable to H264, H263 and MPEG4 encoder.
|
the top of the frame. Setting this control to zero means that
|
||||||
|
macroblocks will not be refreshed. Note that this control will not
|
||||||
|
take effect when ``V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD`` control
|
||||||
|
is set to non zero value.
|
||||||
|
Applicable to H264, H263 and MPEG4 encoder.
|
||||||
|
|
||||||
|
``V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD (integer)``
|
||||||
|
Intra macroblock refresh period. This sets the period to refresh
|
||||||
|
the whole frame. In other words, this defines the number of frames
|
||||||
|
for which the whole frame will be intra-refreshed. An example:
|
||||||
|
setting period to 1 means that the whole frame will be refreshed,
|
||||||
|
setting period to 2 means that the half of macroblocks will be
|
||||||
|
intra-refreshed on frameX and the other half of macroblocks
|
||||||
|
will be refreshed in frameX + 1 and so on. Setting the period to
|
||||||
|
zero means no period is specified.
|
||||||
|
Note that if the client sets this control to non zero value the
|
||||||
|
``V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB`` control shall be
|
||||||
|
ignored. Applicable to H264 and HEVC encoders.
|
||||||
|
|
||||||
``V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (boolean)``
|
``V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (boolean)``
|
||||||
Frame level rate control enable. If this control is disabled then
|
Frame level rate control enable. If this control is disabled then
|
||||||
@ -3000,6 +3017,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
|
|||||||
* - __u8
|
* - __u8
|
||||||
- ``pic_struct``
|
- ``pic_struct``
|
||||||
-
|
-
|
||||||
|
* - __u32
|
||||||
|
- ``slice_segment_addr``
|
||||||
|
-
|
||||||
* - __u8
|
* - __u8
|
||||||
- ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
- ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
||||||
- The list of L0 reference elements as indices in the DPB.
|
- The list of L0 reference elements as indices in the DPB.
|
||||||
|
@ -20,25 +20,26 @@ Image Process Control IDs
|
|||||||
``V4L2_CID_IMAGE_PROC_CLASS (class)``
|
``V4L2_CID_IMAGE_PROC_CLASS (class)``
|
||||||
The IMAGE_PROC class descriptor.
|
The IMAGE_PROC class descriptor.
|
||||||
|
|
||||||
|
.. _v4l2-cid-link-freq:
|
||||||
|
|
||||||
``V4L2_CID_LINK_FREQ (integer menu)``
|
``V4L2_CID_LINK_FREQ (integer menu)``
|
||||||
Data bus frequency. Together with the media bus pixel code, bus type
|
The frequency of the data bus (e.g. parallel or CSI-2).
|
||||||
(clock cycles per sample), the data bus frequency defines the pixel
|
|
||||||
rate (``V4L2_CID_PIXEL_RATE``) in the pixel array (or possibly
|
.. _v4l2-cid-pixel-rate:
|
||||||
elsewhere, if the device is not an image sensor). The frame rate can
|
|
||||||
be calculated from the pixel clock, image width and height and
|
|
||||||
horizontal and vertical blanking. While the pixel rate control may
|
|
||||||
be defined elsewhere than in the subdev containing the pixel array,
|
|
||||||
the frame rate cannot be obtained from that information. This is
|
|
||||||
because only on the pixel array it can be assumed that the vertical
|
|
||||||
and horizontal blanking information is exact: no other blanking is
|
|
||||||
allowed in the pixel array. The selection of frame rate is performed
|
|
||||||
by selecting the desired horizontal and vertical blanking. The unit
|
|
||||||
of this control is Hz.
|
|
||||||
|
|
||||||
``V4L2_CID_PIXEL_RATE (64-bit integer)``
|
``V4L2_CID_PIXEL_RATE (64-bit integer)``
|
||||||
Pixel rate in the source pads of the subdev. This control is
|
Pixel sampling rate in the device's pixel array. This control is
|
||||||
read-only and its unit is pixels / second.
|
read-only and its unit is pixels / second.
|
||||||
|
|
||||||
|
Some devices use horizontal and vertical balanking to configure the frame
|
||||||
|
rate. The frame rate can be calculated from the pixel rate, analogue crop
|
||||||
|
rectangle as well as horizontal and vertical blanking. The pixel rate
|
||||||
|
control may be present in a different sub-device than the blanking controls
|
||||||
|
and the analogue crop rectangle configuration.
|
||||||
|
|
||||||
|
The configuration of the frame rate is performed by selecting the desired
|
||||||
|
horizontal and vertical blanking. The unit of this control is Hz.
|
||||||
|
|
||||||
``V4L2_CID_TEST_PATTERN (menu)``
|
``V4L2_CID_TEST_PATTERN (menu)``
|
||||||
Some capture/display/sensor devices have the capability to generate
|
Some capture/display/sensor devices have the capability to generate
|
||||||
test pattern images. These hardware specific test patterns can be
|
test pattern images. These hardware specific test patterns can be
|
||||||
|
27
MAINTAINERS
27
MAINTAINERS
@ -13833,6 +13833,15 @@ T: git git://linuxtv.org/media_tree.git
|
|||||||
F: Documentation/devicetree/bindings/media/i2c/ov8856.yaml
|
F: Documentation/devicetree/bindings/media/i2c/ov8856.yaml
|
||||||
F: drivers/media/i2c/ov8856.c
|
F: drivers/media/i2c/ov8856.c
|
||||||
|
|
||||||
|
OMNIVISION OV9282 SENSOR DRIVER
|
||||||
|
M: Paul J. Murphy <paul.j.murphy@intel.com>
|
||||||
|
M: Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||||
|
L: linux-media@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
T: git git://linuxtv.org/media_tree.git
|
||||||
|
F: Documentation/devicetree/bindings/media/i2c/ovti,ov9282.yaml
|
||||||
|
F: drivers/media/i2c/ov9282.c
|
||||||
|
|
||||||
OMNIVISION OV9640 SENSOR DRIVER
|
OMNIVISION OV9640 SENSOR DRIVER
|
||||||
M: Petr Cvek <petrcvekcz@gmail.com>
|
M: Petr Cvek <petrcvekcz@gmail.com>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
@ -17366,6 +17375,15 @@ T: git git://linuxtv.org/media_tree.git
|
|||||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml
|
F: Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml
|
||||||
F: drivers/media/i2c/imx334.c
|
F: drivers/media/i2c/imx334.c
|
||||||
|
|
||||||
|
SONY IMX335 SENSOR DRIVER
|
||||||
|
M: Paul J. Murphy <paul.j.murphy@intel.com>
|
||||||
|
M: Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||||
|
L: linux-media@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
T: git git://linuxtv.org/media_tree.git
|
||||||
|
F: Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
|
||||||
|
F: drivers/media/i2c/imx335.c
|
||||||
|
|
||||||
SONY IMX355 SENSOR DRIVER
|
SONY IMX355 SENSOR DRIVER
|
||||||
M: Tianshu Qiu <tian.shu.qiu@intel.com>
|
M: Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
@ -17373,6 +17391,15 @@ S: Maintained
|
|||||||
T: git git://linuxtv.org/media_tree.git
|
T: git git://linuxtv.org/media_tree.git
|
||||||
F: drivers/media/i2c/imx355.c
|
F: drivers/media/i2c/imx355.c
|
||||||
|
|
||||||
|
SONY IMX412 SENSOR DRIVER
|
||||||
|
M: Paul J. Murphy <paul.j.murphy@intel.com>
|
||||||
|
M: Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||||
|
L: linux-media@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
T: git git://linuxtv.org/media_tree.git
|
||||||
|
F: Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
|
||||||
|
F: drivers/media/i2c/imx412.c
|
||||||
|
|
||||||
SONY MEMORYSTICK SUBSYSTEM
|
SONY MEMORYSTICK SUBSYSTEM
|
||||||
M: Maxim Levitsky <maximlevitsky@gmail.com>
|
M: Maxim Levitsky <maximlevitsky@gmail.com>
|
||||||
M: Alex Dubov <oakad@yahoo.com>
|
M: Alex Dubov <oakad@yahoo.com>
|
||||||
|
@ -209,8 +209,8 @@ struct cec_pin {
|
|||||||
u32 work_pin_events_dropped_cnt;
|
u32 work_pin_events_dropped_cnt;
|
||||||
ktime_t timer_ts;
|
ktime_t timer_ts;
|
||||||
u32 timer_cnt;
|
u32 timer_cnt;
|
||||||
u32 timer_100ms_overruns;
|
u32 timer_100us_overruns;
|
||||||
u32 timer_300ms_overruns;
|
u32 timer_300us_overruns;
|
||||||
u32 timer_max_overrun;
|
u32 timer_max_overrun;
|
||||||
u32 timer_sum_overrun;
|
u32 timer_sum_overrun;
|
||||||
|
|
||||||
|
@ -854,9 +854,9 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
|
|||||||
if (delta > 100 && pin->state != CEC_ST_IDLE) {
|
if (delta > 100 && pin->state != CEC_ST_IDLE) {
|
||||||
/* Keep track of timer overruns */
|
/* Keep track of timer overruns */
|
||||||
pin->timer_sum_overrun += delta;
|
pin->timer_sum_overrun += delta;
|
||||||
pin->timer_100ms_overruns++;
|
pin->timer_100us_overruns++;
|
||||||
if (delta > 300)
|
if (delta > 300)
|
||||||
pin->timer_300ms_overruns++;
|
pin->timer_300us_overruns++;
|
||||||
if (delta > pin->timer_max_overrun)
|
if (delta > pin->timer_max_overrun)
|
||||||
pin->timer_max_overrun = delta;
|
pin->timer_max_overrun = delta;
|
||||||
}
|
}
|
||||||
@ -1207,15 +1207,15 @@ static void cec_pin_adap_status(struct cec_adapter *adap,
|
|||||||
seq_printf(file, "cec pin events dropped: %u\n",
|
seq_printf(file, "cec pin events dropped: %u\n",
|
||||||
pin->work_pin_events_dropped_cnt);
|
pin->work_pin_events_dropped_cnt);
|
||||||
seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
|
seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed);
|
||||||
if (pin->timer_100ms_overruns) {
|
if (pin->timer_100us_overruns) {
|
||||||
seq_printf(file, "timer overruns > 100ms: %u of %u\n",
|
seq_printf(file, "timer overruns > 100us: %u of %u\n",
|
||||||
pin->timer_100ms_overruns, pin->timer_cnt);
|
pin->timer_100us_overruns, pin->timer_cnt);
|
||||||
seq_printf(file, "timer overruns > 300ms: %u of %u\n",
|
seq_printf(file, "timer overruns > 300us: %u of %u\n",
|
||||||
pin->timer_300ms_overruns, pin->timer_cnt);
|
pin->timer_300us_overruns, pin->timer_cnt);
|
||||||
seq_printf(file, "max timer overrun: %u usecs\n",
|
seq_printf(file, "max timer overrun: %u usecs\n",
|
||||||
pin->timer_max_overrun);
|
pin->timer_max_overrun);
|
||||||
seq_printf(file, "avg timer overrun: %u usecs\n",
|
seq_printf(file, "avg timer overrun: %u usecs\n",
|
||||||
pin->timer_sum_overrun / pin->timer_100ms_overruns);
|
pin->timer_sum_overrun / pin->timer_100us_overruns);
|
||||||
}
|
}
|
||||||
if (pin->rx_start_bit_low_too_short_cnt)
|
if (pin->rx_start_bit_low_too_short_cnt)
|
||||||
seq_printf(file,
|
seq_printf(file,
|
||||||
@ -1245,8 +1245,8 @@ static void cec_pin_adap_status(struct cec_adapter *adap,
|
|||||||
seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt);
|
seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt);
|
||||||
pin->work_pin_events_dropped_cnt = 0;
|
pin->work_pin_events_dropped_cnt = 0;
|
||||||
pin->timer_cnt = 0;
|
pin->timer_cnt = 0;
|
||||||
pin->timer_100ms_overruns = 0;
|
pin->timer_100us_overruns = 0;
|
||||||
pin->timer_300ms_overruns = 0;
|
pin->timer_300us_overruns = 0;
|
||||||
pin->timer_max_overrun = 0;
|
pin->timer_max_overrun = 0;
|
||||||
pin->timer_sum_overrun = 0;
|
pin->timer_sum_overrun = 0;
|
||||||
pin->rx_start_bit_low_too_short_cnt = 0;
|
pin->rx_start_bit_low_too_short_cnt = 0;
|
||||||
|
@ -305,14 +305,16 @@ static int stm32_cec_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
|
cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
|
||||||
if (IS_ERR(cec->clk_hdmi_cec) &&
|
if (IS_ERR(cec->clk_hdmi_cec) &&
|
||||||
PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER)
|
PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER) {
|
||||||
return -EPROBE_DEFER;
|
ret = -EPROBE_DEFER;
|
||||||
|
goto err_unprepare_cec_clk;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IS_ERR(cec->clk_hdmi_cec)) {
|
if (!IS_ERR(cec->clk_hdmi_cec)) {
|
||||||
ret = clk_prepare(cec->clk_hdmi_cec);
|
ret = clk_prepare(cec->clk_hdmi_cec);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
|
dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
|
||||||
return ret;
|
goto err_unprepare_cec_clk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,19 +326,27 @@ static int stm32_cec_probe(struct platform_device *pdev)
|
|||||||
CEC_NAME, caps, CEC_MAX_LOG_ADDRS);
|
CEC_NAME, caps, CEC_MAX_LOG_ADDRS);
|
||||||
ret = PTR_ERR_OR_ZERO(cec->adap);
|
ret = PTR_ERR_OR_ZERO(cec->adap);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_unprepare_hdmi_cec_clk;
|
||||||
|
|
||||||
ret = cec_register_adapter(cec->adap, &pdev->dev);
|
ret = cec_register_adapter(cec->adap, &pdev->dev);
|
||||||
if (ret) {
|
if (ret)
|
||||||
cec_delete_adapter(cec->adap);
|
goto err_delete_adapter;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
cec_hw_init(cec);
|
cec_hw_init(cec);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, cec);
|
platform_set_drvdata(pdev, cec);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_delete_adapter:
|
||||||
|
cec_delete_adapter(cec->adap);
|
||||||
|
|
||||||
|
err_unprepare_hdmi_cec_clk:
|
||||||
|
clk_unprepare(cec->clk_hdmi_cec);
|
||||||
|
|
||||||
|
err_unprepare_cec_clk:
|
||||||
|
clk_unprepare(cec->clk_cec);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stm32_cec_remove(struct platform_device *pdev)
|
static int stm32_cec_remove(struct platform_device *pdev)
|
||||||
|
@ -366,7 +366,11 @@ static int tegra_cec_probe(struct platform_device *pdev)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_prepare_enable(cec->clk);
|
ret = clk_prepare_enable(cec->clk);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&pdev->dev, "Unable to prepare clock for CEC\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* set context info. */
|
/* set context info. */
|
||||||
cec->dev = &pdev->dev;
|
cec->dev = &pdev->dev;
|
||||||
@ -446,9 +450,7 @@ static int tegra_cec_resume(struct platform_device *pdev)
|
|||||||
|
|
||||||
dev_notice(&pdev->dev, "Resuming\n");
|
dev_notice(&pdev->dev, "Resuming\n");
|
||||||
|
|
||||||
clk_prepare_enable(cec->clk);
|
return clk_prepare_enable(cec->clk);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1172,7 +1172,6 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config,
|
|||||||
"%s: Error attaching frontend %d\n",
|
"%s: Error attaching frontend %d\n",
|
||||||
KBUILD_MODNAME, demod);
|
KBUILD_MODNAME, demod);
|
||||||
goto error1;
|
goto error1;
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
/* new priv instance */
|
/* new priv instance */
|
||||||
priv->i2c = i2c;
|
priv->i2c = i2c;
|
||||||
|
@ -2107,32 +2107,55 @@ static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *an
|
|||||||
dib8000_write_word(state, 117 + mode, ana_fe[mode]);
|
dib8000_write_word(state, 117 + mode, ana_fe[mode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u16 lut_prbs_2k[14] = {
|
static const u16 lut_prbs_2k[13] = {
|
||||||
0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213
|
0x423, 0x009, 0x5C7,
|
||||||
|
0x7A6, 0x3D8, 0x527,
|
||||||
|
0x7FF, 0x79B, 0x3D6,
|
||||||
|
0x3A2, 0x53B, 0x2F4,
|
||||||
|
0x213
|
||||||
};
|
};
|
||||||
static const u16 lut_prbs_4k[14] = {
|
|
||||||
0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E
|
static const u16 lut_prbs_4k[13] = {
|
||||||
|
0x208, 0x0C3, 0x7B9,
|
||||||
|
0x423, 0x5C7, 0x3D8,
|
||||||
|
0x7FF, 0x3D6, 0x53B,
|
||||||
|
0x213, 0x029, 0x0D0,
|
||||||
|
0x48E
|
||||||
};
|
};
|
||||||
static const u16 lut_prbs_8k[14] = {
|
|
||||||
0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684
|
static const u16 lut_prbs_8k[13] = {
|
||||||
|
0x740, 0x069, 0x7DD,
|
||||||
|
0x208, 0x7B9, 0x5C7,
|
||||||
|
0x7FF, 0x53B, 0x029,
|
||||||
|
0x48E, 0x4C4, 0x367,
|
||||||
|
0x684
|
||||||
};
|
};
|
||||||
|
|
||||||
static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
|
static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
|
||||||
{
|
{
|
||||||
int sub_channel_prbs_group = 0;
|
int sub_channel_prbs_group = 0;
|
||||||
|
int prbs_group;
|
||||||
|
|
||||||
sub_channel_prbs_group = (subchannel / 3) + 1;
|
sub_channel_prbs_group = subchannel / 3;
|
||||||
dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]);
|
if (sub_channel_prbs_group >= ARRAY_SIZE(lut_prbs_2k))
|
||||||
|
return 0;
|
||||||
|
|
||||||
switch (state->fe[0]->dtv_property_cache.transmission_mode) {
|
switch (state->fe[0]->dtv_property_cache.transmission_mode) {
|
||||||
case TRANSMISSION_MODE_2K:
|
case TRANSMISSION_MODE_2K:
|
||||||
return lut_prbs_2k[sub_channel_prbs_group];
|
prbs_group = lut_prbs_2k[sub_channel_prbs_group];
|
||||||
|
break;
|
||||||
case TRANSMISSION_MODE_4K:
|
case TRANSMISSION_MODE_4K:
|
||||||
return lut_prbs_4k[sub_channel_prbs_group];
|
prbs_group = lut_prbs_4k[sub_channel_prbs_group];
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
case TRANSMISSION_MODE_8K:
|
case TRANSMISSION_MODE_8K:
|
||||||
return lut_prbs_8k[sub_channel_prbs_group];
|
prbs_group = lut_prbs_8k[sub_channel_prbs_group];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n",
|
||||||
|
sub_channel_prbs_group, subchannel, prbs_group);
|
||||||
|
|
||||||
|
return prbs_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dib8000_set_13seg_channel(struct dib8000_state *state)
|
static void dib8000_set_13seg_channel(struct dib8000_state *state)
|
||||||
@ -2409,10 +2432,8 @@ static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq
|
|||||||
/* TSB or ISDBT ? apply it now */
|
/* TSB or ISDBT ? apply it now */
|
||||||
if (c->isdbt_sb_mode) {
|
if (c->isdbt_sb_mode) {
|
||||||
dib8000_set_sb_channel(state);
|
dib8000_set_sb_channel(state);
|
||||||
if (c->isdbt_sb_subchannel < 14)
|
init_prbs = dib8000_get_init_prbs(state,
|
||||||
init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel);
|
c->isdbt_sb_subchannel);
|
||||||
else
|
|
||||||
init_prbs = 0;
|
|
||||||
} else {
|
} else {
|
||||||
dib8000_set_13seg_channel(state);
|
dib8000_set_13seg_channel(state);
|
||||||
init_prbs = 0xfff;
|
init_prbs = 0xfff;
|
||||||
@ -3004,6 +3025,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
|
|||||||
|
|
||||||
unsigned long *timeout = &state->timeout;
|
unsigned long *timeout = &state->timeout;
|
||||||
unsigned long now = jiffies;
|
unsigned long now = jiffies;
|
||||||
|
u16 init_prbs;
|
||||||
#ifdef DIB8000_AGC_FREEZE
|
#ifdef DIB8000_AGC_FREEZE
|
||||||
u16 agc1, agc2;
|
u16 agc1, agc2;
|
||||||
#endif
|
#endif
|
||||||
@ -3302,8 +3324,10 @@ static int dib8000_tune(struct dvb_frontend *fe)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
|
case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
|
||||||
if (state->subchannel <= 41) {
|
init_prbs = dib8000_get_init_prbs(state, state->subchannel);
|
||||||
dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
|
|
||||||
|
if (init_prbs) {
|
||||||
|
dib8000_set_subchannel_prbs(state, init_prbs);
|
||||||
*tune_state = CT_DEMOD_STEP_9;
|
*tune_state = CT_DEMOD_STEP_9;
|
||||||
} else {
|
} else {
|
||||||
*tune_state = CT_DEMOD_STOP;
|
*tune_state = CT_DEMOD_STOP;
|
||||||
|
@ -842,6 +842,20 @@ config VIDEO_IMX334
|
|||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called imx334.
|
module will be called imx334.
|
||||||
|
|
||||||
|
config VIDEO_IMX335
|
||||||
|
tristate "Sony IMX335 sensor support"
|
||||||
|
depends on OF_GPIO
|
||||||
|
depends on I2C && VIDEO_V4L2
|
||||||
|
select VIDEO_V4L2_SUBDEV_API
|
||||||
|
select MEDIA_CONTROLLER
|
||||||
|
select V4L2_FWNODE
|
||||||
|
help
|
||||||
|
This is a Video4Linux2 sensor driver for the Sony
|
||||||
|
IMX335 camera.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called imx335.
|
||||||
|
|
||||||
config VIDEO_IMX355
|
config VIDEO_IMX355
|
||||||
tristate "Sony IMX355 sensor support"
|
tristate "Sony IMX355 sensor support"
|
||||||
depends on I2C && VIDEO_V4L2
|
depends on I2C && VIDEO_V4L2
|
||||||
@ -854,6 +868,20 @@ config VIDEO_IMX355
|
|||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called imx355.
|
module will be called imx355.
|
||||||
|
|
||||||
|
config VIDEO_IMX412
|
||||||
|
tristate "Sony IMX412 sensor support"
|
||||||
|
depends on OF_GPIO
|
||||||
|
depends on I2C && VIDEO_V4L2
|
||||||
|
select VIDEO_V4L2_SUBDEV_API
|
||||||
|
select MEDIA_CONTROLLER
|
||||||
|
select V4L2_FWNODE
|
||||||
|
help
|
||||||
|
This is a Video4Linux2 sensor driver for the Sony
|
||||||
|
IMX412 camera.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called imx412.
|
||||||
|
|
||||||
config VIDEO_OV02A10
|
config VIDEO_OV02A10
|
||||||
tristate "OmniVision OV02A10 sensor support"
|
tristate "OmniVision OV02A10 sensor support"
|
||||||
depends on VIDEO_V4L2 && I2C
|
depends on VIDEO_V4L2 && I2C
|
||||||
@ -1103,6 +1131,20 @@ config VIDEO_OV8865
|
|||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called ov8865.
|
module will be called ov8865.
|
||||||
|
|
||||||
|
config VIDEO_OV9282
|
||||||
|
tristate "OmniVision OV9282 sensor support"
|
||||||
|
depends on OF_GPIO
|
||||||
|
depends on I2C && VIDEO_V4L2
|
||||||
|
select VIDEO_V4L2_SUBDEV_API
|
||||||
|
select MEDIA_CONTROLLER
|
||||||
|
select V4L2_FWNODE
|
||||||
|
help
|
||||||
|
This is a Video4Linux2 sensor driver for the OmniVision
|
||||||
|
OV9282 camera sensor.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called ov9282.
|
||||||
|
|
||||||
config VIDEO_OV9640
|
config VIDEO_OV9640
|
||||||
tristate "OmniVision OV9640 sensor support"
|
tristate "OmniVision OV9640 sensor support"
|
||||||
depends on I2C && VIDEO_V4L2
|
depends on I2C && VIDEO_V4L2
|
||||||
|
@ -84,6 +84,7 @@ obj-$(CONFIG_VIDEO_OV772X) += ov772x.o
|
|||||||
obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
|
obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
|
||||||
obj-$(CONFIG_VIDEO_OV8856) += ov8856.o
|
obj-$(CONFIG_VIDEO_OV8856) += ov8856.o
|
||||||
obj-$(CONFIG_VIDEO_OV8865) += ov8865.o
|
obj-$(CONFIG_VIDEO_OV8865) += ov8865.o
|
||||||
|
obj-$(CONFIG_VIDEO_OV9282) += ov9282.o
|
||||||
obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
|
obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
|
||||||
obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
|
obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
|
||||||
obj-$(CONFIG_VIDEO_OV9734) += ov9734.o
|
obj-$(CONFIG_VIDEO_OV9734) += ov9734.o
|
||||||
@ -124,11 +125,12 @@ obj-$(CONFIG_VIDEO_IMX274) += imx274.o
|
|||||||
obj-$(CONFIG_VIDEO_IMX290) += imx290.o
|
obj-$(CONFIG_VIDEO_IMX290) += imx290.o
|
||||||
obj-$(CONFIG_VIDEO_IMX319) += imx319.o
|
obj-$(CONFIG_VIDEO_IMX319) += imx319.o
|
||||||
obj-$(CONFIG_VIDEO_IMX334) += imx334.o
|
obj-$(CONFIG_VIDEO_IMX334) += imx334.o
|
||||||
|
obj-$(CONFIG_VIDEO_IMX335) += imx335.o
|
||||||
obj-$(CONFIG_VIDEO_IMX355) += imx355.o
|
obj-$(CONFIG_VIDEO_IMX355) += imx355.o
|
||||||
|
obj-$(CONFIG_VIDEO_IMX412) += imx412.o
|
||||||
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
|
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
|
||||||
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
|
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
|
||||||
obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o
|
obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o
|
||||||
obj-$(CONFIG_VIDEO_RDACM21) += rdacm21.o
|
obj-$(CONFIG_VIDEO_RDACM21) += rdacm21.o
|
||||||
obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
|
obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o
|
||||||
|
|
||||||
obj-$(CONFIG_SDR_MAX2175) += max2175.o
|
obj-$(CONFIG_SDR_MAX2175) += max2175.o
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
#define ADV7180_REG_SHAP_FILTER_CTL_1 0x0017
|
#define ADV7180_REG_SHAP_FILTER_CTL_1 0x0017
|
||||||
#define ADV7180_REG_CTRL_2 0x001d
|
#define ADV7180_REG_CTRL_2 0x001d
|
||||||
#define ADV7180_REG_VSYNC_FIELD_CTL_1 0x0031
|
#define ADV7180_REG_VSYNC_FIELD_CTL_1 0x0031
|
||||||
|
#define ADV7180_VSYNC_FIELD_CTL_1_NEWAV 0x12
|
||||||
#define ADV7180_REG_MANUAL_WIN_CTL_1 0x003d
|
#define ADV7180_REG_MANUAL_WIN_CTL_1 0x003d
|
||||||
#define ADV7180_REG_MANUAL_WIN_CTL_2 0x003e
|
#define ADV7180_REG_MANUAL_WIN_CTL_2 0x003e
|
||||||
#define ADV7180_REG_MANUAL_WIN_CTL_3 0x003f
|
#define ADV7180_REG_MANUAL_WIN_CTL_3 0x003f
|
||||||
@ -205,6 +206,7 @@ struct adv7180_state {
|
|||||||
struct mutex mutex; /* mutual excl. when accessing chip */
|
struct mutex mutex; /* mutual excl. when accessing chip */
|
||||||
int irq;
|
int irq;
|
||||||
struct gpio_desc *pwdn_gpio;
|
struct gpio_desc *pwdn_gpio;
|
||||||
|
struct gpio_desc *rst_gpio;
|
||||||
v4l2_std_id curr_norm;
|
v4l2_std_id curr_norm;
|
||||||
bool powered;
|
bool powered;
|
||||||
bool streaming;
|
bool streaming;
|
||||||
@ -216,6 +218,7 @@ struct adv7180_state {
|
|||||||
struct i2c_client *vpp_client;
|
struct i2c_client *vpp_client;
|
||||||
const struct adv7180_chip_info *chip_info;
|
const struct adv7180_chip_info *chip_info;
|
||||||
enum v4l2_field field;
|
enum v4l2_field field;
|
||||||
|
bool force_bt656_4;
|
||||||
};
|
};
|
||||||
#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
|
#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
|
||||||
struct adv7180_state, \
|
struct adv7180_state, \
|
||||||
@ -484,6 +487,19 @@ static void adv7180_set_power_pin(struct adv7180_state *state, bool on)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void adv7180_set_reset_pin(struct adv7180_state *state, bool on)
|
||||||
|
{
|
||||||
|
if (!state->rst_gpio)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (on) {
|
||||||
|
gpiod_set_value_cansleep(state->rst_gpio, 1);
|
||||||
|
} else {
|
||||||
|
gpiod_set_value_cansleep(state->rst_gpio, 0);
|
||||||
|
usleep_range(5000, 10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int adv7180_set_power(struct adv7180_state *state, bool on)
|
static int adv7180_set_power(struct adv7180_state *state, bool on)
|
||||||
{
|
{
|
||||||
u8 val;
|
u8 val;
|
||||||
@ -963,10 +979,26 @@ static int adv7182_init(struct adv7180_state *state)
|
|||||||
adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x57);
|
adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL, 0x57);
|
||||||
adv7180_write(state, ADV7180_REG_CTRL_2, 0xc0);
|
adv7180_write(state, ADV7180_REG_CTRL_2, 0xc0);
|
||||||
} else {
|
} else {
|
||||||
if (state->chip_info->flags & ADV7180_FLAG_V2)
|
if (state->chip_info->flags & ADV7180_FLAG_V2) {
|
||||||
adv7180_write(state,
|
if (state->force_bt656_4) {
|
||||||
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
|
/* ITU-R BT.656-4 compatible */
|
||||||
0x17);
|
adv7180_write(state,
|
||||||
|
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
|
||||||
|
ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
|
||||||
|
/* Manually set NEWAVMODE */
|
||||||
|
adv7180_write(state,
|
||||||
|
ADV7180_REG_VSYNC_FIELD_CTL_1,
|
||||||
|
ADV7180_VSYNC_FIELD_CTL_1_NEWAV);
|
||||||
|
/* Manually set V bit end position in NTSC mode */
|
||||||
|
adv7180_write(state,
|
||||||
|
ADV7180_REG_NTSC_V_BIT_END,
|
||||||
|
ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
|
||||||
|
} else {
|
||||||
|
adv7180_write(state,
|
||||||
|
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
|
||||||
|
0x17);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
adv7180_write(state,
|
adv7180_write(state,
|
||||||
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
|
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
|
||||||
@ -1263,6 +1295,7 @@ static int init_device(struct adv7180_state *state)
|
|||||||
mutex_lock(&state->mutex);
|
mutex_lock(&state->mutex);
|
||||||
|
|
||||||
adv7180_set_power_pin(state, true);
|
adv7180_set_power_pin(state, true);
|
||||||
|
adv7180_set_reset_pin(state, false);
|
||||||
|
|
||||||
adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
|
adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
|
||||||
usleep_range(5000, 10000);
|
usleep_range(5000, 10000);
|
||||||
@ -1314,6 +1347,7 @@ static int init_device(struct adv7180_state *state)
|
|||||||
static int adv7180_probe(struct i2c_client *client,
|
static int adv7180_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
|
struct device_node *np = client->dev.of_node;
|
||||||
struct adv7180_state *state;
|
struct adv7180_state *state;
|
||||||
struct v4l2_subdev *sd;
|
struct v4l2_subdev *sd;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1338,6 +1372,17 @@ static int adv7180_probe(struct i2c_client *client,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state->rst_gpio = devm_gpiod_get_optional(&client->dev, "reset",
|
||||||
|
GPIOD_OUT_HIGH);
|
||||||
|
if (IS_ERR(state->rst_gpio)) {
|
||||||
|
ret = PTR_ERR(state->rst_gpio);
|
||||||
|
v4l_err(client, "request for reset pin failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (of_property_read_bool(np, "adv,force-bt656-4"))
|
||||||
|
state->force_bt656_4 = true;
|
||||||
|
|
||||||
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
|
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
|
||||||
state->csi_client = i2c_new_dummy_device(client->adapter,
|
state->csi_client = i2c_new_dummy_device(client->adapter,
|
||||||
ADV7180_DEFAULT_CSI_I2C_ADDR);
|
ADV7180_DEFAULT_CSI_I2C_ADDR);
|
||||||
@ -1392,11 +1437,19 @@ static int adv7180_probe(struct i2c_client *client,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_free_irq;
|
goto err_free_irq;
|
||||||
|
|
||||||
v4l_info(client, "chip found @ 0x%02x (%s)\n",
|
mutex_lock(&state->mutex);
|
||||||
client->addr, client->adapter->name);
|
ret = adv7180_read(state, ADV7180_REG_IDENT);
|
||||||
|
mutex_unlock(&state->mutex);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err_v4l2_async_unregister;
|
||||||
|
|
||||||
|
v4l_info(client, "chip id 0x%x found @ 0x%02x (%s)\n",
|
||||||
|
ret, client->addr, client->adapter->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_v4l2_async_unregister:
|
||||||
|
v4l2_async_unregister_subdev(sd);
|
||||||
err_free_irq:
|
err_free_irq:
|
||||||
if (state->irq > 0)
|
if (state->irq > 0)
|
||||||
free_irq(client->irq, state);
|
free_irq(client->irq, state);
|
||||||
@ -1428,6 +1481,7 @@ static int adv7180_remove(struct i2c_client *client)
|
|||||||
i2c_unregister_device(state->vpp_client);
|
i2c_unregister_device(state->vpp_client);
|
||||||
i2c_unregister_device(state->csi_client);
|
i2c_unregister_device(state->csi_client);
|
||||||
|
|
||||||
|
adv7180_set_reset_pin(state, true);
|
||||||
adv7180_set_power_pin(state, false);
|
adv7180_set_power_pin(state, false);
|
||||||
|
|
||||||
mutex_destroy(&state->mutex);
|
mutex_destroy(&state->mutex);
|
||||||
|
@ -1943,6 +1943,51 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ccs_pre_streamon(struct v4l2_subdev *subdev, u32 flags)
|
||||||
|
{
|
||||||
|
struct ccs_sensor *sensor = to_ccs_sensor(subdev);
|
||||||
|
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||||
|
int rval;
|
||||||
|
|
||||||
|
if (flags & V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP) {
|
||||||
|
switch (sensor->hwcfg.csi_signalling_mode) {
|
||||||
|
case CCS_CSI_SIGNALING_MODE_CSI_2_DPHY:
|
||||||
|
if (!(CCS_LIM(sensor, PHY_CTRL_CAPABILITY_2) &
|
||||||
|
CCS_PHY_CTRL_CAPABILITY_2_MANUAL_LP_DPHY))
|
||||||
|
return -EACCES;
|
||||||
|
break;
|
||||||
|
case CCS_CSI_SIGNALING_MODE_CSI_2_CPHY:
|
||||||
|
if (!(CCS_LIM(sensor, PHY_CTRL_CAPABILITY_2) &
|
||||||
|
CCS_PHY_CTRL_CAPABILITY_2_MANUAL_LP_CPHY))
|
||||||
|
return -EACCES;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = ccs_pm_get_init(sensor);
|
||||||
|
if (rval)
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
if (flags & V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP) {
|
||||||
|
rval = ccs_write(sensor, MANUAL_LP_CTRL,
|
||||||
|
CCS_MANUAL_LP_CTRL_ENABLE);
|
||||||
|
if (rval)
|
||||||
|
pm_runtime_put(&client->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ccs_post_streamoff(struct v4l2_subdev *subdev)
|
||||||
|
{
|
||||||
|
struct ccs_sensor *sensor = to_ccs_sensor(subdev);
|
||||||
|
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
|
||||||
|
|
||||||
|
return pm_runtime_put(&client->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int ccs_enum_mbus_code(struct v4l2_subdev *subdev,
|
static int ccs_enum_mbus_code(struct v4l2_subdev *subdev,
|
||||||
struct v4l2_subdev_state *sd_state,
|
struct v4l2_subdev_state *sd_state,
|
||||||
struct v4l2_subdev_mbus_code_enum *code)
|
struct v4l2_subdev_mbus_code_enum *code)
|
||||||
@ -2673,8 +2718,7 @@ static int ccs_get_skip_top_lines(struct v4l2_subdev *subdev, u32 *lines)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
ccs_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
|
nvm_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
|
struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
|
||||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||||
@ -2704,11 +2748,10 @@ ccs_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
|
|||||||
*/
|
*/
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR(nvm, S_IRUGO, ccs_sysfs_nvm_read, NULL);
|
static DEVICE_ATTR_RO(nvm);
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
ccs_sysfs_ident_read(struct device *dev, struct device_attribute *attr,
|
ident_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
|
struct v4l2_subdev *subdev = i2c_get_clientdata(to_i2c_client(dev));
|
||||||
struct ccs_sensor *sensor = to_ccs_sensor(subdev);
|
struct ccs_sensor *sensor = to_ccs_sensor(subdev);
|
||||||
@ -2723,8 +2766,7 @@ ccs_sysfs_ident_read(struct device *dev, struct device_attribute *attr,
|
|||||||
minfo->smia_manufacturer_id, minfo->model_id,
|
minfo->smia_manufacturer_id, minfo->model_id,
|
||||||
minfo->revision_number) + 1;
|
minfo->revision_number) + 1;
|
||||||
}
|
}
|
||||||
|
static DEVICE_ATTR_RO(ident);
|
||||||
static DEVICE_ATTR(ident, S_IRUGO, ccs_sysfs_ident_read, NULL);
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* V4L2 subdev core operations
|
* V4L2 subdev core operations
|
||||||
@ -3058,6 +3100,8 @@ static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
|||||||
|
|
||||||
static const struct v4l2_subdev_video_ops ccs_video_ops = {
|
static const struct v4l2_subdev_video_ops ccs_video_ops = {
|
||||||
.s_stream = ccs_set_stream,
|
.s_stream = ccs_set_stream,
|
||||||
|
.pre_streamon = ccs_pre_streamon,
|
||||||
|
.post_streamoff = ccs_post_streamoff,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct v4l2_subdev_pad_ops ccs_pad_ops = {
|
static const struct v4l2_subdev_pad_ops ccs_pad_ops = {
|
||||||
|
@ -1237,8 +1237,7 @@ static int et8ek8_dev_init(struct v4l2_subdev *subdev)
|
|||||||
* sysfs attributes
|
* sysfs attributes
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
static ssize_t
|
||||||
et8ek8_priv_mem_read(struct device *dev, struct device_attribute *attr,
|
priv_mem_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct v4l2_subdev *subdev = dev_get_drvdata(dev);
|
struct v4l2_subdev *subdev = dev_get_drvdata(dev);
|
||||||
struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
|
struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
|
||||||
@ -1251,7 +1250,7 @@ et8ek8_priv_mem_read(struct device *dev, struct device_attribute *attr,
|
|||||||
|
|
||||||
return ET8EK8_PRIV_MEM_SIZE;
|
return ET8EK8_PRIV_MEM_SIZE;
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR(priv_mem, 0444, et8ek8_priv_mem_read, NULL);
|
static DEVICE_ATTR_RO(priv_mem);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
* V4L2 subdev core operations
|
* V4L2 subdev core operations
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#define IMX258_CHIP_ID 0x0258
|
#define IMX258_CHIP_ID 0x0258
|
||||||
|
|
||||||
/* V_TIMING internal */
|
/* V_TIMING internal */
|
||||||
#define IMX258_VTS_30FPS 0x0c98
|
#define IMX258_VTS_30FPS 0x0c50
|
||||||
#define IMX258_VTS_30FPS_2K 0x0638
|
#define IMX258_VTS_30FPS_2K 0x0638
|
||||||
#define IMX258_VTS_30FPS_VGA 0x034c
|
#define IMX258_VTS_30FPS_VGA 0x034c
|
||||||
#define IMX258_VTS_MAX 0xffff
|
#define IMX258_VTS_MAX 0xffff
|
||||||
@ -47,7 +47,7 @@
|
|||||||
/* Analog gain control */
|
/* Analog gain control */
|
||||||
#define IMX258_REG_ANALOG_GAIN 0x0204
|
#define IMX258_REG_ANALOG_GAIN 0x0204
|
||||||
#define IMX258_ANA_GAIN_MIN 0
|
#define IMX258_ANA_GAIN_MIN 0
|
||||||
#define IMX258_ANA_GAIN_MAX 0x1fff
|
#define IMX258_ANA_GAIN_MAX 480
|
||||||
#define IMX258_ANA_GAIN_STEP 1
|
#define IMX258_ANA_GAIN_STEP 1
|
||||||
#define IMX258_ANA_GAIN_DEFAULT 0x0
|
#define IMX258_ANA_GAIN_DEFAULT 0x0
|
||||||
|
|
||||||
|
1129
drivers/media/i2c/imx335.c
Normal file
1129
drivers/media/i2c/imx335.c
Normal file
File diff suppressed because it is too large
Load Diff
1272
drivers/media/i2c/imx412.c
Normal file
1272
drivers/media/i2c/imx412.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -51,7 +51,7 @@
|
|||||||
#define OV2740_REG_MWB_R_GAIN 0x500a
|
#define OV2740_REG_MWB_R_GAIN 0x500a
|
||||||
#define OV2740_REG_MWB_G_GAIN 0x500c
|
#define OV2740_REG_MWB_G_GAIN 0x500c
|
||||||
#define OV2740_REG_MWB_B_GAIN 0x500e
|
#define OV2740_REG_MWB_B_GAIN 0x500e
|
||||||
#define OV2740_DGTL_GAIN_MIN 0
|
#define OV2740_DGTL_GAIN_MIN 1024
|
||||||
#define OV2740_DGTL_GAIN_MAX 4095
|
#define OV2740_DGTL_GAIN_MAX 4095
|
||||||
#define OV2740_DGTL_GAIN_STEP 1
|
#define OV2740_DGTL_GAIN_STEP 1
|
||||||
#define OV2740_DGTL_GAIN_DEFAULT 1024
|
#define OV2740_DGTL_GAIN_DEFAULT 1024
|
||||||
@ -61,6 +61,12 @@
|
|||||||
#define OV2740_TEST_PATTERN_ENABLE BIT(7)
|
#define OV2740_TEST_PATTERN_ENABLE BIT(7)
|
||||||
#define OV2740_TEST_PATTERN_BAR_SHIFT 2
|
#define OV2740_TEST_PATTERN_BAR_SHIFT 2
|
||||||
|
|
||||||
|
/* Group Access */
|
||||||
|
#define OV2740_REG_GROUP_ACCESS 0x3208
|
||||||
|
#define OV2740_GROUP_HOLD_START 0x0
|
||||||
|
#define OV2740_GROUP_HOLD_END 0x10
|
||||||
|
#define OV2740_GROUP_HOLD_LAUNCH 0xa0
|
||||||
|
|
||||||
/* ISP CTRL00 */
|
/* ISP CTRL00 */
|
||||||
#define OV2740_REG_ISP_CTRL00 0x5000
|
#define OV2740_REG_ISP_CTRL00 0x5000
|
||||||
/* ISP CTRL01 */
|
/* ISP CTRL01 */
|
||||||
@ -438,6 +444,11 @@ static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
|
||||||
|
OV2740_GROUP_HOLD_START);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_R_GAIN, 2, d_gain);
|
ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_R_GAIN, 2, d_gain);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -446,7 +457,18 @@ static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return ov2740_write_reg(ov2740, OV2740_REG_MWB_B_GAIN, 2, d_gain);
|
ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_B_GAIN, 2, d_gain);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
|
||||||
|
OV2740_GROUP_HOLD_END);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ov2740_write_reg(ov2740, OV2740_REG_GROUP_ACCESS, 1,
|
||||||
|
OV2740_GROUP_HOLD_LAUNCH);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ov2740_test_pattern(struct ov2740 *ov2740, u32 pattern)
|
static int ov2740_test_pattern(struct ov2740 *ov2740, u32 pattern)
|
||||||
|
@ -135,7 +135,9 @@ struct ov5640_pixfmt {
|
|||||||
static const struct ov5640_pixfmt ov5640_formats[] = {
|
static const struct ov5640_pixfmt ov5640_formats[] = {
|
||||||
{ MEDIA_BUS_FMT_JPEG_1X8, V4L2_COLORSPACE_JPEG, },
|
{ MEDIA_BUS_FMT_JPEG_1X8, V4L2_COLORSPACE_JPEG, },
|
||||||
{ MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
|
{ MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
|
||||||
|
{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_COLORSPACE_SRGB, },
|
||||||
{ MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
|
{ MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
|
||||||
|
{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_COLORSPACE_SRGB, },
|
||||||
{ MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
|
{ MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
|
||||||
{ MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
|
{ MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
|
||||||
{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB, },
|
{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB, },
|
||||||
@ -2338,11 +2340,13 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor,
|
|||||||
u8 fmt, mux;
|
u8 fmt, mux;
|
||||||
|
|
||||||
switch (format->code) {
|
switch (format->code) {
|
||||||
|
case MEDIA_BUS_FMT_UYVY8_1X16:
|
||||||
case MEDIA_BUS_FMT_UYVY8_2X8:
|
case MEDIA_BUS_FMT_UYVY8_2X8:
|
||||||
/* YUV422, UYVY */
|
/* YUV422, UYVY */
|
||||||
fmt = 0x3f;
|
fmt = 0x3f;
|
||||||
mux = OV5640_FMT_MUX_YUV422;
|
mux = OV5640_FMT_MUX_YUV422;
|
||||||
break;
|
break;
|
||||||
|
case MEDIA_BUS_FMT_YUYV8_1X16:
|
||||||
case MEDIA_BUS_FMT_YUYV8_2X8:
|
case MEDIA_BUS_FMT_YUYV8_2X8:
|
||||||
/* YUV422, YUYV */
|
/* YUV422, YUYV */
|
||||||
fmt = 0x30;
|
fmt = 0x30;
|
||||||
|
@ -2304,25 +2304,26 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
|
|||||||
|
|
||||||
clk_set_rate(ov8856->xvclk, xvclk_rate);
|
clk_set_rate(ov8856->xvclk, xvclk_rate);
|
||||||
xvclk_rate = clk_get_rate(ov8856->xvclk);
|
xvclk_rate = clk_get_rate(ov8856->xvclk);
|
||||||
|
|
||||||
|
ov8856->reset_gpio = devm_gpiod_get_optional(dev, "reset",
|
||||||
|
GPIOD_OUT_LOW);
|
||||||
|
if (IS_ERR(ov8856->reset_gpio))
|
||||||
|
return PTR_ERR(ov8856->reset_gpio);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ov8856_supply_names); i++)
|
||||||
|
ov8856->supplies[i].supply = ov8856_supply_names[i];
|
||||||
|
|
||||||
|
ret = devm_regulator_bulk_get(dev,
|
||||||
|
ARRAY_SIZE(ov8856_supply_names),
|
||||||
|
ov8856->supplies);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xvclk_rate != OV8856_XVCLK_19_2)
|
if (xvclk_rate != OV8856_XVCLK_19_2)
|
||||||
dev_warn(dev, "external clock rate %u is unsupported",
|
dev_warn(dev, "external clock rate %u is unsupported",
|
||||||
xvclk_rate);
|
xvclk_rate);
|
||||||
|
|
||||||
ov8856->reset_gpio = devm_gpiod_get_optional(dev, "reset",
|
|
||||||
GPIOD_OUT_LOW);
|
|
||||||
if (IS_ERR(ov8856->reset_gpio))
|
|
||||||
return PTR_ERR(ov8856->reset_gpio);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ov8856_supply_names); i++)
|
|
||||||
ov8856->supplies[i].supply = ov8856_supply_names[i];
|
|
||||||
|
|
||||||
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ov8856_supply_names),
|
|
||||||
ov8856->supplies);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
|
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
|
||||||
if (!ep)
|
if (!ep)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
1137
drivers/media/i2c/ov9282.c
Normal file
1137
drivers/media/i2c/ov9282.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -60,6 +60,12 @@
|
|||||||
#define OV9734_TEST_PATTERN_ENABLE BIT(7)
|
#define OV9734_TEST_PATTERN_ENABLE BIT(7)
|
||||||
#define OV9734_TEST_PATTERN_BAR_SHIFT 2
|
#define OV9734_TEST_PATTERN_BAR_SHIFT 2
|
||||||
|
|
||||||
|
/* Group Access */
|
||||||
|
#define OV9734_REG_GROUP_ACCESS 0x3208
|
||||||
|
#define OV9734_GROUP_HOLD_START 0x0
|
||||||
|
#define OV9734_GROUP_HOLD_END 0x10
|
||||||
|
#define OV9734_GROUP_HOLD_LAUNCH 0xa0
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OV9734_LINK_FREQ_180MHZ_INDEX,
|
OV9734_LINK_FREQ_180MHZ_INDEX,
|
||||||
};
|
};
|
||||||
@ -433,6 +439,11 @@ static int ov9734_update_digital_gain(struct ov9734 *ov9734, u32 d_gain)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = ov9734_write_reg(ov9734, OV9734_REG_GROUP_ACCESS, 1,
|
||||||
|
OV9734_GROUP_HOLD_START);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
ret = ov9734_write_reg(ov9734, OV9734_REG_MWB_R_GAIN, 2, d_gain);
|
ret = ov9734_write_reg(ov9734, OV9734_REG_MWB_R_GAIN, 2, d_gain);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -441,7 +452,18 @@ static int ov9734_update_digital_gain(struct ov9734 *ov9734, u32 d_gain)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return ov9734_write_reg(ov9734, OV9734_REG_MWB_B_GAIN, 2, d_gain);
|
ret = ov9734_write_reg(ov9734, OV9734_REG_MWB_B_GAIN, 2, d_gain);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ov9734_write_reg(ov9734, OV9734_REG_GROUP_ACCESS, 1,
|
||||||
|
OV9734_GROUP_HOLD_END);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ov9734_write_reg(ov9734, OV9734_REG_GROUP_ACCESS, 1,
|
||||||
|
OV9734_GROUP_HOLD_LAUNCH);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ov9734_test_pattern(struct ov9734 *ov9734, u32 pattern)
|
static int ov9734_test_pattern(struct ov9734 *ov9734, u32 pattern)
|
||||||
|
@ -563,7 +563,7 @@ static void tda1997x_delayed_work_enable_hpd(struct work_struct *work)
|
|||||||
delayed_work_enable_hpd);
|
delayed_work_enable_hpd);
|
||||||
struct v4l2_subdev *sd = &state->sd;
|
struct v4l2_subdev *sd = &state->sd;
|
||||||
|
|
||||||
v4l2_dbg(2, debug, sd, "%s:\n", __func__);
|
v4l2_dbg(2, debug, sd, "%s\n", __func__);
|
||||||
|
|
||||||
/* Set HPD high */
|
/* Set HPD high */
|
||||||
tda1997x_manual_hpd(sd, HPD_HIGH_OTHER);
|
tda1997x_manual_hpd(sd, HPD_HIGH_OTHER);
|
||||||
@ -1107,7 +1107,8 @@ tda1997x_detect_std(struct tda1997x_state *state,
|
|||||||
hper = io_read16(sd, REG_H_PER) & MASK_HPER;
|
hper = io_read16(sd, REG_H_PER) & MASK_HPER;
|
||||||
hsper = io_read16(sd, REG_HS_WIDTH) & MASK_HSWIDTH;
|
hsper = io_read16(sd, REG_HS_WIDTH) & MASK_HSWIDTH;
|
||||||
v4l2_dbg(1, debug, sd, "Signal Timings: %u/%u/%u\n", vper, hper, hsper);
|
v4l2_dbg(1, debug, sd, "Signal Timings: %u/%u/%u\n", vper, hper, hsper);
|
||||||
if (!vper || !hper || !hsper)
|
|
||||||
|
if (!state->input_detect[0] && !state->input_detect[1])
|
||||||
return -ENOLINK;
|
return -ENOLINK;
|
||||||
|
|
||||||
for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) {
|
for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) {
|
||||||
@ -1695,14 +1696,15 @@ static int tda1997x_query_dv_timings(struct v4l2_subdev *sd,
|
|||||||
struct v4l2_dv_timings *timings)
|
struct v4l2_dv_timings *timings)
|
||||||
{
|
{
|
||||||
struct tda1997x_state *state = to_state(sd);
|
struct tda1997x_state *state = to_state(sd);
|
||||||
|
int ret;
|
||||||
|
|
||||||
v4l_dbg(1, debug, state->client, "%s\n", __func__);
|
v4l_dbg(1, debug, state->client, "%s\n", __func__);
|
||||||
memset(timings, 0, sizeof(struct v4l2_dv_timings));
|
memset(timings, 0, sizeof(struct v4l2_dv_timings));
|
||||||
mutex_lock(&state->lock);
|
mutex_lock(&state->lock);
|
||||||
tda1997x_detect_std(state, timings);
|
ret = tda1997x_detect_std(state, timings);
|
||||||
mutex_unlock(&state->lock);
|
mutex_unlock(&state->lock);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct v4l2_subdev_video_ops tda1997x_video_ops = {
|
static const struct v4l2_subdev_video_ops tda1997x_video_ops = {
|
||||||
@ -2233,6 +2235,7 @@ static int tda1997x_core_init(struct v4l2_subdev *sd)
|
|||||||
/* get initial HDMI status */
|
/* get initial HDMI status */
|
||||||
state->hdmi_status = io_read(sd, REG_HDMI_FLAGS);
|
state->hdmi_status = io_read(sd, REG_HDMI_FLAGS);
|
||||||
|
|
||||||
|
io_write(sd, REG_EDID_ENABLE, EDID_ENABLE_A_EN | EDID_ENABLE_B_EN);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -964,7 +964,7 @@ static int tvp5150_enable(struct v4l2_subdev *sd)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable the YCbCr and clock outputs. In discrete sync mode
|
* Enable the YCbCr and clock outputs. In discrete sync mode
|
||||||
* (non-BT.656) additionally enable the the sync outputs.
|
* (non-BT.656) additionally enable the sync outputs.
|
||||||
*/
|
*/
|
||||||
switch (decoder->mbus_type) {
|
switch (decoder->mbus_type) {
|
||||||
case V4L2_MBUS_PARALLEL:
|
case V4L2_MBUS_PARALLEL:
|
||||||
|
@ -556,7 +556,7 @@ static const struct media_file_operations media_device_fops = {
|
|||||||
* sysfs
|
* sysfs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ssize_t show_model(struct device *cd,
|
static ssize_t model_show(struct device *cd,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct media_devnode *devnode = to_media_devnode(cd);
|
struct media_devnode *devnode = to_media_devnode(cd);
|
||||||
@ -565,7 +565,7 @@ static ssize_t show_model(struct device *cd,
|
|||||||
return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
|
return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
|
static DEVICE_ATTR_RO(model);
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Registration/unregistration
|
* Registration/unregistration
|
||||||
|
@ -78,27 +78,53 @@
|
|||||||
#define IVTV_PCI_ID_SONY 0x104d
|
#define IVTV_PCI_ID_SONY 0x104d
|
||||||
|
|
||||||
/* hardware flags, no gaps allowed */
|
/* hardware flags, no gaps allowed */
|
||||||
#define IVTV_HW_CX25840 (1 << 0)
|
enum ivtv_hw_bits {
|
||||||
#define IVTV_HW_SAA7115 (1 << 1)
|
IVTV_HW_BIT_CX25840,
|
||||||
#define IVTV_HW_SAA7127 (1 << 2)
|
IVTV_HW_BIT_SAA7115,
|
||||||
#define IVTV_HW_MSP34XX (1 << 3)
|
IVTV_HW_BIT_SAA7127,
|
||||||
#define IVTV_HW_TUNER (1 << 4)
|
IVTV_HW_BIT_MSP34XX,
|
||||||
#define IVTV_HW_WM8775 (1 << 5)
|
IVTV_HW_BIT_TUNER,
|
||||||
#define IVTV_HW_CS53L32A (1 << 6)
|
IVTV_HW_BIT_WM8775,
|
||||||
#define IVTV_HW_TVEEPROM (1 << 7)
|
IVTV_HW_BIT_CS53L32A,
|
||||||
#define IVTV_HW_SAA7114 (1 << 8)
|
IVTV_HW_BIT_TVEEPROM,
|
||||||
#define IVTV_HW_UPD64031A (1 << 9)
|
IVTV_HW_BIT_SAA7114,
|
||||||
#define IVTV_HW_UPD6408X (1 << 10)
|
IVTV_HW_BIT_UPD64031A,
|
||||||
#define IVTV_HW_SAA717X (1 << 11)
|
IVTV_HW_BIT_UPD6408X,
|
||||||
#define IVTV_HW_WM8739 (1 << 12)
|
IVTV_HW_BIT_SAA717X,
|
||||||
#define IVTV_HW_VP27SMPX (1 << 13)
|
IVTV_HW_BIT_WM8739,
|
||||||
#define IVTV_HW_M52790 (1 << 14)
|
IVTV_HW_BIT_VP27SMPX,
|
||||||
#define IVTV_HW_GPIO (1 << 15)
|
IVTV_HW_BIT_M52790,
|
||||||
#define IVTV_HW_I2C_IR_RX_AVER (1 << 16)
|
IVTV_HW_BIT_GPIO,
|
||||||
#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */
|
IVTV_HW_BIT_I2C_IR_RX_AVER,
|
||||||
#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
|
IVTV_HW_BIT_I2C_IR_RX_HAUP_EXT, /* External before internal */
|
||||||
#define IVTV_HW_Z8F0811_IR_HAUP (1 << 19)
|
IVTV_HW_BIT_I2C_IR_RX_HAUP_INT,
|
||||||
#define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 20)
|
IVTV_HW_BIT_Z8F0811_IR_HAUP,
|
||||||
|
IVTV_HW_BIT_I2C_IR_RX_ADAPTEC,
|
||||||
|
|
||||||
|
IVTV_HW_MAX_BITS /* Should be the last one */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IVTV_HW_CX25840 BIT(IVTV_HW_BIT_CX25840)
|
||||||
|
#define IVTV_HW_SAA7115 BIT(IVTV_HW_BIT_SAA7115)
|
||||||
|
#define IVTV_HW_SAA7127 BIT(IVTV_HW_BIT_SAA7127)
|
||||||
|
#define IVTV_HW_MSP34XX BIT(IVTV_HW_BIT_MSP34XX)
|
||||||
|
#define IVTV_HW_TUNER BIT(IVTV_HW_BIT_TUNER)
|
||||||
|
#define IVTV_HW_WM8775 BIT(IVTV_HW_BIT_WM8775)
|
||||||
|
#define IVTV_HW_CS53L32A BIT(IVTV_HW_BIT_CS53L32A)
|
||||||
|
#define IVTV_HW_TVEEPROM BIT(IVTV_HW_BIT_TVEEPROM)
|
||||||
|
#define IVTV_HW_SAA7114 BIT(IVTV_HW_BIT_SAA7114)
|
||||||
|
#define IVTV_HW_UPD64031A BIT(IVTV_HW_BIT_UPD64031A)
|
||||||
|
#define IVTV_HW_UPD6408X BIT(IVTV_HW_BIT_UPD6408X)
|
||||||
|
#define IVTV_HW_SAA717X BIT(IVTV_HW_BIT_SAA717X)
|
||||||
|
#define IVTV_HW_WM8739 BIT(IVTV_HW_BIT_WM8739)
|
||||||
|
#define IVTV_HW_VP27SMPX BIT(IVTV_HW_BIT_VP27SMPX)
|
||||||
|
#define IVTV_HW_M52790 BIT(IVTV_HW_BIT_M52790)
|
||||||
|
#define IVTV_HW_GPIO BIT(IVTV_HW_BIT_GPIO)
|
||||||
|
#define IVTV_HW_I2C_IR_RX_AVER BIT(IVTV_HW_BIT_I2C_IR_RX_AVER)
|
||||||
|
#define IVTV_HW_I2C_IR_RX_HAUP_EXT BIT(IVTV_HW_BIT_I2C_IR_RX_HAUP_EXT)
|
||||||
|
#define IVTV_HW_I2C_IR_RX_HAUP_INT BIT(IVTV_HW_BIT_I2C_IR_RX_HAUP_INT)
|
||||||
|
#define IVTV_HW_Z8F0811_IR_HAUP BIT(IVTV_HW_BIT_Z8F0811_IR_HAUP)
|
||||||
|
#define IVTV_HW_I2C_IR_RX_ADAPTEC BIT(IVTV_HW_BIT_I2C_IR_RX_ADAPTEC)
|
||||||
|
|
||||||
#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
|
#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
#define IVTV_ADAPTEC_IR_ADDR 0x6b
|
#define IVTV_ADAPTEC_IR_ADDR 0x6b
|
||||||
|
|
||||||
/* This array should match the IVTV_HW_ defines */
|
/* This array should match the IVTV_HW_ defines */
|
||||||
static const u8 hw_addrs[] = {
|
static const u8 hw_addrs[IVTV_HW_MAX_BITS] = {
|
||||||
IVTV_CX25840_I2C_ADDR,
|
IVTV_CX25840_I2C_ADDR,
|
||||||
IVTV_SAA7115_I2C_ADDR,
|
IVTV_SAA7115_I2C_ADDR,
|
||||||
IVTV_SAA7127_I2C_ADDR,
|
IVTV_SAA7127_I2C_ADDR,
|
||||||
@ -110,7 +110,7 @@ static const u8 hw_addrs[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* This array should match the IVTV_HW_ defines */
|
/* This array should match the IVTV_HW_ defines */
|
||||||
static const char * const hw_devicenames[] = {
|
static const char * const hw_devicenames[IVTV_HW_MAX_BITS] = {
|
||||||
"cx25840",
|
"cx25840",
|
||||||
"saa7115",
|
"saa7115",
|
||||||
"saa7127_auto", /* saa7127 or saa7129 */
|
"saa7127_auto", /* saa7127 or saa7129 */
|
||||||
@ -240,10 +240,16 @@ void ivtv_i2c_new_ir_legacy(struct ivtv *itv)
|
|||||||
|
|
||||||
int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
|
int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
|
||||||
{
|
{
|
||||||
struct v4l2_subdev *sd;
|
|
||||||
struct i2c_adapter *adap = &itv->i2c_adap;
|
struct i2c_adapter *adap = &itv->i2c_adap;
|
||||||
const char *type = hw_devicenames[idx];
|
struct v4l2_subdev *sd;
|
||||||
u32 hw = 1 << idx;
|
const char *type;
|
||||||
|
u32 hw;
|
||||||
|
|
||||||
|
if (idx >= IVTV_HW_MAX_BITS)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
type = hw_devicenames[idx];
|
||||||
|
hw = 1 << idx;
|
||||||
|
|
||||||
if (hw == IVTV_HW_TUNER) {
|
if (hw == IVTV_HW_TUNER) {
|
||||||
/* special tuner handling */
|
/* special tuner handling */
|
||||||
|
@ -1215,15 +1215,13 @@ static int alsa_device_exit(struct saa7134_dev *dev)
|
|||||||
static int saa7134_alsa_init(void)
|
static int saa7134_alsa_init(void)
|
||||||
{
|
{
|
||||||
struct saa7134_dev *dev = NULL;
|
struct saa7134_dev *dev = NULL;
|
||||||
struct list_head *list;
|
|
||||||
|
|
||||||
saa7134_dmasound_init = alsa_device_init;
|
saa7134_dmasound_init = alsa_device_init;
|
||||||
saa7134_dmasound_exit = alsa_device_exit;
|
saa7134_dmasound_exit = alsa_device_exit;
|
||||||
|
|
||||||
pr_info("saa7134 ALSA driver for DMA sound loaded\n");
|
pr_info("saa7134 ALSA driver for DMA sound loaded\n");
|
||||||
|
|
||||||
list_for_each(list,&saa7134_devlist) {
|
list_for_each_entry(dev, &saa7134_devlist, devlist) {
|
||||||
dev = list_entry(list, struct saa7134_dev, devlist);
|
|
||||||
if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
|
if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
|
||||||
pr_info("%s/alsa: %s doesn't support digital audio\n",
|
pr_info("%s/alsa: %s doesn't support digital audio\n",
|
||||||
dev->name, saa7134_boards[dev->board].name);
|
dev->name, saa7134_boards[dev->board].name);
|
||||||
|
@ -223,7 +223,8 @@ int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
|
|||||||
__le32 *cpu;
|
__le32 *cpu;
|
||||||
dma_addr_t dma_addr = 0;
|
dma_addr_t dma_addr = 0;
|
||||||
|
|
||||||
cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
|
cpu = dma_alloc_coherent(&pci->dev, SAA7134_PGTABLE_SIZE, &dma_addr,
|
||||||
|
GFP_KERNEL);
|
||||||
if (NULL == cpu)
|
if (NULL == cpu)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
pt->size = SAA7134_PGTABLE_SIZE;
|
pt->size = SAA7134_PGTABLE_SIZE;
|
||||||
@ -254,7 +255,7 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
|
|||||||
{
|
{
|
||||||
if (NULL == pt->cpu)
|
if (NULL == pt->cpu)
|
||||||
return;
|
return;
|
||||||
pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
|
dma_free_coherent(&pci->dev, pt->size, pt->cpu, pt->dma);
|
||||||
pt->cpu = NULL;
|
pt->cpu = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1092,7 +1093,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev,
|
|||||||
dev->pci_lat,
|
dev->pci_lat,
|
||||||
(unsigned long long)pci_resource_start(pci_dev, 0));
|
(unsigned long long)pci_resource_start(pci_dev, 0));
|
||||||
pci_set_master(pci_dev);
|
pci_set_master(pci_dev);
|
||||||
err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
|
err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_warn("%s: Oops: no 32bit PCI DMA ???\n", dev->name);
|
pr_warn("%s: Oops: no 32bit PCI DMA ???\n", dev->name);
|
||||||
goto err_v4l2_unregister;
|
goto err_v4l2_unregister;
|
||||||
|
@ -549,9 +549,6 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
|
|||||||
/* See of other commands are on the bus */
|
/* See of other commands are on the bus */
|
||||||
if (saa7164_cmd_dequeue(dev) != SAA_OK)
|
if (saa7164_cmd_dequeue(dev) != SAA_OK)
|
||||||
printk(KERN_ERR "dequeue(3) failed\n");
|
printk(KERN_ERR "dequeue(3) failed\n");
|
||||||
|
|
||||||
continue;
|
|
||||||
|
|
||||||
} /* (loop) */
|
} /* (loop) */
|
||||||
|
|
||||||
/* Release the sequence number allocation */
|
/* Release the sequence number allocation */
|
||||||
|
@ -663,7 +663,7 @@
|
|||||||
#define TW5864_SYNC 0x8008
|
#define TW5864_SYNC 0x8008
|
||||||
/* Define controls in register TW5864_SYNC */
|
/* Define controls in register TW5864_SYNC */
|
||||||
/*
|
/*
|
||||||
* 0 vlc stream to syncrous port
|
* 0 vlc stream to synchronous port
|
||||||
* 1 vlc stream to ddr buffers
|
* 1 vlc stream to ddr buffers
|
||||||
*/
|
*/
|
||||||
#define TW5864_SYNC_CFG BIT(7)
|
#define TW5864_SYNC_CFG BIT(7)
|
||||||
|
@ -255,6 +255,23 @@ static void isc_sama5d2_config_rlp(struct isc_device *isc)
|
|||||||
struct regmap *regmap = isc->regmap;
|
struct regmap *regmap = isc->regmap;
|
||||||
u32 rlp_mode = isc->config.rlp_cfg_mode;
|
u32 rlp_mode = isc->config.rlp_cfg_mode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In sama5d2, the YUV planar modes and the YUYV modes are treated
|
||||||
|
* in the same way in RLP register.
|
||||||
|
* Normally, YYCC mode should be Luma(n) - Color B(n) - Color R (n)
|
||||||
|
* and YCYC should be Luma(n + 1) - Color B (n) - Luma (n) - Color R (n)
|
||||||
|
* but in sama5d2, the YCYC mode does not exist, and YYCC must be
|
||||||
|
* selected for both planar and interleaved modes, as in fact
|
||||||
|
* both modes are supported.
|
||||||
|
*
|
||||||
|
* Thus, if the YCYC mode is selected, replace it with the
|
||||||
|
* sama5d2-compliant mode which is YYCC .
|
||||||
|
*/
|
||||||
|
if ((rlp_mode & ISC_RLP_CFG_MODE_YCYC) == ISC_RLP_CFG_MODE_YCYC) {
|
||||||
|
rlp_mode &= ~ISC_RLP_CFG_MODE_MASK;
|
||||||
|
rlp_mode |= ISC_RLP_CFG_MODE_YYCC;
|
||||||
|
}
|
||||||
|
|
||||||
regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp,
|
regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp,
|
||||||
ISC_RLP_CFG_MODE_MASK, rlp_mode);
|
ISC_RLP_CFG_MODE_MASK, rlp_mode);
|
||||||
}
|
}
|
||||||
|
@ -2053,17 +2053,25 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
|
|||||||
u32 src_fourcc, dst_fourcc;
|
u32 src_fourcc, dst_fourcc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!ctx->initialized) {
|
|
||||||
ret = __coda_decoder_seq_init(ctx);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
||||||
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||||
src_fourcc = q_data_src->fourcc;
|
src_fourcc = q_data_src->fourcc;
|
||||||
dst_fourcc = q_data_dst->fourcc;
|
dst_fourcc = q_data_dst->fourcc;
|
||||||
|
|
||||||
|
if (!ctx->initialized) {
|
||||||
|
ret = __coda_decoder_seq_init(ctx);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
ctx->frame_mem_ctrl &= ~(CODA_FRAME_CHROMA_INTERLEAVE | (0x3 << 9) |
|
||||||
|
CODA9_FRAME_TILED2LINEAR);
|
||||||
|
if (dst_fourcc == V4L2_PIX_FMT_NV12 || dst_fourcc == V4L2_PIX_FMT_YUYV)
|
||||||
|
ctx->frame_mem_ctrl |= CODA_FRAME_CHROMA_INTERLEAVE;
|
||||||
|
if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP)
|
||||||
|
ctx->frame_mem_ctrl |= (0x3 << 9) |
|
||||||
|
((ctx->use_vdoa) ? 0 : CODA9_FRAME_TILED2LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
|
coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
|
||||||
|
|
||||||
ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc);
|
ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc);
|
||||||
|
@ -189,7 +189,7 @@ int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev)
|
|||||||
if (!ccdc_cfg) {
|
if (!ccdc_cfg) {
|
||||||
/*
|
/*
|
||||||
* TODO. Will this ever happen? if so, we need to fix it.
|
* TODO. Will this ever happen? if so, we need to fix it.
|
||||||
* Proabably we need to add the request to a linked list and
|
* Probably we need to add the request to a linked list and
|
||||||
* walk through it during vpfe probe
|
* walk through it during vpfe probe
|
||||||
*/
|
*/
|
||||||
printk(KERN_ERR "vpfe capture not initialized\n");
|
printk(KERN_ERR "vpfe capture not initialized\n");
|
||||||
|
@ -1238,8 +1238,8 @@ static const struct media_device_ops fimc_md_ops = {
|
|||||||
.link_notify = fimc_md_link_notify,
|
.link_notify = fimc_md_link_notify,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t fimc_md_sysfs_show(struct device *dev,
|
static ssize_t subdev_conf_mode_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct fimc_md *fmd = dev_get_drvdata(dev);
|
struct fimc_md *fmd = dev_get_drvdata(dev);
|
||||||
|
|
||||||
@ -1249,9 +1249,9 @@ static ssize_t fimc_md_sysfs_show(struct device *dev,
|
|||||||
return strscpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
|
return strscpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t fimc_md_sysfs_store(struct device *dev,
|
static ssize_t subdev_conf_mode_store(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct fimc_md *fmd = dev_get_drvdata(dev);
|
struct fimc_md *fmd = dev_get_drvdata(dev);
|
||||||
bool subdev_api;
|
bool subdev_api;
|
||||||
@ -1278,8 +1278,7 @@ static ssize_t fimc_md_sysfs_store(struct device *dev,
|
|||||||
* sub-dev - for media controller API, subdevs must be configured in user
|
* sub-dev - for media controller API, subdevs must be configured in user
|
||||||
* space before starting streaming.
|
* space before starting streaming.
|
||||||
*/
|
*/
|
||||||
static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
|
static DEVICE_ATTR_RW(subdev_conf_mode);
|
||||||
fimc_md_sysfs_show, fimc_md_sysfs_store);
|
|
||||||
|
|
||||||
static int cam_clk_prepare(struct clk_hw *hw)
|
static int cam_clk_prepare(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
|
@ -692,7 +692,7 @@ static void mcam_dma_sg_done(struct mcam_camera *cam, int frame)
|
|||||||
* Scatter/gather mode requires stopping the controller between
|
* Scatter/gather mode requires stopping the controller between
|
||||||
* frames so we can put in a new DMA descriptor array. If no new
|
* frames so we can put in a new DMA descriptor array. If no new
|
||||||
* buffer exists at frame completion, the controller is left stopped;
|
* buffer exists at frame completion, the controller is left stopped;
|
||||||
* this function is charged with gettig things going again.
|
* this function is charged with getting things going again.
|
||||||
*/
|
*/
|
||||||
static void mcam_sg_restart(struct mcam_camera *cam)
|
static void mcam_sg_restart(struct mcam_camera *cam)
|
||||||
{
|
{
|
||||||
|
@ -2037,8 +2037,10 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
|
|||||||
mutex_lock(&isp->media_dev.graph_mutex);
|
mutex_lock(&isp->media_dev.graph_mutex);
|
||||||
|
|
||||||
ret = media_entity_enum_init(&isp->crashed, &isp->media_dev);
|
ret = media_entity_enum_init(&isp->crashed, &isp->media_dev);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
mutex_unlock(&isp->media_dev.graph_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
|
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
|
||||||
if (sd->notifier != &isp->notifier)
|
if (sd->notifier != &isp->notifier)
|
||||||
|
@ -234,6 +234,7 @@ struct venc_controls {
|
|||||||
u32 h264_loop_filter_mode;
|
u32 h264_loop_filter_mode;
|
||||||
s32 h264_loop_filter_alpha;
|
s32 h264_loop_filter_alpha;
|
||||||
s32 h264_loop_filter_beta;
|
s32 h264_loop_filter_beta;
|
||||||
|
u32 h264_8x8_transform;
|
||||||
|
|
||||||
u32 hevc_i_qp;
|
u32 hevc_i_qp;
|
||||||
u32 hevc_p_qp;
|
u32 hevc_p_qp;
|
||||||
@ -256,6 +257,7 @@ struct venc_controls {
|
|||||||
|
|
||||||
u32 header_mode;
|
u32 header_mode;
|
||||||
bool aud_enable;
|
bool aud_enable;
|
||||||
|
u32 intra_refresh_period;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u32 h264;
|
u32 h264;
|
||||||
|
@ -1137,6 +1137,9 @@ int venus_helper_set_format_constraints(struct venus_inst *inst)
|
|||||||
if (!IS_V6(inst->core))
|
if (!IS_V6(inst->core))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (inst->opb_fmt == HFI_COLOR_FORMAT_NV12_UBWC)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
|
pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
|
||||||
pconstraint.num_planes = 2;
|
pconstraint.num_planes = 2;
|
||||||
pconstraint.plane_format[0].stride_multiples = 128;
|
pconstraint.plane_format[0].stride_multiples = 128;
|
||||||
|
@ -1239,6 +1239,14 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case HFI_PROPERTY_PARAM_VENC_H264_TRANSFORM_8X8: {
|
||||||
|
struct hfi_h264_8x8_transform *in = pdata, *tm = prop_data;
|
||||||
|
|
||||||
|
tm->enable_type = in->enable_type;
|
||||||
|
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*tm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
|
case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
|
||||||
case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
|
case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
|
||||||
case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE:
|
case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE:
|
||||||
|
@ -507,6 +507,7 @@
|
|||||||
#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
|
#define HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES 0x2005020
|
||||||
#define HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC 0x2005021
|
#define HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC 0x2005021
|
||||||
#define HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY 0x2005023
|
#define HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY 0x2005023
|
||||||
|
#define HFI_PROPERTY_PARAM_VENC_H264_TRANSFORM_8X8 0x2005025
|
||||||
#define HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER 0x2005026
|
#define HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER 0x2005026
|
||||||
#define HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP 0x2005027
|
#define HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP 0x2005027
|
||||||
#define HFI_PROPERTY_PARAM_VENC_INITIAL_QP 0x2005028
|
#define HFI_PROPERTY_PARAM_VENC_INITIAL_QP 0x2005028
|
||||||
@ -562,6 +563,10 @@ struct hfi_bitrate {
|
|||||||
u32 layer_id;
|
u32 layer_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hfi_h264_8x8_transform {
|
||||||
|
u32 enable_type;
|
||||||
|
};
|
||||||
|
|
||||||
#define HFI_CAPABILITY_FRAME_WIDTH 0x01
|
#define HFI_CAPABILITY_FRAME_WIDTH 0x01
|
||||||
#define HFI_CAPABILITY_FRAME_HEIGHT 0x02
|
#define HFI_CAPABILITY_FRAME_HEIGHT 0x02
|
||||||
#define HFI_CAPABILITY_MBS_PER_FRAME 0x03
|
#define HFI_CAPABILITY_MBS_PER_FRAME 0x03
|
||||||
|
@ -261,7 +261,7 @@ sys_get_prop_image_version(struct device *dev,
|
|||||||
|
|
||||||
smem_tbl_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY,
|
smem_tbl_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY,
|
||||||
SMEM_IMG_VER_TBL, &smem_blk_sz);
|
SMEM_IMG_VER_TBL, &smem_blk_sz);
|
||||||
if (smem_tbl_ptr && smem_blk_sz >= SMEM_IMG_OFFSET_VENUS + VER_STR_SZ)
|
if (!IS_ERR(smem_tbl_ptr) && smem_blk_sz >= SMEM_IMG_OFFSET_VENUS + VER_STR_SZ)
|
||||||
memcpy(smem_tbl_ptr + SMEM_IMG_OFFSET_VENUS,
|
memcpy(smem_tbl_ptr + SMEM_IMG_OFFSET_VENUS,
|
||||||
img_ver, VER_STR_SZ);
|
img_ver, VER_STR_SZ);
|
||||||
}
|
}
|
||||||
|
@ -183,6 +183,8 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
|
|||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
fmt = find_format(inst, pixmp->pixelformat, f->type);
|
fmt = find_format(inst, pixmp->pixelformat, f->type);
|
||||||
|
if (!fmt)
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixmp->width = clamp(pixmp->width, frame_width_min(inst),
|
pixmp->width = clamp(pixmp->width, frame_width_min(inst),
|
||||||
@ -547,6 +549,7 @@ static int venc_set_properties(struct venus_inst *inst)
|
|||||||
struct hfi_quantization_range quant_range;
|
struct hfi_quantization_range quant_range;
|
||||||
struct hfi_enable en;
|
struct hfi_enable en;
|
||||||
struct hfi_ltr_mode ltr_mode;
|
struct hfi_ltr_mode ltr_mode;
|
||||||
|
struct hfi_intra_refresh intra_refresh = {};
|
||||||
u32 ptype, rate_control, bitrate;
|
u32 ptype, rate_control, bitrate;
|
||||||
u32 profile, level;
|
u32 profile, level;
|
||||||
int ret;
|
int ret;
|
||||||
@ -567,6 +570,7 @@ static int venc_set_properties(struct venus_inst *inst)
|
|||||||
struct hfi_h264_vui_timing_info info;
|
struct hfi_h264_vui_timing_info info;
|
||||||
struct hfi_h264_entropy_control entropy;
|
struct hfi_h264_entropy_control entropy;
|
||||||
struct hfi_h264_db_control deblock;
|
struct hfi_h264_db_control deblock;
|
||||||
|
struct hfi_h264_8x8_transform h264_transform;
|
||||||
|
|
||||||
ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
|
ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
|
||||||
info.enable = 1;
|
info.enable = 1;
|
||||||
@ -597,6 +601,17 @@ static int venc_set_properties(struct venus_inst *inst)
|
|||||||
ret = hfi_session_set_property(inst, ptype, &deblock);
|
ret = hfi_session_set_property(inst, ptype, &deblock);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ptype = HFI_PROPERTY_PARAM_VENC_H264_TRANSFORM_8X8;
|
||||||
|
h264_transform.enable_type = 0;
|
||||||
|
if (ctr->profile.h264 == HFI_H264_PROFILE_HIGH ||
|
||||||
|
ctr->profile.h264 == HFI_H264_PROFILE_CONSTRAINED_HIGH)
|
||||||
|
h264_transform.enable_type = ctr->h264_8x8_transform;
|
||||||
|
|
||||||
|
ret = hfi_session_set_property(inst, ptype, &h264_transform);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 ||
|
if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 ||
|
||||||
@ -802,6 +817,31 @@ static int venc_set_properties(struct venus_inst *inst)
|
|||||||
en.enable = 1;
|
en.enable = 1;
|
||||||
|
|
||||||
ret = hfi_session_set_property(inst, ptype, &en);
|
ret = hfi_session_set_property(inst, ptype, &en);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 ||
|
||||||
|
inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) &&
|
||||||
|
(rate_control == HFI_RATE_CONTROL_CBR_VFR ||
|
||||||
|
rate_control == HFI_RATE_CONTROL_CBR_CFR)) {
|
||||||
|
intra_refresh.mode = HFI_INTRA_REFRESH_NONE;
|
||||||
|
intra_refresh.cir_mbs = 0;
|
||||||
|
|
||||||
|
if (ctr->intra_refresh_period) {
|
||||||
|
u32 mbs;
|
||||||
|
|
||||||
|
mbs = ALIGN(inst->width, 16) * ALIGN(inst->height, 16);
|
||||||
|
mbs /= 16 * 16;
|
||||||
|
if (mbs % ctr->intra_refresh_period)
|
||||||
|
mbs++;
|
||||||
|
mbs /= ctr->intra_refresh_period;
|
||||||
|
|
||||||
|
intra_refresh.mode = HFI_INTRA_REFRESH_RANDOM;
|
||||||
|
intra_refresh.cir_mbs = mbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptype = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
|
||||||
|
|
||||||
|
ret = hfi_session_set_property(inst, ptype, &intra_refresh);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#define SLICE_BYTE_SIZE_MAX 1024
|
#define SLICE_BYTE_SIZE_MAX 1024
|
||||||
#define SLICE_BYTE_SIZE_MIN 1024
|
#define SLICE_BYTE_SIZE_MIN 1024
|
||||||
#define SLICE_MB_SIZE_MAX 300
|
#define SLICE_MB_SIZE_MAX 300
|
||||||
#define INTRA_REFRESH_MBS_MAX 300
|
|
||||||
#define AT_SLICE_BOUNDARY \
|
#define AT_SLICE_BOUNDARY \
|
||||||
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
|
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
|
||||||
#define MAX_LTR_FRAME_COUNT 4
|
#define MAX_LTR_FRAME_COUNT 4
|
||||||
@ -227,8 +226,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||||||
}
|
}
|
||||||
mutex_unlock(&inst->lock);
|
mutex_unlock(&inst->lock);
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
|
|
||||||
break;
|
|
||||||
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
|
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
|
||||||
ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
|
ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
|
||||||
&ctr->num_p_frames);
|
&ctr->num_p_frames);
|
||||||
@ -319,6 +316,28 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||||||
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:
|
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:
|
||||||
ctr->mastering = *ctrl->p_new.p_hdr10_mastering;
|
ctr->mastering = *ctrl->p_new.p_hdr10_mastering;
|
||||||
break;
|
break;
|
||||||
|
case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD:
|
||||||
|
ctr->intra_refresh_period = ctrl->val;
|
||||||
|
break;
|
||||||
|
case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
|
||||||
|
if (ctr->profile.h264 != HFI_H264_PROFILE_HIGH &&
|
||||||
|
ctr->profile.h264 != HFI_H264_PROFILE_CONSTRAINED_HIGH)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In video firmware, 8x8 transform is supported only for
|
||||||
|
* high profile(HP) and constrained high profile(CHP).
|
||||||
|
* If client wants to disable 8x8 transform for HP/CHP,
|
||||||
|
* it is better to set profile as main profile(MP).
|
||||||
|
* Because there is no difference between HP and MP
|
||||||
|
* if we disable 8x8 transform for HP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ctrl->val == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ctr->h264_8x8_transform = ctrl->val;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -334,7 +353,7 @@ int venc_ctrl_init(struct venus_inst *inst)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 57);
|
ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 58);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -437,6 +456,9 @@ int venc_ctrl_init(struct venus_inst *inst)
|
|||||||
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
||||||
V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP, 1, 51, 1, 1);
|
V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP, 1, 51, 1, 1);
|
||||||
|
|
||||||
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
||||||
|
V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, 0, 1, 1, 0);
|
||||||
|
|
||||||
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
||||||
V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP, 1, 51, 1, 1);
|
V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP, 1, 51, 1, 1);
|
||||||
|
|
||||||
@ -502,10 +524,6 @@ int venc_ctrl_init(struct venus_inst *inst)
|
|||||||
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
||||||
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0);
|
V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0);
|
||||||
|
|
||||||
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
|
||||||
V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
|
|
||||||
0, INTRA_REFRESH_MBS_MAX, 1, 0);
|
|
||||||
|
|
||||||
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
||||||
V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
|
V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
|
||||||
|
|
||||||
@ -564,6 +582,10 @@ int venc_ctrl_init(struct venus_inst *inst)
|
|||||||
V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY,
|
V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY,
|
||||||
v4l2_ctrl_ptr_create(NULL));
|
v4l2_ctrl_ptr_create(NULL));
|
||||||
|
|
||||||
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
|
||||||
|
V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD, 0,
|
||||||
|
((4096 * 2304) >> 8), 1, 0);
|
||||||
|
|
||||||
ret = inst->ctrl_handler.error;
|
ret = inst->ctrl_handler.error;
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -253,8 +253,8 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sd_state = v4l2_subdev_alloc_state(sd);
|
sd_state = v4l2_subdev_alloc_state(sd);
|
||||||
if (sd_state == NULL)
|
if (IS_ERR(sd_state))
|
||||||
return -ENOMEM;
|
return PTR_ERR(sd_state);
|
||||||
|
|
||||||
if (!rvin_format_from_pixel(vin, pix->pixelformat))
|
if (!rvin_format_from_pixel(vin, pix->pixelformat))
|
||||||
pix->pixelformat = RVIN_DEFAULT_FORMAT;
|
pix->pixelformat = RVIN_DEFAULT_FORMAT;
|
||||||
|
@ -863,12 +863,12 @@ static int rga_probe(struct platform_device *pdev)
|
|||||||
if (IS_ERR(rga->m2m_dev)) {
|
if (IS_ERR(rga->m2m_dev)) {
|
||||||
v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n");
|
v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n");
|
||||||
ret = PTR_ERR(rga->m2m_dev);
|
ret = PTR_ERR(rga->m2m_dev);
|
||||||
goto unreg_video_dev;
|
goto rel_vdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pm_runtime_resume_and_get(rga->dev);
|
ret = pm_runtime_resume_and_get(rga->dev);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto unreg_video_dev;
|
goto rel_vdev;
|
||||||
|
|
||||||
rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
|
rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
|
||||||
rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
|
rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
|
||||||
@ -882,11 +882,23 @@ static int rga_probe(struct platform_device *pdev)
|
|||||||
rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE,
|
rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE,
|
||||||
&rga->cmdbuf_phy, GFP_KERNEL,
|
&rga->cmdbuf_phy, GFP_KERNEL,
|
||||||
DMA_ATTR_WRITE_COMBINE);
|
DMA_ATTR_WRITE_COMBINE);
|
||||||
|
if (!rga->cmdbuf_virt) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto rel_vdev;
|
||||||
|
}
|
||||||
|
|
||||||
rga->src_mmu_pages =
|
rga->src_mmu_pages =
|
||||||
(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
|
(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
|
||||||
|
if (!rga->src_mmu_pages) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto free_dma;
|
||||||
|
}
|
||||||
rga->dst_mmu_pages =
|
rga->dst_mmu_pages =
|
||||||
(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
|
(unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
|
||||||
|
if (rga->dst_mmu_pages) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto free_src_pages;
|
||||||
|
}
|
||||||
|
|
||||||
def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
|
def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
|
||||||
def_frame.size = def_frame.stride * def_frame.height;
|
def_frame.size = def_frame.stride * def_frame.height;
|
||||||
@ -894,7 +906,7 @@ static int rga_probe(struct platform_device *pdev)
|
|||||||
ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
|
ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
|
v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
|
||||||
goto rel_vdev;
|
goto free_dst_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n",
|
v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n",
|
||||||
@ -902,10 +914,15 @@ static int rga_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
free_dst_pages:
|
||||||
|
free_pages((unsigned long)rga->dst_mmu_pages, 3);
|
||||||
|
free_src_pages:
|
||||||
|
free_pages((unsigned long)rga->src_mmu_pages, 3);
|
||||||
|
free_dma:
|
||||||
|
dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt,
|
||||||
|
rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
|
||||||
rel_vdev:
|
rel_vdev:
|
||||||
video_device_release(vfd);
|
video_device_release(vfd);
|
||||||
unreg_video_dev:
|
|
||||||
video_unregister_device(rga->vfd);
|
|
||||||
unreg_v4l2_dev:
|
unreg_v4l2_dev:
|
||||||
v4l2_device_unregister(&rga->v4l2_dev);
|
v4l2_device_unregister(&rga->v4l2_dev);
|
||||||
err_put_clk:
|
err_put_clk:
|
||||||
|
@ -750,7 +750,7 @@ static int rkisp1_vb2_queue_setup(struct vb2_queue *queue,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
|
static int rkisp1_vb2_buf_init(struct vb2_buffer *vb)
|
||||||
{
|
{
|
||||||
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||||
struct rkisp1_buffer *ispbuf =
|
struct rkisp1_buffer *ispbuf =
|
||||||
@ -780,6 +780,15 @@ static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
|
|||||||
if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap)
|
if (cap->pix.info->comp_planes == 3 && cap->pix.cfg->uv_swap)
|
||||||
swap(ispbuf->buff_addr[RKISP1_PLANE_CR],
|
swap(ispbuf->buff_addr[RKISP1_PLANE_CR],
|
||||||
ispbuf->buff_addr[RKISP1_PLANE_CB]);
|
ispbuf->buff_addr[RKISP1_PLANE_CB]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rkisp1_vb2_buf_queue(struct vb2_buffer *vb)
|
||||||
|
{
|
||||||
|
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
||||||
|
struct rkisp1_buffer *ispbuf =
|
||||||
|
container_of(vbuf, struct rkisp1_buffer, vb);
|
||||||
|
struct rkisp1_capture *cap = vb->vb2_queue->drv_priv;
|
||||||
|
|
||||||
spin_lock_irq(&cap->buf.lock);
|
spin_lock_irq(&cap->buf.lock);
|
||||||
list_add_tail(&ispbuf->queue, &cap->buf.queue);
|
list_add_tail(&ispbuf->queue, &cap->buf.queue);
|
||||||
@ -1039,6 +1048,7 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
|
|||||||
|
|
||||||
static const struct vb2_ops rkisp1_vb2_ops = {
|
static const struct vb2_ops rkisp1_vb2_ops = {
|
||||||
.queue_setup = rkisp1_vb2_queue_setup,
|
.queue_setup = rkisp1_vb2_queue_setup,
|
||||||
|
.buf_init = rkisp1_vb2_buf_init,
|
||||||
.buf_queue = rkisp1_vb2_buf_queue,
|
.buf_queue = rkisp1_vb2_buf_queue,
|
||||||
.buf_prepare = rkisp1_vb2_buf_prepare,
|
.buf_prepare = rkisp1_vb2_buf_prepare,
|
||||||
.wait_prepare = vb2_ops_wait_prepare,
|
.wait_prepare = vb2_ops_wait_prepare,
|
||||||
|
@ -156,15 +156,11 @@ struct rkisp1_vdev_node {
|
|||||||
* @vb: vb2 buffer
|
* @vb: vb2 buffer
|
||||||
* @queue: entry of the buffer in the queue
|
* @queue: entry of the buffer in the queue
|
||||||
* @buff_addr: dma addresses of each plane, used only by the capture devices: selfpath, mainpath
|
* @buff_addr: dma addresses of each plane, used only by the capture devices: selfpath, mainpath
|
||||||
* @vaddr: virtual address for buffers used by params and stats devices
|
|
||||||
*/
|
*/
|
||||||
struct rkisp1_buffer {
|
struct rkisp1_buffer {
|
||||||
struct vb2_v4l2_buffer vb;
|
struct vb2_v4l2_buffer vb;
|
||||||
struct list_head queue;
|
struct list_head queue;
|
||||||
union {
|
u32 buff_addr[VIDEO_MAX_PLANES];
|
||||||
u32 buff_addr[VIDEO_MAX_PLANES];
|
|
||||||
void *vaddr;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1143,7 +1143,7 @@ static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params,
|
|||||||
cur_buf = list_first_entry(¶ms->params,
|
cur_buf = list_first_entry(¶ms->params,
|
||||||
struct rkisp1_buffer, queue);
|
struct rkisp1_buffer, queue);
|
||||||
|
|
||||||
new_params = (struct rkisp1_params_cfg *)(cur_buf->vaddr);
|
new_params = (struct rkisp1_params_cfg *)vb2_plane_vaddr(&cur_buf->vb.vb2_buf, 0);
|
||||||
|
|
||||||
rkisp1_isp_isr_other_config(params, new_params);
|
rkisp1_isp_isr_other_config(params, new_params);
|
||||||
rkisp1_isp_isr_meas_config(params, new_params);
|
rkisp1_isp_isr_meas_config(params, new_params);
|
||||||
@ -1382,7 +1382,6 @@ static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb)
|
|||||||
struct vb2_queue *vq = vb->vb2_queue;
|
struct vb2_queue *vq = vb->vb2_queue;
|
||||||
struct rkisp1_params *params = vq->drv_priv;
|
struct rkisp1_params *params = vq->drv_priv;
|
||||||
|
|
||||||
params_buf->vaddr = vb2_plane_vaddr(vb, 0);
|
|
||||||
spin_lock_irq(¶ms->config_lock);
|
spin_lock_irq(¶ms->config_lock);
|
||||||
list_add_tail(¶ms_buf->queue, ¶ms->params);
|
list_add_tail(¶ms_buf->queue, ¶ms->params);
|
||||||
spin_unlock_irq(¶ms->config_lock);
|
spin_unlock_irq(¶ms->config_lock);
|
||||||
|
@ -112,7 +112,6 @@ static void rkisp1_stats_vb2_buf_queue(struct vb2_buffer *vb)
|
|||||||
struct vb2_queue *vq = vb->vb2_queue;
|
struct vb2_queue *vq = vb->vb2_queue;
|
||||||
struct rkisp1_stats *stats_dev = vq->drv_priv;
|
struct rkisp1_stats *stats_dev = vq->drv_priv;
|
||||||
|
|
||||||
stats_buf->vaddr = vb2_plane_vaddr(vb, 0);
|
|
||||||
|
|
||||||
spin_lock_irq(&stats_dev->lock);
|
spin_lock_irq(&stats_dev->lock);
|
||||||
list_add_tail(&stats_buf->queue, &stats_dev->stat);
|
list_add_tail(&stats_buf->queue, &stats_dev->stat);
|
||||||
@ -305,9 +304,8 @@ rkisp1_stats_send_measurement(struct rkisp1_stats *stats, u32 isp_ris)
|
|||||||
if (!cur_buf)
|
if (!cur_buf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cur_stat_buf =
|
cur_stat_buf = (struct rkisp1_stat_buffer *)
|
||||||
(struct rkisp1_stat_buffer *)(cur_buf->vaddr);
|
vb2_plane_vaddr(&cur_buf->vb.vb2_buf, 0);
|
||||||
|
|
||||||
if (isp_ris & RKISP1_CIF_ISP_AWB_DONE)
|
if (isp_ris & RKISP1_CIF_ISP_AWB_DONE)
|
||||||
rkisp1_stats_get_awb_meas(stats, cur_stat_buf);
|
rkisp1_stats_get_awb_meas(stats, cur_stat_buf);
|
||||||
|
|
||||||
|
@ -1418,7 +1418,7 @@ static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev)
|
|||||||
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
|
if (test_and_clear_bit(0, &dev->hw_lock) == 0)
|
||||||
mfc_err("Failed to unlock hardware\n");
|
mfc_err("Failed to unlock hardware\n");
|
||||||
|
|
||||||
/* This is in deed imporant, as no operation has been
|
/* This is indeed important, as no operation has been
|
||||||
* scheduled, reduce the clock count as no one will
|
* scheduled, reduce the clock count as no one will
|
||||||
* ever do this, because no interrupt related to this try_run
|
* ever do this, because no interrupt related to this try_run
|
||||||
* will ever come from hardware. */
|
* will ever come from hardware. */
|
||||||
|
@ -175,8 +175,7 @@ int delta_ipc_open(struct delta_ctx *pctx, const char *name,
|
|||||||
msg.ipc_buf_size = ipc_buf_size;
|
msg.ipc_buf_size = ipc_buf_size;
|
||||||
msg.ipc_buf_paddr = ctx->ipc_buf->paddr;
|
msg.ipc_buf_paddr = ctx->ipc_buf->paddr;
|
||||||
|
|
||||||
memcpy(msg.name, name, sizeof(msg.name));
|
strscpy(msg.name, name, sizeof(msg.name));
|
||||||
msg.name[sizeof(msg.name) - 1] = 0;
|
|
||||||
|
|
||||||
msg.param_size = param->size;
|
msg.param_size = param->size;
|
||||||
memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size);
|
memcpy(ctx->ipc_buf->vaddr, param->data, msg.param_size);
|
||||||
|
@ -45,22 +45,30 @@ static inline void camerarx_write(struct cal_camerarx *phy, u32 offset, u32 val)
|
|||||||
* ------------------------------------------------------------------
|
* ------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static s64 cal_camerarx_get_external_rate(struct cal_camerarx *phy)
|
static s64 cal_camerarx_get_ext_link_freq(struct cal_camerarx *phy)
|
||||||
{
|
{
|
||||||
struct v4l2_ctrl *ctrl;
|
struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 = &phy->endpoint.bus.mipi_csi2;
|
||||||
s64 rate;
|
u32 num_lanes = mipi_csi2->num_data_lanes;
|
||||||
|
const struct cal_format_info *fmtinfo;
|
||||||
|
u32 bpp;
|
||||||
|
s64 freq;
|
||||||
|
|
||||||
ctrl = v4l2_ctrl_find(phy->sensor->ctrl_handler, V4L2_CID_PIXEL_RATE);
|
fmtinfo = cal_format_by_code(phy->formats[CAL_CAMERARX_PAD_SINK].code);
|
||||||
if (!ctrl) {
|
if (!fmtinfo)
|
||||||
phy_err(phy, "no pixel rate control in subdev: %s\n",
|
return -EINVAL;
|
||||||
phy->sensor->name);
|
|
||||||
return -EPIPE;
|
bpp = fmtinfo->bpp;
|
||||||
|
|
||||||
|
freq = v4l2_get_link_freq(phy->source->ctrl_handler, bpp, 2 * num_lanes);
|
||||||
|
if (freq < 0) {
|
||||||
|
phy_err(phy, "failed to get link freq for subdev '%s'\n",
|
||||||
|
phy->source->name);
|
||||||
|
return freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
rate = v4l2_ctrl_g_ctrl_int64(ctrl);
|
phy_dbg(3, phy, "Source Link Freq: %llu\n", freq);
|
||||||
phy_dbg(3, phy, "sensor Pixel Rate: %llu\n", rate);
|
|
||||||
|
|
||||||
return rate;
|
return freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_camerarx_lane_config(struct cal_camerarx *phy)
|
static void cal_camerarx_lane_config(struct cal_camerarx *phy)
|
||||||
@ -116,34 +124,19 @@ void cal_camerarx_disable(struct cal_camerarx *phy)
|
|||||||
#define TCLK_MISS 1
|
#define TCLK_MISS 1
|
||||||
#define TCLK_SETTLE 14
|
#define TCLK_SETTLE 14
|
||||||
|
|
||||||
static void cal_camerarx_config(struct cal_camerarx *phy, s64 external_rate)
|
static void cal_camerarx_config(struct cal_camerarx *phy, s64 link_freq)
|
||||||
{
|
{
|
||||||
unsigned int reg0, reg1;
|
unsigned int reg0, reg1;
|
||||||
unsigned int ths_term, ths_settle;
|
unsigned int ths_term, ths_settle;
|
||||||
unsigned int csi2_ddrclk_khz;
|
|
||||||
struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2 =
|
|
||||||
&phy->endpoint.bus.mipi_csi2;
|
|
||||||
u32 num_lanes = mipi_csi2->num_data_lanes;
|
|
||||||
|
|
||||||
/* DPHY timing configuration */
|
/* DPHY timing configuration */
|
||||||
|
|
||||||
/*
|
|
||||||
* CSI-2 is DDR and we only count used lanes.
|
|
||||||
*
|
|
||||||
* csi2_ddrclk_khz = external_rate / 1000
|
|
||||||
* / (2 * num_lanes) * phy->fmtinfo->bpp;
|
|
||||||
*/
|
|
||||||
csi2_ddrclk_khz = div_s64(external_rate * phy->fmtinfo->bpp,
|
|
||||||
2 * num_lanes * 1000);
|
|
||||||
|
|
||||||
phy_dbg(1, phy, "csi2_ddrclk_khz: %d\n", csi2_ddrclk_khz);
|
|
||||||
|
|
||||||
/* THS_TERM: Programmed value = floor(20 ns/DDRClk period) */
|
/* THS_TERM: Programmed value = floor(20 ns/DDRClk period) */
|
||||||
ths_term = 20 * csi2_ddrclk_khz / 1000000;
|
ths_term = div_s64(20 * link_freq, 1000 * 1000 * 1000);
|
||||||
phy_dbg(1, phy, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
|
phy_dbg(1, phy, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
|
||||||
|
|
||||||
/* THS_SETTLE: Programmed value = floor(105 ns/DDRClk period) + 4 */
|
/* THS_SETTLE: Programmed value = floor(105 ns/DDRClk period) + 4 */
|
||||||
ths_settle = (105 * csi2_ddrclk_khz / 1000000) + 4;
|
ths_settle = div_s64(105 * link_freq, 1000 * 1000 * 1000) + 4;
|
||||||
phy_dbg(1, phy, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
|
phy_dbg(1, phy, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
|
||||||
|
|
||||||
reg0 = camerarx_read(phy, CAL_CSI2_PHY_REG0);
|
reg0 = camerarx_read(phy, CAL_CSI2_PHY_REG0);
|
||||||
@ -240,24 +233,41 @@ static void cal_camerarx_enable_irqs(struct cal_camerarx *phy)
|
|||||||
CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
|
CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
|
||||||
CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
|
CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
|
||||||
CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
|
CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
|
||||||
|
const u32 vc_err_mask =
|
||||||
|
CAL_CSI2_VC_IRQ_CS_IRQ_MASK(0) |
|
||||||
|
CAL_CSI2_VC_IRQ_CS_IRQ_MASK(1) |
|
||||||
|
CAL_CSI2_VC_IRQ_CS_IRQ_MASK(2) |
|
||||||
|
CAL_CSI2_VC_IRQ_CS_IRQ_MASK(3) |
|
||||||
|
CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(0) |
|
||||||
|
CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(1) |
|
||||||
|
CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(2) |
|
||||||
|
CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(3);
|
||||||
|
|
||||||
/* Enable CIO error IRQs. */
|
/* Enable CIO & VC error IRQs. */
|
||||||
cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0),
|
cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0),
|
||||||
CAL_HL_IRQ_CIO_MASK(phy->instance));
|
CAL_HL_IRQ_CIO_MASK(phy->instance) |
|
||||||
|
CAL_HL_IRQ_VC_MASK(phy->instance));
|
||||||
cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance),
|
cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance),
|
||||||
cio_err_mask);
|
cio_err_mask);
|
||||||
|
cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance),
|
||||||
|
vc_err_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_camerarx_disable_irqs(struct cal_camerarx *phy)
|
static void cal_camerarx_disable_irqs(struct cal_camerarx *phy)
|
||||||
{
|
{
|
||||||
/* Disable CIO error irqs */
|
/* Disable CIO error irqs */
|
||||||
cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0),
|
cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0),
|
||||||
CAL_HL_IRQ_CIO_MASK(phy->instance));
|
CAL_HL_IRQ_CIO_MASK(phy->instance) |
|
||||||
|
CAL_HL_IRQ_VC_MASK(phy->instance));
|
||||||
cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0);
|
cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0);
|
||||||
|
cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_camerarx_ppi_enable(struct cal_camerarx *phy)
|
static void cal_camerarx_ppi_enable(struct cal_camerarx *phy)
|
||||||
{
|
{
|
||||||
|
cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
|
||||||
|
1, CAL_CSI2_PPI_CTRL_ECC_EN_MASK);
|
||||||
|
|
||||||
cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
|
cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
|
||||||
1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
|
1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
|
||||||
}
|
}
|
||||||
@ -270,16 +280,21 @@ static void cal_camerarx_ppi_disable(struct cal_camerarx *phy)
|
|||||||
|
|
||||||
static int cal_camerarx_start(struct cal_camerarx *phy)
|
static int cal_camerarx_start(struct cal_camerarx *phy)
|
||||||
{
|
{
|
||||||
s64 external_rate;
|
s64 link_freq;
|
||||||
u32 sscounter;
|
u32 sscounter;
|
||||||
u32 val;
|
u32 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
external_rate = cal_camerarx_get_external_rate(phy);
|
if (phy->enable_count > 0) {
|
||||||
if (external_rate < 0)
|
phy->enable_count++;
|
||||||
return external_rate;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = v4l2_subdev_call(phy->sensor, core, s_power, 1);
|
link_freq = cal_camerarx_get_ext_link_freq(phy);
|
||||||
|
if (link_freq < 0)
|
||||||
|
return link_freq;
|
||||||
|
|
||||||
|
ret = v4l2_subdev_call(phy->source, core, s_power, 1);
|
||||||
if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
|
if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
|
||||||
phy_err(phy, "power on failed in subdev\n");
|
phy_err(phy, "power on failed in subdev\n");
|
||||||
return ret;
|
return ret;
|
||||||
@ -311,7 +326,7 @@ static int cal_camerarx_start(struct cal_camerarx *phy)
|
|||||||
* 2. CSI PHY and link initialization sequence.
|
* 2. CSI PHY and link initialization sequence.
|
||||||
*
|
*
|
||||||
* a. Deassert the CSI-2 PHY reset. Do not wait for reset completion
|
* a. Deassert the CSI-2 PHY reset. Do not wait for reset completion
|
||||||
* at this point, as it requires the external sensor to send the
|
* at this point, as it requires the external source to send the
|
||||||
* CSI-2 HS clock.
|
* CSI-2 HS clock.
|
||||||
*/
|
*/
|
||||||
cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
|
cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
|
||||||
@ -325,7 +340,7 @@ static int cal_camerarx_start(struct cal_camerarx *phy)
|
|||||||
camerarx_read(phy, CAL_CSI2_PHY_REG0);
|
camerarx_read(phy, CAL_CSI2_PHY_REG0);
|
||||||
|
|
||||||
/* Program the PHY timing parameters. */
|
/* Program the PHY timing parameters. */
|
||||||
cal_camerarx_config(phy, external_rate);
|
cal_camerarx_config(phy, link_freq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* b. Assert the FORCERXMODE signal.
|
* b. Assert the FORCERXMODE signal.
|
||||||
@ -370,12 +385,12 @@ static int cal_camerarx_start(struct cal_camerarx *phy)
|
|||||||
cal_camerarx_power(phy, true);
|
cal_camerarx_power(phy, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the sensor to enable the CSI-2 HS clock. We can now wait for
|
* Start the source to enable the CSI-2 HS clock. We can now wait for
|
||||||
* CSI-2 PHY reset to complete.
|
* CSI-2 PHY reset to complete.
|
||||||
*/
|
*/
|
||||||
ret = v4l2_subdev_call(phy->sensor, video, s_stream, 1);
|
ret = v4l2_subdev_call(phy->source, video, s_stream, 1);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
v4l2_subdev_call(phy->sensor, core, s_power, 0);
|
v4l2_subdev_call(phy->source, core, s_power, 0);
|
||||||
cal_camerarx_disable_irqs(phy);
|
cal_camerarx_disable_irqs(phy);
|
||||||
phy_err(phy, "stream on failed in subdev\n");
|
phy_err(phy, "stream on failed in subdev\n");
|
||||||
return ret;
|
return ret;
|
||||||
@ -399,14 +414,18 @@ static int cal_camerarx_start(struct cal_camerarx *phy)
|
|||||||
/* Finally, enable the PHY Protocol Interface (PPI). */
|
/* Finally, enable the PHY Protocol Interface (PPI). */
|
||||||
cal_camerarx_ppi_enable(phy);
|
cal_camerarx_ppi_enable(phy);
|
||||||
|
|
||||||
|
phy->enable_count++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_camerarx_stop(struct cal_camerarx *phy)
|
static void cal_camerarx_stop(struct cal_camerarx *phy)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (--phy->enable_count > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
cal_camerarx_ppi_disable(phy);
|
cal_camerarx_ppi_disable(phy);
|
||||||
|
|
||||||
cal_camerarx_disable_irqs(phy);
|
cal_camerarx_disable_irqs(phy);
|
||||||
@ -418,27 +437,17 @@ static void cal_camerarx_stop(struct cal_camerarx *phy)
|
|||||||
CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
|
CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
|
||||||
CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
|
CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
|
||||||
|
|
||||||
/* Wait for power down completion */
|
phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset\n",
|
||||||
for (i = 0; i < 10; i++) {
|
|
||||||
if (cal_read_field(phy->cal,
|
|
||||||
CAL_CSI2_COMPLEXIO_CFG(phy->instance),
|
|
||||||
CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
|
|
||||||
CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETONGOING)
|
|
||||||
break;
|
|
||||||
usleep_range(1000, 1100);
|
|
||||||
}
|
|
||||||
phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset (%d) %s\n",
|
|
||||||
phy->instance,
|
phy->instance,
|
||||||
cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)), i,
|
cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)));
|
||||||
(i >= 10) ? "(timeout)" : "");
|
|
||||||
|
|
||||||
/* Disable the phy */
|
/* Disable the phy */
|
||||||
cal_camerarx_disable(phy);
|
cal_camerarx_disable(phy);
|
||||||
|
|
||||||
if (v4l2_subdev_call(phy->sensor, video, s_stream, 0))
|
if (v4l2_subdev_call(phy->source, video, s_stream, 0))
|
||||||
phy_err(phy, "stream off failed in subdev\n");
|
phy_err(phy, "stream off failed in subdev\n");
|
||||||
|
|
||||||
ret = v4l2_subdev_call(phy->sensor, core, s_power, 0);
|
ret = v4l2_subdev_call(phy->source, core, s_power, 0);
|
||||||
if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
|
if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
|
||||||
phy_err(phy, "power off failed in subdev\n");
|
phy_err(phy, "power off failed in subdev\n");
|
||||||
}
|
}
|
||||||
@ -558,16 +567,16 @@ static int cal_camerarx_parse_dt(struct cal_camerarx *phy)
|
|||||||
endpoint->bus.mipi_csi2.flags);
|
endpoint->bus.mipi_csi2.flags);
|
||||||
|
|
||||||
/* Retrieve the connected device and store it for later use. */
|
/* Retrieve the connected device and store it for later use. */
|
||||||
phy->sensor_ep_node = of_graph_get_remote_endpoint(ep_node);
|
phy->source_ep_node = of_graph_get_remote_endpoint(ep_node);
|
||||||
phy->sensor_node = of_graph_get_port_parent(phy->sensor_ep_node);
|
phy->source_node = of_graph_get_port_parent(phy->source_ep_node);
|
||||||
if (!phy->sensor_node) {
|
if (!phy->source_node) {
|
||||||
phy_dbg(3, phy, "Can't get remote parent\n");
|
phy_dbg(3, phy, "Can't get remote parent\n");
|
||||||
of_node_put(phy->sensor_ep_node);
|
of_node_put(phy->source_ep_node);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_dbg(1, phy, "Found connected device %pOFn\n", phy->sensor_node);
|
phy_dbg(1, phy, "Found connected device %pOFn\n", phy->source_node);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
of_node_put(ep_node);
|
of_node_put(ep_node);
|
||||||
@ -602,12 +611,18 @@ cal_camerarx_get_pad_format(struct cal_camerarx *phy,
|
|||||||
static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable)
|
static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable)
|
||||||
{
|
{
|
||||||
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mutex_lock(&phy->mutex);
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
return cal_camerarx_start(phy);
|
ret = cal_camerarx_start(phy);
|
||||||
|
else
|
||||||
|
cal_camerarx_stop(phy);
|
||||||
|
|
||||||
cal_camerarx_stop(phy);
|
mutex_unlock(&phy->mutex);
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
|
static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
|
||||||
@ -615,27 +630,36 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
|
|||||||
struct v4l2_subdev_mbus_code_enum *code)
|
struct v4l2_subdev_mbus_code_enum *code)
|
||||||
{
|
{
|
||||||
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
mutex_lock(&phy->mutex);
|
||||||
|
|
||||||
/* No transcoding, source and sink codes must match. */
|
/* No transcoding, source and sink codes must match. */
|
||||||
if (code->pad == CAL_CAMERARX_PAD_SOURCE) {
|
if (cal_rx_pad_is_source(code->pad)) {
|
||||||
struct v4l2_mbus_framefmt *fmt;
|
struct v4l2_mbus_framefmt *fmt;
|
||||||
|
|
||||||
if (code->index > 0)
|
if (code->index > 0) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
||||||
CAL_CAMERARX_PAD_SINK,
|
CAL_CAMERARX_PAD_SINK,
|
||||||
code->which);
|
code->which);
|
||||||
code->code = fmt->code;
|
code->code = fmt->code;
|
||||||
return 0;
|
} else {
|
||||||
|
if (code->index >= cal_num_formats) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
code->code = cal_formats[code->index].code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code->index >= cal_num_formats)
|
out:
|
||||||
return -EINVAL;
|
mutex_unlock(&phy->mutex);
|
||||||
|
|
||||||
code->code = cal_formats[code->index].code;
|
return ret;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
|
static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
|
||||||
@ -644,38 +668,46 @@ static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
|
|||||||
{
|
{
|
||||||
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
||||||
const struct cal_format_info *fmtinfo;
|
const struct cal_format_info *fmtinfo;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (fse->index > 0)
|
if (fse->index > 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
mutex_lock(&phy->mutex);
|
||||||
|
|
||||||
/* No transcoding, source and sink formats must match. */
|
/* No transcoding, source and sink formats must match. */
|
||||||
if (fse->pad == CAL_CAMERARX_PAD_SOURCE) {
|
if (cal_rx_pad_is_source(fse->pad)) {
|
||||||
struct v4l2_mbus_framefmt *fmt;
|
struct v4l2_mbus_framefmt *fmt;
|
||||||
|
|
||||||
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
||||||
CAL_CAMERARX_PAD_SINK,
|
CAL_CAMERARX_PAD_SINK,
|
||||||
fse->which);
|
fse->which);
|
||||||
if (fse->code != fmt->code)
|
if (fse->code != fmt->code) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
fse->min_width = fmt->width;
|
fse->min_width = fmt->width;
|
||||||
fse->max_width = fmt->width;
|
fse->max_width = fmt->width;
|
||||||
fse->min_height = fmt->height;
|
fse->min_height = fmt->height;
|
||||||
fse->max_height = fmt->height;
|
fse->max_height = fmt->height;
|
||||||
|
} else {
|
||||||
|
fmtinfo = cal_format_by_code(fse->code);
|
||||||
|
if (!fmtinfo) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
|
||||||
|
fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
|
||||||
|
fse->min_height = CAL_MIN_HEIGHT_LINES;
|
||||||
|
fse->max_height = CAL_MAX_HEIGHT_LINES;
|
||||||
}
|
}
|
||||||
|
|
||||||
fmtinfo = cal_format_by_code(fse->code);
|
out:
|
||||||
if (!fmtinfo)
|
mutex_unlock(&phy->mutex);
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
|
return ret;
|
||||||
fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
|
|
||||||
fse->min_height = CAL_MIN_HEIGHT_LINES;
|
|
||||||
fse->max_height = CAL_MAX_HEIGHT_LINES;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
|
static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
|
||||||
@ -685,10 +717,14 @@ static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
|
|||||||
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
struct cal_camerarx *phy = to_cal_camerarx(sd);
|
||||||
struct v4l2_mbus_framefmt *fmt;
|
struct v4l2_mbus_framefmt *fmt;
|
||||||
|
|
||||||
|
mutex_lock(&phy->mutex);
|
||||||
|
|
||||||
fmt = cal_camerarx_get_pad_format(phy, sd_state, format->pad,
|
fmt = cal_camerarx_get_pad_format(phy, sd_state, format->pad,
|
||||||
format->which);
|
format->which);
|
||||||
format->format = *fmt;
|
format->format = *fmt;
|
||||||
|
|
||||||
|
mutex_unlock(&phy->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,21 +738,18 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
|
|||||||
unsigned int bpp;
|
unsigned int bpp;
|
||||||
|
|
||||||
/* No transcoding, source and sink formats must match. */
|
/* No transcoding, source and sink formats must match. */
|
||||||
if (format->pad == CAL_CAMERARX_PAD_SOURCE)
|
if (cal_rx_pad_is_source(format->pad))
|
||||||
return cal_camerarx_sd_get_fmt(sd, sd_state, format);
|
return cal_camerarx_sd_get_fmt(sd, sd_state, format);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default to the first format is the requested media bus code isn't
|
* Default to the first format if the requested media bus code isn't
|
||||||
* supported.
|
* supported.
|
||||||
*/
|
*/
|
||||||
fmtinfo = cal_format_by_code(format->format.code);
|
fmtinfo = cal_format_by_code(format->format.code);
|
||||||
if (!fmtinfo)
|
if (!fmtinfo)
|
||||||
fmtinfo = &cal_formats[0];
|
fmtinfo = &cal_formats[0];
|
||||||
|
|
||||||
/*
|
/* Clamp the size, update the code. The colorspace is accepted as-is. */
|
||||||
* Clamp the size, update the code. The field and colorspace are
|
|
||||||
* accepted as-is.
|
|
||||||
*/
|
|
||||||
bpp = ALIGN(fmtinfo->bpp, 8);
|
bpp = ALIGN(fmtinfo->bpp, 8);
|
||||||
|
|
||||||
format->format.width = clamp_t(unsigned int, format->format.width,
|
format->format.width = clamp_t(unsigned int, format->format.width,
|
||||||
@ -726,20 +759,23 @@ static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
|
|||||||
CAL_MIN_HEIGHT_LINES,
|
CAL_MIN_HEIGHT_LINES,
|
||||||
CAL_MAX_HEIGHT_LINES);
|
CAL_MAX_HEIGHT_LINES);
|
||||||
format->format.code = fmtinfo->code;
|
format->format.code = fmtinfo->code;
|
||||||
|
format->format.field = V4L2_FIELD_NONE;
|
||||||
|
|
||||||
/* Store the format and propagate it to the source pad. */
|
/* Store the format and propagate it to the source pad. */
|
||||||
|
|
||||||
|
mutex_lock(&phy->mutex);
|
||||||
|
|
||||||
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
||||||
CAL_CAMERARX_PAD_SINK,
|
CAL_CAMERARX_PAD_SINK,
|
||||||
format->which);
|
format->which);
|
||||||
*fmt = format->format;
|
*fmt = format->format;
|
||||||
|
|
||||||
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
fmt = cal_camerarx_get_pad_format(phy, sd_state,
|
||||||
CAL_CAMERARX_PAD_SOURCE,
|
CAL_CAMERARX_PAD_FIRST_SOURCE,
|
||||||
format->which);
|
format->which);
|
||||||
*fmt = format->format;
|
*fmt = format->format;
|
||||||
|
|
||||||
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
|
mutex_unlock(&phy->mutex);
|
||||||
phy->fmtinfo = fmtinfo;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -798,6 +834,7 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
|
|||||||
struct platform_device *pdev = to_platform_device(cal->dev);
|
struct platform_device *pdev = to_platform_device(cal->dev);
|
||||||
struct cal_camerarx *phy;
|
struct cal_camerarx *phy;
|
||||||
struct v4l2_subdev *sd;
|
struct v4l2_subdev *sd;
|
||||||
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
phy = kzalloc(sizeof(*phy), GFP_KERNEL);
|
phy = kzalloc(sizeof(*phy), GFP_KERNEL);
|
||||||
@ -807,6 +844,8 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
|
|||||||
phy->cal = cal;
|
phy->cal = cal;
|
||||||
phy->instance = instance;
|
phy->instance = instance;
|
||||||
|
|
||||||
|
mutex_init(&phy->mutex);
|
||||||
|
|
||||||
phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||||
(instance == 0) ?
|
(instance == 0) ?
|
||||||
"cal_rx_core0" :
|
"cal_rx_core0" :
|
||||||
@ -838,14 +877,17 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
|
|||||||
sd->dev = cal->dev;
|
sd->dev = cal->dev;
|
||||||
|
|
||||||
phy->pads[CAL_CAMERARX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
|
phy->pads[CAL_CAMERARX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
|
||||||
phy->pads[CAL_CAMERARX_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
|
for (i = CAL_CAMERARX_PAD_FIRST_SOURCE; i < CAL_CAMERARX_NUM_PADS; ++i)
|
||||||
|
phy->pads[i].flags = MEDIA_PAD_FL_SOURCE;
|
||||||
sd->entity.ops = &cal_camerarx_media_ops;
|
sd->entity.ops = &cal_camerarx_media_ops;
|
||||||
ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads),
|
ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads),
|
||||||
phy->pads);
|
phy->pads);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
cal_camerarx_sd_init_cfg(sd, NULL);
|
ret = cal_camerarx_sd_init_cfg(sd, NULL);
|
||||||
|
if (ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd);
|
ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -866,7 +908,8 @@ void cal_camerarx_destroy(struct cal_camerarx *phy)
|
|||||||
|
|
||||||
v4l2_device_unregister_subdev(&phy->subdev);
|
v4l2_device_unregister_subdev(&phy->subdev);
|
||||||
media_entity_cleanup(&phy->subdev.entity);
|
media_entity_cleanup(&phy->subdev.entity);
|
||||||
of_node_put(phy->sensor_ep_node);
|
of_node_put(phy->source_ep_node);
|
||||||
of_node_put(phy->sensor_node);
|
of_node_put(phy->source_node);
|
||||||
|
mutex_destroy(&phy->mutex);
|
||||||
kfree(phy);
|
kfree(phy);
|
||||||
}
|
}
|
||||||
|
@ -102,8 +102,8 @@ static const struct cal_format_info *find_format_by_code(struct cal_ctx *ctx,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_enum_fmt_vid_cap(struct file *file, void *priv,
|
static int cal_legacy_enum_fmt_vid_cap(struct file *file, void *priv,
|
||||||
struct v4l2_fmtdesc *f)
|
struct v4l2_fmtdesc *f)
|
||||||
{
|
{
|
||||||
struct cal_ctx *ctx = video_drvdata(file);
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
const struct cal_format_info *fmtinfo;
|
const struct cal_format_info *fmtinfo;
|
||||||
@ -128,7 +128,7 @@ static int __subdev_get_format(struct cal_ctx *ctx,
|
|||||||
sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||||
sd_fmt.pad = 0;
|
sd_fmt.pad = 0;
|
||||||
|
|
||||||
ret = v4l2_subdev_call(ctx->phy->sensor, pad, get_fmt, NULL, &sd_fmt);
|
ret = v4l2_subdev_call(ctx->phy->source, pad, get_fmt, NULL, &sd_fmt);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ static int __subdev_set_format(struct cal_ctx *ctx,
|
|||||||
sd_fmt.pad = 0;
|
sd_fmt.pad = 0;
|
||||||
*mbus_fmt = *fmt;
|
*mbus_fmt = *fmt;
|
||||||
|
|
||||||
ret = v4l2_subdev_call(ctx->phy->sensor, pad, set_fmt, NULL, &sd_fmt);
|
ret = v4l2_subdev_call(ctx->phy->source, pad, set_fmt, NULL, &sd_fmt);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -189,8 +189,8 @@ static void cal_calc_format_size(struct cal_ctx *ctx,
|
|||||||
f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
|
f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_try_fmt_vid_cap(struct file *file, void *priv,
|
static int cal_legacy_try_fmt_vid_cap(struct file *file, void *priv,
|
||||||
struct v4l2_format *f)
|
struct v4l2_format *f)
|
||||||
{
|
{
|
||||||
struct cal_ctx *ctx = video_drvdata(file);
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
const struct cal_format_info *fmtinfo;
|
const struct cal_format_info *fmtinfo;
|
||||||
@ -216,7 +216,7 @@ static int cal_try_fmt_vid_cap(struct file *file, void *priv,
|
|||||||
fse.code = fmtinfo->code;
|
fse.code = fmtinfo->code;
|
||||||
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||||
for (fse.index = 0; ; fse.index++) {
|
for (fse.index = 0; ; fse.index++) {
|
||||||
ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_frame_size,
|
ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size,
|
||||||
NULL, &fse);
|
NULL, &fse);
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
@ -249,8 +249,8 @@ static int cal_try_fmt_vid_cap(struct file *file, void *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_s_fmt_vid_cap(struct file *file, void *priv,
|
static int cal_legacy_s_fmt_vid_cap(struct file *file, void *priv,
|
||||||
struct v4l2_format *f)
|
struct v4l2_format *f)
|
||||||
{
|
{
|
||||||
struct cal_ctx *ctx = video_drvdata(file);
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
struct vb2_queue *q = &ctx->vb_vidq;
|
struct vb2_queue *q = &ctx->vb_vidq;
|
||||||
@ -266,7 +266,7 @@ static int cal_s_fmt_vid_cap(struct file *file, void *priv,
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cal_try_fmt_vid_cap(file, priv, f);
|
ret = cal_legacy_try_fmt_vid_cap(file, priv, f);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -300,8 +300,8 @@ static int cal_s_fmt_vid_cap(struct file *file, void *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_enum_framesizes(struct file *file, void *fh,
|
static int cal_legacy_enum_framesizes(struct file *file, void *fh,
|
||||||
struct v4l2_frmsizeenum *fsize)
|
struct v4l2_frmsizeenum *fsize)
|
||||||
{
|
{
|
||||||
struct cal_ctx *ctx = video_drvdata(file);
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
const struct cal_format_info *fmtinfo;
|
const struct cal_format_info *fmtinfo;
|
||||||
@ -321,7 +321,7 @@ static int cal_enum_framesizes(struct file *file, void *fh,
|
|||||||
fse.code = fmtinfo->code;
|
fse.code = fmtinfo->code;
|
||||||
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||||
|
|
||||||
ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_frame_size, NULL,
|
ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size, NULL,
|
||||||
&fse);
|
&fse);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -337,8 +337,8 @@ static int cal_enum_framesizes(struct file *file, void *fh,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_enum_input(struct file *file, void *priv,
|
static int cal_legacy_enum_input(struct file *file, void *priv,
|
||||||
struct v4l2_input *inp)
|
struct v4l2_input *inp)
|
||||||
{
|
{
|
||||||
if (inp->index > 0)
|
if (inp->index > 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -348,20 +348,20 @@ static int cal_enum_input(struct file *file, void *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_g_input(struct file *file, void *priv, unsigned int *i)
|
static int cal_legacy_g_input(struct file *file, void *priv, unsigned int *i)
|
||||||
{
|
{
|
||||||
*i = 0;
|
*i = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cal_s_input(struct file *file, void *priv, unsigned int i)
|
static int cal_legacy_s_input(struct file *file, void *priv, unsigned int i)
|
||||||
{
|
{
|
||||||
return i > 0 ? -EINVAL : 0;
|
return i > 0 ? -EINVAL : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timeperframe is arbitrary and continuous */
|
/* timeperframe is arbitrary and continuous */
|
||||||
static int cal_enum_frameintervals(struct file *file, void *priv,
|
static int cal_legacy_enum_frameintervals(struct file *file, void *priv,
|
||||||
struct v4l2_frmivalenum *fival)
|
struct v4l2_frmivalenum *fival)
|
||||||
{
|
{
|
||||||
struct cal_ctx *ctx = video_drvdata(file);
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
const struct cal_format_info *fmtinfo;
|
const struct cal_format_info *fmtinfo;
|
||||||
@ -378,7 +378,7 @@ static int cal_enum_frameintervals(struct file *file, void *priv,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
fie.code = fmtinfo->code;
|
fie.code = fmtinfo->code;
|
||||||
ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_frame_interval,
|
ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_interval,
|
||||||
NULL, &fie);
|
NULL, &fie);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -388,13 +388,27 @@ static int cal_enum_frameintervals(struct file *file, void *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct v4l2_ioctl_ops cal_ioctl_video_ops = {
|
static int cal_legacy_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
|
||||||
|
{
|
||||||
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
|
|
||||||
|
return v4l2_g_parm_cap(video_devdata(file), ctx->phy->source, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cal_legacy_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
|
||||||
|
{
|
||||||
|
struct cal_ctx *ctx = video_drvdata(file);
|
||||||
|
|
||||||
|
return v4l2_s_parm_cap(video_devdata(file), ctx->phy->source, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct v4l2_ioctl_ops cal_ioctl_legacy_ops = {
|
||||||
.vidioc_querycap = cal_querycap,
|
.vidioc_querycap = cal_querycap,
|
||||||
.vidioc_enum_fmt_vid_cap = cal_enum_fmt_vid_cap,
|
.vidioc_enum_fmt_vid_cap = cal_legacy_enum_fmt_vid_cap,
|
||||||
.vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
|
.vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
|
||||||
.vidioc_try_fmt_vid_cap = cal_try_fmt_vid_cap,
|
.vidioc_try_fmt_vid_cap = cal_legacy_try_fmt_vid_cap,
|
||||||
.vidioc_s_fmt_vid_cap = cal_s_fmt_vid_cap,
|
.vidioc_s_fmt_vid_cap = cal_legacy_s_fmt_vid_cap,
|
||||||
.vidioc_enum_framesizes = cal_enum_framesizes,
|
.vidioc_enum_framesizes = cal_legacy_enum_framesizes,
|
||||||
.vidioc_reqbufs = vb2_ioctl_reqbufs,
|
.vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||||
.vidioc_create_bufs = vb2_ioctl_create_bufs,
|
.vidioc_create_bufs = vb2_ioctl_create_bufs,
|
||||||
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
|
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
|
||||||
@ -402,15 +416,17 @@ static const struct v4l2_ioctl_ops cal_ioctl_video_ops = {
|
|||||||
.vidioc_qbuf = vb2_ioctl_qbuf,
|
.vidioc_qbuf = vb2_ioctl_qbuf,
|
||||||
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||||
.vidioc_expbuf = vb2_ioctl_expbuf,
|
.vidioc_expbuf = vb2_ioctl_expbuf,
|
||||||
.vidioc_enum_input = cal_enum_input,
|
.vidioc_enum_input = cal_legacy_enum_input,
|
||||||
.vidioc_g_input = cal_g_input,
|
.vidioc_g_input = cal_legacy_g_input,
|
||||||
.vidioc_s_input = cal_s_input,
|
.vidioc_s_input = cal_legacy_s_input,
|
||||||
.vidioc_enum_frameintervals = cal_enum_frameintervals,
|
.vidioc_enum_frameintervals = cal_legacy_enum_frameintervals,
|
||||||
.vidioc_streamon = vb2_ioctl_streamon,
|
.vidioc_streamon = vb2_ioctl_streamon,
|
||||||
.vidioc_streamoff = vb2_ioctl_streamoff,
|
.vidioc_streamoff = vb2_ioctl_streamoff,
|
||||||
.vidioc_log_status = v4l2_ctrl_log_status,
|
.vidioc_log_status = v4l2_ctrl_log_status,
|
||||||
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
||||||
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||||||
|
.vidioc_g_parm = cal_legacy_g_parm,
|
||||||
|
.vidioc_s_parm = cal_legacy_s_parm,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* ------------------------------------------------------------------
|
||||||
@ -421,13 +437,28 @@ static const struct v4l2_ioctl_ops cal_ioctl_video_ops = {
|
|||||||
static int cal_mc_enum_fmt_vid_cap(struct file *file, void *priv,
|
static int cal_mc_enum_fmt_vid_cap(struct file *file, void *priv,
|
||||||
struct v4l2_fmtdesc *f)
|
struct v4l2_fmtdesc *f)
|
||||||
{
|
{
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int idx;
|
||||||
|
|
||||||
if (f->index >= cal_num_formats)
|
if (f->index >= cal_num_formats)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
f->pixelformat = cal_formats[f->index].fourcc;
|
idx = 0;
|
||||||
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
||||||
|
|
||||||
return 0;
|
for (i = 0; i < cal_num_formats; ++i) {
|
||||||
|
if (f->mbus_code && cal_formats[i].code != f->mbus_code)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (idx == f->index) {
|
||||||
|
f->pixelformat = cal_formats[i].fourcc;
|
||||||
|
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_mc_try_fmt(struct cal_ctx *ctx, struct v4l2_format *f,
|
static void cal_mc_try_fmt(struct cal_ctx *ctx, struct v4l2_format *f,
|
||||||
@ -656,8 +687,13 @@ static void cal_release_buffers(struct cal_ctx *ctx,
|
|||||||
static int cal_video_check_format(struct cal_ctx *ctx)
|
static int cal_video_check_format(struct cal_ctx *ctx)
|
||||||
{
|
{
|
||||||
const struct v4l2_mbus_framefmt *format;
|
const struct v4l2_mbus_framefmt *format;
|
||||||
|
struct media_pad *remote_pad;
|
||||||
|
|
||||||
format = &ctx->phy->formats[CAL_CAMERARX_PAD_SOURCE];
|
remote_pad = media_entity_remote_pad(&ctx->pad);
|
||||||
|
if (!remote_pad)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
format = &ctx->phy->formats[remote_pad->index];
|
||||||
|
|
||||||
if (ctx->fmtinfo->code != format->code ||
|
if (ctx->fmtinfo->code != format->code ||
|
||||||
ctx->v_fmt.fmt.pix.height != format->height ||
|
ctx->v_fmt.fmt.pix.height != format->height ||
|
||||||
@ -692,9 +728,15 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||||||
goto error_pipeline;
|
goto error_pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = cal_ctx_prepare(ctx);
|
||||||
|
if (ret) {
|
||||||
|
ctx_err(ctx, "Failed to prepare context: %d\n", ret);
|
||||||
|
goto error_pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irq(&ctx->dma.lock);
|
spin_lock_irq(&ctx->dma.lock);
|
||||||
buf = list_first_entry(&ctx->dma.queue, struct cal_buffer, list);
|
buf = list_first_entry(&ctx->dma.queue, struct cal_buffer, list);
|
||||||
ctx->dma.pending = buf;
|
ctx->dma.active = buf;
|
||||||
list_del(&buf->list);
|
list_del(&buf->list);
|
||||||
spin_unlock_irq(&ctx->dma.lock);
|
spin_unlock_irq(&ctx->dma.lock);
|
||||||
|
|
||||||
@ -719,6 +761,7 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||||||
error_stop:
|
error_stop:
|
||||||
cal_ctx_stop(ctx);
|
cal_ctx_stop(ctx);
|
||||||
pm_runtime_put_sync(ctx->cal->dev);
|
pm_runtime_put_sync(ctx->cal->dev);
|
||||||
|
cal_ctx_unprepare(ctx);
|
||||||
|
|
||||||
error_pipeline:
|
error_pipeline:
|
||||||
media_pipeline_stop(&ctx->vdev.entity);
|
media_pipeline_stop(&ctx->vdev.entity);
|
||||||
@ -738,6 +781,8 @@ static void cal_stop_streaming(struct vb2_queue *vq)
|
|||||||
|
|
||||||
pm_runtime_put_sync(ctx->cal->dev);
|
pm_runtime_put_sync(ctx->cal->dev);
|
||||||
|
|
||||||
|
cal_ctx_unprepare(ctx);
|
||||||
|
|
||||||
cal_release_buffers(ctx, VB2_BUF_STATE_ERROR);
|
cal_release_buffers(ctx, VB2_BUF_STATE_ERROR);
|
||||||
|
|
||||||
media_pipeline_stop(&ctx->vdev.entity);
|
media_pipeline_stop(&ctx->vdev.entity);
|
||||||
@ -785,20 +830,20 @@ static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
|
|||||||
memset(&mbus_code, 0, sizeof(mbus_code));
|
memset(&mbus_code, 0, sizeof(mbus_code));
|
||||||
mbus_code.index = j;
|
mbus_code.index = j;
|
||||||
mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||||
ret = v4l2_subdev_call(ctx->phy->sensor, pad, enum_mbus_code,
|
ret = v4l2_subdev_call(ctx->phy->source, pad, enum_mbus_code,
|
||||||
NULL, &mbus_code);
|
NULL, &mbus_code);
|
||||||
if (ret == -EINVAL)
|
if (ret == -EINVAL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ctx_err(ctx, "Error enumerating mbus codes in subdev %s: %d\n",
|
ctx_err(ctx, "Error enumerating mbus codes in subdev %s: %d\n",
|
||||||
ctx->phy->sensor->name, ret);
|
ctx->phy->source->name, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx_dbg(2, ctx,
|
ctx_dbg(2, ctx,
|
||||||
"subdev %s: code: %04x idx: %u\n",
|
"subdev %s: code: %04x idx: %u\n",
|
||||||
ctx->phy->sensor->name, mbus_code.code, j);
|
ctx->phy->source->name, mbus_code.code, j);
|
||||||
|
|
||||||
for (k = 0; k < cal_num_formats; k++) {
|
for (k = 0; k < cal_num_formats; k++) {
|
||||||
fmtinfo = &cal_formats[k];
|
fmtinfo = &cal_formats[k];
|
||||||
@ -816,7 +861,7 @@ static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
|
|||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
ctx_err(ctx, "No suitable format reported by subdev %s\n",
|
ctx_err(ctx, "No suitable format reported by subdev %s\n",
|
||||||
ctx->phy->sensor->name);
|
ctx->phy->source->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,22 +886,57 @@ static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cal_ctx_v4l2_init_mc_format(struct cal_ctx *ctx)
|
||||||
|
{
|
||||||
|
const struct cal_format_info *fmtinfo;
|
||||||
|
struct v4l2_pix_format *pix_fmt = &ctx->v_fmt.fmt.pix;
|
||||||
|
|
||||||
|
fmtinfo = cal_format_by_code(MEDIA_BUS_FMT_UYVY8_2X8);
|
||||||
|
if (!fmtinfo)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pix_fmt->width = 640;
|
||||||
|
pix_fmt->height = 480;
|
||||||
|
pix_fmt->field = V4L2_FIELD_NONE;
|
||||||
|
pix_fmt->colorspace = V4L2_COLORSPACE_SRGB;
|
||||||
|
pix_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
|
||||||
|
pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
|
||||||
|
pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
|
||||||
|
pix_fmt->pixelformat = fmtinfo->fourcc;
|
||||||
|
|
||||||
|
ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
|
||||||
|
/* Save current format */
|
||||||
|
cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
|
||||||
|
ctx->fmtinfo = fmtinfo;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int cal_ctx_v4l2_register(struct cal_ctx *ctx)
|
int cal_ctx_v4l2_register(struct cal_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct video_device *vfd = &ctx->vdev;
|
struct video_device *vfd = &ctx->vdev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = cal_ctx_v4l2_init_formats(ctx);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (!cal_mc_api) {
|
if (!cal_mc_api) {
|
||||||
struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
|
struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
|
||||||
|
|
||||||
ret = v4l2_ctrl_add_handler(hdl, ctx->phy->sensor->ctrl_handler,
|
ret = cal_ctx_v4l2_init_formats(ctx);
|
||||||
|
if (ret) {
|
||||||
|
ctx_err(ctx, "Failed to init formats: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = v4l2_ctrl_add_handler(hdl, ctx->phy->source->ctrl_handler,
|
||||||
NULL, true);
|
NULL, true);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ctx_err(ctx, "Failed to add sensor ctrl handler\n");
|
ctx_err(ctx, "Failed to add source ctrl handler\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = cal_ctx_v4l2_init_mc_format(ctx);
|
||||||
|
if (ret) {
|
||||||
|
ctx_err(ctx, "Failed to init format: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -868,13 +948,13 @@ int cal_ctx_v4l2_register(struct cal_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = media_create_pad_link(&ctx->phy->subdev.entity,
|
ret = media_create_pad_link(&ctx->phy->subdev.entity,
|
||||||
CAL_CAMERARX_PAD_SOURCE,
|
CAL_CAMERARX_PAD_FIRST_SOURCE,
|
||||||
&vfd->entity, 0,
|
&vfd->entity, 0,
|
||||||
MEDIA_LNK_FL_IMMUTABLE |
|
MEDIA_LNK_FL_IMMUTABLE |
|
||||||
MEDIA_LNK_FL_ENABLED);
|
MEDIA_LNK_FL_ENABLED);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ctx_err(ctx, "Failed to create media link for context %u\n",
|
ctx_err(ctx, "Failed to create media link for context %u\n",
|
||||||
ctx->index);
|
ctx->dma_ctx);
|
||||||
video_unregister_device(vfd);
|
video_unregister_device(vfd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -926,9 +1006,9 @@ int cal_ctx_v4l2_init(struct cal_ctx *ctx)
|
|||||||
| (cal_mc_api ? V4L2_CAP_IO_MC : 0);
|
| (cal_mc_api ? V4L2_CAP_IO_MC : 0);
|
||||||
vfd->v4l2_dev = &ctx->cal->v4l2_dev;
|
vfd->v4l2_dev = &ctx->cal->v4l2_dev;
|
||||||
vfd->queue = q;
|
vfd->queue = q;
|
||||||
snprintf(vfd->name, sizeof(vfd->name), "CAL output %u", ctx->index);
|
snprintf(vfd->name, sizeof(vfd->name), "CAL output %u", ctx->dma_ctx);
|
||||||
vfd->release = video_device_release_empty;
|
vfd->release = video_device_release_empty;
|
||||||
vfd->ioctl_ops = cal_mc_api ? &cal_ioctl_mc_ops : &cal_ioctl_video_ops;
|
vfd->ioctl_ops = cal_mc_api ? &cal_ioctl_mc_ops : &cal_ioctl_legacy_ops;
|
||||||
vfd->lock = &ctx->mutex;
|
vfd->lock = &ctx->mutex;
|
||||||
video_set_drvdata(vfd, ctx);
|
video_set_drvdata(vfd, ctx);
|
||||||
|
|
||||||
|
@ -290,11 +290,42 @@ void cal_quickdump_regs(struct cal_dev *cal)
|
|||||||
* ------------------------------------------------------------------
|
* ------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define CAL_MAX_PIX_PROC 4
|
||||||
|
|
||||||
|
static int cal_reserve_pix_proc(struct cal_dev *cal)
|
||||||
|
{
|
||||||
|
unsigned long ret;
|
||||||
|
|
||||||
|
spin_lock(&cal->v4l2_dev.lock);
|
||||||
|
|
||||||
|
ret = find_first_zero_bit(&cal->reserved_pix_proc_mask, CAL_MAX_PIX_PROC);
|
||||||
|
|
||||||
|
if (ret == CAL_MAX_PIX_PROC) {
|
||||||
|
spin_unlock(&cal->v4l2_dev.lock);
|
||||||
|
return -ENOSPC;
|
||||||
|
}
|
||||||
|
|
||||||
|
cal->reserved_pix_proc_mask |= BIT(ret);
|
||||||
|
|
||||||
|
spin_unlock(&cal->v4l2_dev.lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cal_release_pix_proc(struct cal_dev *cal, unsigned int pix_proc_num)
|
||||||
|
{
|
||||||
|
spin_lock(&cal->v4l2_dev.lock);
|
||||||
|
|
||||||
|
cal->reserved_pix_proc_mask &= ~BIT(pix_proc_num);
|
||||||
|
|
||||||
|
spin_unlock(&cal->v4l2_dev.lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void cal_ctx_csi2_config(struct cal_ctx *ctx)
|
static void cal_ctx_csi2_config(struct cal_ctx *ctx)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
val = cal_read(ctx->cal, CAL_CSI2_CTX0(ctx->index));
|
val = cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx));
|
||||||
cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK);
|
cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK);
|
||||||
/*
|
/*
|
||||||
* DT type: MIPI CSI-2 Specs
|
* DT type: MIPI CSI-2 Specs
|
||||||
@ -304,15 +335,16 @@ static void cal_ctx_csi2_config(struct cal_ctx *ctx)
|
|||||||
* 0x2A: RAW8 1 pixel = 1 byte
|
* 0x2A: RAW8 1 pixel = 1 byte
|
||||||
* 0x1E: YUV422 2 pixels = 4 bytes
|
* 0x1E: YUV422 2 pixels = 4 bytes
|
||||||
*/
|
*/
|
||||||
cal_set_field(&val, 0x1, CAL_CSI2_CTX_DT_MASK);
|
cal_set_field(&val, ctx->datatype, CAL_CSI2_CTX_DT_MASK);
|
||||||
cal_set_field(&val, 0, CAL_CSI2_CTX_VC_MASK);
|
cal_set_field(&val, ctx->vc, CAL_CSI2_CTX_VC_MASK);
|
||||||
cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
|
cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
|
||||||
cal_set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
|
cal_set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
|
||||||
cal_set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
|
cal_set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
|
||||||
CAL_CSI2_CTX_PACK_MODE_MASK);
|
CAL_CSI2_CTX_PACK_MODE_MASK);
|
||||||
cal_write(ctx->cal, CAL_CSI2_CTX0(ctx->index), val);
|
cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), val);
|
||||||
ctx_dbg(3, ctx, "CAL_CSI2_CTX0(%d) = 0x%08x\n", ctx->index,
|
ctx_dbg(3, ctx, "CAL_CSI2_CTX(%u, %u) = 0x%08x\n",
|
||||||
cal_read(ctx->cal, CAL_CSI2_CTX0(ctx->index)));
|
ctx->phy->instance, ctx->csi2_ctx,
|
||||||
|
cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_ctx_pix_proc_config(struct cal_ctx *ctx)
|
static void cal_ctx_pix_proc_config(struct cal_ctx *ctx)
|
||||||
@ -354,16 +386,16 @@ static void cal_ctx_pix_proc_config(struct cal_ctx *ctx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->index));
|
val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc));
|
||||||
cal_set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK);
|
cal_set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK);
|
||||||
cal_set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);
|
cal_set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);
|
||||||
cal_set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
|
cal_set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
|
||||||
cal_set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);
|
cal_set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);
|
||||||
cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK);
|
cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK);
|
||||||
cal_set_field(&val, 1, CAL_PIX_PROC_EN_MASK);
|
cal_set_field(&val, 1, CAL_PIX_PROC_EN_MASK);
|
||||||
cal_write(ctx->cal, CAL_PIX_PROC(ctx->index), val);
|
cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), val);
|
||||||
ctx_dbg(3, ctx, "CAL_PIX_PROC(%d) = 0x%08x\n", ctx->index,
|
ctx_dbg(3, ctx, "CAL_PIX_PROC(%u) = 0x%08x\n", ctx->pix_proc,
|
||||||
cal_read(ctx->cal, CAL_PIX_PROC(ctx->index)));
|
cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_ctx_wr_dma_config(struct cal_ctx *ctx)
|
static void cal_ctx_wr_dma_config(struct cal_ctx *ctx)
|
||||||
@ -371,27 +403,25 @@ static void cal_ctx_wr_dma_config(struct cal_ctx *ctx)
|
|||||||
unsigned int stride = ctx->v_fmt.fmt.pix.bytesperline;
|
unsigned int stride = ctx->v_fmt.fmt.pix.bytesperline;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->index));
|
val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
|
||||||
cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK);
|
cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK);
|
||||||
cal_set_field(&val, ctx->v_fmt.fmt.pix.height,
|
cal_set_field(&val, ctx->v_fmt.fmt.pix.height,
|
||||||
CAL_WR_DMA_CTRL_YSIZE_MASK);
|
CAL_WR_DMA_CTRL_YSIZE_MASK);
|
||||||
cal_set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,
|
cal_set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,
|
||||||
CAL_WR_DMA_CTRL_DTAG_MASK);
|
CAL_WR_DMA_CTRL_DTAG_MASK);
|
||||||
cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,
|
|
||||||
CAL_WR_DMA_CTRL_MODE_MASK);
|
|
||||||
cal_set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
|
cal_set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
|
||||||
CAL_WR_DMA_CTRL_PATTERN_MASK);
|
CAL_WR_DMA_CTRL_PATTERN_MASK);
|
||||||
cal_set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);
|
cal_set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);
|
||||||
cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->index), val);
|
cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
|
||||||
ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->index,
|
ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->dma_ctx,
|
||||||
cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->index)));
|
cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)));
|
||||||
|
|
||||||
cal_write_field(ctx->cal, CAL_WR_DMA_OFST(ctx->index),
|
cal_write_field(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx),
|
||||||
stride / 16, CAL_WR_DMA_OFST_MASK);
|
stride / 16, CAL_WR_DMA_OFST_MASK);
|
||||||
ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->index,
|
ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->dma_ctx,
|
||||||
cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->index)));
|
cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx)));
|
||||||
|
|
||||||
val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->index));
|
val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx));
|
||||||
/* 64 bit word means no skipping */
|
/* 64 bit word means no skipping */
|
||||||
cal_set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);
|
cal_set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);
|
||||||
/*
|
/*
|
||||||
@ -400,34 +430,32 @@ static void cal_ctx_wr_dma_config(struct cal_ctx *ctx)
|
|||||||
* written per line.
|
* written per line.
|
||||||
*/
|
*/
|
||||||
cal_set_field(&val, stride / 8, CAL_WR_DMA_XSIZE_MASK);
|
cal_set_field(&val, stride / 8, CAL_WR_DMA_XSIZE_MASK);
|
||||||
cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->index), val);
|
cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx), val);
|
||||||
ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->index,
|
ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->dma_ctx,
|
||||||
cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->index)));
|
cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx)));
|
||||||
|
|
||||||
val = cal_read(ctx->cal, CAL_CTRL);
|
|
||||||
cal_set_field(&val, CAL_CTRL_BURSTSIZE_BURST128,
|
|
||||||
CAL_CTRL_BURSTSIZE_MASK);
|
|
||||||
cal_set_field(&val, 0xF, CAL_CTRL_TAGCNT_MASK);
|
|
||||||
cal_set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
|
|
||||||
CAL_CTRL_POSTED_WRITES_MASK);
|
|
||||||
cal_set_field(&val, 0xFF, CAL_CTRL_MFLAGL_MASK);
|
|
||||||
cal_set_field(&val, 0xFF, CAL_CTRL_MFLAGH_MASK);
|
|
||||||
cal_write(ctx->cal, CAL_CTRL, val);
|
|
||||||
ctx_dbg(3, ctx, "CAL_CTRL = 0x%08x\n", cal_read(ctx->cal, CAL_CTRL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr)
|
void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr)
|
||||||
{
|
{
|
||||||
cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->index), addr);
|
cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->dma_ctx), addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cal_ctx_wr_dma_enable(struct cal_ctx *ctx)
|
||||||
|
{
|
||||||
|
u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
|
||||||
|
|
||||||
|
cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,
|
||||||
|
CAL_WR_DMA_CTRL_MODE_MASK);
|
||||||
|
cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cal_ctx_wr_dma_disable(struct cal_ctx *ctx)
|
static void cal_ctx_wr_dma_disable(struct cal_ctx *ctx)
|
||||||
{
|
{
|
||||||
u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->index));
|
u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
|
||||||
|
|
||||||
cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_DIS,
|
cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_DIS,
|
||||||
CAL_WR_DMA_CTRL_MODE_MASK);
|
CAL_WR_DMA_CTRL_MODE_MASK);
|
||||||
cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->index), val);
|
cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
|
static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
|
||||||
@ -441,6 +469,31 @@ static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
|
|||||||
return stopped;
|
return stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cal_ctx_prepare(struct cal_ctx *ctx)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ctx->use_pix_proc = !ctx->fmtinfo->meta;
|
||||||
|
|
||||||
|
if (ctx->use_pix_proc) {
|
||||||
|
ret = cal_reserve_pix_proc(ctx->cal);
|
||||||
|
if (ret < 0) {
|
||||||
|
ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pix_proc = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cal_ctx_unprepare(struct cal_ctx *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->use_pix_proc)
|
||||||
|
cal_release_pix_proc(ctx->cal, ctx->pix_proc);
|
||||||
|
}
|
||||||
|
|
||||||
void cal_ctx_start(struct cal_ctx *ctx)
|
void cal_ctx_start(struct cal_ctx *ctx)
|
||||||
{
|
{
|
||||||
ctx->sequence = 0;
|
ctx->sequence = 0;
|
||||||
@ -448,14 +501,17 @@ void cal_ctx_start(struct cal_ctx *ctx)
|
|||||||
|
|
||||||
/* Configure the CSI-2, pixel processing and write DMA contexts. */
|
/* Configure the CSI-2, pixel processing and write DMA contexts. */
|
||||||
cal_ctx_csi2_config(ctx);
|
cal_ctx_csi2_config(ctx);
|
||||||
cal_ctx_pix_proc_config(ctx);
|
if (ctx->use_pix_proc)
|
||||||
|
cal_ctx_pix_proc_config(ctx);
|
||||||
cal_ctx_wr_dma_config(ctx);
|
cal_ctx_wr_dma_config(ctx);
|
||||||
|
|
||||||
/* Enable IRQ_WDMA_END and IRQ_WDMA_START. */
|
/* Enable IRQ_WDMA_END and IRQ_WDMA_START. */
|
||||||
cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(1),
|
cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(1),
|
||||||
CAL_HL_IRQ_MASK(ctx->index));
|
CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
|
||||||
cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(2),
|
cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(2),
|
||||||
CAL_HL_IRQ_MASK(ctx->index));
|
CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
|
||||||
|
|
||||||
|
cal_ctx_wr_dma_enable(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cal_ctx_stop(struct cal_ctx *ctx)
|
void cal_ctx_stop(struct cal_ctx *ctx)
|
||||||
@ -479,11 +535,18 @@ void cal_ctx_stop(struct cal_ctx *ctx)
|
|||||||
|
|
||||||
/* Disable IRQ_WDMA_END and IRQ_WDMA_START. */
|
/* Disable IRQ_WDMA_END and IRQ_WDMA_START. */
|
||||||
cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(1),
|
cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(1),
|
||||||
CAL_HL_IRQ_MASK(ctx->index));
|
CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
|
||||||
cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(2),
|
cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(2),
|
||||||
CAL_HL_IRQ_MASK(ctx->index));
|
CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
|
||||||
|
|
||||||
ctx->dma.state = CAL_DMA_STOPPED;
|
ctx->dma.state = CAL_DMA_STOPPED;
|
||||||
|
|
||||||
|
/* Disable CSI2 context */
|
||||||
|
cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), 0);
|
||||||
|
|
||||||
|
/* Disable pix proc */
|
||||||
|
if (ctx->use_pix_proc)
|
||||||
|
cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/* ------------------------------------------------------------------
|
||||||
@ -577,6 +640,16 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
|
|||||||
cal_write(cal, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),
|
cal_write(cal, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),
|
||||||
cio_stat);
|
cio_stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status & CAL_HL_IRQ_VC_MASK(i)) {
|
||||||
|
u32 vc_stat = cal_read(cal, CAL_CSI2_VC_IRQSTATUS(i));
|
||||||
|
|
||||||
|
dev_err_ratelimited(cal->dev,
|
||||||
|
"CIO%u VC error: %#08x\n",
|
||||||
|
i, vc_stat);
|
||||||
|
|
||||||
|
cal_write(cal, CAL_CSI2_VC_IRQSTATUS(i), vc_stat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,8 +661,8 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
|
|||||||
/* Clear Interrupt status */
|
/* Clear Interrupt status */
|
||||||
cal_write(cal, CAL_HL_IRQSTATUS(1), status);
|
cal_write(cal, CAL_HL_IRQSTATUS(1), status);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
|
for (i = 0; i < cal->num_contexts; ++i) {
|
||||||
if (status & CAL_HL_IRQ_MASK(i))
|
if (status & CAL_HL_IRQ_WDMA_END_MASK(i))
|
||||||
cal_irq_wdma_end(cal->ctx[i]);
|
cal_irq_wdma_end(cal->ctx[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -602,8 +675,8 @@ static irqreturn_t cal_irq(int irq_cal, void *data)
|
|||||||
/* Clear Interrupt status */
|
/* Clear Interrupt status */
|
||||||
cal_write(cal, CAL_HL_IRQSTATUS(2), status);
|
cal_write(cal, CAL_HL_IRQSTATUS(2), status);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
|
for (i = 0; i < cal->num_contexts; ++i) {
|
||||||
if (status & CAL_HL_IRQ_MASK(i))
|
if (status & CAL_HL_IRQ_WDMA_START_MASK(i))
|
||||||
cal_irq_wdma_start(cal->ctx[i]);
|
cal_irq_wdma_start(cal->ctx[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -635,20 +708,20 @@ static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier,
|
|||||||
int pad;
|
int pad;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (phy->sensor) {
|
if (phy->source) {
|
||||||
phy_info(phy, "Rejecting subdev %s (Already set!!)",
|
phy_info(phy, "Rejecting subdev %s (Already set!!)",
|
||||||
subdev->name);
|
subdev->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
phy->sensor = subdev;
|
phy->source = subdev;
|
||||||
phy_dbg(1, phy, "Using sensor %s for capture\n", subdev->name);
|
phy_dbg(1, phy, "Using source %s for capture\n", subdev->name);
|
||||||
|
|
||||||
pad = media_entity_get_fwnode_pad(&subdev->entity,
|
pad = media_entity_get_fwnode_pad(&subdev->entity,
|
||||||
of_fwnode_handle(phy->sensor_ep_node),
|
of_fwnode_handle(phy->source_ep_node),
|
||||||
MEDIA_PAD_FL_SOURCE);
|
MEDIA_PAD_FL_SOURCE);
|
||||||
if (pad < 0) {
|
if (pad < 0) {
|
||||||
phy_err(phy, "Sensor %s has no connected source pad\n",
|
phy_err(phy, "Source %s has no connected source pad\n",
|
||||||
subdev->name);
|
subdev->name);
|
||||||
return pad;
|
return pad;
|
||||||
}
|
}
|
||||||
@ -658,7 +731,7 @@ static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier,
|
|||||||
MEDIA_LNK_FL_IMMUTABLE |
|
MEDIA_LNK_FL_IMMUTABLE |
|
||||||
MEDIA_LNK_FL_ENABLED);
|
MEDIA_LNK_FL_ENABLED);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
phy_err(phy, "Failed to create media link for sensor %s\n",
|
phy_err(phy, "Failed to create media link for source %s\n",
|
||||||
subdev->name);
|
subdev->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -670,15 +743,30 @@ static int cal_async_notifier_complete(struct v4l2_async_notifier *notifier)
|
|||||||
{
|
{
|
||||||
struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier);
|
struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->ctx); ++i) {
|
for (i = 0; i < cal->num_contexts; ++i) {
|
||||||
if (cal->ctx[i])
|
ret = cal_ctx_v4l2_register(cal->ctx[i]);
|
||||||
cal_ctx_v4l2_register(cal->ctx[i]);
|
if (ret)
|
||||||
|
goto err_ctx_unreg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal_mc_api)
|
if (!cal_mc_api)
|
||||||
ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev);
|
return 0;
|
||||||
|
|
||||||
|
ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev);
|
||||||
|
if (ret)
|
||||||
|
goto err_ctx_unreg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_ctx_unreg:
|
||||||
|
for (; i > 0; --i) {
|
||||||
|
if (!cal->ctx[i - 1])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cal_ctx_v4l2_unregister(cal->ctx[i - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -701,10 +789,10 @@ static int cal_async_notifier_register(struct cal_dev *cal)
|
|||||||
struct cal_v4l2_async_subdev *casd;
|
struct cal_v4l2_async_subdev *casd;
|
||||||
struct fwnode_handle *fwnode;
|
struct fwnode_handle *fwnode;
|
||||||
|
|
||||||
if (!phy->sensor_node)
|
if (!phy->source_node)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fwnode = of_fwnode_handle(phy->sensor_node);
|
fwnode = of_fwnode_handle(phy->source_node);
|
||||||
casd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier,
|
casd = v4l2_async_notifier_add_fwnode_subdev(&cal->notifier,
|
||||||
fwnode,
|
fwnode,
|
||||||
struct cal_v4l2_async_subdev);
|
struct cal_v4l2_async_subdev);
|
||||||
@ -777,10 +865,8 @@ static void cal_media_unregister(struct cal_dev *cal)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Unregister all the V4L2 video devices. */
|
/* Unregister all the V4L2 video devices. */
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->ctx); i++) {
|
for (i = 0; i < cal->num_contexts; i++)
|
||||||
if (cal->ctx[i])
|
cal_ctx_v4l2_unregister(cal->ctx[i]);
|
||||||
cal_ctx_v4l2_unregister(cal->ctx[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
cal_async_notifier_unregister(cal);
|
cal_async_notifier_unregister(cal);
|
||||||
media_device_unregister(&cal->mdev);
|
media_device_unregister(&cal->mdev);
|
||||||
@ -825,13 +911,6 @@ static int cal_media_init(struct cal_dev *cal)
|
|||||||
*/
|
*/
|
||||||
static void cal_media_cleanup(struct cal_dev *cal)
|
static void cal_media_cleanup(struct cal_dev *cal)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->ctx); i++) {
|
|
||||||
if (cal->ctx[i])
|
|
||||||
cal_ctx_v4l2_cleanup(cal->ctx[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
v4l2_device_unregister(&cal->v4l2_dev);
|
v4l2_device_unregister(&cal->v4l2_dev);
|
||||||
media_device_cleanup(&cal->mdev);
|
media_device_cleanup(&cal->mdev);
|
||||||
|
|
||||||
@ -848,14 +927,17 @@ static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
|
|||||||
struct cal_ctx *ctx;
|
struct cal_ctx *ctx;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ctx = devm_kzalloc(cal->dev, sizeof(*ctx), GFP_KERNEL);
|
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ctx->cal = cal;
|
ctx->cal = cal;
|
||||||
ctx->phy = cal->phy[inst];
|
ctx->phy = cal->phy[inst];
|
||||||
ctx->index = inst;
|
ctx->dma_ctx = inst;
|
||||||
|
ctx->csi2_ctx = inst;
|
||||||
ctx->cport = inst;
|
ctx->cport = inst;
|
||||||
|
ctx->vc = 0;
|
||||||
|
ctx->datatype = CAL_CSI2_CTX_DT_ANY;
|
||||||
|
|
||||||
ret = cal_ctx_v4l2_init(ctx);
|
ret = cal_ctx_v4l2_init(ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -864,6 +946,13 @@ static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cal_ctx_destroy(struct cal_ctx *ctx)
|
||||||
|
{
|
||||||
|
cal_ctx_v4l2_cleanup(ctx);
|
||||||
|
|
||||||
|
kfree(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct of_device_id cal_of_match[] = {
|
static const struct of_device_id cal_of_match[] = {
|
||||||
{
|
{
|
||||||
.compatible = "ti,dra72-cal",
|
.compatible = "ti,dra72-cal",
|
||||||
@ -976,7 +1065,6 @@ static int cal_init_camerarx_regmap(struct cal_dev *cal)
|
|||||||
static int cal_probe(struct platform_device *pdev)
|
static int cal_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct cal_dev *cal;
|
struct cal_dev *cal;
|
||||||
struct cal_ctx *ctx;
|
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1045,7 +1133,7 @@ static int cal_probe(struct platform_device *pdev)
|
|||||||
goto error_camerarx;
|
goto error_camerarx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cal->phy[i]->sensor_node)
|
if (cal->phy[i]->source_node)
|
||||||
connected = true;
|
connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,15 +1145,17 @@ static int cal_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
/* Create contexts. */
|
/* Create contexts. */
|
||||||
for (i = 0; i < cal->data->num_csi2_phy; ++i) {
|
for (i = 0; i < cal->data->num_csi2_phy; ++i) {
|
||||||
if (!cal->phy[i]->sensor_node)
|
if (!cal->phy[i]->source_node)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cal->ctx[i] = cal_ctx_create(cal, i);
|
cal->ctx[cal->num_contexts] = cal_ctx_create(cal, i);
|
||||||
if (!cal->ctx[i]) {
|
if (!cal->ctx[cal->num_contexts]) {
|
||||||
cal_err(cal, "Failed to create context %u\n", i);
|
cal_err(cal, "Failed to create context %u\n", cal->num_contexts);
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto error_context;
|
goto error_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cal->num_contexts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the media device. */
|
/* Register the media device. */
|
||||||
@ -1076,11 +1166,8 @@ static int cal_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_context:
|
error_context:
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->ctx); i++) {
|
for (i = 0; i < cal->num_contexts; i++)
|
||||||
ctx = cal->ctx[i];
|
cal_ctx_destroy(cal->ctx[i]);
|
||||||
if (ctx)
|
|
||||||
cal_ctx_v4l2_cleanup(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
error_camerarx:
|
error_camerarx:
|
||||||
for (i = 0; i < cal->data->num_csi2_phy; i++)
|
for (i = 0; i < cal->data->num_csi2_phy; i++)
|
||||||
@ -1106,16 +1193,17 @@ static int cal_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
cal_media_unregister(cal);
|
cal_media_unregister(cal);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(cal->phy); i++) {
|
for (i = 0; i < cal->data->num_csi2_phy; i++)
|
||||||
if (cal->phy[i])
|
cal_camerarx_disable(cal->phy[i]);
|
||||||
cal_camerarx_disable(cal->phy[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
cal_media_cleanup(cal);
|
for (i = 0; i < cal->num_contexts; i++)
|
||||||
|
cal_ctx_destroy(cal->ctx[i]);
|
||||||
|
|
||||||
for (i = 0; i < cal->data->num_csi2_phy; i++)
|
for (i = 0; i < cal->data->num_csi2_phy; i++)
|
||||||
cal_camerarx_destroy(cal->phy[i]);
|
cal_camerarx_destroy(cal->phy[i]);
|
||||||
|
|
||||||
|
cal_media_cleanup(cal);
|
||||||
|
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
pm_runtime_put_sync(&pdev->dev);
|
pm_runtime_put_sync(&pdev->dev);
|
||||||
pm_runtime_disable(&pdev->dev);
|
pm_runtime_disable(&pdev->dev);
|
||||||
@ -1127,6 +1215,7 @@ static int cal_runtime_resume(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct cal_dev *cal = dev_get_drvdata(dev);
|
struct cal_dev *cal = dev_get_drvdata(dev);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
|
if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
|
||||||
/*
|
/*
|
||||||
@ -1143,6 +1232,17 @@ static int cal_runtime_resume(struct device *dev)
|
|||||||
*/
|
*/
|
||||||
cal_write(cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK);
|
cal_write(cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK);
|
||||||
|
|
||||||
|
val = cal_read(cal, CAL_CTRL);
|
||||||
|
cal_set_field(&val, CAL_CTRL_BURSTSIZE_BURST128,
|
||||||
|
CAL_CTRL_BURSTSIZE_MASK);
|
||||||
|
cal_set_field(&val, 0xf, CAL_CTRL_TAGCNT_MASK);
|
||||||
|
cal_set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
|
||||||
|
CAL_CTRL_POSTED_WRITES_MASK);
|
||||||
|
cal_set_field(&val, 0xff, CAL_CTRL_MFLAGL_MASK);
|
||||||
|
cal_set_field(&val, 0xff, CAL_CTRL_MFLAGH_MASK);
|
||||||
|
cal_write(cal, CAL_CTRL, val);
|
||||||
|
cal_dbg(3, cal, "CAL_CTRL = 0x%08x\n", cal_read(cal, CAL_CTRL));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include <media/videobuf2-v4l2.h>
|
#include <media/videobuf2-v4l2.h>
|
||||||
|
|
||||||
#define CAL_MODULE_NAME "cal"
|
#define CAL_MODULE_NAME "cal"
|
||||||
#define CAL_NUM_CONTEXT 2
|
#define CAL_MAX_NUM_CONTEXT 8
|
||||||
#define CAL_NUM_CSI2_PORTS 2
|
#define CAL_NUM_CSI2_PORTS 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -44,7 +44,22 @@
|
|||||||
#define CAL_MAX_HEIGHT_LINES 16383
|
#define CAL_MAX_HEIGHT_LINES 16383
|
||||||
|
|
||||||
#define CAL_CAMERARX_PAD_SINK 0
|
#define CAL_CAMERARX_PAD_SINK 0
|
||||||
#define CAL_CAMERARX_PAD_SOURCE 1
|
#define CAL_CAMERARX_PAD_FIRST_SOURCE 1
|
||||||
|
#define CAL_CAMERARX_NUM_SOURCE_PADS 1
|
||||||
|
#define CAL_CAMERARX_NUM_PADS (1 + CAL_CAMERARX_NUM_SOURCE_PADS)
|
||||||
|
|
||||||
|
static inline bool cal_rx_pad_is_sink(u32 pad)
|
||||||
|
{
|
||||||
|
/* Camera RX has 1 sink pad, and N source pads */
|
||||||
|
return pad == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool cal_rx_pad_is_source(u32 pad)
|
||||||
|
{
|
||||||
|
/* Camera RX has 1 sink pad, and N source pads */
|
||||||
|
return pad >= CAL_CAMERARX_PAD_FIRST_SOURCE &&
|
||||||
|
pad <= CAL_CAMERARX_NUM_SOURCE_PADS;
|
||||||
|
}
|
||||||
|
|
||||||
struct device;
|
struct device;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
@ -73,6 +88,7 @@ struct cal_format_info {
|
|||||||
u32 code;
|
u32 code;
|
||||||
/* Bits per pixel */
|
/* Bits per pixel */
|
||||||
u8 bpp;
|
u8 bpp;
|
||||||
|
bool meta;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* buffer for one video frame */
|
/* buffer for one video frame */
|
||||||
@ -149,22 +165,29 @@ struct cal_data {
|
|||||||
struct cal_camerarx {
|
struct cal_camerarx {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct device *dev;
|
|
||||||
struct regmap_field *fields[F_MAX_FIELDS];
|
struct regmap_field *fields[F_MAX_FIELDS];
|
||||||
|
|
||||||
struct cal_dev *cal;
|
struct cal_dev *cal;
|
||||||
unsigned int instance;
|
unsigned int instance;
|
||||||
|
|
||||||
struct v4l2_fwnode_endpoint endpoint;
|
struct v4l2_fwnode_endpoint endpoint;
|
||||||
struct device_node *sensor_ep_node;
|
struct device_node *source_ep_node;
|
||||||
struct device_node *sensor_node;
|
struct device_node *source_node;
|
||||||
struct v4l2_subdev *sensor;
|
struct v4l2_subdev *source;
|
||||||
struct media_pipeline pipe;
|
struct media_pipeline pipe;
|
||||||
|
|
||||||
struct v4l2_subdev subdev;
|
struct v4l2_subdev subdev;
|
||||||
struct media_pad pads[2];
|
struct media_pad pads[CAL_CAMERARX_NUM_PADS];
|
||||||
struct v4l2_mbus_framefmt formats[2];
|
struct v4l2_mbus_framefmt formats[CAL_CAMERARX_NUM_PADS];
|
||||||
const struct cal_format_info *fmtinfo;
|
|
||||||
|
/*
|
||||||
|
* Lock for camerarx ops. Protects:
|
||||||
|
* - formats
|
||||||
|
* - enable_count
|
||||||
|
*/
|
||||||
|
struct mutex mutex;
|
||||||
|
|
||||||
|
unsigned int enable_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cal_dev {
|
struct cal_dev {
|
||||||
@ -184,11 +207,14 @@ struct cal_dev {
|
|||||||
/* Camera Core Module handle */
|
/* Camera Core Module handle */
|
||||||
struct cal_camerarx *phy[CAL_NUM_CSI2_PORTS];
|
struct cal_camerarx *phy[CAL_NUM_CSI2_PORTS];
|
||||||
|
|
||||||
struct cal_ctx *ctx[CAL_NUM_CONTEXT];
|
u32 num_contexts;
|
||||||
|
struct cal_ctx *ctx[CAL_MAX_NUM_CONTEXT];
|
||||||
|
|
||||||
struct media_device mdev;
|
struct media_device mdev;
|
||||||
struct v4l2_device v4l2_dev;
|
struct v4l2_device v4l2_dev;
|
||||||
struct v4l2_async_notifier notifier;
|
struct v4l2_async_notifier notifier;
|
||||||
|
|
||||||
|
unsigned long reserved_pix_proc_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -212,14 +238,20 @@ struct cal_ctx {
|
|||||||
/* Used to store current pixel format */
|
/* Used to store current pixel format */
|
||||||
struct v4l2_format v_fmt;
|
struct v4l2_format v_fmt;
|
||||||
|
|
||||||
/* Current subdev enumerated format */
|
/* Current subdev enumerated format (legacy) */
|
||||||
const struct cal_format_info **active_fmt;
|
const struct cal_format_info **active_fmt;
|
||||||
unsigned int num_active_fmt;
|
unsigned int num_active_fmt;
|
||||||
|
|
||||||
unsigned int sequence;
|
unsigned int sequence;
|
||||||
struct vb2_queue vb_vidq;
|
struct vb2_queue vb_vidq;
|
||||||
unsigned int index;
|
u8 dma_ctx;
|
||||||
unsigned int cport;
|
u8 cport;
|
||||||
|
u8 csi2_ctx;
|
||||||
|
u8 pix_proc;
|
||||||
|
u8 vc;
|
||||||
|
u8 datatype;
|
||||||
|
|
||||||
|
bool use_pix_proc;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unsigned int cal_debug;
|
extern unsigned int cal_debug;
|
||||||
@ -237,11 +269,11 @@ extern bool cal_mc_api;
|
|||||||
dev_err((cal)->dev, fmt, ##arg)
|
dev_err((cal)->dev, fmt, ##arg)
|
||||||
|
|
||||||
#define ctx_dbg(level, ctx, fmt, arg...) \
|
#define ctx_dbg(level, ctx, fmt, arg...) \
|
||||||
cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg)
|
cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
|
||||||
#define ctx_info(ctx, fmt, arg...) \
|
#define ctx_info(ctx, fmt, arg...) \
|
||||||
cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg)
|
cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
|
||||||
#define ctx_err(ctx, fmt, arg...) \
|
#define ctx_err(ctx, fmt, arg...) \
|
||||||
cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->index, ##arg)
|
cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
|
||||||
|
|
||||||
#define phy_dbg(level, phy, fmt, arg...) \
|
#define phy_dbg(level, phy, fmt, arg...) \
|
||||||
cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
|
cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
|
||||||
@ -297,6 +329,8 @@ struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
|
|||||||
unsigned int instance);
|
unsigned int instance);
|
||||||
void cal_camerarx_destroy(struct cal_camerarx *phy);
|
void cal_camerarx_destroy(struct cal_camerarx *phy);
|
||||||
|
|
||||||
|
int cal_ctx_prepare(struct cal_ctx *ctx);
|
||||||
|
void cal_ctx_unprepare(struct cal_ctx *ctx);
|
||||||
void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr);
|
void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr);
|
||||||
void cal_ctx_start(struct cal_ctx *ctx);
|
void cal_ctx_start(struct cal_ctx *ctx);
|
||||||
void cal_ctx_stop(struct cal_ctx *ctx);
|
void cal_ctx_stop(struct cal_ctx *ctx);
|
||||||
|
@ -72,22 +72,8 @@
|
|||||||
#define CAL_CSI2_TIMING(m) (0x314U + (m) * 0x80U)
|
#define CAL_CSI2_TIMING(m) (0x314U + (m) * 0x80U)
|
||||||
#define CAL_CSI2_VC_IRQENABLE(m) (0x318U + (m) * 0x80U)
|
#define CAL_CSI2_VC_IRQENABLE(m) (0x318U + (m) * 0x80U)
|
||||||
#define CAL_CSI2_VC_IRQSTATUS(m) (0x328U + (m) * 0x80U)
|
#define CAL_CSI2_VC_IRQSTATUS(m) (0x328U + (m) * 0x80U)
|
||||||
#define CAL_CSI2_CTX0(m) (0x330U + (m) * 0x80U)
|
#define CAL_CSI2_CTX(phy, csi2_ctx) (0x330U + (phy) * 0x80U + (csi2_ctx) * 4)
|
||||||
#define CAL_CSI2_CTX1(m) (0x334U + (m) * 0x80U)
|
#define CAL_CSI2_STATUS(phy, csi2_ctx) (0x350U + (phy) * 0x80U + (csi2_ctx) * 4)
|
||||||
#define CAL_CSI2_CTX2(m) (0x338U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_CTX3(m) (0x33cU + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_CTX4(m) (0x340U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_CTX5(m) (0x344U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_CTX6(m) (0x348U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_CTX7(m) (0x34cU + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS0(m) (0x350U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS1(m) (0x354U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS2(m) (0x358U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS3(m) (0x35cU + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS4(m) (0x360U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS5(m) (0x364U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS6(m) (0x368U + (m) * 0x80U)
|
|
||||||
#define CAL_CSI2_STATUS7(m) (0x36cU + (m) * 0x80U)
|
|
||||||
|
|
||||||
/* CAL CSI2 PHY register offsets */
|
/* CAL CSI2 PHY register offsets */
|
||||||
#define CAL_CSI2_PHY_REG0 0x000
|
#define CAL_CSI2_PHY_REG0 0x000
|
||||||
@ -139,7 +125,8 @@
|
|||||||
#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0 0
|
#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0 0
|
||||||
#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0 0
|
#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0 0
|
||||||
|
|
||||||
#define CAL_HL_IRQ_MASK(m) BIT(m)
|
#define CAL_HL_IRQ_WDMA_END_MASK(m) BIT(m)
|
||||||
|
#define CAL_HL_IRQ_WDMA_START_MASK(m) BIT(m)
|
||||||
|
|
||||||
#define CAL_HL_IRQ_OCPO_ERR_MASK BIT(6)
|
#define CAL_HL_IRQ_OCPO_ERR_MASK BIT(6)
|
||||||
|
|
||||||
@ -419,32 +406,16 @@
|
|||||||
#define CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK BIT(14)
|
#define CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK BIT(14)
|
||||||
#define CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK BIT(15)
|
#define CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK BIT(15)
|
||||||
|
|
||||||
#define CAL_CSI2_VC_IRQ_FS_IRQ_0_MASK BIT(0)
|
#define CAL_CSI2_VC_IRQ_FS_IRQ_MASK(n) BIT(0 + ((n) * 8))
|
||||||
#define CAL_CSI2_VC_IRQ_FE_IRQ_0_MASK BIT(1)
|
#define CAL_CSI2_VC_IRQ_FE_IRQ_MASK(n) BIT(1 + ((n) * 8))
|
||||||
#define CAL_CSI2_VC_IRQ_LS_IRQ_0_MASK BIT(2)
|
#define CAL_CSI2_VC_IRQ_LS_IRQ_MASK(n) BIT(2 + ((n) * 8))
|
||||||
#define CAL_CSI2_VC_IRQ_LE_IRQ_0_MASK BIT(3)
|
#define CAL_CSI2_VC_IRQ_LE_IRQ_MASK(n) BIT(3 + ((n) * 8))
|
||||||
#define CAL_CSI2_VC_IRQ_CS_IRQ_0_MASK BIT(4)
|
#define CAL_CSI2_VC_IRQ_CS_IRQ_MASK(n) BIT(4 + ((n) * 8))
|
||||||
#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_0_MASK BIT(5)
|
#define CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(n) BIT(5 + ((n) * 8))
|
||||||
#define CAL_CSI2_VC_IRQ_FS_IRQ_1_MASK BIT(8)
|
|
||||||
#define CAL_CSI2_VC_IRQ_FE_IRQ_1_MASK BIT(9)
|
|
||||||
#define CAL_CSI2_VC_IRQ_LS_IRQ_1_MASK BIT(10)
|
|
||||||
#define CAL_CSI2_VC_IRQ_LE_IRQ_1_MASK BIT(11)
|
|
||||||
#define CAL_CSI2_VC_IRQ_CS_IRQ_1_MASK BIT(12)
|
|
||||||
#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_1_MASK BIT(13)
|
|
||||||
#define CAL_CSI2_VC_IRQ_FS_IRQ_2_MASK BIT(16)
|
|
||||||
#define CAL_CSI2_VC_IRQ_FE_IRQ_2_MASK BIT(17)
|
|
||||||
#define CAL_CSI2_VC_IRQ_LS_IRQ_2_MASK BIT(18)
|
|
||||||
#define CAL_CSI2_VC_IRQ_LE_IRQ_2_MASK BIT(19)
|
|
||||||
#define CAL_CSI2_VC_IRQ_CS_IRQ_2_MASK BIT(20)
|
|
||||||
#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_2_MASK BIT(21)
|
|
||||||
#define CAL_CSI2_VC_IRQ_FS_IRQ_3_MASK BIT(24)
|
|
||||||
#define CAL_CSI2_VC_IRQ_FE_IRQ_3_MASK BIT(25)
|
|
||||||
#define CAL_CSI2_VC_IRQ_LS_IRQ_3_MASK BIT(26)
|
|
||||||
#define CAL_CSI2_VC_IRQ_LE_IRQ_3_MASK BIT(27)
|
|
||||||
#define CAL_CSI2_VC_IRQ_CS_IRQ_3_MASK BIT(28)
|
|
||||||
#define CAL_CSI2_VC_IRQ_ECC_CORRECTION0_IRQ_3_MASK BIT(29)
|
|
||||||
|
|
||||||
#define CAL_CSI2_CTX_DT_MASK GENMASK(5, 0)
|
#define CAL_CSI2_CTX_DT_MASK GENMASK(5, 0)
|
||||||
|
#define CAL_CSI2_CTX_DT_DISABLED 0
|
||||||
|
#define CAL_CSI2_CTX_DT_ANY 1
|
||||||
#define CAL_CSI2_CTX_VC_MASK GENMASK(7, 6)
|
#define CAL_CSI2_CTX_VC_MASK GENMASK(7, 6)
|
||||||
#define CAL_CSI2_CTX_CPORT_MASK GENMASK(12, 8)
|
#define CAL_CSI2_CTX_CPORT_MASK GENMASK(12, 8)
|
||||||
#define CAL_CSI2_CTX_ATT_MASK BIT(13)
|
#define CAL_CSI2_CTX_ATT_MASK BIT(13)
|
||||||
|
@ -676,9 +676,9 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
|
|||||||
* rectangles.
|
* rectangles.
|
||||||
*/
|
*/
|
||||||
entity->config = v4l2_subdev_alloc_state(&entity->subdev);
|
entity->config = v4l2_subdev_alloc_state(&entity->subdev);
|
||||||
if (entity->config == NULL) {
|
if (IS_ERR(entity->config)) {
|
||||||
media_entity_cleanup(&entity->subdev.entity);
|
media_entity_cleanup(&entity->subdev.entity);
|
||||||
return -ENOMEM;
|
return PTR_ERR(entity->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -246,6 +246,16 @@ config IR_MESON
|
|||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called meson-ir.
|
module will be called meson-ir.
|
||||||
|
|
||||||
|
config IR_MESON_TX
|
||||||
|
tristate "Amlogic Meson IR TX"
|
||||||
|
depends on ARCH_MESON || COMPILE_TEST
|
||||||
|
help
|
||||||
|
Say Y if you want to use the IR transmitter available on
|
||||||
|
Amlogic Meson SoCs.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called meson-ir-tx.
|
||||||
|
|
||||||
config IR_MTK
|
config IR_MTK
|
||||||
tristate "Mediatek IR remote receiver"
|
tristate "Mediatek IR remote receiver"
|
||||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||||
|
@ -28,6 +28,7 @@ obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
|
|||||||
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
|
obj-$(CONFIG_IR_MCEUSB) += mceusb.o
|
||||||
obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
|
obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
|
||||||
obj-$(CONFIG_IR_MESON) += meson-ir.o
|
obj-$(CONFIG_IR_MESON) += meson-ir.o
|
||||||
|
obj-$(CONFIG_IR_MESON_TX) += meson-ir-tx.o
|
||||||
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
|
obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
|
||||||
obj-$(CONFIG_IR_ENE) += ene_ir.o
|
obj-$(CONFIG_IR_ENE) += ene_ir.o
|
||||||
obj-$(CONFIG_IR_REDRAT3) += redrat3.o
|
obj-$(CONFIG_IR_REDRAT3) += redrat3.o
|
||||||
|
@ -1052,7 +1052,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
|
|||||||
rdev->device_name = "ENE eHome Infrared Remote Receiver";
|
rdev->device_name = "ENE eHome Infrared Remote Receiver";
|
||||||
|
|
||||||
if (dev->hw_learning_and_tx_capable) {
|
if (dev->hw_learning_and_tx_capable) {
|
||||||
rdev->s_learning_mode = ene_set_learning_mode;
|
rdev->s_wideband_receiver = ene_set_learning_mode;
|
||||||
init_completion(&dev->tx_complete);
|
init_completion(&dev->tx_complete);
|
||||||
rdev->tx_ir = ene_transmit;
|
rdev->tx_ir = ene_transmit;
|
||||||
rdev->s_tx_mask = ene_set_tx_mask;
|
rdev->s_tx_mask = ene_set_tx_mask;
|
||||||
|
@ -412,7 +412,7 @@ static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||||||
val |= LIRC_CAN_SET_REC_CARRIER |
|
val |= LIRC_CAN_SET_REC_CARRIER |
|
||||||
LIRC_CAN_SET_REC_CARRIER_RANGE;
|
LIRC_CAN_SET_REC_CARRIER_RANGE;
|
||||||
|
|
||||||
if (dev->s_learning_mode)
|
if (dev->s_wideband_receiver)
|
||||||
val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
|
val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
|
||||||
|
|
||||||
if (dev->s_carrier_report)
|
if (dev->s_carrier_report)
|
||||||
@ -519,10 +519,10 @@ static long lirc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LIRC_SET_WIDEBAND_RECEIVER:
|
case LIRC_SET_WIDEBAND_RECEIVER:
|
||||||
if (!dev->s_learning_mode)
|
if (!dev->s_wideband_receiver)
|
||||||
ret = -ENOTTY;
|
ret = -ENOTTY;
|
||||||
else
|
else
|
||||||
ret = dev->s_learning_mode(dev, !!val);
|
ret = dev->s_wideband_receiver(dev, !!val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIRC_SET_MEASURE_CARRIER_MODE:
|
case LIRC_SET_MEASURE_CARRIER_MODE:
|
||||||
|
@ -1630,7 +1630,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
|
|||||||
rc->tx_ir = mceusb_tx_ir;
|
rc->tx_ir = mceusb_tx_ir;
|
||||||
}
|
}
|
||||||
if (ir->flags.rx2 > 0) {
|
if (ir->flags.rx2 > 0) {
|
||||||
rc->s_learning_mode = mceusb_set_rx_wideband;
|
rc->s_wideband_receiver = mceusb_set_rx_wideband;
|
||||||
rc->s_carrier_report = mceusb_set_rx_carrier_report;
|
rc->s_carrier_report = mceusb_set_rx_carrier_report;
|
||||||
}
|
}
|
||||||
rc->driver_name = DRIVER_NAME;
|
rc->driver_name = DRIVER_NAME;
|
||||||
|
407
drivers/media/rc/meson-ir-tx.c
Normal file
407
drivers/media/rc/meson-ir-tx.c
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/**
|
||||||
|
* meson-ir-tx.c - Amlogic Meson IR TX driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, SberDevices. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Author: Viktor Prutyanov <viktor.prutyanov@phystech.edu>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <media/rc-core.h>
|
||||||
|
|
||||||
|
#define DEVICE_NAME "Meson IR TX"
|
||||||
|
#define DRIVER_NAME "meson-ir-tx"
|
||||||
|
|
||||||
|
#define MIRTX_DEFAULT_CARRIER 38000
|
||||||
|
#define MIRTX_DEFAULT_DUTY_CYCLE 50
|
||||||
|
#define MIRTX_FIFO_THD 32
|
||||||
|
|
||||||
|
#define IRB_MOD_1US_CLK_RATE 1000000
|
||||||
|
|
||||||
|
#define IRB_FIFO_LEN 128
|
||||||
|
|
||||||
|
#define IRB_ADDR0 0x0
|
||||||
|
#define IRB_ADDR1 0x4
|
||||||
|
#define IRB_ADDR2 0x8
|
||||||
|
#define IRB_ADDR3 0xc
|
||||||
|
|
||||||
|
#define IRB_MAX_DELAY (1 << 10)
|
||||||
|
#define IRB_DELAY_MASK (IRB_MAX_DELAY - 1)
|
||||||
|
|
||||||
|
/* IRCTRL_IR_BLASTER_ADDR0 */
|
||||||
|
#define IRB_MOD_CLK(x) ((x) << 12)
|
||||||
|
#define IRB_MOD_SYS_CLK 0
|
||||||
|
#define IRB_MOD_XTAL3_CLK 1
|
||||||
|
#define IRB_MOD_1US_CLK 2
|
||||||
|
#define IRB_MOD_10US_CLK 3
|
||||||
|
#define IRB_INIT_HIGH BIT(2)
|
||||||
|
#define IRB_ENABLE BIT(0)
|
||||||
|
|
||||||
|
/* IRCTRL_IR_BLASTER_ADDR2 */
|
||||||
|
#define IRB_MOD_COUNT(lo, hi) ((((lo) - 1) << 16) | ((hi) - 1))
|
||||||
|
|
||||||
|
/* IRCTRL_IR_BLASTER_ADDR2 */
|
||||||
|
#define IRB_WRITE_FIFO BIT(16)
|
||||||
|
#define IRB_MOD_ENABLE BIT(12)
|
||||||
|
#define IRB_TB_1US (0x0 << 10)
|
||||||
|
#define IRB_TB_10US (0x1 << 10)
|
||||||
|
#define IRB_TB_100US (0x2 << 10)
|
||||||
|
#define IRB_TB_MOD_CLK (0x3 << 10)
|
||||||
|
|
||||||
|
/* IRCTRL_IR_BLASTER_ADDR3 */
|
||||||
|
#define IRB_FIFO_THD_PENDING BIT(16)
|
||||||
|
#define IRB_FIFO_IRQ_ENABLE BIT(8)
|
||||||
|
|
||||||
|
struct meson_irtx {
|
||||||
|
struct device *dev;
|
||||||
|
void __iomem *reg_base;
|
||||||
|
u32 *buf;
|
||||||
|
unsigned int buf_len;
|
||||||
|
unsigned int buf_head;
|
||||||
|
unsigned int carrier;
|
||||||
|
unsigned int duty_cycle;
|
||||||
|
/* Locks buf */
|
||||||
|
spinlock_t lock;
|
||||||
|
struct completion completion;
|
||||||
|
unsigned long clk_rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void meson_irtx_set_mod(struct meson_irtx *ir)
|
||||||
|
{
|
||||||
|
unsigned int cnt = DIV_ROUND_CLOSEST(ir->clk_rate, ir->carrier);
|
||||||
|
unsigned int pulse_cnt = DIV_ROUND_CLOSEST(cnt * ir->duty_cycle, 100);
|
||||||
|
unsigned int space_cnt = cnt - pulse_cnt;
|
||||||
|
|
||||||
|
dev_dbg(ir->dev, "F_mod = %uHz, T_mod = %luns, duty_cycle = %u%%\n",
|
||||||
|
ir->carrier, NSEC_PER_SEC / ir->clk_rate * cnt,
|
||||||
|
100 * pulse_cnt / cnt);
|
||||||
|
|
||||||
|
writel(IRB_MOD_COUNT(pulse_cnt, space_cnt),
|
||||||
|
ir->reg_base + IRB_ADDR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void meson_irtx_setup(struct meson_irtx *ir, unsigned int clk_nr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Disable the TX, set modulator clock tick and set initialize
|
||||||
|
* output to be high. Set up carrier frequency and duty cycle. Then
|
||||||
|
* unset initialize output. Enable FIFO interrupt, set FIFO interrupt
|
||||||
|
* threshold. Finally, enable the transmitter back.
|
||||||
|
*/
|
||||||
|
writel(~IRB_ENABLE & (IRB_MOD_CLK(clk_nr) | IRB_INIT_HIGH),
|
||||||
|
ir->reg_base + IRB_ADDR0);
|
||||||
|
meson_irtx_set_mod(ir);
|
||||||
|
writel(readl(ir->reg_base + IRB_ADDR0) & ~IRB_INIT_HIGH,
|
||||||
|
ir->reg_base + IRB_ADDR0);
|
||||||
|
writel(IRB_FIFO_IRQ_ENABLE | MIRTX_FIFO_THD,
|
||||||
|
ir->reg_base + IRB_ADDR3);
|
||||||
|
writel(readl(ir->reg_base + IRB_ADDR0) | IRB_ENABLE,
|
||||||
|
ir->reg_base + IRB_ADDR0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 meson_irtx_prepare_pulse(struct meson_irtx *ir, unsigned int time)
|
||||||
|
{
|
||||||
|
unsigned int delay;
|
||||||
|
unsigned int tb = IRB_TB_MOD_CLK;
|
||||||
|
unsigned int tb_us = DIV_ROUND_CLOSEST(USEC_PER_SEC, ir->carrier);
|
||||||
|
|
||||||
|
delay = (DIV_ROUND_CLOSEST(time, tb_us) - 1) & IRB_DELAY_MASK;
|
||||||
|
|
||||||
|
return ((IRB_WRITE_FIFO | IRB_MOD_ENABLE) | tb | delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 meson_irtx_prepare_space(struct meson_irtx *ir, unsigned int time)
|
||||||
|
{
|
||||||
|
unsigned int delay;
|
||||||
|
unsigned int tb = IRB_TB_100US;
|
||||||
|
unsigned int tb_us = 100;
|
||||||
|
|
||||||
|
if (time <= IRB_MAX_DELAY) {
|
||||||
|
tb = IRB_TB_1US;
|
||||||
|
tb_us = 1;
|
||||||
|
} else if (time <= 10 * IRB_MAX_DELAY) {
|
||||||
|
tb = IRB_TB_10US;
|
||||||
|
tb_us = 10;
|
||||||
|
} else if (time <= 100 * IRB_MAX_DELAY) {
|
||||||
|
tb = IRB_TB_100US;
|
||||||
|
tb_us = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay = (DIV_ROUND_CLOSEST(time, tb_us) - 1) & IRB_DELAY_MASK;
|
||||||
|
|
||||||
|
return ((IRB_WRITE_FIFO & ~IRB_MOD_ENABLE) | tb | delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void meson_irtx_send_buffer(struct meson_irtx *ir)
|
||||||
|
{
|
||||||
|
unsigned int nr = 0;
|
||||||
|
unsigned int max_fifo_level = IRB_FIFO_LEN - MIRTX_FIFO_THD;
|
||||||
|
|
||||||
|
while (ir->buf_head < ir->buf_len && nr < max_fifo_level) {
|
||||||
|
writel(ir->buf[ir->buf_head], ir->reg_base + IRB_ADDR2);
|
||||||
|
|
||||||
|
ir->buf_head++;
|
||||||
|
nr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool meson_irtx_check_buf(struct meson_irtx *ir,
|
||||||
|
unsigned int *buf, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
unsigned int max_tb_us;
|
||||||
|
/*
|
||||||
|
* Max space timebase is 100 us.
|
||||||
|
* Pulse timebase equals to carrier period.
|
||||||
|
*/
|
||||||
|
if (i % 2 == 0)
|
||||||
|
max_tb_us = USEC_PER_SEC / ir->carrier;
|
||||||
|
else
|
||||||
|
max_tb_us = 100;
|
||||||
|
|
||||||
|
if (buf[i] >= max_tb_us * IRB_MAX_DELAY)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void meson_irtx_fill_buf(struct meson_irtx *ir, u32 *dst_buf,
|
||||||
|
unsigned int *src_buf, unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (i % 2 == 0)
|
||||||
|
dst_buf[i] = meson_irtx_prepare_pulse(ir, src_buf[i]);
|
||||||
|
else
|
||||||
|
dst_buf[i] = meson_irtx_prepare_space(ir, src_buf[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t meson_irtx_irqhandler(int irq, void *data)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct meson_irtx *ir = data;
|
||||||
|
|
||||||
|
writel(readl(ir->reg_base + IRB_ADDR3) & ~IRB_FIFO_THD_PENDING,
|
||||||
|
ir->reg_base + IRB_ADDR3);
|
||||||
|
|
||||||
|
if (completion_done(&ir->completion))
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ir->lock, flags);
|
||||||
|
if (ir->buf_head < ir->buf_len)
|
||||||
|
meson_irtx_send_buffer(ir);
|
||||||
|
else
|
||||||
|
complete(&ir->completion);
|
||||||
|
spin_unlock_irqrestore(&ir->lock, flags);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int meson_irtx_set_carrier(struct rc_dev *rc, u32 carrier)
|
||||||
|
{
|
||||||
|
struct meson_irtx *ir = rc->priv;
|
||||||
|
|
||||||
|
if (carrier == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ir->carrier = carrier;
|
||||||
|
meson_irtx_set_mod(ir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int meson_irtx_set_duty_cycle(struct rc_dev *rc, u32 duty_cycle)
|
||||||
|
{
|
||||||
|
struct meson_irtx *ir = rc->priv;
|
||||||
|
|
||||||
|
ir->duty_cycle = duty_cycle;
|
||||||
|
meson_irtx_set_mod(ir);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void meson_irtx_update_buf(struct meson_irtx *ir, u32 *buf,
|
||||||
|
unsigned int len, unsigned int head)
|
||||||
|
{
|
||||||
|
ir->buf = buf;
|
||||||
|
ir->buf_len = len;
|
||||||
|
ir->buf_head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int meson_irtx_transmit(struct rc_dev *rc, unsigned int *buf,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
struct meson_irtx *ir = rc->priv;
|
||||||
|
u32 *tx_buf;
|
||||||
|
int ret = len;
|
||||||
|
|
||||||
|
if (!meson_irtx_check_buf(ir, buf, len))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
tx_buf = kmalloc_array(len, sizeof(u32), GFP_KERNEL);
|
||||||
|
if (!tx_buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
meson_irtx_fill_buf(ir, tx_buf, buf, len);
|
||||||
|
dev_dbg(ir->dev, "TX buffer filled, length = %u\n", len);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ir->lock, flags);
|
||||||
|
meson_irtx_update_buf(ir, tx_buf, len, 0);
|
||||||
|
reinit_completion(&ir->completion);
|
||||||
|
meson_irtx_send_buffer(ir);
|
||||||
|
spin_unlock_irqrestore(&ir->lock, flags);
|
||||||
|
|
||||||
|
if (!wait_for_completion_timeout(&ir->completion,
|
||||||
|
usecs_to_jiffies(IR_MAX_DURATION)))
|
||||||
|
ret = -ETIMEDOUT;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ir->lock, flags);
|
||||||
|
kfree(ir->buf);
|
||||||
|
meson_irtx_update_buf(ir, NULL, 0, 0);
|
||||||
|
spin_unlock_irqrestore(&ir->lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int meson_irtx_mod_clock_probe(struct meson_irtx *ir,
|
||||||
|
unsigned int *clk_nr)
|
||||||
|
{
|
||||||
|
struct device_node *np = ir->dev->of_node;
|
||||||
|
struct clk *clock;
|
||||||
|
|
||||||
|
if (!np)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
clock = devm_clk_get(ir->dev, "xtal");
|
||||||
|
if (IS_ERR(clock) || clk_prepare_enable(clock))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
*clk_nr = IRB_MOD_XTAL3_CLK;
|
||||||
|
ir->clk_rate = clk_get_rate(clock) / 3;
|
||||||
|
|
||||||
|
if (ir->clk_rate < IRB_MOD_1US_CLK_RATE) {
|
||||||
|
*clk_nr = IRB_MOD_1US_CLK;
|
||||||
|
ir->clk_rate = IRB_MOD_1US_CLK_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(ir->dev, "F_clk = %luHz\n", ir->clk_rate);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init meson_irtx_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct meson_irtx *ir;
|
||||||
|
struct rc_dev *rc;
|
||||||
|
int irq;
|
||||||
|
unsigned int clk_nr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ir = devm_kzalloc(dev, sizeof(*ir), GFP_KERNEL);
|
||||||
|
if (!ir)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ir->reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
|
if (IS_ERR(ir->reg_base))
|
||||||
|
return PTR_ERR(ir->reg_base);
|
||||||
|
|
||||||
|
irq = platform_get_irq(pdev, 0);
|
||||||
|
if (irq < 0) {
|
||||||
|
dev_err(dev, "no irq resource found\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ir->dev = dev;
|
||||||
|
ir->carrier = MIRTX_DEFAULT_CARRIER;
|
||||||
|
ir->duty_cycle = MIRTX_DEFAULT_DUTY_CYCLE;
|
||||||
|
init_completion(&ir->completion);
|
||||||
|
spin_lock_init(&ir->lock);
|
||||||
|
|
||||||
|
ret = meson_irtx_mod_clock_probe(ir, &clk_nr);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "modulator clock setup failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
meson_irtx_setup(ir, clk_nr);
|
||||||
|
|
||||||
|
ret = devm_request_irq(dev, irq,
|
||||||
|
meson_irtx_irqhandler,
|
||||||
|
IRQF_TRIGGER_RISING,
|
||||||
|
DRIVER_NAME, ir);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "irq request failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = rc_allocate_device(RC_DRIVER_IR_RAW_TX);
|
||||||
|
if (!rc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rc->driver_name = DRIVER_NAME;
|
||||||
|
rc->device_name = DEVICE_NAME;
|
||||||
|
rc->priv = ir;
|
||||||
|
|
||||||
|
rc->tx_ir = meson_irtx_transmit;
|
||||||
|
rc->s_tx_carrier = meson_irtx_set_carrier;
|
||||||
|
rc->s_tx_duty_cycle = meson_irtx_set_duty_cycle;
|
||||||
|
|
||||||
|
ret = rc_register_device(rc);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "rc_dev registration failed\n");
|
||||||
|
rc_free_device(rc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int meson_irtx_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct rc_dev *rc = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
rc_unregister_device(rc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id meson_irtx_dt_match[] = {
|
||||||
|
{
|
||||||
|
.compatible = "amlogic,meson-g12a-ir-tx",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, meson_irtx_dt_match);
|
||||||
|
|
||||||
|
static struct platform_driver meson_irtx_pd = {
|
||||||
|
.remove = meson_irtx_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = meson_irtx_dt_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver_probe(meson_irtx_pd, meson_irtx_probe);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("Meson IR TX driver");
|
||||||
|
MODULE_AUTHOR("Viktor Prutyanov <viktor.prutyanov@phystech.edu>");
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -15,12 +15,9 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <media/rc-core.h>
|
#include <media/rc-core.h>
|
||||||
|
|
||||||
#define DRIVER_NAME "rc-loopback"
|
#define DRIVER_NAME "rc-loopback"
|
||||||
#define dprintk(x...) if (debug) printk(KERN_INFO DRIVER_NAME ": " x)
|
#define RXMASK_NARROWBAND 0x1
|
||||||
#define RXMASK_REGULAR 0x1
|
#define RXMASK_WIDEBAND 0x2
|
||||||
#define RXMASK_LEARNING 0x2
|
|
||||||
|
|
||||||
static bool debug;
|
|
||||||
|
|
||||||
struct loopback_dev {
|
struct loopback_dev {
|
||||||
struct rc_dev *dev;
|
struct rc_dev *dev;
|
||||||
@ -28,7 +25,7 @@ struct loopback_dev {
|
|||||||
u32 txcarrier;
|
u32 txcarrier;
|
||||||
u32 txduty;
|
u32 txduty;
|
||||||
bool idle;
|
bool idle;
|
||||||
bool learning;
|
bool wideband;
|
||||||
bool carrierreport;
|
bool carrierreport;
|
||||||
u32 rxcarriermin;
|
u32 rxcarriermin;
|
||||||
u32 rxcarriermax;
|
u32 rxcarriermax;
|
||||||
@ -40,12 +37,12 @@ static int loop_set_tx_mask(struct rc_dev *dev, u32 mask)
|
|||||||
{
|
{
|
||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) {
|
if ((mask & (RXMASK_NARROWBAND | RXMASK_WIDEBAND)) != mask) {
|
||||||
dprintk("invalid tx mask: %u\n", mask);
|
dev_dbg(&dev->dev, "invalid tx mask: %u\n", mask);
|
||||||
return -EINVAL;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk("setting tx mask: %u\n", mask);
|
dev_dbg(&dev->dev, "setting tx mask: %u\n", mask);
|
||||||
lodev->txmask = mask;
|
lodev->txmask = mask;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -54,7 +51,7 @@ static int loop_set_tx_carrier(struct rc_dev *dev, u32 carrier)
|
|||||||
{
|
{
|
||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
dprintk("setting tx carrier: %u\n", carrier);
|
dev_dbg(&dev->dev, "setting tx carrier: %u\n", carrier);
|
||||||
lodev->txcarrier = carrier;
|
lodev->txcarrier = carrier;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -64,11 +61,11 @@ static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
|
|||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
if (duty_cycle < 1 || duty_cycle > 99) {
|
if (duty_cycle < 1 || duty_cycle > 99) {
|
||||||
dprintk("invalid duty cycle: %u\n", duty_cycle);
|
dev_dbg(&dev->dev, "invalid duty cycle: %u\n", duty_cycle);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk("setting duty cycle: %u\n", duty_cycle);
|
dev_dbg(&dev->dev, "setting duty cycle: %u\n", duty_cycle);
|
||||||
lodev->txduty = duty_cycle;
|
lodev->txduty = duty_cycle;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -78,11 +75,11 @@ static int loop_set_rx_carrier_range(struct rc_dev *dev, u32 min, u32 max)
|
|||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
if (min < 1 || min > max) {
|
if (min < 1 || min > max) {
|
||||||
dprintk("invalid rx carrier range %u to %u\n", min, max);
|
dev_dbg(&dev->dev, "invalid rx carrier range %u to %u\n", min, max);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk("setting rx carrier range %u to %u\n", min, max);
|
dev_dbg(&dev->dev, "setting rx carrier range %u to %u\n", min, max);
|
||||||
lodev->rxcarriermin = min;
|
lodev->rxcarriermin = min;
|
||||||
lodev->rxcarriermax = max;
|
lodev->rxcarriermax = max;
|
||||||
return 0;
|
return 0;
|
||||||
@ -97,25 +94,33 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
|
|||||||
|
|
||||||
if (lodev->txcarrier < lodev->rxcarriermin ||
|
if (lodev->txcarrier < lodev->rxcarriermin ||
|
||||||
lodev->txcarrier > lodev->rxcarriermax) {
|
lodev->txcarrier > lodev->rxcarriermax) {
|
||||||
dprintk("ignoring tx, carrier out of range\n");
|
dev_dbg(&dev->dev, "ignoring tx, carrier out of range\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lodev->learning)
|
if (lodev->wideband)
|
||||||
rxmask = RXMASK_LEARNING;
|
rxmask = RXMASK_WIDEBAND;
|
||||||
else
|
else
|
||||||
rxmask = RXMASK_REGULAR;
|
rxmask = RXMASK_NARROWBAND;
|
||||||
|
|
||||||
if (!(rxmask & lodev->txmask)) {
|
if (!(rxmask & lodev->txmask)) {
|
||||||
dprintk("ignoring tx, rx mask mismatch\n");
|
dev_dbg(&dev->dev, "ignoring tx, rx mask mismatch\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
rawir.pulse = i % 2 ? false : true;
|
rawir.pulse = i % 2 ? false : true;
|
||||||
rawir.duration = txbuf[i];
|
rawir.duration = txbuf[i];
|
||||||
if (rawir.duration)
|
|
||||||
ir_raw_event_store_with_filter(dev, &rawir);
|
ir_raw_event_store_with_filter(dev, &rawir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lodev->carrierreport) {
|
||||||
|
rawir.pulse = false;
|
||||||
|
rawir.carrier_report = true;
|
||||||
|
rawir.carrier = lodev->txcarrier;
|
||||||
|
|
||||||
|
ir_raw_event_store(dev, &rawir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fake a silence long enough to cause us to go idle */
|
/* Fake a silence long enough to cause us to go idle */
|
||||||
@ -134,18 +139,18 @@ static void loop_set_idle(struct rc_dev *dev, bool enable)
|
|||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
if (lodev->idle != enable) {
|
if (lodev->idle != enable) {
|
||||||
dprintk("%sing idle mode\n", enable ? "enter" : "exit");
|
dev_dbg(&dev->dev, "%sing idle mode\n", enable ? "enter" : "exit");
|
||||||
lodev->idle = enable;
|
lodev->idle = enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int loop_set_learning_mode(struct rc_dev *dev, int enable)
|
static int loop_set_wideband_receiver(struct rc_dev *dev, int enable)
|
||||||
{
|
{
|
||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
if (lodev->learning != enable) {
|
if (lodev->wideband != enable) {
|
||||||
dprintk("%sing learning mode\n", enable ? "enter" : "exit");
|
dev_dbg(&dev->dev, "using %sband receiver\n", enable ? "wide" : "narrow");
|
||||||
lodev->learning = !!enable;
|
lodev->wideband = !!enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -156,7 +161,7 @@ static int loop_set_carrier_report(struct rc_dev *dev, int enable)
|
|||||||
struct loopback_dev *lodev = dev->priv;
|
struct loopback_dev *lodev = dev->priv;
|
||||||
|
|
||||||
if (lodev->carrierreport != enable) {
|
if (lodev->carrierreport != enable) {
|
||||||
dprintk("%sabling carrier reports\n", enable ? "en" : "dis");
|
dev_dbg(&dev->dev, "%sabling carrier reports\n", enable ? "en" : "dis");
|
||||||
lodev->carrierreport = !!enable;
|
lodev->carrierreport = !!enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,10 +209,8 @@ static int __init loop_init(void)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
rc = rc_allocate_device(RC_DRIVER_IR_RAW);
|
||||||
if (!rc) {
|
if (!rc)
|
||||||
printk(KERN_ERR DRIVER_NAME ": rc_dev allocation failed\n");
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
rc->device_name = "rc-core loopback device";
|
rc->device_name = "rc-core loopback device";
|
||||||
rc->input_phys = "rc-core/virtual";
|
rc->input_phys = "rc-core/virtual";
|
||||||
@ -219,9 +222,9 @@ static int __init loop_init(void)
|
|||||||
rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
|
||||||
rc->allowed_wakeup_protocols = RC_PROTO_BIT_ALL_IR_ENCODER;
|
rc->allowed_wakeup_protocols = RC_PROTO_BIT_ALL_IR_ENCODER;
|
||||||
rc->encode_wakeup = true;
|
rc->encode_wakeup = true;
|
||||||
rc->timeout = MS_TO_US(100); /* 100 ms */
|
rc->timeout = IR_DEFAULT_TIMEOUT;
|
||||||
rc->min_timeout = 1;
|
rc->min_timeout = 1;
|
||||||
rc->max_timeout = UINT_MAX;
|
rc->max_timeout = IR_MAX_TIMEOUT;
|
||||||
rc->rx_resolution = 1;
|
rc->rx_resolution = 1;
|
||||||
rc->tx_resolution = 1;
|
rc->tx_resolution = 1;
|
||||||
rc->s_tx_mask = loop_set_tx_mask;
|
rc->s_tx_mask = loop_set_tx_mask;
|
||||||
@ -230,22 +233,22 @@ static int __init loop_init(void)
|
|||||||
rc->s_rx_carrier_range = loop_set_rx_carrier_range;
|
rc->s_rx_carrier_range = loop_set_rx_carrier_range;
|
||||||
rc->tx_ir = loop_tx_ir;
|
rc->tx_ir = loop_tx_ir;
|
||||||
rc->s_idle = loop_set_idle;
|
rc->s_idle = loop_set_idle;
|
||||||
rc->s_learning_mode = loop_set_learning_mode;
|
rc->s_wideband_receiver = loop_set_wideband_receiver;
|
||||||
rc->s_carrier_report = loop_set_carrier_report;
|
rc->s_carrier_report = loop_set_carrier_report;
|
||||||
rc->s_wakeup_filter = loop_set_wakeup_filter;
|
rc->s_wakeup_filter = loop_set_wakeup_filter;
|
||||||
|
|
||||||
loopdev.txmask = RXMASK_REGULAR;
|
loopdev.txmask = RXMASK_NARROWBAND;
|
||||||
loopdev.txcarrier = 36000;
|
loopdev.txcarrier = 36000;
|
||||||
loopdev.txduty = 50;
|
loopdev.txduty = 50;
|
||||||
loopdev.rxcarriermin = 1;
|
loopdev.rxcarriermin = 1;
|
||||||
loopdev.rxcarriermax = ~0;
|
loopdev.rxcarriermax = ~0;
|
||||||
loopdev.idle = true;
|
loopdev.idle = true;
|
||||||
loopdev.learning = false;
|
loopdev.wideband = false;
|
||||||
loopdev.carrierreport = false;
|
loopdev.carrierreport = false;
|
||||||
|
|
||||||
ret = rc_register_device(rc);
|
ret = rc_register_device(rc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(KERN_ERR DRIVER_NAME ": rc_dev registration failed\n");
|
dev_err(&rc->dev, "rc_dev registration failed\n");
|
||||||
rc_free_device(rc);
|
rc_free_device(rc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -262,9 +265,6 @@ static void __exit loop_exit(void)
|
|||||||
module_init(loop_init);
|
module_init(loop_init);
|
||||||
module_exit(loop_exit);
|
module_exit(loop_exit);
|
||||||
|
|
||||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
|
||||||
MODULE_PARM_DESC(debug, "Enable debug messages");
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Loopback device for rc-core debugging");
|
MODULE_DESCRIPTION("Loopback device for rc-core debugging");
|
||||||
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
|
MODULE_AUTHOR("David Härdeman <david@hardeman.nu>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -1940,7 +1940,7 @@ int rc_register_device(struct rc_dev *dev)
|
|||||||
kfree(path);
|
kfree(path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* once the the input device is registered in rc_setup_rx_device,
|
* once the input device is registered in rc_setup_rx_device,
|
||||||
* userspace can open the input device and rc_open() will be called
|
* userspace can open the input device and rc_open() will be called
|
||||||
* as a result. This results in driver code being allowed to submit
|
* as a result. This results in driver code being allowed to submit
|
||||||
* keycodes with rc_keydown, so lirc must be registered first.
|
* keycodes with rc_keydown, so lirc must be registered first.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* based heavily on the work of Stephen Cox, with additional
|
* based heavily on the work of Stephen Cox, with additional
|
||||||
* help from RedRat Ltd.
|
* help from RedRat Ltd.
|
||||||
*
|
*
|
||||||
* This driver began life based an an old version of the first-generation
|
* This driver began life based on an old version of the first-generation
|
||||||
* lirc_mceusb driver from the lirc 0.7.2 distribution. It was then
|
* lirc_mceusb driver from the lirc 0.7.2 distribution. It was then
|
||||||
* significantly rewritten by Stephen Cox with the aid of RedRat Ltd's
|
* significantly rewritten by Stephen Cox with the aid of RedRat Ltd's
|
||||||
* Chris Dodge.
|
* Chris Dodge.
|
||||||
|
@ -265,8 +265,6 @@ static void streamzap_callback(struct urb *urb)
|
|||||||
|
|
||||||
ir_raw_event_handle(sz->rdev);
|
ir_raw_event_handle(sz->rdev);
|
||||||
usb_submit_urb(urb, GFP_ATOMIC);
|
usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
|
static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
|
||||||
|
@ -524,13 +524,13 @@ cxd2880_spi_probe(struct spi_device *spi)
|
|||||||
if (IS_ERR(dvb_spi->vcc_supply)) {
|
if (IS_ERR(dvb_spi->vcc_supply)) {
|
||||||
if (PTR_ERR(dvb_spi->vcc_supply) == -EPROBE_DEFER) {
|
if (PTR_ERR(dvb_spi->vcc_supply) == -EPROBE_DEFER) {
|
||||||
ret = -EPROBE_DEFER;
|
ret = -EPROBE_DEFER;
|
||||||
goto fail_adapter;
|
goto fail_regulator;
|
||||||
}
|
}
|
||||||
dvb_spi->vcc_supply = NULL;
|
dvb_spi->vcc_supply = NULL;
|
||||||
} else {
|
} else {
|
||||||
ret = regulator_enable(dvb_spi->vcc_supply);
|
ret = regulator_enable(dvb_spi->vcc_supply);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail_adapter;
|
goto fail_regulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvb_spi->spi = spi;
|
dvb_spi->spi = spi;
|
||||||
@ -618,6 +618,9 @@ cxd2880_spi_probe(struct spi_device *spi)
|
|||||||
fail_attach:
|
fail_attach:
|
||||||
dvb_unregister_adapter(&dvb_spi->adapter);
|
dvb_unregister_adapter(&dvb_spi->adapter);
|
||||||
fail_adapter:
|
fail_adapter:
|
||||||
|
if (!dvb_spi->vcc_supply)
|
||||||
|
regulator_disable(dvb_spi->vcc_supply);
|
||||||
|
fail_regulator:
|
||||||
kfree(dvb_spi);
|
kfree(dvb_spi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -282,5 +282,5 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
|
|||||||
snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d",
|
snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d",
|
||||||
dev->inst, is_source ? "out" : "cap", idx);
|
dev->inst, is_source ? "out" : "cap", idx);
|
||||||
return cec_allocate_adapter(&vivid_cec_adap_ops, dev,
|
return cec_allocate_adapter(&vivid_cec_adap_ops, dev,
|
||||||
name, caps, 1);
|
name, caps, CEC_MAX_LOG_ADDRS);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ config DVB_USB_AF9035
|
|||||||
tristate "Afatech AF9035 DVB-T USB2.0 support"
|
tristate "Afatech AF9035 DVB-T USB2.0 support"
|
||||||
depends on DVB_USB_V2
|
depends on DVB_USB_V2
|
||||||
select DVB_AF9033
|
select DVB_AF9033
|
||||||
|
select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
|
||||||
|
select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
|
||||||
select MEDIA_TUNER_TUA9001 if MEDIA_SUBDRV_AUTOSELECT
|
select MEDIA_TUNER_TUA9001 if MEDIA_SUBDRV_AUTOSELECT
|
||||||
select MEDIA_TUNER_FC0011 if MEDIA_SUBDRV_AUTOSELECT
|
select MEDIA_TUNER_FC0011 if MEDIA_SUBDRV_AUTOSELECT
|
||||||
select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
|
select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
|
||||||
|
@ -210,6 +210,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
|
|||||||
/* register I2C device */
|
/* register I2C device */
|
||||||
client = i2c_new_client_device(adapter, &board_info);
|
client = i2c_new_client_device(adapter, &board_info);
|
||||||
if (!i2c_client_has_driver(client)) {
|
if (!i2c_client_has_driver(client)) {
|
||||||
|
dev_err(&intf->dev, "failed to bind i2c device to %s driver\n", type);
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +541,9 @@ static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
|
|||||||
si2168_config.i2c_adapter = &i2c_adapter;
|
si2168_config.i2c_adapter = &i2c_adapter;
|
||||||
si2168_config.fe = &adap->fe[0];
|
si2168_config.fe = &adap->fe[0];
|
||||||
si2168_config.ts_mode = SI2168_TS_PARALLEL;
|
si2168_config.ts_mode = SI2168_TS_PARALLEL;
|
||||||
if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230C2)
|
if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230C2 ||
|
||||||
|
le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230C2_LITE ||
|
||||||
|
le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230A)
|
||||||
si2168_config.ts_mode |= SI2168_TS_CLK_MANUAL;
|
si2168_config.ts_mode |= SI2168_TS_CLK_MANUAL;
|
||||||
si2168_config.ts_clock_inv = 1;
|
si2168_config.ts_clock_inv = 1;
|
||||||
|
|
||||||
@ -577,15 +579,24 @@ static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
|
|||||||
|
|
||||||
static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
|
static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
|
||||||
{
|
{
|
||||||
dvbsky_gpio_ctrl(d, 0x04, 1);
|
if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230A) {
|
||||||
msleep(20);
|
dvbsky_gpio_ctrl(d, 0x87, 0);
|
||||||
dvbsky_gpio_ctrl(d, 0x83, 0);
|
msleep(20);
|
||||||
dvbsky_gpio_ctrl(d, 0xc0, 1);
|
dvbsky_gpio_ctrl(d, 0x86, 1);
|
||||||
msleep(100);
|
dvbsky_gpio_ctrl(d, 0x80, 0);
|
||||||
dvbsky_gpio_ctrl(d, 0x83, 1);
|
msleep(100);
|
||||||
dvbsky_gpio_ctrl(d, 0xc0, 0);
|
dvbsky_gpio_ctrl(d, 0x80, 1);
|
||||||
msleep(50);
|
msleep(50);
|
||||||
|
} else {
|
||||||
|
dvbsky_gpio_ctrl(d, 0x04, 1);
|
||||||
|
msleep(20);
|
||||||
|
dvbsky_gpio_ctrl(d, 0x83, 0);
|
||||||
|
dvbsky_gpio_ctrl(d, 0xc0, 1);
|
||||||
|
msleep(100);
|
||||||
|
dvbsky_gpio_ctrl(d, 0x83, 1);
|
||||||
|
dvbsky_gpio_ctrl(d, 0xc0, 0);
|
||||||
|
msleep(50);
|
||||||
|
}
|
||||||
return WARM;
|
return WARM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,6 +800,12 @@ static const struct usb_device_id dvbsky_id_table[] = {
|
|||||||
{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2,
|
{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2,
|
||||||
&mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230C v2",
|
&mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230C v2",
|
||||||
RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
|
RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
|
||||||
|
{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2_LITE,
|
||||||
|
&mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230C v2 Lite",
|
||||||
|
NULL) },
|
||||||
|
{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230A,
|
||||||
|
&mygica_t230c_props, "MyGica Mini DVB-(T/T2/C) USB Stick T230A",
|
||||||
|
NULL) },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
|
MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
|
||||||
|
@ -17,7 +17,8 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
|
|||||||
|
|
||||||
if (d->props.i2c_algo == NULL) {
|
if (d->props.i2c_algo == NULL) {
|
||||||
err("no i2c algorithm specified");
|
err("no i2c algorithm specified");
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
strscpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
|
strscpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
|
||||||
@ -27,11 +28,15 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
|
|||||||
|
|
||||||
i2c_set_adapdata(&d->i2c_adap, d);
|
i2c_set_adapdata(&d->i2c_adap, d);
|
||||||
|
|
||||||
if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
|
ret = i2c_add_adapter(&d->i2c_adap);
|
||||||
|
if (ret < 0) {
|
||||||
err("could not add i2c adapter");
|
err("could not add i2c adapter");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
d->state |= DVB_USB_STATE_I2C;
|
d->state |= DVB_USB_STATE_I2C;
|
||||||
|
|
||||||
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,8 +194,8 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
|
|||||||
|
|
||||||
err_adapter_init:
|
err_adapter_init:
|
||||||
dvb_usb_adapter_exit(d);
|
dvb_usb_adapter_exit(d);
|
||||||
err_i2c_init:
|
|
||||||
dvb_usb_i2c_exit(d);
|
dvb_usb_i2c_exit(d);
|
||||||
|
err_i2c_init:
|
||||||
if (d->priv && d->props.priv_destroy)
|
if (d->priv && d->props.priv_destroy)
|
||||||
d->props.priv_destroy(d);
|
d->props.priv_destroy(d);
|
||||||
err_priv_init:
|
err_priv_init:
|
||||||
|
@ -130,7 +130,7 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
|||||||
|
|
||||||
static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
|
static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
|
||||||
{
|
{
|
||||||
int i;
|
int i, ret;
|
||||||
u8 b;
|
u8 b;
|
||||||
|
|
||||||
mac[0] = 0x00;
|
mac[0] = 0x00;
|
||||||
@ -139,7 +139,9 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
|
|||||||
|
|
||||||
/* this is a complete guess, but works for my box */
|
/* this is a complete guess, but works for my box */
|
||||||
for (i = 136; i < 139; i++) {
|
for (i = 136; i < 139; i++) {
|
||||||
dibusb_read_eeprom_byte(d,i, &b);
|
ret = dibusb_read_eeprom_byte(d, i, &b);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
mac[5 - (i - 136)] = b;
|
mac[5 - (i - 136)] = b;
|
||||||
}
|
}
|
||||||
|
@ -291,16 +291,22 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
|||||||
static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
|
static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
|
||||||
{
|
{
|
||||||
u8 i, *buf;
|
u8 i, *buf;
|
||||||
|
int ret;
|
||||||
struct vp702x_device_state *st = d->priv;
|
struct vp702x_device_state *st = d->priv;
|
||||||
|
|
||||||
mutex_lock(&st->buf_mutex);
|
mutex_lock(&st->buf_mutex);
|
||||||
buf = st->buf;
|
buf = st->buf;
|
||||||
for (i = 6; i < 12; i++)
|
for (i = 6; i < 12; i++) {
|
||||||
vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
|
ret = vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1,
|
||||||
|
&buf[i - 6], 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(mac, buf, 6);
|
memcpy(mac, buf, 6);
|
||||||
|
err:
|
||||||
mutex_unlock(&st->buf_mutex);
|
mutex_unlock(&st->buf_mutex);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
|
static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
|
||||||
|
@ -842,7 +842,6 @@ static int em28xx_ir_init(struct em28xx *dev)
|
|||||||
kfree(ir);
|
kfree(ir);
|
||||||
ref_put:
|
ref_put:
|
||||||
em28xx_shutdown_buttons(dev);
|
em28xx_shutdown_buttons(dev);
|
||||||
kref_put(&dev->ref, em28xx_free_device);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,49 +691,23 @@ struct go7007 *go7007_alloc(const struct go7007_board_info *board,
|
|||||||
struct device *dev)
|
struct device *dev)
|
||||||
{
|
{
|
||||||
struct go7007 *go;
|
struct go7007 *go;
|
||||||
int i;
|
|
||||||
|
|
||||||
go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
|
go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
|
||||||
if (go == NULL)
|
if (go == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
go->dev = dev;
|
go->dev = dev;
|
||||||
go->board_info = board;
|
go->board_info = board;
|
||||||
go->board_id = 0;
|
|
||||||
go->tuner_type = -1;
|
go->tuner_type = -1;
|
||||||
go->channel_number = 0;
|
|
||||||
go->name[0] = 0;
|
|
||||||
mutex_init(&go->hw_lock);
|
mutex_init(&go->hw_lock);
|
||||||
init_waitqueue_head(&go->frame_waitq);
|
init_waitqueue_head(&go->frame_waitq);
|
||||||
spin_lock_init(&go->spinlock);
|
spin_lock_init(&go->spinlock);
|
||||||
go->status = STATUS_INIT;
|
go->status = STATUS_INIT;
|
||||||
memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
|
|
||||||
go->i2c_adapter_online = 0;
|
|
||||||
go->interrupt_available = 0;
|
|
||||||
init_waitqueue_head(&go->interrupt_waitq);
|
init_waitqueue_head(&go->interrupt_waitq);
|
||||||
go->input = 0;
|
|
||||||
go7007_update_board(go);
|
go7007_update_board(go);
|
||||||
go->encoder_h_halve = 0;
|
|
||||||
go->encoder_v_halve = 0;
|
|
||||||
go->encoder_subsample = 0;
|
|
||||||
go->format = V4L2_PIX_FMT_MJPEG;
|
go->format = V4L2_PIX_FMT_MJPEG;
|
||||||
go->bitrate = 1500000;
|
go->bitrate = 1500000;
|
||||||
go->fps_scale = 1;
|
go->fps_scale = 1;
|
||||||
go->pali = 0;
|
|
||||||
go->aspect_ratio = GO7007_RATIO_1_1;
|
go->aspect_ratio = GO7007_RATIO_1_1;
|
||||||
go->gop_size = 0;
|
|
||||||
go->ipb = 0;
|
|
||||||
go->closed_gop = 0;
|
|
||||||
go->repeat_seqhead = 0;
|
|
||||||
go->seq_header_enable = 0;
|
|
||||||
go->gop_header_enable = 0;
|
|
||||||
go->dvd_mode = 0;
|
|
||||||
go->interlace_coding = 0;
|
|
||||||
for (i = 0; i < 4; ++i)
|
|
||||||
go->modet[i].enable = 0;
|
|
||||||
for (i = 0; i < 1624; ++i)
|
|
||||||
go->modet_map[i] = 0;
|
|
||||||
go->audio_deliver = NULL;
|
|
||||||
go->audio_enabled = 0;
|
|
||||||
|
|
||||||
return go;
|
return go;
|
||||||
}
|
}
|
||||||
|
@ -1134,7 +1134,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
|
|||||||
|
|
||||||
ep = usb->usbdev->ep_in[4];
|
ep = usb->usbdev->ep_in[4];
|
||||||
if (!ep)
|
if (!ep)
|
||||||
return -ENODEV;
|
goto allocfail;
|
||||||
|
|
||||||
/* Allocate the URB and buffer for receiving incoming interrupts */
|
/* Allocate the URB and buffer for receiving incoming interrupts */
|
||||||
usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
|
usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||||
|
@ -4,7 +4,6 @@ menuconfig USB_GSPCA
|
|||||||
depends on VIDEO_V4L2
|
depends on VIDEO_V4L2
|
||||||
depends on INPUT || INPUT=n
|
depends on INPUT || INPUT=n
|
||||||
select VIDEOBUF2_VMALLOC
|
select VIDEOBUF2_VMALLOC
|
||||||
default m
|
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable selecting webcams based
|
Say Y here if you want to enable selecting webcams based
|
||||||
on the GSPCA framework.
|
on the GSPCA framework.
|
||||||
|
@ -1796,7 +1796,7 @@ static const u8 ov7660_60HZ[][4] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 ov7660_NoFliker[][4] = {
|
static const u8 ov7660_NoFlicker[][4] = {
|
||||||
{0x00, 0x13, 0x87, 0xaa},
|
{0x00, 0x13, 0x87, 0xaa},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
@ -3319,8 +3319,8 @@ static void sethvflip(struct gspca_dev *gspca_dev, bool hflip, bool vflip)
|
|||||||
static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
|
static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
static const u8 (*ov7660_freq_tb[3])[4] =
|
static const u8 (*ov7660_freq_tb[3])[4] = {
|
||||||
{ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ};
|
ov7660_NoFlicker, ov7660_50HZ, ov7660_60HZ};
|
||||||
|
|
||||||
if (sd->sensor != SENSOR_OV7660)
|
if (sd->sensor != SENSOR_OV7660)
|
||||||
return;
|
return;
|
||||||
|
@ -323,7 +323,7 @@ static const struct usb_action adcm2700_60HZ[] = {
|
|||||||
{0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
|
{0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action adcm2700_NoFliker[] = {
|
static const struct usb_action adcm2700_NoFlicker[] = {
|
||||||
{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
|
{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
|
||||||
{0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
|
{0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
|
||||||
{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
|
{0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
|
||||||
@ -525,7 +525,7 @@ static const struct usb_action cs2102_60HZ[] = {
|
|||||||
{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
|
{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action cs2102_NoFlikerScale[] = {
|
static const struct usb_action cs2102_NoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xaa, 0x23, 0x0001},
|
{0xaa, 0x23, 0x0001},
|
||||||
{0xaa, 0x24, 0x005f},
|
{0xaa, 0x24, 0x005f},
|
||||||
@ -547,7 +547,7 @@ static const struct usb_action cs2102_NoFlikerScale[] = {
|
|||||||
{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
|
{0xa0, 0xff, ZC3XX_R020_HSYNC_3},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action cs2102_NoFliker[] = {
|
static const struct usb_action cs2102_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xaa, 0x23, 0x0000},
|
{0xaa, 0x23, 0x0000},
|
||||||
{0xaa, 0x24, 0x00af},
|
{0xaa, 0x24, 0x00af},
|
||||||
@ -1385,7 +1385,7 @@ static const struct usb_action gc0305_60HZ[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action gc0305_NoFliker[] = {
|
static const struct usb_action gc0305_NoFlicker[] = {
|
||||||
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */
|
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */
|
||||||
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
|
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
|
||||||
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
|
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
|
||||||
@ -1710,7 +1710,7 @@ static const struct usb_action hdcs2020_60HZ[] = {
|
|||||||
{0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */
|
{0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action hdcs2020_NoFliker[] = {
|
static const struct usb_action hdcs2020_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
|
{0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
|
||||||
{0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
|
{0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
|
||||||
@ -1925,7 +1925,7 @@ static const struct usb_action hv7131b_60HZScale[] = { /* 320x240 */
|
|||||||
{0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
|
{0xa0, 0x40, ZC3XX_R020_HSYNC_3}, /* 00,20,40,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
|
static const struct usb_action hv7131b_NoFlicker[] = { /* 640x480*/
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
|
{0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
|
||||||
{0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
|
{0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
|
||||||
@ -1950,7 +1950,7 @@ static const struct usb_action hv7131b_NoFliker[] = { /* 640x480*/
|
|||||||
{0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
|
{0xa0, 0x03, ZC3XX_R020_HSYNC_3}, /* 00,20,03,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action hv7131b_NoFlikerScale[] = { /* 320x240 */
|
static const struct usb_action hv7131b_NoFlickerScale[] = { /* 320x240 */
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
|
{0xaa, 0x25, 0x0003}, /* 00,25,03,aa */
|
||||||
{0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
|
{0xaa, 0x26, 0x0000}, /* 00,26,00,aa */
|
||||||
@ -2141,7 +2141,7 @@ static const struct usb_action hv7131r_60HZScale[] = {
|
|||||||
{0xa0, 0x08, ZC3XX_R020_HSYNC_3},
|
{0xa0, 0x08, ZC3XX_R020_HSYNC_3},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action hv7131r_NoFliker[] = {
|
static const struct usb_action hv7131r_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH},
|
{0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH},
|
||||||
{0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID},
|
{0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID},
|
||||||
@ -2159,7 +2159,7 @@ static const struct usb_action hv7131r_NoFliker[] = {
|
|||||||
{0xa0, 0x08, ZC3XX_R020_HSYNC_3},
|
{0xa0, 0x08, ZC3XX_R020_HSYNC_3},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action hv7131r_NoFlikerScale[] = {
|
static const struct usb_action hv7131r_NoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH},
|
{0xa0, 0x2f, ZC3XX_R190_EXPOSURELIMITHIGH},
|
||||||
{0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID},
|
{0xa0, 0xf8, ZC3XX_R191_EXPOSURELIMITMID},
|
||||||
@ -2662,7 +2662,7 @@ static const struct usb_action icm105a_60HZ[] = {
|
|||||||
{0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
|
{0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action icm105a_NoFlikerScale[] = {
|
static const struct usb_action icm105a_NoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
|
{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
|
||||||
{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
|
{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
|
||||||
@ -2693,7 +2693,7 @@ static const struct usb_action icm105a_NoFlikerScale[] = {
|
|||||||
{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
|
{0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action icm105a_NoFliker[] = {
|
static const struct usb_action icm105a_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
|
{0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
|
||||||
{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
|
{0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
|
||||||
@ -3009,7 +3009,7 @@ static const struct usb_action mc501cb_60HZScale[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action mc501cb_NoFliker[] = {
|
static const struct usb_action mc501cb_NoFlicker[] = {
|
||||||
{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
|
{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
|
||||||
{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
|
{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
|
||||||
{0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
|
{0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
|
||||||
@ -3021,7 +3021,7 @@ static const struct usb_action mc501cb_NoFliker[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action mc501cb_NoFlikerScale[] = {
|
static const struct usb_action mc501cb_NoFlickerScale[] = {
|
||||||
{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
|
{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
|
||||||
{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
|
{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
|
||||||
{0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
|
{0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
|
||||||
@ -3211,7 +3211,7 @@ static const struct usb_action ov7620_60HZ[] = {
|
|||||||
{0xa1, 0x01, 0x0037}, */
|
{0xa1, 0x01, 0x0037}, */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action ov7620_NoFliker[] = {
|
static const struct usb_action ov7620_NoFlicker[] = {
|
||||||
{0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
|
{0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
|
||||||
{0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */
|
{0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */
|
||||||
/* disable 1/120s & 1/100s exposures for banding filter */
|
/* disable 1/120s & 1/100s exposures for banding filter */
|
||||||
@ -3827,7 +3827,7 @@ static const struct usb_action pas106b_60HZ[] = {
|
|||||||
{0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */
|
{0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action pas106b_NoFliker[] = {
|
static const struct usb_action pas106b_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
|
{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
|
||||||
{0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
|
{0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
|
||||||
{0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */
|
{0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */
|
||||||
@ -4051,7 +4051,7 @@ static const struct usb_action pas202b_60HZScale[] = {
|
|||||||
{0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
|
{0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action pas202b_NoFliker[] = {
|
static const struct usb_action pas202b_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
|
{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
|
||||||
{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
|
{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
|
||||||
@ -4080,7 +4080,7 @@ static const struct usb_action pas202b_NoFliker[] = {
|
|||||||
{0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
|
{0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, /* 00,88,0e,cc */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action pas202b_NoFlikerScale[] = {
|
static const struct usb_action pas202b_NoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
|
{0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, /* 00,87,20,cc */
|
||||||
{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
|
{0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, /* 00,88,21,cc */
|
||||||
@ -4309,7 +4309,7 @@ static const struct usb_action mt9v111_1_AE60HZScale[] = {
|
|||||||
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action mt9v111_1_AENoFliker[] = {
|
static const struct usb_action mt9v111_1_AENoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xbb, 0x00, 0x0509},
|
{0xbb, 0x00, 0x0509},
|
||||||
@ -4332,7 +4332,7 @@ static const struct usb_action mt9v111_1_AENoFliker[] = {
|
|||||||
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action mt9v111_1_AENoFlikerScale[] = {
|
static const struct usb_action mt9v111_1_AENoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xbb, 0x00, 0x0534},
|
{0xbb, 0x00, 0x0534},
|
||||||
@ -4554,7 +4554,7 @@ static const struct usb_action mt9v111_3_AE60HZScale[] = {
|
|||||||
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action mt9v111_3_AENoFliker[] = {
|
static const struct usb_action mt9v111_3_AENoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xaa, 0x05, 0x0034},
|
{0xaa, 0x05, 0x0034},
|
||||||
@ -4577,7 +4577,7 @@ static const struct usb_action mt9v111_3_AENoFliker[] = {
|
|||||||
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action mt9v111_3_AENoFlikerScale[] = {
|
static const struct usb_action mt9v111_3_AENoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
{0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xaa, 0x05, 0x0034},
|
{0xaa, 0x05, 0x0034},
|
||||||
@ -4787,7 +4787,7 @@ static const struct usb_action pb0330_60HZScale[] = {
|
|||||||
{0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
|
{0xa0, 0xd0, ZC3XX_R020_HSYNC_3},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action pb0330_NoFliker[] = {
|
static const struct usb_action pb0330_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xbb, 0x00, 0x0509},
|
{0xbb, 0x00, 0x0509},
|
||||||
{0xbb, 0x02, 0x0940},
|
{0xbb, 0x02, 0x0940},
|
||||||
@ -4809,7 +4809,7 @@ static const struct usb_action pb0330_NoFliker[] = {
|
|||||||
{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
|
{0xa0, 0xe0, ZC3XX_R020_HSYNC_3},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action pb0330_NoFlikerScale[] = {
|
static const struct usb_action pb0330_NoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
|
||||||
{0xbb, 0x00, 0x0535},
|
{0xbb, 0x00, 0x0535},
|
||||||
{0xbb, 0x01, 0x0980},
|
{0xbb, 0x01, 0x0980},
|
||||||
@ -5031,7 +5031,7 @@ static const struct usb_action po2030_60HZ[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action po2030_NoFliker[] = {
|
static const struct usb_action po2030_NoFlicker[] = {
|
||||||
{0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
|
{0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
|
||||||
{0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
|
{0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
|
||||||
{0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
|
{0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
|
||||||
@ -5215,7 +5215,7 @@ static const struct usb_action tas5130c_60HZScale[] = {
|
|||||||
{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
|
{0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
static const struct usb_action tas5130c_NoFliker[] = {
|
static const struct usb_action tas5130c_NoFlicker[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
|
{0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
|
||||||
{0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */
|
{0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */
|
||||||
@ -5241,7 +5241,7 @@ static const struct usb_action tas5130c_NoFliker[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action tas5130c_NoFlikerScale[] = {
|
static const struct usb_action tas5130c_NoFlickerScale[] = {
|
||||||
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
{0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
|
||||||
{0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
|
{0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
|
||||||
{0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */
|
{0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */
|
||||||
@ -5482,7 +5482,7 @@ static const struct usb_action gc0303_60HZScale[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action gc0303_NoFliker[] = {
|
static const struct usb_action gc0303_NoFlicker[] = {
|
||||||
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
|
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
|
||||||
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
|
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
|
||||||
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
|
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
|
||||||
@ -5504,7 +5504,7 @@ static const struct usb_action gc0303_NoFliker[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_action gc0303_NoFlikerScale[] = {
|
static const struct usb_action gc0303_NoFlickerScale[] = {
|
||||||
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
|
{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
|
||||||
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
|
{0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
|
||||||
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
|
{0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
|
||||||
@ -5806,7 +5806,7 @@ static void setquality(struct gspca_dev *gspca_dev)
|
|||||||
* Valid frequencies are:
|
* Valid frequencies are:
|
||||||
* 50Hz, for European and Asian lighting (default)
|
* 50Hz, for European and Asian lighting (default)
|
||||||
* 60Hz, for American lighting
|
* 60Hz, for American lighting
|
||||||
* 0 = No Fliker (for outdoore usage)
|
* 0 = No Flicker (for outdoor usage)
|
||||||
*/
|
*/
|
||||||
static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
|
static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
|
||||||
{
|
{
|
||||||
@ -5814,80 +5814,80 @@ static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
|
|||||||
int i, mode;
|
int i, mode;
|
||||||
const struct usb_action *zc3_freq;
|
const struct usb_action *zc3_freq;
|
||||||
static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
|
static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
|
||||||
[SENSOR_ADCM2700] =
|
[SENSOR_ADCM2700] = {
|
||||||
{adcm2700_NoFliker, adcm2700_NoFliker,
|
adcm2700_NoFlicker, adcm2700_NoFlicker,
|
||||||
adcm2700_50HZ, adcm2700_50HZ,
|
adcm2700_50HZ, adcm2700_50HZ,
|
||||||
adcm2700_60HZ, adcm2700_60HZ},
|
adcm2700_60HZ, adcm2700_60HZ},
|
||||||
[SENSOR_CS2102] =
|
[SENSOR_CS2102] = {
|
||||||
{cs2102_NoFliker, cs2102_NoFlikerScale,
|
cs2102_NoFlicker, cs2102_NoFlickerScale,
|
||||||
cs2102_50HZ, cs2102_50HZScale,
|
cs2102_50HZ, cs2102_50HZScale,
|
||||||
cs2102_60HZ, cs2102_60HZScale},
|
cs2102_60HZ, cs2102_60HZScale},
|
||||||
[SENSOR_CS2102K] =
|
[SENSOR_CS2102K] = {
|
||||||
{cs2102_NoFliker, cs2102_NoFlikerScale,
|
cs2102_NoFlicker, cs2102_NoFlickerScale,
|
||||||
NULL, NULL, /* currently disabled */
|
NULL, NULL, /* currently disabled */
|
||||||
NULL, NULL},
|
NULL, NULL},
|
||||||
[SENSOR_GC0303] =
|
[SENSOR_GC0303] = {
|
||||||
{gc0303_NoFliker, gc0303_NoFlikerScale,
|
gc0303_NoFlicker, gc0303_NoFlickerScale,
|
||||||
gc0303_50HZ, gc0303_50HZScale,
|
gc0303_50HZ, gc0303_50HZScale,
|
||||||
gc0303_60HZ, gc0303_60HZScale},
|
gc0303_60HZ, gc0303_60HZScale},
|
||||||
[SENSOR_GC0305] =
|
[SENSOR_GC0305] = {
|
||||||
{gc0305_NoFliker, gc0305_NoFliker,
|
gc0305_NoFlicker, gc0305_NoFlicker,
|
||||||
gc0305_50HZ, gc0305_50HZ,
|
gc0305_50HZ, gc0305_50HZ,
|
||||||
gc0305_60HZ, gc0305_60HZ},
|
gc0305_60HZ, gc0305_60HZ},
|
||||||
[SENSOR_HDCS2020] =
|
[SENSOR_HDCS2020] = {
|
||||||
{hdcs2020_NoFliker, hdcs2020_NoFliker,
|
hdcs2020_NoFlicker, hdcs2020_NoFlicker,
|
||||||
hdcs2020_50HZ, hdcs2020_50HZ,
|
hdcs2020_50HZ, hdcs2020_50HZ,
|
||||||
hdcs2020_60HZ, hdcs2020_60HZ},
|
hdcs2020_60HZ, hdcs2020_60HZ},
|
||||||
[SENSOR_HV7131B] =
|
[SENSOR_HV7131B] = {
|
||||||
{hv7131b_NoFliker, hv7131b_NoFlikerScale,
|
hv7131b_NoFlicker, hv7131b_NoFlickerScale,
|
||||||
hv7131b_50HZ, hv7131b_50HZScale,
|
hv7131b_50HZ, hv7131b_50HZScale,
|
||||||
hv7131b_60HZ, hv7131b_60HZScale},
|
hv7131b_60HZ, hv7131b_60HZScale},
|
||||||
[SENSOR_HV7131R] =
|
[SENSOR_HV7131R] = {
|
||||||
{hv7131r_NoFliker, hv7131r_NoFlikerScale,
|
hv7131r_NoFlicker, hv7131r_NoFlickerScale,
|
||||||
hv7131r_50HZ, hv7131r_50HZScale,
|
hv7131r_50HZ, hv7131r_50HZScale,
|
||||||
hv7131r_60HZ, hv7131r_60HZScale},
|
hv7131r_60HZ, hv7131r_60HZScale},
|
||||||
[SENSOR_ICM105A] =
|
[SENSOR_ICM105A] = {
|
||||||
{icm105a_NoFliker, icm105a_NoFlikerScale,
|
icm105a_NoFlicker, icm105a_NoFlickerScale,
|
||||||
icm105a_50HZ, icm105a_50HZScale,
|
icm105a_50HZ, icm105a_50HZScale,
|
||||||
icm105a_60HZ, icm105a_60HZScale},
|
icm105a_60HZ, icm105a_60HZScale},
|
||||||
[SENSOR_MC501CB] =
|
[SENSOR_MC501CB] = {
|
||||||
{mc501cb_NoFliker, mc501cb_NoFlikerScale,
|
mc501cb_NoFlicker, mc501cb_NoFlickerScale,
|
||||||
mc501cb_50HZ, mc501cb_50HZScale,
|
mc501cb_50HZ, mc501cb_50HZScale,
|
||||||
mc501cb_60HZ, mc501cb_60HZScale},
|
mc501cb_60HZ, mc501cb_60HZScale},
|
||||||
[SENSOR_MT9V111_1] =
|
[SENSOR_MT9V111_1] = {
|
||||||
{mt9v111_1_AENoFliker, mt9v111_1_AENoFlikerScale,
|
mt9v111_1_AENoFlicker, mt9v111_1_AENoFlickerScale,
|
||||||
mt9v111_1_AE50HZ, mt9v111_1_AE50HZScale,
|
mt9v111_1_AE50HZ, mt9v111_1_AE50HZScale,
|
||||||
mt9v111_1_AE60HZ, mt9v111_1_AE60HZScale},
|
mt9v111_1_AE60HZ, mt9v111_1_AE60HZScale},
|
||||||
[SENSOR_MT9V111_3] =
|
[SENSOR_MT9V111_3] = {
|
||||||
{mt9v111_3_AENoFliker, mt9v111_3_AENoFlikerScale,
|
mt9v111_3_AENoFlicker, mt9v111_3_AENoFlickerScale,
|
||||||
mt9v111_3_AE50HZ, mt9v111_3_AE50HZScale,
|
mt9v111_3_AE50HZ, mt9v111_3_AE50HZScale,
|
||||||
mt9v111_3_AE60HZ, mt9v111_3_AE60HZScale},
|
mt9v111_3_AE60HZ, mt9v111_3_AE60HZScale},
|
||||||
[SENSOR_OV7620] =
|
[SENSOR_OV7620] = {
|
||||||
{ov7620_NoFliker, ov7620_NoFliker,
|
ov7620_NoFlicker, ov7620_NoFlicker,
|
||||||
ov7620_50HZ, ov7620_50HZ,
|
ov7620_50HZ, ov7620_50HZ,
|
||||||
ov7620_60HZ, ov7620_60HZ},
|
ov7620_60HZ, ov7620_60HZ},
|
||||||
[SENSOR_OV7630C] =
|
[SENSOR_OV7630C] = {
|
||||||
{NULL, NULL,
|
NULL, NULL,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
NULL, NULL},
|
NULL, NULL},
|
||||||
[SENSOR_PAS106] =
|
[SENSOR_PAS106] = {
|
||||||
{pas106b_NoFliker, pas106b_NoFliker,
|
pas106b_NoFlicker, pas106b_NoFlicker,
|
||||||
pas106b_50HZ, pas106b_50HZ,
|
pas106b_50HZ, pas106b_50HZ,
|
||||||
pas106b_60HZ, pas106b_60HZ},
|
pas106b_60HZ, pas106b_60HZ},
|
||||||
[SENSOR_PAS202B] =
|
[SENSOR_PAS202B] = {
|
||||||
{pas202b_NoFliker, pas202b_NoFlikerScale,
|
pas202b_NoFlicker, pas202b_NoFlickerScale,
|
||||||
pas202b_50HZ, pas202b_50HZScale,
|
pas202b_50HZ, pas202b_50HZScale,
|
||||||
pas202b_60HZ, pas202b_60HZScale},
|
pas202b_60HZ, pas202b_60HZScale},
|
||||||
[SENSOR_PB0330] =
|
[SENSOR_PB0330] = {
|
||||||
{pb0330_NoFliker, pb0330_NoFlikerScale,
|
pb0330_NoFlicker, pb0330_NoFlickerScale,
|
||||||
pb0330_50HZ, pb0330_50HZScale,
|
pb0330_50HZ, pb0330_50HZScale,
|
||||||
pb0330_60HZ, pb0330_60HZScale},
|
pb0330_60HZ, pb0330_60HZScale},
|
||||||
[SENSOR_PO2030] =
|
[SENSOR_PO2030] = {
|
||||||
{po2030_NoFliker, po2030_NoFliker,
|
po2030_NoFlicker, po2030_NoFlicker,
|
||||||
po2030_50HZ, po2030_50HZ,
|
po2030_50HZ, po2030_50HZ,
|
||||||
po2030_60HZ, po2030_60HZ},
|
po2030_60HZ, po2030_60HZ},
|
||||||
[SENSOR_TAS5130C] =
|
[SENSOR_TAS5130C] = {
|
||||||
{tas5130c_NoFliker, tas5130c_NoFlikerScale,
|
tas5130c_NoFlicker, tas5130c_NoFlickerScale,
|
||||||
tas5130c_50HZ, tas5130c_50HZScale,
|
tas5130c_50HZ, tas5130c_50HZScale,
|
||||||
tas5130c_60HZ, tas5130c_60HZScale},
|
tas5130c_60HZ, tas5130c_60HZScale},
|
||||||
};
|
};
|
||||||
|
@ -1346,7 +1346,7 @@ static int stk_camera_probe(struct usb_interface *interface,
|
|||||||
if (!dev->isoc_ep) {
|
if (!dev->isoc_ep) {
|
||||||
pr_err("Could not find isoc-in endpoint\n");
|
pr_err("Could not find isoc-in endpoint\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto error;
|
goto error_put;
|
||||||
}
|
}
|
||||||
dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
|
dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
|
||||||
dev->vsettings.mode = MODE_VGA;
|
dev->vsettings.mode = MODE_VGA;
|
||||||
@ -1359,10 +1359,12 @@ static int stk_camera_probe(struct usb_interface *interface,
|
|||||||
|
|
||||||
err = stk_register_video_device(dev);
|
err = stk_register_video_device(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error_put;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_put:
|
||||||
|
usb_put_intf(interface);
|
||||||
error:
|
error:
|
||||||
v4l2_ctrl_handler_free(hdl);
|
v4l2_ctrl_handler_free(hdl);
|
||||||
v4l2_device_unregister(&dev->v4l2_dev);
|
v4l2_device_unregister(&dev->v4l2_dev);
|
||||||
|
@ -899,8 +899,8 @@ static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
|
|||||||
{
|
{
|
||||||
struct uvc_fh *handle = fh;
|
struct uvc_fh *handle = fh;
|
||||||
struct uvc_video_chain *chain = handle->chain;
|
struct uvc_video_chain *chain = handle->chain;
|
||||||
|
u8 *buf;
|
||||||
int ret;
|
int ret;
|
||||||
u8 i;
|
|
||||||
|
|
||||||
if (chain->selector == NULL ||
|
if (chain->selector == NULL ||
|
||||||
(chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
|
(chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
|
||||||
@ -908,22 +908,27 @@ static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = kmalloc(1, GFP_KERNEL);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id,
|
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id,
|
||||||
chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
|
chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
|
||||||
&i, 1);
|
buf, 1);
|
||||||
if (ret < 0)
|
if (!ret)
|
||||||
return ret;
|
*input = *buf - 1;
|
||||||
|
|
||||||
*input = i - 1;
|
kfree(buf);
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
|
static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
|
||||||
{
|
{
|
||||||
struct uvc_fh *handle = fh;
|
struct uvc_fh *handle = fh;
|
||||||
struct uvc_video_chain *chain = handle->chain;
|
struct uvc_video_chain *chain = handle->chain;
|
||||||
|
u8 *buf;
|
||||||
int ret;
|
int ret;
|
||||||
u32 i;
|
|
||||||
|
|
||||||
ret = uvc_acquire_privileges(handle);
|
ret = uvc_acquire_privileges(handle);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -939,10 +944,17 @@ static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
|
|||||||
if (input >= chain->selector->bNrInPins)
|
if (input >= chain->selector->bNrInPins)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
i = input + 1;
|
buf = kmalloc(1, GFP_KERNEL);
|
||||||
return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id,
|
if (!buf)
|
||||||
chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
|
return -ENOMEM;
|
||||||
&i, 1);
|
|
||||||
|
*buf = input + 1;
|
||||||
|
ret = uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id,
|
||||||
|
chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
|
||||||
|
buf, 1);
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uvc_ioctl_queryctrl(struct file *file, void *fh,
|
static int uvc_ioctl_queryctrl(struct file *file, void *fh,
|
||||||
|
@ -833,6 +833,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|||||||
case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface";
|
case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface";
|
||||||
case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable";
|
case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable";
|
||||||
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs";
|
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs";
|
||||||
|
case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD: return "Intra Refresh Period";
|
||||||
case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable";
|
case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable";
|
||||||
case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control";
|
case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control";
|
||||||
case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode";
|
case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode";
|
||||||
@ -1258,6 +1259,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
|||||||
case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
|
case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
|
||||||
case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
|
case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
|
||||||
case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY:
|
case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY:
|
||||||
|
case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD:
|
||||||
*type = V4L2_CTRL_TYPE_INTEGER;
|
*type = V4L2_CTRL_TYPE_INTEGER;
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_MPEG_VIDEO_LTR_COUNT:
|
case V4L2_CID_MPEG_VIDEO_LTR_COUNT:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user