mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
[GIT PULL for v6.16] media updates
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmg1X0MACgkQCF8+vY7k 4RX+9A//bExEiDHHgTptAhnPpdUKz4+WoNCasW/FIV41ry/OpjnbIuREio7/mkxk 03r/EEakycSCL8jrnIN7xHxUu5i53X3um2vzVpLgMfYHdxN1nGktGFFtbXq1uLlp An3e1fGR2VpU4aXs66Zy7nkaa4r2epfrKa0+dqsL9Tkix6wmbTYmJ2fxBtIjCupr bYm8WuQAvK8SvBuBvegAmr6AaVYF56bOh74B1VuRko6IAksHfrppNCUAFvXiU4NL FiqNyq9XaHXQtsS7gCCrjVUeTHpzdjjIZEkV3A+60G4Bc5A2wv17TzpR5GPMuUsQ BMHlGc1zex5AvieJLCDf5HityEkwD6+1eHxzuTgKtCM3gJYlJYJGMw8Gr219CVw4 +jJ6VImkfT/nScg+xsoyiYLHj/I4Awhj2mobnO6UnMyprTHC9AjnHA5eijvdSnRg wyAA80ofjRr6n21adwkw5QXDKEE/UZMEbiUmAkL4qIZ1Y1iBVvPzmCLDp9qCpq8+ lsxsn26pXFAGySzx9WWHEmdYWU6/Z0XkifRgYhOR6tcUoGDar2iLJlzn9AEm8hPS mU72eQOOdELVzr1rDYkGI0rskkYelmmJbWIQCkUEXhm4BhWn5EGK56stckmIcW0a X9e+GQDR5trjl8hAgLD/I80CI3bRKK9ox2VQdsRWKoho8NmkgyI= =4pGJ -----END PGP SIGNATURE----- Merge tag 'media/v6.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - v4l2-core fix: V4L2_BUF_TYPE_VIDEO_OVERLAY is capture, not output - New driver: Amlogic C3 ISP - New sensor drivers: ST VD55G1 and VD56G3, OmniVision OV02C10 - amlogic: c3-mipi-csi2: Handle 64-bits division - a fix for 64-bits division at the amlogic c3-mipi-csi2 driver - Changes at atomisp to support mainline mt9m114 driver and remove deprecated GPIO APIs - various cleanups, fixes and enhancements * tag 'media/v6.16-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (314 commits) media: rkvdec: h264: Support High 10 and 4:2:2 profiles media: rkvdec: Add get_image_fmt ops media: rkvdec: Initialize the m2m context before the controls media: rkvdec: h264: Limit minimum profile to constrained baseline media: mediatek: jpeg: support 34bits media: verisilicon: Free post processor buffers on error media: platform: mtk-mdp3: Remove unused mdp_get_plat_device media: amlogic: c3-mipi-csi2: Handle 64-bits division media: uvcvideo: Use dev_err_probe for devm_gpiod_get_optional media: uvcvideo: Fix deferred probing error media: uvcvideo: Rollback non processed entities on error media: uvcvideo: Send control events for partial succeeds media: uvcvideo: Return the number of processed controls media: uvcvideo: Do not turn on the camera for some ioctls media: uvcvideo: Make power management granular media: uvcvideo: Increase/decrease the PM counter per IOCTL media: uvcvideo: Create uvc_pm_(get|put) functions media: uvcvideo: Keep streaming state in the file handle Documentation: media: Add documentation file c3-isp.rst Documentation: media: Add documentation file metafmt-c3-isp.rst ...
This commit is contained in:
commit
a61e260381
1
.mailmap
1
.mailmap
|
@ -511,6 +511,7 @@ Mayuresh Janorkar <mayur@ti.com>
|
|||
Md Sadre Alam <quic_mdalam@quicinc.com> <mdalam@codeaurora.org>
|
||||
Miaoqing Pan <quic_miaoqing@quicinc.com> <miaoqing@codeaurora.org>
|
||||
Michael Buesch <m@bues.ch>
|
||||
Michael Riesch <michael.riesch@collabora.com> <michael.riesch@wolfvision.net>
|
||||
Michal Simek <michal.simek@amd.com> <michal.simek@xilinx.com>
|
||||
Michel Dänzer <michel@tungstengraphics.com>
|
||||
Michel Lespinasse <michel@lespinasse.org>
|
||||
|
|
26
Documentation/admin-guide/media/c3-isp.dot
Normal file
26
Documentation/admin-guide/media/c3-isp.dot
Normal file
|
@ -0,0 +1,26 @@
|
|||
digraph board {
|
||||
rankdir=TB
|
||||
n00000001 [label="{{<port0> 0 | <port1> 1} | c3-isp-core\n/dev/v4l-subdev0 | {<port2> 2 | <port3> 3 | <port4> 4 | <port5> 5}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000001:port3 -> n00000008:port0
|
||||
n00000001:port4 -> n0000000b:port0
|
||||
n00000001:port5 -> n0000000e:port0
|
||||
n00000001:port2 -> n00000027
|
||||
n00000008 [label="{{<port0> 0} | c3-isp-resizer0\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000008:port1 -> n00000016 [style=bold]
|
||||
n0000000b [label="{{<port0> 0} | c3-isp-resizer1\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n0000000b:port1 -> n0000001a [style=bold]
|
||||
n0000000e [label="{{<port0> 0} | c3-isp-resizer2\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n0000000e:port1 -> n00000023 [style=bold]
|
||||
n00000011 [label="{{<port0> 0} | c3-mipi-adapter\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n00000011:port1 -> n00000001:port0 [style=bold]
|
||||
n00000016 [label="c3-isp-cap0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
|
||||
n0000001a [label="c3-isp-cap1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
|
||||
n0000001e [label="{{<port0> 0} | c3-mipi-csi2\n/dev/v4l-subdev5 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n0000001e:port1 -> n00000011:port0 [style=bold]
|
||||
n00000023 [label="c3-isp-cap2\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
|
||||
n00000027 [label="c3-isp-stats\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
|
||||
n0000002b [label="c3-isp-params\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
|
||||
n0000002b -> n00000001:port1
|
||||
n0000003f [label="{{} | imx290 2-001a\n/dev/v4l-subdev6 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
|
||||
n0000003f:port0 -> n0000001e:port0 [style=bold]
|
||||
}
|
101
Documentation/admin-guide/media/c3-isp.rst
Normal file
101
Documentation/admin-guide/media/c3-isp.rst
Normal file
|
@ -0,0 +1,101 @@
|
|||
.. SPDX-License-Identifier: (GPL-2.0-only OR MIT)
|
||||
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
=================================================
|
||||
Amlogic C3 Image Signal Processing (C3ISP) driver
|
||||
=================================================
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This file documents the Amlogic C3ISP driver located under
|
||||
drivers/media/platform/amlogic/c3/isp.
|
||||
|
||||
The current version of the driver supports the C3ISP found on
|
||||
Amlogic C308L processor.
|
||||
|
||||
The driver implements V4L2, Media controller and V4L2 subdev interfaces.
|
||||
Camera sensor using V4L2 subdev interface in the kernel is supported.
|
||||
|
||||
The driver has been tested on AW419-C308L-Socket platform.
|
||||
|
||||
Amlogic C3 ISP
|
||||
==============
|
||||
|
||||
The Camera hardware found on C308L processors and supported by
|
||||
the driver consists of:
|
||||
|
||||
- 1 MIPI-CSI-2 module: handles the physical layer of the MIPI CSI-2 receiver and
|
||||
receives data from the connected camera sensor.
|
||||
- 1 MIPI-ADAPTER module: organizes MIPI data to meet ISP input requirements and
|
||||
send MIPI data to ISP.
|
||||
- 1 ISP (Image Signal Processing) module: contains a pipeline of image processing
|
||||
hardware blocks. The ISP pipeline contains three resizers at the end each of
|
||||
them connected to a DMA interface which writes the output data to memory.
|
||||
|
||||
A high-level functional view of the C3 ISP is presented below.::
|
||||
|
||||
+----------+ +-------+
|
||||
| Resizer |--->| WRMIF |
|
||||
+---------+ +------------+ +--------------+ +-------+ |----------+ +-------+
|
||||
| Sensor |--->| MIPI CSI-2 |--->| MIPI ADAPTER |--->| ISP |---|----------+ +-------+
|
||||
+---------+ +------------+ +--------------+ +-------+ | Resizer |--->| WRMIF |
|
||||
+----------+ +-------+
|
||||
|----------+ +-------+
|
||||
| Resizer |--->| WRMIF |
|
||||
+----------+ +-------+
|
||||
|
||||
Driver architecture and design
|
||||
==============================
|
||||
|
||||
With the goal to model the hardware links between the modules and to expose a
|
||||
clean, logical and usable interface, the driver registers the following V4L2
|
||||
sub-devices:
|
||||
|
||||
- 1 `c3-mipi-csi2` sub-device - the MIPI CSI-2 receiver
|
||||
- 1 `c3-mipi-adapter` sub-device - the MIPI adapter
|
||||
- 1 `c3-isp-core` sub-device - the ISP core
|
||||
- 3 `c3-isp-resizer` sub-devices - the ISP resizers
|
||||
|
||||
The `c3-isp-core` sub-device is linked to 2 video device nodes for statistics
|
||||
capture and parameters programming:
|
||||
|
||||
- the `c3-isp-stats` capture video device node for statistics capture
|
||||
- the `c3-isp-params` output video device for parameters programming
|
||||
|
||||
Each `c3-isp-resizer` sub-device is linked to a capture video device node where
|
||||
frames are captured from:
|
||||
|
||||
- `c3-isp-resizer0` is linked to the `c3-isp-cap0` capture video device
|
||||
- `c3-isp-resizer1` is linked to the `c3-isp-cap1` capture video device
|
||||
- `c3-isp-resizer2` is linked to the `c3-isp-cap2` capture video device
|
||||
|
||||
The media controller pipeline graph is as follows (with connected a
|
||||
IMX290 camera sensor):
|
||||
|
||||
.. _isp_topology_graph:
|
||||
|
||||
.. kernel-figure:: c3-isp.dot
|
||||
:alt: c3-isp.dot
|
||||
:align: center
|
||||
|
||||
Media pipeline topology
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Runtime configuration of the ISP hardware is performed on the `c3-isp-params`
|
||||
video device node using the :ref:`V4L2_META_FMT_C3ISP_PARAMS
|
||||
<v4l2-meta-fmt-c3isp-params>` as data format. The buffer structure is defined by
|
||||
:c:type:`c3_isp_params_cfg`.
|
||||
|
||||
Statistics are captured from the `c3-isp-stats` video device node using the
|
||||
:ref:`V4L2_META_FMT_C3ISP_STATS <v4l2-meta-fmt-c3isp-stats>` data format.
|
||||
|
||||
The final picture size and format is configured using the V4L2 video
|
||||
capture interface on the `c3-isp-cap[0, 2]` video device nodes.
|
||||
|
||||
The Amlogic C3 ISP is supported by `libcamera <https://libcamera.org>`_ with a
|
||||
dedicated pipeline handler and algorithms that perform run-time image correction
|
||||
and enhancement.
|
|
@ -1,8 +1,17 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
The mgb4 driver
|
||||
===============
|
||||
|
||||
Copyright |copy| 2023 - 2025 Digiteq Automotive
|
||||
author: Martin Tůma <martin.tuma@digiteqautomotive.com>
|
||||
|
||||
This is a v4l2 device driver for the Digiteq Automotive FrameGrabber 4, a PCIe
|
||||
card capable of capturing and generating FPD-Link III and GMSL2/3 video streams
|
||||
as used in the automotive industry.
|
||||
|
||||
sysfs interface
|
||||
---------------
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ saa7134 Philips SAA7134
|
|||
saa7164 NXP SAA7164
|
||||
smipcie SMI PCIe DVBSky cards
|
||||
solo6x10 Bluecherry / Softlogic 6x10 capture cards (MPEG-4/H.264)
|
||||
sta2x11_vip STA2X11 VIP Video For Linux
|
||||
tw5864 Techwell TW5864 video/audio grabber and encoder
|
||||
tw686x Intersil/Techwell TW686x
|
||||
tw68 Techwell tw68x Video For Linux
|
||||
|
|
|
@ -10,6 +10,7 @@ Video4Linux (V4L) driver-specific documentation
|
|||
:maxdepth: 2
|
||||
|
||||
bttv
|
||||
c3-isp
|
||||
cafe_ccic
|
||||
cx88
|
||||
fimc
|
||||
|
|
88
Documentation/devicetree/bindings/media/amlogic,c3-isp.yaml
Normal file
88
Documentation/devicetree/bindings/media/amlogic,c3-isp.yaml
Normal file
|
@ -0,0 +1,88 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/amlogic,c3-isp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic C3 Image Signal Processing Unit
|
||||
|
||||
maintainers:
|
||||
- Keke Li <keke.li@amlogic.com>
|
||||
|
||||
description:
|
||||
Amlogic ISP is the RAW image processing module
|
||||
and supports three channels image output.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,c3-isp
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: isp
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: vapb
|
||||
- const: isp0
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: input port node.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
|
||||
#include <dt-bindings/power/amlogic,c3-pwrc.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
isp: isp@ff000000 {
|
||||
compatible = "amlogic,c3-isp";
|
||||
reg = <0x0 0xff000000 0x0 0xf000>;
|
||||
reg-names = "isp";
|
||||
power-domains = <&pwrc PWRC_C3_ISP_TOP_ID>;
|
||||
clocks = <&clkc_periphs CLKID_VAPB>,
|
||||
<&clkc_periphs CLKID_ISP0>;
|
||||
clock-names = "vapb", "isp0";
|
||||
assigned-clocks = <&clkc_periphs CLKID_VAPB>,
|
||||
<&clkc_periphs CLKID_ISP0>;
|
||||
assigned-clock-rates = <0>, <400000000>;
|
||||
interrupts = <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>;
|
||||
|
||||
port {
|
||||
c3_isp_in: endpoint {
|
||||
remote-endpoint = <&c3_adap_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -0,0 +1,111 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/amlogic,c3-mipi-adapter.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic C3 MIPI adapter receiver
|
||||
|
||||
maintainers:
|
||||
- Keke Li <keke.li@amlogic.com>
|
||||
|
||||
description:
|
||||
MIPI adapter is used to convert the MIPI CSI-2 data
|
||||
into an ISP supported data format.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,c3-mipi-adapter
|
||||
|
||||
reg:
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: top
|
||||
- const: fd
|
||||
- const: rd
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: vapb
|
||||
- const: isp0
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: input port node.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: output port node.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
|
||||
#include <dt-bindings/power/amlogic,c3-pwrc.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
adap: adap@ff010000 {
|
||||
compatible = "amlogic,c3-mipi-adapter";
|
||||
reg = <0x0 0xff010000 0x0 0x100>,
|
||||
<0x0 0xff01b000 0x0 0x100>,
|
||||
<0x0 0xff01d000 0x0 0x200>;
|
||||
reg-names = "top", "fd", "rd";
|
||||
power-domains = <&pwrc PWRC_C3_ISP_TOP_ID>;
|
||||
clocks = <&clkc_periphs CLKID_VAPB>,
|
||||
<&clkc_periphs CLKID_ISP0>;
|
||||
clock-names = "vapb", "isp0";
|
||||
assigned-clocks = <&clkc_periphs CLKID_VAPB>,
|
||||
<&clkc_periphs CLKID_ISP0>;
|
||||
assigned-clock-rates = <0>, <400000000>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
c3_adap_in: endpoint {
|
||||
remote-endpoint = <&c3_mipi_csi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
c3_adap_out: endpoint {
|
||||
remote-endpoint = <&c3_isp_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -0,0 +1,127 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/amlogic,c3-mipi-csi2.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic C3 MIPI CSI-2 receiver
|
||||
|
||||
maintainers:
|
||||
- Keke Li <keke.li@amlogic.com>
|
||||
|
||||
description:
|
||||
MIPI CSI-2 receiver contains CSI-2 RX PHY and host controller.
|
||||
It receives the MIPI data from the image sensor and sends MIPI data
|
||||
to MIPI adapter.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,c3-mipi-csi2
|
||||
|
||||
reg:
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: aphy
|
||||
- const: dphy
|
||||
- const: host
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: vapb
|
||||
- const: phy0
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description: input port node, connected to sensor.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: output port node
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/amlogic,c3-peripherals-clkc.h>
|
||||
#include <dt-bindings/power/amlogic,c3-pwrc.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
csi: csi@ff018000 {
|
||||
compatible = "amlogic,c3-mipi-csi2";
|
||||
reg = <0x0 0xff018000 0x0 0x400>,
|
||||
<0x0 0xff019000 0x0 0x300>,
|
||||
<0x0 0xff01a000 0x0 0x100>;
|
||||
reg-names = "aphy", "dphy", "host";
|
||||
power-domains = <&pwrc PWRC_C3_MIPI_ISP_WRAP_ID>;
|
||||
clocks = <&clkc_periphs CLKID_VAPB>,
|
||||
<&clkc_periphs CLKID_CSI_PHY0>;
|
||||
clock-names = "vapb", "phy0";
|
||||
assigned-clocks = <&clkc_periphs CLKID_VAPB>,
|
||||
<&clkc_periphs CLKID_CSI_PHY0>;
|
||||
assigned-clock-rates = <0>, <200000000>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
c3_mipi_csi_in: endpoint {
|
||||
remote-endpoint = <&imx290_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
c3_mipi_csi_out: endpoint {
|
||||
remote-endpoint = <&c3_adap_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -14,10 +14,16 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra114-cec
|
||||
- nvidia,tegra124-cec
|
||||
- nvidia,tegra210-cec
|
||||
oneOf:
|
||||
- enum:
|
||||
- nvidia,tegra114-cec
|
||||
- nvidia,tegra124-cec
|
||||
- nvidia,tegra210-cec
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra186-cec
|
||||
- nvidia,tegra194-cec
|
||||
- const: nvidia,tegra210-cec
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/fsl,imx-capture-subsystem.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale i.MX Media Video Device
|
||||
|
||||
description:
|
||||
This is the media controller node for video capture support. It is a
|
||||
virtual device that lists the camera serial interface nodes that the
|
||||
media device will control
|
||||
|
||||
maintainers:
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,imx-capture-subsystem
|
||||
|
||||
ports:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description:
|
||||
Should contain a list of phandles pointing to camera
|
||||
sensor interface ports of IPU devices.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
capture-subsystem {
|
||||
compatible = "fsl,imx-capture-subsystem";
|
||||
ports = <&ipu1_csi0>, <&ipu1_csi1>;
|
||||
};
|
143
Documentation/devicetree/bindings/media/fsl,imx6-mipi-csi2.yaml
Normal file
143
Documentation/devicetree/bindings/media/fsl,imx6-mipi-csi2.yaml
Normal file
|
@ -0,0 +1,143 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/fsl,imx6-mipi-csi2.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MIPI CSI-2 Receiver core in the i.MX SoC
|
||||
|
||||
description:
|
||||
This is the device node for the MIPI CSI-2 Receiver core in the i.MX
|
||||
SoC. This is a Synopsys Designware MIPI CSI-2 host controller core
|
||||
combined with a D-PHY core mixed into the same register block. In
|
||||
addition this device consists of an i.MX-specific "CSI2IPU gasket"
|
||||
glue logic, also controlled from the same register block. The CSI2IPU
|
||||
gasket demultiplexes the four virtual channel streams from the host
|
||||
controller's 32-bit output image bus onto four 16-bit parallel busses
|
||||
to the i.MX IPU CSIs.
|
||||
|
||||
maintainers:
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,imx6-mipi-csi2
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: hsi_tx (the D-PHY clock)
|
||||
- description: video_27m (D-PHY PLL reference clock)
|
||||
- description: eim_podf;
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: dphy
|
||||
- const: ref
|
||||
- const: pix
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: CSI-2 ERR1 irq
|
||||
- description: CSI-2 ERR2 irq
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
Input port node, single endpoint describing the CSI-2 transmitter.
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
clock-lanes:
|
||||
const: 0
|
||||
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
- const: 3
|
||||
- const: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
patternProperties:
|
||||
'^port@[1-4]$':
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
ports 1 through 4 are output ports connecting with parallel bus sink
|
||||
endpoint nodes and correspond to the four MIPI CSI-2 virtual channel
|
||||
outputs.
|
||||
|
||||
properties:
|
||||
endpoint@0:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
endpoint@1:
|
||||
$ref: video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx6qdl-clock.h>
|
||||
|
||||
mipi@21dc000 {
|
||||
compatible = "fsl,imx6-mipi-csi2";
|
||||
reg = <0x021dc000 0x4000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clocks = <&clks IMX6QDL_CLK_HSI_TX>,
|
||||
<&clks IMX6QDL_CLK_VIDEO_27M>,
|
||||
<&clks IMX6QDL_CLK_EIM_PODF>;
|
||||
clock-names = "dphy", "ref", "pix";
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&ov5640_to_mipi_csi2>;
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&ipu1_csi0_mux_from_mipi_vc0>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&ipu1_csi1_mux_from_mipi_vc0>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,28 +0,0 @@
|
|||
* Analog Devices AD5820 autofocus coil
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: Must contain one of:
|
||||
- "adi,ad5820"
|
||||
- "adi,ad5821"
|
||||
- "adi,ad5823"
|
||||
|
||||
- reg: I2C slave address
|
||||
|
||||
- VANA-supply: supply of voltage for VANA pin
|
||||
|
||||
Optional properties:
|
||||
|
||||
- enable-gpios : GPIO spec for the XSHUTDOWN pin. The XSHUTDOWN signal is
|
||||
active low, a high level on the pin enables the device.
|
||||
|
||||
Example:
|
||||
|
||||
ad5820: coil@c {
|
||||
compatible = "adi,ad5820";
|
||||
reg = <0x0c>;
|
||||
|
||||
VANA-supply = <&vaux4>;
|
||||
enable-gpios = <&msmgpio 26 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
56
Documentation/devicetree/bindings/media/i2c/adi,ad5820.yaml
Normal file
56
Documentation/devicetree/bindings/media/i2c/adi,ad5820.yaml
Normal file
|
@ -0,0 +1,56 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/adi,ad5820.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD5820 autofocus coil
|
||||
|
||||
maintainers:
|
||||
- Pavel Machek <pavel@ucw.cz>
|
||||
|
||||
description:
|
||||
The AD5820 is a current sink driver designed for precise control of
|
||||
voice coil motors (VCMs) in camera autofocus systems.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad5820
|
||||
- adi,ad5821
|
||||
- adi,ad5823
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
GPIO spec for the XSHUTDOWN pin. The XSHUTDOWN signal is active low,
|
||||
a high level on the pin enables the device.
|
||||
|
||||
VANA-supply:
|
||||
description: supply of voltage for VANA pin
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- VANA-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
coil@c {
|
||||
compatible = "adi,ad5820";
|
||||
reg = <0x0c>;
|
||||
|
||||
enable-gpios = <&msmgpio 26 GPIO_ACTIVE_HIGH>;
|
||||
VANA-supply = <&vaux4>;
|
||||
};
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/adv7180.yaml#
|
||||
$id: http://devicetree.org/schemas/media/i2c/adi,adv7180.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADV7180 analog video decoder family
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/adv748x.yaml#
|
||||
$id: http://devicetree.org/schemas/media/i2c/adi,adv748x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADV748X video decoder with HDMI receiver
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/adv7604.yaml#
|
||||
$id: http://devicetree.org/schemas/media/i2c/adi,adv7604.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADV7604/10/11/12 video decoder with HDMI receiver
|
152
Documentation/devicetree/bindings/media/i2c/ovti,ov02e10.yaml
Normal file
152
Documentation/devicetree/bindings/media/i2c/ovti,ov02e10.yaml
Normal file
|
@ -0,0 +1,152 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright (c) 2025 Linaro Ltd.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov02e10.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Omnivision OV02E10 CMOS Sensor
|
||||
|
||||
maintainers:
|
||||
- Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
|
||||
description: |
|
||||
The Omnivision OV02E10 and OV02C10 sensors are 2 megapixel, CMOS image sensors which support:
|
||||
- Automatic black level calibration (ABLC)
|
||||
- Programmable controls for frame rate, mirror and flip, binning, cropping
|
||||
and windowing
|
||||
- OVO2C10
|
||||
- 10 bit RAW Bayer 1920x1080 60 fps 2-lane @ 800 Mbps/lane
|
||||
- 10 bit RAW Bayer 1920x1080 60 fps 1-lane @ 1500 Mbps/lane
|
||||
- 10 bit RAW Bayer 1280x720 60 fps cropped 1-lane @ 960 Mbps/lane
|
||||
- 10 bit RGB/BW 640x480 60 fps bin2 or skip2 1-lane @ 800 Mbps/lane
|
||||
- 10 bit RGB/BW 480x270 60 fps bin4 or skip4 1-lane @ 800 Mbps/lane
|
||||
- OV02E10
|
||||
- 10 bit RAW Bayer 1920x1088 60 fps 2-lane @ 720 Mbps/lane
|
||||
- 10 bit RAW Bayer 1280x1080 60 fps 2-lane @ 720 Mbps/lane
|
||||
- 10 bit Quad Bayer 960x540 60 fps 2-lane 360 Mbps/lane
|
||||
- 8 bit Quad Bayer 480x270 1/3/5/10 fps sub2 288 Mbps/lane
|
||||
- 8 bit Quad Bayer 232x132 1/3/5/10 fps sub4 144 Mbps/lane
|
||||
- Dynamic defect pixel cancellation
|
||||
- Standard SCCB command interface
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ovti,ov02c10
|
||||
- ovti,ov02e10
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description: Analogue circuit voltage supply.
|
||||
|
||||
dovdd-supply:
|
||||
description: I/O circuit voltage supply.
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital circuit voltage supply.
|
||||
|
||||
reset-gpios:
|
||||
description: Active low GPIO connected to XSHUTDOWN pad of the sensor.
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
link-frequencies: true
|
||||
remote-endpoint: true
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
- remote-endpoint
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ov02e10: camera@10 {
|
||||
compatible = "ovti,ov02e10";
|
||||
reg = <0x10>;
|
||||
|
||||
reset-gpios = <&tlmm 237 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_rgb_defaultt>;
|
||||
|
||||
clocks = <&ov02e10_clk>;
|
||||
|
||||
assigned-clocks = <&ov02e10_clk>;
|
||||
assigned-clock-parents = <&ov02e10_clk_parent>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
avdd-supply = <&vreg_l7b_2p8>;
|
||||
dvdd-supply = <&vreg_l7b_1p8>;
|
||||
dovdd-supply = <&vreg_l3m_1p8>;
|
||||
|
||||
port {
|
||||
ov02e10_ep: endpoint {
|
||||
remote-endpoint = <&csiphy4_ep>;
|
||||
data-lanes = <1 2>;
|
||||
link-frequencies = /bits/ 64 <400000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ov02c10: camera@36 {
|
||||
compatible = "ovti,ov02c10";
|
||||
reg = <0x36>;
|
||||
|
||||
reset-gpios = <&tlmm 237 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_rgb_defaultt>;
|
||||
|
||||
clocks = <&ov02c10_clk>;
|
||||
|
||||
assigned-clocks = <&ov02c10_clk>;
|
||||
assigned-clock-parents = <&ov02c10_clk_parent>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
avdd-supply = <&vreg_l7b_2p8>;
|
||||
dvdd-supply = <&vreg_l7b_1p8>;
|
||||
dovdd-supply = <&vreg_l3m_1p8>;
|
||||
|
||||
port {
|
||||
ov02c10_ep: endpoint {
|
||||
remote-endpoint = <&csiphy4_ep>;
|
||||
data-lanes = <1 2>;
|
||||
link-frequencies = /bits/ 64 <400000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/imx219.yaml#
|
||||
$id: http://devicetree.org/schemas/media/i2c/sony,imx219.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sony 1/4.0-Inch 8Mpixel CMOS Digital Image Sensor
|
|
@ -136,7 +136,7 @@ examples:
|
|||
port {
|
||||
imx290_ep: endpoint {
|
||||
data-lanes = <1 2 3 4>;
|
||||
link-frequencies = /bits/ 64 <445500000>;
|
||||
link-frequencies = /bits/ 64 <222750000 148500000>;
|
||||
remote-endpoint = <&csiphy0_ep>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Sony IMX415 CMOS Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Michael Riesch <michael.riesch@wolfvision.net>
|
||||
- Michael Riesch <michael.riesch@collabora.com>
|
||||
|
||||
description: |-
|
||||
The Sony IMX415 is a diagonal 6.4 mm (Type 1/2.8) CMOS active pixel type
|
||||
|
|
133
Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
Normal file
133
Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
Normal file
|
@ -0,0 +1,133 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright (c) 2025 STMicroelectronics SA.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/st,vd55g1.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics VD55G1 Global Shutter Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Benjamin Mugnier <benjamin.mugnier@foss.st.com>
|
||||
- Sylvain Petinot <sylvain.petinot@foss.st.com>
|
||||
|
||||
description: |-
|
||||
The STMicroelectronics VD55G1 is a global shutter image sensor with an active
|
||||
array size of 804H x 704V. It is programmable through I2C interface. The I2C
|
||||
address is fixed to 0x10.
|
||||
|
||||
Image data is sent through MIPI CSI-2, which is configured as only 1 data
|
||||
lane. The sensor provides 4 GPIOS that can be used for external LED signal
|
||||
(synchronized with sensor integration periods).
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,vd55g1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
vcore-supply:
|
||||
description: Digital core power supply (1.15V)
|
||||
|
||||
vddio-supply:
|
||||
description: Digital IO power supply (1.8V)
|
||||
|
||||
vana-supply:
|
||||
description: Analog power supply (2.8V)
|
||||
|
||||
reset-gpios:
|
||||
description: Sensor reset active low GPIO (XSHUTDOWN)
|
||||
maxItems: 1
|
||||
|
||||
st,leds:
|
||||
description:
|
||||
List sensor's GPIOs used to control strobe light sources during exposure
|
||||
time. The numbers identify the sensor pin on which the illumination
|
||||
system is connected. GPIOs are active-high.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
|
||||
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
|
||||
|
||||
link-frequencies:
|
||||
maxItems: 1
|
||||
items:
|
||||
minimum: 125000000
|
||||
maximum: 600000000
|
||||
|
||||
lane-polarities:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- vcore-supply
|
||||
- vddio-supply
|
||||
- vana-supply
|
||||
- reset-gpios
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera-sensor@10 {
|
||||
compatible = "st,vd55g1";
|
||||
reg = <0x10>;
|
||||
|
||||
clocks = <&camera_clk_12M>;
|
||||
|
||||
vcore-supply = <&camera_vcore_v1v15>;
|
||||
vddio-supply = <&camera_vddio_v1v8>;
|
||||
vana-supply = <&camera_vana_v2v8>;
|
||||
|
||||
reset-gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
|
||||
st,leds = <2>;
|
||||
|
||||
orientation = <2>;
|
||||
rotation = <0>;
|
||||
|
||||
port {
|
||||
endpoint {
|
||||
data-lanes = <1>;
|
||||
link-frequencies = /bits/ 64 <600000000>;
|
||||
remote-endpoint = <&csiphy0_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
139
Documentation/devicetree/bindings/media/i2c/st,vd56g3.yaml
Normal file
139
Documentation/devicetree/bindings/media/i2c/st,vd56g3.yaml
Normal file
|
@ -0,0 +1,139 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright (c) 2024 STMicroelectronics SA.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/st,vd56g3.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics VD56G3 Global Shutter Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Benjamin Mugnier <benjamin.mugnier@foss.st.com>
|
||||
- Sylvain Petinot <sylvain.petinot@foss.st.com>
|
||||
|
||||
description: |-
|
||||
The STMicroelectronics VD56G3 is a 1.5 M pixel global shutter image sensor
|
||||
with an active array size of 1124 x 1364 (portrait orientation). It is
|
||||
programmable through I2C, the address is fixed to 0x10. The sensor output is
|
||||
available via CSI-2, which is configured as either 1 or 2 data lanes. The
|
||||
sensor provides 8 GPIOS that can be used for external LED signal
|
||||
(synchronized with sensor integration periods)
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- st,vd56g3
|
||||
- st,vd66gy
|
||||
description:
|
||||
Two variants are availables; VD56G3 is a monochrome sensor while VD66GY
|
||||
is a colour variant.
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
vcore-supply:
|
||||
description: Digital core power supply (1.15V)
|
||||
|
||||
vddio-supply:
|
||||
description: Digital IO power supply (1.8V)
|
||||
|
||||
vana-supply:
|
||||
description: Analog power supply (2.8V)
|
||||
|
||||
reset-gpios:
|
||||
description: Sensor reset active low GPIO (XSHUTDOWN)
|
||||
maxItems: 1
|
||||
|
||||
st,leds:
|
||||
description:
|
||||
List sensor's GPIOs used to control strobe light sources during exposure
|
||||
time. The numbers identify the sensor pin on which the illumination system
|
||||
is connected. GPIOs are active-high.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum: [1, 2]
|
||||
|
||||
link-frequencies:
|
||||
maxItems: 1
|
||||
items:
|
||||
enum: [402000000, 750000000]
|
||||
|
||||
lane-polarities:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
description: Any lane can be inverted or not.
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- vcore-supply
|
||||
- vddio-supply
|
||||
- vana-supply
|
||||
- reset-gpios
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera-sensor@10 {
|
||||
compatible = "st,vd56g3";
|
||||
reg = <0x10>;
|
||||
|
||||
clocks = <&camera_clk_12M>;
|
||||
|
||||
vcore-supply = <&camera_vcore_v1v15>;
|
||||
vddio-supply = <&camera_vddio_v1v8>;
|
||||
vana-supply = <&camera_vana_v2v8>;
|
||||
|
||||
reset-gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
|
||||
st,leds = <6>;
|
||||
|
||||
orientation = <2>;
|
||||
rotation = <0>;
|
||||
|
||||
port {
|
||||
endpoint {
|
||||
data-lanes = <1 2>;
|
||||
link-frequencies = /bits/ 64 <402000000>;
|
||||
remote-endpoint = <&csiphy0_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -38,6 +38,13 @@ properties:
|
|||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description:
|
||||
The strap I2C address of the serializer. Can be used by the deserializer
|
||||
to communicate over back-channel when the forward-channel is not yet
|
||||
active.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
|
@ -81,51 +88,57 @@ examples:
|
|||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
serializer {
|
||||
compatible = "ti,ds90ub953-q1";
|
||||
link {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
serializer@18 {
|
||||
compatible = "ti,ds90ub953-q1";
|
||||
reg = <0x18>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#clock-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
ub953_in: endpoint {
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
remote-endpoint = <&sensor_out>;
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
ub953_in: endpoint {
|
||||
clock-lanes = <0>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
remote-endpoint = <&sensor_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&deser_fpd_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&deser_fpd_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
sensor@1a {
|
||||
compatible = "sony,imx274";
|
||||
reg = <0x1a>;
|
||||
|
||||
sensor@1a {
|
||||
compatible = "sony,imx274";
|
||||
reg = <0x1a>;
|
||||
reset-gpios = <&serializer 0 GPIO_ACTIVE_LOW>;
|
||||
|
||||
reset-gpios = <&serializer 0 GPIO_ACTIVE_LOW>;
|
||||
clocks = <&serializer>;
|
||||
clock-names = "inck";
|
||||
|
||||
clocks = <&serializer>;
|
||||
clock-names = "inck";
|
||||
|
||||
port {
|
||||
sensor_out: endpoint {
|
||||
remote-endpoint = <&ub953_in>;
|
||||
port {
|
||||
sensor_out: endpoint {
|
||||
remote-endpoint = <&ub953_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -68,6 +68,12 @@ properties:
|
|||
description: The link number
|
||||
maxItems: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
i2c-alias:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
|
@ -107,7 +113,8 @@ properties:
|
|||
maximum: 14
|
||||
description: Manual EQ level
|
||||
|
||||
serializer:
|
||||
patternProperties:
|
||||
'^serializer(@[0-9a-f]+)*$':
|
||||
type: object
|
||||
description: FPD-Link Serializer node
|
||||
|
||||
|
@ -115,7 +122,6 @@ properties:
|
|||
- reg
|
||||
- i2c-alias
|
||||
- ti,rx-mode
|
||||
- serializer
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -309,13 +315,17 @@ examples:
|
|||
/* Link 0 has DS90UB953 serializer and IMX274 sensor */
|
||||
|
||||
link@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
reg = <0>;
|
||||
i2c-alias = <0x44>;
|
||||
|
||||
ti,rx-mode = <3>;
|
||||
|
||||
serializer1: serializer {
|
||||
serializer1: serializer@30 {
|
||||
compatible = "ti,ds90ub953-q1";
|
||||
reg = <0x30>;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
Freescale i.MX Media Video Device
|
||||
=================================
|
||||
|
||||
Video Media Controller node
|
||||
---------------------------
|
||||
|
||||
This is the media controller node for video capture support. It is a
|
||||
virtual device that lists the camera serial interface nodes that the
|
||||
media device will control.
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,imx-capture-subsystem";
|
||||
- ports : Should contain a list of phandles pointing to camera
|
||||
sensor interface ports of IPU devices
|
||||
|
||||
example:
|
||||
|
||||
capture-subsystem {
|
||||
compatible = "fsl,imx-capture-subsystem";
|
||||
ports = <&ipu1_csi0>, <&ipu1_csi1>;
|
||||
};
|
||||
|
||||
|
||||
mipi_csi2 node
|
||||
--------------
|
||||
|
||||
This is the device node for the MIPI CSI-2 Receiver core in the i.MX
|
||||
SoC. This is a Synopsys Designware MIPI CSI-2 host controller core
|
||||
combined with a D-PHY core mixed into the same register block. In
|
||||
addition this device consists of an i.MX-specific "CSI2IPU gasket"
|
||||
glue logic, also controlled from the same register block. The CSI2IPU
|
||||
gasket demultiplexes the four virtual channel streams from the host
|
||||
controller's 32-bit output image bus onto four 16-bit parallel busses
|
||||
to the i.MX IPU CSIs.
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,imx6-mipi-csi2";
|
||||
- reg : physical base address and length of the register set;
|
||||
- clocks : the MIPI CSI-2 receiver requires three clocks: hsi_tx
|
||||
(the D-PHY clock), video_27m (D-PHY PLL reference
|
||||
clock), and eim_podf;
|
||||
- clock-names : must contain "dphy", "ref", "pix";
|
||||
- port@* : five port nodes must exist, containing endpoints
|
||||
connecting to the source and sink devices according to
|
||||
of_graph bindings. The first port is an input port,
|
||||
connecting with a MIPI CSI-2 source, and ports 1
|
||||
through 4 are output ports connecting with parallel
|
||||
bus sink endpoint nodes and correspond to the four
|
||||
MIPI CSI-2 virtual channel outputs.
|
||||
|
||||
Optional properties:
|
||||
- interrupts : must contain two level-triggered interrupts,
|
||||
in order: 100 and 101;
|
|
@ -93,6 +93,10 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -112,6 +116,10 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
|
|
@ -112,6 +112,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -131,6 +136,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -150,6 +160,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
|
|
@ -115,6 +115,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -134,6 +139,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -153,6 +163,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -172,6 +187,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7180-venus
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,qcs615-venus
|
||||
- const: qcom,sc7180-venus
|
||||
- const: qcom,sc7180-venus
|
||||
|
||||
power-domains:
|
||||
minItems: 2
|
||||
|
|
|
@ -143,6 +143,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -166,6 +171,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -189,6 +199,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -212,6 +227,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
|
|
@ -121,6 +121,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -140,6 +145,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -159,6 +169,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -178,6 +193,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
|
|
@ -108,6 +108,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -127,6 +132,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -146,6 +156,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
@ -165,6 +180,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
|
|
|
@ -128,6 +128,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -151,6 +156,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -174,6 +184,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -197,6 +212,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -220,6 +240,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
@ -243,6 +268,11 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
bus-type:
|
||||
enum:
|
||||
- 1 # MEDIA_BUS_TYPE_CSI2_CPHY
|
||||
- 4 # MEDIA_BUS_TYPE_CSI2_DPHY
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
|
|
@ -14,12 +14,17 @@ description:
|
|||
The iris video processing unit is a video encode and decode accelerator
|
||||
present on Qualcomm platforms.
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,venus-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8550-iris
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sa8775p-iris
|
||||
- const: qcom,sm8550-iris
|
||||
- enum:
|
||||
- qcom,qcs8300-iris
|
||||
- qcom,sm8550-iris
|
||||
- qcom,sm8650-iris
|
||||
|
||||
power-domains:
|
||||
maxItems: 4
|
||||
|
@ -49,11 +54,15 @@ properties:
|
|||
- const: video-mem
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: bus
|
||||
- const: xo
|
||||
- const: core
|
||||
|
||||
iommus:
|
||||
maxItems: 2
|
||||
|
@ -75,6 +84,26 @@ required:
|
|||
- iommus
|
||||
- dma-coherent
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,venus-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm8650-iris
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 3
|
||||
reset-names:
|
||||
minItems: 3
|
||||
else:
|
||||
properties:
|
||||
resets:
|
||||
maxItems: 1
|
||||
reset-names:
|
||||
maxItems: 1
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
367
Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml
Normal file
367
Documentation/devicetree/bindings/media/qcom,x1e80100-camss.yaml
Normal file
|
@ -0,0 +1,367 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/qcom,x1e80100-camss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm X1E80100 Camera Subsystem (CAMSS)
|
||||
|
||||
maintainers:
|
||||
- Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
|
||||
description:
|
||||
The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,x1e80100-camss
|
||||
|
||||
reg:
|
||||
maxItems: 17
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csid2
|
||||
- const: csid_lite0
|
||||
- const: csid_lite1
|
||||
- const: csid_wrapper
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csiphy2
|
||||
- const: csiphy4
|
||||
- const: csitpg0
|
||||
- const: csitpg1
|
||||
- const: csitpg2
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
- const: vfe_lite0
|
||||
- const: vfe_lite1
|
||||
|
||||
clocks:
|
||||
maxItems: 29
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: camnoc_nrt_axi
|
||||
- const: camnoc_rt_axi
|
||||
- const: core_ahb
|
||||
- const: cpas_ahb
|
||||
- const: cpas_fast_ahb
|
||||
- const: cpas_vfe0
|
||||
- const: cpas_vfe1
|
||||
- const: cpas_vfe_lite
|
||||
- const: cphy_rx_clk_src
|
||||
- const: csid
|
||||
- const: csid_csiphy_rx
|
||||
- const: csiphy0
|
||||
- const: csiphy0_timer
|
||||
- const: csiphy1
|
||||
- const: csiphy1_timer
|
||||
- const: csiphy2
|
||||
- const: csiphy2_timer
|
||||
- const: csiphy4
|
||||
- const: csiphy4_timer
|
||||
- const: gcc_axi_hf
|
||||
- const: gcc_axi_sf
|
||||
- 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: 13
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: csid0
|
||||
- const: csid1
|
||||
- const: csid2
|
||||
- const: csid_lite0
|
||||
- const: csid_lite1
|
||||
- const: csiphy0
|
||||
- const: csiphy1
|
||||
- const: csiphy2
|
||||
- const: csiphy4
|
||||
- const: vfe0
|
||||
- const: vfe1
|
||||
- const: vfe_lite0
|
||||
- const: vfe_lite1
|
||||
|
||||
interconnects:
|
||||
maxItems: 4
|
||||
|
||||
interconnect-names:
|
||||
items:
|
||||
- const: ahb
|
||||
- const: hf_mnoc
|
||||
- const: sf_mnoc
|
||||
- const: sf_icp_mnoc
|
||||
|
||||
iommus:
|
||||
maxItems: 8
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
|
||||
- description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
|
||||
- description: Titan Top GDSC - Titan ISP Block, Global Distributed Switch Controller.
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: ife0
|
||||
- const: ife1
|
||||
- const: top
|
||||
|
||||
vdd-csiphy-0p8-supply:
|
||||
description:
|
||||
Phandle to a 0.8V regulator supply to a PHY.
|
||||
|
||||
vdd-csiphy-1p2-supply:
|
||||
description:
|
||||
Phandle to 1.8V regulator supply to a PHY.
|
||||
|
||||
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:
|
||||
clock-lanes:
|
||||
maxItems: 1
|
||||
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- clock-lanes
|
||||
- data-lanes
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- interconnects
|
||||
- interconnect-names
|
||||
- iommus
|
||||
- power-domains
|
||||
- power-domain-names
|
||||
- vdd-csiphy-0p8-supply
|
||||
- vdd-csiphy-1p2-supply
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/qcom,x1e80100-gcc.h>
|
||||
#include <dt-bindings/clock/qcom,x1e80100-camcc.h>
|
||||
#include <dt-bindings/interconnect/qcom,icc.h>
|
||||
#include <dt-bindings/interconnect/qcom,x1e80100-rpmh.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
camss: isp@acb6000 {
|
||||
compatible = "qcom,x1e80100-camss";
|
||||
|
||||
reg = <0 0x0acb7000 0 0x2000>,
|
||||
<0 0x0acb9000 0 0x2000>,
|
||||
<0 0x0acbb000 0 0x2000>,
|
||||
<0 0x0acc6000 0 0x1000>,
|
||||
<0 0x0acca000 0 0x1000>,
|
||||
<0 0x0acb6000 0 0x1000>,
|
||||
<0 0x0ace4000 0 0x1000>,
|
||||
<0 0x0ace6000 0 0x1000>,
|
||||
<0 0x0ace8000 0 0x1000>,
|
||||
<0 0x0acec000 0 0x4000>,
|
||||
<0 0x0acf6000 0 0x1000>,
|
||||
<0 0x0acf7000 0 0x1000>,
|
||||
<0 0x0acf8000 0 0x1000>,
|
||||
<0 0x0ac62000 0 0x4000>,
|
||||
<0 0x0ac71000 0 0x4000>,
|
||||
<0 0x0acc7000 0 0x2000>,
|
||||
<0 0x0accb000 0 0x2000>;
|
||||
|
||||
reg-names = "csid0",
|
||||
"csid1",
|
||||
"csid2",
|
||||
"csid_lite0",
|
||||
"csid_lite1",
|
||||
"csid_wrapper",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csiphy2",
|
||||
"csiphy4",
|
||||
"csitpg0",
|
||||
"csitpg1",
|
||||
"csitpg2",
|
||||
"vfe0",
|
||||
"vfe1",
|
||||
"vfe_lite0",
|
||||
"vfe_lite1";
|
||||
|
||||
clocks = <&camcc CAM_CC_CAMNOC_AXI_NRT_CLK>,
|
||||
<&camcc CAM_CC_CAMNOC_AXI_RT_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_0_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_1_CLK>,
|
||||
<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
|
||||
<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
|
||||
<&camcc CAM_CC_CSID_CLK>,
|
||||
<&camcc CAM_CC_CSID_CSIPHY_RX_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_CSIPHY4_CLK>,
|
||||
<&camcc CAM_CC_CSI4PHYTIMER_CLK>,
|
||||
<&gcc GCC_CAMERA_HF_AXI_CLK>,
|
||||
<&gcc GCC_CAMERA_SF_AXI_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_nrt_axi",
|
||||
"camnoc_rt_axi",
|
||||
"core_ahb",
|
||||
"cpas_ahb",
|
||||
"cpas_fast_ahb",
|
||||
"cpas_vfe0",
|
||||
"cpas_vfe1",
|
||||
"cpas_vfe_lite",
|
||||
"cphy_rx_clk_src",
|
||||
"csid",
|
||||
"csid_csiphy_rx",
|
||||
"csiphy0",
|
||||
"csiphy0_timer",
|
||||
"csiphy1",
|
||||
"csiphy1_timer",
|
||||
"csiphy2",
|
||||
"csiphy2_timer",
|
||||
"csiphy4",
|
||||
"csiphy4_timer",
|
||||
"gcc_axi_hf",
|
||||
"gcc_axi_sf",
|
||||
"vfe0",
|
||||
"vfe0_fast_ahb",
|
||||
"vfe1",
|
||||
"vfe1_fast_ahb",
|
||||
"vfe_lite",
|
||||
"vfe_lite_ahb",
|
||||
"vfe_lite_cphy_rx",
|
||||
"vfe_lite_csid";
|
||||
|
||||
interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 431 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 359 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 122 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>;
|
||||
|
||||
interrupt-names = "csid0",
|
||||
"csid1",
|
||||
"csid2",
|
||||
"csid_lite0",
|
||||
"csid_lite1",
|
||||
"csiphy0",
|
||||
"csiphy1",
|
||||
"csiphy2",
|
||||
"csiphy4",
|
||||
"vfe0",
|
||||
"vfe1",
|
||||
"vfe_lite0",
|
||||
"vfe_lite1";
|
||||
|
||||
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>,
|
||||
<&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ALWAYS
|
||||
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
|
||||
<&mmss_noc MASTER_CAMNOC_ICP QCOM_ICC_TAG_ALWAYS
|
||||
&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
|
||||
|
||||
interconnect-names = "ahb",
|
||||
"hf_mnoc",
|
||||
"sf_mnoc",
|
||||
"sf_icp_mnoc";
|
||||
|
||||
iommus = <&apps_smmu 0x800 0x60>,
|
||||
<&apps_smmu 0x860 0x60>,
|
||||
<&apps_smmu 0x1800 0x60>,
|
||||
<&apps_smmu 0x1860 0x60>,
|
||||
<&apps_smmu 0x18e0 0x00>,
|
||||
<&apps_smmu 0x1980 0x20>,
|
||||
<&apps_smmu 0x1900 0x00>,
|
||||
<&apps_smmu 0x19a0 0x20>;
|
||||
|
||||
power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
|
||||
<&camcc CAM_CC_IFE_1_GDSC>,
|
||||
<&camcc CAM_CC_TITAN_TOP_GDSC>;
|
||||
|
||||
power-domain-names = "ife0",
|
||||
"ife1",
|
||||
"top";
|
||||
|
||||
vdd-csiphy-0p8-supply = <&csiphy_0p8_supply>;
|
||||
vdd-csiphy-1p2-supply = <&csiphy_1p2_supply>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
csiphy_ep0: endpoint {
|
||||
clock-lanes = <7>;
|
||||
data-lanes = <0 1>;
|
||||
remote-endpoint = <&sensor_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -30,6 +30,7 @@ properties:
|
|||
- renesas,r9a07g043u-fcpvd # RZ/G2UL
|
||||
- renesas,r9a07g044-fcpvd # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-fcpvd # RZ/V2L
|
||||
- renesas,r9a09g057-fcpvd # RZ/V2H(P)
|
||||
- const: renesas,fcpv # Generic FCP for VSP fallback
|
||||
|
||||
reg:
|
||||
|
@ -66,6 +67,7 @@ allOf:
|
|||
- renesas,r9a07g043u-fcpvd
|
||||
- renesas,r9a07g044-fcpvd
|
||||
- renesas,r9a07g054-fcpvd
|
||||
- renesas,r9a09g057-fcpvd
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
|
|
|
@ -25,19 +25,55 @@ properties:
|
|||
- renesas,r8a779h0-isp # V4M
|
||||
- const: renesas,rcar-gen4-isp # Generic R-Car Gen4
|
||||
reg:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: cs
|
||||
- const: core
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: cs
|
||||
- const: core
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: cs
|
||||
- const: core
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: cs
|
||||
- const: core
|
||||
|
||||
renesas,vspx:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
A phandle to the companion VSPX responsible for the Streaming Bridge
|
||||
functionality. The Streaming Bridge is responsible for feeding image
|
||||
and configuration data to the ISP when operating in memory-to-memory
|
||||
mode.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -103,10 +139,14 @@ properties:
|
|||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
- ports
|
||||
|
||||
additionalProperties: false
|
||||
|
@ -119,11 +159,18 @@ examples:
|
|||
|
||||
isp1: isp@fed20000 {
|
||||
compatible = "renesas,r8a779a0-isp", "renesas,rcar-gen4-isp";
|
||||
reg = <0xfed20000 0x10000>;
|
||||
interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 613>;
|
||||
reg = <0xfed20000 0x10000>, <0xfee00000 0x100000>;
|
||||
reg-names = "cs", "core";
|
||||
interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "cs", "core";
|
||||
clocks = <&cpg CPG_MOD 613>, <&cpg CPG_MOD 17>;
|
||||
clock-names = "cs", "core";
|
||||
power-domains = <&sysc R8A779A0_PD_A3ISP01>;
|
||||
resets = <&cpg 613>;
|
||||
resets = <&cpg 613>, <&cpg 17>;
|
||||
reset-names = "cs", "core";
|
||||
|
||||
renesas,vspx = <&vspx1>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
|
|
|
@ -17,24 +17,43 @@ description:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-cru # RZ/G2UL
|
||||
- renesas,r9a07g044-cru # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-cru # RZ/V2L
|
||||
- const: renesas,rzg2l-cru
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-cru # RZ/G2UL
|
||||
- renesas,r9a07g044-cru # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-cru # RZ/V2L
|
||||
- const: renesas,rzg2l-cru
|
||||
- const: renesas,r9a09g047-cru # RZ/G3E
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
oneOf:
|
||||
- items:
|
||||
- description: CRU Interrupt for image_conv
|
||||
- description: CRU Interrupt for image_conv_err
|
||||
- description: CRU AXI master error interrupt
|
||||
- items:
|
||||
- description: CRU Interrupt for image_conv
|
||||
- description: CRU AXI master error interrupt
|
||||
- description: CRU Video Data AXI Master Address 0 Write End interrupt
|
||||
- description: CRU Statistics data AXI master addr 0 write end interrupt
|
||||
- description: CRU Video statistics data AXI master addr 0 write end interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: image_conv
|
||||
- const: image_conv_err
|
||||
- const: axi_mst_err
|
||||
oneOf:
|
||||
- items:
|
||||
- const: image_conv
|
||||
- const: image_conv_err
|
||||
- const: axi_mst_err
|
||||
- items:
|
||||
- const: image_conv
|
||||
- const: axi_mst_err
|
||||
- const: vd_addr_wend
|
||||
- const: sd_addr_wend
|
||||
- const: vsd_addr_wend
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
@ -109,6 +128,10 @@ allOf:
|
|||
- renesas,r9a07g054-cru
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
interrupt-names:
|
||||
maxItems: 3
|
||||
ports:
|
||||
required:
|
||||
- port@0
|
||||
|
@ -122,10 +145,30 @@ allOf:
|
|||
- renesas,r9a07g043-cru
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
interrupt-names:
|
||||
maxItems: 3
|
||||
ports:
|
||||
properties:
|
||||
port@0: false
|
||||
required:
|
||||
- port@1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,r9a09g047-cru
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 5
|
||||
interrupt-names:
|
||||
minItems: 5
|
||||
ports:
|
||||
properties:
|
||||
port@0: false
|
||||
required:
|
||||
- port@1
|
||||
|
||||
|
|
|
@ -17,12 +17,17 @@ description:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-csi2 # RZ/G2UL
|
||||
- renesas,r9a07g044-csi2 # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-csi2 # RZ/V2L
|
||||
- const: renesas,rzg2l-csi2
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-csi2 # RZ/G2UL
|
||||
- renesas,r9a07g044-csi2 # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-csi2 # RZ/V2L
|
||||
- const: renesas,rzg2l-csi2
|
||||
- items:
|
||||
- const: renesas,r9a09g047-csi2 # RZ/G3E
|
||||
- const: renesas,r9a09g057-csi2
|
||||
- const: renesas,r9a09g057-csi2 # RZ/V2H(P)
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -31,16 +36,24 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Internal clock for connecting CRU and MIPI
|
||||
- description: CRU Main clock
|
||||
- description: CRU Register access clock
|
||||
oneOf:
|
||||
- items:
|
||||
- description: Internal clock for connecting CRU and MIPI
|
||||
- description: CRU Main clock
|
||||
- description: CRU Register access clock
|
||||
- items:
|
||||
- description: CRU Main clock
|
||||
- description: CRU Register access clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: system
|
||||
- const: video
|
||||
- const: apb
|
||||
oneOf:
|
||||
- items:
|
||||
- const: system
|
||||
- const: video
|
||||
- const: apb
|
||||
- items:
|
||||
- const: video
|
||||
- const: apb
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
@ -48,7 +61,7 @@ properties:
|
|||
resets:
|
||||
items:
|
||||
- description: CRU_PRESETN reset terminal
|
||||
- description: CRU_CMN_RSTB reset terminal
|
||||
- description: D-PHY reset (CRU_CMN_RSTB or CRU_n_S_RESETN)
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
|
@ -101,6 +114,25 @@ required:
|
|||
- reset-names
|
||||
- ports
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,r9a09g057-csi2
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 2
|
||||
clock-names:
|
||||
maxItems: 2
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 3
|
||||
clock-names:
|
||||
minItems: 3
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
@ -25,6 +25,7 @@ properties:
|
|||
- enum:
|
||||
- renesas,r9a07g043u-vsp2 # RZ/G2UL
|
||||
- renesas,r9a07g054-vsp2 # RZ/V2L
|
||||
- renesas,r9a09g057-vsp2 # RZ/V2H(P)
|
||||
- const: renesas,r9a07g044-vsp2 # RZ/G2L fallback
|
||||
|
||||
reg:
|
||||
|
|
|
@ -12,6 +12,7 @@ These formats are used for the :ref:`metadata` interface only.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
metafmt-c3-isp
|
||||
metafmt-d4xx
|
||||
metafmt-generic
|
||||
metafmt-intel-ipu3
|
||||
|
|
86
Documentation/userspace-api/media/v4l/metafmt-c3-isp.rst
Normal file
86
Documentation/userspace-api/media/v4l/metafmt-c3-isp.rst
Normal file
|
@ -0,0 +1,86 @@
|
|||
.. SPDX-License-Identifier: (GPL-2.0-only OR MIT)
|
||||
|
||||
.. _v4l2-meta-fmt-c3isp-stats:
|
||||
.. _v4l2-meta-fmt-c3isp-params:
|
||||
|
||||
***********************************************************************
|
||||
V4L2_META_FMT_C3ISP_STATS ('C3ST'), V4L2_META_FMT_C3ISP_PARAMS ('C3PM')
|
||||
***********************************************************************
|
||||
|
||||
.. c3_isp_stats_info
|
||||
|
||||
3A Statistics
|
||||
=============
|
||||
|
||||
The C3 ISP can collect different statistics over an input Bayer frame.
|
||||
Those statistics are obtained from the "c3-isp-stats" metadata capture video nodes,
|
||||
using the :c:type:`v4l2_meta_format` interface.
|
||||
They are formatted as described by the :c:type:`c3_isp_stats_info` structure.
|
||||
|
||||
The statistics collected are Auto-white balance,
|
||||
Auto-exposure and Auto-focus information.
|
||||
|
||||
.. c3_isp_params_cfg
|
||||
|
||||
Configuration Parameters
|
||||
========================
|
||||
|
||||
The configuration parameters are passed to the c3-isp-params metadata output video node,
|
||||
using the :c:type:`v4l2_meta_format` interface. Rather than a single struct containing
|
||||
sub-structs for each configurable area of the ISP, parameters for the C3-ISP
|
||||
are defined as distinct structs or "blocks" which may be added to the data
|
||||
member of :c:type:`c3_isp_params_cfg`. Userspace is responsible for
|
||||
populating the data member with the blocks that need to be configured by the driver, but
|
||||
need not populate it with **all** the blocks, or indeed with any at all if there
|
||||
are no configuration changes to make. Populated blocks **must** be consecutive
|
||||
in the buffer. To assist both userspace and the driver in identifying the
|
||||
blocks each block-specific struct embeds
|
||||
:c:type:`c3_isp_params_block_header` as its first member and userspace
|
||||
must populate the type member with a value from
|
||||
:c:type:`c3_isp_params_block_type`. Once the blocks have been populated
|
||||
into the data buffer, the combined size of all populated blocks shall be set in
|
||||
the data_size member of :c:type:`c3_isp_params_cfg`. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct c3_isp_params_cfg *params =
|
||||
(struct c3_isp_params_cfg *)buffer;
|
||||
|
||||
params->version = C3_ISP_PARAM_BUFFER_V0;
|
||||
params->data_size = 0;
|
||||
|
||||
void *data = (void *)params->data;
|
||||
|
||||
struct c3_isp_params_awb_gains *gains =
|
||||
(struct c3_isp_params_awb_gains *)data;
|
||||
|
||||
gains->header.type = C3_ISP_PARAMS_BLOCK_AWB_GAINS;
|
||||
gains->header.flags = C3_ISP_PARAMS_BLOCK_FL_ENABLE;
|
||||
gains->header.size = sizeof(struct c3_isp_params_awb_gains);
|
||||
|
||||
gains->gr_gain = 256;
|
||||
gains->r_gain = 256;
|
||||
gains->b_gain = 256;
|
||||
gains->gb_gain = 256;
|
||||
|
||||
data += sizeof(struct c3_isp__params_awb_gains);
|
||||
params->data_size += sizeof(struct c3_isp_params_awb_gains);
|
||||
|
||||
struct c3_isp_params_awb_config *awb_cfg =
|
||||
(struct c3_isp_params_awb_config *)data;
|
||||
|
||||
awb_cfg->header.type = C3_ISP_PARAMS_BLOCK_AWB_CONFIG;
|
||||
awb_cfg->header.flags = C3_ISP_PARAMS_BLOCK_FL_ENABLE;
|
||||
awb_cfg->header.size = sizeof(struct c3_isp_params_awb_config);
|
||||
|
||||
awb_cfg->tap_point = C3_ISP_AWB_STATS_TAP_BEFORE_WB;
|
||||
awb_cfg->satur = 1;
|
||||
awb_cfg->horiz_zones_num = 32;
|
||||
awb_cfg->vert_zones_num = 24;
|
||||
|
||||
params->data_size += sizeof(struct c3_isp_params_awb_config);
|
||||
|
||||
Amlogic C3 ISP uAPI data types
|
||||
===============================
|
||||
|
||||
.. kernel-doc:: include/uapi/linux/media/amlogic/c3-isp-config.h
|
|
@ -137,6 +137,13 @@ All components are stored with the same number of bits per component.
|
|||
- Cb, Cr
|
||||
- No
|
||||
- Linear
|
||||
* - V4L2_PIX_FMT_NV15
|
||||
- 'NV15'
|
||||
- 10
|
||||
- 4:2:0
|
||||
- Cb, Cr
|
||||
- Yes
|
||||
- Linear
|
||||
* - V4L2_PIX_FMT_NV15_4L4
|
||||
- 'VT15'
|
||||
- 15
|
||||
|
@ -186,6 +193,13 @@ All components are stored with the same number of bits per component.
|
|||
- Cr, Cb
|
||||
- No
|
||||
- Linear
|
||||
* - V4L2_PIX_FMT_NV20
|
||||
- 'NV20'
|
||||
- 10
|
||||
- 4:2:2
|
||||
- Cb, Cr
|
||||
- Yes
|
||||
- Linear
|
||||
* - V4L2_PIX_FMT_NV24
|
||||
- 'NV24'
|
||||
- 8
|
||||
|
@ -302,6 +316,57 @@ of the luma plane.
|
|||
- Cr\ :sub:`11`
|
||||
|
||||
|
||||
.. _V4L2-PIX-FMT-NV15:
|
||||
|
||||
NV15
|
||||
----
|
||||
|
||||
Semi-planar 10-bit YUV 4:2:0 format similar to NV12, using 10-bit components
|
||||
with no padding between each component. A group of 4 components are stored over
|
||||
5 bytes in little endian order.
|
||||
|
||||
.. flat-table:: Sample 4x4 NV15 Image (1 byte per cell)
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
|
||||
* - start + 0:
|
||||
- Y'\ :sub:`00[7:0]`
|
||||
- Y'\ :sub:`01[5:0]`\ Y'\ :sub:`00[9:8]`
|
||||
- Y'\ :sub:`02[3:0]`\ Y'\ :sub:`01[9:6]`
|
||||
- Y'\ :sub:`03[1:0]`\ Y'\ :sub:`02[9:4]`
|
||||
- Y'\ :sub:`03[9:2]`
|
||||
* - start + 5:
|
||||
- Y'\ :sub:`10[7:0]`
|
||||
- Y'\ :sub:`11[5:0]`\ Y'\ :sub:`10[9:8]`
|
||||
- Y'\ :sub:`12[3:0]`\ Y'\ :sub:`11[9:6]`
|
||||
- Y'\ :sub:`13[1:0]`\ Y'\ :sub:`12[9:4]`
|
||||
- Y'\ :sub:`13[9:2]`
|
||||
* - start + 10:
|
||||
- Y'\ :sub:`20[7:0]`
|
||||
- Y'\ :sub:`21[5:0]`\ Y'\ :sub:`20[9:8]`
|
||||
- Y'\ :sub:`22[3:0]`\ Y'\ :sub:`21[9:6]`
|
||||
- Y'\ :sub:`23[1:0]`\ Y'\ :sub:`22[9:4]`
|
||||
- Y'\ :sub:`23[9:2]`
|
||||
* - start + 15:
|
||||
- Y'\ :sub:`30[7:0]`
|
||||
- Y'\ :sub:`31[5:0]`\ Y'\ :sub:`30[9:8]`
|
||||
- Y'\ :sub:`32[3:0]`\ Y'\ :sub:`31[9:6]`
|
||||
- Y'\ :sub:`33[1:0]`\ Y'\ :sub:`32[9:4]`
|
||||
- Y'\ :sub:`33[9:2]`
|
||||
* - start + 20:
|
||||
- Cb\ :sub:`00[7:0]`
|
||||
- Cr\ :sub:`00[5:0]`\ Cb\ :sub:`00[9:8]`
|
||||
- Cb\ :sub:`01[3:0]`\ Cr\ :sub:`00[9:6]`
|
||||
- Cr\ :sub:`01[1:0]`\ Cb\ :sub:`01[9:4]`
|
||||
- Cr\ :sub:`01[9:2]`
|
||||
* - start + 25:
|
||||
- Cb\ :sub:`10[7:0]`
|
||||
- Cr\ :sub:`10[5:0]`\ Cb\ :sub:`10[9:8]`
|
||||
- Cb\ :sub:`11[3:0]`\ Cr\ :sub:`10[9:6]`
|
||||
- Cr\ :sub:`11[1:0]`\ Cb\ :sub:`11[9:4]`
|
||||
- Cr\ :sub:`11[9:2]`
|
||||
|
||||
|
||||
.. _V4L2-PIX-FMT-NV12MT:
|
||||
.. _V4L2-PIX-FMT-NV12MT-16X16:
|
||||
.. _V4L2-PIX-FMT-NV12-4L4:
|
||||
|
@ -631,6 +696,69 @@ number of lines as the luma plane.
|
|||
- Cr\ :sub:`32`
|
||||
|
||||
|
||||
.. _V4L2-PIX-FMT-NV20:
|
||||
|
||||
NV20
|
||||
----
|
||||
|
||||
Semi-planar 10-bit YUV 4:2:2 format similar to NV16, using 10-bit components
|
||||
with no padding between each component. A group of 4 components are stored over
|
||||
5 bytes in little endian order.
|
||||
|
||||
.. flat-table:: Sample 4x4 NV20 Image (1 byte per cell)
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
|
||||
* - start + 0:
|
||||
- Y'\ :sub:`00[7:0]`
|
||||
- Y'\ :sub:`01[5:0]`\ Y'\ :sub:`00[9:8]`
|
||||
- Y'\ :sub:`02[3:0]`\ Y'\ :sub:`01[9:6]`
|
||||
- Y'\ :sub:`03[1:0]`\ Y'\ :sub:`02[9:4]`
|
||||
- Y'\ :sub:`03[9:2]`
|
||||
* - start + 5:
|
||||
- Y'\ :sub:`10[7:0]`
|
||||
- Y'\ :sub:`11[5:0]`\ Y'\ :sub:`10[9:8]`
|
||||
- Y'\ :sub:`12[3:0]`\ Y'\ :sub:`11[9:6]`
|
||||
- Y'\ :sub:`13[1:0]`\ Y'\ :sub:`12[9:4]`
|
||||
- Y'\ :sub:`13[9:2]`
|
||||
* - start + 10:
|
||||
- Y'\ :sub:`20[7:0]`
|
||||
- Y'\ :sub:`21[5:0]`\ Y'\ :sub:`20[9:8]`
|
||||
- Y'\ :sub:`22[3:0]`\ Y'\ :sub:`21[9:6]`
|
||||
- Y'\ :sub:`23[1:0]`\ Y'\ :sub:`22[9:4]`
|
||||
- Y'\ :sub:`23[9:2]`
|
||||
* - start + 15:
|
||||
- Y'\ :sub:`30[7:0]`
|
||||
- Y'\ :sub:`31[5:0]`\ Y'\ :sub:`30[9:8]`
|
||||
- Y'\ :sub:`32[3:0]`\ Y'\ :sub:`31[9:6]`
|
||||
- Y'\ :sub:`33[1:0]`\ Y'\ :sub:`32[9:4]`
|
||||
- Y'\ :sub:`33[9:2]`
|
||||
* - start + 20:
|
||||
- Cb\ :sub:`00[7:0]`
|
||||
- Cr\ :sub:`00[5:0]`\ Cb\ :sub:`00[9:8]`
|
||||
- Cb\ :sub:`01[3:0]`\ Cr\ :sub:`00[9:6]`
|
||||
- Cr\ :sub:`01[1:0]`\ Cb\ :sub:`01[9:4]`
|
||||
- Cr\ :sub:`01[9:2]`
|
||||
* - start + 25:
|
||||
- Cb\ :sub:`10[7:0]`
|
||||
- Cr\ :sub:`10[5:0]`\ Cb\ :sub:`10[9:8]`
|
||||
- Cb\ :sub:`11[3:0]`\ Cr\ :sub:`10[9:6]`
|
||||
- Cr\ :sub:`11[1:0]`\ Cb\ :sub:`11[9:4]`
|
||||
- Cr\ :sub:`11[9:2]`
|
||||
* - start + 30:
|
||||
- Cb\ :sub:`20[7:0]`
|
||||
- Cr\ :sub:`20[5:0]`\ Cb\ :sub:`20[9:8]`
|
||||
- Cb\ :sub:`21[3:0]`\ Cr\ :sub:`20[9:6]`
|
||||
- Cr\ :sub:`21[1:0]`\ Cb\ :sub:`21[9:4]`
|
||||
- Cr\ :sub:`21[9:2]`
|
||||
* - start + 35:
|
||||
- Cb\ :sub:`30[7:0]`
|
||||
- Cr\ :sub:`30[5:0]`\ Cb\ :sub:`30[9:8]`
|
||||
- Cb\ :sub:`31[3:0]`\ Cr\ :sub:`30[9:6]`
|
||||
- Cr\ :sub:`31[1:0]`\ Cb\ :sub:`31[9:4]`
|
||||
- Cr\ :sub:`31[9:2]`
|
||||
|
||||
|
||||
.. _V4L2-PIX-FMT-NV24:
|
||||
.. _V4L2-PIX-FMT-NV42:
|
||||
|
||||
|
|
96
MAINTAINERS
96
MAINTAINERS
|
@ -528,6 +528,7 @@ ADP1653 FLASH CONTROLLER DRIVER
|
|||
M: Sakari Ailus <sakari.ailus@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/adi,adp1653.txt
|
||||
F: drivers/media/i2c/adp1653.c
|
||||
F: include/media/i2c/adp1653.h
|
||||
|
||||
|
@ -1255,6 +1256,31 @@ F: Documentation/devicetree/bindings/perf/amlogic,g12-ddr-pmu.yaml
|
|||
F: drivers/perf/amlogic/
|
||||
F: include/soc/amlogic/
|
||||
|
||||
AMLOGIC ISP DRIVER
|
||||
M: Keke Li <keke.li@amlogic.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/admin-guide/media/c3-isp.dot
|
||||
F: Documentation/admin-guide/media/c3-isp.rst
|
||||
F: Documentation/devicetree/bindings/media/amlogic,c3-isp.yaml
|
||||
F: Documentation/userspace-api/media/v4l/metafmt-c3-isp.rst
|
||||
F: drivers/media/platform/amlogic/c3/isp/
|
||||
F: include/uapi/linux/media/amlogic/
|
||||
|
||||
AMLOGIC MIPI ADAPTER DRIVER
|
||||
M: Keke Li <keke.li@amlogic.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/amlogic,c3-mipi-adapter.yaml
|
||||
F: drivers/media/platform/amlogic/c3/mipi-adapter/
|
||||
|
||||
AMLOGIC MIPI CSI2 DRIVER
|
||||
M: Keke Li <keke.li@amlogic.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/amlogic,c3-mipi-csi2.yaml
|
||||
F: drivers/media/platform/amlogic/c3/mipi-csi2/
|
||||
|
||||
AMLOGIC PINCTRL DRIVER
|
||||
M: Xianwei Zhao <xianwei.zhao@amlogic.com>
|
||||
L: linux-amlogic@lists.infradead.org
|
||||
|
@ -1596,14 +1622,14 @@ M: Lars-Peter Clausen <lars@metafoo.de>
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/media/i2c/adv7180.yaml
|
||||
F: Documentation/devicetree/bindings/media/i2c/adi,adv7180.yaml
|
||||
F: drivers/media/i2c/adv7180.c
|
||||
|
||||
ANALOG DEVICES INC ADV748X DRIVER
|
||||
M: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/adv748x.yaml
|
||||
F: Documentation/devicetree/bindings/media/i2c/adi,adv748x.yaml
|
||||
F: drivers/media/i2c/adv748x/*
|
||||
|
||||
ANALOG DEVICES INC ADV7511 DRIVER
|
||||
|
@ -1616,7 +1642,7 @@ ANALOG DEVICES INC ADV7604 DRIVER
|
|||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/adv7604.yaml
|
||||
F: Documentation/devicetree/bindings/media/i2c/adi,adv7604.yaml
|
||||
F: drivers/media/i2c/adv7604*
|
||||
|
||||
ANALOG DEVICES INC ADV7842 DRIVER
|
||||
|
@ -14519,7 +14545,7 @@ M: Ramesh Shanmugasundaram <rashanmu@gmail.com>
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/max2175.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/maxim,max2175.txt
|
||||
F: Documentation/userspace-api/media/drivers/max2175.rst
|
||||
F: drivers/media/i2c/max2175*
|
||||
F: include/uapi/linux/max2175.h
|
||||
|
@ -14856,7 +14882,7 @@ L: linux-media@vger.kernel.org
|
|||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/admin-guide/media/imx.rst
|
||||
F: Documentation/devicetree/bindings/media/imx.txt
|
||||
F: Documentation/devicetree/bindings/media/fsl,imx6-mipi-csi2.yaml
|
||||
F: drivers/staging/media/imx/
|
||||
F: include/linux/imx-media.h
|
||||
F: include/media/imx.h
|
||||
|
@ -14977,7 +15003,7 @@ F: Documentation/devicetree/bindings/media/renesas,csi2.yaml
|
|||
F: Documentation/devicetree/bindings/media/renesas,isp.yaml
|
||||
F: Documentation/devicetree/bindings/media/renesas,vin.yaml
|
||||
F: drivers/media/platform/renesas/rcar-csi2.c
|
||||
F: drivers/media/platform/renesas/rcar-isp.c
|
||||
F: drivers/media/platform/renesas/rcar-isp/
|
||||
F: drivers/media/platform/renesas/rcar-vin/
|
||||
|
||||
MEDIA DRIVERS FOR RENESAS - VSP1
|
||||
|
@ -16740,7 +16766,7 @@ M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/mt9v032.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/aptina,mt9v032.txt
|
||||
F: drivers/media/i2c/mt9v032.c
|
||||
F: include/media/i2c/mt9v032.h
|
||||
|
||||
|
@ -17463,6 +17489,7 @@ M: Pavel Machek <pavel@kernel.org>
|
|||
M: Sakari Ailus <sakari.ailus@iki.fi>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/adi,ad5820.yaml
|
||||
F: drivers/media/i2c/ad5820.c
|
||||
F: drivers/media/i2c/et8ek8
|
||||
|
||||
|
@ -18058,6 +18085,23 @@ T: git git://linuxtv.org/media.git
|
|||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov02a10.yaml
|
||||
F: drivers/media/i2c/ov02a10.c
|
||||
|
||||
OMNIVISION OV02C10 SENSOR DRIVER
|
||||
M: Hans de Goede <hansg@kernel.org>
|
||||
R: Bryan O'Donoghue <bod@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: drivers/media/i2c/ov02c10.c
|
||||
|
||||
OMNIVISION OV02E10 SENSOR DRIVER
|
||||
M: Bryan O'Donoghue <bod@kernel.org>
|
||||
M: Hans de Goede <hansg@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov02e10.yaml
|
||||
F: drivers/media/i2c/ov02e10.c
|
||||
|
||||
OMNIVISION OV08D10 SENSOR DRIVER
|
||||
M: Jimmy Su <jimmy.su@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -18180,7 +18224,7 @@ OMNIVISION OV7670 SENSOR DRIVER
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Orphan
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ov7670.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov7670.txt
|
||||
F: drivers/media/i2c/ov7670.c
|
||||
|
||||
OMNIVISION OV772x SENSOR DRIVER
|
||||
|
@ -18196,7 +18240,7 @@ OMNIVISION OV7740 SENSOR DRIVER
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Orphan
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ov7740.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov7740.txt
|
||||
F: drivers/media/i2c/ov7740.c
|
||||
|
||||
OMNIVISION OV8856 SENSOR DRIVER
|
||||
|
@ -18237,7 +18281,7 @@ R: Sylwester Nawrocki <s.nawrocki@samsung.com>
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ov9650.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov9650.txt
|
||||
F: drivers/media/i2c/ov9650.c
|
||||
|
||||
OMNIVISION OV9734 SENSOR DRIVER
|
||||
|
@ -18442,6 +18486,7 @@ S: Maintained
|
|||
W: https://linuxtv.org
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
T: git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov2659.txt
|
||||
F: drivers/media/i2c/ov2659.c
|
||||
F: include/media/i2c/ov2659.h
|
||||
|
||||
|
@ -20232,6 +20277,7 @@ QUALCOMM IRIS VIDEO ACCELERATOR DRIVER
|
|||
M: Vikash Garodia <quic_vgarodia@quicinc.com>
|
||||
M: Dikshita Agarwal <quic_dikshita@quicinc.com>
|
||||
R: Abhinav Kumar <quic_abhinavk@quicinc.com>
|
||||
R: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -20293,8 +20339,8 @@ F: Documentation/devicetree/bindings/usb/qcom,pmic-*.yaml
|
|||
F: drivers/usb/typec/tcpm/qcom/
|
||||
|
||||
QUALCOMM VENUS VIDEO ACCELERATOR DRIVER
|
||||
M: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>
|
||||
M: Vikash Garodia <quic_vgarodia@quicinc.com>
|
||||
M: Dikshita Agarwal <quic_dikshita@quicinc.com>
|
||||
R: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
|
@ -22756,7 +22802,7 @@ M: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/imx219.yaml
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx219.yaml
|
||||
F: drivers/media/i2c/imx219.c
|
||||
|
||||
SONY IMX258 SENSOR DRIVER
|
||||
|
@ -22816,8 +22862,9 @@ F: Documentation/devicetree/bindings/media/i2c/sony,imx334.yaml
|
|||
F: drivers/media/i2c/imx334.c
|
||||
|
||||
SONY IMX335 SENSOR DRIVER
|
||||
M: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Orphan
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
|
||||
F: drivers/media/i2c/imx335.c
|
||||
|
@ -22837,7 +22884,7 @@ F: Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
|
|||
F: drivers/media/i2c/imx412.c
|
||||
|
||||
SONY IMX415 SENSOR DRIVER
|
||||
M: Michael Riesch <michael.riesch@wolfvision.net>
|
||||
M: Michael Riesch <michael.riesch@collabora.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media.git
|
||||
|
@ -23174,6 +23221,22 @@ S: Maintained
|
|||
F: Documentation/hwmon/stpddc60.rst
|
||||
F: drivers/hwmon/pmbus/stpddc60.c
|
||||
|
||||
ST VD55G1 DRIVER
|
||||
M: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
|
||||
M: Sylvain Petinot <sylvain.petinot@foss.st.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
|
||||
F: drivers/media/i2c/vd55g1.c
|
||||
|
||||
ST VD56G3 IMAGE SENSOR DRIVER
|
||||
M: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
|
||||
M: Sylvain Petinot <sylvain.petinot@foss.st.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/st,vd56g3.yaml
|
||||
F: drivers/media/i2c/vd56g3.c
|
||||
|
||||
ST VGXY61 DRIVER
|
||||
M: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
|
||||
M: Sylvain Petinot <sylvain.petinot@foss.st.com>
|
||||
|
@ -23893,6 +23956,7 @@ L: linux-media@vger.kernel.org
|
|||
S: Maintained
|
||||
W: https://linuxtv.org
|
||||
Q: http://patchwork.linuxtv.org/project/linux-media/list/
|
||||
F: Documentation/devicetree/bindings/media/i2c/nxp,tda1997x.txt
|
||||
F: drivers/media/i2c/tda1997x.*
|
||||
|
||||
TDA827x MEDIA DRIVER
|
||||
|
@ -24736,7 +24800,7 @@ TOSHIBA TC358743 DRIVER
|
|||
M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/i2c/tc358743.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/toshiba,tc358743.txt
|
||||
F: drivers/media/i2c/tc358743*
|
||||
F: include/media/i2c/tc358743.h
|
||||
|
||||
|
@ -25578,6 +25642,8 @@ F: drivers/media/i2c/mt*
|
|||
F: drivers/media/i2c/og*
|
||||
F: drivers/media/i2c/ov*
|
||||
F: drivers/media/i2c/s5*
|
||||
F: drivers/media/i2c/vd55g1.c
|
||||
F: drivers/media/i2c/vd56g3.c
|
||||
F: drivers/media/i2c/vgxy61.c
|
||||
|
||||
VF610 NAND DRIVER
|
||||
|
|
|
@ -298,6 +298,7 @@ struct cec_dmi_match {
|
|||
static const char *const port_b_conns[] = { "Port B", NULL };
|
||||
static const char *const port_db_conns[] = { "Port D", "Port B", NULL };
|
||||
static const char *const port_ba_conns[] = { "Port B", "Port A", NULL };
|
||||
static const char *const port_ab_conns[] = { "Port A", "Port B", NULL };
|
||||
static const char *const port_d_conns[] = { "Port D", NULL };
|
||||
|
||||
static const struct cec_dmi_match cec_dmi_match_table[] = {
|
||||
|
@ -329,6 +330,10 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
|
|||
{ "Google", "Dexi", "0000:00:02.0", port_db_conns },
|
||||
/* Google Dita */
|
||||
{ "Google", "Dita", "0000:00:02.0", port_db_conns },
|
||||
/* Google Dirks */
|
||||
{ "Google", "Dirks", "0000:00:02.0", port_ab_conns },
|
||||
/* Google Moxie */
|
||||
{ "Google", "Moxie", "0000:00:02.0", port_b_conns },
|
||||
};
|
||||
|
||||
static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
|
||||
|
|
|
@ -1002,8 +1002,8 @@ static int extron_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
|
|||
u32 signal_free_time, struct cec_msg *msg)
|
||||
{
|
||||
struct extron_port *port = cec_get_drvdata(adap);
|
||||
char buf[CEC_MAX_MSG_SIZE * 3 + 1];
|
||||
char cmd[CEC_MAX_MSG_SIZE * 3 + 13];
|
||||
char buf[(CEC_MAX_MSG_SIZE - 1) * 3 + 1];
|
||||
char cmd[sizeof(buf) + 14];
|
||||
unsigned int i;
|
||||
|
||||
if (port->disconnected)
|
||||
|
|
|
@ -469,7 +469,7 @@ vb2_dma_sg_dmabuf_ops_begin_cpu_access(struct dma_buf *dbuf,
|
|||
struct vb2_dma_sg_buf *buf = dbuf->priv;
|
||||
struct sg_table *sgt = buf->dma_sgt;
|
||||
|
||||
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
|
||||
dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -480,7 +480,7 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf,
|
|||
struct vb2_dma_sg_buf *buf = dbuf->priv;
|
||||
struct sg_table *sgt = buf->dma_sgt;
|
||||
|
||||
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
|
||||
dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -903,6 +903,11 @@ EXPORT_SYMBOL_GPL(vb2_expbuf);
|
|||
|
||||
int vb2_queue_init_name(struct vb2_queue *q, const char *name)
|
||||
{
|
||||
/* vb2_memory should match with v4l2_memory */
|
||||
BUILD_BUG_ON(VB2_MEMORY_MMAP != (int)V4L2_MEMORY_MMAP);
|
||||
BUILD_BUG_ON(VB2_MEMORY_USERPTR != (int)V4L2_MEMORY_USERPTR);
|
||||
BUILD_BUG_ON(VB2_MEMORY_DMABUF != (int)V4L2_MEMORY_DMABUF);
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
|
@ -916,12 +921,6 @@ int vb2_queue_init_name(struct vb2_queue *q, const char *name)
|
|||
WARN_ON((q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) ==
|
||||
V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN);
|
||||
|
||||
/* Warn that vb2_memory should match with v4l2_memory */
|
||||
if (WARN_ON(VB2_MEMORY_MMAP != (int)V4L2_MEMORY_MMAP)
|
||||
|| WARN_ON(VB2_MEMORY_USERPTR != (int)V4L2_MEMORY_USERPTR)
|
||||
|| WARN_ON(VB2_MEMORY_DMABUF != (int)V4L2_MEMORY_DMABUF))
|
||||
return -EINVAL;
|
||||
|
||||
if (q->buf_struct_size == 0)
|
||||
q->buf_struct_size = sizeof(struct vb2_v4l2_buffer);
|
||||
|
||||
|
|
|
@ -2630,7 +2630,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
|
|||
dib7090_configMpegMux(state, 3, 1, 1);
|
||||
dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
|
||||
} else {/* Use Smooth block */
|
||||
dprintk("setting output mode TS_SERIAL using Smooth bloc\n");
|
||||
dprintk("setting output mode TS_SERIAL using Smooth block\n");
|
||||
dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
|
||||
outreg |= (2<<6) | (0 << 1);
|
||||
}
|
||||
|
@ -2654,7 +2654,7 @@ static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
|
|||
outreg |= (1<<6);
|
||||
break;
|
||||
|
||||
case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
|
||||
case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux block */
|
||||
dprintk("setting output mode TS_FIFO using Smooth block\n");
|
||||
dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
|
||||
outreg |= (5<<6);
|
||||
|
|
|
@ -1584,7 +1584,7 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
|
|||
dib8096p_configMpegMux(state, 3, 1, 1);
|
||||
dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
|
||||
} else {/* Use Smooth block */
|
||||
dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc\n");
|
||||
dprintk("dib8096P setting output mode TS_SERIAL using Smooth block\n");
|
||||
dib8096p_setHostBusMux(state,
|
||||
DEMOUT_ON_HOSTBUS);
|
||||
outreg |= (2 << 6) | (0 << 1);
|
||||
|
@ -1612,7 +1612,8 @@ static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
|
|||
|
||||
case OUTMODE_MPEG2_FIFO:
|
||||
/* Using Smooth block because not supported
|
||||
by new Mpeg Mux bloc */
|
||||
* by new Mpeg Mux block
|
||||
*/
|
||||
dprintk("dib8096P setting output mode TS_FIFO using Smooth block\n");
|
||||
dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
|
||||
outreg |= (5 << 6);
|
||||
|
|
|
@ -217,6 +217,7 @@ config VIDEO_IMX319
|
|||
config VIDEO_IMX334
|
||||
tristate "Sony IMX334 sensor support"
|
||||
depends on OF_GPIO
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Sony
|
||||
IMX334 camera.
|
||||
|
@ -356,6 +357,26 @@ config VIDEO_OV02A10
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov02a10.
|
||||
|
||||
config VIDEO_OV02E10
|
||||
tristate "OmniVision OV02E10 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the OmniVision
|
||||
OV02E10 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov02e10.
|
||||
|
||||
config VIDEO_OV02C10
|
||||
tristate "OmniVision OV02C10 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the OmniVision
|
||||
OV02C10 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov02c10.
|
||||
|
||||
config VIDEO_OV08D10
|
||||
tristate "OmniVision OV08D10 sensor support"
|
||||
help
|
||||
|
@ -691,6 +712,28 @@ config VIDEO_S5K6A3
|
|||
This is a V4L2 sensor driver for Samsung S5K6A3 raw
|
||||
camera sensor.
|
||||
|
||||
config VIDEO_VD55G1
|
||||
tristate "ST VD55G1 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
depends on GPIOLIB
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the ST VD55G1
|
||||
camera sensor.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called vd55g1.
|
||||
|
||||
config VIDEO_VD56G3
|
||||
tristate "ST VD56G3 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
depends on GPIOLIB
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the ST VD56G3
|
||||
camera sensor.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called vd56g3.
|
||||
|
||||
config VIDEO_VGXY61
|
||||
tristate "ST VGXY61 sensor support"
|
||||
select V4L2_CCI_I2C
|
||||
|
|
|
@ -83,6 +83,8 @@ obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o
|
|||
obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o
|
||||
obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o
|
||||
obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
|
||||
obj-$(CONFIG_VIDEO_OV02C10) += ov02c10.o
|
||||
obj-$(CONFIG_VIDEO_OV02E10) += ov02e10.o
|
||||
obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o
|
||||
obj-$(CONFIG_VIDEO_OV08X40) += ov08x40.o
|
||||
obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
|
||||
|
@ -153,6 +155,8 @@ obj-$(CONFIG_VIDEO_TW9910) += tw9910.o
|
|||
obj-$(CONFIG_VIDEO_UDA1342) += uda1342.o
|
||||
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
|
||||
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
|
||||
obj-$(CONFIG_VIDEO_VD55G1) += vd55g1.o
|
||||
obj-$(CONFIG_VIDEO_VD56G3) += vd56g3.o
|
||||
obj-$(CONFIG_VIDEO_VGXY61) += vgxy61.o
|
||||
obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
|
||||
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
|
||||
|
|
|
@ -1370,9 +1370,9 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd,
|
|||
case V4L2_COLORSPACE_BT2020:
|
||||
c = HDMI_COLORIMETRY_EXTENDED;
|
||||
if (y && format->format.ycbcr_enc == V4L2_YCBCR_ENC_BT2020_CONST_LUM)
|
||||
ec = 5; /* Not yet available in hdmi.h */
|
||||
ec = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
|
||||
else
|
||||
ec = 6; /* Not yet available in hdmi.h */
|
||||
ec = HDMI_EXTENDED_COLORIMETRY_BT2020;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -123,10 +123,15 @@ static void print_pll(struct device *dev, const struct ccs_pll *pll)
|
|||
pll->pixel_rate_pixel_array);
|
||||
dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n",
|
||||
pll->pixel_rate_csi);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s\n",
|
||||
static void print_pll_flags(struct device *dev, struct ccs_pll *pll)
|
||||
{
|
||||
dev_dbg(dev, "PLL flags%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
pll->flags & PLL_FL(OP_PIX_CLOCK_PER_LANE) ? " op-pix-clock-per-lane" : "",
|
||||
pll->flags & PLL_FL(EVEN_PLL_MULTIPLIER) ? " even-pll-multiplier" : "",
|
||||
pll->flags & PLL_FL(NO_OP_CLOCKS) ? " no-op-clocks" : "",
|
||||
pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "",
|
||||
pll->flags & PLL_FL(LINK_DECOUPLED) ? " link-decoupled" : "",
|
||||
pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ?
|
||||
" ext-ip-pll-divider" : "",
|
||||
pll->flags & PLL_FL(FLEXIBLE_OP_PIX_CLK_DIV) ?
|
||||
|
@ -311,14 +316,24 @@ __ccs_pll_calculate_vt_tree(struct device *dev,
|
|||
more_mul *= DIV_ROUND_UP(lim_fr->min_pll_multiplier, mul * more_mul);
|
||||
dev_dbg(dev, "more_mul2: %u\n", more_mul);
|
||||
|
||||
pll_fr->pll_multiplier = mul * more_mul;
|
||||
if (pll->flags & CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER &&
|
||||
(mul & 1) && (more_mul & 1))
|
||||
more_mul <<= 1;
|
||||
|
||||
if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz >
|
||||
lim_fr->max_pll_op_clk_freq_hz)
|
||||
pll_fr->pll_multiplier = mul * more_mul;
|
||||
if (pll_fr->pll_multiplier > lim_fr->max_pll_multiplier) {
|
||||
dev_dbg(dev, "pll multiplier %u too high\n",
|
||||
pll_fr->pll_multiplier);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_fr->pll_op_clk_freq_hz =
|
||||
pll_fr->pll_ip_clk_freq_hz * pll_fr->pll_multiplier;
|
||||
if (pll_fr->pll_op_clk_freq_hz > lim_fr->max_pll_op_clk_freq_hz) {
|
||||
dev_dbg(dev, "too high OP clock %u\n",
|
||||
pll_fr->pll_op_clk_freq_hz);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vt_div = div * more_mul;
|
||||
|
||||
|
@ -397,6 +412,8 @@ static int ccs_pll_calculate_vt_tree(struct device *dev,
|
|||
min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
|
||||
pll->ext_clk_freq_hz /
|
||||
lim_fr->max_pll_ip_clk_freq_hz);
|
||||
if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
|
||||
min_pre_pll_clk_div = clk_div_even(min_pre_pll_clk_div);
|
||||
|
||||
dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
|
||||
min_pre_pll_clk_div, max_pre_pll_clk_div);
|
||||
|
@ -432,10 +449,11 @@ static int ccs_pll_calculate_vt_tree(struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "unable to compute VT pre_pll divisor\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
|
||||
const struct ccs_pll_branch_limits_bk *op_lim_bk,
|
||||
struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr,
|
||||
|
@ -558,6 +576,8 @@ ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
if (best_pix_div < SHRT_MAX >> 1)
|
||||
break;
|
||||
}
|
||||
if (best_pix_div == SHRT_MAX >> 1)
|
||||
return -EINVAL;
|
||||
|
||||
pll->vt_bk.sys_clk_div = DIV_ROUND_UP(vt_div, best_pix_div);
|
||||
pll->vt_bk.pix_clk_div = best_pix_div;
|
||||
|
@ -570,6 +590,8 @@ ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
out_calc_pixel_rate:
|
||||
pll->pixel_rate_pixel_array =
|
||||
pll->vt_bk.pix_clk_freq_hz * pll->vt_lanes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -659,6 +681,10 @@ ccs_pll_calculate_op(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
if (!is_one_or_even(i))
|
||||
i <<= 1;
|
||||
|
||||
if (pll->flags & CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER &&
|
||||
mul & 1 && i & 1)
|
||||
i <<= 1;
|
||||
|
||||
dev_dbg(dev, "final more_mul: %u\n", i);
|
||||
if (i > more_mul_max) {
|
||||
dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max);
|
||||
|
@ -716,6 +742,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
u32 i;
|
||||
int rval = -EINVAL;
|
||||
|
||||
print_pll_flags(dev, pll);
|
||||
|
||||
if (!(pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)) {
|
||||
pll->op_lanes = 1;
|
||||
pll->vt_lanes = 1;
|
||||
|
@ -792,7 +820,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
|
||||
max_op_pre_pll_clk_div =
|
||||
min_t(u16, op_lim_fr->max_pre_pll_clk_div,
|
||||
clk_div_even(pll->ext_clk_freq_hz /
|
||||
DIV_ROUND_UP(pll->ext_clk_freq_hz,
|
||||
op_lim_fr->min_pll_ip_clk_freq_hz));
|
||||
min_op_pre_pll_clk_div =
|
||||
max_t(u16, op_lim_fr->min_pre_pll_clk_div,
|
||||
|
@ -815,6 +843,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
one_or_more(
|
||||
DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
|
||||
pll->ext_clk_freq_hz))));
|
||||
if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
|
||||
min_op_pre_pll_clk_div = clk_div_even(min_op_pre_pll_clk_div);
|
||||
dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
|
||||
min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);
|
||||
|
||||
|
@ -843,8 +873,10 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
if (pll->flags & CCS_PLL_FLAG_DUAL_PLL)
|
||||
break;
|
||||
|
||||
ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr,
|
||||
op_pll_bk, cphy, phy_const);
|
||||
rval = ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr,
|
||||
op_pll_bk, cphy, phy_const);
|
||||
if (rval)
|
||||
continue;
|
||||
|
||||
rval = check_bk_bounds(dev, lim, pll, PLL_VT);
|
||||
if (rval)
|
||||
|
@ -857,8 +889,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
|
|||
}
|
||||
|
||||
if (rval) {
|
||||
dev_dbg(dev, "unable to compute pre_pll divisor\n");
|
||||
|
||||
dev_dbg(dev, "unable to compute OP pre_pll divisor\n");
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,19 +18,40 @@
|
|||
#define CCS_PLL_BUS_TYPE_CSI2_DPHY 0x00
|
||||
#define CCS_PLL_BUS_TYPE_CSI2_CPHY 0x01
|
||||
|
||||
/* Old SMIA and implementation specific flags */
|
||||
/* op pix clock is for all lanes in total normally */
|
||||
/* Old SMIA and implementation specific flags. */
|
||||
/* OP PIX clock is for all lanes in total normally. */
|
||||
#define CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE BIT(0)
|
||||
#define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1)
|
||||
/* If set, the PLL multipliers are required to be even. */
|
||||
#define CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER BIT(3)
|
||||
|
||||
/* CCS PLL flags */
|
||||
|
||||
/* The sensor doesn't have OP clocks at all. */
|
||||
#define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1)
|
||||
/* System speed model if this flag is unset. */
|
||||
#define CCS_PLL_FLAG_LANE_SPEED_MODEL BIT(2)
|
||||
#define CCS_PLL_FLAG_LINK_DECOUPLED BIT(3)
|
||||
/* If set, the pre-PLL divider may have odd values, too. */
|
||||
#define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER BIT(4)
|
||||
/*
|
||||
* If set, the OP PIX clock doesn't have to exactly match with data rate, it may
|
||||
* be higher. See "OP Domain Formulas" in MIPI CCS 1.1 spec.
|
||||
*/
|
||||
#define CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV BIT(5)
|
||||
/* If set, the VT domain may run faster than the OP domain. */
|
||||
#define CCS_PLL_FLAG_FIFO_DERATING BIT(6)
|
||||
/* If set, the VT domain may run slower than the OP domain. */
|
||||
#define CCS_PLL_FLAG_FIFO_OVERRATING BIT(7)
|
||||
/* If set, the PLL tree has two PLLs instead of one. */
|
||||
#define CCS_PLL_FLAG_DUAL_PLL BIT(8)
|
||||
/*
|
||||
* If set, the OP SYS clock is a dual data rate clock, transferring two bits per
|
||||
* cycle instead of one.
|
||||
*/
|
||||
#define CCS_PLL_FLAG_OP_SYS_DDR BIT(9)
|
||||
/*
|
||||
* If set, the OP PIX clock is a dual data rate clock, transferring two pixels
|
||||
* per cycle instead of one.
|
||||
*/
|
||||
#define CCS_PLL_FLAG_OP_PIX_DDR BIT(10)
|
||||
|
||||
/**
|
||||
|
|
|
@ -1354,8 +1354,10 @@ static int ccs_change_cci_addr(struct ccs_sensor *sensor)
|
|||
|
||||
client->addr = sensor->hwcfg.i2c_addr_dfl;
|
||||
|
||||
rval = ccs_write(sensor, CCI_ADDRESS_CTRL,
|
||||
sensor->hwcfg.i2c_addr_alt << 1);
|
||||
rval = read_poll_timeout(ccs_write, rval, !rval, CCS_RESET_DELAY_US,
|
||||
CCS_RESET_TIMEOUT_US, false, sensor,
|
||||
CCI_ADDRESS_CTRL,
|
||||
sensor->hwcfg.i2c_addr_alt << 1);
|
||||
if (rval)
|
||||
return rval;
|
||||
|
||||
|
@ -1575,44 +1577,38 @@ static int ccs_power_on(struct device *dev)
|
|||
if (ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA)
|
||||
sleep = SMIAPP_RESET_DELAY(sensor->hwcfg.ext_clk);
|
||||
else
|
||||
sleep = 5000;
|
||||
sleep = CCS_RESET_DELAY_US;
|
||||
|
||||
usleep_range(sleep, sleep);
|
||||
}
|
||||
|
||||
/*
|
||||
* Failures to respond to the address change command have been noticed.
|
||||
* Those failures seem to be caused by the sensor requiring a longer
|
||||
* boot time than advertised. An additional 10ms delay seems to work
|
||||
* around the issue, but the SMIA++ I2C write retry hack makes the delay
|
||||
* unnecessary. The failures need to be investigated to find a proper
|
||||
* fix, and a delay will likely need to be added here if the I2C write
|
||||
* retry hack is reverted before the root cause of the boot time issue
|
||||
* is found.
|
||||
* Some devices take longer than the spec-defined time to respond
|
||||
* after reset. Try until some time has passed before flagging it
|
||||
* an error.
|
||||
*/
|
||||
|
||||
if (!sensor->reset && !sensor->xshutdown) {
|
||||
u8 retry = 100;
|
||||
u32 reset;
|
||||
|
||||
rval = ccs_write(sensor, SOFTWARE_RESET, CCS_SOFTWARE_RESET_ON);
|
||||
rval = read_poll_timeout(ccs_write, rval, !rval,
|
||||
CCS_RESET_DELAY_US,
|
||||
CCS_RESET_TIMEOUT_US,
|
||||
false, sensor, SOFTWARE_RESET,
|
||||
CCS_SOFTWARE_RESET_ON);
|
||||
if (rval < 0) {
|
||||
dev_err(dev, "software reset failed\n");
|
||||
goto out_cci_addr_fail;
|
||||
}
|
||||
|
||||
do {
|
||||
rval = ccs_read(sensor, SOFTWARE_RESET, &reset);
|
||||
reset = !rval && reset == CCS_SOFTWARE_RESET_OFF;
|
||||
if (reset)
|
||||
break;
|
||||
|
||||
usleep_range(1000, 2000);
|
||||
} while (--retry);
|
||||
|
||||
if (!reset) {
|
||||
dev_err(dev, "software reset failed\n");
|
||||
rval = -EIO;
|
||||
rval = read_poll_timeout(ccs_read, rval,
|
||||
!rval &&
|
||||
reset == CCS_SOFTWARE_RESET_OFF,
|
||||
CCS_RESET_DELAY_US,
|
||||
CCS_RESET_TIMEOUT_US, false, sensor,
|
||||
SOFTWARE_RESET, &reset);
|
||||
if (rval < 0) {
|
||||
dev_err_probe(dev, rval,
|
||||
"failed to respond after reset\n");
|
||||
goto out_cci_addr_fail;
|
||||
}
|
||||
}
|
||||
|
@ -2857,10 +2853,6 @@ static int ccs_identify_module(struct ccs_sensor *sensor)
|
|||
break;
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(ccs_module_idents))
|
||||
dev_warn(&client->dev,
|
||||
"no quirks for this module; let's hope it's fully compliant\n");
|
||||
|
||||
dev_dbg(&client->dev, "the sensor is called %s\n", minfo->name);
|
||||
|
||||
return 0;
|
||||
|
@ -3131,8 +3123,6 @@ static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev)
|
|||
|
||||
rval = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
|
||||
&hwcfg->ext_clk);
|
||||
if (rval)
|
||||
dev_info(dev, "can't get clock-frequency\n");
|
||||
|
||||
dev_dbg(dev, "clk %u, mode %u\n", hwcfg->ext_clk,
|
||||
hwcfg->csi_signalling_mode);
|
||||
|
@ -3451,7 +3441,6 @@ static int ccs_probe(struct i2c_client *client)
|
|||
CCS_LIM(sensor, NUM_OF_VT_LANES) + 1;
|
||||
sensor->pll.op_lanes =
|
||||
CCS_LIM(sensor, NUM_OF_OP_LANES) + 1;
|
||||
sensor->pll.flags |= CCS_PLL_FLAG_LINK_DECOUPLED;
|
||||
} else {
|
||||
sensor->pll.vt_lanes = sensor->pll.csi2.lanes;
|
||||
sensor->pll.op_lanes = sensor->pll.csi2.lanes;
|
||||
|
|
|
@ -190,8 +190,7 @@ static int jt8ev1_post_streamoff(struct ccs_sensor *sensor)
|
|||
|
||||
static int jt8ev1_init(struct ccs_sensor *sensor)
|
||||
{
|
||||
sensor->pll.flags |= CCS_PLL_FLAG_LANE_SPEED_MODEL |
|
||||
CCS_PLL_FLAG_LINK_DECOUPLED;
|
||||
sensor->pll.flags |= CCS_PLL_FLAG_LANE_SPEED_MODEL;
|
||||
sensor->pll.vt_lanes = 1;
|
||||
sensor->pll.op_lanes = sensor->pll.csi2.lanes;
|
||||
|
||||
|
|
|
@ -210,7 +210,6 @@ int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val)
|
|||
*/
|
||||
int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
|
||||
{
|
||||
unsigned int retries = 10;
|
||||
int rval;
|
||||
|
||||
rval = ccs_call_quirk(sensor, reg_access, true, ®, &val);
|
||||
|
@ -219,13 +218,7 @@ int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
|
|||
if (rval < 0)
|
||||
return rval;
|
||||
|
||||
rval = 0;
|
||||
do {
|
||||
if (cci_write(sensor->regmap, reg, val, &rval))
|
||||
fsleep(1000);
|
||||
} while (rval && --retries);
|
||||
|
||||
return rval;
|
||||
return cci_write(sensor->regmap, reg, val, NULL);
|
||||
}
|
||||
|
||||
#define MAX_WRITE_LEN 32U
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#define SMIAPP_RESET_DELAY(clk) \
|
||||
(1000 + (SMIAPP_RESET_DELAY_CLOCKS * 1000 \
|
||||
+ (clk) / 1000 - 1) / ((clk) / 1000))
|
||||
#define CCS_RESET_DELAY_US 5000
|
||||
#define CCS_RESET_TIMEOUT_US 1000000
|
||||
|
||||
#define CCS_COLOUR_COMPONENTS 4
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c-atr.h>
|
||||
#include <linux/i2c.h>
|
||||
|
@ -119,44 +118,66 @@ static const struct ub913_format_info *ub913_find_format(u32 incode)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val)
|
||||
static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val,
|
||||
int *err)
|
||||
{
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
ret = regmap_read(priv->regmap, reg, &v);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev,
|
||||
"Cannot read register 0x%02x: %d!\n", reg, ret);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*val = v;
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val)
|
||||
static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val,
|
||||
int *err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
ret = regmap_write(priv->regmap, reg, val);
|
||||
if (ret < 0)
|
||||
dev_err(&priv->client->dev,
|
||||
"Cannot write register 0x%02x: %d!\n", reg, ret);
|
||||
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ub913_update_bits(const struct ub913_data *priv, u8 reg, u8 mask,
|
||||
u8 val)
|
||||
u8 val, int *err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap, reg, mask, val);
|
||||
if (ret < 0)
|
||||
dev_err(&priv->client->dev,
|
||||
"Cannot update register 0x%02x %d!\n", reg, ret);
|
||||
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -204,7 +225,7 @@ static int ub913_gpiochip_probe(struct ub913_data *priv)
|
|||
int ret;
|
||||
|
||||
/* Initialize GPIOs 0 and 1 to local control, tri-state */
|
||||
ub913_write(priv, UB913_REG_GPIO_CFG(0), 0);
|
||||
ub913_write(priv, UB913_REG_GPIO_CFG(0), 0, NULL);
|
||||
|
||||
gc->label = dev_name(dev);
|
||||
gc->parent = dev;
|
||||
|
@ -450,10 +471,10 @@ static int ub913_set_fmt(struct v4l2_subdev *sd,
|
|||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
||||
format->format.code = finfo->outcode;
|
||||
|
||||
*fmt = format->format;
|
||||
|
||||
fmt->code = finfo->outcode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -482,25 +503,41 @@ static int ub913_log_status(struct v4l2_subdev *sd)
|
|||
{
|
||||
struct ub913_data *priv = sd_to_ub913(sd);
|
||||
struct device *dev = &priv->client->dev;
|
||||
u8 v = 0, v1 = 0, v2 = 0;
|
||||
u8 v, v1, v2;
|
||||
int ret;
|
||||
|
||||
ret = ub913_read(priv, UB913_REG_MODE_SEL, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ub913_read(priv, UB913_REG_MODE_SEL, &v);
|
||||
dev_info(dev, "MODE_SEL %#02x\n", v);
|
||||
|
||||
ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1);
|
||||
ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2);
|
||||
ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1, &ret);
|
||||
ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2, &ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CRC errors %u\n", v1 | (v2 << 8));
|
||||
|
||||
/* clear CRC errors */
|
||||
ub913_read(priv, UB913_REG_GENERAL_CFG, &v);
|
||||
ub913_read(priv, UB913_REG_GENERAL_CFG, &v, &ret);
|
||||
ub913_write(priv, UB913_REG_GENERAL_CFG,
|
||||
v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET);
|
||||
ub913_write(priv, UB913_REG_GENERAL_CFG, v);
|
||||
v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET, &ret);
|
||||
ub913_write(priv, UB913_REG_GENERAL_CFG, v, &ret);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ub913_read(priv, UB913_REG_GENERAL_STATUS, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ub913_read(priv, UB913_REG_GENERAL_STATUS, &v);
|
||||
dev_info(dev, "GENERAL_STATUS %#02x\n", v);
|
||||
|
||||
ub913_read(priv, UB913_REG_PLL_OVR, &v);
|
||||
ret = ub913_read(priv, UB913_REG_PLL_OVR, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "PLL_OVR %#02x\n", v);
|
||||
|
||||
return 0;
|
||||
|
@ -656,11 +693,11 @@ static int ub913_i2c_master_init(struct ub913_data *priv)
|
|||
scl_high = div64_u64((u64)scl_high * ref, 1000000000);
|
||||
scl_low = div64_u64((u64)scl_low * ref, 1000000000);
|
||||
|
||||
ret = ub913_write(priv, UB913_REG_SCL_HIGH_TIME, scl_high);
|
||||
ret = ub913_write(priv, UB913_REG_SCL_HIGH_TIME, scl_high, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ub913_write(priv, UB913_REG_SCL_LOW_TIME, scl_low);
|
||||
ret = ub913_write(priv, UB913_REG_SCL_LOW_TIME, scl_low, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -729,7 +766,7 @@ static int ub913_hw_init(struct ub913_data *priv)
|
|||
int ret;
|
||||
u8 v;
|
||||
|
||||
ret = ub913_read(priv, UB913_REG_MODE_SEL, &v);
|
||||
ret = ub913_read(priv, UB913_REG_MODE_SEL, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -750,7 +787,7 @@ static int ub913_hw_init(struct ub913_data *priv)
|
|||
ret = ub913_update_bits(priv, UB913_REG_GENERAL_CFG,
|
||||
UB913_REG_GENERAL_CFG_PCLK_RISING,
|
||||
FIELD_PREP(UB913_REG_GENERAL_CFG_PCLK_RISING,
|
||||
priv->pclk_polarity_rising));
|
||||
priv->pclk_polarity_rising), NULL);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c-atr.h>
|
||||
#include <linux/i2c.h>
|
||||
|
@ -28,6 +27,8 @@
|
|||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
|
||||
#include "ds90ub953.h"
|
||||
|
||||
#define UB953_PAD_SINK 0
|
||||
#define UB953_PAD_SOURCE 1
|
||||
|
||||
|
@ -35,89 +36,6 @@
|
|||
|
||||
#define UB953_DEFAULT_CLKOUT_RATE 25000000UL
|
||||
|
||||
#define UB953_REG_RESET_CTL 0x01
|
||||
#define UB953_REG_RESET_CTL_DIGITAL_RESET_1 BIT(1)
|
||||
#define UB953_REG_RESET_CTL_DIGITAL_RESET_0 BIT(0)
|
||||
|
||||
#define UB953_REG_GENERAL_CFG 0x02
|
||||
#define UB953_REG_GENERAL_CFG_CONT_CLK BIT(6)
|
||||
#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT 4
|
||||
#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_MASK GENMASK(5, 4)
|
||||
#define UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE BIT(1)
|
||||
#define UB953_REG_GENERAL_CFG_I2C_STRAP_MODE BIT(0)
|
||||
|
||||
#define UB953_REG_MODE_SEL 0x03
|
||||
#define UB953_REG_MODE_SEL_MODE_DONE BIT(3)
|
||||
#define UB953_REG_MODE_SEL_MODE_OVERRIDE BIT(4)
|
||||
#define UB953_REG_MODE_SEL_MODE_MASK GENMASK(2, 0)
|
||||
|
||||
#define UB953_REG_CLKOUT_CTRL0 0x06
|
||||
#define UB953_REG_CLKOUT_CTRL1 0x07
|
||||
|
||||
#define UB953_REG_SCL_HIGH_TIME 0x0b
|
||||
#define UB953_REG_SCL_LOW_TIME 0x0c
|
||||
|
||||
#define UB953_REG_LOCAL_GPIO_DATA 0x0d
|
||||
#define UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(n) BIT(4 + (n))
|
||||
#define UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(n) BIT(0 + (n))
|
||||
|
||||
#define UB953_REG_GPIO_INPUT_CTRL 0x0e
|
||||
#define UB953_REG_GPIO_INPUT_CTRL_OUT_EN(n) BIT(4 + (n))
|
||||
#define UB953_REG_GPIO_INPUT_CTRL_INPUT_EN(n) BIT(0 + (n))
|
||||
|
||||
#define UB953_REG_BC_CTRL 0x49
|
||||
#define UB953_REG_BC_CTRL_CRC_ERR_CLR BIT(3)
|
||||
|
||||
#define UB953_REG_REV_MASK_ID 0x50
|
||||
#define UB953_REG_GENERAL_STATUS 0x52
|
||||
|
||||
#define UB953_REG_GPIO_PIN_STS 0x53
|
||||
#define UB953_REG_GPIO_PIN_STS_GPIO_STS(n) BIT(0 + (n))
|
||||
|
||||
#define UB953_REG_BIST_ERR_CNT 0x54
|
||||
#define UB953_REG_CRC_ERR_CNT1 0x55
|
||||
#define UB953_REG_CRC_ERR_CNT2 0x56
|
||||
|
||||
#define UB953_REG_CSI_ERR_CNT 0x5c
|
||||
#define UB953_REG_CSI_ERR_STATUS 0x5d
|
||||
#define UB953_REG_CSI_ERR_DLANE01 0x5e
|
||||
#define UB953_REG_CSI_ERR_DLANE23 0x5f
|
||||
#define UB953_REG_CSI_ERR_CLK_LANE 0x60
|
||||
#define UB953_REG_CSI_PKT_HDR_VC_ID 0x61
|
||||
#define UB953_REG_PKT_HDR_WC_LSB 0x62
|
||||
#define UB953_REG_PKT_HDR_WC_MSB 0x63
|
||||
#define UB953_REG_CSI_ECC 0x64
|
||||
|
||||
#define UB953_REG_IND_ACC_CTL 0xb0
|
||||
#define UB953_REG_IND_ACC_ADDR 0xb1
|
||||
#define UB953_REG_IND_ACC_DATA 0xb2
|
||||
|
||||
#define UB953_REG_FPD3_RX_ID(n) (0xf0 + (n))
|
||||
#define UB953_REG_FPD3_RX_ID_LEN 6
|
||||
|
||||
/* Indirect register blocks */
|
||||
#define UB953_IND_TARGET_PAT_GEN 0x00
|
||||
#define UB953_IND_TARGET_FPD3_TX 0x01
|
||||
#define UB953_IND_TARGET_DIE_ID 0x02
|
||||
|
||||
#define UB953_IND_PGEN_CTL 0x01
|
||||
#define UB953_IND_PGEN_CTL_PGEN_ENABLE BIT(0)
|
||||
#define UB953_IND_PGEN_CFG 0x02
|
||||
#define UB953_IND_PGEN_CSI_DI 0x03
|
||||
#define UB953_IND_PGEN_LINE_SIZE1 0x04
|
||||
#define UB953_IND_PGEN_LINE_SIZE0 0x05
|
||||
#define UB953_IND_PGEN_BAR_SIZE1 0x06
|
||||
#define UB953_IND_PGEN_BAR_SIZE0 0x07
|
||||
#define UB953_IND_PGEN_ACT_LPF1 0x08
|
||||
#define UB953_IND_PGEN_ACT_LPF0 0x09
|
||||
#define UB953_IND_PGEN_TOT_LPF1 0x0a
|
||||
#define UB953_IND_PGEN_TOT_LPF0 0x0b
|
||||
#define UB953_IND_PGEN_LINE_PD1 0x0c
|
||||
#define UB953_IND_PGEN_LINE_PD0 0x0d
|
||||
#define UB953_IND_PGEN_VBP 0x0e
|
||||
#define UB953_IND_PGEN_VFP 0x0f
|
||||
#define UB953_IND_PGEN_COLOR(n) (0x10 + (n)) /* n <= 15 */
|
||||
|
||||
/* Note: Only sync mode supported for now */
|
||||
enum ub953_mode {
|
||||
/* FPD-Link III CSI-2 synchronous mode */
|
||||
|
@ -185,11 +103,14 @@ static inline struct ub953_data *sd_to_ub953(struct v4l2_subdev *sd)
|
|||
* HW Access
|
||||
*/
|
||||
|
||||
static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val)
|
||||
static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val, int *err)
|
||||
{
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
mutex_lock(&priv->reg_lock);
|
||||
|
||||
ret = regmap_read(priv->regmap, reg, &v);
|
||||
|
@ -204,13 +125,19 @@ static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val)
|
|||
out_unlock:
|
||||
mutex_unlock(&priv->reg_lock);
|
||||
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ub953_write(struct ub953_data *priv, u8 reg, u8 val)
|
||||
static int ub953_write(struct ub953_data *priv, u8 reg, u8 val, int *err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
mutex_lock(&priv->reg_lock);
|
||||
|
||||
ret = regmap_write(priv->regmap, reg, val);
|
||||
|
@ -220,6 +147,9 @@ static int ub953_write(struct ub953_data *priv, u8 reg, u8 val)
|
|||
|
||||
mutex_unlock(&priv->reg_lock);
|
||||
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -244,11 +174,15 @@ static int ub953_select_ind_reg_block(struct ub953_data *priv, u8 block)
|
|||
}
|
||||
|
||||
__maybe_unused
|
||||
static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val)
|
||||
static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val,
|
||||
int *err)
|
||||
{
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
mutex_lock(&priv->reg_lock);
|
||||
|
||||
ret = ub953_select_ind_reg_block(priv, block);
|
||||
|
@ -258,7 +192,7 @@ static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val)
|
|||
ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev,
|
||||
"Write to IND_ACC_ADDR failed when reading %u:%x02x: %d\n",
|
||||
"Write to IND_ACC_ADDR failed when reading %u:0x%02x: %d\n",
|
||||
block, reg, ret);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
@ -266,7 +200,7 @@ static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val)
|
|||
ret = regmap_read(priv->regmap, UB953_REG_IND_ACC_DATA, &v);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev,
|
||||
"Write to IND_ACC_DATA failed when reading %u:%x02x: %d\n",
|
||||
"Write to IND_ACC_DATA failed when reading %u:0x%02x: %d\n",
|
||||
block, reg, ret);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
@ -276,14 +210,21 @@ static int ub953_read_ind(struct ub953_data *priv, u8 block, u8 reg, u8 *val)
|
|||
out_unlock:
|
||||
mutex_unlock(&priv->reg_lock);
|
||||
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
__maybe_unused
|
||||
static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
|
||||
static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val,
|
||||
int *err)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (err && *err)
|
||||
return *err;
|
||||
|
||||
mutex_lock(&priv->reg_lock);
|
||||
|
||||
ret = ub953_select_ind_reg_block(priv, block);
|
||||
|
@ -293,7 +234,7 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
|
|||
ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev,
|
||||
"Write to IND_ACC_ADDR failed when writing %u:%x02x: %d\n",
|
||||
"Write to IND_ACC_ADDR failed when writing %u:0x%02x: %d\n",
|
||||
block, reg, ret);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
@ -301,13 +242,16 @@ static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
|
|||
ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val);
|
||||
if (ret) {
|
||||
dev_err(&priv->client->dev,
|
||||
"Write to IND_ACC_DATA failed when writing %u:%x02x\n: %d\n",
|
||||
"Write to IND_ACC_DATA failed when writing %u:0x%02x: %d\n",
|
||||
block, reg, ret);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&priv->reg_lock);
|
||||
|
||||
if (ret && err)
|
||||
*err = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -320,7 +264,7 @@ static int ub953_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
|
|||
int ret;
|
||||
u8 v;
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &v);
|
||||
ret = ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -366,7 +310,7 @@ static int ub953_gpio_get(struct gpio_chip *gc, unsigned int offset)
|
|||
int ret;
|
||||
u8 v;
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_GPIO_PIN_STS, &v);
|
||||
ret = ub953_read(priv, UB953_REG_GPIO_PIN_STS, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -400,11 +344,11 @@ static int ub953_gpiochip_probe(struct ub953_data *priv)
|
|||
int ret;
|
||||
|
||||
/* Set all GPIOs to local input mode */
|
||||
ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0);
|
||||
ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf);
|
||||
ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -607,23 +551,33 @@ static int ub953_log_status(struct v4l2_subdev *sd)
|
|||
{
|
||||
struct ub953_data *priv = sd_to_ub953(sd);
|
||||
struct device *dev = &priv->client->dev;
|
||||
u8 v = 0, v1 = 0, v2 = 0;
|
||||
unsigned int i;
|
||||
char id[UB953_REG_FPD3_RX_ID_LEN];
|
||||
u8 gpio_local_data = 0;
|
||||
u8 gpio_input_ctrl = 0;
|
||||
u8 gpio_pin_sts = 0;
|
||||
u8 gpio_local_data;
|
||||
u8 gpio_input_ctrl;
|
||||
u8 gpio_pin_sts;
|
||||
unsigned int i;
|
||||
u8 v, v1, v2;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < sizeof(id); i++)
|
||||
ub953_read(priv, UB953_REG_FPD3_RX_ID(i), &id[i]);
|
||||
for (i = 0; i < sizeof(id); i++) {
|
||||
ret = ub953_read(priv, UB953_REG_FPD3_RX_ID(i), &id[i], NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id);
|
||||
|
||||
ub953_read(priv, UB953_REG_GENERAL_STATUS, &v);
|
||||
ret = ub953_read(priv, UB953_REG_GENERAL_STATUS, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "GENERAL_STATUS %#02x\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1);
|
||||
ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2);
|
||||
ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1, &ret);
|
||||
ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2, &ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CRC error count %u\n", v1 | (v2 << 8));
|
||||
|
||||
/* Clear CRC error counter */
|
||||
|
@ -632,34 +586,60 @@ static int ub953_log_status(struct v4l2_subdev *sd)
|
|||
UB953_REG_BC_CTRL_CRC_ERR_CLR,
|
||||
UB953_REG_BC_CTRL_CRC_ERR_CLR);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI error count %u\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_ERR_STATUS, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_ERR_STATUS, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI_ERR_STATUS %#02x\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_ERR_DLANE01, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_ERR_DLANE01, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI_ERR_DLANE01 %#02x\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_ERR_DLANE23, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_ERR_DLANE23, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI_ERR_DLANE23 %#02x\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_ERR_CLK_LANE, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_ERR_CLK_LANE, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI_ERR_CLK_LANE %#02x\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_PKT_HDR_VC_ID, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_PKT_HDR_VC_ID, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI packet header VC %u ID %u\n", v >> 6, v & 0x3f);
|
||||
|
||||
ub953_read(priv, UB953_REG_PKT_HDR_WC_LSB, &v1);
|
||||
ub953_read(priv, UB953_REG_PKT_HDR_WC_MSB, &v2);
|
||||
ub953_read(priv, UB953_REG_PKT_HDR_WC_LSB, &v1, &ret);
|
||||
ub953_read(priv, UB953_REG_PKT_HDR_WC_MSB, &v2, &ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI packet header WC %u\n", (v2 << 8) | v1);
|
||||
|
||||
ub953_read(priv, UB953_REG_CSI_ECC, &v);
|
||||
ret = ub953_read(priv, UB953_REG_CSI_ECC, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "CSI ECC %#02x\n", v);
|
||||
|
||||
ub953_read(priv, UB953_REG_LOCAL_GPIO_DATA, &gpio_local_data);
|
||||
ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &gpio_input_ctrl);
|
||||
ub953_read(priv, UB953_REG_GPIO_PIN_STS, &gpio_pin_sts);
|
||||
ub953_read(priv, UB953_REG_LOCAL_GPIO_DATA, &gpio_local_data, &ret);
|
||||
ub953_read(priv, UB953_REG_GPIO_INPUT_CTRL, &gpio_input_ctrl, &ret);
|
||||
ub953_read(priv, UB953_REG_GPIO_PIN_STS, &gpio_pin_sts, &ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < UB953_NUM_GPIOS; i++) {
|
||||
dev_info(dev,
|
||||
|
@ -843,11 +823,11 @@ static int ub953_i2c_master_init(struct ub953_data *priv)
|
|||
scl_high = div64_u64((u64)scl_high * ref, 1000000000) - 5;
|
||||
scl_low = div64_u64((u64)scl_low * ref, 1000000000) - 5;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_SCL_HIGH_TIME, scl_high);
|
||||
ret = ub953_write(priv, UB953_REG_SCL_HIGH_TIME, scl_high, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_SCL_LOW_TIME, scl_low);
|
||||
ret = ub953_write(priv, UB953_REG_SCL_LOW_TIME, scl_low, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -986,11 +966,11 @@ static int ub953_write_clkout_regs(struct ub953_data *priv,
|
|||
|
||||
clkout_ctrl1 = clkout_data->n;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0);
|
||||
ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1);
|
||||
ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1009,13 +989,13 @@ static unsigned long ub953_clkout_recalc_rate(struct clk_hw *hw,
|
|||
u64 rate;
|
||||
int ret;
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL0, &ctrl0);
|
||||
ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL0, &ctrl0, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read CLKOUT_CTRL0: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL1, &ctrl1);
|
||||
ret = ub953_read(priv, UB953_REG_CLKOUT_CTRL1, &ctrl1, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read CLKOUT_CTRL1: %d\n", ret);
|
||||
return 0;
|
||||
|
@ -1191,7 +1171,7 @@ static int ub953_hw_init(struct ub953_data *priv)
|
|||
int ret;
|
||||
u8 v;
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_MODE_SEL, &v);
|
||||
ret = ub953_read(priv, UB953_REG_MODE_SEL, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1231,13 +1211,13 @@ static int ub953_hw_init(struct ub953_data *priv)
|
|||
return dev_err_probe(dev, -EINVAL,
|
||||
"clkin required for non-sync ext mode\n");
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_REV_MASK_ID, &v);
|
||||
ret = ub953_read(priv, UB953_REG_REV_MASK_ID, &v, NULL);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to read revision");
|
||||
|
||||
dev_info(dev, "Found %s rev/mask %#04x\n", priv->hw_data->model, v);
|
||||
|
||||
ret = ub953_read(priv, UB953_REG_GENERAL_CFG, &v);
|
||||
ret = ub953_read(priv, UB953_REG_GENERAL_CFG, &v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1254,11 +1234,16 @@ static int ub953_hw_init(struct ub953_data *priv)
|
|||
UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT;
|
||||
v |= UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v);
|
||||
ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
v = 1U << UB953_REG_I2C_CONTROL2_SDA_OUTPUT_SETUP_SHIFT;
|
||||
v |= UB953_REG_I2C_CONTROL2_BUS_SPEEDUP;
|
||||
|
||||
ret = ub953_write(priv, UB953_REG_I2C_CONTROL2, v, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ub953_subdev_init(struct ub953_data *priv)
|
||||
|
|
104
drivers/media/i2c/ds90ub953.h
Normal file
104
drivers/media/i2c/ds90ub953.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __MEDIA_I2C_DS90UB953_H__
|
||||
#define __MEDIA_I2C_DS90UB953_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define UB953_REG_RESET_CTL 0x01
|
||||
#define UB953_REG_RESET_CTL_DIGITAL_RESET_1 BIT(1)
|
||||
#define UB953_REG_RESET_CTL_DIGITAL_RESET_0 BIT(0)
|
||||
|
||||
#define UB953_REG_GENERAL_CFG 0x02
|
||||
#define UB953_REG_GENERAL_CFG_CONT_CLK BIT(6)
|
||||
#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT 4
|
||||
#define UB953_REG_GENERAL_CFG_CSI_LANE_SEL_MASK GENMASK(5, 4)
|
||||
#define UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE BIT(1)
|
||||
#define UB953_REG_GENERAL_CFG_I2C_STRAP_MODE BIT(0)
|
||||
|
||||
#define UB953_REG_MODE_SEL 0x03
|
||||
#define UB953_REG_MODE_SEL_MODE_DONE BIT(3)
|
||||
#define UB953_REG_MODE_SEL_MODE_OVERRIDE BIT(4)
|
||||
#define UB953_REG_MODE_SEL_MODE_MASK GENMASK(2, 0)
|
||||
|
||||
#define UB953_REG_CLKOUT_CTRL0 0x06
|
||||
#define UB953_REG_CLKOUT_CTRL1 0x07
|
||||
|
||||
#define UB953_REG_I2C_CONTROL2 0x0a
|
||||
#define UB953_REG_I2C_CONTROL2_SDA_OUTPUT_SETUP_SHIFT 4
|
||||
#define UB953_REG_I2C_CONTROL2_BUS_SPEEDUP BIT(1)
|
||||
|
||||
#define UB953_REG_SCL_HIGH_TIME 0x0b
|
||||
#define UB953_REG_SCL_LOW_TIME 0x0c
|
||||
|
||||
#define UB953_REG_LOCAL_GPIO_DATA 0x0d
|
||||
#define UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(n) BIT(4 + (n))
|
||||
#define UB953_REG_LOCAL_GPIO_DATA_GPIO_OUT_SRC(n) BIT(0 + (n))
|
||||
|
||||
#define UB953_REG_GPIO_INPUT_CTRL 0x0e
|
||||
#define UB953_REG_GPIO_INPUT_CTRL_OUT_EN(n) BIT(4 + (n))
|
||||
#define UB953_REG_GPIO_INPUT_CTRL_INPUT_EN(n) BIT(0 + (n))
|
||||
|
||||
#define UB953_REG_BC_CTRL 0x49
|
||||
#define UB953_REG_BC_CTRL_CRC_ERR_CLR BIT(3)
|
||||
|
||||
#define UB953_REG_REV_MASK_ID 0x50
|
||||
#define UB953_REG_GENERAL_STATUS 0x52
|
||||
|
||||
#define UB953_REG_GPIO_PIN_STS 0x53
|
||||
#define UB953_REG_GPIO_PIN_STS_GPIO_STS(n) BIT(0 + (n))
|
||||
|
||||
#define UB953_REG_BIST_ERR_CNT 0x54
|
||||
#define UB953_REG_CRC_ERR_CNT1 0x55
|
||||
#define UB953_REG_CRC_ERR_CNT2 0x56
|
||||
|
||||
#define UB953_REG_CSI_ERR_CNT 0x5c
|
||||
#define UB953_REG_CSI_ERR_STATUS 0x5d
|
||||
#define UB953_REG_CSI_ERR_DLANE01 0x5e
|
||||
#define UB953_REG_CSI_ERR_DLANE23 0x5f
|
||||
#define UB953_REG_CSI_ERR_CLK_LANE 0x60
|
||||
#define UB953_REG_CSI_PKT_HDR_VC_ID 0x61
|
||||
#define UB953_REG_PKT_HDR_WC_LSB 0x62
|
||||
#define UB953_REG_PKT_HDR_WC_MSB 0x63
|
||||
#define UB953_REG_CSI_ECC 0x64
|
||||
|
||||
#define UB953_REG_IND_ACC_CTL 0xb0
|
||||
#define UB953_REG_IND_ACC_ADDR 0xb1
|
||||
#define UB953_REG_IND_ACC_DATA 0xb2
|
||||
|
||||
#define UB953_REG_FPD3_RX_ID(n) (0xf0 + (n))
|
||||
#define UB953_REG_FPD3_RX_ID_LEN 6
|
||||
|
||||
/* Indirect register blocks */
|
||||
#define UB953_IND_TARGET_PAT_GEN 0x00
|
||||
#define UB953_IND_TARGET_ANALOG 0x01
|
||||
#define UB953_IND_TARGET_DIE_ID 0x02
|
||||
|
||||
#define UB953_IND_PGEN_CTL 0x01
|
||||
#define UB953_IND_PGEN_CTL_PGEN_ENABLE BIT(0)
|
||||
#define UB953_IND_PGEN_CFG 0x02
|
||||
#define UB953_IND_PGEN_CSI_DI 0x03
|
||||
#define UB953_IND_PGEN_LINE_SIZE1 0x04
|
||||
#define UB953_IND_PGEN_LINE_SIZE0 0x05
|
||||
#define UB953_IND_PGEN_BAR_SIZE1 0x06
|
||||
#define UB953_IND_PGEN_BAR_SIZE0 0x07
|
||||
#define UB953_IND_PGEN_ACT_LPF1 0x08
|
||||
#define UB953_IND_PGEN_ACT_LPF0 0x09
|
||||
#define UB953_IND_PGEN_TOT_LPF1 0x0a
|
||||
#define UB953_IND_PGEN_TOT_LPF0 0x0b
|
||||
#define UB953_IND_PGEN_LINE_PD1 0x0c
|
||||
#define UB953_IND_PGEN_LINE_PD0 0x0d
|
||||
#define UB953_IND_PGEN_VBP 0x0e
|
||||
#define UB953_IND_PGEN_VFP 0x0f
|
||||
#define UB953_IND_PGEN_COLOR(n) (0x10 + (n)) /* n <= 15 */
|
||||
|
||||
#define UB953_IND_ANA_TEMP_DYNAMIC_CFG 0x4b
|
||||
#define UB953_IND_ANA_TEMP_DYNAMIC_CFG_OV BIT(5)
|
||||
#define UB953_IND_ANA_TEMP_STATIC_CFG 0x4c
|
||||
#define UB953_IND_ANA_TEMP_STATIC_CFG_MASK GENMASK(6, 4)
|
||||
|
||||
/* UB971 Registers */
|
||||
|
||||
#define UB971_ENH_BC_CHK 0x4b
|
||||
|
||||
#endif /* __MEDIA_I2C_DS90UB953_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -718,9 +718,11 @@ static int imx219_configure_lanes(struct imx219 *imx219)
|
|||
ARRAY_SIZE(imx219_4lane_regs), NULL);
|
||||
};
|
||||
|
||||
static int imx219_start_streaming(struct imx219 *imx219,
|
||||
struct v4l2_subdev_state *state)
|
||||
static int imx219_enable_streams(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state, u32 pad,
|
||||
u64 streams_mask)
|
||||
{
|
||||
struct imx219 *imx219 = to_imx219(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
|
||||
int ret;
|
||||
|
||||
|
@ -769,12 +771,16 @@ static int imx219_start_streaming(struct imx219 *imx219,
|
|||
return 0;
|
||||
|
||||
err_rpm_put:
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_mark_last_busy(&client->dev);
|
||||
pm_runtime_put_autosuspend(&client->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void imx219_stop_streaming(struct imx219 *imx219)
|
||||
static int imx219_disable_streams(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state, u32 pad,
|
||||
u64 streams_mask)
|
||||
{
|
||||
struct imx219 *imx219 = to_imx219(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
|
||||
int ret;
|
||||
|
||||
|
@ -787,23 +793,9 @@ static void imx219_stop_streaming(struct imx219 *imx219)
|
|||
__v4l2_ctrl_grab(imx219->vflip, false);
|
||||
__v4l2_ctrl_grab(imx219->hflip, false);
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
}
|
||||
pm_runtime_mark_last_busy(&client->dev);
|
||||
pm_runtime_put_autosuspend(&client->dev);
|
||||
|
||||
static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
{
|
||||
struct imx219 *imx219 = to_imx219(sd);
|
||||
struct v4l2_subdev_state *state;
|
||||
int ret = 0;
|
||||
|
||||
state = v4l2_subdev_lock_and_get_active_state(sd);
|
||||
|
||||
if (enable)
|
||||
ret = imx219_start_streaming(imx219, state);
|
||||
else
|
||||
imx219_stop_streaming(imx219);
|
||||
|
||||
v4l2_subdev_unlock_state(state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -995,7 +987,7 @@ static int imx219_init_state(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
static const struct v4l2_subdev_video_ops imx219_video_ops = {
|
||||
.s_stream = imx219_set_stream,
|
||||
.s_stream = v4l2_subdev_s_stream_helper,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
|
||||
|
@ -1004,6 +996,8 @@ static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
|
|||
.set_fmt = imx219_set_pad_format,
|
||||
.get_selection = imx219_get_selection,
|
||||
.enum_frame_size = imx219_enum_frame_size,
|
||||
.enable_streams = imx219_enable_streams,
|
||||
.disable_streams = imx219_disable_streams,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops imx219_subdev_ops = {
|
||||
|
@ -1280,6 +1274,8 @@ static int imx219_probe(struct i2c_client *client)
|
|||
}
|
||||
|
||||
pm_runtime_idle(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, 1000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1082,7 +1082,7 @@ static int imx283_start_streaming(struct imx283 *imx283,
|
|||
cci_write(imx283->cci, IMX283_REG_SVR, 0x00, &ret);
|
||||
|
||||
dev_dbg(imx283->dev, "Mode: Size %d x %d\n", mode->width, mode->height);
|
||||
dev_dbg(imx283->dev, "Analogue Crop (in the mode) %d,%d %dx%d\n",
|
||||
dev_dbg(imx283->dev, "Analogue Crop (in the mode) (%d,%d)/%ux%u\n",
|
||||
mode->crop.left,
|
||||
mode->crop.top,
|
||||
mode->crop.width,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,7 +31,7 @@
|
|||
#define IMX335_REG_CPWAIT_TIME CCI_REG8(0x300d)
|
||||
#define IMX335_REG_WINMODE CCI_REG8(0x3018)
|
||||
#define IMX335_REG_HTRIMMING_START CCI_REG16_LE(0x302c)
|
||||
#define IMX335_REG_HNUM CCI_REG8(0x302e)
|
||||
#define IMX335_REG_HNUM CCI_REG16_LE(0x302e)
|
||||
|
||||
/* Lines per frame */
|
||||
#define IMX335_REG_VMAX CCI_REG24_LE(0x3030)
|
||||
|
@ -660,7 +660,8 @@ static int imx335_enum_frame_size(struct v4l2_subdev *sd,
|
|||
struct imx335 *imx335 = to_imx335(sd);
|
||||
u32 code;
|
||||
|
||||
if (fsize->index > ARRAY_SIZE(imx335_mbus_codes))
|
||||
/* Only a single supported_mode available. */
|
||||
if (fsize->index > 0)
|
||||
return -EINVAL;
|
||||
|
||||
code = imx335_get_format_code(imx335, fsize->code);
|
||||
|
|
|
@ -605,10 +605,10 @@ static int lt6911uxe_probe(struct i2c_client *client)
|
|||
return dev_err_probe(dev, PTR_ERR(lt6911uxe->reset_gpio),
|
||||
"failed to get reset gpio\n");
|
||||
|
||||
lt6911uxe->irq_gpio = devm_gpiod_get(dev, "readystat", GPIOD_IN);
|
||||
lt6911uxe->irq_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN);
|
||||
if (IS_ERR(lt6911uxe->irq_gpio))
|
||||
return dev_err_probe(dev, PTR_ERR(lt6911uxe->irq_gpio),
|
||||
"failed to get ready_stat gpio\n");
|
||||
"failed to get hpd gpio\n");
|
||||
|
||||
ret = lt6911uxe_fwnode_parse(lt6911uxe, dev);
|
||||
if (ret)
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <media/v4l2-cci.h>
|
||||
|
|
1013
drivers/media/i2c/ov02c10.c
Normal file
1013
drivers/media/i2c/ov02c10.c
Normal file
File diff suppressed because it is too large
Load Diff
969
drivers/media/i2c/ov02e10.c
Normal file
969
drivers/media/i2c/ov02e10.c
Normal file
|
@ -0,0 +1,969 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2023 Intel Corporation.
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <media/v4l2-cci.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
#define OV02E10_LINK_FREQ_360MHZ 360000000ULL
|
||||
#define OV02E10_SCLK 36000000LL
|
||||
#define OV02E10_MCLK 19200000
|
||||
#define OV02E10_DATA_LANES 2
|
||||
#define OV02E10_RGB_DEPTH 10
|
||||
|
||||
#define OV02E10_REG_PAGE_FLAG CCI_REG8(0xfd)
|
||||
#define OV02E10_PAGE_0 0x0
|
||||
#define OV02E10_PAGE_1 0x1
|
||||
#define OV02E10_PAGE_2 0x2
|
||||
#define OV02E10_PAGE_3 0x3
|
||||
#define OV02E10_PAGE_5 0x4
|
||||
#define OV02E10_PAGE_7 0x5
|
||||
#define OV02E10_PAGE_8 0x6
|
||||
#define OV02E10_PAGE_9 0xF
|
||||
#define OV02E10_PAGE_D 0x8
|
||||
#define OV02E10_PAGE_E 0x9
|
||||
#define OV02E10_PAGE_F 0xA
|
||||
|
||||
#define OV02E10_REG_CHIP_ID CCI_REG32(0x00)
|
||||
#define OV02E10_CHIP_ID 0x45025610
|
||||
|
||||
/* Horizontal and vertical flip */
|
||||
#define OV02E10_REG_ORIENTATION CCI_REG8(0x32)
|
||||
|
||||
/* vertical-timings from sensor */
|
||||
#define OV02E10_REG_VTS CCI_REG16(0x35)
|
||||
#define OV02E10_VTS_DEF 2244
|
||||
#define OV02E10_VTS_MIN 2244
|
||||
#define OV02E10_VTS_MAX 0x7fff
|
||||
|
||||
/* horizontal-timings from sensor */
|
||||
#define OV02E10_REG_HTS CCI_REG16(0x37)
|
||||
|
||||
/* Exposure controls from sensor */
|
||||
#define OV02E10_REG_EXPOSURE CCI_REG16(0x03)
|
||||
#define OV02E10_EXPOSURE_MIN 1
|
||||
#define OV02E10_EXPOSURE_MAX_MARGIN 2
|
||||
#define OV02E10_EXPOSURE_STEP 1
|
||||
|
||||
/* Analog gain controls from sensor */
|
||||
#define OV02E10_REG_ANALOG_GAIN CCI_REG8(0x24)
|
||||
#define OV02E10_ANAL_GAIN_MIN 0x10
|
||||
#define OV02E10_ANAL_GAIN_MAX 0xf8
|
||||
#define OV02E10_ANAL_GAIN_STEP 1
|
||||
|
||||
/* Digital gain controls from sensor */
|
||||
#define OV02E10_REG_DIGITAL_GAIN CCI_REG16(0x21)
|
||||
#define OV02E10_DGTL_GAIN_MIN 256
|
||||
#define OV02E10_DGTL_GAIN_MAX 1020
|
||||
#define OV02E10_DGTL_GAIN_STEP 1
|
||||
#define OV02E10_DGTL_GAIN_DEFAULT 256
|
||||
|
||||
/* Register update control */
|
||||
#define OV02E10_REG_COMMAND_UPDATE CCI_REG8(0xE7)
|
||||
#define OV02E10_COMMAND_UPDATE 0x00
|
||||
#define OV02E10_COMMAND_HOLD 0x01
|
||||
|
||||
/* Test Pattern Control */
|
||||
#define OV02E10_REG_TEST_PATTERN CCI_REG8(0x12)
|
||||
#define OV02E10_TEST_PATTERN_ENABLE BIT(0)
|
||||
#define OV02E10_TEST_PATTERN_BAR_SHIFT 1
|
||||
|
||||
struct reg_sequence_list {
|
||||
u32 num_regs;
|
||||
const struct reg_sequence *regs;
|
||||
};
|
||||
|
||||
struct ov02e10_mode {
|
||||
/* Frame width in pixels */
|
||||
u32 width;
|
||||
|
||||
/* Frame height in pixels */
|
||||
u32 height;
|
||||
|
||||
/* Horizontal timining size */
|
||||
u32 hts;
|
||||
|
||||
/* Default vertical timing */
|
||||
u32 vts_def;
|
||||
|
||||
/* Min vertical timining size */
|
||||
u32 vts_min;
|
||||
|
||||
/* Sensor register settings for this resolution */
|
||||
const struct reg_sequence_list reg_list;
|
||||
};
|
||||
|
||||
static const struct reg_sequence mode_1928x1088_30fps_2lane[] = {
|
||||
{ 0xfd, 0x00 },
|
||||
{ 0x20, 0x00 },
|
||||
{ 0x20, 0x0b },
|
||||
{ 0x21, 0x02 },
|
||||
{ 0x10, 0x23 },
|
||||
{ 0xc5, 0x04 },
|
||||
{ 0x21, 0x00 },
|
||||
{ 0x14, 0x96 },
|
||||
{ 0x17, 0x01 },
|
||||
{ 0xfd, 0x01 },
|
||||
{ 0x03, 0x00 },
|
||||
{ 0x04, 0x04 },
|
||||
{ 0x05, 0x04 },
|
||||
{ 0x06, 0x62 },
|
||||
{ 0x07, 0x01 },
|
||||
{ 0x22, 0x80 },
|
||||
{ 0x24, 0xff },
|
||||
{ 0x40, 0xc6 },
|
||||
{ 0x41, 0x18 },
|
||||
{ 0x45, 0x3f },
|
||||
{ 0x48, 0x0c },
|
||||
{ 0x4c, 0x08 },
|
||||
{ 0x51, 0x12 },
|
||||
{ 0x52, 0x10 },
|
||||
{ 0x57, 0x98 },
|
||||
{ 0x59, 0x06 },
|
||||
{ 0x5a, 0x04 },
|
||||
{ 0x5c, 0x38 },
|
||||
{ 0x5e, 0x10 },
|
||||
{ 0x67, 0x11 },
|
||||
{ 0x7b, 0x04 },
|
||||
{ 0x81, 0x12 },
|
||||
{ 0x90, 0x51 },
|
||||
{ 0x91, 0x09 },
|
||||
{ 0x92, 0x21 },
|
||||
{ 0x93, 0x28 },
|
||||
{ 0x95, 0x54 },
|
||||
{ 0x9d, 0x20 },
|
||||
{ 0x9e, 0x04 },
|
||||
{ 0xb1, 0x9a },
|
||||
{ 0xb2, 0x86 },
|
||||
{ 0xb6, 0x3f },
|
||||
{ 0xb9, 0x30 },
|
||||
{ 0xc1, 0x01 },
|
||||
{ 0xc5, 0xa0 },
|
||||
{ 0xc6, 0x73 },
|
||||
{ 0xc7, 0x04 },
|
||||
{ 0xc8, 0x25 },
|
||||
{ 0xc9, 0x05 },
|
||||
{ 0xca, 0x28 },
|
||||
{ 0xcb, 0x00 },
|
||||
{ 0xcf, 0x16 },
|
||||
{ 0xd2, 0xd0 },
|
||||
{ 0xd7, 0x3f },
|
||||
{ 0xd8, 0x40 },
|
||||
{ 0xd9, 0x40 },
|
||||
{ 0xda, 0x44 },
|
||||
{ 0xdb, 0x3d },
|
||||
{ 0xdc, 0x3d },
|
||||
{ 0xdd, 0x3d },
|
||||
{ 0xde, 0x3d },
|
||||
{ 0xdf, 0xf0 },
|
||||
{ 0xea, 0x0f },
|
||||
{ 0xeb, 0x04 },
|
||||
{ 0xec, 0x29 },
|
||||
{ 0xee, 0x47 },
|
||||
{ 0xfd, 0x01 },
|
||||
{ 0x31, 0x01 },
|
||||
{ 0x27, 0x00 },
|
||||
{ 0x2f, 0x41 },
|
||||
{ 0xfd, 0x02 },
|
||||
{ 0xa1, 0x01 },
|
||||
{ 0xfd, 0x02 },
|
||||
{ 0x9a, 0x03 },
|
||||
{ 0xfd, 0x03 },
|
||||
{ 0x9d, 0x0f },
|
||||
{ 0xfd, 0x07 },
|
||||
{ 0x42, 0x00 },
|
||||
{ 0x43, 0xad },
|
||||
{ 0x44, 0x00 },
|
||||
{ 0x45, 0xa8 },
|
||||
{ 0x46, 0x00 },
|
||||
{ 0x47, 0xa8 },
|
||||
{ 0x48, 0x00 },
|
||||
{ 0x49, 0xad },
|
||||
{ 0xfd, 0x00 },
|
||||
{ 0xc4, 0x01 },
|
||||
{ 0xfd, 0x01 },
|
||||
{ 0x33, 0x03 },
|
||||
{ 0xfd, 0x00 },
|
||||
{ 0x20, 0x1f },
|
||||
};
|
||||
|
||||
static const char *const ov02e10_test_pattern_menu[] = {
|
||||
"Disabled",
|
||||
"Color Bar",
|
||||
};
|
||||
|
||||
static const s64 link_freq_menu_items[] = {
|
||||
OV02E10_LINK_FREQ_360MHZ,
|
||||
};
|
||||
|
||||
static const struct ov02e10_mode supported_modes[] = {
|
||||
{
|
||||
.width = 1928,
|
||||
.height = 1088,
|
||||
.hts = 534,
|
||||
.vts_def = 2244,
|
||||
.vts_min = 2244,
|
||||
.reg_list = {
|
||||
.num_regs = ARRAY_SIZE(mode_1928x1088_30fps_2lane),
|
||||
.regs = mode_1928x1088_30fps_2lane,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const char * const ov02e10_supply_names[] = {
|
||||
"dovdd", /* Digital I/O power */
|
||||
"avdd", /* Analog power */
|
||||
"dvdd", /* Digital core power */
|
||||
};
|
||||
|
||||
struct ov02e10 {
|
||||
struct regmap *regmap;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
|
||||
/* V4L2 Controls */
|
||||
struct v4l2_ctrl *link_freq;
|
||||
struct v4l2_ctrl *pixel_rate;
|
||||
struct v4l2_ctrl *vblank;
|
||||
struct v4l2_ctrl *hblank;
|
||||
struct v4l2_ctrl *exposure;
|
||||
struct v4l2_ctrl *vflip;
|
||||
struct v4l2_ctrl *hflip;
|
||||
|
||||
struct clk *img_clk;
|
||||
struct regulator_bulk_data supplies[ARRAY_SIZE(ov02e10_supply_names)];
|
||||
struct gpio_desc *reset;
|
||||
|
||||
/* Current mode */
|
||||
const struct ov02e10_mode *cur_mode;
|
||||
|
||||
/* MIPI lanes info */
|
||||
u32 link_freq_index;
|
||||
u8 mipi_lanes;
|
||||
};
|
||||
|
||||
static inline struct ov02e10 *to_ov02e10(struct v4l2_subdev *subdev)
|
||||
{
|
||||
return container_of(subdev, struct ov02e10, sd);
|
||||
}
|
||||
|
||||
static u64 to_pixel_rate(u32 f_index)
|
||||
{
|
||||
u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV02E10_DATA_LANES;
|
||||
|
||||
do_div(pixel_rate, OV02E10_RGB_DEPTH);
|
||||
|
||||
return pixel_rate;
|
||||
}
|
||||
|
||||
static u64 to_pixels_per_line(u32 hts, u32 f_index)
|
||||
{
|
||||
u64 ppl = hts * to_pixel_rate(f_index);
|
||||
|
||||
do_div(ppl, OV02E10_SCLK);
|
||||
|
||||
return ppl;
|
||||
}
|
||||
|
||||
static void ov02e10_test_pattern(struct ov02e10 *ov02e10, u32 pattern, int *pret)
|
||||
{
|
||||
if (pattern)
|
||||
pattern = pattern << OV02E10_TEST_PATTERN_BAR_SHIFT |
|
||||
OV02E10_TEST_PATTERN_ENABLE;
|
||||
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_TEST_PATTERN, pattern, pret);
|
||||
}
|
||||
|
||||
static int ov02e10_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct ov02e10 *ov02e10 = container_of(ctrl->handler,
|
||||
struct ov02e10, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov02e10->sd);
|
||||
s64 exposure_max;
|
||||
int ret;
|
||||
|
||||
/* Propagate change of current control to all related controls */
|
||||
if (ctrl->id == V4L2_CID_VBLANK) {
|
||||
/* Update max exposure while meeting expected vblanking */
|
||||
exposure_max = ov02e10->cur_mode->height + ctrl->val -
|
||||
OV02E10_EXPOSURE_MAX_MARGIN;
|
||||
ret = __v4l2_ctrl_modify_range(ov02e10->exposure,
|
||||
ov02e10->exposure->minimum,
|
||||
exposure_max,
|
||||
ov02e10->exposure->step,
|
||||
exposure_max);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* V4L2 controls values will be applied only when power is already up */
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
ret = cci_write(ov02e10->regmap, OV02E10_REG_COMMAND_UPDATE,
|
||||
OV02E10_COMMAND_HOLD, NULL);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_ANALOGUE_GAIN:
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_1, &ret);
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_ANALOG_GAIN,
|
||||
ctrl->val, &ret);
|
||||
break;
|
||||
|
||||
case V4L2_CID_DIGITAL_GAIN:
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_1, &ret);
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_DIGITAL_GAIN,
|
||||
ctrl->val, &ret);
|
||||
break;
|
||||
|
||||
case V4L2_CID_EXPOSURE:
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_1, &ret);
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_EXPOSURE,
|
||||
ctrl->val, &ret);
|
||||
break;
|
||||
|
||||
case V4L2_CID_HFLIP:
|
||||
case V4L2_CID_VFLIP:
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_1, &ret);
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_ORIENTATION,
|
||||
ov02e10->hflip->val | ov02e10->vflip->val << 1, &ret);
|
||||
break;
|
||||
case V4L2_CID_VBLANK:
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_1, &ret);
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_VTS,
|
||||
ov02e10->cur_mode->height + ctrl->val, &ret);
|
||||
break;
|
||||
|
||||
case V4L2_CID_TEST_PATTERN:
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_1, &ret);
|
||||
ov02e10_test_pattern(ov02e10, ctrl->val, &ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_COMMAND_UPDATE,
|
||||
OV02E10_COMMAND_UPDATE, &ret);
|
||||
|
||||
pm_runtime_put(&client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops ov02e10_ctrl_ops = {
|
||||
.s_ctrl = ov02e10_set_ctrl,
|
||||
};
|
||||
|
||||
static int ov02e10_init_controls(struct ov02e10 *ov02e10)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov02e10->sd);
|
||||
struct v4l2_ctrl_handler *ctrl_hdlr = &ov02e10->ctrl_handler;
|
||||
const struct ov02e10_mode *mode = ov02e10->cur_mode;
|
||||
u32 vblank_min, vblank_max, vblank_def;
|
||||
struct v4l2_fwnode_device_properties props;
|
||||
s64 exposure_max, h_blank, pixel_rate;
|
||||
int ret;
|
||||
|
||||
v4l2_ctrl_handler_init(ctrl_hdlr, 12);
|
||||
|
||||
ov02e10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
|
||||
&ov02e10_ctrl_ops,
|
||||
V4L2_CID_LINK_FREQ,
|
||||
ov02e10->link_freq_index,
|
||||
0, link_freq_menu_items);
|
||||
if (ov02e10->link_freq)
|
||||
ov02e10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
|
||||
pixel_rate = to_pixel_rate(ov02e10->link_freq_index);
|
||||
ov02e10->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE, 0,
|
||||
pixel_rate, 1, pixel_rate);
|
||||
|
||||
vblank_min = mode->vts_min - mode->height;
|
||||
vblank_max = OV02E10_VTS_MAX - mode->height;
|
||||
vblank_def = mode->vts_def - mode->height;
|
||||
ov02e10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_VBLANK, vblank_min,
|
||||
vblank_max, 1, vblank_def);
|
||||
|
||||
h_blank = mode->hts - mode->width;
|
||||
ov02e10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_HBLANK, h_blank, h_blank,
|
||||
1, h_blank);
|
||||
if (ov02e10->hblank)
|
||||
ov02e10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
|
||||
v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
|
||||
OV02E10_ANAL_GAIN_MIN, OV02E10_ANAL_GAIN_MAX,
|
||||
OV02E10_ANAL_GAIN_STEP, OV02E10_ANAL_GAIN_MIN);
|
||||
|
||||
v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
|
||||
OV02E10_DGTL_GAIN_MIN, OV02E10_DGTL_GAIN_MAX,
|
||||
OV02E10_DGTL_GAIN_STEP, OV02E10_DGTL_GAIN_DEFAULT);
|
||||
|
||||
exposure_max = mode->vts_def - OV02E10_EXPOSURE_MAX_MARGIN;
|
||||
ov02e10->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE,
|
||||
OV02E10_EXPOSURE_MIN,
|
||||
exposure_max,
|
||||
OV02E10_EXPOSURE_STEP,
|
||||
exposure_max);
|
||||
|
||||
ov02e10->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
if (ov02e10->hflip)
|
||||
ov02e10->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
|
||||
|
||||
ov02e10->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
if (ov02e10->vflip)
|
||||
ov02e10->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
|
||||
|
||||
v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov02e10_ctrl_ops,
|
||||
V4L2_CID_TEST_PATTERN,
|
||||
ARRAY_SIZE(ov02e10_test_pattern_menu) - 1,
|
||||
0, 0, ov02e10_test_pattern_menu);
|
||||
|
||||
ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov02e10_ctrl_ops, &props);
|
||||
|
||||
if (ctrl_hdlr->error)
|
||||
return ctrl_hdlr->error;
|
||||
|
||||
ov02e10->sd.ctrl_handler = ctrl_hdlr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ov02e10_update_pad_format(const struct ov02e10_mode *mode,
|
||||
struct v4l2_mbus_framefmt *fmt)
|
||||
{
|
||||
fmt->width = mode->width;
|
||||
fmt->height = mode->height;
|
||||
fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
|
||||
fmt->field = V4L2_FIELD_NONE;
|
||||
}
|
||||
|
||||
static int ov02e10_set_stream_mode(struct ov02e10 *ov02e10, u8 val)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG, OV02E10_PAGE_0, &ret);
|
||||
cci_write(ov02e10->regmap, CCI_REG8(0xa0), val, &ret);
|
||||
cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG, OV02E10_PAGE_1, &ret);
|
||||
cci_write(ov02e10->regmap, CCI_REG8(0x01), 0x02, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov02e10_enable_streams(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state,
|
||||
u32 pad, u64 streams_mask)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
const struct reg_sequence_list *reg_list;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(&client->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg_list = &ov02e10->cur_mode->reg_list;
|
||||
ret = regmap_multi_reg_write(ov02e10->regmap, reg_list->regs,
|
||||
reg_list->num_regs);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to set mode\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = __v4l2_ctrl_handler_setup(ov02e10->sd.ctrl_handler);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = ov02e10_set_stream_mode(ov02e10, 1);
|
||||
|
||||
out:
|
||||
if (ret)
|
||||
pm_runtime_put(&client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov02e10_disable_streams(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state,
|
||||
u32 pad, u64 streams_mask)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
|
||||
ov02e10_set_stream_mode(ov02e10, 0);
|
||||
pm_runtime_put(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov02e10_get_pm_resources(struct device *dev)
|
||||
{
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
int i;
|
||||
|
||||
ov02e10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ov02e10->reset))
|
||||
return dev_err_probe(dev, PTR_ERR(ov02e10->reset),
|
||||
"failed to get reset gpio\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ov02e10_supply_names); i++)
|
||||
ov02e10->supplies[i].supply = ov02e10_supply_names[i];
|
||||
|
||||
return devm_regulator_bulk_get(dev, ARRAY_SIZE(ov02e10_supply_names),
|
||||
ov02e10->supplies);
|
||||
}
|
||||
|
||||
static int ov02e10_power_off(struct device *dev)
|
||||
{
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
|
||||
if (ov02e10->reset)
|
||||
gpiod_set_value_cansleep(ov02e10->reset, 1);
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(ov02e10_supply_names),
|
||||
ov02e10->supplies);
|
||||
|
||||
clk_disable_unprepare(ov02e10->img_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov02e10_power_on(struct device *dev)
|
||||
{
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(ov02e10->img_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable imaging clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(ov02e10_supply_names),
|
||||
ov02e10->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable regulators\n");
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
if (ov02e10->reset) {
|
||||
usleep_range(5000, 5100);
|
||||
gpiod_set_value_cansleep(ov02e10->reset, 0);
|
||||
usleep_range(8000, 8100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(ov02e10->img_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov02e10_set_format(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
{
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
const struct ov02e10_mode *mode;
|
||||
s32 vblank_def, h_blank;
|
||||
int ret = 0;
|
||||
|
||||
mode = v4l2_find_nearest_size(supported_modes,
|
||||
ARRAY_SIZE(supported_modes),
|
||||
width, height, fmt->format.width,
|
||||
fmt->format.height);
|
||||
|
||||
ov02e10_update_pad_format(mode, &fmt->format);
|
||||
|
||||
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||
*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
|
||||
} else {
|
||||
ov02e10->cur_mode = mode;
|
||||
ret = __v4l2_ctrl_s_ctrl(ov02e10->link_freq,
|
||||
ov02e10->link_freq_index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __v4l2_ctrl_s_ctrl_int64(ov02e10->pixel_rate,
|
||||
to_pixel_rate(ov02e10->link_freq_index));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Update limits and set FPS to default */
|
||||
vblank_def = mode->vts_def - mode->height;
|
||||
ret = __v4l2_ctrl_modify_range(ov02e10->vblank,
|
||||
mode->vts_min - mode->height,
|
||||
OV02E10_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __v4l2_ctrl_s_ctrl(ov02e10->vblank, vblank_def);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
h_blank = to_pixels_per_line(mode->hts, ov02e10->link_freq_index);
|
||||
h_blank -= mode->width;
|
||||
ret = __v4l2_ctrl_modify_range(ov02e10->hblank, h_blank,
|
||||
h_blank, 1, h_blank);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov02e10_get_format(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
{
|
||||
struct ov02e10 *ov02e10 = to_ov02e10(sd);
|
||||
|
||||
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
|
||||
fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad);
|
||||
else
|
||||
ov02e10_update_pad_format(ov02e10->cur_mode, &fmt->format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov02e10_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
{
|
||||
if (code->index > 0)
|
||||
return -EINVAL;
|
||||
|
||||
code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov02e10_enum_frame_size(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
{
|
||||
if (fse->index >= ARRAY_SIZE(supported_modes))
|
||||
return -EINVAL;
|
||||
|
||||
if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
|
||||
return -EINVAL;
|
||||
|
||||
fse->min_width = supported_modes[fse->index].width;
|
||||
fse->max_width = fse->min_width;
|
||||
fse->min_height = supported_modes[fse->index].height;
|
||||
fse->max_height = fse->min_height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov02e10_init_state(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state)
|
||||
{
|
||||
ov02e10_update_pad_format(&supported_modes[0],
|
||||
v4l2_subdev_state_get_format(sd_state, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_video_ops ov02e10_video_ops = {
|
||||
.s_stream = v4l2_subdev_s_stream_helper,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_pad_ops ov02e10_pad_ops = {
|
||||
.set_fmt = ov02e10_set_format,
|
||||
.get_fmt = ov02e10_get_format,
|
||||
.enum_mbus_code = ov02e10_enum_mbus_code,
|
||||
.enum_frame_size = ov02e10_enum_frame_size,
|
||||
.enable_streams = ov02e10_enable_streams,
|
||||
.disable_streams = ov02e10_disable_streams,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops ov02e10_subdev_ops = {
|
||||
.video = &ov02e10_video_ops,
|
||||
.pad = &ov02e10_pad_ops,
|
||||
};
|
||||
|
||||
static const struct media_entity_operations ov02e10_subdev_entity_ops = {
|
||||
.link_validate = v4l2_subdev_link_validate,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_internal_ops ov02e10_internal_ops = {
|
||||
.init_state = ov02e10_init_state,
|
||||
};
|
||||
|
||||
static int ov02e10_identify_module(struct ov02e10 *ov02e10)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov02e10->sd);
|
||||
int ret;
|
||||
u64 val;
|
||||
|
||||
ret = cci_write(ov02e10->regmap, OV02E10_REG_PAGE_FLAG,
|
||||
OV02E10_PAGE_0, NULL);
|
||||
cci_read(ov02e10->regmap, OV02E10_REG_CHIP_ID, &val, &ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val != OV02E10_CHIP_ID) {
|
||||
dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
|
||||
OV02E10_CHIP_ID, (u32)val);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov02e10_check_hwcfg(struct device *dev, struct ov02e10 *ov02e10)
|
||||
{
|
||||
struct v4l2_fwnode_endpoint bus_cfg = {
|
||||
.bus_type = V4L2_MBUS_CSI2_DPHY
|
||||
};
|
||||
struct fwnode_handle *ep;
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
unsigned long link_freq_bitmap;
|
||||
u32 ext_clk;
|
||||
int ret;
|
||||
|
||||
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
|
||||
if (!ep)
|
||||
return dev_err_probe(dev, -EPROBE_DEFER,
|
||||
"waiting for fwnode graph endpoint\n");
|
||||
|
||||
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
|
||||
fwnode_handle_put(ep);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "parsing endpoint failed\n");
|
||||
|
||||
ov02e10->img_clk = devm_clk_get_optional(dev, NULL);
|
||||
if (IS_ERR(ov02e10->img_clk)) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(ov02e10->img_clk),
|
||||
"failed to get imaging clock\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (ov02e10->img_clk) {
|
||||
ext_clk = clk_get_rate(ov02e10->img_clk);
|
||||
} else {
|
||||
ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
|
||||
&ext_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency\n");
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
if (ext_clk != OV02E10_MCLK) {
|
||||
dev_err(dev, "external clock %d is not supported\n",
|
||||
ext_clk);
|
||||
ret = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV02E10_DATA_LANES) {
|
||||
dev_err(dev, "number of CSI2 data lanes %d is not supported\n",
|
||||
bus_cfg.bus.mipi_csi2.num_data_lanes);
|
||||
ret = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!bus_cfg.nr_of_link_frequencies) {
|
||||
dev_err(dev, "no link frequencies defined\n");
|
||||
ret = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
|
||||
bus_cfg.nr_of_link_frequencies,
|
||||
link_freq_menu_items,
|
||||
ARRAY_SIZE(link_freq_menu_items),
|
||||
&link_freq_bitmap);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
/* v4l2_link_freq_to_bitmap() guarantees at least 1 bit is set */
|
||||
ov02e10->link_freq_index = ffs(link_freq_bitmap) - 1;
|
||||
ov02e10->mipi_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
|
||||
out_err:
|
||||
v4l2_fwnode_endpoint_free(&bus_cfg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ov02e10_remove(struct i2c_client *client)
|
||||
{
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
|
||||
v4l2_async_unregister_subdev(sd);
|
||||
v4l2_subdev_cleanup(sd);
|
||||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
pm_runtime_disable(&client->dev);
|
||||
|
||||
if (!pm_runtime_status_suspended(&client->dev)) {
|
||||
ov02e10_power_off(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
}
|
||||
}
|
||||
|
||||
static int ov02e10_probe(struct i2c_client *client)
|
||||
{
|
||||
struct ov02e10 *ov02e10;
|
||||
int ret;
|
||||
|
||||
ov02e10 = devm_kzalloc(&client->dev, sizeof(*ov02e10), GFP_KERNEL);
|
||||
if (!ov02e10)
|
||||
return -ENOMEM;
|
||||
|
||||
v4l2_i2c_subdev_init(&ov02e10->sd, client, &ov02e10_subdev_ops);
|
||||
|
||||
/* Check HW config */
|
||||
ret = ov02e10_check_hwcfg(&client->dev, ov02e10);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Initialize subdev */
|
||||
ov02e10->regmap = devm_cci_regmap_init_i2c(client, 8);
|
||||
if (IS_ERR(ov02e10->regmap))
|
||||
return PTR_ERR(ov02e10->regmap);
|
||||
|
||||
ret = ov02e10_get_pm_resources(&client->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ov02e10_power_on(&client->dev);
|
||||
if (ret) {
|
||||
dev_err_probe(&client->dev, ret, "failed to power on\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check module identity */
|
||||
ret = ov02e10_identify_module(ov02e10);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d\n", ret);
|
||||
goto probe_error_power_off;
|
||||
}
|
||||
|
||||
ov02e10->cur_mode = &supported_modes[0];
|
||||
ret = ov02e10_init_controls(ov02e10);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init controls: %d\n", ret);
|
||||
goto probe_error_v4l2_ctrl_handler_free;
|
||||
}
|
||||
|
||||
/* Initialize subdev */
|
||||
ov02e10->sd.internal_ops = &ov02e10_internal_ops;
|
||||
ov02e10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
ov02e10->sd.entity.ops = &ov02e10_subdev_entity_ops;
|
||||
ov02e10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
|
||||
|
||||
/* Initialize source pad */
|
||||
ov02e10->pad.flags = MEDIA_PAD_FL_SOURCE;
|
||||
ret = media_entity_pads_init(&ov02e10->sd.entity, 1, &ov02e10->pad);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to init entity pads: %d", ret);
|
||||
goto probe_error_v4l2_ctrl_handler_free;
|
||||
}
|
||||
|
||||
ov02e10->sd.state_lock = ov02e10->ctrl_handler.lock;
|
||||
ret = v4l2_subdev_init_finalize(&ov02e10->sd);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "failed to init subdev: %d", ret);
|
||||
goto probe_error_media_entity_cleanup;
|
||||
}
|
||||
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&ov02e10->sd);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "failed to register V4L2 subdev: %d",
|
||||
ret);
|
||||
goto probe_error_v4l2_subdev_cleanup;
|
||||
}
|
||||
|
||||
pm_runtime_idle(&client->dev);
|
||||
return 0;
|
||||
|
||||
probe_error_v4l2_subdev_cleanup:
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
v4l2_subdev_cleanup(&ov02e10->sd);
|
||||
|
||||
probe_error_media_entity_cleanup:
|
||||
media_entity_cleanup(&ov02e10->sd.entity);
|
||||
|
||||
probe_error_v4l2_ctrl_handler_free:
|
||||
v4l2_ctrl_handler_free(ov02e10->sd.ctrl_handler);
|
||||
|
||||
probe_error_power_off:
|
||||
ov02e10_power_off(&client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(ov02e10_pm_ops, ov02e10_power_off,
|
||||
ov02e10_power_on, NULL);
|
||||
|
||||
static const struct acpi_device_id ov02e10_acpi_ids[] = {
|
||||
{ "OVTI02E1" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, ov02e10_acpi_ids);
|
||||
|
||||
static const struct of_device_id ov02e10_of_match[] = {
|
||||
{ .compatible = "ovti,ov02e10" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ov02e10_of_match);
|
||||
|
||||
static struct i2c_driver ov02e10_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ov02e10",
|
||||
.pm = pm_sleep_ptr(&ov02e10_pm_ops),
|
||||
.acpi_match_table = ov02e10_acpi_ids,
|
||||
.of_match_table = ov02e10_of_match,
|
||||
},
|
||||
.probe = ov02e10_probe,
|
||||
.remove = ov02e10_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(ov02e10_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Jingjing Xiong <jingjing.xiong@intel.com>");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_AUTHOR("Alan Stern <stern@rowland.harvard.edu>");
|
||||
MODULE_AUTHOR("Bryan O'Donoghue <bryan.odonoghue@linaro.org>");
|
||||
MODULE_DESCRIPTION("OmniVision OV02E10 sensor driver");
|
||||
MODULE_LICENSE("GPL");
|
File diff suppressed because it is too large
Load Diff
|
@ -34,9 +34,6 @@
|
|||
#define OV13B10_VTS_120FPS 0x0320
|
||||
#define OV13B10_VTS_MAX 0x7fff
|
||||
|
||||
/* HBLANK control - read only */
|
||||
#define OV13B10_PPL_560MHZ 4704
|
||||
|
||||
/* Exposure control */
|
||||
#define OV13B10_REG_EXPOSURE 0x3500
|
||||
#define OV13B10_EXPOSURE_MIN 4
|
||||
|
@ -95,7 +92,7 @@ struct ov13b10_reg_list {
|
|||
|
||||
/* Link frequency config */
|
||||
struct ov13b10_link_freq_config {
|
||||
u32 pixels_per_line;
|
||||
u64 link_freq;
|
||||
|
||||
/* registers for this link frequency */
|
||||
struct ov13b10_reg_list reg_list;
|
||||
|
@ -114,6 +111,10 @@ struct ov13b10_mode {
|
|||
|
||||
/* Index of Link frequency config to be used */
|
||||
u32 link_freq_index;
|
||||
|
||||
/* Pixels per line in current mode */
|
||||
u32 ppl;
|
||||
|
||||
/* Default register values */
|
||||
struct ov13b10_reg_list reg_list;
|
||||
};
|
||||
|
@ -513,6 +514,52 @@ static const struct ov13b10_reg mode_1364x768_120fps_regs[] = {
|
|||
{0x5001, 0x0d},
|
||||
};
|
||||
|
||||
static const struct ov13b10_reg mode_2lanes_2104x1560_60fps_regs[] = {
|
||||
{0x3016, 0x32},
|
||||
{0x3106, 0x29},
|
||||
{0x0305, 0xaf},
|
||||
{0x3501, 0x06},
|
||||
{0x3662, 0x88},
|
||||
{0x3714, 0x28},
|
||||
{0x3739, 0x10},
|
||||
{0x37c2, 0x14},
|
||||
{0x37d9, 0x06},
|
||||
{0x37e2, 0x0c},
|
||||
{0x3800, 0x00},
|
||||
{0x3801, 0x00},
|
||||
{0x3802, 0x00},
|
||||
{0x3803, 0x08},
|
||||
{0x3804, 0x10},
|
||||
{0x3805, 0x8f},
|
||||
{0x3806, 0x0c},
|
||||
{0x3807, 0x47},
|
||||
{0x3808, 0x08},
|
||||
{0x3809, 0x38},
|
||||
{0x380a, 0x06},
|
||||
{0x380b, 0x18},
|
||||
{0x380c, 0x04},
|
||||
{0x380d, 0x98},
|
||||
{0x380e, 0x06},
|
||||
{0x380f, 0x3e},
|
||||
{0x3810, 0x00},
|
||||
{0x3811, 0x07},
|
||||
{0x3812, 0x00},
|
||||
{0x3813, 0x05},
|
||||
{0x3814, 0x03},
|
||||
{0x3816, 0x03},
|
||||
{0x3820, 0x8b},
|
||||
{0x3c8c, 0x18},
|
||||
{0x4008, 0x00},
|
||||
{0x4009, 0x05},
|
||||
{0x4050, 0x00},
|
||||
{0x4051, 0x05},
|
||||
{0x4501, 0x08},
|
||||
{0x4505, 0x00},
|
||||
{0x4837, 0x0e},
|
||||
{0x5000, 0xfd},
|
||||
{0x5001, 0x0d},
|
||||
};
|
||||
|
||||
static const char * const ov13b10_test_pattern_menu[] = {
|
||||
"Disabled",
|
||||
"Vertical Color Bar Type 1",
|
||||
|
@ -526,15 +573,16 @@ static const char * const ov13b10_test_pattern_menu[] = {
|
|||
#define OV13B10_LINK_FREQ_INDEX_0 0
|
||||
|
||||
#define OV13B10_EXT_CLK 19200000
|
||||
#define OV13B10_DATA_LANES 4
|
||||
#define OV13B10_4_DATA_LANES 4
|
||||
#define OV13B10_2_DATA_LANES 2
|
||||
|
||||
/*
|
||||
* pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
|
||||
* data rate => double data rate; number of lanes => 4; bits per pixel => 10
|
||||
* pixel_rate = data_rate * nr_of_lanes / bits_per_pixel
|
||||
* data_rate => link_freq * 2; number of lanes => 4 or 2; bits per pixel => 10
|
||||
*/
|
||||
static u64 link_freq_to_pixel_rate(u64 f)
|
||||
static u64 link_freq_to_pixel_rate(u64 f, u8 lanes)
|
||||
{
|
||||
f *= 2 * OV13B10_DATA_LANES;
|
||||
f *= 2 * lanes;
|
||||
do_div(f, 10);
|
||||
|
||||
return f;
|
||||
|
@ -549,7 +597,7 @@ static const s64 link_freq_menu_items[] = {
|
|||
static const struct ov13b10_link_freq_config
|
||||
link_freq_configs[] = {
|
||||
{
|
||||
.pixels_per_line = OV13B10_PPL_560MHZ,
|
||||
.link_freq = OV13B10_LINK_FREQ_560MHZ,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mipi_data_rate_1120mbps),
|
||||
.regs = mipi_data_rate_1120mbps,
|
||||
|
@ -558,12 +606,14 @@ static const struct ov13b10_link_freq_config
|
|||
};
|
||||
|
||||
/* Mode configs */
|
||||
static const struct ov13b10_mode supported_modes[] = {
|
||||
static const struct ov13b10_mode supported_4_lanes_modes[] = {
|
||||
/* 4 data lanes */
|
||||
{
|
||||
.width = 4208,
|
||||
.height = 3120,
|
||||
.vts_def = OV13B10_VTS_30FPS,
|
||||
.vts_min = OV13B10_VTS_30FPS,
|
||||
.ppl = 4704,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_4208x3120_regs),
|
||||
.regs = mode_4208x3120_regs,
|
||||
|
@ -575,6 +625,7 @@ static const struct ov13b10_mode supported_modes[] = {
|
|||
.height = 3120,
|
||||
.vts_def = OV13B10_VTS_30FPS,
|
||||
.vts_min = OV13B10_VTS_30FPS,
|
||||
.ppl = 4704,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_4160x3120_regs),
|
||||
.regs = mode_4160x3120_regs,
|
||||
|
@ -586,6 +637,7 @@ static const struct ov13b10_mode supported_modes[] = {
|
|||
.height = 2340,
|
||||
.vts_def = OV13B10_VTS_30FPS,
|
||||
.vts_min = OV13B10_VTS_30FPS,
|
||||
.ppl = 4704,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_4160x2340_regs),
|
||||
.regs = mode_4160x2340_regs,
|
||||
|
@ -597,6 +649,7 @@ static const struct ov13b10_mode supported_modes[] = {
|
|||
.height = 1560,
|
||||
.vts_def = OV13B10_VTS_60FPS,
|
||||
.vts_min = OV13B10_VTS_60FPS,
|
||||
.ppl = 4704,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_2104x1560_regs),
|
||||
.regs = mode_2104x1560_regs,
|
||||
|
@ -608,6 +661,7 @@ static const struct ov13b10_mode supported_modes[] = {
|
|||
.height = 1170,
|
||||
.vts_def = OV13B10_VTS_60FPS,
|
||||
.vts_min = OV13B10_VTS_60FPS,
|
||||
.ppl = 4704,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_2080x1170_regs),
|
||||
.regs = mode_2080x1170_regs,
|
||||
|
@ -620,6 +674,7 @@ static const struct ov13b10_mode supported_modes[] = {
|
|||
.vts_def = OV13B10_VTS_120FPS,
|
||||
.vts_min = OV13B10_VTS_120FPS,
|
||||
.link_freq_index = OV13B10_LINK_FREQ_INDEX_0,
|
||||
.ppl = 4664,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_1364x768_120fps_regs),
|
||||
.regs = mode_1364x768_120fps_regs,
|
||||
|
@ -627,6 +682,23 @@ static const struct ov13b10_mode supported_modes[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct ov13b10_mode supported_2_lanes_modes[] = {
|
||||
/* 2 data lanes */
|
||||
{
|
||||
.width = 2104,
|
||||
.height = 1560,
|
||||
.vts_def = OV13B10_VTS_60FPS,
|
||||
.vts_min = OV13B10_VTS_60FPS,
|
||||
.link_freq_index = OV13B10_LINK_FREQ_INDEX_0,
|
||||
.ppl = 2352,
|
||||
.reg_list = {
|
||||
.num_of_regs =
|
||||
ARRAY_SIZE(mode_2lanes_2104x1560_60fps_regs),
|
||||
.regs = mode_2lanes_2104x1560_60fps_regs,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
struct ov13b10 {
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
|
@ -644,12 +716,20 @@ struct ov13b10 {
|
|||
struct v4l2_ctrl *hblank;
|
||||
struct v4l2_ctrl *exposure;
|
||||
|
||||
/* Supported modes */
|
||||
const struct ov13b10_mode *supported_modes;
|
||||
|
||||
/* Current mode */
|
||||
const struct ov13b10_mode *cur_mode;
|
||||
|
||||
/* Mutex for serialized access */
|
||||
struct mutex mutex;
|
||||
|
||||
u8 supported_modes_num;
|
||||
|
||||
/* Data lanes used */
|
||||
u8 data_lanes;
|
||||
|
||||
/* True if the device has been identified */
|
||||
bool identified;
|
||||
};
|
||||
|
@ -753,8 +833,8 @@ static int ov13b10_write_reg_list(struct ov13b10 *ov13b,
|
|||
/* Open sub-device */
|
||||
static int ov13b10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
const struct ov13b10_mode *default_mode = &supported_modes[0];
|
||||
struct ov13b10 *ov13b = to_ov13b10(sd);
|
||||
const struct ov13b10_mode *default_mode = ov13b->supported_modes;
|
||||
struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_state_get_format(fh->state,
|
||||
0);
|
||||
|
||||
|
@ -973,7 +1053,10 @@ static int ov13b10_enum_frame_size(struct v4l2_subdev *sd,
|
|||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
{
|
||||
if (fse->index >= ARRAY_SIZE(supported_modes))
|
||||
struct ov13b10 *ov13b = to_ov13b10(sd);
|
||||
const struct ov13b10_mode *supported_modes = ov13b->supported_modes;
|
||||
|
||||
if (fse->index >= ov13b->supported_modes_num)
|
||||
return -EINVAL;
|
||||
|
||||
if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
|
||||
|
@ -1033,6 +1116,7 @@ ov13b10_set_pad_format(struct v4l2_subdev *sd,
|
|||
{
|
||||
struct ov13b10 *ov13b = to_ov13b10(sd);
|
||||
const struct ov13b10_mode *mode;
|
||||
const struct ov13b10_mode *supported_modes = ov13b->supported_modes;
|
||||
struct v4l2_mbus_framefmt *framefmt;
|
||||
s32 vblank_def;
|
||||
s32 vblank_min;
|
||||
|
@ -1047,7 +1131,7 @@ ov13b10_set_pad_format(struct v4l2_subdev *sd,
|
|||
fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
|
||||
|
||||
mode = v4l2_find_nearest_size(supported_modes,
|
||||
ARRAY_SIZE(supported_modes),
|
||||
ov13b->supported_modes_num,
|
||||
width, height,
|
||||
fmt->format.width, fmt->format.height);
|
||||
ov13b10_update_pad_format(mode, fmt);
|
||||
|
@ -1058,23 +1142,18 @@ ov13b10_set_pad_format(struct v4l2_subdev *sd,
|
|||
ov13b->cur_mode = mode;
|
||||
__v4l2_ctrl_s_ctrl(ov13b->link_freq, mode->link_freq_index);
|
||||
link_freq = link_freq_menu_items[mode->link_freq_index];
|
||||
pixel_rate = link_freq_to_pixel_rate(link_freq);
|
||||
pixel_rate = link_freq_to_pixel_rate(link_freq,
|
||||
ov13b->data_lanes);
|
||||
__v4l2_ctrl_s_ctrl_int64(ov13b->pixel_rate, pixel_rate);
|
||||
|
||||
/* Update limits and set FPS to default */
|
||||
vblank_def = ov13b->cur_mode->vts_def -
|
||||
ov13b->cur_mode->height;
|
||||
vblank_min = ov13b->cur_mode->vts_min -
|
||||
ov13b->cur_mode->height;
|
||||
vblank_def = mode->vts_def - mode->height;
|
||||
vblank_min = mode->vts_min - mode->height;
|
||||
__v4l2_ctrl_modify_range(ov13b->vblank, vblank_min,
|
||||
OV13B10_VTS_MAX
|
||||
- ov13b->cur_mode->height,
|
||||
1,
|
||||
vblank_def);
|
||||
OV13B10_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
__v4l2_ctrl_s_ctrl(ov13b->vblank, vblank_def);
|
||||
h_blank =
|
||||
link_freq_configs[mode->link_freq_index].pixels_per_line
|
||||
- ov13b->cur_mode->width;
|
||||
h_blank = mode->ppl - mode->width;
|
||||
__v4l2_ctrl_modify_range(ov13b->hblank, h_blank,
|
||||
h_blank, 1, h_blank);
|
||||
}
|
||||
|
@ -1311,7 +1390,8 @@ static int ov13b10_init_controls(struct ov13b10 *ov13b)
|
|||
if (ov13b->link_freq)
|
||||
ov13b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
|
||||
pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
|
||||
pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0],
|
||||
ov13b->data_lanes);
|
||||
pixel_rate_min = 0;
|
||||
/* By default, PIXEL_RATE is read only */
|
||||
ov13b->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov13b10_ctrl_ops,
|
||||
|
@ -1328,8 +1408,7 @@ static int ov13b10_init_controls(struct ov13b10 *ov13b)
|
|||
OV13B10_VTS_MAX - mode->height, 1,
|
||||
vblank_def);
|
||||
|
||||
hblank = link_freq_configs[mode->link_freq_index].pixels_per_line -
|
||||
mode->width;
|
||||
hblank = mode->ppl - mode->width;
|
||||
ov13b->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov13b10_ctrl_ops,
|
||||
V4L2_CID_HBLANK,
|
||||
hblank, hblank, 1, hblank);
|
||||
|
@ -1423,7 +1502,7 @@ static int ov13b10_get_pm_resources(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ov13b10_check_hwcfg(struct device *dev)
|
||||
static int ov13b10_check_hwcfg(struct device *dev, struct ov13b10 *ov13b)
|
||||
{
|
||||
struct v4l2_fwnode_endpoint bus_cfg = {
|
||||
.bus_type = V4L2_MBUS_CSI2_DPHY
|
||||
|
@ -1433,6 +1512,7 @@ static int ov13b10_check_hwcfg(struct device *dev)
|
|||
unsigned int i, j;
|
||||
int ret;
|
||||
u32 ext_clk;
|
||||
u8 dlane;
|
||||
|
||||
if (!fwnode)
|
||||
return -ENXIO;
|
||||
|
@ -1459,13 +1539,32 @@ static int ov13b10_check_hwcfg(struct device *dev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV13B10_DATA_LANES) {
|
||||
dlane = bus_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
switch (dlane) {
|
||||
case OV13B10_4_DATA_LANES:
|
||||
ov13b->supported_modes = supported_4_lanes_modes;
|
||||
ov13b->supported_modes_num =
|
||||
ARRAY_SIZE(supported_4_lanes_modes);
|
||||
break;
|
||||
|
||||
case OV13B10_2_DATA_LANES:
|
||||
ov13b->supported_modes = supported_2_lanes_modes;
|
||||
ov13b->supported_modes_num =
|
||||
ARRAY_SIZE(supported_2_lanes_modes);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(dev, "number of CSI2 data lanes %d is not supported",
|
||||
bus_cfg.bus.mipi_csi2.num_data_lanes);
|
||||
dlane);
|
||||
ret = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
ov13b->data_lanes = dlane;
|
||||
ov13b->cur_mode = ov13b->supported_modes;
|
||||
dev_dbg(dev, "%u lanes with %u modes selected\n",
|
||||
ov13b->data_lanes, ov13b->supported_modes_num);
|
||||
|
||||
if (!bus_cfg.nr_of_link_frequencies) {
|
||||
dev_err(dev, "no link frequencies defined");
|
||||
ret = -EINVAL;
|
||||
|
@ -1499,17 +1598,17 @@ static int ov13b10_probe(struct i2c_client *client)
|
|||
bool full_power;
|
||||
int ret;
|
||||
|
||||
ov13b = devm_kzalloc(&client->dev, sizeof(*ov13b), GFP_KERNEL);
|
||||
if (!ov13b)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Check HW config */
|
||||
ret = ov13b10_check_hwcfg(&client->dev);
|
||||
ret = ov13b10_check_hwcfg(&client->dev, ov13b);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to check hwcfg: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ov13b = devm_kzalloc(&client->dev, sizeof(*ov13b), GFP_KERNEL);
|
||||
if (!ov13b)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Initialize subdev */
|
||||
v4l2_i2c_subdev_init(&ov13b->sd, client, &ov13b10_subdev_ops);
|
||||
|
||||
|
@ -1533,9 +1632,6 @@ static int ov13b10_probe(struct i2c_client *client)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set default mode to max resolution */
|
||||
ov13b->cur_mode = &supported_modes[0];
|
||||
|
||||
ret = ov13b10_init_controls(ov13b);
|
||||
if (ret)
|
||||
goto error_power_off;
|
||||
|
|
|
@ -1456,12 +1456,12 @@ static int ov2740_probe(struct i2c_client *client)
|
|||
return 0;
|
||||
|
||||
probe_error_v4l2_subdev_cleanup:
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
v4l2_subdev_cleanup(&ov2740->sd);
|
||||
|
||||
probe_error_media_entity_cleanup:
|
||||
media_entity_cleanup(&ov2740->sd.entity);
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
|
||||
probe_error_v4l2_ctrl_handler_free:
|
||||
v4l2_ctrl_handler_free(ov2740->sd.ctrl_handler);
|
||||
|
|
|
@ -1295,11 +1295,8 @@ static int ov5675_probe(struct i2c_client *client)
|
|||
return -ENOMEM;
|
||||
|
||||
ret = ov5675_get_hwcfg(ov5675, &client->dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to get HW configuration: %d",
|
||||
ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
|
||||
|
||||
|
|
|
@ -2276,8 +2276,8 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
|
|||
if (!is_acpi_node(fwnode)) {
|
||||
ov8856->xvclk = devm_clk_get(dev, "xvclk");
|
||||
if (IS_ERR(ov8856->xvclk)) {
|
||||
dev_err(dev, "could not get xvclk clock (%pe)\n",
|
||||
ov8856->xvclk);
|
||||
dev_err_probe(dev, PTR_ERR(ov8856->xvclk),
|
||||
"could not get xvclk clock\n");
|
||||
return PTR_ERR(ov8856->xvclk);
|
||||
}
|
||||
|
||||
|
@ -2382,11 +2382,8 @@ static int ov8856_probe(struct i2c_client *client)
|
|||
return -ENOMEM;
|
||||
|
||||
ret = ov8856_get_hwcfg(ov8856, &client->dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to get HW configuration: %d",
|
||||
ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
|
@ -575,10 +575,9 @@ static int rdacm20_probe(struct i2c_client *client)
|
|||
dev->dev = &client->dev;
|
||||
dev->serializer.client = client;
|
||||
|
||||
ret = of_property_read_u32_array(client->dev.of_node, "reg",
|
||||
dev->addrs, 2);
|
||||
ret = device_property_read_u32_array(dev->dev, "reg", dev->addrs, 2);
|
||||
if (ret < 0) {
|
||||
dev_err(dev->dev, "Invalid DT reg property: %d\n", ret);
|
||||
dev_err(dev->dev, "Invalid FW reg property: %d\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fwnode.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
|
@ -551,10 +551,9 @@ static int rdacm21_probe(struct i2c_client *client)
|
|||
dev->dev = &client->dev;
|
||||
dev->serializer.client = client;
|
||||
|
||||
ret = of_property_read_u32_array(client->dev.of_node, "reg",
|
||||
dev->addrs, 2);
|
||||
ret = device_property_read_u32_array(dev->dev, "reg", dev->addrs, 2);
|
||||
if (ret < 0) {
|
||||
dev_err(dev->dev, "Invalid DT reg property: %d\n", ret);
|
||||
dev_err(dev->dev, "Invalid FW reg property: %d\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -313,6 +313,10 @@ static int tc358743_get_detected_timings(struct v4l2_subdev *sd,
|
|||
|
||||
memset(timings, 0, sizeof(struct v4l2_dv_timings));
|
||||
|
||||
/* if HPD is low, ignore any video */
|
||||
if (!(i2c_rd8(sd, HPD_CTL) & MASK_HPD_OUT0))
|
||||
return -ENOLINK;
|
||||
|
||||
if (no_signal(sd)) {
|
||||
v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__);
|
||||
return -ENOLINK;
|
||||
|
|
1965
drivers/media/i2c/vd55g1.c
Normal file
1965
drivers/media/i2c/vd55g1.c
Normal file
File diff suppressed because it is too large
Load Diff
1586
drivers/media/i2c/vd56g3.c
Normal file
1586
drivers/media/i2c/vd56g3.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user