[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:
Linus Torvalds 2025-10-02 13:13:26 -07:00
commit f79e772258
576 changed files with 16902 additions and 9286 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -81,6 +81,7 @@ properties:
required:
- compatible
- reg
- clocks
- port
unevaluatedProperties: false

View File

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

View File

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

View File

@ -361,6 +361,9 @@ examples:
compatible = "sony,imx274";
reg = <0x1a>;
clocks = <&serializer>;
clock-names = "inck";
reset-gpios = <&serializer1 0 GPIO_ACTIVE_LOW>;
port {

View File

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

View File

@ -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 = <&reg_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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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() 中解除文件句柄的关联。文件句柄的退出函数也
将被调用。

View File

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

View File

@ -26,7 +26,7 @@ Revision and Copyright
**********************
Authors:
- Verkuil, Hans <hverkuil-cisco@xs4all.nl>
- Verkuil, Hans <hverkuil@kernel.org>
- Initial version.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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