[GIT PULL for v6.18] media updates
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmjdReIACgkQCF8+vY7k 4RUyzxAAmqaYUomji7+Imoy/M9lFE5EBwC5HAZ2wfS9c8l7sYw9kZEaoq+JOapKB EU+dLr/judjpntmIOYqGPBgbVdzalGEvYsZ2KgVbygZS5JgF0K+Yb4ary3t+wN+H 43pGExsdRdwZhVU02xkSOohBcvWTEtWCjypdRSxSs03oLQtJ7AOcSNvsD25DTSNC 05l3Fr/5Ckjr9PpjjYaTX1SdRyPWoRD536yeGbbRo3ZTCGG8dFXwqZdhAqrMfFmb dAVttiTvMBHY/4LdA7YFLW/Ww3ty9uMgwv7D2LYCBPwKr01W32x4e0hZjQNjltlk omcw13oKMDhWm7bsB4ja2X3DjFLZnFcULyAtdhgR/+5748fIL82pp16XR80Zbweb UgO5WsUCQbYAfKdiu6CG/amwG1yHJW/2fRh6xD8WEKcsLjnIFhPN4rTsLXo6IeMY KVru2OOfXJUdo6fMfHk7EZElWGMS9H1iQy64v3eJe1bAIa0tMZKhwxrpAJTk1Ykf fvWdqdp761c1+P53is/LHtt7fqCN6aHsDcwXTCsJGH1YI4b/qxXjcgPMyedf6kRu GY+soXWcpldhxrR4yblMFhaJGFgIdFmnYDHWWzMxgQ0a8ch0ORf8aGlF5kT5SP+9 VPnZqY+EECrHqvI3DU4CaHNbZFXp6RKW+2ZkXFpIRH12v1aARmE= =Fuey -----END PGP SIGNATURE----- Merge tag 'media/v6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - Added a new V4L2 clock helper - New camera sensor drivers - iris: Enable H.264/H.265 encoder support and fixes in iris driver common code - camss: add support for new SoC flavors - venus: add new SoC support - tc358743: support more infoframe types - Various fixes, driver improvements and cleanups * tag 'media/v6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (439 commits) media: venus: pm_helpers: add fallback for the opp-table media: qcom: camss: vfe: Fix BPL alignment for QCM2290 media: tuner: xc5000: Fix use-after-free in xc5000_release media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe media: b2c2: Fix use-after-free causing by irq_check_work in flexcop_pci_remove media: vsp1: Export missing vsp1_isp_free_buffer symbol media: renesas: vsp1: Convert to SYSTEM_SLEEP/RUNTIME_PM_OPS() media: renesas: ceu: Convert to RUNTIME_PM_OPS() media: renesas: fdp1: Convert to RUNTIME_PM_OPS() media: renesas: rcar-vin: Convert to DEFINE_SIMPLE_DEV_PM_OPS() media: renesas: rcar_drif: Convert to DEFINE_SIMPLE_DEV_PM_OPS() media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID media: uvcvideo: Support UVC_CROSXU_CONTROL_IQ_PROFILE media: uvcvideo: Run uvc_ctrl_init_ctrl for all controls media: uvcvideo: Shorten the transfer size non compliance message media: uvcvideo: Do not re-reference dev->udev media: uvcvideo: Use intf instead of udev for printks media: uvcvideo: Move video_device under video_queue media: uvcvideo: Drop stream->mutex media: uvcvideo: Move MSXU_CONTROL_METADATA definition to header ...
This commit is contained in:
commit
f79e772258
6
.mailmap
6
.mailmap
|
@ -216,7 +216,8 @@ Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com>
|
|||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
|
||||
Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
|
||||
<dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be>
|
||||
Dikshita Agarwal <quic_dikshita@quicinc.com> <dikshita@codeaurora.org>
|
||||
Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com> <dikshita@codeaurora.org>
|
||||
Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com> <quic_dikshita@quicinc.com>
|
||||
Dmitry Baryshkov <lumag@kernel.org> <dbaryshkov@gmail.com>
|
||||
Dmitry Baryshkov <lumag@kernel.org> <[dbaryshkov@gmail.com]>
|
||||
Dmitry Baryshkov <lumag@kernel.org> <dmitry_baryshkov@mentor.com>
|
||||
|
@ -819,7 +820,8 @@ Valentin Schneider <vschneid@redhat.com> <valentin.schneider@arm.com>
|
|||
Veera Sundaram Sankaran <quic_veeras@quicinc.com> <veeras@codeaurora.org>
|
||||
Veerabhadrarao Badiganti <quic_vbadigan@quicinc.com> <vbadigan@codeaurora.org>
|
||||
Venkateswara Naralasetty <quic_vnaralas@quicinc.com> <vnaralas@codeaurora.org>
|
||||
Vikash Garodia <quic_vgarodia@quicinc.com> <vgarodia@codeaurora.org>
|
||||
Vikash Garodia <vikash.garodia@oss.qualcomm.com> <vgarodia@codeaurora.org>
|
||||
Vikash Garodia <vikash.garodia@oss.qualcomm.com> <quic_vgarodia@quicinc.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com>
|
||||
Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
What: /sys/kernel/debug/cec/*/error-inj
|
||||
Date: March 2018
|
||||
Contact: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
Contact: Hans Verkuil <hverkuil@kernel.org>
|
||||
Description:
|
||||
|
||||
The CEC Framework allows for CEC error injection commands through
|
||||
|
|
|
@ -252,7 +252,7 @@ For example, if you find a bug at the gspca's sonixj.c file, you can get
|
|||
its maintainers with::
|
||||
|
||||
$ ./scripts/get_maintainer.pl --bug -f drivers/media/usb/gspca/sonixj.c
|
||||
Hans Verkuil <hverkuil@xs4all.nl> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Hans Verkuil <hverkuil@kernel.org> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%)
|
||||
Tejun Heo <tj@kernel.org> (commit_signer:1/1=100%)
|
||||
Bhaktipriya Shridhar <bhaktipriya96@gmail.com> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%)
|
||||
|
|
|
@ -91,7 +91,6 @@ ov5647 OmniVision OV5647 sensor
|
|||
ov5670 OmniVision OV5670 sensor
|
||||
ov5675 OmniVision OV5675 sensor
|
||||
ov5695 OmniVision OV5695 sensor
|
||||
ov6650 OmniVision OV6650 sensor
|
||||
ov7251 OmniVision OV7251 sensor
|
||||
ov7640 OmniVision OV7640 sensor
|
||||
ov7670 OmniVision OV7670 sensor
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
The ivtv driver
|
||||
===============
|
||||
|
||||
Author: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Author: Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
This is a v4l2 device driver for the Conexant cx23415/6 MPEG encoder/decoder.
|
||||
The cx23415 can do both encoding and decoding, the cx23416 can only do MPEG
|
||||
|
|
|
@ -312,7 +312,8 @@ examples:
|
|||
|
||||
clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
|
||||
clock-names = "xvclk";
|
||||
clock-frequency = <19200000>;
|
||||
assigned-clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
dovdd-supply = <&vreg_lvs1a_1p8>;
|
||||
avdd-supply = <&cam0_avdd_2v8>;
|
||||
|
@ -344,7 +345,8 @@ examples:
|
|||
|
||||
clocks = <&clock_camcc CAM_CC_MCLK3_CLK>;
|
||||
clock-names = "xclk";
|
||||
clock-frequency = <24000000>;
|
||||
assigned-clocks = <&clock_camcc CAM_CC_MCLK3_CLK>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
|
||||
vdddo-supply = <&vreg_lvs1a_1p8>;
|
||||
vdda-supply = <&cam3_avdd_2v8>;
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: HDMI CEC Adapters Common Properties
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil@xs4all.nl>
|
||||
- Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: HDMI CEC GPIO
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
- Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
description: |
|
||||
The HDMI CEC GPIO module supports CEC implementations where the CEC line is
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: NVIDIA Tegra HDMI CEC
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
- Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
allOf:
|
||||
- $ref: cec-common.yaml#
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Analog Devices ADV7604/10/11/12 video decoder with HDMI receiver
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
- Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
description:
|
||||
The ADV7604 and ADV7610/11/12 are multiformat video decoders with
|
||||
|
|
|
@ -55,6 +55,7 @@ properties:
|
|||
|
||||
clock-frequency:
|
||||
description: Frequency of the external clock to the sensor in Hz.
|
||||
deprecated: true
|
||||
|
||||
reset-gpios:
|
||||
description: Reset GPIO. Also commonly called XSHUTDOWN in hardware
|
||||
|
@ -93,7 +94,6 @@ properties:
|
|||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clock-frequency
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
@ -114,8 +114,11 @@ examples:
|
|||
reg = <0x10>;
|
||||
reset-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
|
||||
vana-supply = <&vaux3>;
|
||||
|
||||
clocks = <&omap3_isp 0>;
|
||||
clock-frequency = <9600000>;
|
||||
assigned-clocks = <&omap3_isp 0>;
|
||||
assigned-clock-rates = <9600000>;
|
||||
|
||||
port {
|
||||
ccs_ep: endpoint {
|
||||
data-lanes = <1 2>;
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,og0ve1b.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: OmniVision OG0VE1B Image Sensor
|
||||
|
||||
description:
|
||||
OmniVision OG0VE1B image sensor is a low power consuming monochrome
|
||||
image sensor. The sensor is controlled over a serial camera control
|
||||
bus protocol (SCCB), the widest supported image size is 640x480 at
|
||||
120 frames per second rate, data output format is 8/10-bit RAW
|
||||
transferred over one-lane MIPI D-PHY at up to 800 Mbps.
|
||||
|
||||
maintainers:
|
||||
- Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,og0ve1b
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: XVCLK supply clock, 6MHz to 27MHz frequency.
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
description: Active low GPIO connected to XSHUTDOWN pad of the sensor.
|
||||
maxItems: 1
|
||||
|
||||
strobe-gpios:
|
||||
description: Input GPIO connected to strobe pad of the sensor.
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description: Analog voltage supply, 2.6 to 3.0 volts.
|
||||
|
||||
dovdd-supply:
|
||||
description: Digital I/O voltage supply, 1.7 to 3.0 volts.
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital core voltage supply.
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera@3e {
|
||||
compatible = "ovti,og0ve1b";
|
||||
reg = <0x3e>;
|
||||
clocks = <&camera_clk 0>;
|
||||
assigned-clocks = <&camera_clk 0>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
avdd-supply = <&vreg_2p8>;
|
||||
dovdd-supply = <&vreg_1p8>;
|
||||
dvdd-supply = <&vreg_1p2>;
|
||||
|
||||
port {
|
||||
endpoint {
|
||||
link-frequencies = /bits/ 64 <500000000>;
|
||||
remote-endpoint = <&mipi_csi2_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -39,6 +39,7 @@ properties:
|
|||
clock-frequency:
|
||||
description:
|
||||
Frequency of the eclk clock in Hz.
|
||||
deprecated: true
|
||||
|
||||
dovdd-supply:
|
||||
description:
|
||||
|
@ -100,7 +101,6 @@ required:
|
|||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- clock-frequency
|
||||
- dovdd-supply
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
|
@ -127,7 +127,6 @@ examples:
|
|||
|
||||
clocks = <&ov02a10_clk>;
|
||||
clock-names = "eclk";
|
||||
clock-frequency = <24000000>;
|
||||
|
||||
rotation = <180>;
|
||||
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov2735.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: OmniVision OV2735 Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
|
||||
|
||||
description:
|
||||
The OmniVision OV2735 is a 2MP (1920x1080) color CMOS image sensor controlled
|
||||
through an I2C-compatible SCCB bus. it outputs RAW10 format and uses a 1/2.7"
|
||||
optical format.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov2735
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: XVCLK clock
|
||||
|
||||
avdd-supply:
|
||||
description: Analog Domain Power Supply
|
||||
|
||||
dovdd-supply:
|
||||
description: I/O Domain Power Supply
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital Domain Power Supply
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description: Reset Pin GPIO Control (active low)
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
Active-low enable pin. Labeled as 'PWDN' in the datasheet, but acts as
|
||||
an enable signal. During power rail ramp-up, the device remains powered
|
||||
down. Once power rails are stable, pulling this pin low powers on the
|
||||
device.
|
||||
|
||||
port:
|
||||
description: MIPI CSI-2 transmitter port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- avdd-supply
|
||||
- dovdd-supply
|
||||
- dvdd-supply
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera-sensor@3c {
|
||||
compatible = "ovti,ov2735";
|
||||
reg = <0x3c>;
|
||||
clocks = <&ov2735_clk>;
|
||||
|
||||
avdd-supply = <&ov2735_avdd>;
|
||||
dovdd-supply = <&ov2735_dovdd>;
|
||||
dvdd-supply = <&ov2735_dvdd>;
|
||||
|
||||
reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
|
||||
enable-gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
cam_out: endpoint {
|
||||
remote-endpoint = <&mipi_in_cam>;
|
||||
data-lanes = <1 2>;
|
||||
link-frequencies = /bits/ 64 <420000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -21,6 +21,7 @@ properties:
|
|||
|
||||
clock-frequency:
|
||||
description: Frequency of the xclk clock in Hz.
|
||||
deprecated: true
|
||||
|
||||
vdda-supply:
|
||||
description: Analog voltage supply, 2.8 volts
|
||||
|
@ -83,8 +84,11 @@ examples:
|
|||
camera@3c {
|
||||
compatible = "ovti,ov5645";
|
||||
reg = <0x3c>;
|
||||
|
||||
clocks = <&clks 1>;
|
||||
clock-frequency = <24000000>;
|
||||
assigned-clocks = <&clks 1>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
|
||||
vdddo-supply = <&ov5645_vdddo_1v8>;
|
||||
vdda-supply = <&ov5645_vdda_2v8>;
|
||||
vddd-supply = <&ov5645_vddd_1v5>;
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov6211.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: OmniVision OV6211 Image Sensor
|
||||
|
||||
description:
|
||||
OmniVision OV6211 image sensor is a high performance monochrome image
|
||||
sensor. The sensor is controlled over a serial camera control bus
|
||||
protocol (SCCB), the widest supported output image frame size is 400x400
|
||||
at 120 frames per second rate, data output format is 8/10-bit RAW
|
||||
transferred over one-lane MIPI D-PHY interface.
|
||||
|
||||
maintainers:
|
||||
- Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov6211
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: XVCLK supply clock, 6MHz to 27MHz frequency.
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
description: Active low GPIO connected to XSHUTDOWN pad of the sensor.
|
||||
maxItems: 1
|
||||
|
||||
strobe-gpios:
|
||||
description: Input GPIO connected to strobe pad of the sensor.
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description: Analogue voltage supply, 2.6 to 3.0 volts.
|
||||
|
||||
dovdd-supply:
|
||||
description: Digital I/O voltage supply, 1.8 volts.
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital core voltage supply.
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera@60 {
|
||||
compatible = "ovti,ov6211";
|
||||
reg = <0x60>;
|
||||
clocks = <&camera_clk 0>;
|
||||
assigned-clocks = <&camera_clk 0>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
avdd-supply = <&vreg_2p8>;
|
||||
dovdd-supply = <&vreg_1p8>;
|
||||
dvdd-supply = <&vreg_1p2>;
|
||||
|
||||
port {
|
||||
endpoint {
|
||||
link-frequencies = /bits/ 64 <480000000>;
|
||||
remote-endpoint = <&mipi_csi2_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -29,6 +29,7 @@ properties:
|
|||
|
||||
clock-frequency:
|
||||
description: Frequency of the xclk clock in Hz.
|
||||
deprecated: true
|
||||
|
||||
vdda-supply:
|
||||
description: Analog voltage supply, 2.8 volts
|
||||
|
@ -89,8 +90,11 @@ examples:
|
|||
camera@3c {
|
||||
compatible = "ovti,ov7251";
|
||||
reg = <0x3c>;
|
||||
|
||||
clocks = <&clks 1>;
|
||||
clock-frequency = <24000000>;
|
||||
assigned-clocks = <&clks 1>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
|
||||
vdddo-supply = <&ov7251_vdddo_1v8>;
|
||||
vdda-supply = <&ov7251_vdda_2v8>;
|
||||
vddd-supply = <&ov7251_vddd_1v5>;
|
||||
|
|
|
@ -37,6 +37,7 @@ properties:
|
|||
clock-frequency:
|
||||
description:
|
||||
Frequency of the xvclk clock in Hertz.
|
||||
deprecated: true
|
||||
|
||||
dovdd-supply:
|
||||
description:
|
||||
|
@ -87,7 +88,6 @@ required:
|
|||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- clock-frequency
|
||||
- dovdd-supply
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
|
@ -114,7 +114,6 @@ examples:
|
|||
|
||||
clocks = <&cam_osc>;
|
||||
clock-names = "xvclk";
|
||||
clock-frequency = <19200000>;
|
||||
|
||||
avdd-supply = <&mt6358_vcama2_reg>;
|
||||
dvdd-supply = <&mt6358_vcamd_reg>;
|
||||
|
|
|
@ -26,6 +26,7 @@ properties:
|
|||
clock-frequency:
|
||||
default: 24000000
|
||||
description: mclk clock frequency
|
||||
deprecated: true
|
||||
|
||||
rstn-gpios:
|
||||
maxItems: 1
|
||||
|
@ -82,9 +83,12 @@ examples:
|
|||
sensor@2d {
|
||||
compatible = "samsung,s5k5baf";
|
||||
reg = <0x2d>;
|
||||
|
||||
clocks = <&camera 0>;
|
||||
assigned-clocks = <&camera 0>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
|
||||
clock-names = "mclk";
|
||||
clock-frequency = <24000000>;
|
||||
rstn-gpios = <&gpl2 1 GPIO_ACTIVE_LOW>;
|
||||
stbyn-gpios = <&gpl2 0 GPIO_ACTIVE_LOW>;
|
||||
vdda-supply = <&cam_io_en_reg>;
|
||||
|
|
|
@ -30,6 +30,7 @@ properties:
|
|||
clock-frequency:
|
||||
default: 24000000
|
||||
description: extclk clock frequency
|
||||
deprecated: true
|
||||
|
||||
gpios:
|
||||
maxItems: 1
|
||||
|
@ -80,8 +81,11 @@ examples:
|
|||
sensor@10 {
|
||||
compatible = "samsung,s5k6a3";
|
||||
reg = <0x10>;
|
||||
clock-frequency = <24000000>;
|
||||
|
||||
clocks = <&camera 1>;
|
||||
assigned-clocks = <&camera 1>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
|
||||
clock-names = "extclk";
|
||||
gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
|
||||
afvdd-supply = <&ldo19_reg>;
|
||||
|
|
|
@ -81,6 +81,7 @@ properties:
|
|||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
|
|
@ -46,6 +46,8 @@ properties:
|
|||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
@ -59,6 +61,8 @@ examples:
|
|||
imx274: camera-sensor@1a {
|
||||
compatible = "sony,imx274";
|
||||
reg = <0x1a>;
|
||||
clocks = <&imx274_clk>;
|
||||
clock-names = "inck";
|
||||
reset-gpios = <&gpio_sensor 0 0>;
|
||||
|
||||
port {
|
||||
|
|
|
@ -51,6 +51,7 @@ properties:
|
|||
|
||||
clock-frequency:
|
||||
description: Frequency of the xclk clock in Hz
|
||||
deprecated: true
|
||||
|
||||
vdda-supply:
|
||||
description: Analog power supply (2.9V)
|
||||
|
@ -100,7 +101,6 @@ required:
|
|||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- clock-frequency
|
||||
- vdda-supply
|
||||
- vddd-supply
|
||||
- vdddo-supply
|
||||
|
@ -125,7 +125,8 @@ examples:
|
|||
|
||||
clocks = <&gcc 90>;
|
||||
clock-names = "xclk";
|
||||
clock-frequency = <37125000>;
|
||||
assigned-clocks = <&clks 1>;
|
||||
assigned-clock-rates = <37125000>;
|
||||
|
||||
vdddo-supply = <&camera_vdddo_1v8>;
|
||||
vdda-supply = <&camera_vdda_2v8>;
|
||||
|
|
|
@ -361,6 +361,9 @@ examples:
|
|||
compatible = "sony,imx274";
|
||||
reg = <0x1a>;
|
||||
|
||||
clocks = <&serializer>;
|
||||
clock-names = "inck";
|
||||
|
||||
reset-gpios = <&serializer1 0 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
|
|
|
@ -13,9 +13,6 @@ Mandatory properties
|
|||
- reg: I2C address (0x3e, or an alternative address)
|
||||
- vana-supply: Analogue voltage supply (VANA), 2.8 volts
|
||||
- clocks: External clock to the sensor
|
||||
- clock-frequency: Frequency of the external clock to the sensor. Camera
|
||||
driver will set this frequency on the external clock. The clock frequency is
|
||||
a pre-determined frequency known to be suitable to the board.
|
||||
- reset-gpios: XSHUTDOWN GPIO. The XSHUTDOWN signal is active low. The sensor
|
||||
is in hardware standby mode when the signal is in the low state.
|
||||
|
||||
|
@ -43,8 +40,11 @@ Example
|
|||
compatible = "toshiba,et8ek8";
|
||||
reg = <0x3e>;
|
||||
vana-supply = <&vaux4>;
|
||||
|
||||
clocks = <&isp 0>;
|
||||
clock-frequency = <9600000>;
|
||||
assigned-clocks = <&isp 0>;
|
||||
assigned-clock-rates = <9600000>;
|
||||
|
||||
reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
|
||||
port {
|
||||
csi_cam1: endpoint {
|
||||
|
|
|
@ -66,6 +66,14 @@ properties:
|
|||
clock-frequency:
|
||||
description: The desired external clock ("wrap") frequency, in Hz
|
||||
default: 166000000
|
||||
deprecated: true
|
||||
|
||||
fsl,num-channels:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Number of output channels
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
default: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -147,7 +155,9 @@ examples:
|
|||
<&clks IMX7D_MIPI_CSI_ROOT_CLK>,
|
||||
<&clks IMX7D_MIPI_DPHY_ROOT_CLK>;
|
||||
clock-names = "pclk", "wrap", "phy";
|
||||
clock-frequency = <166000000>;
|
||||
|
||||
assigned-clocks = <&clks IMX7D_MIPI_CSI_ROOT_CLK>;
|
||||
assigned-clock-rates = <166000000>;
|
||||
|
||||
power-domains = <&pgc_mipi_phy>;
|
||||
phy-supply = <®_1p0d>;
|
||||
|
@ -185,12 +195,16 @@ examples:
|
|||
compatible = "fsl,imx8mm-mipi-csi2";
|
||||
reg = <0x32e30000 0x1000>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-frequency = <333000000>;
|
||||
|
||||
clocks = <&clk IMX8MM_CLK_DISP_APB_ROOT>,
|
||||
<&clk IMX8MM_CLK_CSI1_ROOT>,
|
||||
<&clk IMX8MM_CLK_CSI1_PHY_REF>,
|
||||
<&clk IMX8MM_CLK_DISP_AXI_ROOT>;
|
||||
clock-names = "pclk", "wrap", "phy", "axi";
|
||||
|
||||
assigned-clocks = <&clk IMX8MM_CLK_CSI1_ROOT>;
|
||||
assigned-clock-rates = <250000000>;
|
||||
|
||||
power-domains = <&mipi_pd>;
|
||||
|
||||
ports {
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/qcom,qcm2290-camss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCM2290 Camera Subsystem (CAMSS)
|
||||
|
||||
maintainers:
|
||||
- Loic Poulain <loic.poulain@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcm2290-camss
|
||||
|
||||
reg:
|
||||
maxItems: 9
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: top
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csitpg0
|
||||
- const: csitpg1
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
|
||||
clocks:
|
||||
maxItems: 15
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: axi
|
||||
- const: camnoc_nrt_axi
|
||||
- const: camnoc_rt_axi
|
||||
- const: csi0
|
||||
- const: csi1
|
||||
- const: csiphy0
|
||||
- const: csiphy0_timer
|
||||
- const: csiphy1
|
||||
- const: csiphy1_timer
|
||||
- const: top_ahb
|
||||
- const: vfe0
|
||||
- const: vfe0_cphy_rx
|
||||
- const: vfe1
|
||||
- const: vfe1_cphy_rx
|
||||
|
||||
interrupts:
|
||||
maxItems: 8
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csitpg0
|
||||
- const: csitpg1
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
|
||||
interconnects:
|
||||
maxItems: 3
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: hf_mnoc
|
||||
- const: sf_mnoc
|
||||
|
||||
iommus:
|
||||
maxItems: 4
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: GDSC CAMSS Block, Global Distributed Switch Controller.
|
||||
|
||||
vdd-csiphy-1p2-supply:
|
||||
description:
|
||||
Phandle to a 1.2V regulator supply to CSI PHYs.
|
||||
|
||||
vdd-csiphy-1p8-supply:
|
||||
description:
|
||||
Phandle to 1.8V regulator supply to CSI PHYs pll block.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
description:
|
||||
CSI input ports.
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-3]+$":
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
|
||||
description:
|
||||
Input port for receiving CSI data from a CSIPHY.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- interconnects
|
||||
- interconnect-names
|
||||
- iommus
|
||||
- power-domains
|
||||
- vdd-csiphy-1p2-supply
|
||||
- vdd-csiphy-1p8-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
|
||||
#include <dt-bindings/interconnect/qcom,rpm-icc.h>
|
||||
#include <dt-bindings/interconnect/qcom,qcm2290.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
camss: camss@5c6e000 {
|
||||
compatible = "qcom,qcm2290-camss";
|
||||
|
||||
reg = <0x0 0x5c11000 0x0 0x1000>,
|
||||
<0x0 0x5c6e000 0x0 0x1000>,
|
||||
<0x0 0x5c75000 0x0 0x1000>,
|
||||
<0x0 0x5c52000 0x0 0x1000>,
|
||||
<0x0 0x5c53000 0x0 0x1000>,
|
||||
<0x0 0x5c66000 0x0 0x400>,
|
||||
<0x0 0x5c68000 0x0 0x400>,
|
||||
<0x0 0x5c6f000 0x0 0x4000>,
|
||||
<0x0 0x5c76000 0x0 0x4000>;
|
||||
reg-names = "top",
|
||||
"csid0",
|
||||
"csid1",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csitpg0",
|
||||
"csitpg1",
|
||||
"vfe0",
|
||||
"vfe1";
|
||||
|
||||
clocks = <&gcc GCC_CAMERA_AHB_CLK>,
|
||||
<&gcc GCC_CAMSS_AXI_CLK>,
|
||||
<&gcc GCC_CAMSS_NRT_AXI_CLK>,
|
||||
<&gcc GCC_CAMSS_RT_AXI_CLK>,
|
||||
<&gcc GCC_CAMSS_TFE_0_CSID_CLK>,
|
||||
<&gcc GCC_CAMSS_TFE_1_CSID_CLK>,
|
||||
<&gcc GCC_CAMSS_CPHY_0_CLK>,
|
||||
<&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>,
|
||||
<&gcc GCC_CAMSS_CPHY_1_CLK>,
|
||||
<&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>,
|
||||
<&gcc GCC_CAMSS_TOP_AHB_CLK>,
|
||||
<&gcc GCC_CAMSS_TFE_0_CLK>,
|
||||
<&gcc GCC_CAMSS_TFE_0_CPHY_RX_CLK>,
|
||||
<&gcc GCC_CAMSS_TFE_1_CLK>,
|
||||
<&gcc GCC_CAMSS_TFE_1_CPHY_RX_CLK>;
|
||||
clock-names = "ahb",
|
||||
"axi",
|
||||
"camnoc_nrt_axi",
|
||||
"camnoc_rt_axi",
|
||||
"csi0",
|
||||
"csi1",
|
||||
"csiphy0",
|
||||
"csiphy0_timer",
|
||||
"csiphy1",
|
||||
"csiphy1_timer",
|
||||
"top_ahb",
|
||||
"vfe0",
|
||||
"vfe0_cphy_rx",
|
||||
"vfe1",
|
||||
"vfe1_cphy_rx";
|
||||
|
||||
interrupts = <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 212 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 72 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 73 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 309 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 310 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 211 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 213 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "csid0",
|
||||
"csid1",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csitpg0",
|
||||
"csitpg1",
|
||||
"vfe0",
|
||||
"vfe1";
|
||||
|
||||
interconnects = <&bimc MASTER_APPSS_PROC RPM_ACTIVE_TAG
|
||||
&config_noc SLAVE_CAMERA_CFG RPM_ACTIVE_TAG>,
|
||||
<&mmrt_virt MASTER_CAMNOC_HF RPM_ALWAYS_TAG
|
||||
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>,
|
||||
<&mmnrt_virt MASTER_CAMNOC_SF RPM_ALWAYS_TAG
|
||||
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>;
|
||||
interconnect-names = "ahb",
|
||||
"hf_mnoc",
|
||||
"sf_mnoc";
|
||||
|
||||
iommus = <&apps_smmu 0x400 0x0>,
|
||||
<&apps_smmu 0x800 0x0>,
|
||||
<&apps_smmu 0x820 0x0>,
|
||||
<&apps_smmu 0x840 0x0>;
|
||||
|
||||
power-domains = <&gcc GCC_CAMSS_TOP_GDSC>;
|
||||
|
||||
vdd-csiphy-1p2-supply = <&pm4125_l5>;
|
||||
vdd-csiphy-1p8-supply = <&pm4125_l13>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,130 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/qcom,qcm2290-venus.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCM2290 Venus video encode and decode accelerators
|
||||
|
||||
maintainers:
|
||||
- Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
The Venus AR50_LITE IP is a video encode and decode accelerator present
|
||||
on Qualcomm platforms.
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,venus-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcm2290-venus
|
||||
|
||||
power-domains:
|
||||
maxItems: 3
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: venus
|
||||
- const: vcodec0
|
||||
- const: cx
|
||||
|
||||
clocks:
|
||||
maxItems: 6
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: iface
|
||||
- const: bus
|
||||
- const: throttle
|
||||
- const: vcodec0_core
|
||||
- const: vcodec0_bus
|
||||
|
||||
iommus:
|
||||
maxItems: 5
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: video-mem
|
||||
- const: cpu-cfg
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- power-domain-names
|
||||
- iommus
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
|
||||
#include <dt-bindings/interconnect/qcom,qcm2290.h>
|
||||
#include <dt-bindings/interconnect/qcom,rpm-icc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
venus: video-codec@5a00000 {
|
||||
compatible = "qcom,qcm2290-venus";
|
||||
reg = <0x5a00000 0xf0000>;
|
||||
|
||||
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
power-domains = <&gcc GCC_VENUS_GDSC>,
|
||||
<&gcc GCC_VCODEC0_GDSC>,
|
||||
<&rpmpd QCM2290_VDDCX>;
|
||||
power-domain-names = "venus",
|
||||
"vcodec0",
|
||||
"cx";
|
||||
|
||||
operating-points-v2 = <&venus_opp_table>;
|
||||
|
||||
clocks = <&gcc GCC_VIDEO_VENUS_CTL_CLK>,
|
||||
<&gcc GCC_VIDEO_AHB_CLK>,
|
||||
<&gcc GCC_VENUS_CTL_AXI_CLK>,
|
||||
<&gcc GCC_VIDEO_THROTTLE_CORE_CLK>,
|
||||
<&gcc GCC_VIDEO_VCODEC0_SYS_CLK>,
|
||||
<&gcc GCC_VCODEC0_AXI_CLK>;
|
||||
clock-names = "core",
|
||||
"iface",
|
||||
"bus",
|
||||
"throttle",
|
||||
"vcodec0_core",
|
||||
"vcodec0_bus";
|
||||
|
||||
memory-region = <&pil_video_mem>;
|
||||
|
||||
iommus = <&apps_smmu 0x860 0x0>,
|
||||
<&apps_smmu 0x880 0x0>,
|
||||
<&apps_smmu 0x861 0x04>,
|
||||
<&apps_smmu 0x863 0x0>,
|
||||
<&apps_smmu 0x804 0xe0>;
|
||||
|
||||
interconnects = <&mmnrt_virt MASTER_VIDEO_P0 RPM_ALWAYS_TAG
|
||||
&bimc SLAVE_EBI1 RPM_ALWAYS_TAG>,
|
||||
<&bimc MASTER_APPSS_PROC RPM_ACTIVE_TAG
|
||||
&config_noc SLAVE_VENUS_CFG RPM_ACTIVE_TAG>;
|
||||
interconnect-names = "video-mem",
|
||||
"cpu-cfg";
|
||||
|
||||
venus_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-133333333 {
|
||||
opp-hz = /bits/ 64 <133333333>;
|
||||
required-opps = <&rpmpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-240000000 {
|
||||
opp-hz = /bits/ 64 <240000000>;
|
||||
required-opps = <&rpmpd_opp_svs>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,336 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/qcom,qcs8300-camss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm QCS8300 CAMSS ISP
|
||||
|
||||
maintainers:
|
||||
- Vikram Sharma <quic_vikramsa@quicinc.com>
|
||||
|
||||
description:
|
||||
The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcs8300-camss
|
||||
|
||||
reg:
|
||||
maxItems: 21
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: csid_wrapper
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csid_lite0
|
||||
- const: csid_lite1
|
||||
- const: csid_lite2
|
||||
- const: csid_lite3
|
||||
- const: csid_lite4
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csiphy2
|
||||
- const: tpg0
|
||||
- const: tpg1
|
||||
- const: tpg2
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
- const: vfe_lite0
|
||||
- const: vfe_lite1
|
||||
- const: vfe_lite2
|
||||
- const: vfe_lite3
|
||||
- const: vfe_lite4
|
||||
|
||||
clocks:
|
||||
maxItems: 26
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: camnoc_axi
|
||||
- const: core_ahb
|
||||
- const: cpas_ahb
|
||||
- const: cpas_fast_ahb_clk
|
||||
- const: cpas_vfe_lite
|
||||
- const: cpas_vfe0
|
||||
- const: cpas_vfe1
|
||||
- const: csid
|
||||
- const: csiphy0
|
||||
- const: csiphy0_timer
|
||||
- const: csiphy1
|
||||
- const: csiphy1_timer
|
||||
- const: csiphy2
|
||||
- const: csiphy2_timer
|
||||
- const: csiphy_rx
|
||||
- const: gcc_axi_hf
|
||||
- const: gcc_axi_sf
|
||||
- const: icp_ahb
|
||||
- const: vfe0
|
||||
- const: vfe0_fast_ahb
|
||||
- const: vfe1
|
||||
- const: vfe1_fast_ahb
|
||||
- const: vfe_lite
|
||||
- const: vfe_lite_ahb
|
||||
- const: vfe_lite_cphy_rx
|
||||
- const: vfe_lite_csid
|
||||
|
||||
interrupts:
|
||||
maxItems: 20
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csid_lite0
|
||||
- const: csid_lite1
|
||||
- const: csid_lite2
|
||||
- const: csid_lite3
|
||||
- const: csid_lite4
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csiphy2
|
||||
- const: tpg0
|
||||
- const: tpg1
|
||||
- const: tpg2
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
- const: vfe_lite0
|
||||
- const: vfe_lite1
|
||||
- const: vfe_lite2
|
||||
- const: vfe_lite3
|
||||
- const: vfe_lite4
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: hf_0
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: top
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
description:
|
||||
CSI input ports.
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-2]+$":
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Input port for receiving CSI data on CSIPHY 0-2.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- interconnects
|
||||
- interconnect-names
|
||||
- iommus
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
|
||||
#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
|
||||
#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
|
||||
#include <dt-bindings/interconnect/qcom,icc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
isp@ac78000 {
|
||||
compatible = "qcom,qcs8300-camss";
|
||||
|
||||
reg = <0x0 0xac78000 0x0 0x1000>,
|
||||
<0x0 0xac7a000 0x0 0x0f00>,
|
||||
<0x0 0xac7c000 0x0 0x0f00>,
|
||||
<0x0 0xac84000 0x0 0x0f00>,
|
||||
<0x0 0xac88000 0x0 0x0f00>,
|
||||
<0x0 0xac8c000 0x0 0x0f00>,
|
||||
<0x0 0xac90000 0x0 0x0f00>,
|
||||
<0x0 0xac94000 0x0 0x0f00>,
|
||||
<0x0 0xac9c000 0x0 0x2000>,
|
||||
<0x0 0xac9e000 0x0 0x2000>,
|
||||
<0x0 0xaca0000 0x0 0x2000>,
|
||||
<0x0 0xacac000 0x0 0x0400>,
|
||||
<0x0 0xacad000 0x0 0x0400>,
|
||||
<0x0 0xacae000 0x0 0x0400>,
|
||||
<0x0 0xac4d000 0x0 0xd000>,
|
||||
<0x0 0xac60000 0x0 0xd000>,
|
||||
<0x0 0xac85000 0x0 0x0d00>,
|
||||
<0x0 0xac89000 0x0 0x0d00>,
|
||||
<0x0 0xac8d000 0x0 0x0d00>,
|
||||
<0x0 0xac91000 0x0 0x0d00>,
|
||||
<0x0 0xac95000 0x0 0x0d00>;
|
||||
reg-names = "csid_wrapper",
|
||||
"csid0",
|
||||
"csid1",
|
||||
"csid_lite0",
|
||||
"csid_lite1",
|
||||
"csid_lite2",
|
||||
"csid_lite3",
|
||||
"csid_lite4",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csiphy2",
|
||||
"tpg0",
|
||||
"tpg1",
|
||||
"tpg2",
|
||||
"vfe0",
|
||||
"vfe1",
|
||||
"vfe_lite0",
|
||||
"vfe_lite1",
|
||||
"vfe_lite2",
|
||||
"vfe_lite3",
|
||||
"vfe_lite4";
|
||||
|
||||
clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
|
||||
<&camcc CAM_CC_CORE_AHB_CLK>,
|
||||
<&camcc CAM_CC_CPAS_AHB_CLK>,
|
||||
<&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_0_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_1_CLK>,
|
||||
<&camcc CAM_CC_CSID_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY0_CLK>,
|
||||
<&camcc CAM_CC_CSI0PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY1_CLK>,
|
||||
<&camcc CAM_CC_CSI1PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY2_CLK>,
|
||||
<&camcc CAM_CC_CSI2PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
|
||||
<&gcc GCC_CAMERA_HF_AXI_CLK>,
|
||||
<&gcc GCC_CAMERA_SF_AXI_CLK>,
|
||||
<&camcc CAM_CC_ICP_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_0_CLK>,
|
||||
<&camcc CAM_CC_IFE_0_FAST_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_1_CLK>,
|
||||
<&camcc CAM_CC_IFE_1_FAST_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_CSID_CLK>;
|
||||
clock-names = "camnoc_axi",
|
||||
"core_ahb",
|
||||
"cpas_ahb",
|
||||
"cpas_fast_ahb_clk",
|
||||
"cpas_vfe_lite",
|
||||
"cpas_vfe0",
|
||||
"cpas_vfe1",
|
||||
"csid",
|
||||
"csiphy0",
|
||||
"csiphy0_timer",
|
||||
"csiphy1",
|
||||
"csiphy1_timer",
|
||||
"csiphy2",
|
||||
"csiphy2_timer",
|
||||
"csiphy_rx",
|
||||
"gcc_axi_hf",
|
||||
"gcc_axi_sf",
|
||||
"icp_ahb",
|
||||
"vfe0",
|
||||
"vfe0_fast_ahb",
|
||||
"vfe1",
|
||||
"vfe1_fast_ahb",
|
||||
"vfe_lite",
|
||||
"vfe_lite_ahb",
|
||||
"vfe_lite_cphy_rx",
|
||||
"vfe_lite_csid";
|
||||
|
||||
interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 564 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 759 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 758 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 604 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 545 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 546 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 547 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 761 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 760 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "csid0",
|
||||
"csid1",
|
||||
"csid_lite0",
|
||||
"csid_lite1",
|
||||
"csid_lite2",
|
||||
"csid_lite3",
|
||||
"csid_lite4",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csiphy2",
|
||||
"tpg0",
|
||||
"tpg1",
|
||||
"tpg2",
|
||||
"vfe0",
|
||||
"vfe1",
|
||||
"vfe_lite0",
|
||||
"vfe_lite1",
|
||||
"vfe_lite2",
|
||||
"vfe_lite3",
|
||||
"vfe_lite4";
|
||||
|
||||
interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
|
||||
&config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
|
||||
<&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
|
||||
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
|
||||
interconnect-names = "ahb",
|
||||
"hf_0";
|
||||
|
||||
iommus = <&apps_smmu 0x2400 0x20>;
|
||||
|
||||
power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
|
||||
power-domain-names = "top";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,361 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/qcom,sa8775p-camss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SA8775P CAMSS ISP
|
||||
|
||||
maintainers:
|
||||
- Vikram Sharma <quic_vikramsa@quicinc.com>
|
||||
|
||||
description:
|
||||
The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sa8775p-camss
|
||||
|
||||
reg:
|
||||
maxItems: 22
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: csid_wrapper
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csid_lite0
|
||||
- const: csid_lite1
|
||||
- const: csid_lite2
|
||||
- const: csid_lite3
|
||||
- const: csid_lite4
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csiphy2
|
||||
- const: csiphy3
|
||||
- const: tpg0
|
||||
- const: tpg1
|
||||
- const: tpg2
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
- const: vfe_lite0
|
||||
- const: vfe_lite1
|
||||
- const: vfe_lite2
|
||||
- const: vfe_lite3
|
||||
- const: vfe_lite4
|
||||
|
||||
clocks:
|
||||
maxItems: 28
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: camnoc_axi
|
||||
- const: core_ahb
|
||||
- const: cpas_ahb
|
||||
- const: cpas_fast_ahb_clk
|
||||
- const: cpas_vfe_lite
|
||||
- const: cpas_vfe0
|
||||
- const: cpas_vfe1
|
||||
- const: csid
|
||||
- const: csiphy0
|
||||
- const: csiphy0_timer
|
||||
- const: csiphy1
|
||||
- const: csiphy1_timer
|
||||
- const: csiphy2
|
||||
- const: csiphy2_timer
|
||||
- const: csiphy3
|
||||
- const: csiphy3_timer
|
||||
- const: csiphy_rx
|
||||
- const: gcc_axi_hf
|
||||
- const: gcc_axi_sf
|
||||
- const: icp_ahb
|
||||
- const: vfe0
|
||||
- const: vfe0_fast_ahb
|
||||
- const: vfe1
|
||||
- const: vfe1_fast_ahb
|
||||
- const: vfe_lite
|
||||
- const: vfe_lite_ahb
|
||||
- const: vfe_lite_cphy_rx
|
||||
- const: vfe_lite_csid
|
||||
|
||||
interrupts:
|
||||
maxItems: 21
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csid_lite0
|
||||
- const: csid_lite1
|
||||
- const: csid_lite2
|
||||
- const: csid_lite3
|
||||
- const: csid_lite4
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csiphy2
|
||||
- const: csiphy3
|
||||
- const: tpg0
|
||||
- const: tpg1
|
||||
- const: tpg2
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
- const: vfe_lite0
|
||||
- const: vfe_lite1
|
||||
- const: vfe_lite2
|
||||
- const: vfe_lite3
|
||||
- const: vfe_lite4
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: hf_0
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller.
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: top
|
||||
|
||||
vdda-phy-supply:
|
||||
description:
|
||||
Phandle to a regulator supply to PHY core block.
|
||||
|
||||
vdda-pll-supply:
|
||||
description:
|
||||
Phandle to 1.8V regulator supply to PHY refclk pll block.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
description:
|
||||
CSI input ports.
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-3]+$":
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Input port for receiving CSI data on CSIPHY 0-3.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- interconnects
|
||||
- interconnect-names
|
||||
- iommus
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
- vdda-phy-supply
|
||||
- vdda-pll-supply
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
|
||||
#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
|
||||
#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
|
||||
#include <dt-bindings/interconnect/qcom,icc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
isp@ac78000 {
|
||||
compatible = "qcom,sa8775p-camss";
|
||||
|
||||
reg = <0x0 0xac78000 0x0 0x1000>,
|
||||
<0x0 0xac7a000 0x0 0x0f00>,
|
||||
<0x0 0xac7c000 0x0 0x0f00>,
|
||||
<0x0 0xac84000 0x0 0x0f00>,
|
||||
<0x0 0xac88000 0x0 0x0f00>,
|
||||
<0x0 0xac8c000 0x0 0x0f00>,
|
||||
<0x0 0xac90000 0x0 0x0f00>,
|
||||
<0x0 0xac94000 0x0 0x0f00>,
|
||||
<0x0 0xac9c000 0x0 0x2000>,
|
||||
<0x0 0xac9e000 0x0 0x2000>,
|
||||
<0x0 0xaca0000 0x0 0x2000>,
|
||||
<0x0 0xaca2000 0x0 0x2000>,
|
||||
<0x0 0xacac000 0x0 0x0400>,
|
||||
<0x0 0xacad000 0x0 0x0400>,
|
||||
<0x0 0xacae000 0x0 0x0400>,
|
||||
<0x0 0xac4d000 0x0 0xd000>,
|
||||
<0x0 0xac5a000 0x0 0xd000>,
|
||||
<0x0 0xac85000 0x0 0x0d00>,
|
||||
<0x0 0xac89000 0x0 0x0d00>,
|
||||
<0x0 0xac8d000 0x0 0x0d00>,
|
||||
<0x0 0xac91000 0x0 0x0d00>,
|
||||
<0x0 0xac95000 0x0 0x0d00>;
|
||||
reg-names = "csid_wrapper",
|
||||
"csid0",
|
||||
"csid1",
|
||||
"csid_lite0",
|
||||
"csid_lite1",
|
||||
"csid_lite2",
|
||||
"csid_lite3",
|
||||
"csid_lite4",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csiphy2",
|
||||
"csiphy3",
|
||||
"tpg0",
|
||||
"tpg1",
|
||||
"tpg2",
|
||||
"vfe0",
|
||||
"vfe1",
|
||||
"vfe_lite0",
|
||||
"vfe_lite1",
|
||||
"vfe_lite2",
|
||||
"vfe_lite3",
|
||||
"vfe_lite4";
|
||||
|
||||
clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
|
||||
<&camcc CAM_CC_CORE_AHB_CLK>,
|
||||
<&camcc CAM_CC_CPAS_AHB_CLK>,
|
||||
<&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_0_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_1_CLK>,
|
||||
<&camcc CAM_CC_CSID_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY0_CLK>,
|
||||
<&camcc CAM_CC_CSI0PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY1_CLK>,
|
||||
<&camcc CAM_CC_CSI1PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY2_CLK>,
|
||||
<&camcc CAM_CC_CSI2PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSIPHY3_CLK>,
|
||||
<&camcc CAM_CC_CSI3PHYTIMER_CLK>,
|
||||
<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
|
||||
<&gcc GCC_CAMERA_HF_AXI_CLK>,
|
||||
<&gcc GCC_CAMERA_SF_AXI_CLK>,
|
||||
<&camcc CAM_CC_ICP_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_0_CLK>,
|
||||
<&camcc CAM_CC_IFE_0_FAST_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_1_CLK>,
|
||||
<&camcc CAM_CC_IFE_1_FAST_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
|
||||
<&camcc CAM_CC_IFE_LITE_CSID_CLK>;
|
||||
clock-names = "camnoc_axi",
|
||||
"core_ahb",
|
||||
"cpas_ahb",
|
||||
"cpas_fast_ahb_clk",
|
||||
"cpas_vfe_lite",
|
||||
"cpas_vfe0",
|
||||
"cpas_vfe1",
|
||||
"csid",
|
||||
"csiphy0",
|
||||
"csiphy0_timer",
|
||||
"csiphy1",
|
||||
"csiphy1_timer",
|
||||
"csiphy2",
|
||||
"csiphy2_timer",
|
||||
"csiphy3",
|
||||
"csiphy3_timer",
|
||||
"csiphy_rx",
|
||||
"gcc_axi_hf",
|
||||
"gcc_axi_sf",
|
||||
"icp_ahb",
|
||||
"vfe0",
|
||||
"vfe0_fast_ahb",
|
||||
"vfe1",
|
||||
"vfe1_fast_ahb",
|
||||
"vfe_lite",
|
||||
"vfe_lite_ahb",
|
||||
"vfe_lite_cphy_rx",
|
||||
"vfe_lite_csid";
|
||||
|
||||
interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 564 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 759 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 758 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 604 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 545 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 546 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 547 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 761 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 760 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "csid0",
|
||||
"csid1",
|
||||
"csid_lite0",
|
||||
"csid_lite1",
|
||||
"csid_lite2",
|
||||
"csid_lite3",
|
||||
"csid_lite4",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csiphy2",
|
||||
"csiphy3",
|
||||
"tpg0",
|
||||
"tpg1",
|
||||
"tpg2",
|
||||
"vfe0",
|
||||
"vfe1",
|
||||
"vfe_lite0",
|
||||
"vfe_lite1",
|
||||
"vfe_lite2",
|
||||
"vfe_lite3",
|
||||
"vfe_lite4";
|
||||
|
||||
interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
|
||||
&config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
|
||||
<&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
|
||||
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
|
||||
interconnect-names = "ahb",
|
||||
"hf_0";
|
||||
|
||||
iommus = <&apps_smmu 0x3400 0x20>;
|
||||
|
||||
power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
|
||||
power-domain-names = "top";
|
||||
|
||||
vdda-phy-supply = <&vreg_l4a_0p88>;
|
||||
vdda-pll-supply = <&vreg_l1c_1p2>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -8,7 +8,7 @@ title: Qualcomm iris video encode and decode accelerators
|
|||
|
||||
maintainers:
|
||||
- Vikash Garodia <quic_vgarodia@quicinc.com>
|
||||
- Dikshita Agarwal <quic_dikshita@quicinc.com>
|
||||
- Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
The iris video processing unit is a video encode and decode accelerator
|
||||
|
@ -20,12 +20,16 @@ properties:
|
|||
- items:
|
||||
- enum:
|
||||
- qcom,sa8775p-iris
|
||||
- qcom,x1e80100-iris
|
||||
- const: qcom,sm8550-iris
|
||||
- enum:
|
||||
- qcom,qcs8300-iris
|
||||
- qcom,sm8550-iris
|
||||
- qcom,sm8650-iris
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 4
|
||||
|
||||
|
@ -45,6 +49,12 @@ properties:
|
|||
- const: core
|
||||
- const: vcodec0_core
|
||||
|
||||
firmware-name:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
|
@ -69,6 +79,9 @@ properties:
|
|||
|
||||
dma-coherent: true
|
||||
|
||||
memory-region:
|
||||
maxItems: 1
|
||||
|
||||
operating-points-v2: true
|
||||
|
||||
opp-table:
|
||||
|
@ -85,7 +98,6 @@ required:
|
|||
- dma-coherent
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,venus-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/qcom,sm8750-iris.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm SM8750 SoC Iris video encoder and decoder
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
|
||||
description:
|
||||
The Iris video processing unit on Qualcomm SM8750 SoC is a video encode and
|
||||
decode accelerator.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm8750-iris
|
||||
|
||||
clocks:
|
||||
maxItems: 6
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface # AXI0
|
||||
- const: core
|
||||
- const: vcodec0_core
|
||||
- const: iface1 # AXI1
|
||||
- const: core_freerun
|
||||
- const: vcodec0_core_freerun
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
interconnects:
|
||||
maxItems: 2
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: cpu-cfg
|
||||
- const: video-mem
|
||||
|
||||
iommus:
|
||||
maxItems: 2
|
||||
|
||||
operating-points-v2: true
|
||||
opp-table:
|
||||
type: object
|
||||
|
||||
power-domains:
|
||||
maxItems: 4
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: venus
|
||||
- const: vcodec0
|
||||
- const: mxc
|
||||
- const: mmcx
|
||||
|
||||
resets:
|
||||
maxItems: 4
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: bus0
|
||||
- const: bus1
|
||||
- const: core
|
||||
- const: vcodec0_core
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- dma-coherent
|
||||
- interconnects
|
||||
- interconnect-names
|
||||
- iommus
|
||||
- power-domain-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,venus-common.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/clock/qcom,sm8750-gcc.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interconnect/qcom,icc.h>
|
||||
#include <dt-bindings/interconnect/qcom,sm8750-rpmh.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
|
||||
video-codec@aa00000 {
|
||||
compatible = "qcom,sm8750-iris";
|
||||
reg = <0x0aa00000 0xf0000>;
|
||||
|
||||
clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
|
||||
<&videocc_mvs0c_clk>,
|
||||
<&videocc_mvs0_clk>,
|
||||
<&gcc GCC_VIDEO_AXI1_CLK>,
|
||||
<&videocc_mvs0c_freerun_clk>,
|
||||
<&videocc_mvs0_freerun_clk>;
|
||||
clock-names = "iface",
|
||||
"core",
|
||||
"vcodec0_core",
|
||||
"iface1",
|
||||
"core_freerun",
|
||||
"vcodec0_core_freerun";
|
||||
|
||||
dma-coherent;
|
||||
iommus = <&apps_smmu 0x1940 0>,
|
||||
<&apps_smmu 0x1947 0>;
|
||||
|
||||
interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
|
||||
&config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
|
||||
<&mmss_noc MASTER_VIDEO_MVP QCOM_ICC_TAG_ALWAYS
|
||||
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
|
||||
interconnect-names = "cpu-cfg",
|
||||
"video-mem";
|
||||
|
||||
interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
operating-points-v2 = <&iris_opp_table>;
|
||||
|
||||
memory-region = <&video_mem>;
|
||||
|
||||
power-domains = <&videocc_mvs0c_gdsc>,
|
||||
<&videocc_mvs0_gdsc>,
|
||||
<&rpmhpd RPMHPD_MXC>,
|
||||
<&rpmhpd RPMHPD_MMCX>;
|
||||
power-domain-names = "venus",
|
||||
"vcodec0",
|
||||
"mxc",
|
||||
"mmcx";
|
||||
|
||||
resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>,
|
||||
<&gcc GCC_VIDEO_AXI1_CLK_ARES>,
|
||||
<&videocc_mvs0c_freerun_clk_ares>,
|
||||
<&videocc_mvs0_freerun_clk_ares>;
|
||||
reset-names = "bus0",
|
||||
"bus1",
|
||||
"core",
|
||||
"vcodec0_core";
|
||||
|
||||
iris_opp_table: opp-table {
|
||||
compatible = "operating-points-v2";
|
||||
|
||||
opp-240000000 {
|
||||
opp-hz = /bits/ 64 <240000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs_d1>,
|
||||
<&rpmhpd_opp_low_svs_d1>;
|
||||
};
|
||||
|
||||
opp-338000000 {
|
||||
opp-hz = /bits/ 64 <338000000>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>,
|
||||
<&rpmhpd_opp_low_svs>;
|
||||
};
|
||||
|
||||
opp-420000000 {
|
||||
opp-hz = /bits/ 64 <420000000>;
|
||||
required-opps = <&rpmhpd_opp_svs>,
|
||||
<&rpmhpd_opp_svs>;
|
||||
};
|
||||
|
||||
opp-444000000 {
|
||||
opp-hz = /bits/ 64 <444000000>;
|
||||
required-opps = <&rpmhpd_opp_svs_l1>,
|
||||
<&rpmhpd_opp_svs_l1>;
|
||||
};
|
||||
|
||||
opp-533333334 {
|
||||
opp-hz = /bits/ 64 <533333334>;
|
||||
required-opps = <&rpmhpd_opp_nom>,
|
||||
<&rpmhpd_opp_nom>;
|
||||
};
|
||||
|
||||
opp-630000000 {
|
||||
opp-hz = /bits/ 64 <630000000>;
|
||||
required-opps = <&rpmhpd_opp_turbo>,
|
||||
<&rpmhpd_opp_turbo>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -71,7 +71,16 @@ properties:
|
|||
const: dphy
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
items:
|
||||
- description: ISP power domain
|
||||
- description: MIPI CSI-2 power domain
|
||||
|
||||
power-domain-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: isp
|
||||
- const: csi2
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -155,14 +164,26 @@ allOf:
|
|||
const: fsl,imx8mp-isp
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
clock-names:
|
||||
minItems: 4
|
||||
iommus: false
|
||||
phys: false
|
||||
phy-names: false
|
||||
power-domains:
|
||||
minItems: 2
|
||||
power-domain-names:
|
||||
minItems: 2
|
||||
required:
|
||||
- fsl,blk-ctrl
|
||||
- power-domain-names
|
||||
else:
|
||||
properties:
|
||||
fsl,blk-ctrl: false
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
power-domain-names: false
|
||||
required:
|
||||
- iommus
|
||||
- phys
|
||||
|
|
|
@ -209,9 +209,10 @@ examples:
|
|||
svdda-supply = <&cam_io_reg>;
|
||||
svddio-supply = <&ldo19_reg>;
|
||||
afvdd-supply = <&ldo19_reg>;
|
||||
clock-frequency = <24000000>;
|
||||
clocks = <&camera 1>;
|
||||
clock-names = "extclk";
|
||||
assigned-clocks = <&camera 1>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
|
|
|
@ -259,10 +259,11 @@ examples:
|
|||
svdda-supply = <&cam_io_reg>;
|
||||
svddio-supply = <&ldo19_reg>;
|
||||
afvdd-supply = <&ldo19_reg>;
|
||||
clock-frequency = <24000000>;
|
||||
/* CAM_B_CLKOUT */
|
||||
clocks = <&camera 1>;
|
||||
clock-names = "extclk";
|
||||
assigned-clocks = <&camera 1>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Silicon Labs Si470x FM Radio Receiver
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil@xs4all.nl>
|
||||
- Hans Verkuil <hverkuil@kernel.org>
|
||||
- Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
|
||||
|
||||
properties:
|
||||
|
|
|
@ -29,21 +29,31 @@ used in the system. Using another frequency may cause harmful effects
|
|||
elsewhere. Therefore only the pre-determined frequencies are configurable by the
|
||||
user.
|
||||
|
||||
The external clock frequency shall be retrieved by obtaining the external clock
|
||||
using the ``devm_v4l2_sensor_clk_get()`` helper function, and then getting its
|
||||
frequency with ``clk_get_rate()``. Usage of the helper function guarantees
|
||||
correct behaviour regardless of whether the sensor is integrated in a DT-based
|
||||
or ACPI-based system.
|
||||
|
||||
ACPI
|
||||
~~~~
|
||||
|
||||
Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
|
||||
can rely on this frequency being used.
|
||||
ACPI-based systems typically don't register the sensor external clock with the
|
||||
kernel, but specify the external clock frequency in the ``clock-frequency``
|
||||
_DSD property. The ``devm_v4l2_sensor_clk_get()`` helper creates and returns a
|
||||
fixed clock set at that rate.
|
||||
|
||||
Devicetree
|
||||
~~~~~~~~~~
|
||||
|
||||
The preferred way to achieve this is using ``assigned-clocks``,
|
||||
``assigned-clock-parents`` and ``assigned-clock-rates`` properties. See the
|
||||
`clock device tree bindings
|
||||
Devicetree-based systems declare the sensor external clock in the device tree
|
||||
and reference it from the sensor node. The preferred way to select the external
|
||||
clock frequency is to use the ``assigned-clocks``, ``assigned-clock-parents``
|
||||
and ``assigned-clock-rates`` properties in the sensor node to set the clock
|
||||
rate. See the `clock device tree bindings
|
||||
<https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml>`_
|
||||
for more information. The driver then gets the frequency using
|
||||
``clk_get_rate()``.
|
||||
for more information. The ``devm_v4l2_sensor_clk_get()`` helper retrieves and
|
||||
returns that clock.
|
||||
|
||||
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
|
||||
|
|
|
@ -75,7 +75,7 @@ The media maintainers that work on specific areas of the subsystem are:
|
|||
Sean Young <sean@mess.org>
|
||||
|
||||
- HDMI CEC:
|
||||
Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
- Media controller drivers:
|
||||
Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
|
@ -84,7 +84,7 @@ The media maintainers that work on specific areas of the subsystem are:
|
|||
Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
|
||||
- V4L2 drivers and core V4L2 frameworks:
|
||||
Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
The subsystem maintainer is:
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org>
|
||||
|
|
|
@ -1,33 +1,27 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
V4L2 File handlers
|
||||
------------------
|
||||
V4L2 File handles
|
||||
-----------------
|
||||
|
||||
struct v4l2_fh provides a way to easily keep file handle specific
|
||||
data that is used by the V4L2 framework.
|
||||
struct v4l2_fh provides a way to easily keep file handle specific data that is
|
||||
used by the V4L2 framework. Its usage is mandatory in all drivers.
|
||||
|
||||
.. attention::
|
||||
New drivers must use struct v4l2_fh
|
||||
since it is also used to implement priority handling
|
||||
(:ref:`VIDIOC_G_PRIORITY`).
|
||||
struct v4l2_fh is allocated in the driver's ``open()`` file operation handler.
|
||||
It is typically embedded in a larger driver-specific structure. The
|
||||
:c:type:`v4l2_fh` must be initialized with a call to :c:func:`v4l2_fh_init`,
|
||||
and added to the video device with :c:func:`v4l2_fh_add`. This associates the
|
||||
:c:type:`v4l2_fh` with the :c:type:`file` by setting ``file->private_data`` to
|
||||
point to the :c:type:`v4l2_fh`.
|
||||
|
||||
The users of :c:type:`v4l2_fh` (in the V4L2 framework, not the driver) know
|
||||
whether a driver uses :c:type:`v4l2_fh` as its ``file->private_data`` pointer
|
||||
by testing the ``V4L2_FL_USES_V4L2_FH`` bit in :c:type:`video_device`->flags.
|
||||
This bit is set whenever :c:func:`v4l2_fh_init` is called.
|
||||
Similarly, the struct v4l2_fh is freed in the driver's ``release()`` file
|
||||
operation handler. It must be removed from the video device with
|
||||
:c:func:`v4l2_fh_del` and cleaned up with :c:func:`v4l2_fh_exit` before being
|
||||
freed.
|
||||
|
||||
struct v4l2_fh is allocated as a part of the driver's own file handle
|
||||
structure and ``file->private_data`` is set to it in the driver's ``open()``
|
||||
function by the driver.
|
||||
|
||||
In many cases the struct v4l2_fh will be embedded in a larger
|
||||
structure. In that case you should call:
|
||||
|
||||
#) :c:func:`v4l2_fh_init` and :c:func:`v4l2_fh_add` in ``open()``
|
||||
#) :c:func:`v4l2_fh_del` and :c:func:`v4l2_fh_exit` in ``release()``
|
||||
|
||||
Drivers can extract their own file handle structure by using the container_of
|
||||
macro.
|
||||
Drivers must not access ``file->private_data`` directly. They can retrieve the
|
||||
:c:type:`v4l2_fh` associated with a :c:type:`file` by calling
|
||||
:c:func:`file_to_v4l2_fh`. Drivers can extract their own file handle structure
|
||||
by using the container_of macro.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -56,18 +50,17 @@ Example:
|
|||
|
||||
...
|
||||
|
||||
file->private_data = &my_fh->fh;
|
||||
v4l2_fh_add(&my_fh->fh);
|
||||
v4l2_fh_add(&my_fh->fh, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_release(struct file *file)
|
||||
{
|
||||
struct v4l2_fh *fh = file->private_data;
|
||||
struct v4l2_fh *fh = file_to_v4l2_fh(file);
|
||||
struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
|
||||
|
||||
...
|
||||
v4l2_fh_del(&my_fh->fh);
|
||||
v4l2_fh_del(&my_fh->fh, file);
|
||||
v4l2_fh_exit(&my_fh->fh);
|
||||
kfree(my_fh);
|
||||
return 0;
|
||||
|
@ -78,19 +71,17 @@ Below is a short description of the :c:type:`v4l2_fh` functions used:
|
|||
:c:func:`v4l2_fh_init <v4l2_fh_init>`
|
||||
(:c:type:`fh <v4l2_fh>`, :c:type:`vdev <video_device>`)
|
||||
|
||||
|
||||
- Initialise the file handle. This **MUST** be performed in the driver's
|
||||
:c:type:`v4l2_file_operations`->open() handler.
|
||||
|
||||
|
||||
:c:func:`v4l2_fh_add <v4l2_fh_add>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
(:c:type:`fh <v4l2_fh>`, struct file \*filp)
|
||||
|
||||
- Add a :c:type:`v4l2_fh` to :c:type:`video_device` file handle list.
|
||||
Must be called once the file handle is completely initialized.
|
||||
|
||||
:c:func:`v4l2_fh_del <v4l2_fh_del>`
|
||||
(:c:type:`fh <v4l2_fh>`)
|
||||
(:c:type:`fh <v4l2_fh>`, struct file \*filp)
|
||||
|
||||
- Unassociate the file handle from :c:type:`video_device`. The file handle
|
||||
exit function may now be called.
|
||||
|
@ -101,6 +92,10 @@ Below is a short description of the :c:type:`v4l2_fh` functions used:
|
|||
- Uninitialise the file handle. After uninitialisation the :c:type:`v4l2_fh`
|
||||
memory can be freed.
|
||||
|
||||
:c:func:`file_to_v4l2_fh <file_to_v4l2_fh>`
|
||||
(struct file \*filp)
|
||||
|
||||
- Retrieve the :c:type:`v4l2_fh` instance associated with a :c:type:`file`.
|
||||
|
||||
If struct v4l2_fh is not embedded, then you can use these helper functions:
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ objdump
|
|||
例如,您在gspca的sonixj.c文件中发现一个缺陷,则可以通过以下方法找到它的维护者::
|
||||
|
||||
$ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c
|
||||
Hans Verkuil <hverkuil@xs4all.nl> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Hans Verkuil <hverkuil@kernel.org> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%)
|
||||
Tejun Heo <tj@kernel.org> (commit_signer:1/1=100%)
|
||||
Bhaktipriya Shridhar <bhaktipriya96@gmail.com> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%)
|
||||
|
|
|
@ -775,11 +775,6 @@ v4l2_fh 结构体提供一个保存用于 V4L2 框架的文件句柄特定数据
|
|||
如果 video_device 标志,新驱动
|
||||
必须使用 v4l2_fh 结构体,因为它也用于实现优先级处理(VIDIOC_G/S_PRIORITY)。
|
||||
|
||||
v4l2_fh 的用户(位于 V4l2 框架中,并非驱动)可通过测试
|
||||
video_device->flags 中的 V4L2_FL_USES_V4L2_FH 位得知驱动是否使用
|
||||
v4l2_fh 作为他的 file->private_data 指针。这个位会在调用 v4l2_fh_init()
|
||||
时被设置。
|
||||
|
||||
v4l2_fh 结构体作为驱动自身文件句柄结构体的一部分被分配,且驱动在
|
||||
其打开函数中将 file->private_data 指向它。
|
||||
|
||||
|
@ -812,18 +807,17 @@ int my_open(struct file *file)
|
|||
|
||||
...
|
||||
|
||||
file->private_data = &my_fh->fh;
|
||||
v4l2_fh_add(&my_fh->fh);
|
||||
v4l2_fh_add(&my_fh->fh, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_release(struct file *file)
|
||||
{
|
||||
struct v4l2_fh *fh = file->private_data;
|
||||
struct v4l2_fh *fh = file_to_v4l2_fh(file);
|
||||
struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
|
||||
|
||||
...
|
||||
v4l2_fh_del(&my_fh->fh);
|
||||
v4l2_fh_del(&my_fh->fh, file);
|
||||
v4l2_fh_exit(&my_fh->fh);
|
||||
kfree(my_fh);
|
||||
return 0;
|
||||
|
@ -836,12 +830,12 @@ void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
|
|||
初始化文件句柄。这*必须*在驱动的 v4l2_file_operations->open()
|
||||
函数中执行。
|
||||
|
||||
void v4l2_fh_add(struct v4l2_fh *fh)
|
||||
void v4l2_fh_add(struct v4l2_fh *fh, struct file *filp)
|
||||
|
||||
添加一个 v4l2_fh 到 video_device 文件句柄列表。一旦文件句柄
|
||||
初始化完成就必须调用。
|
||||
|
||||
void v4l2_fh_del(struct v4l2_fh *fh)
|
||||
void v4l2_fh_del(struct v4l2_fh *fh, struct file *filp)
|
||||
|
||||
从 video_device() 中解除文件句柄的关联。文件句柄的退出函数也
|
||||
将被调用。
|
||||
|
|
|
@ -242,7 +242,7 @@ objdump
|
|||
例如,您在gspca的sonixj.c文件中發現一個缺陷,則可以通過以下方法找到它的維護者::
|
||||
|
||||
$ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c
|
||||
Hans Verkuil <hverkuil@xs4all.nl> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Hans Verkuil <hverkuil@kernel.org> (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%)
|
||||
Mauro Carvalho Chehab <mchehab@kernel.org> (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%)
|
||||
Tejun Heo <tj@kernel.org> (commit_signer:1/1=100%)
|
||||
Bhaktipriya Shridhar <bhaktipriya96@gmail.com> (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%)
|
||||
|
|
|
@ -26,7 +26,7 @@ Revision and Copyright
|
|||
**********************
|
||||
Authors:
|
||||
|
||||
- Verkuil, Hans <hverkuil-cisco@xs4all.nl>
|
||||
- Verkuil, Hans <hverkuil@kernel.org>
|
||||
|
||||
- Initial version.
|
||||
|
||||
|
|
|
@ -10,11 +10,13 @@ used to control the camera sensor drivers.
|
|||
|
||||
You may also find :ref:`media_writing_camera_sensor_drivers` useful.
|
||||
|
||||
Frame size
|
||||
----------
|
||||
Sensor internal pipeline configuration
|
||||
--------------------------------------
|
||||
|
||||
There are two distinct ways to configure the frame size produced by camera
|
||||
sensors.
|
||||
Camera sensors have an internal processing pipeline including cropping and
|
||||
binning functionality. The sensor drivers belong to two distinct classes, freely
|
||||
configurable and register list-based drivers, depending on how the driver
|
||||
configures this functionality.
|
||||
|
||||
Freely configurable camera sensor drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -26,10 +28,10 @@ of cropping and scaling operations from the device's pixel array's size.
|
|||
|
||||
An example of such a driver is the CCS driver.
|
||||
|
||||
Register list based drivers
|
||||
Register list-based drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Register list based drivers generally, instead of able to configure the device
|
||||
Register list-based drivers generally, instead of able to configure the device
|
||||
they control based on user requests, are limited to a number of preset
|
||||
configurations that combine a number of different parameters that on hardware
|
||||
level are independent. How a driver picks such configuration is based on the
|
||||
|
@ -67,7 +69,7 @@ is pixels and the unit of the ``V4L2_CID_VBLANK`` is lines. The pixel rate in
|
|||
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
|
||||
device's internal processing pipeline.
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ Raw format c example
|
|||
Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data
|
||||
---------------------------------------------------------
|
||||
|
||||
Author: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
Author: Hans Verkuil <hverkuil@kernel.org>
|
||||
|
||||
|
||||
This section describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data
|
||||
|
|
|
@ -26,7 +26,7 @@ Arguments
|
|||
File descriptor returned by :c:func:`open()`.
|
||||
|
||||
``tone``
|
||||
An integer enumered value described at :c:type:`fe_sec_mini_cmd`.
|
||||
An integer enumerated value described at :c:type:`fe_sec_mini_cmd`.
|
||||
|
||||
Description
|
||||
===========
|
||||
|
|
|
@ -26,7 +26,7 @@ Arguments
|
|||
File descriptor returned by :c:func:`open()`.
|
||||
|
||||
``tone``
|
||||
an integer enumered value described at :c:type:`fe_sec_tone_mode`
|
||||
An integer enumerated value described at :c:type:`fe_sec_tone_mode`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
|
|
@ -26,7 +26,7 @@ Arguments
|
|||
File descriptor returned by :c:func:`open()`.
|
||||
|
||||
``voltage``
|
||||
an integer enumered value described at :c:type:`fe_sec_voltage`
|
||||
An integer enumerated value described at :c:type:`fe_sec_voltage`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
|
|
@ -72,11 +72,11 @@ DTV_MODULATION
|
|||
==============
|
||||
|
||||
Specifies the frontend modulation type for delivery systems that
|
||||
supports more multiple modulations.
|
||||
support multiple modulations.
|
||||
|
||||
The modulation can be one of the types defined by enum :c:type:`fe_modulation`.
|
||||
|
||||
Most of the digital TV standards offers more than one possible
|
||||
Most of the digital TV standards offer more than one possible
|
||||
modulation type.
|
||||
|
||||
The table below presents a summary of the types of modulation types
|
||||
|
@ -143,9 +143,8 @@ ISDB-T 5MHz, 6MHz, 7MHz and 8MHz, although most places
|
|||
(DTV_ISDBT_SB_SEGMENT_IDX, DTV_ISDBT_SB_SEGMENT_COUNT).
|
||||
|
||||
#. On Satellite and Cable delivery systems, the bandwidth depends on
|
||||
the symbol rate. So, the Kernel will silently ignore any setting
|
||||
:ref:`DTV-BANDWIDTH-HZ`. I will however fill it back with a
|
||||
bandwidth estimation.
|
||||
the symbol rate. The kernel will silently ignore any :ref:`DTV-BANDWIDTH-HZ`
|
||||
setting and overwrites it with bandwidth estimation.
|
||||
|
||||
Such bandwidth estimation takes into account the symbol rate set with
|
||||
:ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for
|
||||
|
@ -200,7 +199,7 @@ DTV_VOLTAGE
|
|||
Used on satellite delivery systems.
|
||||
|
||||
The voltage is usually used with non-DiSEqC capable LNBs to switch the
|
||||
polarzation (horizontal/vertical). When using DiSEqC epuipment this
|
||||
polarization (horizontal/vertical). When using DiSEqC equipment this
|
||||
voltage has to be switched consistently to the DiSEqC commands as
|
||||
described in the DiSEqC spec.
|
||||
|
||||
|
@ -280,7 +279,7 @@ DTV_ISDBT_PARTIAL_RECEPTION
|
|||
|
||||
Used only on ISDB.
|
||||
|
||||
If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents
|
||||
If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit field represents
|
||||
whether the channel is in partial reception mode or not.
|
||||
|
||||
If '1' ``DTV_ISDBT_LAYERA_*`` values are assigned to the center segment
|
||||
|
@ -331,8 +330,8 @@ broadcaster has several possibilities to put those channels in the air:
|
|||
Assuming a normal 13-segment ISDB-T spectrum he can align the 8 segments
|
||||
from position 1-8 to 5-13 or anything in between.
|
||||
|
||||
The underlying layer of segments are subchannels: each segment is
|
||||
consisting of several subchannels with a predefined IDs. A sub-channel
|
||||
The underlying layer of segments are sub-channels: each segment is
|
||||
consisting of several sub-channels with a predefined IDs. A sub-channel
|
||||
is used to help the demodulator to synchronize on the channel.
|
||||
|
||||
An ISDB-T channel is always centered over all sub-channels. As for the
|
||||
|
@ -728,7 +727,7 @@ DTV_ATSCMH_RS_FRAME_ENSEMBLE
|
|||
|
||||
Used only on ATSC-MH.
|
||||
|
||||
Reed Solomon(RS) frame ensemble.
|
||||
Reed Solomon (RS) frame ensemble.
|
||||
|
||||
The acceptable values are defined by :c:type:`atscmh_rs_frame_ensemble`.
|
||||
|
||||
|
@ -954,14 +953,14 @@ DTV_ENUM_DELSYS
|
|||
|
||||
A Multi standard frontend needs to advertise the delivery systems
|
||||
provided. Applications need to enumerate the provided delivery systems,
|
||||
before using any other operation with the frontend. Prior to it's
|
||||
before using any other operation with the frontend. Prior to its
|
||||
introduction, FE_GET_INFO was used to determine a frontend type. A
|
||||
frontend which provides more than a single delivery system,
|
||||
FE_GET_INFO doesn't help much. Applications which intends to use a
|
||||
multistandard frontend must enumerate the delivery systems associated
|
||||
with it, rather than trying to use FE_GET_INFO. In the case of a
|
||||
legacy frontend, the result is just the same as with FE_GET_INFO, but
|
||||
in a more structured format
|
||||
in a more structured format.
|
||||
|
||||
The acceptable values are defined by :c:type:`fe_delivery_system`.
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ DVB-T2 delivery system
|
|||
======================
|
||||
|
||||
DVB-T2 support is currently in the early stages of development, so
|
||||
expect that this section maygrow and become more detailed with time.
|
||||
expect that this section may grow and become more detailed with time.
|
||||
|
||||
The following parameters are valid for DVB-T2:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
|
||||
|
||||
.. _dvb_introdution:
|
||||
.. _dvb_introduction:
|
||||
|
||||
************
|
||||
Introduction
|
||||
|
@ -125,7 +125,7 @@ demux, CA and IP-over-DVB networking. The video and audio devices
|
|||
control the MPEG2 decoder hardware, the frontend device the tuner and
|
||||
the Digital TV demodulator. The demux device gives you control over the PES
|
||||
and section filters of the hardware. If the hardware does not support
|
||||
filtering these filters can be implemented in software. Finally, the CA
|
||||
filtering, these filters can be implemented in software. Finally, the CA
|
||||
device controls all the conditional access capabilities of the hardware.
|
||||
It can depend on the individual security requirements of the platform,
|
||||
if and how many of the CA functions are made available to the
|
||||
|
|
|
@ -195,7 +195,7 @@ Description
|
|||
~~~~~~~~~~~
|
||||
|
||||
The audio channel selected via `AUDIO_CHANNEL_SELECT`_ is determined by
|
||||
this values.
|
||||
this value.
|
||||
|
||||
|
||||
-----
|
||||
|
@ -413,7 +413,7 @@ Constants
|
|||
- ``AUDIO_CAP_MP3``
|
||||
|
||||
- The hardware accepts MPEG-1 Audio Layer III.
|
||||
Commomly known as .mp3.
|
||||
Commonly known as .mp3.
|
||||
|
||||
- ..
|
||||
|
||||
|
|
|
@ -509,7 +509,7 @@ source pads.
|
|||
.. _subdev-routing:
|
||||
|
||||
Streams, multiplexed media pads and internal routing
|
||||
----------------------------------------------------
|
||||
====================================================
|
||||
|
||||
Simple V4L2 sub-devices do not support multiple, unrelated video streams,
|
||||
and only a single stream can pass through a media link and a media pad.
|
||||
|
@ -534,7 +534,7 @@ does not support streams, then only stream 0 of source end may be captured.
|
|||
There may be additional limitations specific to the sink device.
|
||||
|
||||
Understanding streams
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
---------------------
|
||||
|
||||
A stream is a stream of content (e.g. pixel data or metadata) flowing through
|
||||
the media pipeline from a source (e.g. a sensor) towards the final sink (e.g. a
|
||||
|
@ -554,7 +554,7 @@ sub-device and a (pad, stream) pair. For sub-devices that do not support
|
|||
multiplexed streams the 'stream' field is always 0.
|
||||
|
||||
Interaction between routes, streams, formats and selections
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
-----------------------------------------------------------
|
||||
|
||||
The addition of streams to the V4L2 sub-device interface moves the sub-device
|
||||
formats and selections from pads to (pad, stream) pairs. Besides the
|
||||
|
@ -573,7 +573,7 @@ are independent of similar configurations on other streams. This is
|
|||
subject to change in the future.
|
||||
|
||||
Device types and routing setup
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
------------------------------
|
||||
|
||||
Different kinds of sub-devices have differing behaviour for route activation,
|
||||
depending on the hardware. In all cases, however, only routes that have the
|
||||
|
@ -596,7 +596,7 @@ called on the sub-device. Such newly created routes have the device's default
|
|||
configuration for format and selection rectangles.
|
||||
|
||||
Configuring streams
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
-------------------
|
||||
|
||||
The configuration of the streams is done individually for each sub-device and
|
||||
the validity of the streams between sub-devices is validated when the pipeline
|
||||
|
@ -619,7 +619,7 @@ There are three steps in configuring the streams:
|
|||
:ref:`VIDIOC_SUBDEV_S_ROUTING <VIDIOC_SUBDEV_G_ROUTING>` ioctl.
|
||||
|
||||
Multiplexed streams setup example
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
---------------------------------
|
||||
|
||||
A simple example of a multiplexed stream setup might be as follows:
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ This format is little endian.
|
|||
**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_10.**
|
||||
Each cell is one byte. "M" denotes a byte of metadata and "x" a byte of padding.
|
||||
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{.8cm}|
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.8cm}|
|
||||
|
||||
.. flat-table:: Sample 4x2 Metadata Frame
|
||||
:header-rows: 0
|
||||
|
@ -115,7 +115,7 @@ This format is little endian.
|
|||
**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_12.**
|
||||
Each cell is one byte. "M" denotes a byte of metadata and "x" a byte of padding.
|
||||
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{.8cm}|p{.8cm}|
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.8cm}|p{1.2cm}|p{1.2cm}|p{1.8cm}|
|
||||
|
||||
.. flat-table:: Sample 4x2 Metadata Frame
|
||||
:header-rows: 0
|
||||
|
@ -156,7 +156,7 @@ This format is little endian.
|
|||
**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_14.**
|
||||
Each cell is one byte. "M" denotes a byte of metadata and "x" a byte of padding.
|
||||
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{.8cm}|
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.8cm}|p{1.8cm}|p{1.8cm}|
|
||||
|
||||
.. flat-table:: Sample 4x2 Metadata Frame
|
||||
:header-rows: 0
|
||||
|
@ -252,7 +252,7 @@ This format is little endian.
|
|||
**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_20.**
|
||||
Each cell is one byte. "M" denotes a byte of metadata and "x" a byte of padding.
|
||||
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}|
|
||||
.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.8cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.8cm}
|
||||
|
||||
.. flat-table:: Sample 4x2 Metadata Frame
|
||||
:header-rows: 0
|
||||
|
|
|
@ -86,7 +86,7 @@ Authors, in alphabetical order:
|
|||
|
||||
- Documented the fielded V4L2_MPEG_STREAM_VBI_FMT_IVTV MPEG stream embedded, sliced VBI data format in this specification.
|
||||
|
||||
- Verkuil, Hans <hverkuil@xs4all.nl>
|
||||
- Verkuil, Hans <hverkuil@kernel.org>
|
||||
|
||||
- Designed and documented the VIDIOC_LOG_STATUS ioctl, the extended control ioctls, major parts of the sliced VBI API, the MPEG encoder and decoder APIs and the DV Timings API.
|
||||
|
||||
|
|
150
MAINTAINERS
150
MAINTAINERS
|
@ -717,7 +717,7 @@ S: Maintained
|
|||
F: drivers/scsi/aic7xxx/
|
||||
|
||||
AIMSLAB FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -1709,20 +1709,20 @@ F: Documentation/devicetree/bindings/media/i2c/adi,adv748x.yaml
|
|||
F: drivers/media/i2c/adv748x/*
|
||||
|
||||
ANALOG DEVICES INC ADV7511 DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/adv7511*
|
||||
|
||||
ANALOG DEVICES INC ADV7604 DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/adi,adv7604.yaml
|
||||
F: drivers/media/i2c/adv7604*
|
||||
|
||||
ANALOG DEVICES INC ADV7842 DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/adv7842*
|
||||
|
@ -3477,7 +3477,7 @@ F: arch/arm/mach-berlin/
|
|||
F: arch/arm64/boot/dts/synaptics/
|
||||
|
||||
ARM/TEGRA HDMI CEC SUBSYSTEM SUPPORT
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-tegra@vger.kernel.org
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -4178,7 +4178,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/usb/dvb-usb-v2/az6007.c
|
||||
|
||||
AZTECH FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -5404,6 +5404,7 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/media/cdns,*.txt
|
||||
F: Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
|
||||
F: drivers/media/platform/cadence/cdns-csi2*
|
||||
F: include/media/cadence/cdns-csi2*
|
||||
|
||||
CADENCE NAND DRIVER
|
||||
L: linux-mtd@lists.infradead.org
|
||||
|
@ -5437,7 +5438,7 @@ F: drivers/usb/cdns3/
|
|||
X: drivers/usb/cdns3/cdns3*
|
||||
|
||||
CADET FM/AM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -5630,7 +5631,7 @@ F: drivers/char/hw_random/cctrng.c
|
|||
F: drivers/char/hw_random/cctrng.h
|
||||
|
||||
CEC FRAMEWORK
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://linuxtv.org
|
||||
|
@ -5647,7 +5648,7 @@ F: include/uapi/linux/cec-funcs.h
|
|||
F: include/uapi/linux/cec.h
|
||||
|
||||
CEC GPIO DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://linuxtv.org
|
||||
|
@ -6062,7 +6063,7 @@ S: Supported
|
|||
F: drivers/platform/x86/classmate-laptop.c
|
||||
|
||||
COBALT MEDIA DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://linuxtv.org
|
||||
|
@ -6588,7 +6589,7 @@ F: crypto/ansi_cprng.c
|
|||
F: crypto/rng.c
|
||||
|
||||
CS3308 MEDIA DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: http://linuxtv.org
|
||||
|
@ -6629,7 +6630,7 @@ F: drivers/media/pci/cx18/
|
|||
F: include/uapi/linux/ivtv*
|
||||
|
||||
CX2341X MPEG ENCODER HELPER MODULE
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -8626,7 +8627,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/radio/dsbr100.c
|
||||
|
||||
DT3155 MEDIA DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: https://linuxtv.org
|
||||
|
@ -9379,7 +9380,7 @@ F: tools/bootconfig/*
|
|||
F: tools/bootconfig/scripts/*
|
||||
|
||||
EXTRON DA HD 4K PLUS CEC DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -10253,6 +10254,12 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/media/i2c/galaxycore,gc0308.yaml
|
||||
F: drivers/media/i2c/gc0308.c
|
||||
|
||||
GALAXYCORE GC0310 CAMERA SENSOR DRIVER
|
||||
M: Hans de Goede <hansg@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/i2c/gc0310.c
|
||||
|
||||
GALAXYCORE GC05a2 CAMERA SENSOR DRIVER
|
||||
M: Zhi Mao <zhi.mao@mediatek.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -10321,7 +10328,7 @@ S: Maintained
|
|||
F: drivers/crypto/gemini/
|
||||
|
||||
GEMTEK FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -10510,7 +10517,7 @@ F: drivers/gnss/
|
|||
F: include/linux/gnss.h
|
||||
|
||||
GO7007 MPEG CODEC
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/usb/go7007/
|
||||
|
@ -10770,7 +10777,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/usb/gspca/m5602/
|
||||
|
||||
GSPCA PAC207 SONIXB SUBDRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -10791,7 +10798,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/usb/gspca/t613.c
|
||||
|
||||
GSPCA USB WEBCAM DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -10908,7 +10915,7 @@ S: Maintained
|
|||
F: sound/parisc/harmony.*
|
||||
|
||||
HDPVR USB VIDEO ENCODER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: https://linuxtv.org
|
||||
|
@ -12576,7 +12583,6 @@ F: drivers/media/pci/intel/ipu6/
|
|||
INTEL IPU7 INPUT SYSTEM DRIVER
|
||||
M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
R: Bingbu Cao <bingbu.cao@intel.com>
|
||||
R: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -12872,7 +12878,6 @@ INTEL VISION SENSING CONTROLLER DRIVER
|
|||
M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
R: Bingbu Cao <bingbu.cao@intel.com>
|
||||
R: Lixu Zhang <lixu.zhang@intel.com>
|
||||
R: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -13119,7 +13124,7 @@ F: drivers/base/isa.c
|
|||
F: include/linux/isa.h
|
||||
|
||||
ISA RADIO MODULE
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -13295,7 +13300,7 @@ F: fs/jbd2/
|
|||
F: include/linux/jbd2.h
|
||||
|
||||
JPU V4L2 MEM2MEM DRIVER FOR RENESAS
|
||||
M: Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>
|
||||
M: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -13391,7 +13396,7 @@ F: include/uapi/linux/vmcore.h
|
|||
F: kernel/crash_*.c
|
||||
|
||||
KEENE FM RADIO TRANSMITTER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -15293,7 +15298,7 @@ F: include/linux/mfd/max77693*.h
|
|||
F: include/linux/mfd/max77705*.h
|
||||
|
||||
MAXIRADIO FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -17225,7 +17230,7 @@ F: drivers/irqchip/irq-loongson*
|
|||
F: drivers/platform/mips/cpu_hwmon.c
|
||||
|
||||
MIROSOUND PCM20 FM RADIO RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: https://linuxtv.org
|
||||
|
@ -17492,7 +17497,6 @@ S: Maintained
|
|||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/aptina,mt9v032.txt
|
||||
F: drivers/media/i2c/mt9v032.c
|
||||
F: include/media/i2c/mt9v032.h
|
||||
|
||||
MT9V111 APTINA CAMERA SENSOR
|
||||
M: Jacopo Mondi <jacopo@jmondi.org>
|
||||
|
@ -18825,6 +18829,14 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/media/i2c/ovti,og01a1b.yaml
|
||||
F: drivers/media/i2c/og01a1b.c
|
||||
|
||||
OMNIVISION OG0VE1B SENSOR DRIVER
|
||||
M: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,og0ve1b.yaml
|
||||
F: drivers/media/i2c/og0ve1b.c
|
||||
|
||||
OMNIVISION OV01A10 SENSOR DRIVER
|
||||
M: Bingbu Cao <bingbu.cao@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -18902,6 +18914,14 @@ T: git git://linuxtv.org/media.git
|
|||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov2685.yaml
|
||||
F: drivers/media/i2c/ov2685.c
|
||||
|
||||
OMNIVISION OV2735 SENSOR DRIVER
|
||||
M: Hardevsinh Palaniya <hardevsinh.palaniya@siliconsignals.io>
|
||||
M: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov2735.yaml
|
||||
F: drivers/media/i2c/ov2735.c
|
||||
|
||||
OMNIVISION OV2740 SENSOR DRIVER
|
||||
M: Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||
R: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
|
@ -18966,6 +18986,14 @@ S: Maintained
|
|||
T: git git://linuxtv.org/media.git
|
||||
F: drivers/media/i2c/ov5695.c
|
||||
|
||||
OMNIVISION OV6211 SENSOR DRIVER
|
||||
M: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov6211.yaml
|
||||
F: drivers/media/i2c/ov6211.c
|
||||
|
||||
OMNIVISION OV64A40 SENSOR DRIVER
|
||||
M: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -20579,7 +20607,7 @@ F: include/uapi/linux/ptrace.h
|
|||
F: kernel/ptrace.c
|
||||
|
||||
PULSE8-CEC DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -20602,7 +20630,7 @@ F: Documentation/driver-api/media/drivers/pvrusb2*
|
|||
F: drivers/media/usb/pvrusb2/
|
||||
|
||||
PWC WEBCAM DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -21060,10 +21088,9 @@ F: Documentation/devicetree/bindings/regulator/vqmmc-ipq4019-regulator.yaml
|
|||
F: drivers/regulator/vqmmc-ipq4019-regulator.c
|
||||
|
||||
QUALCOMM IRIS VIDEO ACCELERATOR DRIVER
|
||||
M: Vikash Garodia <quic_vgarodia@quicinc.com>
|
||||
M: Dikshita Agarwal <quic_dikshita@quicinc.com>
|
||||
M: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
|
||||
M: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
|
||||
R: Abhinav Kumar <abhinav.kumar@linux.dev>
|
||||
R: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -21078,6 +21105,17 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/mtd/qcom,nandc.yaml
|
||||
F: drivers/mtd/nand/raw/qcom_nandc.c
|
||||
|
||||
QUALCOMM MEDIA PLATFORM
|
||||
M: Bryan O'Donoghue <bod@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Supported
|
||||
Q: https://patchwork.linuxtv.org/project/linux-media/list
|
||||
T: git https://gitlab.freedesktop.org/linux-media/media-committers.git
|
||||
F: Documentation/devicetree/bindings/media/*qcom*
|
||||
F: drivers/media/platform/qcom
|
||||
F: include/dt-bindings/media/*qcom*
|
||||
|
||||
QUALCOMM SMB CHARGER DRIVER
|
||||
M: Casey Connolly <casey.connolly@linaro.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
|
@ -21139,9 +21177,8 @@ F: Documentation/devicetree/bindings/usb/qcom,pmic-*.yaml
|
|||
F: drivers/usb/typec/tcpm/qcom/
|
||||
|
||||
QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
|
||||
M: Vikash Garodia <quic_vgarodia@quicinc.com>
|
||||
M: Dikshita Agarwal <quic_dikshita@quicinc.com>
|
||||
R: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
M: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
|
||||
M: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -21186,14 +21223,14 @@ F: drivers/video/fbdev/aty/radeon*
|
|||
F: include/uapi/linux/radeonfb.h
|
||||
|
||||
RADIOSHARK RADIO DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: drivers/media/radio/radio-shark.c
|
||||
|
||||
RADIOSHARK2 RADIO DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -21217,7 +21254,7 @@ S: Orphan
|
|||
F: drivers/video/fbdev/aty/aty128fb.c
|
||||
|
||||
RAINSHADOW-CEC DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -22080,6 +22117,7 @@ F: drivers/media/platform/rockchip/rga/
|
|||
|
||||
ROCKCHIP RKVDEC VIDEO DECODER DRIVER
|
||||
M: Detlev Casanova <detlev.casanova@collabora.com>
|
||||
M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-rockchip@lists.infradead.org
|
||||
S: Maintained
|
||||
|
@ -22100,14 +22138,6 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/sound/rockchip,rk3576-sai.yaml
|
||||
F: sound/soc/rockchip/rockchip_sai.*
|
||||
|
||||
ROCKCHIP VIDEO DECODER DRIVER
|
||||
M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-rockchip@lists.infradead.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/rockchip,vdec.yaml
|
||||
F: drivers/staging/media/rkvdec/
|
||||
|
||||
ROCKER DRIVER
|
||||
M: Jiri Pirko <jiri@resnulli.us>
|
||||
L: netdev@vger.kernel.org
|
||||
|
@ -22527,7 +22557,7 @@ S: Supported
|
|||
F: drivers/s390/scsi/zfcp_*
|
||||
|
||||
SAA6588 RDS RECEIVER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: https://linuxtv.org
|
||||
|
@ -22544,7 +22574,7 @@ F: Documentation/driver-api/media/drivers/saa7134*
|
|||
F: drivers/media/pci/saa7134/
|
||||
|
||||
SAA7146 VIDEO4LINUX-2 DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -23270,7 +23300,7 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
|||
F: drivers/media/dvb-frontends/si2168*
|
||||
|
||||
SI470X FM RADIO RECEIVER I2C DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: https://linuxtv.org
|
||||
|
@ -23279,7 +23309,7 @@ F: Documentation/devicetree/bindings/media/silabs,si470x.yaml
|
|||
F: drivers/media/radio/si470x/radio-si470x-i2c.c
|
||||
|
||||
SI470X FM RADIO RECEIVER USB DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -23305,7 +23335,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/radio/si4713/radio-platform-si4713.c
|
||||
|
||||
SI4713 FM RADIO TRANSMITTER USB DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -24942,7 +24972,7 @@ T: git git://linuxtv.org/mkrufky/tuners.git
|
|||
F: drivers/media/tuners/tda8290.*
|
||||
|
||||
TDA9840 MEDIA DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -24966,7 +24996,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/tuners/tea5767.*
|
||||
|
||||
TEA6415C MEDIA DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -24974,7 +25004,7 @@ T: git git://linuxtv.org/media.git
|
|||
F: drivers/media/i2c/tea6415c*
|
||||
|
||||
TEA6420 MEDIA DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -25283,7 +25313,7 @@ F: Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml
|
|||
F: drivers/iio/temperature/tmp117.c
|
||||
|
||||
THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -25631,7 +25661,7 @@ S: Maintained
|
|||
F: sound/soc/codecs/twl4030*
|
||||
|
||||
TI VPE/CAL DRIVERS
|
||||
M: Benoit Parrot <bparrot@ti.com>
|
||||
M: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://linuxtv.org/
|
||||
|
@ -25780,7 +25810,7 @@ F: include/linux/toshiba.h
|
|||
F: include/uapi/linux/toshiba.h
|
||||
|
||||
TOSHIBA TC358743 DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/toshiba,tc358743.txt
|
||||
|
@ -25989,7 +26019,7 @@ S: Supported
|
|||
F: drivers/media/pci/tw5864/
|
||||
|
||||
TW68 VIDEO4LINUX DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
W: https://linuxtv.org
|
||||
|
@ -26792,7 +26822,7 @@ S: Maintained
|
|||
F: drivers/net/ethernet/via/via-velocity.*
|
||||
|
||||
VICODEC VIRTUAL CODEC DRIVER
|
||||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
@ -27104,7 +27134,7 @@ S: Supported
|
|||
F: drivers/media/test-drivers/visl
|
||||
|
||||
VIVID VIRTUAL VIDEO DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
M: Hans Verkuil <hverkuil@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
*
|
||||
* https://hverkuil.home.xs4all.nl/cec-status.txt
|
||||
*
|
||||
* Please mail me (hverkuil@xs4all.nl) if you find an adapter that works
|
||||
* Please mail me (hverkuil@kernel.org) if you find an adapter that works
|
||||
* and is not yet listed there.
|
||||
*
|
||||
* Note that the current implementation does not support CEC over an MST hub.
|
||||
|
|
|
@ -439,6 +439,6 @@ static void __exit cec_devnode_exit(void)
|
|||
subsys_initcall(cec_devnode_init);
|
||||
module_exit(cec_devnode_exit)
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_DESCRIPTION("Device node registration for cec drivers");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -291,6 +291,6 @@ static struct platform_driver cec_gpio_pdrv = {
|
|||
|
||||
module_platform_driver(cec_gpio_pdrv);
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("CEC GPIO driver");
|
||||
|
|
|
@ -248,7 +248,6 @@ static const struct regmap_config stm32_cec_regmap_cfg = {
|
|||
.val_bits = 32,
|
||||
.reg_stride = sizeof(u32),
|
||||
.max_register = 0x14,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static int stm32_cec_probe(struct platform_device *pdev)
|
||||
|
|
|
@ -1,8 +1,2 @@
|
|||
extron-da-hd-4k-plus-cec-objs := extron-da-hd-4k-plus.o cec-splitter.o
|
||||
obj-$(CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC) := extron-da-hd-4k-plus-cec.o
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(shell pwd) modules
|
||||
|
||||
install:
|
||||
$(MAKE) -C $(KDIR) M=$(shell pwd) modules_install
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "extron-da-hd-4k-plus.h"
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_DESCRIPTION("Extron DA HD 4K PLUS HDMI CEC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
@ -1252,7 +1252,7 @@ static int extron_s_output(struct file *file, void *priv, unsigned int o)
|
|||
return o ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static int extron_g_edid(struct file *file, void *_fh,
|
||||
static int extron_g_edid(struct file *file, void *priv,
|
||||
struct v4l2_edid *edid)
|
||||
{
|
||||
struct extron_port *port = video_drvdata(file);
|
||||
|
@ -1280,7 +1280,7 @@ static int extron_g_edid(struct file *file, void *_fh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int extron_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid)
|
||||
static int extron_s_edid(struct file *file, void *priv, struct v4l2_edid *edid)
|
||||
{
|
||||
struct extron_port *port = video_drvdata(file);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* Pulse Eight HDMI CEC driver
|
||||
*
|
||||
* Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
|
||||
* Copyright 2016 Hans Verkuil <hverkuil@kernel.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -41,7 +41,7 @@
|
|||
|
||||
#include <media/cec.h>
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_DESCRIPTION("Pulse Eight HDMI CEC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* RainShadow Tech HDMI CEC driver
|
||||
*
|
||||
* Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
|
||||
* Copyright 2016 Hans Verkuil <hverkuil@kernel.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <media/cec.h>
|
||||
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -352,7 +352,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
|
|||
sram_set_size(adapter, 0x10000);
|
||||
sram_init(adapter);
|
||||
write_reg_dw(adapter, 0x208, tmp);
|
||||
dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
|
||||
dprintk("%s: SRAM detection failed. Set to 32K\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ static void flexcop_reset(struct flexcop_device *fc)
|
|||
flexcop_ibi_value v210, v204;
|
||||
|
||||
/* reset the flexcop itself */
|
||||
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
|
||||
fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
|
||||
|
||||
v210.raw = 0;
|
||||
v210.sw_reset_210.reset_block_000 = 1;
|
||||
|
@ -183,17 +183,17 @@ static void flexcop_reset(struct flexcop_device *fc)
|
|||
v210.sw_reset_210.reset_block_700 = 1;
|
||||
v210.sw_reset_210.Block_reset_enable = 0xb2;
|
||||
v210.sw_reset_210.Special_controls = 0xc259;
|
||||
fc->write_ibi_reg(fc,sw_reset_210,v210);
|
||||
fc->write_ibi_reg(fc, sw_reset_210, v210);
|
||||
msleep(1);
|
||||
|
||||
/* reset the periphical devices */
|
||||
|
||||
v204 = fc->read_ibi_reg(fc,misc_204);
|
||||
v204 = fc->read_ibi_reg(fc, misc_204);
|
||||
v204.misc_204.Per_reset_sig = 0;
|
||||
fc->write_ibi_reg(fc,misc_204,v204);
|
||||
fc->write_ibi_reg(fc, misc_204, v204);
|
||||
msleep(1);
|
||||
v204.misc_204.Per_reset_sig = 1;
|
||||
fc->write_ibi_reg(fc,misc_204,v204);
|
||||
fc->write_ibi_reg(fc, misc_204, v204);
|
||||
}
|
||||
|
||||
void flexcop_reset_block_300(struct flexcop_device *fc)
|
||||
|
@ -202,13 +202,13 @@ void flexcop_reset_block_300(struct flexcop_device *fc)
|
|||
v210 = fc->read_ibi_reg(fc, sw_reset_210);
|
||||
|
||||
deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
|
||||
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
|
||||
fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
|
||||
|
||||
v210.sw_reset_210.reset_block_300 = 1;
|
||||
v210.sw_reset_210.Block_reset_enable = 0xb2;
|
||||
|
||||
fc->write_ibi_reg(fc,sw_reset_210,v210);
|
||||
fc->write_ibi_reg(fc,ctrl_208,v208_save);
|
||||
fc->write_ibi_reg(fc, sw_reset_210, v210);
|
||||
fc->write_ibi_reg(fc, ctrl_208, v208_save);
|
||||
}
|
||||
|
||||
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
|
||||
|
@ -266,8 +266,8 @@ int flexcop_device_initialize(struct flexcop_device *fc)
|
|||
if (fc->get_mac_addr(fc, 0) == 0) {
|
||||
u8 *b = fc->dvb_adapter.proposed_mac;
|
||||
info("MAC address = %pM", b);
|
||||
flexcop_set_mac_filter(fc,b);
|
||||
flexcop_mac_filter_ctrl(fc,1);
|
||||
flexcop_set_mac_filter(fc, b);
|
||||
flexcop_mac_filter_ctrl(fc, 1);
|
||||
} else
|
||||
warn("reading of MAC address failed.\n");
|
||||
|
||||
|
@ -275,7 +275,7 @@ int flexcop_device_initialize(struct flexcop_device *fc)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
flexcop_device_name(fc,"initialization of","complete");
|
||||
flexcop_device_name(fc, "initialization of", "complete");
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* cx2341x - generic code for cx23415/6/8 based devices
|
||||
*
|
||||
* Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
|
||||
* Copyright (C) 2006 Hans Verkuil <hverkuil@kernel.org>
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -973,18 +973,14 @@ EXPORT_SYMBOL_GPL(vb2_queue_change_type);
|
|||
|
||||
__poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(file);
|
||||
struct v4l2_fh *fh = file_to_v4l2_fh(file);
|
||||
__poll_t res;
|
||||
|
||||
res = vb2_core_poll(q, file, wait);
|
||||
|
||||
if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
|
||||
struct v4l2_fh *fh = file->private_data;
|
||||
|
||||
poll_wait(file, &fh->wait, wait);
|
||||
if (v4l2_event_pending(fh))
|
||||
res |= EPOLLPRI;
|
||||
}
|
||||
poll_wait(file, &fh->wait, wait);
|
||||
if (v4l2_event_pending(fh))
|
||||
res |= EPOLLPRI;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ config DVB_CX24123
|
|||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_DS3000
|
||||
tristate "Montage Tehnology DS3000 based"
|
||||
tristate "Montage Technology DS3000 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
|
@ -270,7 +270,7 @@ config DVB_TDA826X
|
|||
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_TS2020
|
||||
tristate "Montage Tehnology TS2020 based tuners"
|
||||
tristate "Montage Technology TS2020 based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
select REGMAP_I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
|
|
|
@ -27,7 +27,7 @@ config VIDEO_IR_I2C
|
|||
|
||||
menuconfig VIDEO_CAMERA_SENSOR
|
||||
bool "Camera sensor devices"
|
||||
depends on MEDIA_CAMERA_SUPPORT && I2C
|
||||
depends on MEDIA_CAMERA_SUPPORT && I2C && HAVE_CLK
|
||||
select MEDIA_CONTROLLER
|
||||
select V4L2_FWNODE
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
|
@ -70,6 +70,16 @@ config VIDEO_GC0308
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called gc0308.
|
||||
|
||||
config VIDEO_GC0310
|
||||
tristate "GalaxyCore GC0310 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor-level driver for the Galaxycore
|
||||
GC0310 0.3MP sensor.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gc0310.
|
||||
|
||||
config VIDEO_GC05A2
|
||||
tristate "GalaxyCore gc05a2 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
|
@ -317,6 +327,7 @@ config VIDEO_MT9V011
|
|||
|
||||
config VIDEO_MT9V032
|
||||
tristate "Micron MT9V032 sensor support"
|
||||
depends on OF
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Micron
|
||||
|
@ -340,6 +351,16 @@ config VIDEO_OG01A1B
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called og01a1b.
|
||||
|
||||
config VIDEO_OG0VE1B
|
||||
tristate "OmniVision OG0VE1B sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the OmniVision
|
||||
OG0VE1B camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called og0ve1b.
|
||||
|
||||
config VIDEO_OV01A10
|
||||
tristate "OmniVision OV01A10 sensor support"
|
||||
help
|
||||
|
@ -446,6 +467,16 @@ config VIDEO_OV2685
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov2685.
|
||||
|
||||
config VIDEO_OV2735
|
||||
tristate "OmniVision OV2735 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Sony
|
||||
OV2735 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov2735.
|
||||
|
||||
config VIDEO_OV2740
|
||||
tristate "OmniVision OV2740 sensor support"
|
||||
depends on ACPI || COMPILE_TEST
|
||||
|
@ -542,6 +573,16 @@ config VIDEO_OV5695
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov5695.
|
||||
|
||||
config VIDEO_OV6211
|
||||
tristate "OmniVision OV6211 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the OmniVision
|
||||
OV6211 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov6211.
|
||||
|
||||
config VIDEO_OV64A40
|
||||
tristate "OmniVision OV64A40 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
|
@ -552,15 +593,6 @@ config VIDEO_OV64A40
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov64a40.
|
||||
|
||||
config VIDEO_OV6650
|
||||
tristate "OmniVision OV6650 sensor support"
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the OmniVision
|
||||
OV6650 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov6650.
|
||||
|
||||
config VIDEO_OV7251
|
||||
tristate "OmniVision OV7251 sensor support"
|
||||
help
|
||||
|
|
|
@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
|
|||
obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
|
||||
obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
|
||||
obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
|
||||
obj-$(CONFIG_VIDEO_GC0310) += gc0310.o
|
||||
obj-$(CONFIG_VIDEO_GC05A2) += gc05a2.o
|
||||
obj-$(CONFIG_VIDEO_GC08A3) += gc08a3.o
|
||||
obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
|
||||
|
@ -81,6 +82,7 @@ obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
|
|||
obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
|
||||
obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o
|
||||
obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o
|
||||
obj-$(CONFIG_VIDEO_OG0VE1B) += og0ve1b.o
|
||||
obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o
|
||||
obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
|
||||
obj-$(CONFIG_VIDEO_OV02C10) += ov02c10.o
|
||||
|
@ -93,6 +95,7 @@ obj-$(CONFIG_VIDEO_OV2640) += ov2640.o
|
|||
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
|
||||
obj-$(CONFIG_VIDEO_OV2680) += ov2680.o
|
||||
obj-$(CONFIG_VIDEO_OV2685) += ov2685.o
|
||||
obj-$(CONFIG_VIDEO_OV2735) += ov2735.o
|
||||
obj-$(CONFIG_VIDEO_OV2740) += ov2740.o
|
||||
obj-$(CONFIG_VIDEO_OV4689) += ov4689.o
|
||||
obj-$(CONFIG_VIDEO_OV5640) += ov5640.o
|
||||
|
@ -103,8 +106,8 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
|
|||
obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
|
||||
obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
|
||||
obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
|
||||
obj-$(CONFIG_VIDEO_OV6211) += ov6211.o
|
||||
obj-$(CONFIG_VIDEO_OV64A40) += ov64a40.o
|
||||
obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
|
||||
obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
|
||||
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
|
||||
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
|
||||
|
|
|
@ -214,7 +214,6 @@ struct adv7180_state {
|
|||
struct gpio_desc *pwdn_gpio;
|
||||
struct gpio_desc *rst_gpio;
|
||||
v4l2_std_id curr_norm;
|
||||
bool powered;
|
||||
bool streaming;
|
||||
u8 input;
|
||||
|
||||
|
@ -274,6 +273,38 @@ static int adv7180_vpp_write(struct adv7180_state *state, unsigned int reg,
|
|||
return i2c_smbus_write_byte_data(state->vpp_client, reg, value);
|
||||
}
|
||||
|
||||
static int adv7180_set_power(struct adv7180_state *state, bool on)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (on)
|
||||
val = ADV7180_PWR_MAN_ON;
|
||||
else
|
||||
val = ADV7180_PWR_MAN_OFF;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_PWR_MAN, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
|
||||
if (on) {
|
||||
adv7180_csi_write(state, 0xDE, 0x02);
|
||||
adv7180_csi_write(state, 0xD2, 0xF7);
|
||||
adv7180_csi_write(state, 0xD8, 0x65);
|
||||
adv7180_csi_write(state, 0xE0, 0x09);
|
||||
adv7180_csi_write(state, 0x2C, 0x00);
|
||||
if (state->field == V4L2_FIELD_NONE)
|
||||
adv7180_csi_write(state, 0x1D, 0x80);
|
||||
adv7180_csi_write(state, 0x00, 0x00);
|
||||
} else {
|
||||
adv7180_csi_write(state, 0x00, 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
|
||||
{
|
||||
/* in case V4L2_IN_ST_NO_SIGNAL */
|
||||
|
@ -357,32 +388,27 @@ static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
|
|||
static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
|
||||
{
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
int err = mutex_lock_interruptible(&state->mutex);
|
||||
if (err)
|
||||
return err;
|
||||
int ret;
|
||||
|
||||
if (state->streaming) {
|
||||
err = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
err = adv7180_set_video_standard(state,
|
||||
ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM);
|
||||
if (err)
|
||||
goto unlock;
|
||||
/*
|
||||
* We can't sample the standard if the device is streaming as that would
|
||||
* interfere with the capture session as the VID_SEL reg is touched.
|
||||
*/
|
||||
if (state->streaming)
|
||||
return -EBUSY;
|
||||
|
||||
/* Set the standard to autodetect PAL B/G/H/I/D, NTSC J or SECAM */
|
||||
ret = adv7180_set_video_standard(state,
|
||||
ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Allow some time for the autodetection to run. */
|
||||
msleep(100);
|
||||
__adv7180_status(state, NULL, std);
|
||||
|
||||
err = v4l2_std_to_adv7180(state->curr_norm);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = adv7180_set_video_standard(state, err);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&state->mutex);
|
||||
return err;
|
||||
return __adv7180_status(state, NULL, std);
|
||||
}
|
||||
|
||||
static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
|
||||
|
@ -437,22 +463,18 @@ static int adv7180_program_std(struct adv7180_state *state)
|
|||
static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
|
||||
{
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
int ret = mutex_lock_interruptible(&state->mutex);
|
||||
int ret;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
/* Make sure we can support this std */
|
||||
ret = v4l2_std_to_adv7180(std);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
state->curr_norm = std;
|
||||
|
||||
ret = adv7180_program_std(state);
|
||||
out:
|
||||
mutex_unlock(&state->mutex);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7180_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
|
||||
|
@ -514,55 +536,6 @@ static void adv7180_set_reset_pin(struct adv7180_state *state, bool on)
|
|||
}
|
||||
}
|
||||
|
||||
static int adv7180_set_power(struct adv7180_state *state, bool on)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (on)
|
||||
val = ADV7180_PWR_MAN_ON;
|
||||
else
|
||||
val = ADV7180_PWR_MAN_OFF;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_PWR_MAN, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
|
||||
if (on) {
|
||||
adv7180_csi_write(state, 0xDE, 0x02);
|
||||
adv7180_csi_write(state, 0xD2, 0xF7);
|
||||
adv7180_csi_write(state, 0xD8, 0x65);
|
||||
adv7180_csi_write(state, 0xE0, 0x09);
|
||||
adv7180_csi_write(state, 0x2C, 0x00);
|
||||
if (state->field == V4L2_FIELD_NONE)
|
||||
adv7180_csi_write(state, 0x1D, 0x80);
|
||||
adv7180_csi_write(state, 0x00, 0x00);
|
||||
} else {
|
||||
adv7180_csi_write(state, 0x00, 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7180_s_power(struct v4l2_subdev *sd, int on)
|
||||
{
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&state->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_set_power(state, on);
|
||||
if (ret == 0)
|
||||
state->powered = on;
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * const test_pattern_menu[] = {
|
||||
"Single color",
|
||||
"Color bars",
|
||||
|
@ -601,11 +574,11 @@ static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
int ret = mutex_lock_interruptible(&state->mutex);
|
||||
int ret = 0;
|
||||
int val;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
lockdep_assert_held(&state->mutex);
|
||||
|
||||
val = ctrl->val;
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
|
@ -647,7 +620,6 @@ static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
|
|||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&state->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -668,6 +640,7 @@ static const struct v4l2_ctrl_config adv7180_ctrl_fast_switch = {
|
|||
static int adv7180_init_controls(struct adv7180_state *state)
|
||||
{
|
||||
v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
|
||||
state->ctrl_hdl.lock = &state->mutex;
|
||||
|
||||
v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
|
||||
|
@ -700,7 +673,6 @@ static int adv7180_init_controls(struct adv7180_state *state)
|
|||
v4l2_ctrl_handler_free(&state->ctrl_hdl);
|
||||
return err;
|
||||
}
|
||||
v4l2_ctrl_handler_setup(&state->ctrl_hdl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -812,12 +784,7 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd,
|
|||
ret = adv7180_mbus_fmt(sd, &format->format);
|
||||
|
||||
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
|
||||
if (state->field != format->format.field) {
|
||||
state->field = format->format.field;
|
||||
adv7180_set_power(state, false);
|
||||
adv7180_set_field_mode(state);
|
||||
adv7180_set_power(state, true);
|
||||
}
|
||||
state->field = format->format.field;
|
||||
} else {
|
||||
framefmt = v4l2_subdev_state_get_format(sd_state, 0);
|
||||
*framefmt = format->format;
|
||||
|
@ -874,23 +841,117 @@ static int adv7180_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int init_device(struct adv7180_state *state)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&state->mutex);
|
||||
|
||||
ret = adv7180_program_std(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
adv7180_set_field_mode(state);
|
||||
|
||||
__v4l2_ctrl_handler_setup(&state->ctrl_hdl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adv7180_reset_device(struct adv7180_state *state)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&state->mutex);
|
||||
|
||||
adv7180_set_power_pin(state, true);
|
||||
adv7180_set_reset_pin(state, false);
|
||||
|
||||
adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
|
||||
usleep_range(5000, 10000);
|
||||
|
||||
/*
|
||||
* If the devices decoder is power on after reset, power off so the
|
||||
* device can be configured.
|
||||
*/
|
||||
if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
|
||||
adv7180_set_power(state, false);
|
||||
|
||||
ret = state->chip_info->init(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = init_device(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* register for interrupts */
|
||||
if (state->irq > 0) {
|
||||
/* config the Interrupt pin to be active low */
|
||||
ret = adv7180_write(state, ADV7180_REG_ICONF1,
|
||||
ADV7180_ICONF1_ACTIVE_LOW |
|
||||
ADV7180_ICONF1_PSYNC_ONLY);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* enable AD change interrupts */
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR3,
|
||||
ADV7180_IRQ3_AD_CHANGE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the devices decoder is power on after reset, restore the power
|
||||
* after configuration. This is to preserve the behavior of the driver,
|
||||
* not doing this result in the first 35+ frames captured being garbage.
|
||||
*/
|
||||
if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
|
||||
adv7180_set_power(state, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7180_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
int ret;
|
||||
|
||||
/* It's always safe to stop streaming, no need to take the lock */
|
||||
if (!enable) {
|
||||
state->streaming = enable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Must wait until querystd released the lock */
|
||||
ret = mutex_lock_interruptible(&state->mutex);
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
/*
|
||||
* Always power off the decoder even if streaming is to be enabled, the
|
||||
* decoder needs to be off for the device to be configured.
|
||||
*/
|
||||
ret = adv7180_set_power(state, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (enable) {
|
||||
ret = init_device(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_set_power(state, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
state->streaming = enable;
|
||||
mutex_unlock(&state->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -919,7 +980,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = {
|
|||
};
|
||||
|
||||
static const struct v4l2_subdev_core_ops adv7180_core_ops = {
|
||||
.s_power = adv7180_s_power,
|
||||
.subscribe_event = adv7180_subscribe_event,
|
||||
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||||
};
|
||||
|
@ -1343,62 +1403,6 @@ static const struct adv7180_chip_info adv7282_m_info = {
|
|||
.select_input = adv7182_select_input,
|
||||
};
|
||||
|
||||
static int init_device(struct adv7180_state *state)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&state->mutex);
|
||||
|
||||
adv7180_set_power_pin(state, true);
|
||||
adv7180_set_reset_pin(state, false);
|
||||
|
||||
adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
|
||||
usleep_range(5000, 10000);
|
||||
|
||||
ret = state->chip_info->init(state);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = adv7180_program_std(state);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
adv7180_set_field_mode(state);
|
||||
|
||||
/* register for interrupts */
|
||||
if (state->irq > 0) {
|
||||
/* config the Interrupt pin to be active low */
|
||||
ret = adv7180_write(state, ADV7180_REG_ICONF1,
|
||||
ADV7180_ICONF1_ACTIVE_LOW |
|
||||
ADV7180_ICONF1_PSYNC_ONLY);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
/* enable AD change interrupts interrupts */
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR3,
|
||||
ADV7180_IRQ3_AD_CHANGE);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&state->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adv7180_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device_node *np = client->dev.of_node;
|
||||
|
@ -1457,10 +1461,7 @@ static int adv7180_probe(struct i2c_client *client)
|
|||
state->irq = client->irq;
|
||||
mutex_init(&state->mutex);
|
||||
state->curr_norm = V4L2_STD_NTSC;
|
||||
if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
|
||||
state->powered = true;
|
||||
else
|
||||
state->powered = false;
|
||||
|
||||
state->input = 0;
|
||||
sd = &state->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
|
||||
|
@ -1477,7 +1478,9 @@ static int adv7180_probe(struct i2c_client *client)
|
|||
if (ret)
|
||||
goto err_free_ctrl;
|
||||
|
||||
ret = init_device(state);
|
||||
mutex_lock(&state->mutex);
|
||||
ret = adv7180_reset_device(state);
|
||||
mutex_unlock(&state->mutex);
|
||||
if (ret)
|
||||
goto err_media_entity_cleanup;
|
||||
|
||||
|
@ -1549,6 +1552,8 @@ static int adv7180_suspend(struct device *dev)
|
|||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
return adv7180_set_power(state, false);
|
||||
}
|
||||
|
||||
|
@ -1558,13 +1563,18 @@ static int adv7180_resume(struct device *dev)
|
|||
struct adv7180_state *state = to_state(sd);
|
||||
int ret;
|
||||
|
||||
ret = init_device(state);
|
||||
guard(mutex)(&state->mutex);
|
||||
|
||||
ret = adv7180_reset_device(state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = adv7180_set_power(state, state->powered);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* If we were streaming when suspending, start decoder. */
|
||||
if (state->streaming) {
|
||||
ret = adv7180_set_power(state, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ module_param(debug, int, 0644);
|
|||
MODULE_PARM_DESC(debug, "debug level (0-2)");
|
||||
|
||||
MODULE_DESCRIPTION("Analog Devices ADV7604/10/11/12 video decoder driver");
|
||||
MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ module_param(debug, int, 0644);
|
|||
MODULE_PARM_DESC(debug, "debug level (0-2)");
|
||||
|
||||
MODULE_DESCRIPTION("Analog Devices ADV7842 video decoder driver");
|
||||
MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
|
||||
MODULE_AUTHOR("Hans Verkuil <hverkuil@kernel.org>");
|
||||
MODULE_AUTHOR("Martin Bugge <marbugge@cisco.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
|
|
@ -1077,11 +1077,10 @@ static int ar0521_probe(struct i2c_client *client)
|
|||
}
|
||||
|
||||
/* Get master clock (extclk) */
|
||||
sensor->extclk = devm_clk_get(dev, "extclk");
|
||||
if (IS_ERR(sensor->extclk)) {
|
||||
dev_err(dev, "failed to get extclk\n");
|
||||
return PTR_ERR(sensor->extclk);
|
||||
}
|
||||
sensor->extclk = devm_v4l2_sensor_clk_get(dev, "extclk");
|
||||
if (IS_ERR(sensor->extclk))
|
||||
return dev_err_probe(dev, PTR_ERR(sensor->extclk),
|
||||
"failed to get extclk\n");
|
||||
|
||||
sensor->extclk_freq = clk_get_rate(sensor->extclk);
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
* Changes by Tyler Trafford <tatrafford@comcast.net>
|
||||
* - cleanup/rewrite for V4L2 API (2005)
|
||||
*
|
||||
* VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
|
||||
* VBI support by Hans Verkuil <hverkuil@kernel.org>.
|
||||
*
|
||||
* NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>
|
||||
* with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.
|
||||
* with additional fixes by Hans Verkuil <hverkuil@kernel.org>.
|
||||
*
|
||||
* CX23885 support by Steven Toth <stoth@linuxtv.org>.
|
||||
*
|
||||
|
|
|
@ -333,8 +333,7 @@ static int _ub913_set_routing(struct v4l2_subdev *sd,
|
|||
.quantization = V4L2_QUANTIZATION_LIM_RANGE,
|
||||
.xfer_func = V4L2_XFER_FUNC_SRGB,
|
||||
};
|
||||
struct v4l2_subdev_stream_configs *stream_configs;
|
||||
unsigned int i;
|
||||
struct v4l2_subdev_route *route;
|
||||
int ret;
|
||||
|
||||
ret = v4l2_subdev_routing_validate(sd, routing,
|
||||
|
@ -346,13 +345,15 @@ static int _ub913_set_routing(struct v4l2_subdev *sd,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
stream_configs = &state->stream_configs;
|
||||
for_each_active_route(&state->routing, route) {
|
||||
struct v4l2_mbus_framefmt *fmt;
|
||||
|
||||
for (i = 0; i < stream_configs->num_configs; i++) {
|
||||
if (stream_configs->configs[i].pad == UB913_PAD_SINK)
|
||||
stream_configs->configs[i].fmt = in_format;
|
||||
else
|
||||
stream_configs->configs[i].fmt = out_format;
|
||||
fmt = v4l2_subdev_state_get_format(state, route->sink_pad,
|
||||
route->sink_stream);
|
||||
*fmt = in_format;
|
||||
fmt = v4l2_subdev_state_get_format(state, route->source_pad,
|
||||
route->source_stream);
|
||||
*fmt = out_format;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -816,7 +816,6 @@ static int et8ek8_power_on(struct et8ek8_sensor *sensor)
|
|||
{
|
||||
struct v4l2_subdev *subdev = &sensor->subdev;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(subdev);
|
||||
unsigned int xclk_freq;
|
||||
int val, rval;
|
||||
|
||||
rval = regulator_enable(sensor->vana);
|
||||
|
@ -825,17 +824,6 @@ static int et8ek8_power_on(struct et8ek8_sensor *sensor)
|
|||
return rval;
|
||||
}
|
||||
|
||||
if (sensor->current_reglist)
|
||||
xclk_freq = sensor->current_reglist->mode.ext_clock;
|
||||
else
|
||||
xclk_freq = sensor->xclk_freq;
|
||||
|
||||
rval = clk_set_rate(sensor->ext_clk, xclk_freq);
|
||||
if (rval < 0) {
|
||||
dev_err(&client->dev, "unable to set extclk clock freq to %u\n",
|
||||
xclk_freq);
|
||||
goto out;
|
||||
}
|
||||
rval = clk_prepare_enable(sensor->ext_clk);
|
||||
if (rval < 0) {
|
||||
dev_err(&client->dev, "failed to enable extclk\n");
|
||||
|
@ -849,7 +837,7 @@ static int et8ek8_power_on(struct et8ek8_sensor *sensor)
|
|||
|
||||
gpiod_set_value(sensor->reset, 1);
|
||||
|
||||
msleep(5000 * 1000 / xclk_freq + 1); /* Wait 5000 cycles */
|
||||
msleep(5000 * 1000 / sensor->xclk_freq + 1); /* Wait 5000 cycles */
|
||||
|
||||
rval = et8ek8_i2c_reglist_find_write(client, &meta_reglist,
|
||||
ET8EK8_REGLIST_POWERON);
|
||||
|
@ -1085,9 +1073,6 @@ static int et8ek8_set_frame_interval(struct v4l2_subdev *subdev,
|
|||
if (!reglist)
|
||||
return -EINVAL;
|
||||
|
||||
if (sensor->current_reglist->mode.ext_clock != reglist->mode.ext_clock)
|
||||
return -EINVAL;
|
||||
|
||||
sensor->current_reglist = reglist;
|
||||
et8ek8_update_controls(sensor);
|
||||
|
||||
|
@ -1433,18 +1418,13 @@ static int et8ek8_probe(struct i2c_client *client)
|
|||
return PTR_ERR(sensor->vana);
|
||||
}
|
||||
|
||||
sensor->ext_clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(sensor->ext_clk)) {
|
||||
dev_err(&client->dev, "could not get clock\n");
|
||||
return PTR_ERR(sensor->ext_clk);
|
||||
}
|
||||
sensor->ext_clk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, true,
|
||||
9600000);
|
||||
if (IS_ERR(sensor->ext_clk))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(sensor->ext_clk),
|
||||
"could not get clock\n");
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "clock-frequency",
|
||||
&sensor->xclk_freq);
|
||||
if (ret) {
|
||||
dev_warn(dev, "can't get clock-frequency\n");
|
||||
return ret;
|
||||
}
|
||||
sensor->xclk_freq = clk_get_rate(sensor->ext_clk);
|
||||
|
||||
mutex_init(&sensor->power_lock);
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
|
|||
.window_width = 2592,
|
||||
.window_height = 1968,
|
||||
.pixel_clock = 80000000,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 1207
|
||||
|
@ -145,7 +144,6 @@ static struct et8ek8_reglist mode1_16vga_2592x1968_13_12fps_dpcm10_8 = {
|
|||
.window_width = 2592,
|
||||
.window_height = 1968,
|
||||
.pixel_clock = 80000000,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 1292
|
||||
|
@ -201,7 +199,6 @@ static struct et8ek8_reglist mode3_4vga_1296x984_29_99fps_dpcm10_8 = {
|
|||
.window_width = 1296,
|
||||
.window_height = 984,
|
||||
.pixel_clock = 96533333,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 3000
|
||||
|
@ -257,7 +254,6 @@ static struct et8ek8_reglist mode4_svga_864x656_29_88fps = {
|
|||
.window_width = 864,
|
||||
.window_height = 656,
|
||||
.pixel_clock = 80000000,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 2988
|
||||
|
@ -313,7 +309,6 @@ static struct et8ek8_reglist mode5_vga_648x492_29_93fps = {
|
|||
.window_width = 648,
|
||||
.window_height = 492,
|
||||
.pixel_clock = 80000000,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 2993
|
||||
|
@ -369,7 +364,6 @@ static struct et8ek8_reglist mode2_16vga_2592x1968_3_99fps = {
|
|||
.window_width = 2592,
|
||||
.window_height = 1968,
|
||||
.pixel_clock = 80000000,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 399
|
||||
|
@ -424,7 +418,6 @@ static struct et8ek8_reglist mode_648x492_5fps = {
|
|||
.window_width = 648,
|
||||
.window_height = 492,
|
||||
.pixel_clock = 13333333,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 499
|
||||
|
@ -480,7 +473,6 @@ static struct et8ek8_reglist mode3_4vga_1296x984_5fps = {
|
|||
.window_width = 1296,
|
||||
.window_height = 984,
|
||||
.pixel_clock = 49400000,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 501
|
||||
|
@ -536,7 +528,6 @@ static struct et8ek8_reglist mode_4vga_1296x984_25fps_dpcm10_8 = {
|
|||
.window_width = 1296,
|
||||
.window_height = 984,
|
||||
.pixel_clock = 84266667,
|
||||
.ext_clock = 9600000,
|
||||
.timeperframe = {
|
||||
.numerator = 100,
|
||||
.denominator = 2500
|
||||
|
|
|
@ -37,7 +37,6 @@ struct et8ek8_mode {
|
|||
u16 window_height;
|
||||
|
||||
u32 pixel_clock; /* in Hz */
|
||||
u32 ext_clock; /* in Hz */
|
||||
struct v4l2_fract timeperframe;
|
||||
u32 max_exp; /* Maximum exposure value */
|
||||
u32 bus_format; /* MEDIA_BUS_FMT_ */
|
||||
|
|
|
@ -1235,16 +1235,12 @@ static int gc05a2_probe(struct i2c_client *client)
|
|||
return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
|
||||
"failed to init CCI\n");
|
||||
|
||||
gc05a2->xclk = devm_clk_get(dev, NULL);
|
||||
gc05a2->xclk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, true,
|
||||
GC05A2_DEFAULT_CLK_FREQ);
|
||||
if (IS_ERR(gc05a2->xclk))
|
||||
return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
|
||||
"failed to get xclk\n");
|
||||
|
||||
ret = clk_set_rate(gc05a2->xclk, GC05A2_DEFAULT_CLK_FREQ);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to set xclk frequency\n");
|
||||
|
||||
ret = gc05a2_get_regulators(dev, gc05a2);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret,
|
||||
|
|
|
@ -1199,16 +1199,12 @@ static int gc08a3_probe(struct i2c_client *client)
|
|||
return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
|
||||
"failed to init CCI\n");
|
||||
|
||||
gc08a3->xclk = devm_clk_get(dev, NULL);
|
||||
gc08a3->xclk = devm_v4l2_sensor_clk_get_legacy(dev, NULL, true,
|
||||
GC08A3_DEFAULT_CLK_FREQ);
|
||||
if (IS_ERR(gc08a3->xclk))
|
||||
return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
|
||||
"failed to get xclk\n");
|
||||
|
||||
ret = clk_set_rate(gc08a3->xclk, GC08A3_DEFAULT_CLK_FREQ);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to set xclk frequency\n");
|
||||
|
||||
ret = gc08a3_get_regulators(dev, gc08a3);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret,
|
||||
|
|
|
@ -1331,7 +1331,7 @@ static int gc2145_probe(struct i2c_client *client)
|
|||
return -EINVAL;
|
||||
|
||||
/* Get system clock (xclk) */
|
||||
gc2145->xclk = devm_clk_get(dev, NULL);
|
||||
gc2145->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
|
||||
if (IS_ERR(gc2145->xclk))
|
||||
return dev_err_probe(dev, PTR_ERR(gc2145->xclk),
|
||||
"failed to get xclk\n");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2019 Intel Corporation.
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -10,6 +9,8 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
@ -631,6 +632,8 @@ static const char * const hi556_supply_names[] = {
|
|||
};
|
||||
|
||||
struct hi556 {
|
||||
struct device *dev;
|
||||
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
@ -715,7 +718,6 @@ static int hi556_write_reg(struct hi556 *hi556, u16 reg, u16 len, u32 val)
|
|||
static int hi556_write_reg_list(struct hi556 *hi556,
|
||||
const struct hi556_reg_list *r_list)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -724,7 +726,7 @@ static int hi556_write_reg_list(struct hi556 *hi556,
|
|||
HI556_REG_VALUE_16BIT,
|
||||
r_list->regs[i].val);
|
||||
if (ret) {
|
||||
dev_err_ratelimited(&client->dev,
|
||||
dev_err_ratelimited(hi556->dev,
|
||||
"failed to write reg 0x%4.4x. error = %d\n",
|
||||
r_list->regs[i].address, ret);
|
||||
return ret;
|
||||
|
@ -785,7 +787,6 @@ static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct hi556 *hi556 = container_of(ctrl->handler,
|
||||
struct hi556, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
|
||||
s64 exposure_max;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -801,7 +802,7 @@ static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
}
|
||||
|
||||
/* V4L2 controls values will be applied only when power is already up */
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
if (!pm_runtime_get_if_in_use(hi556->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@ -835,7 +836,7 @@ static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(hi556->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -921,7 +922,6 @@ static void hi556_assign_pad_format(const struct hi556_mode *mode,
|
|||
|
||||
static int hi556_identify_module(struct hi556 *hi556)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
|
@ -934,7 +934,7 @@ static int hi556_identify_module(struct hi556 *hi556)
|
|||
return ret;
|
||||
|
||||
if (val != HI556_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
|
||||
dev_err(hi556->dev, "chip id mismatch: %x!=%x\n",
|
||||
HI556_CHIP_ID, val);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
@ -998,7 +998,6 @@ static int hi556_get_selection(struct v4l2_subdev *sd,
|
|||
|
||||
static int hi556_start_streaming(struct hi556 *hi556)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
|
||||
const struct hi556_reg_list *reg_list;
|
||||
int link_freq_index, ret;
|
||||
|
||||
|
@ -1010,14 +1009,14 @@ static int hi556_start_streaming(struct hi556 *hi556)
|
|||
reg_list = &link_freq_configs[link_freq_index].reg_list;
|
||||
ret = hi556_write_reg_list(hi556, reg_list);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set plls\n");
|
||||
dev_err(hi556->dev, "failed to set plls\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg_list = &hi556->cur_mode->reg_list;
|
||||
ret = hi556_write_reg_list(hi556, reg_list);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set mode\n");
|
||||
dev_err(hi556->dev, "failed to set mode\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1028,7 @@ static int hi556_start_streaming(struct hi556 *hi556)
|
|||
HI556_REG_VALUE_16BIT, HI556_MODE_STREAMING);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set stream\n");
|
||||
dev_err(hi556->dev, "failed to set stream\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1038,22 +1037,19 @@ static int hi556_start_streaming(struct hi556 *hi556)
|
|||
|
||||
static void hi556_stop_streaming(struct hi556 *hi556)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
|
||||
|
||||
if (hi556_write_reg(hi556, HI556_REG_MODE_SELECT,
|
||||
HI556_REG_VALUE_16BIT, HI556_MODE_STANDBY))
|
||||
dev_err(&client->dev, "failed to set stream\n");
|
||||
dev_err(hi556->dev, "failed to set stream\n");
|
||||
}
|
||||
|
||||
static int hi556_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct hi556 *hi556 = to_hi556(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hi556->mutex);
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(hi556->dev);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&hi556->mutex);
|
||||
return ret;
|
||||
|
@ -1062,11 +1058,11 @@ static int hi556_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
ret = hi556_start_streaming(hi556);
|
||||
if (ret) {
|
||||
hi556_stop_streaming(hi556);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(hi556->dev);
|
||||
}
|
||||
} else {
|
||||
hi556_stop_streaming(hi556);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(hi556->dev);
|
||||
}
|
||||
|
||||
mutex_unlock(&hi556->mutex);
|
||||
|
@ -1217,7 +1213,6 @@ static int hi556_check_hwcfg(struct device *dev)
|
|||
struct v4l2_fwnode_endpoint bus_cfg = {
|
||||
.bus_type = V4L2_MBUS_CSI2_DPHY
|
||||
};
|
||||
u32 mclk;
|
||||
int ret = 0;
|
||||
unsigned int i, j;
|
||||
|
||||
|
@ -1235,18 +1230,6 @@ static int hi556_check_hwcfg(struct device *dev)
|
|||
if (ret)
|
||||
return dev_err_probe(dev, ret, "parsing endpoint failed\n");
|
||||
|
||||
ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency\n");
|
||||
goto check_hwcfg_error;
|
||||
}
|
||||
|
||||
if (mclk != HI556_MCLK) {
|
||||
dev_err(dev, "external clock %d is not supported\n", mclk);
|
||||
ret = -EINVAL;
|
||||
goto check_hwcfg_error;
|
||||
}
|
||||
|
||||
if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
|
||||
dev_err(dev, "number of CSI2 data lanes %d is not supported\n",
|
||||
bus_cfg.bus.mipi_csi2.num_data_lanes);
|
||||
|
@ -1289,7 +1272,7 @@ static void hi556_remove(struct i2c_client *client)
|
|||
v4l2_async_unregister_subdev(sd);
|
||||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_disable(hi556->dev);
|
||||
mutex_destroy(&hi556->mutex);
|
||||
}
|
||||
|
||||
|
@ -1336,6 +1319,7 @@ static int hi556_resume(struct device *dev)
|
|||
static int hi556_probe(struct i2c_client *client)
|
||||
{
|
||||
struct hi556 *hi556;
|
||||
unsigned long freq;
|
||||
bool full_power;
|
||||
int i, ret;
|
||||
|
||||
|
@ -1347,40 +1331,48 @@ static int hi556_probe(struct i2c_client *client)
|
|||
if (!hi556)
|
||||
return -ENOMEM;
|
||||
|
||||
hi556->dev = &client->dev;
|
||||
|
||||
v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops);
|
||||
|
||||
hi556->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
|
||||
hi556->reset_gpio = devm_gpiod_get_optional(hi556->dev, "reset",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(hi556->reset_gpio))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(hi556->reset_gpio),
|
||||
return dev_err_probe(hi556->dev, PTR_ERR(hi556->reset_gpio),
|
||||
"failed to get reset GPIO\n");
|
||||
|
||||
hi556->clk = devm_clk_get_optional(&client->dev, "clk");
|
||||
hi556->clk = devm_v4l2_sensor_clk_get(hi556->dev, "clk");
|
||||
if (IS_ERR(hi556->clk))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(hi556->clk),
|
||||
return dev_err_probe(hi556->dev, PTR_ERR(hi556->clk),
|
||||
"failed to get clock\n");
|
||||
|
||||
freq = clk_get_rate(hi556->clk);
|
||||
if (freq != HI556_MCLK)
|
||||
return dev_err_probe(hi556->dev, -EINVAL,
|
||||
"external clock %lu is not supported\n",
|
||||
freq);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hi556_supply_names); i++)
|
||||
hi556->supplies[i].supply = hi556_supply_names[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(&client->dev,
|
||||
ret = devm_regulator_bulk_get(hi556->dev,
|
||||
ARRAY_SIZE(hi556_supply_names),
|
||||
hi556->supplies);
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
return dev_err_probe(hi556->dev, ret,
|
||||
"failed to get regulators\n");
|
||||
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
full_power = acpi_dev_state_d0(hi556->dev);
|
||||
if (full_power) {
|
||||
/* Ensure non ACPI managed resources are enabled */
|
||||
ret = hi556_resume(&client->dev);
|
||||
ret = hi556_resume(hi556->dev);
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
return dev_err_probe(hi556->dev, ret,
|
||||
"failed to power on sensor\n");
|
||||
|
||||
ret = hi556_identify_module(hi556);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d\n", ret);
|
||||
dev_err(hi556->dev, "failed to find sensor: %d\n", ret);
|
||||
goto probe_error_power_off;
|
||||
}
|
||||
}
|
||||
|
@ -1389,7 +1381,7 @@ static int hi556_probe(struct i2c_client *client)
|
|||
hi556->cur_mode = &supported_modes[0];
|
||||
ret = hi556_init_controls(hi556);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init controls: %d\n", ret);
|
||||
dev_err(hi556->dev, "failed to init controls: %d\n", ret);
|
||||
goto probe_error_v4l2_ctrl_handler_free;
|
||||
}
|
||||
|
||||
|
@ -1400,22 +1392,22 @@ static int hi556_probe(struct i2c_client *client)
|
|||
hi556->pad.flags = MEDIA_PAD_FL_SOURCE;
|
||||
ret = media_entity_pads_init(&hi556->sd.entity, 1, &hi556->pad);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init entity pads: %d\n", ret);
|
||||
dev_err(hi556->dev, "failed to init entity pads: %d\n", ret);
|
||||
goto probe_error_v4l2_ctrl_handler_free;
|
||||
}
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&hi556->sd);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "failed to register V4L2 subdev: %d\n",
|
||||
dev_err(hi556->dev, "failed to register V4L2 subdev: %d\n",
|
||||
ret);
|
||||
goto probe_error_media_entity_cleanup;
|
||||
}
|
||||
|
||||
/* Set the device's state to active if it's in D0 state. */
|
||||
if (full_power)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
pm_runtime_set_active(hi556->dev);
|
||||
pm_runtime_enable(hi556->dev);
|
||||
pm_runtime_idle(hi556->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1428,7 +1420,7 @@ probe_error_v4l2_ctrl_handler_free:
|
|||
|
||||
probe_error_power_off:
|
||||
if (full_power)
|
||||
hi556_suspend(&client->dev);
|
||||
hi556_suspend(hi556->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2052,12 +2052,11 @@ static int hi846_probe(struct i2c_client *client)
|
|||
return ret;
|
||||
}
|
||||
|
||||
hi846->clock = devm_clk_get(&client->dev, NULL);
|
||||
if (IS_ERR(hi846->clock)) {
|
||||
dev_err(&client->dev, "failed to get clock: %pe\n",
|
||||
hi846->clock);
|
||||
return PTR_ERR(hi846->clock);
|
||||
}
|
||||
hi846->clock = devm_v4l2_sensor_clk_get(&client->dev, NULL);
|
||||
if (IS_ERR(hi846->clock))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(hi846->clock),
|
||||
"failed to get clock: %pe\n",
|
||||
hi846->clock);
|
||||
|
||||
mclk_freq = clk_get_rate(hi846->clock);
|
||||
if (mclk_freq != 25000000)
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022 Intel Corporation.
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
@ -2166,6 +2168,9 @@ static const struct hi847_mode supported_modes[] = {
|
|||
};
|
||||
|
||||
struct hi847 {
|
||||
struct device *dev;
|
||||
struct clk *clk;
|
||||
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
@ -2244,7 +2249,6 @@ static int hi847_write_reg(struct hi847 *hi847, u16 reg, u16 len, u32 val)
|
|||
static int hi847_write_reg_list(struct hi847 *hi847,
|
||||
const struct hi847_reg_list *r_list)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -2253,7 +2257,7 @@ static int hi847_write_reg_list(struct hi847 *hi847,
|
|||
HI847_REG_VALUE_16BIT,
|
||||
r_list->regs[i].val);
|
||||
if (ret) {
|
||||
dev_err_ratelimited(&client->dev,
|
||||
dev_err_ratelimited(hi847->dev,
|
||||
"failed to write reg 0x%4.4x. error = %d",
|
||||
r_list->regs[i].address, ret);
|
||||
return ret;
|
||||
|
@ -2408,7 +2412,6 @@ static int hi847_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct hi847 *hi847 = container_of(ctrl->handler,
|
||||
struct hi847, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
|
||||
s64 exposure_max;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -2424,7 +2427,7 @@ static int hi847_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
}
|
||||
|
||||
/* V4L2 controls values will be applied only when power is already up */
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
if (!pm_runtime_get_if_in_use(hi847->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@ -2466,7 +2469,7 @@ static int hi847_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(hi847->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2557,7 +2560,6 @@ static void hi847_assign_pad_format(const struct hi847_mode *mode,
|
|||
|
||||
static int hi847_start_streaming(struct hi847 *hi847)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
|
||||
const struct hi847_reg_list *reg_list;
|
||||
int link_freq_index, ret;
|
||||
|
||||
|
@ -2565,14 +2567,14 @@ static int hi847_start_streaming(struct hi847 *hi847)
|
|||
reg_list = &link_freq_configs[link_freq_index].reg_list;
|
||||
ret = hi847_write_reg_list(hi847, reg_list);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set plls");
|
||||
dev_err(hi847->dev, "failed to set plls");
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg_list = &hi847->cur_mode->reg_list;
|
||||
ret = hi847_write_reg_list(hi847, reg_list);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set mode");
|
||||
dev_err(hi847->dev, "failed to set mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2587,7 +2589,7 @@ static int hi847_start_streaming(struct hi847 *hi847)
|
|||
HI847_REG_VALUE_16BIT, HI847_MODE_STREAMING);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set stream");
|
||||
dev_err(hi847->dev, "failed to set stream");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2596,28 +2598,25 @@ static int hi847_start_streaming(struct hi847 *hi847)
|
|||
|
||||
static void hi847_stop_streaming(struct hi847 *hi847)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
|
||||
|
||||
if (hi847_write_reg(hi847, HI847_REG_MODE_TG,
|
||||
HI847_REG_VALUE_16BIT, HI847_REG_MODE_TG_DISABLE))
|
||||
dev_err(&client->dev, "failed to set stream 0x%x",
|
||||
dev_err(hi847->dev, "failed to set stream 0x%x",
|
||||
HI847_REG_MODE_TG);
|
||||
|
||||
if (hi847_write_reg(hi847, HI847_REG_MODE_SELECT,
|
||||
HI847_REG_VALUE_16BIT, HI847_MODE_STANDBY))
|
||||
dev_err(&client->dev, "failed to set stream 0x%x",
|
||||
dev_err(hi847->dev, "failed to set stream 0x%x",
|
||||
HI847_REG_MODE_SELECT);
|
||||
}
|
||||
|
||||
static int hi847_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct hi847 *hi847 = to_hi847(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hi847->mutex);
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(hi847->dev);
|
||||
if (ret) {
|
||||
mutex_unlock(&hi847->mutex);
|
||||
return ret;
|
||||
|
@ -2627,11 +2626,11 @@ static int hi847_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
if (ret) {
|
||||
enable = 0;
|
||||
hi847_stop_streaming(hi847);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(hi847->dev);
|
||||
}
|
||||
} else {
|
||||
hi847_stop_streaming(hi847);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(hi847->dev);
|
||||
}
|
||||
|
||||
mutex_unlock(&hi847->mutex);
|
||||
|
@ -2768,7 +2767,6 @@ static const struct v4l2_subdev_internal_ops hi847_internal_ops = {
|
|||
|
||||
static int hi847_identify_module(struct hi847 *hi847)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi847->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
|
@ -2778,7 +2776,7 @@ static int hi847_identify_module(struct hi847 *hi847)
|
|||
return ret;
|
||||
|
||||
if (val != HI847_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x",
|
||||
dev_err(hi847->dev, "chip id mismatch: %x!=%x",
|
||||
HI847_CHIP_ID, val);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
@ -2793,24 +2791,12 @@ static int hi847_check_hwcfg(struct device *dev)
|
|||
struct v4l2_fwnode_endpoint bus_cfg = {
|
||||
.bus_type = V4L2_MBUS_CSI2_DPHY
|
||||
};
|
||||
u32 mclk;
|
||||
int ret;
|
||||
unsigned int i, j;
|
||||
|
||||
if (!fwnode)
|
||||
return -ENXIO;
|
||||
|
||||
ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mclk != HI847_MCLK) {
|
||||
dev_err(dev, "external clock %d is not supported", mclk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
|
||||
if (!ep)
|
||||
return -ENXIO;
|
||||
|
@ -2862,22 +2848,36 @@ static void hi847_remove(struct i2c_client *client)
|
|||
v4l2_async_unregister_subdev(sd);
|
||||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_disable(hi847->dev);
|
||||
mutex_destroy(&hi847->mutex);
|
||||
}
|
||||
|
||||
static int hi847_probe(struct i2c_client *client)
|
||||
{
|
||||
struct hi847 *hi847;
|
||||
unsigned long freq;
|
||||
int ret;
|
||||
|
||||
hi847 = devm_kzalloc(&client->dev, sizeof(*hi847), GFP_KERNEL);
|
||||
if (!hi847)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = hi847_check_hwcfg(&client->dev);
|
||||
hi847->dev = &client->dev;
|
||||
|
||||
hi847->clk = devm_v4l2_sensor_clk_get(hi847->dev, NULL);
|
||||
if (IS_ERR(hi847->clk))
|
||||
return dev_err_probe(hi847->dev, PTR_ERR(hi847->clk),
|
||||
"failed to get clock\n");
|
||||
|
||||
freq = clk_get_rate(hi847->clk);
|
||||
if (freq != HI847_MCLK)
|
||||
return dev_err_probe(hi847->dev, -EINVAL,
|
||||
"external clock %lu is not supported\n",
|
||||
freq);
|
||||
|
||||
ret = hi847_check_hwcfg(hi847->dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to get HW configuration: %d",
|
||||
dev_err(hi847->dev, "failed to get HW configuration: %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2885,7 +2885,7 @@ static int hi847_probe(struct i2c_client *client)
|
|||
v4l2_i2c_subdev_init(&hi847->sd, client, &hi847_subdev_ops);
|
||||
ret = hi847_identify_module(hi847);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
dev_err(hi847->dev, "failed to find sensor: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2893,7 +2893,7 @@ static int hi847_probe(struct i2c_client *client)
|
|||
hi847->cur_mode = &supported_modes[0];
|
||||
ret = hi847_init_controls(hi847);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init controls: %d", ret);
|
||||
dev_err(hi847->dev, "failed to init controls: %d", ret);
|
||||
goto probe_error_v4l2_ctrl_handler_free;
|
||||
}
|
||||
|
||||
|
@ -2904,20 +2904,20 @@ static int hi847_probe(struct i2c_client *client)
|
|||
hi847->pad.flags = MEDIA_PAD_FL_SOURCE;
|
||||
ret = media_entity_pads_init(&hi847->sd.entity, 1, &hi847->pad);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init entity pads: %d", ret);
|
||||
dev_err(hi847->dev, "failed to init entity pads: %d", ret);
|
||||
goto probe_error_v4l2_ctrl_handler_free;
|
||||
}
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&hi847->sd);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "failed to register V4L2 subdev: %d",
|
||||
dev_err(hi847->dev, "failed to register V4L2 subdev: %d",
|
||||
ret);
|
||||
goto probe_error_media_entity_cleanup;
|
||||
}
|
||||
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
pm_runtime_set_active(hi847->dev);
|
||||
pm_runtime_enable(hi847->dev);
|
||||
pm_runtime_idle(hi847->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
// Copyright (C) 2021 Intel Corporation
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#define IMX208_REG_MODE_SELECT 0x0100
|
||||
#define IMX208_MODE_STANDBY 0x00
|
||||
|
@ -268,6 +270,9 @@ static const struct imx208_mode supported_modes[] = {
|
|||
};
|
||||
|
||||
struct imx208 {
|
||||
struct device *dev;
|
||||
struct clk *clk;
|
||||
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
|
||||
|
@ -372,7 +377,6 @@ static int imx208_write_reg(struct imx208 *imx208, u16 reg, u32 len, u32 val)
|
|||
static int imx208_write_regs(struct imx208 *imx208,
|
||||
const struct imx208_reg *regs, u32 len)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -380,7 +384,7 @@ static int imx208_write_regs(struct imx208 *imx208,
|
|||
ret = imx208_write_reg(imx208, regs[i].address, 1,
|
||||
regs[i].val);
|
||||
if (ret) {
|
||||
dev_err_ratelimited(&client->dev,
|
||||
dev_err_ratelimited(imx208->dev,
|
||||
"Failed to write reg 0x%4.4x. error = %d\n",
|
||||
regs[i].address, ret);
|
||||
|
||||
|
@ -431,14 +435,13 @@ static int imx208_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct imx208 *imx208 =
|
||||
container_of(ctrl->handler, struct imx208, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Applying V4L2 control value only happens
|
||||
* when power is up for streaming
|
||||
*/
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
if (!pm_runtime_get_if_in_use(imx208->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@ -471,13 +474,13 @@ static int imx208_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
dev_err(&client->dev,
|
||||
dev_err(imx208->dev,
|
||||
"ctrl(id:0x%x,val:0x%x) is not handled\n",
|
||||
ctrl->id, ctrl->val);
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx208->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -620,7 +623,6 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd,
|
|||
|
||||
static int imx208_identify_module(struct imx208 *imx208)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
|
@ -630,13 +632,13 @@ static int imx208_identify_module(struct imx208 *imx208)
|
|||
ret = imx208_read_reg(imx208, IMX208_REG_CHIP_ID,
|
||||
2, &val);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to read chip id %x\n",
|
||||
dev_err(imx208->dev, "failed to read chip id %x\n",
|
||||
IMX208_CHIP_ID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val != IMX208_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
|
||||
dev_err(imx208->dev, "chip id mismatch: %x!=%x\n",
|
||||
IMX208_CHIP_ID, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -649,7 +651,6 @@ static int imx208_identify_module(struct imx208 *imx208)
|
|||
/* Start streaming */
|
||||
static int imx208_start_streaming(struct imx208 *imx208)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
|
||||
const struct imx208_reg_list *reg_list;
|
||||
int ret, link_freq_index;
|
||||
|
||||
|
@ -662,7 +663,7 @@ static int imx208_start_streaming(struct imx208 *imx208)
|
|||
reg_list = &link_freq_configs[link_freq_index].reg_list;
|
||||
ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set plls\n", __func__);
|
||||
dev_err(imx208->dev, "%s failed to set plls\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -670,7 +671,7 @@ static int imx208_start_streaming(struct imx208 *imx208)
|
|||
reg_list = &imx208->cur_mode->reg_list;
|
||||
ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set mode\n", __func__);
|
||||
dev_err(imx208->dev, "%s failed to set mode\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -687,14 +688,13 @@ static int imx208_start_streaming(struct imx208 *imx208)
|
|||
/* Stop streaming */
|
||||
static int imx208_stop_streaming(struct imx208 *imx208)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
|
||||
int ret;
|
||||
|
||||
/* set stream off register */
|
||||
ret = imx208_write_reg(imx208, IMX208_REG_MODE_SELECT,
|
||||
1, IMX208_MODE_STANDBY);
|
||||
if (ret)
|
||||
dev_err(&client->dev, "%s failed to set stream\n", __func__);
|
||||
dev_err(imx208->dev, "%s failed to set stream\n", __func__);
|
||||
|
||||
/*
|
||||
* Return success even if it was an error, as there is nothing the
|
||||
|
@ -706,13 +706,12 @@ static int imx208_stop_streaming(struct imx208 *imx208)
|
|||
static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct imx208 *imx208 = to_imx208(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&imx208->imx208_mx);
|
||||
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(imx208->dev);
|
||||
if (ret) {
|
||||
mutex_unlock(&imx208->imx208_mx);
|
||||
return ret;
|
||||
|
@ -727,7 +726,7 @@ static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
goto err_rpm_put;
|
||||
} else {
|
||||
imx208_stop_streaming(imx208);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx208->dev);
|
||||
}
|
||||
|
||||
mutex_unlock(&imx208->imx208_mx);
|
||||
|
@ -739,7 +738,7 @@ static int imx208_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
return ret;
|
||||
|
||||
err_rpm_put:
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx208->dev);
|
||||
mutex_unlock(&imx208->imx208_mx);
|
||||
|
||||
return ret;
|
||||
|
@ -778,7 +777,7 @@ static int imx208_read_otp(struct imx208 *imx208)
|
|||
if (imx208->otp_read)
|
||||
goto out_unlock;
|
||||
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(imx208->dev);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
|
@ -805,7 +804,7 @@ static int imx208_read_otp(struct imx208 *imx208)
|
|||
}
|
||||
|
||||
out_pm_put:
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx208->dev);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&imx208->imx208_mx);
|
||||
|
@ -835,7 +834,6 @@ static const BIN_ATTR_RO(otp, IMX208_OTP_SIZE);
|
|||
/* Initialize control handlers */
|
||||
static int imx208_init_controls(struct imx208 *imx208)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd);
|
||||
struct v4l2_ctrl_handler *ctrl_hdlr = &imx208->ctrl_handler;
|
||||
s64 exposure_max;
|
||||
s64 vblank_def;
|
||||
|
@ -914,7 +912,7 @@ static int imx208_init_controls(struct imx208 *imx208)
|
|||
|
||||
if (ctrl_hdlr->error) {
|
||||
ret = ctrl_hdlr->error;
|
||||
dev_err(&client->dev, "%s control init failed (%d)\n",
|
||||
dev_err(imx208->dev, "%s control init failed (%d)\n",
|
||||
__func__, ret);
|
||||
goto error;
|
||||
}
|
||||
|
@ -938,31 +936,36 @@ static void imx208_free_controls(struct imx208 *imx208)
|
|||
static int imx208_probe(struct i2c_client *client)
|
||||
{
|
||||
struct imx208 *imx208;
|
||||
unsigned long freq;
|
||||
int ret;
|
||||
bool full_power;
|
||||
u32 val = 0;
|
||||
|
||||
device_property_read_u32(&client->dev, "clock-frequency", &val);
|
||||
if (val != 19200000) {
|
||||
dev_err(&client->dev,
|
||||
"Unsupported clock-frequency %u. Expected 19200000.\n",
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
imx208 = devm_kzalloc(&client->dev, sizeof(*imx208), GFP_KERNEL);
|
||||
if (!imx208)
|
||||
return -ENOMEM;
|
||||
|
||||
imx208->dev = &client->dev;
|
||||
|
||||
imx208->clk = devm_v4l2_sensor_clk_get(imx208->dev, NULL);
|
||||
if (IS_ERR(imx208->clk))
|
||||
return dev_err_probe(imx208->dev, PTR_ERR(imx208->clk),
|
||||
"failed to get clock\n");
|
||||
|
||||
freq = clk_get_rate(imx208->clk);
|
||||
if (freq != 19200000)
|
||||
return dev_err_probe(imx208->dev, -EINVAL,
|
||||
"external clock %lu is not supported\n",
|
||||
freq);
|
||||
|
||||
/* Initialize subdev */
|
||||
v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops);
|
||||
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
full_power = acpi_dev_state_d0(imx208->dev);
|
||||
if (full_power) {
|
||||
/* Check module identity */
|
||||
ret = imx208_identify_module(imx208);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
dev_err(imx208->dev, "failed to find sensor: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
}
|
||||
|
@ -972,7 +975,7 @@ static int imx208_probe(struct i2c_client *client)
|
|||
|
||||
ret = imx208_init_controls(imx208);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init controls: %d", ret);
|
||||
dev_err(imx208->dev, "failed to init controls: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
|
||||
|
@ -985,7 +988,7 @@ static int imx208_probe(struct i2c_client *client)
|
|||
imx208->pad.flags = MEDIA_PAD_FL_SOURCE;
|
||||
ret = media_entity_pads_init(&imx208->sd.entity, 1, &imx208->pad);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed:%d\n", __func__, ret);
|
||||
dev_err(imx208->dev, "%s failed:%d\n", __func__, ret);
|
||||
goto error_handler_free;
|
||||
}
|
||||
|
||||
|
@ -993,17 +996,17 @@ static int imx208_probe(struct i2c_client *client)
|
|||
if (ret < 0)
|
||||
goto error_media_entity;
|
||||
|
||||
ret = device_create_bin_file(&client->dev, &bin_attr_otp);
|
||||
ret = device_create_bin_file(imx208->dev, &bin_attr_otp);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "sysfs otp creation failed\n");
|
||||
dev_err(imx208->dev, "sysfs otp creation failed\n");
|
||||
goto error_async_subdev;
|
||||
}
|
||||
|
||||
/* Set the device's state to active if it's in D0 state. */
|
||||
if (full_power)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
pm_runtime_set_active(imx208->dev);
|
||||
pm_runtime_enable(imx208->dev);
|
||||
pm_runtime_idle(imx208->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1027,13 +1030,13 @@ static void imx208_remove(struct i2c_client *client)
|
|||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct imx208 *imx208 = to_imx208(sd);
|
||||
|
||||
device_remove_bin_file(&client->dev, &bin_attr_otp);
|
||||
device_remove_bin_file(imx208->dev, &bin_attr_otp);
|
||||
v4l2_async_unregister_subdev(sd);
|
||||
media_entity_cleanup(&sd->entity);
|
||||
imx208_free_controls(imx208);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_disable(imx208->dev);
|
||||
pm_runtime_set_suspended(imx208->dev);
|
||||
|
||||
mutex_destroy(&imx208->imx208_mx);
|
||||
}
|
||||
|
|
|
@ -881,6 +881,109 @@ static const struct v4l2_ctrl_ops imx214_ctrl_ops = {
|
|||
.s_ctrl = imx214_set_ctrl,
|
||||
};
|
||||
|
||||
static int imx214_pll_calculate(struct imx214 *imx214, struct ccs_pll *pll,
|
||||
unsigned int link_freq)
|
||||
{
|
||||
struct ccs_pll_limits limits = {
|
||||
.min_ext_clk_freq_hz = 6000000,
|
||||
.max_ext_clk_freq_hz = 27000000,
|
||||
|
||||
.vt_fr = {
|
||||
.min_pre_pll_clk_div = 1,
|
||||
.max_pre_pll_clk_div = 15,
|
||||
/* Value is educated guess as we don't have a spec */
|
||||
.min_pll_ip_clk_freq_hz = 6000000,
|
||||
/* Value is educated guess as we don't have a spec */
|
||||
.max_pll_ip_clk_freq_hz = 12000000,
|
||||
.min_pll_multiplier = 12,
|
||||
.max_pll_multiplier = 1200,
|
||||
.min_pll_op_clk_freq_hz = 338000000,
|
||||
.max_pll_op_clk_freq_hz = 1200000000,
|
||||
},
|
||||
.vt_bk = {
|
||||
.min_sys_clk_div = 2,
|
||||
.max_sys_clk_div = 4,
|
||||
.min_pix_clk_div = 5,
|
||||
.max_pix_clk_div = 10,
|
||||
.min_pix_clk_freq_hz = 30000000,
|
||||
.max_pix_clk_freq_hz = 120000000,
|
||||
},
|
||||
.op_bk = {
|
||||
.min_sys_clk_div = 1,
|
||||
.max_sys_clk_div = 2,
|
||||
.min_pix_clk_div = 6,
|
||||
.max_pix_clk_div = 10,
|
||||
.min_pix_clk_freq_hz = 30000000,
|
||||
.max_pix_clk_freq_hz = 120000000,
|
||||
},
|
||||
|
||||
.min_line_length_pck_bin = IMX214_PPL_DEFAULT,
|
||||
.min_line_length_pck = IMX214_PPL_DEFAULT,
|
||||
};
|
||||
unsigned int num_lanes = imx214->bus_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
|
||||
/*
|
||||
* There are no documented constraints on the sys clock frequency, for
|
||||
* either branch. Recover them based on the PLL output clock frequency
|
||||
* and sys_clk_div limits on one hand, and the pix clock frequency and
|
||||
* the pix_clk_div limits on the other hand.
|
||||
*/
|
||||
limits.vt_bk.min_sys_clk_freq_hz =
|
||||
max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.vt_bk.max_sys_clk_div,
|
||||
limits.vt_bk.min_pix_clk_freq_hz * limits.vt_bk.min_pix_clk_div);
|
||||
limits.vt_bk.max_sys_clk_freq_hz =
|
||||
min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.vt_bk.min_sys_clk_div,
|
||||
limits.vt_bk.max_pix_clk_freq_hz * limits.vt_bk.max_pix_clk_div);
|
||||
|
||||
limits.op_bk.min_sys_clk_freq_hz =
|
||||
max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.op_bk.max_sys_clk_div,
|
||||
limits.op_bk.min_pix_clk_freq_hz * limits.op_bk.min_pix_clk_div);
|
||||
limits.op_bk.max_sys_clk_freq_hz =
|
||||
min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.op_bk.min_sys_clk_div,
|
||||
limits.op_bk.max_pix_clk_freq_hz * limits.op_bk.max_pix_clk_div);
|
||||
|
||||
memset(pll, 0, sizeof(*pll));
|
||||
|
||||
pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
|
||||
pll->op_lanes = num_lanes;
|
||||
pll->vt_lanes = num_lanes;
|
||||
pll->csi2.lanes = num_lanes;
|
||||
|
||||
pll->binning_horizontal = 1;
|
||||
pll->binning_vertical = 1;
|
||||
pll->scale_m = 1;
|
||||
pll->scale_n = 1;
|
||||
pll->bits_per_pixel =
|
||||
IMX214_CSI_DATA_FORMAT_RAW10 & IMX214_BITS_PER_PIXEL_MASK;
|
||||
pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
|
||||
pll->link_freq = link_freq;
|
||||
pll->ext_clk_freq_hz = clk_get_rate(imx214->xclk);
|
||||
|
||||
return ccs_pll_calculate(imx214->dev, &limits, pll);
|
||||
}
|
||||
|
||||
static int imx214_pll_update(struct imx214 *imx214)
|
||||
{
|
||||
u64 link_freq;
|
||||
int ret;
|
||||
|
||||
link_freq = imx214->bus_cfg.link_frequencies[imx214->link_freq->val];
|
||||
ret = imx214_pll_calculate(imx214, &imx214->pll, link_freq);
|
||||
if (ret) {
|
||||
dev_err(imx214->dev, "PLL calculations failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = v4l2_ctrl_s_ctrl_int64(imx214->pixel_rate,
|
||||
imx214->pll.pixel_rate_pixel_array);
|
||||
if (ret) {
|
||||
dev_err(imx214->dev, "failed to set pixel rate\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx214_ctrls_init(struct imx214 *imx214)
|
||||
{
|
||||
static const struct v4l2_area unit_size = {
|
||||
|
@ -1003,6 +1106,13 @@ static int imx214_ctrls_init(struct imx214 *imx214)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = imx214_pll_update(imx214);
|
||||
if (ret < 0) {
|
||||
v4l2_ctrl_handler_free(ctrl_hdlr);
|
||||
dev_err(imx214->dev, "failed to update PLL\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
imx214->sd.ctrl_handler = ctrl_hdlr;
|
||||
|
||||
return 0;
|
||||
|
@ -1029,8 +1139,8 @@ static int imx214_start_streaming(struct imx214 *imx214)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bit_rate_mbps = (imx214->pll.pixel_rate_csi / 1000000)
|
||||
* imx214->pll.bits_per_pixel;
|
||||
bit_rate_mbps = imx214->pll.pixel_rate_csi / 1000000
|
||||
* imx214->pll.bits_per_pixel;
|
||||
ret = cci_write(imx214->regmap, IMX214_REG_REQ_LINK_BIT_RATE,
|
||||
IMX214_LINK_BIT_RATE_MBPS(bit_rate_mbps), NULL);
|
||||
if (ret) {
|
||||
|
@ -1115,109 +1225,6 @@ err_rpm_put:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int imx214_pll_calculate(struct imx214 *imx214, struct ccs_pll *pll,
|
||||
unsigned int link_freq)
|
||||
{
|
||||
struct ccs_pll_limits limits = {
|
||||
.min_ext_clk_freq_hz = 6000000,
|
||||
.max_ext_clk_freq_hz = 27000000,
|
||||
|
||||
.vt_fr = {
|
||||
.min_pre_pll_clk_div = 1,
|
||||
.max_pre_pll_clk_div = 15,
|
||||
/* Value is educated guess as we don't have a spec */
|
||||
.min_pll_ip_clk_freq_hz = 6000000,
|
||||
/* Value is educated guess as we don't have a spec */
|
||||
.max_pll_ip_clk_freq_hz = 12000000,
|
||||
.min_pll_multiplier = 12,
|
||||
.max_pll_multiplier = 1200,
|
||||
.min_pll_op_clk_freq_hz = 338000000,
|
||||
.max_pll_op_clk_freq_hz = 1200000000,
|
||||
},
|
||||
.vt_bk = {
|
||||
.min_sys_clk_div = 2,
|
||||
.max_sys_clk_div = 4,
|
||||
.min_pix_clk_div = 5,
|
||||
.max_pix_clk_div = 10,
|
||||
.min_pix_clk_freq_hz = 30000000,
|
||||
.max_pix_clk_freq_hz = 120000000,
|
||||
},
|
||||
.op_bk = {
|
||||
.min_sys_clk_div = 1,
|
||||
.max_sys_clk_div = 2,
|
||||
.min_pix_clk_div = 6,
|
||||
.max_pix_clk_div = 10,
|
||||
.min_pix_clk_freq_hz = 30000000,
|
||||
.max_pix_clk_freq_hz = 120000000,
|
||||
},
|
||||
|
||||
.min_line_length_pck_bin = IMX214_PPL_DEFAULT,
|
||||
.min_line_length_pck = IMX214_PPL_DEFAULT,
|
||||
};
|
||||
unsigned int num_lanes = imx214->bus_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
|
||||
/*
|
||||
* There are no documented constraints on the sys clock frequency, for
|
||||
* either branch. Recover them based on the PLL output clock frequency
|
||||
* and sys_clk_div limits on one hand, and the pix clock frequency and
|
||||
* the pix_clk_div limits on the other hand.
|
||||
*/
|
||||
limits.vt_bk.min_sys_clk_freq_hz =
|
||||
max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.vt_bk.max_sys_clk_div,
|
||||
limits.vt_bk.min_pix_clk_freq_hz * limits.vt_bk.min_pix_clk_div);
|
||||
limits.vt_bk.max_sys_clk_freq_hz =
|
||||
min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.vt_bk.min_sys_clk_div,
|
||||
limits.vt_bk.max_pix_clk_freq_hz * limits.vt_bk.max_pix_clk_div);
|
||||
|
||||
limits.op_bk.min_sys_clk_freq_hz =
|
||||
max(limits.vt_fr.min_pll_op_clk_freq_hz / limits.op_bk.max_sys_clk_div,
|
||||
limits.op_bk.min_pix_clk_freq_hz * limits.op_bk.min_pix_clk_div);
|
||||
limits.op_bk.max_sys_clk_freq_hz =
|
||||
min(limits.vt_fr.max_pll_op_clk_freq_hz / limits.op_bk.min_sys_clk_div,
|
||||
limits.op_bk.max_pix_clk_freq_hz * limits.op_bk.max_pix_clk_div);
|
||||
|
||||
memset(pll, 0, sizeof(*pll));
|
||||
|
||||
pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
|
||||
pll->op_lanes = num_lanes;
|
||||
pll->vt_lanes = num_lanes;
|
||||
pll->csi2.lanes = num_lanes;
|
||||
|
||||
pll->binning_horizontal = 1;
|
||||
pll->binning_vertical = 1;
|
||||
pll->scale_m = 1;
|
||||
pll->scale_n = 1;
|
||||
pll->bits_per_pixel =
|
||||
IMX214_CSI_DATA_FORMAT_RAW10 & IMX214_BITS_PER_PIXEL_MASK;
|
||||
pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
|
||||
pll->link_freq = link_freq;
|
||||
pll->ext_clk_freq_hz = clk_get_rate(imx214->xclk);
|
||||
|
||||
return ccs_pll_calculate(imx214->dev, &limits, pll);
|
||||
}
|
||||
|
||||
static int imx214_pll_update(struct imx214 *imx214)
|
||||
{
|
||||
u64 link_freq;
|
||||
int ret;
|
||||
|
||||
link_freq = imx214->bus_cfg.link_frequencies[imx214->link_freq->val];
|
||||
ret = imx214_pll_calculate(imx214, &imx214->pll, link_freq);
|
||||
if (ret) {
|
||||
dev_err(imx214->dev, "PLL calculations failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = v4l2_ctrl_s_ctrl_int64(imx214->pixel_rate,
|
||||
imx214->pll.pixel_rate_pixel_array);
|
||||
if (ret) {
|
||||
dev_err(imx214->dev, "failed to set pixel rate\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_interval *fival)
|
||||
|
@ -1324,10 +1331,11 @@ static int imx214_identify_module(struct imx214 *imx214)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
|
||||
static int imx214_parse_fwnode(struct imx214 *imx214)
|
||||
{
|
||||
struct fwnode_handle *endpoint __free(fwnode_handle) = NULL;
|
||||
struct v4l2_fwnode_endpoint *bus_cfg = &imx214->bus_cfg;
|
||||
struct fwnode_handle *endpoint;
|
||||
struct device *dev = imx214->dev;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -1337,11 +1345,8 @@ static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
|
|||
|
||||
bus_cfg->bus_type = V4L2_MBUS_CSI2_DPHY;
|
||||
ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, bus_cfg);
|
||||
fwnode_handle_put(endpoint);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "parsing endpoint node failed\n");
|
||||
goto error;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "parsing endpoint node failed\n");
|
||||
|
||||
/* Check the number of MIPI CSI2 data lanes */
|
||||
if (bus_cfg->bus.mipi_csi2.num_data_lanes != 4) {
|
||||
|
@ -1357,18 +1362,16 @@ static int imx214_parse_fwnode(struct device *dev, struct imx214 *imx214)
|
|||
u64 freq = bus_cfg->link_frequencies[i];
|
||||
struct ccs_pll pll;
|
||||
|
||||
if (!imx214_pll_calculate(imx214, &pll, freq))
|
||||
break;
|
||||
if (freq == IMX214_DEFAULT_LINK_FREQ_LEGACY) {
|
||||
dev_warn(dev,
|
||||
"link-frequencies %d not supported, please review your DT. Continuing anyway\n",
|
||||
IMX214_DEFAULT_LINK_FREQ);
|
||||
freq = IMX214_DEFAULT_LINK_FREQ;
|
||||
if (imx214_pll_calculate(imx214, &pll, freq))
|
||||
continue;
|
||||
bus_cfg->link_frequencies[i] = freq;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!imx214_pll_calculate(imx214, &pll, freq))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == bus_cfg->nr_of_link_frequencies)
|
||||
|
@ -1396,7 +1399,7 @@ static int imx214_probe(struct i2c_client *client)
|
|||
|
||||
imx214->dev = dev;
|
||||
|
||||
imx214->xclk = devm_clk_get(dev, NULL);
|
||||
imx214->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
|
||||
if (IS_ERR(imx214->xclk))
|
||||
return dev_err_probe(dev, PTR_ERR(imx214->xclk),
|
||||
"failed to get xclk\n");
|
||||
|
@ -1415,7 +1418,7 @@ static int imx214_probe(struct i2c_client *client)
|
|||
return dev_err_probe(dev, PTR_ERR(imx214->regmap),
|
||||
"failed to initialize CCI\n");
|
||||
|
||||
ret = imx214_parse_fwnode(dev, imx214);
|
||||
ret = imx214_parse_fwnode(imx214);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1459,12 +1462,6 @@ static int imx214_probe(struct i2c_client *client)
|
|||
pm_runtime_set_active(imx214->dev);
|
||||
pm_runtime_enable(imx214->dev);
|
||||
|
||||
ret = imx214_pll_update(imx214);
|
||||
if (ret < 0) {
|
||||
dev_err_probe(dev, ret, "failed to update PLL\n");
|
||||
goto error_subdev_cleanup;
|
||||
}
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&imx214->sd);
|
||||
if (ret < 0) {
|
||||
dev_err_probe(dev, ret,
|
||||
|
|
|
@ -1032,6 +1032,10 @@ static int imx219_power_on(struct device *dev)
|
|||
goto reg_off;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Misinterpretation of reset assertion - do not re-use this code.
|
||||
* XCLR pin is using incorrect (for reset signal) logical level.
|
||||
*/
|
||||
gpiod_set_value_cansleep(imx219->reset_gpio, 1);
|
||||
usleep_range(IMX219_XCLR_MIN_DELAY_US,
|
||||
IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
|
||||
|
@ -1186,7 +1190,7 @@ static int imx219_probe(struct i2c_client *client)
|
|||
"failed to initialize CCI\n");
|
||||
|
||||
/* Get system clock (xclk) */
|
||||
imx219->xclk = devm_clk_get(dev, NULL);
|
||||
imx219->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
|
||||
if (IS_ERR(imx219->xclk))
|
||||
return dev_err_probe(dev, PTR_ERR(imx219->xclk),
|
||||
"failed to get xclk\n");
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <media/v4l2-cci.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#define IMX258_REG_MODE_SELECT CCI_REG8(0x0100)
|
||||
#define IMX258_MODE_STANDBY 0x00
|
||||
|
@ -645,6 +646,8 @@ static const struct imx258_mode supported_modes[] = {
|
|||
};
|
||||
|
||||
struct imx258 {
|
||||
struct device *dev;
|
||||
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct regmap *regmap;
|
||||
|
@ -751,7 +754,6 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct imx258 *imx258 =
|
||||
container_of(ctrl->handler, struct imx258, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
|
@ -765,7 +767,7 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
* Applying V4L2 control value only happens
|
||||
* when power is up for streaming
|
||||
*/
|
||||
if (pm_runtime_get_if_in_use(&client->dev) == 0)
|
||||
if (pm_runtime_get_if_in_use(imx258->dev) == 0)
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@ -811,14 +813,14 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
NULL);
|
||||
break;
|
||||
default:
|
||||
dev_info(&client->dev,
|
||||
dev_info(imx258->dev,
|
||||
"ctrl(id:0x%x,val:0x%x) is not handled\n",
|
||||
ctrl->id, ctrl->val);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx258->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1013,14 +1015,13 @@ static int imx258_get_selection(struct v4l2_subdev *sd,
|
|||
/* Start streaming */
|
||||
static int imx258_start_streaming(struct imx258 *imx258)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
|
||||
const struct imx258_reg_list *reg_list;
|
||||
const struct imx258_link_freq_config *link_freq_cfg;
|
||||
int ret, link_freq_index;
|
||||
|
||||
ret = cci_write(imx258->regmap, IMX258_REG_RESET, 0x01, NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to reset sensor\n", __func__);
|
||||
dev_err(imx258->dev, "%s failed to reset sensor\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1034,21 +1035,21 @@ static int imx258_start_streaming(struct imx258 *imx258)
|
|||
reg_list = &link_freq_cfg->link_cfg[imx258->lane_mode_idx].reg_list;
|
||||
ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set plls\n", __func__);
|
||||
dev_err(imx258->dev, "%s failed to set plls\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cci_multi_reg_write(imx258->regmap, mode_common_regs,
|
||||
ARRAY_SIZE(mode_common_regs), NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set common regs\n", __func__);
|
||||
dev_err(imx258->dev, "%s failed to set common regs\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cci_multi_reg_write(imx258->regmap, imx258->variant_cfg->regs,
|
||||
imx258->variant_cfg->num_regs, NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set variant config\n",
|
||||
dev_err(imx258->dev, "%s failed to set variant config\n",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1057,7 +1058,7 @@ static int imx258_start_streaming(struct imx258 *imx258)
|
|||
!!(imx258->csi2_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK),
|
||||
NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set clock lane mode\n", __func__);
|
||||
dev_err(imx258->dev, "%s failed to set clock lane mode\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1066,7 @@ static int imx258_start_streaming(struct imx258 *imx258)
|
|||
reg_list = &imx258->cur_mode->reg_list;
|
||||
ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set mode\n", __func__);
|
||||
dev_err(imx258->dev, "%s failed to set mode\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1082,14 +1083,13 @@ static int imx258_start_streaming(struct imx258 *imx258)
|
|||
/* Stop streaming */
|
||||
static int imx258_stop_streaming(struct imx258 *imx258)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
|
||||
int ret;
|
||||
|
||||
/* set stream off register */
|
||||
ret = cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,
|
||||
IMX258_MODE_STANDBY, NULL);
|
||||
if (ret)
|
||||
dev_err(&client->dev, "%s failed to set stream\n", __func__);
|
||||
dev_err(imx258->dev, "%s failed to set stream\n", __func__);
|
||||
|
||||
/*
|
||||
* Return success even if it was an error, as there is nothing the
|
||||
|
@ -1135,13 +1135,12 @@ static int imx258_power_off(struct device *dev)
|
|||
static int imx258_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct imx258 *imx258 = to_imx258(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&imx258->mutex);
|
||||
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(imx258->dev);
|
||||
if (ret < 0)
|
||||
goto err_unlock;
|
||||
|
||||
|
@ -1154,7 +1153,7 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
goto err_rpm_put;
|
||||
} else {
|
||||
imx258_stop_streaming(imx258);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx258->dev);
|
||||
}
|
||||
|
||||
mutex_unlock(&imx258->mutex);
|
||||
|
@ -1162,7 +1161,7 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
return ret;
|
||||
|
||||
err_rpm_put:
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx258->dev);
|
||||
err_unlock:
|
||||
mutex_unlock(&imx258->mutex);
|
||||
|
||||
|
@ -1172,20 +1171,19 @@ err_unlock:
|
|||
/* Verify chip ID */
|
||||
static int imx258_identify_module(struct imx258 *imx258)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
|
||||
int ret;
|
||||
u64 val;
|
||||
|
||||
ret = cci_read(imx258->regmap, IMX258_REG_CHIP_ID,
|
||||
&val, NULL);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to read chip id %x\n",
|
||||
dev_err(imx258->dev, "failed to read chip id %x\n",
|
||||
IMX258_CHIP_ID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val != IMX258_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",
|
||||
dev_err(imx258->dev, "chip id mismatch: %x!=%llx\n",
|
||||
IMX258_CHIP_ID, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1217,7 +1215,6 @@ static const struct v4l2_subdev_internal_ops imx258_internal_ops = {
|
|||
/* Initialize control handlers */
|
||||
static int imx258_init_controls(struct imx258 *imx258)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
|
||||
const struct imx258_link_freq_config *link_freq_cfgs;
|
||||
struct v4l2_fwnode_device_properties props;
|
||||
struct v4l2_ctrl_handler *ctrl_hdlr;
|
||||
|
@ -1308,12 +1305,12 @@ static int imx258_init_controls(struct imx258 *imx258)
|
|||
|
||||
if (ctrl_hdlr->error) {
|
||||
ret = ctrl_hdlr->error;
|
||||
dev_err(&client->dev, "%s control init failed (%d)\n",
|
||||
dev_err(imx258->dev, "%s control init failed (%d)\n",
|
||||
__func__, ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
||||
ret = v4l2_fwnode_device_parse(imx258->dev, &props);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
@ -1339,15 +1336,14 @@ static void imx258_free_controls(struct imx258 *imx258)
|
|||
mutex_destroy(&imx258->mutex);
|
||||
}
|
||||
|
||||
static int imx258_get_regulators(struct imx258 *imx258,
|
||||
struct i2c_client *client)
|
||||
static int imx258_get_regulators(struct imx258 *imx258)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < IMX258_NUM_SUPPLIES; i++)
|
||||
imx258->supplies[i].supply = imx258_supply_name[i];
|
||||
|
||||
return devm_regulator_bulk_get(&client->dev,
|
||||
return devm_regulator_bulk_get(imx258->dev,
|
||||
IMX258_NUM_SUPPLIES, imx258->supplies);
|
||||
}
|
||||
|
||||
|
@ -1365,30 +1361,27 @@ static int imx258_probe(struct i2c_client *client)
|
|||
if (!imx258)
|
||||
return -ENOMEM;
|
||||
|
||||
imx258->dev = &client->dev;
|
||||
|
||||
imx258->regmap = devm_cci_regmap_init_i2c(client, 16);
|
||||
if (IS_ERR(imx258->regmap)) {
|
||||
ret = PTR_ERR(imx258->regmap);
|
||||
dev_err(&client->dev, "failed to initialize CCI: %d\n", ret);
|
||||
dev_err(imx258->dev, "failed to initialize CCI: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = imx258_get_regulators(imx258, client);
|
||||
ret = imx258_get_regulators(imx258);
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret,
|
||||
return dev_err_probe(imx258->dev, ret,
|
||||
"failed to get regulators\n");
|
||||
|
||||
imx258->clk = devm_clk_get_optional(&client->dev, NULL);
|
||||
imx258->clk = devm_v4l2_sensor_clk_get_legacy(imx258->dev, NULL, false,
|
||||
0);
|
||||
if (IS_ERR(imx258->clk))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
|
||||
return dev_err_probe(imx258->dev, PTR_ERR(imx258->clk),
|
||||
"error getting clock\n");
|
||||
if (!imx258->clk) {
|
||||
dev_dbg(&client->dev,
|
||||
"no clock provided, using clock-frequency property\n");
|
||||
|
||||
device_property_read_u32(&client->dev, "clock-frequency", &val);
|
||||
} else {
|
||||
val = clk_get_rate(imx258->clk);
|
||||
}
|
||||
val = clk_get_rate(imx258->clk);
|
||||
|
||||
switch (val) {
|
||||
case 19200000:
|
||||
|
@ -1400,32 +1393,32 @@ static int imx258_probe(struct i2c_client *client)
|
|||
imx258->link_freq_menu_items = link_freq_menu_items_24;
|
||||
break;
|
||||
default:
|
||||
dev_err(&client->dev, "input clock frequency of %u not supported\n",
|
||||
dev_err(imx258->dev, "input clock frequency of %u not supported\n",
|
||||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
|
||||
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx258->dev), NULL);
|
||||
if (!endpoint) {
|
||||
dev_err(&client->dev, "Endpoint node not found\n");
|
||||
dev_err(imx258->dev, "Endpoint node not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
|
||||
fwnode_handle_put(endpoint);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "Parsing endpoint node failed\n");
|
||||
dev_err(imx258->dev, "Parsing endpoint node failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = v4l2_link_freq_to_bitmap(&client->dev,
|
||||
ret = v4l2_link_freq_to_bitmap(imx258->dev,
|
||||
ep.link_frequencies,
|
||||
ep.nr_of_link_frequencies,
|
||||
imx258->link_freq_menu_items,
|
||||
ARRAY_SIZE(link_freq_menu_items_19_2),
|
||||
&imx258->link_freq_bitmap);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "Link frequency not supported\n");
|
||||
dev_err(imx258->dev, "Link frequency not supported\n");
|
||||
goto error_endpoint_free;
|
||||
}
|
||||
|
||||
|
@ -1438,7 +1431,7 @@ static int imx258_probe(struct i2c_client *client)
|
|||
imx258->lane_mode_idx = IMX258_4_LANE_MODE;
|
||||
break;
|
||||
default:
|
||||
dev_err(&client->dev, "Invalid data lanes: %u\n",
|
||||
dev_err(imx258->dev, "Invalid data lanes: %u\n",
|
||||
ep.bus.mipi_csi2.num_data_lanes);
|
||||
ret = -EINVAL;
|
||||
goto error_endpoint_free;
|
||||
|
@ -1446,7 +1439,7 @@ static int imx258_probe(struct i2c_client *client)
|
|||
|
||||
imx258->csi2_flags = ep.bus.mipi_csi2.flags;
|
||||
|
||||
imx258->variant_cfg = device_get_match_data(&client->dev);
|
||||
imx258->variant_cfg = device_get_match_data(imx258->dev);
|
||||
if (!imx258->variant_cfg)
|
||||
imx258->variant_cfg = &imx258_cfg;
|
||||
|
||||
|
@ -1454,7 +1447,7 @@ static int imx258_probe(struct i2c_client *client)
|
|||
v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
|
||||
|
||||
/* Will be powered off via pm_runtime_idle */
|
||||
ret = imx258_power_on(&client->dev);
|
||||
ret = imx258_power_on(imx258->dev);
|
||||
if (ret)
|
||||
goto error_endpoint_free;
|
||||
|
||||
|
@ -1486,9 +1479,9 @@ static int imx258_probe(struct i2c_client *client)
|
|||
if (ret < 0)
|
||||
goto error_media_entity;
|
||||
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
pm_runtime_set_active(imx258->dev);
|
||||
pm_runtime_enable(imx258->dev);
|
||||
pm_runtime_idle(imx258->dev);
|
||||
v4l2_fwnode_endpoint_free(&ep);
|
||||
|
||||
return 0;
|
||||
|
@ -1500,7 +1493,7 @@ error_handler_free:
|
|||
imx258_free_controls(imx258);
|
||||
|
||||
error_identify:
|
||||
imx258_power_off(&client->dev);
|
||||
imx258_power_off(imx258->dev);
|
||||
|
||||
error_endpoint_free:
|
||||
v4l2_fwnode_endpoint_free(&ep);
|
||||
|
@ -1517,10 +1510,10 @@ static void imx258_remove(struct i2c_client *client)
|
|||
media_entity_cleanup(&sd->entity);
|
||||
imx258_free_controls(imx258);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
imx258_power_off(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_disable(imx258->dev);
|
||||
if (!pm_runtime_status_suspended(imx258->dev))
|
||||
imx258_power_off(imx258->dev);
|
||||
pm_runtime_set_suspended(imx258->dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops imx258_pm_ops = {
|
||||
|
|
|
@ -826,6 +826,8 @@ static int imx274_start_stream(struct stimx274 *priv)
|
|||
* if rst = 0, keep it in reset;
|
||||
* if rst = 1, bring it out of reset.
|
||||
*
|
||||
* Note: Misinterpretation of reset assertion - do not re-use this code.
|
||||
* XCLR pin is using incorrect (for reset signal) logical level.
|
||||
*/
|
||||
static void imx274_reset(struct stimx274 *priv, int rst)
|
||||
{
|
||||
|
|
|
@ -1460,11 +1460,10 @@ static int imx283_probe(struct i2c_client *client)
|
|||
}
|
||||
|
||||
/* Get system clock (xclk) */
|
||||
imx283->xclk = devm_clk_get(imx283->dev, NULL);
|
||||
if (IS_ERR(imx283->xclk)) {
|
||||
imx283->xclk = devm_v4l2_sensor_clk_get(imx283->dev, NULL);
|
||||
if (IS_ERR(imx283->xclk))
|
||||
return dev_err_probe(imx283->dev, PTR_ERR(imx283->xclk),
|
||||
"failed to get xclk\n");
|
||||
}
|
||||
|
||||
xclk_freq = clk_get_rate(imx283->xclk);
|
||||
for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
|
||||
|
|
|
@ -1422,14 +1422,14 @@ static int imx290_get_regulators(struct device *dev, struct imx290 *imx290)
|
|||
static int imx290_init_clk(struct imx290 *imx290)
|
||||
{
|
||||
u32 xclk_freq;
|
||||
int ret;
|
||||
|
||||
ret = device_property_read_u32(imx290->dev, "clock-frequency",
|
||||
&xclk_freq);
|
||||
if (ret) {
|
||||
dev_err(imx290->dev, "Could not get xclk frequency\n");
|
||||
return ret;
|
||||
}
|
||||
imx290->xclk = devm_v4l2_sensor_clk_get_legacy(imx290->dev, "xclk",
|
||||
false, 0);
|
||||
if (IS_ERR(imx290->xclk))
|
||||
return dev_err_probe(imx290->dev, PTR_ERR(imx290->xclk),
|
||||
"Could not get xclk\n");
|
||||
|
||||
xclk_freq = clk_get_rate(imx290->xclk);
|
||||
|
||||
/* external clock must be 37.125 MHz or 74.25MHz */
|
||||
switch (xclk_freq) {
|
||||
|
@ -1445,12 +1445,6 @@ static int imx290_init_clk(struct imx290 *imx290)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(imx290->xclk, xclk_freq);
|
||||
if (ret) {
|
||||
dev_err(imx290->dev, "Could not set xclk frequency\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1596,11 +1590,6 @@ static int imx290_probe(struct i2c_client *client)
|
|||
return ret;
|
||||
|
||||
/* Acquire resources. */
|
||||
imx290->xclk = devm_clk_get(dev, "xclk");
|
||||
if (IS_ERR(imx290->xclk))
|
||||
return dev_err_probe(dev, PTR_ERR(imx290->xclk),
|
||||
"Could not get xclk\n");
|
||||
|
||||
ret = imx290_get_regulators(dev, imx290);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev, ret, "Cannot get regulators\n");
|
||||
|
@ -1611,7 +1600,7 @@ static int imx290_probe(struct i2c_client *client)
|
|||
return dev_err_probe(dev, PTR_ERR(imx290->rst_gpio),
|
||||
"Cannot get reset gpio\n");
|
||||
|
||||
/* Initialize external clock frequency. */
|
||||
/* Initialize external clock. */
|
||||
ret = imx290_init_clk(imx290);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -921,7 +921,7 @@ static int imx296_read_temperature(struct imx296 *sensor, int *temp)
|
|||
|
||||
tmdout &= IMX296_TMDOUT_MASK;
|
||||
|
||||
/* T(°C) = 246.312 - 0.304 * TMDOUT */;
|
||||
/* T(°C) = 246.312 - 0.304 * TMDOUT */
|
||||
*temp = 246312 - 304 * tmdout;
|
||||
|
||||
return imx296_write(sensor, IMX296_TMDCTRL, 0, NULL);
|
||||
|
@ -1043,7 +1043,7 @@ static int imx296_probe(struct i2c_client *client)
|
|||
return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
|
||||
"failed to get reset GPIO\n");
|
||||
|
||||
sensor->clk = devm_clk_get(sensor->dev, "inck");
|
||||
sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, "inck");
|
||||
if (IS_ERR(sensor->clk))
|
||||
return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
|
||||
"failed to get clock\n");
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
@ -106,11 +108,12 @@ struct imx319_mode {
|
|||
};
|
||||
|
||||
struct imx319_hwcfg {
|
||||
u32 ext_clk; /* sensor external clk */
|
||||
unsigned long link_freq_bitmap;
|
||||
};
|
||||
|
||||
struct imx319 {
|
||||
struct device *dev;
|
||||
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
|
||||
|
@ -1839,14 +1842,13 @@ static int imx319_write_reg(struct imx319 *imx319, u16 reg, u32 len, u32 val)
|
|||
static int imx319_write_regs(struct imx319 *imx319,
|
||||
const struct imx319_reg *regs, u32 len)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
int ret;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = imx319_write_reg(imx319, regs[i].address, 1, regs[i].val);
|
||||
if (ret) {
|
||||
dev_err_ratelimited(&client->dev,
|
||||
dev_err_ratelimited(imx319->dev,
|
||||
"write reg 0x%4.4x return err %d",
|
||||
regs[i].address, ret);
|
||||
return ret;
|
||||
|
@ -1880,7 +1882,6 @@ static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct imx319 *imx319 = container_of(ctrl->handler,
|
||||
struct imx319, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
s64 max;
|
||||
int ret;
|
||||
|
||||
|
@ -1899,7 +1900,7 @@ static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
* Applying V4L2 control value only happens
|
||||
* when power is up for streaming
|
||||
*/
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
if (!pm_runtime_get_if_in_use(imx319->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@ -1933,12 +1934,12 @@ static int imx319_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
|
||||
dev_info(imx319->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
|
||||
ctrl->id, ctrl->val);
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx319->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -2087,7 +2088,6 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
|
|||
/* Verify chip ID */
|
||||
static int imx319_identify_module(struct imx319 *imx319)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
|
@ -2099,7 +2099,7 @@ static int imx319_identify_module(struct imx319 *imx319)
|
|||
return ret;
|
||||
|
||||
if (val != IMX319_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x",
|
||||
dev_err(imx319->dev, "chip id mismatch: %x!=%x",
|
||||
IMX319_CHIP_ID, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -2112,7 +2112,6 @@ static int imx319_identify_module(struct imx319 *imx319)
|
|||
/* Start streaming */
|
||||
static int imx319_start_streaming(struct imx319 *imx319)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
const struct imx319_reg_list *reg_list;
|
||||
int ret;
|
||||
|
||||
|
@ -2124,7 +2123,7 @@ static int imx319_start_streaming(struct imx319 *imx319)
|
|||
reg_list = &imx319_global_setting;
|
||||
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set global settings");
|
||||
dev_err(imx319->dev, "failed to set global settings");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2132,7 +2131,7 @@ static int imx319_start_streaming(struct imx319 *imx319)
|
|||
reg_list = &imx319->cur_mode->reg_list;
|
||||
ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set mode");
|
||||
dev_err(imx319->dev, "failed to set mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2160,13 +2159,12 @@ static int imx319_stop_streaming(struct imx319 *imx319)
|
|||
static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct imx319 *imx319 = to_imx319(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&imx319->mutex);
|
||||
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(imx319->dev);
|
||||
if (ret < 0)
|
||||
goto err_unlock;
|
||||
|
||||
|
@ -2179,7 +2177,7 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
goto err_rpm_put;
|
||||
} else {
|
||||
imx319_stop_streaming(imx319);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx319->dev);
|
||||
}
|
||||
|
||||
/* vflip and hflip cannot change during streaming */
|
||||
|
@ -2191,7 +2189,7 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
return ret;
|
||||
|
||||
err_rpm_put:
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx319->dev);
|
||||
err_unlock:
|
||||
mutex_unlock(&imx319->mutex);
|
||||
|
||||
|
@ -2231,7 +2229,6 @@ static const struct v4l2_subdev_internal_ops imx319_internal_ops = {
|
|||
/* Initialize control handlers */
|
||||
static int imx319_init_controls(struct imx319 *imx319)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd);
|
||||
struct v4l2_ctrl_handler *ctrl_hdlr;
|
||||
s64 exposure_max;
|
||||
s64 vblank_def;
|
||||
|
@ -2311,7 +2308,7 @@ static int imx319_init_controls(struct imx319 *imx319)
|
|||
0, 0, imx319_test_pattern_menu);
|
||||
if (ctrl_hdlr->error) {
|
||||
ret = ctrl_hdlr->error;
|
||||
dev_err(&client->dev, "control init failed: %d", ret);
|
||||
dev_err(imx319->dev, "control init failed: %d", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -2350,20 +2347,6 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
|
|||
if (!cfg)
|
||||
goto out_err;
|
||||
|
||||
ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
|
||||
&cfg->ext_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
|
||||
if (cfg->ext_clk != IMX319_EXT_CLK) {
|
||||
dev_err(dev, "external clock %d is not supported",
|
||||
cfg->ext_clk);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
|
||||
bus_cfg.nr_of_link_frequencies,
|
||||
link_freq_menu_items,
|
||||
|
@ -2385,6 +2368,8 @@ out_err:
|
|||
static int imx319_probe(struct i2c_client *client)
|
||||
{
|
||||
struct imx319 *imx319;
|
||||
unsigned long freq;
|
||||
struct clk *clk;
|
||||
bool full_power;
|
||||
int ret;
|
||||
|
||||
|
@ -2392,24 +2377,37 @@ static int imx319_probe(struct i2c_client *client)
|
|||
if (!imx319)
|
||||
return -ENOMEM;
|
||||
|
||||
imx319->dev = &client->dev;
|
||||
|
||||
mutex_init(&imx319->mutex);
|
||||
|
||||
clk = devm_v4l2_sensor_clk_get(imx319->dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(imx319->dev, PTR_ERR(clk),
|
||||
"failed to acquire clock\n");
|
||||
|
||||
freq = clk_get_rate(clk);
|
||||
if (freq != IMX319_EXT_CLK)
|
||||
return dev_err_probe(imx319->dev, -EINVAL,
|
||||
"external clock %lu is not supported",
|
||||
freq);
|
||||
|
||||
/* Initialize subdev */
|
||||
v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops);
|
||||
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
full_power = acpi_dev_state_d0(imx319->dev);
|
||||
if (full_power) {
|
||||
/* Check module identity */
|
||||
ret = imx319_identify_module(imx319);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
dev_err(imx319->dev, "failed to find sensor: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
}
|
||||
|
||||
imx319->hwcfg = imx319_get_hwcfg(&client->dev);
|
||||
imx319->hwcfg = imx319_get_hwcfg(imx319->dev);
|
||||
if (!imx319->hwcfg) {
|
||||
dev_err(&client->dev, "failed to get hwcfg");
|
||||
dev_err(imx319->dev, "failed to get hwcfg");
|
||||
ret = -ENODEV;
|
||||
goto error_probe;
|
||||
}
|
||||
|
@ -2419,7 +2417,7 @@ static int imx319_probe(struct i2c_client *client)
|
|||
|
||||
ret = imx319_init_controls(imx319);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init controls: %d", ret);
|
||||
dev_err(imx319->dev, "failed to init controls: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
|
||||
|
@ -2434,27 +2432,27 @@ static int imx319_probe(struct i2c_client *client)
|
|||
imx319->pad.flags = MEDIA_PAD_FL_SOURCE;
|
||||
ret = media_entity_pads_init(&imx319->sd.entity, 1, &imx319->pad);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init entity pads: %d", ret);
|
||||
dev_err(imx319->dev, "failed to init entity pads: %d", ret);
|
||||
goto error_handler_free;
|
||||
}
|
||||
|
||||
/* Set the device's state to active if it's in D0 state. */
|
||||
if (full_power)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_set_active(imx319->dev);
|
||||
pm_runtime_enable(imx319->dev);
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&imx319->sd);
|
||||
if (ret < 0)
|
||||
goto error_media_entity_pm;
|
||||
|
||||
pm_runtime_idle(&client->dev);
|
||||
pm_runtime_idle(imx319->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
error_media_entity_pm:
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_disable(imx319->dev);
|
||||
if (full_power)
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_set_suspended(imx319->dev);
|
||||
media_entity_cleanup(&imx319->sd.entity);
|
||||
|
||||
error_handler_free:
|
||||
|
@ -2475,9 +2473,9 @@ static void imx319_remove(struct i2c_client *client)
|
|||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_disable(imx319->dev);
|
||||
if (!pm_runtime_status_suspended(imx319->dev))
|
||||
pm_runtime_set_suspended(imx319->dev);
|
||||
|
||||
mutex_destroy(&imx319->mutex);
|
||||
}
|
||||
|
|
|
@ -118,6 +118,9 @@
|
|||
#define IMX334_REG_TP CCI_REG8(0x329e)
|
||||
#define IMX334_TP_COLOR_HBARS 0xa
|
||||
#define IMX334_TP_COLOR_VBARS 0xb
|
||||
#define IMX334_TP_BLACK 0x0
|
||||
#define IMX334_TP_WHITE 0x1
|
||||
#define IMX334_TP_BLACK_GREY 0xc
|
||||
|
||||
#define IMX334_TPG_EN_DOUT CCI_REG8(0x329c)
|
||||
#define IMX334_TP_ENABLE 0x1
|
||||
|
@ -398,12 +401,18 @@ static const char * const imx334_test_pattern_menu[] = {
|
|||
"Disabled",
|
||||
"Vertical Color Bars",
|
||||
"Horizontal Color Bars",
|
||||
"Black and Grey Bars",
|
||||
"Black Color",
|
||||
"White Color",
|
||||
};
|
||||
|
||||
static const int imx334_test_pattern_val[] = {
|
||||
IMX334_TP_DISABLE,
|
||||
IMX334_TP_COLOR_HBARS,
|
||||
IMX334_TP_COLOR_VBARS,
|
||||
IMX334_TP_BLACK_GREY,
|
||||
IMX334_TP_BLACK,
|
||||
IMX334_TP_WHITE,
|
||||
};
|
||||
|
||||
static const struct cci_reg_sequence raw10_framefmt_regs[] = {
|
||||
|
@ -997,7 +1006,7 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
|
|||
"failed to get reset gpio\n");
|
||||
|
||||
/* Get sensor input clock */
|
||||
imx334->inclk = devm_clk_get(imx334->dev, NULL);
|
||||
imx334->inclk = devm_v4l2_sensor_clk_get(imx334->dev, NULL);
|
||||
if (IS_ERR(imx334->inclk))
|
||||
return dev_err_probe(imx334->dev, PTR_ERR(imx334->inclk),
|
||||
"could not get inclk\n");
|
||||
|
@ -1070,6 +1079,10 @@ static int imx334_power_on(struct device *dev)
|
|||
struct imx334 *imx334 = to_imx334(sd);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Note: Misinterpretation of reset assertion - do not re-use this code.
|
||||
* XCLR pin is using incorrect (for reset signal) logical level.
|
||||
*/
|
||||
gpiod_set_value_cansleep(imx334->reset_gpio, 1);
|
||||
|
||||
ret = clk_prepare_enable(imx334->inclk);
|
||||
|
|
|
@ -1026,11 +1026,10 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
|
|||
}
|
||||
|
||||
/* Get sensor input clock */
|
||||
imx335->inclk = devm_clk_get(imx335->dev, NULL);
|
||||
if (IS_ERR(imx335->inclk)) {
|
||||
dev_err(imx335->dev, "could not get inclk\n");
|
||||
return PTR_ERR(imx335->inclk);
|
||||
}
|
||||
imx335->inclk = devm_v4l2_sensor_clk_get(imx335->dev, NULL);
|
||||
if (IS_ERR(imx335->inclk))
|
||||
return dev_err_probe(imx335->dev, PTR_ERR(imx335->inclk),
|
||||
"could not get inclk\n");
|
||||
|
||||
rate = clk_get_rate(imx335->inclk);
|
||||
if (rate != IMX335_INCLK_RATE) {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-event.h>
|
||||
|
@ -92,11 +94,13 @@ struct imx355_mode {
|
|||
};
|
||||
|
||||
struct imx355_hwcfg {
|
||||
u32 ext_clk; /* sensor external clk */
|
||||
unsigned long link_freq_bitmap;
|
||||
};
|
||||
|
||||
struct imx355 {
|
||||
struct device *dev;
|
||||
struct clk *clk;
|
||||
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
|
||||
|
@ -1136,14 +1140,13 @@ static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
|
|||
static int imx355_write_regs(struct imx355 *imx355,
|
||||
const struct imx355_reg *regs, u32 len)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
|
||||
int ret;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
|
||||
if (ret) {
|
||||
dev_err_ratelimited(&client->dev,
|
||||
dev_err_ratelimited(imx355->dev,
|
||||
"write reg 0x%4.4x return err %d",
|
||||
regs[i].address, ret);
|
||||
|
||||
|
@ -1178,7 +1181,6 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
{
|
||||
struct imx355 *imx355 = container_of(ctrl->handler,
|
||||
struct imx355, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
|
||||
s64 max;
|
||||
int ret;
|
||||
|
||||
|
@ -1197,7 +1199,7 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
* Applying V4L2 control value only happens
|
||||
* when power is up for streaming
|
||||
*/
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
if (!pm_runtime_get_if_in_use(imx355->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@ -1231,12 +1233,12 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
|
||||
dev_info(imx355->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
|
||||
ctrl->id, ctrl->val);
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx355->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1385,7 +1387,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
|
|||
/* Start streaming */
|
||||
static int imx355_start_streaming(struct imx355 *imx355)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
|
||||
const struct imx355_reg_list *reg_list;
|
||||
int ret;
|
||||
|
||||
|
@ -1393,7 +1394,7 @@ static int imx355_start_streaming(struct imx355 *imx355)
|
|||
reg_list = &imx355_global_setting;
|
||||
ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set global settings");
|
||||
dev_err(imx355->dev, "failed to set global settings");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1401,7 +1402,7 @@ static int imx355_start_streaming(struct imx355 *imx355)
|
|||
reg_list = &imx355->cur_mode->reg_list;
|
||||
ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set mode");
|
||||
dev_err(imx355->dev, "failed to set mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1429,13 +1430,12 @@ static int imx355_stop_streaming(struct imx355 *imx355)
|
|||
static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct imx355 *imx355 = to_imx355(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&imx355->mutex);
|
||||
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
ret = pm_runtime_resume_and_get(imx355->dev);
|
||||
if (ret < 0)
|
||||
goto err_unlock;
|
||||
|
||||
|
@ -1448,7 +1448,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
goto err_rpm_put;
|
||||
} else {
|
||||
imx355_stop_streaming(imx355);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx355->dev);
|
||||
}
|
||||
|
||||
/* vflip and hflip cannot change during streaming */
|
||||
|
@ -1460,7 +1460,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
|
|||
return ret;
|
||||
|
||||
err_rpm_put:
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_put(imx355->dev);
|
||||
err_unlock:
|
||||
mutex_unlock(&imx355->mutex);
|
||||
|
||||
|
@ -1470,7 +1470,6 @@ err_unlock:
|
|||
/* Verify chip ID */
|
||||
static int imx355_identify_module(struct imx355 *imx355)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
|
@ -1479,7 +1478,7 @@ static int imx355_identify_module(struct imx355 *imx355)
|
|||
return ret;
|
||||
|
||||
if (val != IMX355_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x",
|
||||
dev_err(imx355->dev, "chip id mismatch: %x!=%x",
|
||||
IMX355_CHIP_ID, val);
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -1519,7 +1518,6 @@ static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
|
|||
/* Initialize control handlers */
|
||||
static int imx355_init_controls(struct imx355 *imx355)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
|
||||
struct v4l2_fwnode_device_properties props;
|
||||
struct v4l2_ctrl_handler *ctrl_hdlr;
|
||||
s64 exposure_max;
|
||||
|
@ -1600,11 +1598,11 @@ static int imx355_init_controls(struct imx355 *imx355)
|
|||
0, 0, imx355_test_pattern_menu);
|
||||
if (ctrl_hdlr->error) {
|
||||
ret = ctrl_hdlr->error;
|
||||
dev_err(&client->dev, "control init failed: %d", ret);
|
||||
dev_err(imx355->dev, "control init failed: %d", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
||||
ret = v4l2_fwnode_device_parse(imx355->dev, &props);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
|
@ -1648,20 +1646,6 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
|
|||
if (!cfg)
|
||||
goto out_err;
|
||||
|
||||
ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
|
||||
&cfg->ext_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
|
||||
if (cfg->ext_clk != IMX355_EXT_CLK) {
|
||||
dev_err(dev, "external clock %d is not supported",
|
||||
cfg->ext_clk);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
|
||||
bus_cfg.nr_of_link_frequencies,
|
||||
link_freq_menu_items,
|
||||
|
@ -1683,27 +1667,41 @@ out_err:
|
|||
static int imx355_probe(struct i2c_client *client)
|
||||
{
|
||||
struct imx355 *imx355;
|
||||
unsigned long freq;
|
||||
int ret;
|
||||
|
||||
imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
|
||||
if (!imx355)
|
||||
return -ENOMEM;
|
||||
|
||||
imx355->dev = &client->dev;
|
||||
|
||||
mutex_init(&imx355->mutex);
|
||||
|
||||
imx355->clk = devm_v4l2_sensor_clk_get(imx355->dev, NULL);
|
||||
if (IS_ERR(imx355->clk))
|
||||
return dev_err_probe(imx355->dev, PTR_ERR(imx355->clk),
|
||||
"failed to get clock\n");
|
||||
|
||||
freq = clk_get_rate(imx355->clk);
|
||||
if (freq != IMX355_EXT_CLK)
|
||||
return dev_err_probe(imx355->dev, -EINVAL,
|
||||
"external clock %lu is not supported\n",
|
||||
freq);
|
||||
|
||||
/* Initialize subdev */
|
||||
v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
|
||||
|
||||
/* Check module identity */
|
||||
ret = imx355_identify_module(imx355);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
dev_err(imx355->dev, "failed to find sensor: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
|
||||
imx355->hwcfg = imx355_get_hwcfg(&client->dev);
|
||||
imx355->hwcfg = imx355_get_hwcfg(imx355->dev);
|
||||
if (!imx355->hwcfg) {
|
||||
dev_err(&client->dev, "failed to get hwcfg");
|
||||
dev_err(imx355->dev, "failed to get hwcfg");
|
||||
ret = -ENODEV;
|
||||
goto error_probe;
|
||||
}
|
||||
|
@ -1713,7 +1711,7 @@ static int imx355_probe(struct i2c_client *client)
|
|||
|
||||
ret = imx355_init_controls(imx355);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init controls: %d", ret);
|
||||
dev_err(imx355->dev, "failed to init controls: %d", ret);
|
||||
goto error_probe;
|
||||
}
|
||||
|
||||
|
@ -1728,7 +1726,7 @@ static int imx355_probe(struct i2c_client *client)
|
|||
imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
|
||||
ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init entity pads: %d", ret);
|
||||
dev_err(imx355->dev, "failed to init entity pads: %d", ret);
|
||||
goto error_handler_free;
|
||||
}
|
||||
|
||||
|
@ -1736,9 +1734,9 @@ static int imx355_probe(struct i2c_client *client)
|
|||
* Device is already turned on by i2c-core with ACPI domain PM.
|
||||
* Enable runtime PM and turn off the device.
|
||||
*/
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
pm_runtime_set_active(imx355->dev);
|
||||
pm_runtime_enable(imx355->dev);
|
||||
pm_runtime_idle(imx355->dev);
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&imx355->sd);
|
||||
if (ret < 0)
|
||||
|
@ -1747,8 +1745,8 @@ static int imx355_probe(struct i2c_client *client)
|
|||
return 0;
|
||||
|
||||
error_media_entity_runtime_pm:
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_disable(imx355->dev);
|
||||
pm_runtime_set_suspended(imx355->dev);
|
||||
media_entity_cleanup(&imx355->sd.entity);
|
||||
|
||||
error_handler_free:
|
||||
|
@ -1769,8 +1767,8 @@ static void imx355_remove(struct i2c_client *client)
|
|||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_disable(imx355->dev);
|
||||
pm_runtime_set_suspended(imx355->dev);
|
||||
|
||||
mutex_destroy(&imx355->mutex);
|
||||
}
|
||||
|
|
|
@ -933,11 +933,10 @@ static int imx412_parse_hw_config(struct imx412 *imx412)
|
|||
}
|
||||
|
||||
/* Get sensor input clock */
|
||||
imx412->inclk = devm_clk_get(imx412->dev, NULL);
|
||||
if (IS_ERR(imx412->inclk)) {
|
||||
dev_err(imx412->dev, "could not get inclk\n");
|
||||
return PTR_ERR(imx412->inclk);
|
||||
}
|
||||
imx412->inclk = devm_v4l2_sensor_clk_get(imx412->dev, NULL);
|
||||
if (IS_ERR(imx412->inclk))
|
||||
return dev_err_probe(imx412->dev, PTR_ERR(imx412->inclk),
|
||||
"could not get inclk\n");
|
||||
|
||||
rate = clk_get_rate(imx412->inclk);
|
||||
if (rate != IMX412_INCLK_RATE) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue