media updates for v6.8-rc1

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmWhMN0ACgkQCF8+vY7k
 4RUNmw/9FNwS6woEDPUgoaqBqES5N1R/QzqqWgALQSiywUSWsAnHuALR7Aio4oH4
 IMRrXn3nQpg1wj+f2OtVcXreuf1OMdD0WmQvcj/hcjGIx3mZUh2dBXJpR/iRrCRA
 jbGUDZqsiT9gPf6IcqspFccoShVjQDM7NKLa6xQMpwyITBAXhY0d5LPOs70VJO3f
 EH6wdJbhbQoocylSFCOl61un4Ebk/Zou2TDyzAAnIMQxmanVTWnRE9QL6G59t8PA
 XgTcSRiyQGdNScR8c/xgyHDj4KchvkwFHQfOAH+HPot6CIy+UsC02ofcBralTuN6
 HTiJ8upj9U/N2ArX7L9w4xOFaRlXSO4MBTbQsroCgl7vkSfjMx/Ik5gHNVSoP25y
 MdLVg9ReW6D22tWnHvqpwbv4YPjT1uFX9LzuNtINwjJVC5Hn7EMPiE7hdsBGdKZE
 98dVJKNMUHQT5KfEUqjDkdrcAYm5Pd46trEa1aMDnoxtshxlmwHYwUj0QNKVX2gT
 Wa5lw9twFvmvYPGFwIT11HrkFukj4zR7N7Eh0IOK93zjJl6gtr1UNmujj8KFXJS3
 ZB4yTlcSgFunsmkyfcZ+02bgM9fq7SC1/rL9bXBYxdo2EcuduJ93Gr5riaQtVu44
 6t6Gi8Ucf9Uh7B68Alf0GQAd+AhXPzbqtisHdYJb0ijGjRMhq7w=
 =KPPn
 -----END PGP SIGNATURE-----

Merge tag 'media/v6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

 - v4l core: subdev frame interval now supports which field

 - v4l kapi: moves and renames the init_cfg pad op to init_state as an
   internal op.

 - new sensor drivers: gc0308, gc2145, Avnet Alvium, ov64a40, tw9900

 - new camera driver: STM32 DCMIPP

 - s5p-mfc has gained MFC v12 support

 - new ISP driver added to staging: Starfive

 - new stateful encoder/decoded: Wave5 codec It is found on the J721S2
   SoC, JH7100 SoC, ssd202d SoC. Etc.

 - fwnode gained support for MIPI "DisCo for Imaging"
   (https://www.mipi.org/specifications/mipi-disco-imaging)

 - as usual, lots of cleanups, fixups and driver improvements.

* tag 'media/v6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (309 commits)
  media: i2c: thp7312: select CONFIG_FW_LOADER
  media: i2c: mt9m114: use fsleep() in place of udelay()
  media: videobuf2: core: Rename min_buffers_needed field in vb2_queue
  media: i2c: thp7312: Store frame interval in subdev state
  media: docs: uAPI: Fix documentation of 'which' field for routing ioctls
  media: docs: uAPI: Expand error documentation for invalid 'which' value
  media: docs: uAPI: Clarify error documentation for invalid 'which' value
  media: v4l2-subdev: Store frame interval in subdev state
  media: v4l2-subdev: Add which field to struct v4l2_subdev_frame_interval
  media: v4l2-subdev: Turn .[gs]_frame_interval into pad operations
  media: v4l: subdev: Move out subdev state lock macros outside CONFIG_MEDIA_CONTROLLER
  media: s5p-mfc: DPB Count Independent of VIDIOC_REQBUF
  media: s5p-mfc: Load firmware for each run in MFCv12.
  media: s5p-mfc: Set context for valid case before calling try_run
  media: s5p-mfc: Add support for DMABUF for encoder
  media: s5p-mfc: Add support for UHD encoding.
  media: s5p-mfc: Add support for rate controls in MFCv12
  media: s5p-mfc: Add YV12 and I420 multiplanar format support
  media: s5p-mfc: Add initial support for MFCv12
  media: s5p-mfc: Rename IS_MFCV10 macro
  ...
This commit is contained in:
Linus Torvalds 2024-01-12 14:29:48 -08:00
commit 61da593f44
478 changed files with 38148 additions and 5205 deletions

View File

@ -0,0 +1,72 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
================================
Starfive Camera Subsystem driver
================================
Introduction
------------
This file documents the driver for the Starfive Camera Subsystem found on
Starfive JH7110 SoC. The driver is located under drivers/staging/media/starfive/
camss.
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 successfully used on the Gstreamer 1.18.5 with v4l2src
plugin.
Starfive Camera Subsystem hardware
----------------------------------
The Starfive Camera Subsystem hardware consists of::
|\ +---------------+ +-----------+
+----------+ | \ | | | |
| | | | | | | |
| MIPI |----->| |----->| ISP |----->| |
| | | | | | | |
+----------+ | | | | | Memory |
|MUX| +---------------+ | Interface |
+----------+ | | | |
| | | |---------------------------->| |
| Parallel |----->| | | |
| | | | | |
+----------+ | / | |
|/ +-----------+
- MIPI: The MIPI interface, receiving data from a MIPI CSI-2 camera sensor.
- Parallel: The parallel interface, receiving data from a parallel sensor.
- ISP: The ISP, processing raw Bayer data from an image sensor and producing
YUV frames.
Topology
--------
The media controller pipeline graph is as follows:
.. _starfive_camss_graph:
.. kernel-figure:: starfive_camss_graph.dot
:alt: starfive_camss_graph.dot
:align: center
The driver has 2 video devices:
- capture_raw: The capture device, capturing image data directly from a sensor.
- capture_yuv: The capture device, capturing YUV frame data processed by the
ISP module
The driver has 3 subdevices:
- stf_isp: is responsible for all the isp operations, outputs YUV frames.
- cdns_csi2rx: a CSI-2 bridge supporting up to 4 CSI lanes in input, and 4
different pixel streams in output.
- imx219: an image sensor, image data is sent through MIPI CSI-2.

View File

@ -0,0 +1,12 @@
digraph board {
rankdir=TB
n00000001 [label="{{<port0> 0} | stf_isp\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
n00000001:port1 -> n00000008 [style=dashed]
n00000004 [label="capture_raw\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
n00000008 [label="capture_yuv\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
n0000000e [label="{{<port0> 0} | cdns_csi2rx.19800000.csi-bridge\n | {<port1> 1 | <port2> 2 | <port3> 3 | <port4> 4}}", shape=Mrecord, style=filled, fillcolor=green]
n0000000e:port1 -> n00000001:port0 [style=dashed]
n0000000e:port1 -> n00000004 [style=dashed]
n00000018 [label="{{} | imx219 6-0010\n/dev/v4l-subdev1 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
n00000018:port0 -> n0000000e:port0 [style=bold]
}

View File

@ -28,6 +28,7 @@ Video4Linux (V4L) driver-specific documentation
si470x
si4713
si476x
starfive_camss
vimc
visl
vivid

View File

@ -71,6 +71,7 @@ The following codecs are supported:
- VP9
- H.264
- HEVC
- AV1
visl trace events
-----------------
@ -79,6 +80,7 @@ The trace events are defined on a per-codec basis, e.g.:
.. code-block:: bash
$ ls /sys/kernel/tracing/events/ | grep visl
visl_av1_controls
visl_fwht_controls
visl_h264_controls
visl_hevc_controls

View File

@ -0,0 +1,61 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/cnm,wave521c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Chips&Media Wave 5 Series multi-standard codec IP
maintainers:
- Nas Chung <nas.chung@chipsnmedia.com>
- Jackson Lee <jackson.lee@chipsnmedia.com>
description:
The Chips&Media WAVE codec IP is a multi format video encoder/decoder
properties:
compatible:
items:
- enum:
- ti,k3-j721s2-wave521c
- const: cnm,wave521c
reg:
maxItems: 1
clocks:
items:
- description: VCODEC clock
interrupts:
maxItems: 1
power-domains:
maxItems: 1
resets:
maxItems: 1
sram:
$ref: /schemas/types.yaml#/definitions/phandle
description:
The VPU uses the SRAM to store some of the reference data instead of
storing it on DMA memory. It is mainly used for the purpose of reducing
bandwidth.
required:
- compatible
- reg
- clocks
additionalProperties: false
examples:
- |
vpu: video-codec@12345678 {
compatible = "ti,k3-j721s2-wave521c", "cnm,wave521c";
reg = <0x12345678 0x1000>;
clocks = <&clks 42>;
interrupts = <42>;
sram = <&sram>;
};

View File

@ -0,0 +1,81 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/alliedvision,alvium-csi2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allied Vision Alvium Camera
maintainers:
- Tommaso Merciai <tomm.merciai@gmail.com>
- Martin Hecht <martin.hecht@avnet.eu>
allOf:
- $ref: /schemas/media/video-interface-devices.yaml#
properties:
compatible:
const: alliedvision,alvium-csi2
reg:
maxItems: 1
vcc-ext-in-supply:
description: |
The regulator that supplies power to the VCC_EXT_IN pins.
port:
description: Digital Output Port
$ref: /schemas/graph.yaml#/$defs/port-base
additionalProperties: false
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
link-frequencies: true
data-lanes:
minItems: 1
items:
- const: 1
- const: 2
- const: 3
- const: 4
required:
- data-lanes
- link-frequencies
required:
- compatible
- reg
- vcc-ext-in-supply
- port
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
alvium: camera@3c {
compatible = "alliedvision,alvium-csi2";
reg = <0x3c>;
vcc-ext-in-supply = <&reg_vcc_ext_in>;
port {
alvium_out: endpoint {
remote-endpoint = <&mipi_csi_0_in>;
data-lanes = <1 2 3 4>;
link-frequencies = /bits/ 64 <681250000>;
};
};
};
};
...

View File

@ -15,7 +15,9 @@ description:
properties:
compatible:
const: asahi-kasei,ak7375
enum:
- asahi-kasei,ak7345
- asahi-kasei,ak7375
reg:
maxItems: 1

View File

@ -0,0 +1,108 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc0308.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Galaxycore GC0308 and GC0309 Image Sensors
maintainers:
- Sebastian Reichel <sre@kernel.org>
description: |
The GalaxyCore GC0308 (1/6.5") and GC0309 (1/9") are 640x480 VGA sensors
programmable through an I2C interface and connected via parallel bus.
They include an ISP capable of auto exposure and auto white balance.
allOf:
- $ref: ../video-interface-devices.yaml#
properties:
compatible:
oneOf:
- const: galaxycore,gc0308
- items:
- const: galaxycore,gc0309
- const: galaxycore,gc0308
reg:
const: 0x21
clocks:
description: Reference to the xclk clock.
maxItems: 1
reset-gpios:
description: GPIO descriptor for the reset pin.
maxItems: 1
powerdown-gpios:
description: GPIO descriptor for the powerdown pin.
maxItems: 1
vdd28-supply:
description: 2.8V supply
port:
$ref: /schemas/graph.yaml#/$defs/port-base
description: |
Video output port.
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
bus-width: true
data-shift: true
hsync-active: true
vsync-active: true
data-active: true
pclk-sample: true
required:
- bus-width
additionalProperties: false
required:
- compatible
- reg
- clocks
- powerdown-gpios
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
camera-sensor@21 {
compatible = "galaxycore,gc0308";
reg = <0x21>;
clocks = <&camera_clk>;
powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
vdd28-supply = <&vdd28>;
port {
gc0308_ep: endpoint {
remote-endpoint = <&parallel_from_gc0308>;
bus-width = <8>;
data-shift = <2>; /* lines 9:2 are used */
hsync-active = <1>; /* active high */
vsync-active = <1>; /* active high */
data-active = <1>; /* active high */
pclk-sample = <1>; /* sample on rising edge */
};
};
};
};
...

View File

@ -0,0 +1,113 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc2145.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Galaxy Core 1/5'' UXGA CMOS Image Sensor
maintainers:
- Alain Volmat <alain.volmat@foss.st.com>
description:
The Galaxy Core GC2145 is a 2 Megapixel CMOS image sensor, for mobile
phone camera applications and digital camera products. GC2145 incorporates a
1616V x 1232H active pixel array, on-chip 10-bit ADC, and image signal
processor allowing AE/AWB/interpolation/de-noise/color-conversion and
gamma correction. Bayer RGB, RGB565 and YCbCr 4:2:2 can be provided by the
sensor. It is programmable through an I2C interface. Image data is sent
either through a parallel interface or through MIPI CSI-2.
allOf:
- $ref: ../video-interface-devices.yaml#
properties:
compatible:
const: galaxycore,gc2145
reg:
const: 0x3c
clocks:
maxItems: 1
powerdown-gpios:
maxItems: 1
reset-gpios:
maxItems: 1
iovdd-supply:
description: Power Supply for I/O circuits (1.7 - 3V).
avdd-supply:
description: Power for analog circuit/sensor array (2.7 - 3V).
dvdd-supply:
description: Power for digital core (1.7 - 1.9V).
orientation: true
rotation: true
port:
$ref: /schemas/graph.yaml#/$defs/port-base
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
link-frequencies: true
required:
- link-frequencies
required:
- endpoint
additionalProperties: false
required:
- compatible
- reg
- clocks
- powerdown-gpios
- reset-gpios
- iovdd-supply
- avdd-supply
- dvdd-supply
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
camera@3c {
compatible = "galaxycore,gc2145";
reg = <0x3c>;
clocks = <&clk_ext_camera>;
iovdd-supply = <&scmi_v3v3_sw>;
avdd-supply = <&scmi_v3v3_sw>;
dvdd-supply = <&scmi_v3v3_sw>;
powerdown-gpios = <&mcp23017 3 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
reset-gpios = <&mcp23017 4 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
port {
endpoint {
remote-endpoint = <&mipid02_0>;
data-lanes = <1 2>;
link-frequencies = /bits/ 64 <120000000 192000000 240000000>;
};
};
};
};
...

View File

@ -67,19 +67,17 @@ properties:
properties:
data-lanes:
description: |-
The driver only supports four-lane operation.
items:
- const: 1
- const: 2
- const: 3
- const: 4
link-frequencies:
description: Frequencies listed are driver, not h/w limitations.
maxItems: 2
items:
enum: [ 360000000, 180000000 ]
oneOf:
- items:
- const: 1
- items:
- const: 1
- const: 2
- items:
- const: 1
- const: 2
- const: 3
- const: 4
required:
- link-frequencies

View File

@ -0,0 +1,103 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/ovti,ov64a40.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: OmniVision OV64A40 Image Sensor
maintainers:
- Jacopo Mondi <jacopo.mondi@ideasonboard.com>
allOf:
- $ref: /schemas/media/video-interface-devices.yaml#
properties:
compatible:
const: ovti,ov64a40
reg:
maxItems: 1
clocks:
maxItems: 1
avdd-supply:
description: Analog voltage supply, 2.8 volts
dvdd-supply:
description: Digital core voltage supply, 1.1 volts
dovdd-supply:
description: Digital I/O voltage supply, 1.8 volts
powerdown-gpios:
maxItems: 1
reset-gpios:
maxItems: 1
port:
$ref: /schemas/graph.yaml#/$defs/port-base
additionalProperties: false
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
additionalProperties: false
properties:
bus-type:
enum:
- 1 # MIPI CSI-2 C-PHY
- 4 # MIPI CSI-2 D-PHY
data-lanes: true
link-frequencies: true
clock-noncontinuous: true
remote-endpoint: true
required:
- bus-type
- data-lanes
- link-frequencies
required:
- compatible
- reg
- clocks
- port
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
camera@36 {
compatible = "ovti,ov64a40";
reg = <0x36>;
clocks = <&camera_clk>;
dovdd-supply = <&vgen4_reg>;
avdd-supply = <&vgen3_reg>;
dvdd-supply = <&vgen2_reg>;
powerdown-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
rotation = <180>;
orientation = <2>;
port {
endpoint {
remote-endpoint = <&mipi_csi2_in>;
bus-type = <4>;
data-lanes = <1 2 3 4>;
link-frequencies = /bits/ 64 <456000000>;
};
};
};
};
...

View File

@ -32,6 +32,15 @@ properties:
description: Clock frequency from 6 to 27 MHz, 37.125MHz, 74.25MHz
maxItems: 1
avdd-supply:
description: Analog power supply (2.9V)
ovdd-supply:
description: Interface power supply (1.8V)
dvdd-supply:
description: Digital power supply (1.2V)
reset-gpios:
description: Reference to the GPIO connected to the XCLR pin, if any.
maxItems: 1
@ -79,6 +88,10 @@ examples:
assigned-clock-parents = <&imx335_clk_parent>;
assigned-clock-rates = <24000000>;
avdd-supply = <&camera_vdda_2v9>;
ovdd-supply = <&camera_vddo_1v8>;
dvdd-supply = <&camera_vddd_1v2>;
port {
imx335: endpoint {
remote-endpoint = <&cam>;

View File

@ -0,0 +1,137 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/techwell,tw9900.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Techwell TW9900 NTSC/PAL video decoder
maintainers:
- Mehdi Djait <mehdi.djait@bootlin.com>
description:
The tw9900 is a multi-standard video decoder, supporting NTSC, PAL standards
with auto-detection features.
properties:
compatible:
const: techwell,tw9900
reg:
maxItems: 1
vdd-supply:
description: VDD power supply
reset-gpios:
description: GPIO descriptor for the RESET input pin
maxItems: 1
powerdown-gpios:
description: GPIO descriptor for the POWERDOWN input pin
maxItems: 1
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/$defs/port-base
description: Analog input port
properties:
endpoint@0:
$ref: /schemas/graph.yaml#/properties/endpoint
description: CVBS over MUX0
endpoint@1:
$ref: /schemas/graph.yaml#/properties/endpoint
description: CVBS over MUX1
endpoint@2:
$ref: /schemas/graph.yaml#/properties/endpoint
description: Chroma over CIN0 and Y over MUX0
endpoint@3:
$ref: /schemas/graph.yaml#/properties/endpoint
description: Chroma over CIN0 and Y over MUX1
oneOf:
- required:
- endpoint@0
- required:
- endpoint@1
- required:
- endpoint@2
- required:
- endpoint@3
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: Video port for the decoder output.
required:
- port@0
- port@1
required:
- compatible
- ports
- reg
- vdd-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/display/sdtv-standards.h>
#include <dt-bindings/gpio/gpio.h>
composite_connector {
compatible = "composite-video-connector";
label = "tv";
sdtv-standards = <(SDTV_STD_PAL | SDTV_STD_NTSC)>;
port {
composite_to_tw9900: endpoint {
remote-endpoint = <&tw9900_to_composite>;
};
};
};
i2c {
#address-cells = <1>;
#size-cells = <0>;
video-decoder@44 {
compatible = "techwell,tw9900";
reg = <0x44>;
vdd-supply = <&tw9900_supply>;
reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
tw9900_to_composite: endpoint@0 {
reg = <0>;
remote-endpoint = <&composite_to_tw9900>;
};
};
port@1 {
reg = <1>;
endpoint {
remote-endpoint = <&cif_in>;
};
};
};
};
};

View File

@ -0,0 +1,224 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (c) 2023 Ideas on Board
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/i2c/thine,thp7312.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: THine THP7312
maintainers:
- Paul Elder <paul.elder@@ideasonboard.com>
description:
The THP7312 is a standalone ISP controlled over i2c, and is capable of
various image processing and correction functions, including 3A control. It
can be connected to CMOS image sensors from various vendors, supporting both
MIPI CSI-2 and parallel interfaces. It can also output on either MIPI CSI-2
or parallel. The hardware is capable of transmitting and receiving MIPI
interlaved data strams with data types or multiple virtual channel
identifiers.
allOf:
- $ref: /schemas/media/video-interface-devices.yaml#
properties:
compatible:
const: thine,thp7312
reg:
maxItems: 1
clocks:
maxItems: 1
description: CLKI clock input
thine,boot-mode:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1
default: 1
description:
Boot mode of the THP7312, reflecting the value of the BOOT[0] pin strap.
0 is for the SPI/2-wire slave boot, 1 is for the SPI master boot (from
external flash ROM).
reset-gpios:
maxItems: 1
description:
Reference to the GPIO connected to the RESET_N pin, if any.
Must be released (set high) after all supplies are applied.
vddcore-supply:
description:
1.2V supply for core, PLL, MIPI rx and MIPI tx.
vhtermrx-supply:
description:
Supply for input (RX). 1.8V for MIPI, or 1.8/2.8/3.3V for parallel.
vddtx-supply:
description:
Supply for output (TX). 1.8V for MIPI, or 1.8/2.8/3.3V for parallel.
vddhost-supply:
description:
Supply for host interface. 1.8V, 2.8V, or 3.3V.
vddcmos-supply:
description:
Supply for sensor interface. 1.8V, 2.8V, or 3.3V.
vddgpio-0-supply:
description:
Supply for GPIO_0. 1.8V, 2.8V, or 3.3V.
vddgpio-1-supply:
description:
Supply for GPIO_1. 1.8V, 2.8V, or 3.3V.
orientation: true
rotation: true
port:
$ref: /schemas/graph.yaml#/$defs/port-base
additionalProperties: false
properties:
endpoint:
$ref: /schemas/media/video-interfaces.yaml#
unevaluatedProperties: false
properties:
bus-type:
const: 4 # CSI-2 D-PHY
data-lanes:
description:
This property is for lane reordering between the THP7312 and the
SoC. The sensor supports either two-lane, or four-lane operation.
If this property is omitted four-lane operation is assumed. For
two-lane operation the property must be set to <1 2>.
minItems: 2
maxItems: 4
items:
maximum: 4
sensors:
type: object
description: List of connected sensors
properties:
"#address-cells":
const: 1
"#size-cells":
const: 0
patternProperties:
"^sensor@[01]$":
type: object
description:
Sensors connected to the first and second input, with one node per
sensor.
properties:
thine,model:
$ref: /schemas/types.yaml#/definitions/string
description:
Model of the connected sensors. Must be a valid compatible string.
reg:
description: THP7312 input port number
items:
- maximum: 1
data-lanes:
$ref: /schemas/media/video-interfaces.yaml#/properties/data-lanes
items:
maxItems: 4
description:
This property is for lane reordering between the THP7312 and the imaging
sensor that it is connected to.
required:
- reg
- data-lanes
additionalProperties: false
required:
- "#address-cells"
- "#size-cells"
additionalProperties: false
required:
- compatible
- reg
- reset-gpios
- clocks
- vddcore-supply
- vhtermrx-supply
- vddtx-supply
- vddhost-supply
- vddcmos-supply
- vddgpio-0-supply
- vddgpio-1-supply
- sensors
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/media/video-interfaces.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
camera@61 {
compatible = "thine,thp7312";
reg = <0x61>;
pinctrl-names = "default";
pinctrl-0 = <&cam1_pins_default>;
reset-gpios = <&pio 119 GPIO_ACTIVE_LOW>;
clocks = <&camera61_clk>;
vddcore-supply = <&vsys_v4p2>;
vhtermrx-supply = <&vsys_v4p2>;
vddtx-supply = <&vsys_v4p2>;
vddhost-supply = <&vsys_v4p2>;
vddcmos-supply = <&vsys_v4p2>;
vddgpio-0-supply = <&vsys_v4p2>;
vddgpio-1-supply = <&vsys_v4p2>;
orientation = <0>;
rotation = <0>;
sensors {
#address-cells = <1>;
#size-cells = <0>;
sensor@0 {
thine,model = "sony,imx258";
reg = <0>;
data-lanes = <4 1 3 2>;
};
};
port {
thp7312_2_endpoint: endpoint {
remote-endpoint = <&mipi_thp7312_2>;
bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
data-lanes = <4 2 1 3>;
};
};
};
};
...

View File

@ -90,15 +90,16 @@ properties:
description: connection point for input on the parallel interface
properties:
bus-type:
enum: [5, 6]
endpoint:
$ref: video-interfaces.yaml#
unevaluatedProperties: false
required:
- bus-type
properties:
bus-type:
enum: [5, 6]
required:
- bus-type
anyOf:
- required:

View File

@ -24,6 +24,7 @@ properties:
- samsung,mfc-v7 # Exynos5420
- samsung,mfc-v8 # Exynos5800
- samsung,mfc-v10 # Exynos7880
- tesla,fsd-mfc # Tesla FSD
- items:
- enum:
- samsung,exynos3250-mfc # Exynos3250
@ -165,6 +166,23 @@ allOf:
minItems: 1
maxItems: 2
- if:
properties:
compatible:
contains:
enum:
- tesla,fsd-mfc
then:
properties:
clocks:
maxItems: 1
clock-names:
items:
- const: mfc
iommus:
maxItems: 2
iommus-names: false
examples:
- |
#include <dt-bindings/clock/exynos4.h>

View File

@ -0,0 +1,89 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/st,stm32-dcmipp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 DCMIPP Digital Camera Memory Interface Pixel Processor
maintainers:
- Hugues Fruchet <hugues.fruchet@foss.st.com>
- Alain Volmat <alain.volmat@foss.st.com>
properties:
compatible:
const: st,stm32mp13-dcmipp
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
resets:
maxItems: 1
port:
$ref: /schemas/graph.yaml#/$defs/port-base
unevaluatedProperties: false
description:
DCMIPP supports a single port node with parallel bus.
properties:
endpoint:
$ref: video-interfaces.yaml#
unevaluatedProperties: false
properties:
bus-type:
enum: [5, 6]
default: 5
bus-width:
enum: [8, 10, 12, 14]
default: 8
pclk-sample: true
hsync-active: true
vsync-active: true
required:
- pclk-sample
required:
- compatible
- reg
- interrupts
- clocks
- resets
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/stm32mp13-clks.h>
#include <dt-bindings/reset/stm32mp13-resets.h>
dcmipp@5a000000 {
compatible = "st,stm32mp13-dcmipp";
reg = <0x5a000000 0x400>;
interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
resets = <&rcc DCMIPP_R>;
clocks = <&rcc DCMIPP_K>;
port {
endpoint {
remote-endpoint = <&mipid02_2>;
bus-width = <8>;
hsync-active = <0>;
vsync-active = <0>;
pclk-sample = <0>;
};
};
};
...

View File

@ -0,0 +1,180 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Starfive SoC CAMSS ISP
maintainers:
- Jack Zhu <jack.zhu@starfivetech.com>
- Changhuang Liang <changhuang.liang@starfivetech.com>
description:
The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
consists of a VIN controller (Video In Controller, a top-level control unit)
and an ISP.
properties:
compatible:
const: starfive,jh7110-camss
reg:
maxItems: 2
reg-names:
items:
- const: syscon
- const: isp
clocks:
maxItems: 7
clock-names:
items:
- const: apb_func
- const: wrapper_clk_c
- const: dvp_inv
- const: axiwr
- const: mipi_rx0_pxl
- const: ispcore_2x
- const: isp_axi
resets:
maxItems: 6
reset-names:
items:
- const: wrapper_p
- const: wrapper_c
- const: axird
- const: axiwr
- const: isp_top_n
- const: isp_top_axi
power-domains:
items:
- description: JH7110 ISP Power Domain Switch Controller.
interrupts:
maxItems: 4
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/$defs/port-base
unevaluatedProperties: false
description: Input port for receiving DVP data.
properties:
endpoint:
$ref: video-interfaces.yaml#
unevaluatedProperties: false
properties:
bus-type:
enum: [5, 6]
bus-width:
enum: [8, 10, 12]
data-shift:
enum: [0, 2]
default: 0
hsync-active:
enum: [0, 1]
default: 1
vsync-active:
enum: [0, 1]
default: 1
required:
- bus-type
- bus-width
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: Input port for receiving CSI data.
required:
- port@0
- port@1
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
- resets
- reset-names
- power-domains
- interrupts
- ports
additionalProperties: false
examples:
- |
isp@19840000 {
compatible = "starfive,jh7110-camss";
reg = <0x19840000 0x10000>,
<0x19870000 0x30000>;
reg-names = "syscon", "isp";
clocks = <&ispcrg 0>,
<&ispcrg 13>,
<&ispcrg 2>,
<&ispcrg 12>,
<&ispcrg 1>,
<&syscrg 51>,
<&syscrg 52>;
clock-names = "apb_func",
"wrapper_clk_c",
"dvp_inv",
"axiwr",
"mipi_rx0_pxl",
"ispcore_2x",
"isp_axi";
resets = <&ispcrg 0>,
<&ispcrg 1>,
<&ispcrg 10>,
<&ispcrg 11>,
<&syscrg 41>,
<&syscrg 42>;
reset-names = "wrapper_p",
"wrapper_c",
"axird",
"axiwr",
"isp_top_n",
"isp_top_axi";
power-domains = <&pwrc 5>;
interrupts = <92>, <87>, <88>, <90>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
vin_from_sc2235: endpoint {
remote-endpoint = <&sc2235_to_vin>;
bus-type = <5>;
bus-width = <8>;
data-shift = <2>;
hsync-active = <1>;
vsync-active = <0>;
pclk-sample = <1>;
};
};
port@1 {
reg = <1>;
vin_from_csi2rx: endpoint {
remote-endpoint = <&csi2rx_to_vin>;
};
};
};
};

View File

@ -79,6 +79,8 @@ patternProperties:
description: ALFA Network Inc.
"^allegro,.*":
description: Allegro DVT
"^alliedvision,.*":
description: Allied Vision Technologies GmbH
"^allo,.*":
description: Allo.com
"^allwinner,.*":
@ -508,6 +510,8 @@ patternProperties:
description: Fujitsu Ltd.
"^fxtec,.*":
description: FX Technology Ltd.
"^galaxycore,.*":
description: GalaxyCore Inc.
"^gardena,.*":
description: GARDENA GmbH
"^gateway,.*":
@ -1391,6 +1395,8 @@ patternProperties:
description: Technologic Systems
"^techstar,.*":
description: Shenzhen Techstar Electronics Co., Ltd.
"^techwell,.*":
description: Techwell, Inc.
"^teejet,.*":
description: TeeJet
"^teltonika,.*":

View File

@ -9,8 +9,8 @@ This document covers the in-kernel APIs only. For the best practices on
userspace API implementation in camera sensor drivers, please see
:ref:`media_using_camera_sensor_drivers`.
CSI-2 and parallel (BT.601 and BT.656) busses
---------------------------------------------
CSI-2, parallel and BT.656 buses
--------------------------------
Please see :ref:`transmitter-receiver`.
@ -60,7 +60,8 @@ management over the pipeline.
Camera sensor drivers are responsible for controlling the power state of the
device they otherwise control as well. They shall use runtime PM to manage
power states. Runtime PM shall be enabled at probe time and disabled at remove
time. Drivers should enable runtime PM autosuspend.
time. Drivers should enable runtime PM autosuspend. Also see
:ref:`async sub-device registration <media-registering-async-subdevs>`.
The runtime PM handlers shall handle clocks, regulators, GPIOs, and other
system resources required to power the sensor up and down. For drivers that

View File

@ -82,14 +82,6 @@ for my $fh ($H, $LH) {
print $fh "/* $license */\n$copyright$note\n";
}
sub bit_def($) {
my $bit = shift @_;
return "BIT($bit)" if defined $kernel;
return "(1U << $bit)" if $bit =~ /^[a-zA-Z0-9_]+$/;
return "(1U << ($bit))";
}
print $H <<EOF
#ifndef __${uc_header}__
#define __${uc_header}__
@ -97,23 +89,63 @@ print $H <<EOF
EOF
;
print $H "#include <linux/bits.h>\n\n" if defined $kernel;
print $H <<EOF
#define CCS_FL_BASE 16
#include <linux/bits.h>
#include <media/v4l2-cci.h>
EOF
;
if defined $kernel;
print $H "#define CCS_FL_16BIT " . bit_def("CCS_FL_BASE") . "\n";
print $H "#define CCS_FL_32BIT " . bit_def("CCS_FL_BASE + 1") . "\n";
print $H "#define CCS_FL_FLOAT_IREAL " . bit_def("CCS_FL_BASE + 2") . "\n";
print $H "#define CCS_FL_IREAL " . bit_def("CCS_FL_BASE + 3") . "\n";
print $H "#define CCS_FL_BASE " .
(defined $kernel ? "CCI_REG_PRIVATE_SHIFT" : 16) . "\n";
my $flag = -1;
my $all_flags;
sub bit_def($) {
my $bit = shift @_;
if (defined $kernel) {
return "BIT$bit" if $bit =~ /^\(.*\)$/;
return "BIT($bit)";
}
return "(1U << $bit)";
}
sub flag_str($$) {
my ($flag, $check) = @_;
$$flag++;
my $flag_str = !$$flag ? "CCS_FL_BASE" : "(CCS_FL_BASE + $$flag)";
$flag_str = bit_def($flag_str);
$$check .= " | " if defined $$check;
$$check .= $flag_str;
return $flag_str;
}
if (! defined $kernel) {
print $H "#define CCS_FL_16BIT " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_FL_32BIT " . flag_str(\$flag, \$all_flags) . "\n";
}
print $H "#define CCS_FL_FLOAT_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_FL_IREAL " . flag_str(\$flag, \$all_flags) . "\n";
print $H "#define CCS_BUILD_BUG \\
BUILD_BUG_ON(~CCI_REG_PRIVATE_MASK & ($all_flags))\n"
if defined $kernel;
print $H <<EOF
#define CCS_R_ADDR(r) ((r) & 0xffff)
EOF
;
if ! defined $kernel;
print $A <<EOF
#include <stdint.h>
@ -189,12 +221,12 @@ sub tabconv($) {
return (join "\n", @l) . "\n";
}
sub elem_size(@) {
sub elem_bits(@) {
my @flags = @_;
return 2 if grep /^16$/, @flags;
return 4 if grep /^32$/, @flags;
return 1;
return 16 if grep /^16$/, @flags;
return 32 if grep /^32$/, @flags;
return 8;
}
sub arr_size($) {
@ -296,9 +328,13 @@ while (<$R>) {
next if $#{$this{args}} + 1 != scalar keys %{$this{argparams}};
my $reg_formula = "($this{addr}";
my $reg_formula = "$this{addr}";
my $lim_formula;
chop $reg_formula;
$reg_formula = "(" . $reg_formula if $this{flagstring} ne "";
foreach my $arg (@{$this{args}}) {
my $d = $h->{$arg}->{discontig};
my $times = $h->{$arg}->{elsize} != 1 ?
@ -315,11 +351,13 @@ while (<$R>) {
$lim_formula .= (defined $lim_formula ? " + " : "") . "($arg)$times";
}
$reg_formula .= ")\n";
$reg_formula .= ")";
$lim_formula =~ s/^\(([a-z0-9]+)\)$/$1/i;
print $H tabconv sprintf("#define %-62s %s", "CCS_R_" . (uc $this{name}) .
$this{arglist}, $reg_formula);
$this{arglist}, $reg_formula .
(($this{flagstring} eq "") ? "" :
" | " . $this{flagstring} . ")") . "\n");
print $H tabconv $hdr_data;
undef $hdr_data;
@ -369,16 +407,23 @@ while (<$R>) {
$name =~ s/[,\.-]/_/g;
my $flagstring = "";
my $size = elem_size(@flags);
$flagstring .= "| CCS_FL_16BIT " if $size eq "2";
$flagstring .= "| CCS_FL_32BIT " if $size eq "4";
my $bits = elem_bits(@flags);
if (! defined $kernel) {
$flagstring .= "| CCS_FL_16BIT " if $bits == 16;
$flagstring .= "| CCS_FL_32BIT " if $bits == 32;
}
$flagstring .= "| CCS_FL_FLOAT_IREAL " if grep /^float_ireal$/, @flags;
$flagstring .= "| CCS_FL_IREAL " if grep /^ireal$/, @flags;
$flagstring =~ s/^\| //;
$flagstring =~ s/ $//;
$flagstring = "($flagstring)" if $flagstring =~ /\|/;
my $base_addr = $addr;
$addr = "($addr | $flagstring)" if $flagstring ne "";
$addr = "CCI_REG$bits($addr)" if defined $kernel;
if ($flagstring ne "" && !@$args) {
$addr = "($addr | $flagstring)";
$flagstring = "";
}
my $arglist = @$args ? "(" . (join ", ", @$args) . ")" : "";
$hdr_data .= sprintf "#define %-62s %s\n", "CCS_R_" . (uc $name), $addr
@ -388,11 +433,12 @@ while (<$R>) {
%this = ( name => $name,
addr => $addr,
flagstring => $flagstring,
base_addr => $base_addr,
argparams => {},
args => $args,
arglist => $arglist,
elsize => $size,
elsize => $bits / 8,
);
if (!@$args) {

View File

@ -6,8 +6,8 @@ Pixel data transmitter and receiver drivers
===========================================
V4L2 supports various devices that transmit and receive pixel data. Examples of
these devices include a camera sensor, a TV tuner and a parallel or a CSI-2
receiver in an SoC.
these devices include a camera sensor, a TV tuner and a parallel, a BT.656 or a
CSI-2 receiver in an SoC.
Bus types
---------
@ -22,12 +22,13 @@ the host SoC. It is defined by the `MIPI alliance`_.
.. _`MIPI alliance`: https://www.mipi.org/
Parallel
^^^^^^^^
Parallel and BT.656
^^^^^^^^^^^^^^^^^^^
`BT.601`_ and `BT.656`_ are the most common parallel busses.
The parallel and `BT.656`_ buses transport one bit of data on each clock cycle
per data line. The parallel bus uses synchronisation and other additional
signals whereas BT.656 embeds synchronisation.
.. _`BT.601`: https://en.wikipedia.org/wiki/Rec._601
.. _`BT.656`: https://en.wikipedia.org/wiki/ITU-R_BT.656
Transmitter drivers
@ -90,8 +91,8 @@ where
pixel rate on the camera sensor's pixel array which is indicated by the
:ref:`V4L2_CID_PIXEL_RATE <v4l2-cid-pixel-rate>` control.
LP-11 and LP-111 modes
^^^^^^^^^^^^^^^^^^^^^^
LP-11 and LP-111 states
^^^^^^^^^^^^^^^^^^^^^^^
As part of transitioning to high speed mode, a CSI-2 transmitter typically
briefly sets the bus to LP-11 or LP-111 state, depending on the PHY. This period
@ -105,7 +106,7 @@ in software, especially when there is no interrupt telling something is
happening.
One way to address this is to configure the transmitter side explicitly to LP-11
or LP-111 mode, which requires support from the transmitter hardware. This is
or LP-111 state, which requires support from the transmitter hardware. This is
not universally available. Many devices return to this state once streaming is
stopped while the state after power-on is LP-00 or LP-000.
@ -116,11 +117,11 @@ transitioning to streaming state, but not yet start streaming. Similarly, the
to call ``.post_streamoff()`` for each successful call of ``.pre_streamon()``.
In the context of CSI-2, the ``.pre_streamon()`` callback is used to transition
the transmitter to the LP-11 or LP-111 mode. This also requires powering on the
the transmitter to the LP-11 or LP-111 state. This also requires powering on the
device, so this should be only done when it is needed.
Receiver drivers that do not need explicit LP-11 or LP-111 mode setup are waived
from calling the two callbacks.
Receiver drivers that do not need explicit LP-11 or LP-111 state setup are
waived from calling the two callbacks.
Stopping the transmitter
^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -181,6 +181,8 @@ You can unregister a sub-device using:
Afterwards the subdev module can be unloaded and
:c:type:`sd <v4l2_subdev>`->dev == ``NULL``.
.. _media-registering-async-subdevs:
Registering asynchronous sub-devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -195,6 +197,11 @@ performed using the :c:func:`v4l2_async_unregister_subdev` call. Subdevices
registered this way are stored in a global list of subdevices, ready to be
picked up by bridge drivers.
Drivers must complete all initialization of the sub-device before
registering it using :c:func:`v4l2_async_register_subdev`, including
enabling runtime PM. This is because the sub-device becomes accessible
as soon as it gets registered.
Asynchronous sub-device notifiers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -562,8 +569,8 @@ device configuration. This is often implemented as e.g. an array of struct
v4l2_mbus_framefmt, one entry for each pad, and similarly for crop and compose
rectangles.
In addition to the active configuration, each subdev file handle has an array of
struct v4l2_subdev_pad_config, managed by the V4L2 core, which contains the try
In addition to the active configuration, each subdev file handle has a struct
v4l2_subdev_state, managed by the V4L2 core, which contains the try
configuration.
To simplify the subdev drivers the V4L2 subdev API now optionally supports a

View File

@ -36,4 +36,5 @@ For more details see the file COPYING in the source distribution of Linux.
npcm-video
omap3isp-uapi
st-vgxy61
thp7312
uvcvideo

View File

@ -0,0 +1,39 @@
.. SPDX-License-Identifier: GPL-2.0-only
THine THP7312 ISP driver
========================
The THP7312 driver implements the following driver-specific controls:
``V4L2_CID_THP7312_LOW_LIGHT_COMPENSATION``
Enable/Disable auto-adjustment, based on lighting conditions, of the frame
rate when auto-exposure is enabled.
``V4L2_CID_THP7312_AUTO_FOCUS_METHOD``
Set method of auto-focus. Only takes effect when auto-focus is enabled.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``0``
- Contrast-based auto-focus
* - ``1``
- PDAF
* - ``2``
- Hybrid of contrast-based and PDAF
Supported values for the control depend on the camera sensor module
connected to the THP7312. If the module doesn't have a focus lens actuator,
this control will not be exposed by the THP7312 driver. If the module has a
controllable focus lens but the sensor doesn't support PDAF, only the
contrast-based auto-focus value will be valid. Otherwise all values for the
controls will be supported.
``V4L2_CID_THP7312_NOISE_REDUCTION_AUTO``
Enable/Disable auto noise reduction.
``V4L2_CID_THP7312_NOISE_REDUCTION_ABSOLUTE``
Set the noise reduction strength, where 0 is the weakest and 10 is the
strongest.

View File

@ -116,9 +116,13 @@ than the number requested.
- ``flags``
- Specifies additional buffer management attributes.
See :ref:`memory-flags`.
* - __u32
- ``reserved``\ [6]
- ``max_num_buffers``
- If the V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS capability flag is set
this field indicates the maximum possible number of buffers
for this queue.
* - __u32
- ``reserved``\ [5]
- A place holder for future extensions. Drivers and applications
must set the array to zero.

View File

@ -295,6 +295,14 @@ still cause this situation.
- ``p_av1_film_grain``
- A pointer to a struct :c:type:`v4l2_ctrl_av1_film_grain`. Valid if this control is
of type ``V4L2_CTRL_TYPE_AV1_FILM_GRAIN``.
* - struct :c:type:`v4l2_ctrl_hdr10_cll_info` *
- ``p_hdr10_cll_info``
- A pointer to a struct :c:type:`v4l2_ctrl_hdr10_cll_info`. Valid if this control is
of type ``V4L2_CTRL_TYPE_HDR10_CLL_INFO``.
* - struct :c:type:`v4l2_ctrl_hdr10_mastering_display` *
- ``p_hdr10_mastering_display``
- A pointer to a struct :c:type:`v4l2_ctrl_hdr10_mastering_display`. Valid if this control is
of type ``V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY``.
* - void *
- ``ptr``
- A pointer to a compound type which can be an N-dimensional array

View File

@ -120,6 +120,7 @@ aborting or finishing any DMA in progress, an implicit
.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:
.. _V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS:
.. _V4L2-BUF-CAP-SUPPORTS-MAX-NUM-BUFFERS:
.. raw:: latex

View File

@ -107,8 +107,7 @@ appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
EINVAL
The struct
:c:type:`v4l2_subdev_frame_interval_enum`
``pad`` references a non-existing pad, one of the ``code``,
``width`` or ``height`` fields are invalid for the given pad or the
``index`` field is out of bounds.
The struct :c:type:`v4l2_subdev_frame_interval_enum` ``pad`` references a
non-existing pad, the ``which`` field has an unsupported value, one of the
``code``, ``width`` or ``height`` fields are invalid for the given pad, or
the ``index`` field is out of bounds.

View File

@ -126,7 +126,6 @@ appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
EINVAL
The struct
:c:type:`v4l2_subdev_frame_size_enum`
``pad`` references a non-existing pad, the ``code`` is invalid for
the given pad or the ``index`` field is out of bounds.
The struct :c:type:`v4l2_subdev_frame_size_enum` ``pad`` references a
non-existing pad, the ``which`` field has an unsupported value, the ``code``
is invalid for the given pad, or the ``index`` field is out of bounds.

View File

@ -158,7 +158,6 @@ appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
EINVAL
The struct
:c:type:`v4l2_subdev_mbus_code_enum`
``pad`` references a non-existing pad, or the ``index`` field is out
of bounds.
The struct :c:type:`v4l2_subdev_mbus_code_enum` ``pad`` references a
non-existing pad, the ``which`` field has an unsupported value, or the
``index`` field is out of bounds.

View File

@ -71,6 +71,11 @@ is unknown to the kernel.
of 'stream' fields (referring to the stream number) with various
ioctls. If this is not set (which is the default), the 'stream' fields
will be forced to 0 by the kernel.
* - ``V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH``
- The client is aware of the :c:type:`v4l2_subdev_frame_interval`
``which`` field. If this is not set (which is the default), the
``which`` field is forced to ``V4L2_SUBDEV_FORMAT_ACTIVE`` by the
kernel.
Return Value
============

View File

@ -118,10 +118,9 @@ EBUSY
``VIDIOC_SUBDEV_S_CROP``
EINVAL
The struct :c:type:`v4l2_subdev_crop` ``pad``
references a non-existing pad, the ``which`` field references a
non-existing format, or cropping is not supported on the given
subdev pad.
The struct :c:type:`v4l2_subdev_crop` ``pad`` references a non-existing pad,
the ``which`` field has an unsupported value, or cropping is not supported
on the given subdev pad.
EPERM
The ``VIDIOC_SUBDEV_S_CROP`` ioctl has been called on a read-only subdevice

View File

@ -140,9 +140,8 @@ EBUSY
fix the problem first. Only returned by ``VIDIOC_SUBDEV_S_FMT``
EINVAL
The struct :c:type:`v4l2_subdev_format`
``pad`` references a non-existing pad, or the ``which`` field
references a non-existing format.
The struct :c:type:`v4l2_subdev_format` ``pad`` references a non-existing
pad, or the ``which`` field has an unsupported value.
EPERM
The ``VIDIOC_SUBDEV_S_FMT`` ioctl has been called on a read-only subdevice

View File

@ -58,8 +58,9 @@ struct
contains the current frame interval as would be returned by a
``VIDIOC_SUBDEV_G_FRAME_INTERVAL`` call.
Calling ``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` on a subdev device node that has been
registered in read-only mode is not allowed. An error is returned and the errno
If the subdev device node has been registered in read-only mode, calls to
``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` are only valid if the ``which`` field is set
to ``V4L2_SUBDEV_FORMAT_TRY``, otherwise an error is returned and the errno
variable is set to ``-EPERM``.
Drivers must not return an error solely because the requested interval
@ -93,7 +94,11 @@ the same sub-device is not defined.
- ``stream``
- Stream identifier.
* - __u32
- ``reserved``\ [8]
- ``which``
- Active or try frame interval, from enum
:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
* - __u32
- ``reserved``\ [7]
- Reserved for future extensions. Applications and drivers must set
the array to zero.
@ -112,11 +117,10 @@ EBUSY
``VIDIOC_SUBDEV_S_FRAME_INTERVAL``
EINVAL
The struct
:c:type:`v4l2_subdev_frame_interval`
``pad`` references a non-existing pad, or the pad doesn't support
frame intervals.
The struct :c:type:`v4l2_subdev_frame_interval` ``pad`` references a
non-existing pad, the ``which`` field has an unsupported value, or the pad
doesn't support frame intervals.
EPERM
The ``VIDIOC_SUBDEV_S_FRAME_INTERVAL`` ioctl has been called on a read-only
subdevice.
subdevice and the ``which`` field is set to ``V4L2_SUBDEV_FORMAT_ACTIVE``.

View File

@ -72,7 +72,7 @@ On a successful ``VIDIOC_SUBDEV_G_ROUTING`` call the driver updates the
* - __u32
- ``which``
- Format to modified, from enum
- Routing table to be accessed, from enum
:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
* - struct :c:type:`v4l2_subdev_route`
- ``routes[]``
@ -140,8 +140,9 @@ ENOSPC
all the available routes the subdevice exposes.
EINVAL
The sink or source pad identifiers reference a non-existing pad, or reference
pads of different types (ie. the sink_pad identifiers refers to a source pad).
The sink or source pad identifiers reference a non-existing pad or reference
pads of different types (ie. the sink_pad identifiers refers to a source
pad), or the ``which`` field has an unsupported value.
E2BIG
The application provided ``num_routes`` for ``VIDIOC_SUBDEV_S_ROUTING`` is

View File

@ -116,10 +116,9 @@ EBUSY
``VIDIOC_SUBDEV_S_SELECTION``
EINVAL
The struct :c:type:`v4l2_subdev_selection`
``pad`` references a non-existing pad, the ``which`` field
references a non-existing format, or the selection target is not
supported on the given subdev pad.
The struct :c:type:`v4l2_subdev_selection` ``pad`` references a
non-existing pad, the ``which`` field has an unsupported value, or the
selection target is not supported on the given subdev pad.
EPERM
The ``VIDIOC_SUBDEV_S_SELECTION`` ioctl has been called on a read-only

View File

@ -699,6 +699,15 @@ S: Maintained
F: Documentation/devicetree/bindings/media/allegro,al5e.yaml
F: drivers/media/platform/allegro-dvt/
ALLIED VISION ALVIUM CAMERA DRIVER
M: Tommaso Merciai <tomm.merciai@gmail.com>
M: Martin Hecht <martin.hecht@avnet.eu>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/alliedvision,alvium-csi2.yaml
F: drivers/media/i2c/alvium-csi2.c
F: drivers/media/i2c/alvium-csi2.h
ALLWINNER A10 CSI DRIVER
M: Maxime Ripard <mripard@kernel.org>
L: linux-media@vger.kernel.org
@ -5160,7 +5169,7 @@ M: Philipp Zabel <p.zabel@pengutronix.de>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/coda.yaml
F: drivers/media/platform/chips-media/
F: drivers/media/platform/chips-media/coda
CODE OF CONDUCT
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
@ -8757,6 +8766,21 @@ F: kernel/futex/*
F: tools/perf/bench/futex*
F: tools/testing/selftests/futex/
GALAXYCORE GC0308 CAMERA SENSOR DRIVER
M: Sebastian Reichel <sre@kernel.org>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/galaxycore,gc0308.yaml
F: drivers/media/i2c/gc0308.c
GALAXYCORE GC2145 SENSOR DRIVER
M: Alain Volmat <alain.volmat@foss.st.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/galaxycore,gc2145.yaml
F: drivers/media/i2c/gc2145.c
GATEWORKS SYSTEM CONTROLLER (GSC) DRIVER
M: Tim Harvey <tharvey@gateworks.com>
S: Maintained
@ -13087,6 +13111,7 @@ MAX96712 QUAD GMSL2 DESERIALIZER DRIVER
M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
F: drivers/staging/media/max96712/max96712.c
MAX9860 MONO AUDIO VOICE CODEC DRIVER
@ -13507,13 +13532,16 @@ W: https://linuxtv.org
T: git git://linuxtv.org/media_tree.git
F: drivers/media/dvb-frontends/stv6111*
MEDIA DRIVERS FOR STM32 - DCMI
MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP
M: Hugues Fruchet <hugues.fruchet@foss.st.com>
M: Alain Volmat <alain.volmat@foss.st.com>
L: linux-media@vger.kernel.org
S: Supported
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml
F: Documentation/devicetree/bindings/media/st,stm32-dcmipp.yaml
F: drivers/media/platform/st/stm32/stm32-dcmi.c
F: drivers/media/platform/st/stm32/stm32-dcmipp/*
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
M: Mauro Carvalho Chehab <mchehab@kernel.org>
@ -16090,6 +16118,14 @@ S: Maintained
T: git git://linuxtv.org/media_tree.git
F: drivers/media/i2c/ov5695.c
OMNIVISION OV64A40 SENSOR DRIVER
M: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/ovti,ov64a40.yaml
F: drivers/media/i2c/ov64a40.c
OMNIVISION OV7670 SENSOR DRIVER
L: linux-media@vger.kernel.org
S: Orphan
@ -20681,6 +20717,15 @@ M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes
F: drivers/net/ethernet/adaptec/starfire*
STARFIVE CAMERA SUBSYSTEM DRIVER
M: Jack Zhu <jack.zhu@starfivetech.com>
M: Changhuang Liang <changhuang.liang@starfivetech.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/admin-guide/media/starfive_camss.rst
F: Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
F: drivers/staging/media/starfive/camss
STARFIVE CRYPTO DRIVER
M: Jia Jie Ho <jiajie.ho@starfivetech.com>
M: William Qiu <william.qiu@starfivetech.com>
@ -21381,6 +21426,12 @@ L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/rc/ttusbir.c
TECHWELL TW9900 VIDEO DECODER
M: Mehdi Djait <mehdi.djait@bootlin.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/i2c/tw9900.c
TECHWELL TW9910 VIDEO DECODER
L: linux-media@vger.kernel.org
S: Orphan
@ -21689,6 +21740,17 @@ S: Maintained
F: Documentation/ABI/testing/sysfs-class-firmware-attributes
F: drivers/platform/x86/think-lmi.?
THP7312 ISP DRIVER
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
M: Paul Elder <paul.elder@ideasonboard.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/thine,thp7312.yaml
F: Documentation/userspace-api/media/drivers/thp7312.rst
F: drivers/media/i2c/thp7312.c
F: include/uapi/linux/thp7312.h
THUNDERBOLT DMA TRAFFIC TEST DRIVER
M: Isaac Hazan <isaac.hazan@intel.com>
L: linux-usb@vger.kernel.org
@ -22834,6 +22896,7 @@ S: Maintained
F: Documentation/driver-api/media/camera-sensor.rst
F: Documentation/driver-api/media/tx-rx.rst
F: drivers/media/i2c/ar*
F: drivers/media/i2c/gc*
F: drivers/media/i2c/hi*
F: drivers/media/i2c/imx*
F: drivers/media/i2c/mt*
@ -23476,6 +23539,14 @@ F: include/linux/watchdog.h
F: include/trace/events/watchdog.h
F: include/uapi/linux/watchdog.h
WAVE5 VPU CODEC DRIVER
M: Nas Chung <nas.chung@chipsnmedia.com>
M: Jackson Lee <jackson.lee@chipsnmedia.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/cnm,wave521c.yaml
F: drivers/media/platform/chips-media/wave5/
WHISKEYCOVE PMIC GPIO DRIVER
M: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
L: linux-gpio@vger.kernel.org

View File

@ -594,6 +594,34 @@ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
return fwnode_call_ptr_op(fwnode, get_name_prefix);
}
/**
* fwnode_name_eq - Return true if node name is equal
* @fwnode: The firmware node
* @name: The name to which to compare the node name
*
* Compare the name provided as an argument to the name of the node, stopping
* the comparison at either NUL or '@' character, whichever comes first. This
* function is generally used for comparing node names while ignoring the
* possible unit address of the node.
*
* Return: true if the node name matches with the name provided in the @name
* argument, false otherwise.
*/
bool fwnode_name_eq(const struct fwnode_handle *fwnode, const char *name)
{
const char *node_name;
ptrdiff_t len;
node_name = fwnode_get_name(fwnode);
if (!node_name)
return false;
len = strchrnul(node_name, '@') - node_name;
return str_has_prefix(node_name, name) == len;
}
EXPORT_SYMBOL_GPL(fwnode_name_eq);
/**
* fwnode_get_parent - Return parent firwmare node
* @fwnode: Firmware whose parent is retrieved

View File

@ -2546,7 +2546,7 @@ static const struct vb2_queue mxt_queue = {
.ops = &mxt_queue_ops,
.mem_ops = &vb2_vmalloc_memops,
.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
.min_buffers_needed = 1,
.min_queued_buffers = 1,
};
static int mxt_vidioc_querycap(struct file *file, void *priv,

View File

@ -847,9 +847,10 @@ static int sur40_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_devs[])
{
struct sur40_state *sur40 = vb2_get_drv_priv(q);
unsigned int q_num_bufs = vb2_get_num_buffers(q);
if (q->num_buffers + *nbuffers < 3)
*nbuffers = 3 - q->num_buffers;
if (q_num_bufs + *nbuffers < 3)
*nbuffers = 3 - q_num_bufs;
if (*nplanes)
return sizes[0] < sur40->pix_fmt.sizeimage ? -EINVAL : 0;
@ -1123,7 +1124,7 @@ static const struct vb2_queue sur40_queue = {
.ops = &sur40_queue_ops,
.mem_ops = &vb2_dma_sg_memops,
.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
.min_buffers_needed = 3,
.min_queued_buffers = 3,
};
static const struct v4l2_file_operations sur40_video_fops = {

View File

@ -511,7 +511,7 @@ int cec_thread_func(void *_adap)
pr_warn("cec-%s: transmit timed out\n", adap->name);
}
adap->transmit_in_progress = false;
adap->tx_timeouts++;
adap->tx_timeout_cnt++;
goto unlock;
}
@ -625,6 +625,33 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
msg->tx_low_drive_cnt += low_drive_cnt;
msg->tx_error_cnt += error_cnt;
adap->tx_arb_lost_cnt += arb_lost_cnt;
adap->tx_low_drive_cnt += low_drive_cnt;
adap->tx_error_cnt += error_cnt;
/*
* Low Drive transmission errors should really not happen for
* well-behaved CEC devices and proper HDMI cables.
*
* Ditto for the 'Error' status.
*
* For the first few times that this happens, log this.
* Stop logging after that, since that will not add any more
* useful information and instead it will just flood the kernel log.
*/
if (done && adap->tx_low_drive_log_cnt < 8 && msg->tx_low_drive_cnt) {
adap->tx_low_drive_log_cnt++;
dprintk(0, "low drive counter: %u (seq %u: %*ph)\n",
msg->tx_low_drive_cnt, msg->sequence,
msg->len, msg->msg);
}
if (done && adap->tx_error_log_cnt < 8 && msg->tx_error_cnt) {
adap->tx_error_log_cnt++;
dprintk(0, "error counter: %u (seq %u: %*ph)\n",
msg->tx_error_cnt, msg->sequence,
msg->len, msg->msg);
}
/* Mark that we're done with this transmit */
adap->transmitting = NULL;
@ -1607,6 +1634,8 @@ int cec_adap_enable(struct cec_adapter *adap)
if (enable) {
adap->last_initiator = 0xff;
adap->transmit_in_progress = false;
adap->tx_low_drive_log_cnt = 0;
adap->tx_error_log_cnt = 0;
ret = adap->ops->adap_enable(adap, true);
if (!ret) {
/*
@ -2265,10 +2294,25 @@ int cec_adap_status(struct seq_file *file, void *priv)
if (adap->monitor_pin_cnt)
seq_printf(file, "file handles in Monitor Pin mode: %u\n",
adap->monitor_pin_cnt);
if (adap->tx_timeouts) {
seq_printf(file, "transmit timeouts: %u\n",
adap->tx_timeouts);
adap->tx_timeouts = 0;
if (adap->tx_timeout_cnt) {
seq_printf(file, "transmit timeout count: %u\n",
adap->tx_timeout_cnt);
adap->tx_timeout_cnt = 0;
}
if (adap->tx_low_drive_cnt) {
seq_printf(file, "transmit low drive count: %u\n",
adap->tx_low_drive_cnt);
adap->tx_low_drive_cnt = 0;
}
if (adap->tx_arb_lost_cnt) {
seq_printf(file, "transmit arbitration lost count: %u\n",
adap->tx_arb_lost_cnt);
adap->tx_arb_lost_cnt = 0;
}
if (adap->tx_error_cnt) {
seq_printf(file, "transmit error count: %u\n",
adap->tx_error_cnt);
adap->tx_error_cnt = 0;
}
data = adap->transmitting;
if (data)

View File

@ -324,6 +324,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
{ "Google", "Boxy", "0000:00:02.0", port_d_conns },
/* Google Taranza */
{ "Google", "Taranza", "0000:00:02.0", port_db_conns },
/* Google Dexi */
{ "Google", "Dexi", "0000:00:02.0", port_db_conns },
};
static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,

View File

@ -387,7 +387,7 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
q->gfp_flags = __GFP_DMA32;
q->buf_struct_size = sizeof(struct saa7146_buf);
q->lock = &dev->v4l2_lock;
q->min_buffers_needed = 2;
q->min_queued_buffers = 2;
q->dev = &dev->pci->dev;
err = vb2_queue_init(q);
if (err)

File diff suppressed because it is too large Load Diff

View File

@ -487,9 +487,15 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf,
static int vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf,
struct iosys_map *map)
{
struct vb2_dma_sg_buf *buf = dbuf->priv;
struct vb2_dma_sg_buf *buf;
void *vaddr;
iosys_map_set_vaddr(map, buf->vaddr);
buf = dbuf->priv;
vaddr = vb2_dma_sg_vaddr(buf->vb, buf);
if (!vaddr)
return -EINVAL;
iosys_map_set_vaddr(map, vaddr);
return 0;
}

View File

@ -364,13 +364,12 @@ static void set_buffer_cache_hints(struct vb2_queue *q,
}
static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
struct v4l2_buffer *b, bool is_prepare,
struct media_request **p_req)
struct vb2_buffer *vb, struct v4l2_buffer *b,
bool is_prepare, struct media_request **p_req)
{
const char *opname = is_prepare ? "prepare_buf" : "qbuf";
struct media_request *req;
struct vb2_v4l2_buffer *vbuf;
struct vb2_buffer *vb;
int ret;
if (b->type != q->type) {
@ -378,23 +377,11 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md
return -EINVAL;
}
if (b->index >= q->num_buffers) {
dprintk(q, 1, "%s: buffer index out of range\n", opname);
return -EINVAL;
}
if (q->bufs[b->index] == NULL) {
/* Should never happen */
dprintk(q, 1, "%s: buffer is NULL\n", opname);
return -EINVAL;
}
if (b->memory != q->memory) {
dprintk(q, 1, "%s: invalid memory type\n", opname);
return -EINVAL;
}
vb = q->bufs[b->index];
vbuf = to_vb2_v4l2_buffer(vb);
ret = __verify_planes_array(vb, b);
if (ret)
@ -628,11 +615,22 @@ static const struct vb2_buf_ops v4l2_buf_ops = {
struct vb2_buffer *vb2_find_buffer(struct vb2_queue *q, u64 timestamp)
{
unsigned int i;
struct vb2_buffer *vb2;
for (i = 0; i < q->num_buffers; i++)
if (q->bufs[i]->copied_timestamp &&
q->bufs[i]->timestamp == timestamp)
return vb2_get_buffer(q, i);
/*
* This loop doesn't scale if there is a really large number of buffers.
* Maybe something more efficient will be needed in this case.
*/
for (i = 0; i < q->max_num_buffers; i++) {
vb2 = vb2_get_buffer(q, i);
if (!vb2)
continue;
if (vb2->copied_timestamp &&
vb2->timestamp == timestamp)
return vb2;
}
return NULL;
}
EXPORT_SYMBOL_GPL(vb2_find_buffer);
@ -660,14 +658,15 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
return -EINVAL;
}
if (b->index >= q->num_buffers) {
dprintk(q, 1, "buffer index out of range\n");
vb = vb2_get_buffer(q, b->index);
if (!vb) {
dprintk(q, 1, "can't find the requested buffer %u\n", b->index);
return -EINVAL;
}
vb = q->bufs[b->index];
ret = __verify_planes_array(vb, b);
if (!ret)
vb2_core_querybuf(q, b->index, b);
vb2_core_querybuf(q, vb, b);
return ret;
}
EXPORT_SYMBOL(vb2_querybuf);
@ -685,10 +684,8 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
*caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
if (q->allow_cache_hints && q->io_modes & VB2_MMAP)
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS;
#ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API
if (q->supports_requests)
*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
#endif
}
static void validate_memory_flags(struct vb2_queue *q,
@ -723,6 +720,7 @@ EXPORT_SYMBOL_GPL(vb2_reqbufs);
int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
struct v4l2_buffer *b)
{
struct vb2_buffer *vb;
int ret;
if (vb2_fileio_is_active(q)) {
@ -733,9 +731,15 @@ int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev,
if (b->flags & V4L2_BUF_FLAG_REQUEST_FD)
return -EINVAL;
ret = vb2_queue_or_prepare_buf(q, mdev, b, true, NULL);
vb = vb2_get_buffer(q, b->index);
if (!vb) {
dprintk(q, 1, "can't find the requested buffer %u\n", b->index);
return -EINVAL;
}
return ret ? ret : vb2_core_prepare_buf(q, b->index, b);
ret = vb2_queue_or_prepare_buf(q, mdev, vb, b, true, NULL);
return ret ? ret : vb2_core_prepare_buf(q, vb, b);
}
EXPORT_SYMBOL_GPL(vb2_prepare_buf);
@ -749,7 +753,9 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
fill_buf_caps(q, &create->capabilities);
validate_memory_flags(q, create->memory, &create->flags);
create->index = q->num_buffers;
create->index = vb2_get_num_buffers(q);
create->max_num_buffers = q->max_num_buffers;
create->capabilities |= V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS;
if (create->count == 0)
return ret != -EBUSY ? ret : 0;
@ -803,6 +809,7 @@ int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev,
struct v4l2_buffer *b)
{
struct media_request *req = NULL;
struct vb2_buffer *vb;
int ret;
if (vb2_fileio_is_active(q)) {
@ -810,10 +817,16 @@ int vb2_qbuf(struct vb2_queue *q, struct media_device *mdev,
return -EBUSY;
}
ret = vb2_queue_or_prepare_buf(q, mdev, b, false, &req);
vb = vb2_get_buffer(q, b->index);
if (!vb) {
dprintk(q, 1, "can't find the requested buffer %u\n", b->index);
return -EINVAL;
}
ret = vb2_queue_or_prepare_buf(q, mdev, vb, b, false, &req);
if (ret)
return ret;
ret = vb2_core_qbuf(q, b->index, b, req);
ret = vb2_core_qbuf(q, vb, b, req);
if (req)
media_request_put(req);
return ret;
@ -873,7 +886,15 @@ EXPORT_SYMBOL_GPL(vb2_streamoff);
int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
{
return vb2_core_expbuf(q, &eb->fd, eb->type, eb->index,
struct vb2_buffer *vb;
vb = vb2_get_buffer(q, eb->index);
if (!vb) {
dprintk(q, 1, "can't find the requested buffer %u\n", eb->index);
return -EINVAL;
}
return vb2_core_expbuf(q, &eb->fd, eb->type, vb,
eb->plane, eb->flags);
}
EXPORT_SYMBOL_GPL(vb2_expbuf);
@ -1115,7 +1136,7 @@ int _vb2_fop_release(struct file *file, struct mutex *lock)
if (lock)
mutex_lock(lock);
if (file->private_data == vdev->queue->owner) {
if (!vdev->queue->owner || file->private_data == vdev->queue->owner) {
vb2_queue_release(vdev->queue);
vdev->queue->owner = NULL;
}
@ -1243,7 +1264,7 @@ void vb2_video_unregister_device(struct video_device *vdev)
*/
get_device(&vdev->dev);
video_unregister_device(vdev);
if (vdev->queue && vdev->queue->owner) {
if (vdev->queue) {
struct mutex *lock = vdev->queue->lock ?
vdev->queue->lock : vdev->lock;

View File

@ -167,17 +167,14 @@ int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
memset(ctx, 0, sizeof(struct dvb_vb2_ctx));
q->type = DVB_BUF_TYPE_CAPTURE;
/**capture type*/
q->is_output = 0;
/**only mmap is supported currently*/
q->io_modes = VB2_MMAP;
q->drv_priv = ctx;
q->buf_struct_size = sizeof(struct dvb_buffer);
q->min_buffers_needed = 1;
q->min_queued_buffers = 1;
q->ops = &dvb_vb2_qops;
q->mem_ops = &vb2_vmalloc_memops;
q->buf_ops = &dvb_vb2_buf_ops;
q->num_buffers = 0;
ret = vb2_core_queue_init(q);
if (ret) {
ctx->state = DVB_VB2_STATE_NONE;
@ -355,12 +352,13 @@ int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
{
struct vb2_queue *q = &ctx->vb_q;
struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);
if (b->index >= q->num_buffers) {
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
if (!vb2) {
dprintk(1, "[%s] invalid buffer index\n", ctx->name);
return -EINVAL;
}
vb2_core_querybuf(&ctx->vb_q, b->index, b);
vb2_core_querybuf(&ctx->vb_q, vb2, b);
dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
return 0;
}
@ -370,7 +368,7 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
struct vb2_queue *q = &ctx->vb_q;
int ret;
ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, exp->index,
ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, q->bufs[exp->index],
0, exp->flags);
if (ret) {
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
@ -385,13 +383,14 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
{
struct vb2_queue *q = &ctx->vb_q;
struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);
int ret;
if (b->index >= q->num_buffers) {
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
if (!vb2) {
dprintk(1, "[%s] invalid buffer index\n", ctx->name);
return -EINVAL;
}
ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL);
ret = vb2_core_qbuf(&ctx->vb_q, vb2, b, NULL);
if (ret) {
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
b->index, ret);

View File

@ -104,6 +104,8 @@ static int dvb_device_open(struct inode *inode, struct file *file)
err = file->f_op->open(inode, file);
up_read(&minor_rwsem);
mutex_unlock(&dvbdev_mutex);
if (err)
dvb_device_put(dvbdev);
return err;
}
fail:

View File

@ -1894,7 +1894,7 @@ static int m88ds3103_probe(struct i2c_client *client)
/* get frontend address */
ret = regmap_read(dev->regmap, 0x29, &utmp);
if (ret)
goto err_kfree;
goto err_del_adapters;
dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1;
dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr);
@ -1902,11 +1902,14 @@ static int m88ds3103_probe(struct i2c_client *client)
dev->dt_addr);
if (IS_ERR(dev->dt_client)) {
ret = PTR_ERR(dev->dt_client);
goto err_kfree;
goto err_del_adapters;
}
}
return 0;
err_del_adapters:
i2c_mux_del_adapters(dev->muxc);
err_kfree:
kfree(dev);
err:

View File

@ -439,12 +439,13 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
{
struct rtl2832_sdr_dev *dev = vb2_get_drv_priv(vq);
struct platform_device *pdev = dev->pdev;
unsigned int q_num_bufs = vb2_get_num_buffers(vq);
dev_dbg(&pdev->dev, "nbuffers=%d\n", *nbuffers);
/* Need at least 8 buffers */
if (vq->num_buffers + *nbuffers < 8)
*nbuffers = 8 - vq->num_buffers;
if (q_num_bufs + *nbuffers < 8)
*nbuffers = 8 - q_num_bufs;
*nplanes = 1;
sizes[0] = PAGE_ALIGN(dev->buffersize);
dev_dbg(&pdev->dev, "nbuffers=%d sizes[0]=%d\n", *nbuffers, sizes[0]);

View File

@ -41,6 +41,16 @@ config VIDEO_APTINA_PLL
config VIDEO_CCS_PLL
tristate
config VIDEO_ALVIUM_CSI2
tristate "Allied Vision ALVIUM MIPI CSI-2 camera support"
select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor-level driver for the Allied Vision
ALVIUM camera connected via MIPI CSI-2 interface.
To compile this driver as a module, choose M here: the
module will be called alvium-csi2.
config VIDEO_AR0521
tristate "ON Semiconductor AR0521 sensor support"
help
@ -50,6 +60,26 @@ config VIDEO_AR0521
To compile this driver as a module, choose M here: the
module will be called ar0521.
config VIDEO_GC0308
tristate "GalaxyCore GC0308 sensor support"
select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the GalaxyCore
GC0308 camera.
To compile this driver as a module, choose M here: the
module will be called gc0308.
config VIDEO_GC2145
select V4L2_CCI_I2C
tristate "GalaxyCore GC2145 sensor support"
help
This is a V4L2 sensor-level driver for GalaxyCore GC2145
2 Mpixel camera.
To compile this driver as a module, choose M here: the
module will be called gc2145.
config VIDEO_HI556
tristate "Hynix Hi-556 sensor support"
help
@ -455,6 +485,16 @@ config VIDEO_OV5695
To compile this driver as a module, choose M here: the
module will be called ov5695.
config VIDEO_OV64A40
tristate "OmniVision OV64A40 sensor support"
select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the OmniVision
OV64A40 camera.
To compile this driver as a module, choose M here: the
module will be called ov64a40.
config VIDEO_OV6650
tristate "OmniVision OV6650 sensor support"
help
@ -628,6 +668,23 @@ source "drivers/media/i2c/et8ek8/Kconfig"
endif
menu "Camera ISPs"
visible if MEDIA_CAMERA_SUPPORT
config VIDEO_THP7312
tristate "THine THP7312 support"
depends on I2C
select FW_LOADER
select MEDIA_CONTROLLER
select V4L2_CCI_I2C
select V4L2_FWNODE
select VIDEO_V4L2_SUBDEV_API
help
This is a Video4Linux2 sensor-level driver for the THine
THP7312 ISP.
endmenu
menu "Lens drivers"
visible if MEDIA_CAMERA_SUPPORT
@ -1186,6 +1243,21 @@ config VIDEO_TW2804
To compile this driver as a module, choose M here: the
module will be called tw2804.
config VIDEO_TW9900
tristate "Techwell TW9900 video decoder"
depends on GPIOLIB
depends on VIDEO_DEV && I2C
depends on PM
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
select V4L2_ASYNC
help
Support for the Techwell TW9900 multi-standard video decoder.
It supports NTSC, PAL standards with auto-detection features.
To compile this driver as a module, choose M here: the
module will be called tw9900.
config VIDEO_TW9903
tristate "Techwell TW9903 video decoder"
depends on VIDEO_DEV && I2C
@ -1432,6 +1504,7 @@ config VIDEO_ST_MIPID02
depends on I2C && VIDEO_DEV
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API
select V4L2_CCI_I2C
select V4L2_FWNODE
help
Support for STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge.

View File

@ -17,6 +17,7 @@ obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o
obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o
obj-$(CONFIG_VIDEO_AK7375) += ak7375.o
obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
obj-$(CONFIG_VIDEO_ALVIUM_CSI2) += alvium-csi2.o
obj-$(CONFIG_VIDEO_APTINA_PLL) += aptina-pll.o
obj-$(CONFIG_VIDEO_AR0521) += ar0521.o
obj-$(CONFIG_VIDEO_BT819) += bt819.o
@ -36,6 +37,8 @@ obj-$(CONFIG_VIDEO_DW9719) += dw9719.o
obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
obj-$(CONFIG_VIDEO_HI556) += hi556.o
obj-$(CONFIG_VIDEO_HI846) += hi846.o
obj-$(CONFIG_VIDEO_HI847) += hi847.o
@ -92,6 +95,7 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
obj-$(CONFIG_VIDEO_OV64A40) += ov64a40.o
obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
@ -128,6 +132,7 @@ obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
obj-$(CONFIG_VIDEO_THP7312) += thp7312.o
obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
obj-$(CONFIG_VIDEO_THS8200) += ths8200.o
obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
@ -136,6 +141,7 @@ obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
obj-$(CONFIG_VIDEO_TW2804) += tw2804.o
obj-$(CONFIG_VIDEO_TW9900) += tw9900.o
obj-$(CONFIG_VIDEO_TW9903) += tw9903.o
obj-$(CONFIG_VIDEO_TW9906) += tw9906.o
obj-$(CONFIG_VIDEO_TW9910) += tw9910.o

View File

@ -463,11 +463,19 @@ static int adv7180_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
return 0;
}
static int adv7180_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
static int adv7180_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct adv7180_state *state = to_state(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (state->curr_norm & V4L2_STD_525_60) {
fi->interval.numerator = 1001;
fi->interval.denominator = 30000;
@ -769,7 +777,7 @@ static int adv7180_get_pad_format(struct v4l2_subdev *sd,
struct adv7180_state *state = to_state(sd);
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
format->format = *v4l2_subdev_get_try_format(sd, sd_state, 0);
format->format = *v4l2_subdev_state_get_format(sd_state, 0);
} else {
adv7180_mbus_fmt(sd, &format->format);
format->format.field = state->field;
@ -806,15 +814,15 @@ static int adv7180_set_pad_format(struct v4l2_subdev *sd,
adv7180_set_power(state, true);
}
} else {
framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0);
framefmt = v4l2_subdev_state_get_format(sd_state, 0);
*framefmt = format->format;
}
return ret;
}
static int adv7180_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int adv7180_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_subdev_format fmt = {
.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
@ -913,7 +921,6 @@ static int adv7180_subscribe_event(struct v4l2_subdev *sd,
static const struct v4l2_subdev_video_ops adv7180_video_ops = {
.s_std = adv7180_s_std,
.g_std = adv7180_g_std,
.g_frame_interval = adv7180_g_frame_interval,
.querystd = adv7180_querystd,
.g_input_status = adv7180_g_input_status,
.s_routing = adv7180_s_routing,
@ -929,10 +936,10 @@ static const struct v4l2_subdev_core_ops adv7180_core_ops = {
};
static const struct v4l2_subdev_pad_ops adv7180_pad_ops = {
.init_cfg = adv7180_init_cfg,
.enum_mbus_code = adv7180_enum_mbus_code,
.set_fmt = adv7180_set_pad_format,
.get_fmt = adv7180_get_pad_format,
.get_frame_interval = adv7180_get_frame_interval,
.get_mbus_config = adv7180_get_mbus_config,
};
@ -947,6 +954,10 @@ static const struct v4l2_subdev_ops adv7180_ops = {
.sensor = &adv7180_sensor_ops,
};
static const struct v4l2_subdev_internal_ops adv7180_internal_ops = {
.init_state = adv7180_init_state,
};
static irqreturn_t adv7180_irq(int irq, void *devid)
{
struct adv7180_state *state = devid;
@ -1458,6 +1469,7 @@ static int adv7180_probe(struct i2c_client *client)
state->input = 0;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
sd->internal_ops = &adv7180_internal_ops;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
ret = adv7180_init_controls(state);

View File

@ -442,8 +442,6 @@ static int adv7183_set_fmt(struct v4l2_subdev *sd,
}
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
decoder->fmt = *fmt;
else
sd_state->pads->try_fmt = *fmt;
return 0;
}

View File

@ -354,8 +354,8 @@ static int adv748x_afe_get_format(struct v4l2_subdev *sd,
return -EINVAL;
if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) {
mbusformat = v4l2_subdev_get_try_format(sd, sd_state,
sdformat->pad);
mbusformat = v4l2_subdev_state_get_format(sd_state,
sdformat->pad);
sdformat->format = *mbusformat;
} else {
adv748x_afe_fill_format(afe, &sdformat->format);
@ -378,7 +378,7 @@ static int adv748x_afe_set_format(struct v4l2_subdev *sd,
if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
return adv748x_afe_get_format(sd, sd_state, sdformat);
mbusformat = v4l2_subdev_get_try_format(sd, sd_state, sdformat->pad);
mbusformat = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
*mbusformat = sdformat->format;
return 0;

View File

@ -147,7 +147,7 @@ adv748x_csi2_get_pad_format(struct v4l2_subdev *sd,
struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
if (which == V4L2_SUBDEV_FORMAT_TRY)
return v4l2_subdev_get_try_format(sd, sd_state, pad);
return v4l2_subdev_state_get_format(sd_state, pad);
return &tx->format;
}

View File

@ -441,8 +441,8 @@ static int adv748x_hdmi_get_format(struct v4l2_subdev *sd,
return -EINVAL;
if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) {
mbusformat = v4l2_subdev_get_try_format(sd, sd_state,
sdformat->pad);
mbusformat = v4l2_subdev_state_get_format(sd_state,
sdformat->pad);
sdformat->format = *mbusformat;
} else {
adv748x_hdmi_fill_format(hdmi, &sdformat->format);
@ -464,7 +464,7 @@ static int adv748x_hdmi_set_format(struct v4l2_subdev *sd,
if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
return adv748x_hdmi_get_format(sd, sd_state, sdformat);
mbusformat = v4l2_subdev_get_try_format(sd, sd_state, sdformat->pad);
mbusformat = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
*mbusformat = sdformat->format;
return 0;

View File

@ -1238,7 +1238,7 @@ static int adv7511_get_fmt(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
format->format.code = fmt->code;
format->format.colorspace = fmt->colorspace;
format->format.ycbcr_enc = fmt->ycbcr_enc;
@ -1293,7 +1293,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
fmt->code = format->format.code;
fmt->colorspace = format->format.colorspace;
fmt->ycbcr_enc = format->format.ycbcr_enc;

View File

@ -1929,7 +1929,7 @@ static int adv76xx_get_format(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
format->format.code = fmt->code;
} else {
format->format.code = state->format->code;
@ -1978,7 +1978,7 @@ static int adv76xx_set_format(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
fmt->code = format->format.code;
} else {
state->format = info;

View File

@ -2087,7 +2087,7 @@ static int adv7842_get_format(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
format->format.code = fmt->code;
} else {
format->format.code = state->format->code;
@ -2119,7 +2119,7 @@ static int adv7842_set_format(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
fmt->code = format->format.code;
} else {
state->format = info;

View File

@ -10,30 +10,60 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#define AK7375_MAX_FOCUS_POS 4095
/*
* This sets the minimum granularity for the focus positions.
* A value of 1 gives maximum accuracy for a desired focus position
*/
#define AK7375_FOCUS_STEPS 1
/*
* This acts as the minimum granularity of lens movement.
* Keep this value power of 2, so the control steps can be
* uniformly adjusted for gradual lens movement, with desired
* number of control steps.
*/
#define AK7375_CTRL_STEPS 64
#define AK7375_CTRL_DELAY_US 1000
/*
* The vcm may take up 10 ms (tDELAY) to power on and start taking
* I2C messages. Based on AK7371 datasheet.
*/
#define AK7375_POWER_DELAY_US 10000
struct ak73xx_chipdef {
u8 reg_position;
u8 reg_cont;
u8 shift_pos;
u8 mode_active;
u8 mode_standby;
bool has_standby; /* Some chips may not have standby mode */
u16 focus_pos_max;
/*
* This sets the minimum granularity for the focus positions.
* A value of 1 gives maximum accuracy for a desired focus position
*/
u16 focus_steps;
/*
* This acts as the minimum granularity of lens movement.
* Keep this value power of 2, so the control steps can be
* uniformly adjusted for gradual lens movement, with desired
* number of control steps.
*/
u16 ctrl_steps;
u16 ctrl_delay_us;
/*
* The vcm may take time (tDELAY) to power on and start taking
* I2C messages.
*/
u16 power_delay_us;
};
#define AK7375_REG_POSITION 0x0
#define AK7375_REG_CONT 0x2
#define AK7375_MODE_ACTIVE 0x0
#define AK7375_MODE_STANDBY 0x40
static const struct ak73xx_chipdef ak7345_cdef = {
.reg_position = 0x0,
.reg_cont = 0x2,
.shift_pos = 7, /* 9 bits position values, need to << 7 */
.mode_active = 0x0,
.has_standby = false,
.focus_pos_max = 511,
.focus_steps = 1,
.ctrl_steps = 16,
.ctrl_delay_us = 1000,
.power_delay_us = 20000,
};
static const struct ak73xx_chipdef ak7375_cdef = {
.reg_position = 0x0,
.reg_cont = 0x2,
.shift_pos = 4, /* 12 bits position values, need to << 4 */
.mode_active = 0x0,
.mode_standby = 0x40,
.has_standby = true,
.focus_pos_max = 4095,
.focus_steps = 1,
.ctrl_steps = 64,
.ctrl_delay_us = 1000,
.power_delay_us = 10000,
};
static const char * const ak7375_supply_names[] = {
"vdd",
@ -42,6 +72,7 @@ static const char * const ak7375_supply_names[] = {
/* ak7375 device structure */
struct ak7375_device {
const struct ak73xx_chipdef *cdef;
struct v4l2_ctrl_handler ctrls_vcm;
struct v4l2_subdev sd;
struct v4l2_ctrl *focus;
@ -86,10 +117,11 @@ static int ak7375_i2c_write(struct ak7375_device *ak7375,
static int ak7375_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ak7375_device *dev_vcm = to_ak7375_vcm(ctrl);
const struct ak73xx_chipdef *cdef = dev_vcm->cdef;
if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
return ak7375_i2c_write(dev_vcm, AK7375_REG_POSITION,
ctrl->val << 4, 2);
return ak7375_i2c_write(dev_vcm, cdef->reg_position,
ctrl->val << cdef->shift_pos, 2);
return -EINVAL;
}
@ -128,11 +160,12 @@ static int ak7375_init_controls(struct ak7375_device *dev_vcm)
{
struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
const struct v4l2_ctrl_ops *ops = &ak7375_vcm_ctrl_ops;
const struct ak73xx_chipdef *cdef = dev_vcm->cdef;
v4l2_ctrl_handler_init(hdl, 1);
dev_vcm->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
0, AK7375_MAX_FOCUS_POS, AK7375_FOCUS_STEPS, 0);
0, cdef->focus_pos_max, cdef->focus_steps, 0);
if (hdl->error)
dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
@ -153,6 +186,8 @@ static int ak7375_probe(struct i2c_client *client)
if (!ak7375_dev)
return -ENOMEM;
ak7375_dev->cdef = device_get_match_data(&client->dev);
for (i = 0; i < ARRAY_SIZE(ak7375_supply_names); i++)
ak7375_dev->supplies[i].supply = ak7375_supply_names[i];
@ -206,32 +241,35 @@ static void ak7375_remove(struct i2c_client *client)
/*
* This function sets the vcm position, so it consumes least current
* The lens position is gradually moved in units of AK7375_CTRL_STEPS,
* The lens position is gradually moved in units of ctrl_steps,
* to make the movements smoothly.
*/
static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct ak7375_device *ak7375_dev = sd_to_ak7375_vcm(sd);
const struct ak73xx_chipdef *cdef = ak7375_dev->cdef;
int ret, val;
if (!ak7375_dev->active)
return 0;
for (val = ak7375_dev->focus->val & ~(AK7375_CTRL_STEPS - 1);
val >= 0; val -= AK7375_CTRL_STEPS) {
ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_POSITION,
val << 4, 2);
for (val = ak7375_dev->focus->val & ~(cdef->ctrl_steps - 1);
val >= 0; val -= cdef->ctrl_steps) {
ret = ak7375_i2c_write(ak7375_dev, cdef->reg_position,
val << cdef->shift_pos, 2);
if (ret)
dev_err_once(dev, "%s I2C failure: %d\n",
__func__, ret);
usleep_range(AK7375_CTRL_DELAY_US, AK7375_CTRL_DELAY_US + 10);
usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10);
}
ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_CONT,
AK7375_MODE_STANDBY, 1);
if (ret)
dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
if (cdef->has_standby) {
ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont,
cdef->mode_standby, 1);
if (ret)
dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
}
ret = regulator_bulk_disable(ARRAY_SIZE(ak7375_supply_names),
ak7375_dev->supplies);
@ -246,13 +284,14 @@ static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
/*
* This function sets the vcm position to the value set by the user
* through v4l2_ctrl_ops s_ctrl handler
* The lens position is gradually moved in units of AK7375_CTRL_STEPS,
* The lens position is gradually moved in units of ctrl_steps,
* to make the movements smoothly.
*/
static int __maybe_unused ak7375_vcm_resume(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct ak7375_device *ak7375_dev = sd_to_ak7375_vcm(sd);
const struct ak73xx_chipdef *cdef = ak7375_dev->cdef;
int ret, val;
if (ak7375_dev->active)
@ -264,24 +303,24 @@ static int __maybe_unused ak7375_vcm_resume(struct device *dev)
return ret;
/* Wait for vcm to become ready */
usleep_range(AK7375_POWER_DELAY_US, AK7375_POWER_DELAY_US + 500);
usleep_range(cdef->power_delay_us, cdef->power_delay_us + 500);
ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_CONT,
AK7375_MODE_ACTIVE, 1);
ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont,
cdef->mode_active, 1);
if (ret) {
dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
return ret;
}
for (val = ak7375_dev->focus->val % AK7375_CTRL_STEPS;
for (val = ak7375_dev->focus->val % cdef->ctrl_steps;
val <= ak7375_dev->focus->val;
val += AK7375_CTRL_STEPS) {
ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_POSITION,
val << 4, 2);
val += cdef->ctrl_steps) {
ret = ak7375_i2c_write(ak7375_dev, cdef->reg_position,
val << cdef->shift_pos, 2);
if (ret)
dev_err_ratelimited(dev, "%s I2C failure: %d\n",
__func__, ret);
usleep_range(AK7375_CTRL_DELAY_US, AK7375_CTRL_DELAY_US + 10);
usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10);
}
ak7375_dev->active = true;
@ -290,7 +329,8 @@ static int __maybe_unused ak7375_vcm_resume(struct device *dev)
}
static const struct of_device_id ak7375_of_table[] = {
{ .compatible = "asahi-kasei,ak7375" },
{ .compatible = "asahi-kasei,ak7345", .data = &ak7345_cdef, },
{ .compatible = "asahi-kasei,ak7375", .data = &ak7375_cdef, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ak7375_of_table);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,475 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Allied Vision Technologies GmbH Alvium camera driver
*
* Copyright (C) 2023 Tommaso Merciai
* Copyright (C) 2023 Martin Hecht
* Copyright (C) 2023 Avnet EMG GmbH
*/
#ifndef ALVIUM_CSI2_H_
#define ALVIUM_CSI2_H_
#include <linux/kernel.h>
#include <linux/regulator/consumer.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#define REG_BCRM_V4L2 BIT(31)
#define REG_BCRM_V4L2_8BIT(n) (REG_BCRM_V4L2 | CCI_REG8(n))
#define REG_BCRM_V4L2_16BIT(n) (REG_BCRM_V4L2 | CCI_REG16(n))
#define REG_BCRM_V4L2_32BIT(n) (REG_BCRM_V4L2 | CCI_REG32(n))
#define REG_BCRM_V4L2_64BIT(n) (REG_BCRM_V4L2 | CCI_REG64(n))
/* Basic Control Register Map register offsets (BCRM) */
#define REG_BCRM_MINOR_VERSION_R CCI_REG16(0x0000)
#define REG_BCRM_MAJOR_VERSION_R CCI_REG16(0x0002)
#define REG_BCRM_REG_ADDR_R CCI_REG16(0x0014)
#define REG_BCRM_FEATURE_INQUIRY_R REG_BCRM_V4L2_64BIT(0x0008)
#define REG_BCRM_DEVICE_FW_SPEC_VERSION_R REG_BCRM_V4L2_8BIT(0x0010)
#define REG_BCRM_DEVICE_FW_MAJOR_VERSION_R REG_BCRM_V4L2_8BIT(0x0011)
#define REG_BCRM_DEVICE_FW_MINOR_VERSION_R REG_BCRM_V4L2_16BIT(0x0012)
#define REG_BCRM_DEVICE_FW_PATCH_VERSION_R REG_BCRM_V4L2_32BIT(0x0014)
#define REG_BCRM_WRITE_HANDSHAKE_RW REG_BCRM_V4L2_8BIT(0x0018)
/* Streaming Control Registers */
#define REG_BCRM_SUPPORTED_CSI2_LANE_COUNTS_R REG_BCRM_V4L2_8BIT(0x0040)
#define REG_BCRM_CSI2_LANE_COUNT_RW REG_BCRM_V4L2_8BIT(0x0044)
#define REG_BCRM_CSI2_CLOCK_MIN_R REG_BCRM_V4L2_32BIT(0x0048)
#define REG_BCRM_CSI2_CLOCK_MAX_R REG_BCRM_V4L2_32BIT(0x004c)
#define REG_BCRM_CSI2_CLOCK_RW REG_BCRM_V4L2_32BIT(0x0050)
#define REG_BCRM_BUFFER_SIZE_R REG_BCRM_V4L2_32BIT(0x0054)
#define REG_BCRM_IPU_X_MIN_W REG_BCRM_V4L2_32BIT(0x0058)
#define REG_BCRM_IPU_X_MAX_W REG_BCRM_V4L2_32BIT(0x005c)
#define REG_BCRM_IPU_X_INC_W REG_BCRM_V4L2_32BIT(0x0060)
#define REG_BCRM_IPU_Y_MIN_W REG_BCRM_V4L2_32BIT(0x0064)
#define REG_BCRM_IPU_Y_MAX_W REG_BCRM_V4L2_32BIT(0x0068)
#define REG_BCRM_IPU_Y_INC_W REG_BCRM_V4L2_32BIT(0x006c)
#define REG_BCRM_IPU_X_R REG_BCRM_V4L2_32BIT(0x0070)
#define REG_BCRM_IPU_Y_R REG_BCRM_V4L2_32BIT(0x0074)
#define REG_BCRM_PHY_RESET_RW REG_BCRM_V4L2_8BIT(0x0078)
#define REG_BCRM_LP2HS_DELAY_RW REG_BCRM_V4L2_32BIT(0x007c)
/* Acquisition Control Registers */
#define REG_BCRM_ACQUISITION_START_RW REG_BCRM_V4L2_8BIT(0x0080)
#define REG_BCRM_ACQUISITION_STOP_RW REG_BCRM_V4L2_8BIT(0x0084)
#define REG_BCRM_ACQUISITION_ABORT_RW REG_BCRM_V4L2_8BIT(0x0088)
#define REG_BCRM_ACQUISITION_STATUS_R REG_BCRM_V4L2_8BIT(0x008c)
#define REG_BCRM_ACQUISITION_FRAME_RATE_RW REG_BCRM_V4L2_64BIT(0x0090)
#define REG_BCRM_ACQUISITION_FRAME_RATE_MIN_R REG_BCRM_V4L2_64BIT(0x0098)
#define REG_BCRM_ACQUISITION_FRAME_RATE_MAX_R REG_BCRM_V4L2_64BIT(0x00a0)
#define REG_BCRM_ACQUISITION_FRAME_RATE_INC_R REG_BCRM_V4L2_64BIT(0x00a8)
#define REG_BCRM_ACQUISITION_FRAME_RATE_ENABLE_RW REG_BCRM_V4L2_8BIT(0x00b0)
#define REG_BCRM_FRAME_START_TRIGGER_MODE_RW REG_BCRM_V4L2_8BIT(0x00b4)
#define REG_BCRM_FRAME_START_TRIGGER_SOURCE_RW REG_BCRM_V4L2_8BIT(0x00b8)
#define REG_BCRM_FRAME_START_TRIGGER_ACTIVATION_RW REG_BCRM_V4L2_8BIT(0x00bc)
#define REG_BCRM_FRAME_START_TRIGGER_SOFTWARE_W REG_BCRM_V4L2_8BIT(0x00c0)
#define REG_BCRM_FRAME_START_TRIGGER_DELAY_RW REG_BCRM_V4L2_32BIT(0x00c4)
#define REG_BCRM_EXPOSURE_ACTIVE_LINE_MODE_RW REG_BCRM_V4L2_8BIT(0x00c8)
#define REG_BCRM_EXPOSURE_ACTIVE_LINE_SELECTOR_RW REG_BCRM_V4L2_8BIT(0x00cc)
#define REG_BCRM_LINE_CONFIGURATION_RW REG_BCRM_V4L2_32BIT(0x00d0)
#define REG_BCRM_IMG_WIDTH_RW REG_BCRM_V4L2_32BIT(0x0100)
#define REG_BCRM_IMG_WIDTH_MIN_R REG_BCRM_V4L2_32BIT(0x0104)
#define REG_BCRM_IMG_WIDTH_MAX_R REG_BCRM_V4L2_32BIT(0x0108)
#define REG_BCRM_IMG_WIDTH_INC_R REG_BCRM_V4L2_32BIT(0x010c)
#define REG_BCRM_IMG_HEIGHT_RW REG_BCRM_V4L2_32BIT(0x0110)
#define REG_BCRM_IMG_HEIGHT_MIN_R REG_BCRM_V4L2_32BIT(0x0114)
#define REG_BCRM_IMG_HEIGHT_MAX_R REG_BCRM_V4L2_32BIT(0x0118)
#define REG_BCRM_IMG_HEIGHT_INC_R REG_BCRM_V4L2_32BIT(0x011c)
#define REG_BCRM_IMG_OFFSET_X_RW REG_BCRM_V4L2_32BIT(0x0120)
#define REG_BCRM_IMG_OFFSET_X_MIN_R REG_BCRM_V4L2_32BIT(0x0124)
#define REG_BCRM_IMG_OFFSET_X_MAX_R REG_BCRM_V4L2_32BIT(0x0128)
#define REG_BCRM_IMG_OFFSET_X_INC_R REG_BCRM_V4L2_32BIT(0x012c)
#define REG_BCRM_IMG_OFFSET_Y_RW REG_BCRM_V4L2_32BIT(0x0130)
#define REG_BCRM_IMG_OFFSET_Y_MIN_R REG_BCRM_V4L2_32BIT(0x0134)
#define REG_BCRM_IMG_OFFSET_Y_MAX_R REG_BCRM_V4L2_32BIT(0x0138)
#define REG_BCRM_IMG_OFFSET_Y_INC_R REG_BCRM_V4L2_32BIT(0x013c)
#define REG_BCRM_IMG_MIPI_DATA_FORMAT_RW REG_BCRM_V4L2_32BIT(0x0140)
#define REG_BCRM_IMG_AVAILABLE_MIPI_DATA_FORMATS_R REG_BCRM_V4L2_64BIT(0x0148)
#define REG_BCRM_IMG_BAYER_PATTERN_INQUIRY_R REG_BCRM_V4L2_8BIT(0x0150)
#define REG_BCRM_IMG_BAYER_PATTERN_RW REG_BCRM_V4L2_8BIT(0x0154)
#define REG_BCRM_IMG_REVERSE_X_RW REG_BCRM_V4L2_8BIT(0x0158)
#define REG_BCRM_IMG_REVERSE_Y_RW REG_BCRM_V4L2_8BIT(0x015c)
#define REG_BCRM_SENSOR_WIDTH_R REG_BCRM_V4L2_32BIT(0x0160)
#define REG_BCRM_SENSOR_HEIGHT_R REG_BCRM_V4L2_32BIT(0x0164)
#define REG_BCRM_WIDTH_MAX_R REG_BCRM_V4L2_32BIT(0x0168)
#define REG_BCRM_HEIGHT_MAX_R REG_BCRM_V4L2_32BIT(0x016c)
#define REG_BCRM_EXPOSURE_TIME_RW REG_BCRM_V4L2_64BIT(0x0180)
#define REG_BCRM_EXPOSURE_TIME_MIN_R REG_BCRM_V4L2_64BIT(0x0188)
#define REG_BCRM_EXPOSURE_TIME_MAX_R REG_BCRM_V4L2_64BIT(0x0190)
#define REG_BCRM_EXPOSURE_TIME_INC_R REG_BCRM_V4L2_64BIT(0x0198)
#define REG_BCRM_EXPOSURE_AUTO_RW REG_BCRM_V4L2_8BIT(0x01a0)
#define REG_BCRM_INTENSITY_AUTO_PRECEDENCE_RW REG_BCRM_V4L2_8BIT(0x01a4)
#define REG_BCRM_INTENSITY_AUTO_PRECEDENCE_VALUE_RW REG_BCRM_V4L2_32BIT(0x01a8)
#define REG_BCRM_INTENSITY_AUTO_PRECEDENCE_MIN_R REG_BCRM_V4L2_32BIT(0x01ac)
#define REG_BCRM_INTENSITY_AUTO_PRECEDENCE_MAX_R REG_BCRM_V4L2_32BIT(0x01b0)
#define REG_BCRM_INTENSITY_AUTO_PRECEDENCE_INC_R REG_BCRM_V4L2_32BIT(0x01b4)
#define REG_BCRM_BLACK_LEVEL_RW REG_BCRM_V4L2_32BIT(0x01b8)
#define REG_BCRM_BLACK_LEVEL_MIN_R REG_BCRM_V4L2_32BIT(0x01bc)
#define REG_BCRM_BLACK_LEVEL_MAX_R REG_BCRM_V4L2_32BIT(0x01c0)
#define REG_BCRM_BLACK_LEVEL_INC_R REG_BCRM_V4L2_32BIT(0x01c4)
#define REG_BCRM_GAIN_RW REG_BCRM_V4L2_64BIT(0x01c8)
#define REG_BCRM_GAIN_MIN_R REG_BCRM_V4L2_64BIT(0x01d0)
#define REG_BCRM_GAIN_MAX_R REG_BCRM_V4L2_64BIT(0x01d8)
#define REG_BCRM_GAIN_INC_R REG_BCRM_V4L2_64BIT(0x01e0)
#define REG_BCRM_GAIN_AUTO_RW REG_BCRM_V4L2_8BIT(0x01e8)
#define REG_BCRM_GAMMA_RW REG_BCRM_V4L2_64BIT(0x01f0)
#define REG_BCRM_GAMMA_MIN_R REG_BCRM_V4L2_64BIT(0x01f8)
#define REG_BCRM_GAMMA_MAX_R REG_BCRM_V4L2_64BIT(0x0200)
#define REG_BCRM_GAMMA_INC_R REG_BCRM_V4L2_64BIT(0x0208)
#define REG_BCRM_CONTRAST_VALUE_RW REG_BCRM_V4L2_32BIT(0x0214)
#define REG_BCRM_CONTRAST_VALUE_MIN_R REG_BCRM_V4L2_32BIT(0x0218)
#define REG_BCRM_CONTRAST_VALUE_MAX_R REG_BCRM_V4L2_32BIT(0x021c)
#define REG_BCRM_CONTRAST_VALUE_INC_R REG_BCRM_V4L2_32BIT(0x0220)
#define REG_BCRM_SATURATION_RW REG_BCRM_V4L2_32BIT(0x0240)
#define REG_BCRM_SATURATION_MIN_R REG_BCRM_V4L2_32BIT(0x0244)
#define REG_BCRM_SATURATION_MAX_R REG_BCRM_V4L2_32BIT(0x0248)
#define REG_BCRM_SATURATION_INC_R REG_BCRM_V4L2_32BIT(0x024c)
#define REG_BCRM_HUE_RW REG_BCRM_V4L2_32BIT(0x0250)
#define REG_BCRM_HUE_MIN_R REG_BCRM_V4L2_32BIT(0x0254)
#define REG_BCRM_HUE_MAX_R REG_BCRM_V4L2_32BIT(0x0258)
#define REG_BCRM_HUE_INC_R REG_BCRM_V4L2_32BIT(0x025c)
#define REG_BCRM_ALL_BALANCE_RATIO_RW REG_BCRM_V4L2_64BIT(0x0260)
#define REG_BCRM_ALL_BALANCE_RATIO_MIN_R REG_BCRM_V4L2_64BIT(0x0268)
#define REG_BCRM_ALL_BALANCE_RATIO_MAX_R REG_BCRM_V4L2_64BIT(0x0270)
#define REG_BCRM_ALL_BALANCE_RATIO_INC_R REG_BCRM_V4L2_64BIT(0x0278)
#define REG_BCRM_RED_BALANCE_RATIO_RW REG_BCRM_V4L2_64BIT(0x0280)
#define REG_BCRM_RED_BALANCE_RATIO_MIN_R REG_BCRM_V4L2_64BIT(0x0288)
#define REG_BCRM_RED_BALANCE_RATIO_MAX_R REG_BCRM_V4L2_64BIT(0x0290)
#define REG_BCRM_RED_BALANCE_RATIO_INC_R REG_BCRM_V4L2_64BIT(0x0298)
#define REG_BCRM_GREEN_BALANCE_RATIO_RW REG_BCRM_V4L2_64BIT(0x02a0)
#define REG_BCRM_GREEN_BALANCE_RATIO_MIN_R REG_BCRM_V4L2_64BIT(0x02a8)
#define REG_BCRM_GREEN_BALANCE_RATIO_MAX_R REG_BCRM_V4L2_64BIT(0x02b0)
#define REG_BCRM_GREEN_BALANCE_RATIO_INC_R REG_BCRM_V4L2_64BIT(0x02b8)
#define REG_BCRM_BLUE_BALANCE_RATIO_RW REG_BCRM_V4L2_64BIT(0x02c0)
#define REG_BCRM_BLUE_BALANCE_RATIO_MIN_R REG_BCRM_V4L2_64BIT(0x02c8)
#define REG_BCRM_BLUE_BALANCE_RATIO_MAX_R REG_BCRM_V4L2_64BIT(0x02d0)
#define REG_BCRM_BLUE_BALANCE_RATIO_INC_R REG_BCRM_V4L2_64BIT(0x02d8)
#define REG_BCRM_WHITE_BALANCE_AUTO_RW REG_BCRM_V4L2_8BIT(0x02e0)
#define REG_BCRM_SHARPNESS_RW REG_BCRM_V4L2_32BIT(0x0300)
#define REG_BCRM_SHARPNESS_MIN_R REG_BCRM_V4L2_32BIT(0x0304)
#define REG_BCRM_SHARPNESS_MAX_R REG_BCRM_V4L2_32BIT(0x0308)
#define REG_BCRM_SHARPNESS_INC_R REG_BCRM_V4L2_32BIT(0x030c)
#define REG_BCRM_DEVICE_TEMPERATURE_R REG_BCRM_V4L2_32BIT(0x0310)
#define REG_BCRM_EXPOSURE_AUTO_MIN_RW REG_BCRM_V4L2_64BIT(0x0330)
#define REG_BCRM_EXPOSURE_AUTO_MAX_RW REG_BCRM_V4L2_64BIT(0x0338)
#define REG_BCRM_GAIN_AUTO_MIN_RW REG_BCRM_V4L2_64BIT(0x0340)
#define REG_BCRM_GAIN_AUTO_MAX_RW REG_BCRM_V4L2_64BIT(0x0348)
/* Heartbeat reg*/
#define REG_BCRM_HEARTBEAT_RW CCI_REG8(0x021f)
/* GenCP Registers */
#define REG_GENCP_CHANGEMODE_W CCI_REG8(0x021c)
#define REG_GENCP_CURRENTMODE_R CCI_REG8(0x021d)
#define REG_GENCP_IN_HANDSHAKE_RW CCI_REG8(0x001c)
#define REG_GENCP_OUT_SIZE_W CCI_REG16(0x0020)
#define REG_GENCP_IN_SIZE_R CCI_REG16(0x0024)
/* defines */
#define REG_BCRM_HANDSHAKE_STATUS_MASK 0x01
#define REG_BCRM_HANDSHAKE_AVAILABLE_MASK 0x80
#define BCRM_HANDSHAKE_W_DONE_EN_BIT BIT(0)
#define ALVIUM_DEFAULT_FR_HZ 10
#define ALVIUM_DEFAULT_PIXEL_RATE_MHZ 148000000
#define ALVIUM_LP2HS_DELAY_MS 100
enum alvium_bcrm_mode {
ALVIUM_BCM_MODE,
ALVIUM_GENCP_MODE,
ALVIUM_NUM_MODE
};
enum alvium_mipi_fmt {
ALVIUM_FMT_UYVY8_2X8 = 0,
ALVIUM_FMT_UYVY8_1X16,
ALVIUM_FMT_YUYV8_1X16,
ALVIUM_FMT_YUYV8_2X8,
ALVIUM_FMT_YUYV10_1X20,
ALVIUM_FMT_RGB888_1X24,
ALVIUM_FMT_RBG888_1X24,
ALVIUM_FMT_BGR888_1X24,
ALVIUM_FMT_RGB888_3X8,
ALVIUM_FMT_Y8_1X8,
ALVIUM_FMT_SGRBG8_1X8,
ALVIUM_FMT_SRGGB8_1X8,
ALVIUM_FMT_SGBRG8_1X8,
ALVIUM_FMT_SBGGR8_1X8,
ALVIUM_FMT_Y10_1X10,
ALVIUM_FMT_SGRBG10_1X10,
ALVIUM_FMT_SRGGB10_1X10,
ALVIUM_FMT_SGBRG10_1X10,
ALVIUM_FMT_SBGGR10_1X10,
ALVIUM_FMT_Y12_1X12,
ALVIUM_FMT_SGRBG12_1X12,
ALVIUM_FMT_SRGGB12_1X12,
ALVIUM_FMT_SGBRG12_1X12,
ALVIUM_FMT_SBGGR12_1X12,
ALVIUM_FMT_SBGGR14_1X14,
ALVIUM_FMT_SGBRG14_1X14,
ALVIUM_FMT_SRGGB14_1X14,
ALVIUM_FMT_SGRBG14_1X14,
ALVIUM_NUM_SUPP_MIPI_DATA_FMT
};
enum alvium_av_bayer_bit {
ALVIUM_BIT_BAY_NONE = -1,
ALVIUM_BIT_BAY_MONO = 0,
ALVIUM_BIT_BAY_GR,
ALVIUM_BIT_BAY_RG,
ALVIUM_BIT_BAY_GB,
ALVIUM_BIT_BAY_BG,
ALVIUM_NUM_BAY_AV_BIT
};
enum alvium_av_mipi_bit {
ALVIUM_BIT_YUV420_8_LEG = 0,
ALVIUM_BIT_YUV420_8,
ALVIUM_BIT_YUV420_10,
ALVIUM_BIT_YUV420_8_CSPS,
ALVIUM_BIT_YUV420_10_CSPS,
ALVIUM_BIT_YUV422_8,
ALVIUM_BIT_YUV422_10,
ALVIUM_BIT_RGB888,
ALVIUM_BIT_RGB666,
ALVIUM_BIT_RGB565,
ALVIUM_BIT_RGB555,
ALVIUM_BIT_RGB444,
ALVIUM_BIT_RAW6,
ALVIUM_BIT_RAW7,
ALVIUM_BIT_RAW8,
ALVIUM_BIT_RAW10,
ALVIUM_BIT_RAW12,
ALVIUM_BIT_RAW14,
ALVIUM_BIT_JPEG,
ALVIUM_NUM_SUPP_MIPI_DATA_BIT
};
struct alvium_avail_feat {
u64 rev_x:1;
u64 rev_y:1;
u64 int_autop:1;
u64 black_lvl:1;
u64 gain:1;
u64 gamma:1;
u64 contrast:1;
u64 sat:1;
u64 hue:1;
u64 whiteb:1;
u64 sharp:1;
u64 auto_exp:1;
u64 auto_gain:1;
u64 auto_whiteb:1;
u64 dev_temp:1;
u64 acq_abort:1;
u64 acq_fr:1;
u64 fr_trigger:1;
u64 exp_acq_line:1;
u64 reserved:45;
};
struct alvium_avail_mipi_fmt {
u64 yuv420_8_leg:1;
u64 yuv420_8:1;
u64 yuv420_10:1;
u64 yuv420_8_csps:1;
u64 yuv420_10_csps:1;
u64 yuv422_8:1;
u64 yuv422_10:1;
u64 rgb888:1;
u64 rgb666:1;
u64 rgb565:1;
u64 rgb555:1;
u64 rgb444:1;
u64 raw6:1;
u64 raw7:1;
u64 raw8:1;
u64 raw10:1;
u64 raw12:1;
u64 raw14:1;
u64 jpeg:1;
u64 reserved:45;
};
struct alvium_avail_bayer {
u8 mono:1;
u8 gr:1;
u8 rg:1;
u8 gb:1;
u8 bg:1;
u8 reserved:3;
};
struct alvium_mode {
struct v4l2_rect crop;
struct v4l2_mbus_framefmt fmt;
u32 width;
u32 height;
};
struct alvium_pixfmt {
u32 code;
u32 colorspace;
u64 mipi_fmt_regval;
u64 bay_fmt_regval;
u8 id;
u8 is_raw;
u8 fmt_av_bit;
u8 bay_av_bit;
};
struct alvium_ctrls {
struct v4l2_ctrl_handler handler;
struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *auto_exp;
struct v4l2_ctrl *exposure;
struct v4l2_ctrl *auto_wb;
struct v4l2_ctrl *blue_balance;
struct v4l2_ctrl *red_balance;
struct v4l2_ctrl *auto_gain;
struct v4l2_ctrl *gain;
struct v4l2_ctrl *saturation;
struct v4l2_ctrl *hue;
struct v4l2_ctrl *contrast;
struct v4l2_ctrl *gamma;
struct v4l2_ctrl *sharpness;
struct v4l2_ctrl *hflip;
struct v4l2_ctrl *vflip;
};
struct alvium_dev {
struct i2c_client *i2c_client;
struct v4l2_subdev sd;
struct v4l2_fwnode_endpoint ep;
struct media_pad pad;
struct regmap *regmap;
struct regulator *reg_vcc;
u16 bcrm_addr;
struct alvium_avail_feat avail_ft;
u8 is_mipi_fmt_avail[ALVIUM_NUM_SUPP_MIPI_DATA_BIT];
u8 is_bay_avail[ALVIUM_NUM_BAY_AV_BIT];
u32 min_csi_clk;
u32 max_csi_clk;
u32 dft_img_width;
u32 img_min_width;
u32 img_max_width;
u32 img_inc_width;
u32 dft_img_height;
u32 img_min_height;
u32 img_max_height;
u32 img_inc_height;
u32 min_offx;
u32 max_offx;
u32 inc_offx;
u32 min_offy;
u32 max_offy;
u32 inc_offy;
u64 dft_gain;
u64 min_gain;
u64 max_gain;
u64 inc_gain;
u64 dft_exp;
u64 min_exp;
u64 max_exp;
u64 inc_exp;
u64 dft_rbalance;
u64 min_rbalance;
u64 max_rbalance;
u64 inc_rbalance;
u64 dft_bbalance;
u64 min_bbalance;
u64 max_bbalance;
u64 inc_bbalance;
s32 dft_hue;
s32 min_hue;
s32 max_hue;
s32 inc_hue;
u32 dft_contrast;
u32 min_contrast;
u32 max_contrast;
u32 inc_contrast;
u32 dft_sat;
u32 min_sat;
u32 max_sat;
u32 inc_sat;
s32 dft_black_lvl;
s32 min_black_lvl;
s32 max_black_lvl;
s32 inc_black_lvl;
u64 dft_gamma;
u64 min_gamma;
u64 max_gamma;
u64 inc_gamma;
s32 dft_sharp;
s32 min_sharp;
s32 max_sharp;
s32 inc_sharp;
struct alvium_mode mode;
struct v4l2_fract frame_interval;
u64 dft_fr;
u64 min_fr;
u64 max_fr;
u64 fr;
u8 h_sup_csi_lanes;
u64 link_freq;
struct alvium_ctrls ctrls;
u8 bcrm_mode;
struct alvium_pixfmt *alvium_csi2_fmt;
u8 alvium_csi2_fmt_n;
u8 streaming;
u8 apply_fiv;
};
static inline struct alvium_dev *sd_to_alvium(struct v4l2_subdev *sd)
{
return container_of_const(sd, struct alvium_dev, sd);
}
static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
{
return &container_of_const(ctrl->handler, struct alvium_dev,
ctrls.handler)->sd;
}
#endif /* ALVIUM_CSI2_H_ */

View File

@ -446,8 +446,7 @@ static int ar0521_get_fmt(struct v4l2_subdev *sd,
mutex_lock(&sensor->lock);
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, 0
/* pad */);
fmt = v4l2_subdev_state_get_format(sd_state, 0);
else
fmt = &sensor->fmt;
@ -472,7 +471,7 @@ static int ar0521_set_fmt(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_get_try_format(sd, sd_state, 0 /* pad */);
fmt = v4l2_subdev_state_get_format(sd_state, 0);
*fmt = format->format;
mutex_unlock(&sensor->lock);

View File

@ -2,6 +2,7 @@
config VIDEO_CCS
tristate "MIPI CCS/SMIA++/SMIA sensor support"
depends on HAVE_CLK
select V4L2_CCI_I2C
select VIDEO_CCS_PLL
help
This is a generic driver for MIPI CCS, SMIA++ and SMIA compliant

View File

@ -25,8 +25,9 @@
#include <linux/slab.h>
#include <linux/smiapp.h>
#include <linux/v4l2-mediabus.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <uapi/linux/ccs.h>
#include "ccs.h"
@ -98,7 +99,7 @@ static int ccs_limit_ptr(struct ccs_sensor *sensor, unsigned int limit,
linfo = &ccs_limits[ccs_limit_offsets[limit].info];
if (WARN_ON(!sensor->ccs_limits) ||
WARN_ON(offset + ccs_reg_width(linfo->reg) >
WARN_ON(offset + CCI_REG_WIDTH_BYTES(linfo->reg) >
ccs_limit_offsets[limit + 1].lim))
return -EINVAL;
@ -124,7 +125,7 @@ void ccs_replace_limit(struct ccs_sensor *sensor,
dev_dbg(&client->dev, "quirk: 0x%8.8x \"%s\" %u = %u, 0x%x\n",
linfo->reg, linfo->name, offset, val, val);
ccs_assign_limit(ptr, ccs_reg_width(linfo->reg), val);
ccs_assign_limit(ptr, CCI_REG_WIDTH_BYTES(linfo->reg), val);
}
u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit,
@ -138,7 +139,7 @@ u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit,
if (ret)
return 0;
switch (ccs_reg_width(ccs_limits[ccs_limit_offsets[limit].info].reg)) {
switch (CCI_REG_WIDTH_BYTES(ccs_limits[ccs_limit_offsets[limit].info].reg)) {
case sizeof(u8):
val = *(u8 *)ptr;
break;
@ -172,9 +173,11 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor)
end = alloc + ccs_limit_offsets[CCS_L_LAST].lim;
sensor->ccs_limits = alloc;
for (i = 0, l = 0, ptr = alloc; ccs_limits[i].size; i++) {
u32 reg = ccs_limits[i].reg;
unsigned int width = ccs_reg_width(reg);
unsigned int width = CCI_REG_WIDTH_BYTES(reg);
unsigned int j;
if (l == CCS_L_LAST) {
@ -186,6 +189,7 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor)
for (j = 0; j < ccs_limits[i].size / width;
j++, reg += width, ptr += width) {
char str[16] = "";
u32 val;
ret = ccs_read_addr_noconv(sensor, reg, &val);
@ -204,8 +208,15 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor)
ccs_assign_limit(ptr, width, val);
dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n",
reg, ccs_limits[i].name, val, val);
#ifdef CONFIG_DYNAMIC_DEBUG
if (reg & (CCS_FL_FLOAT_IREAL | CCS_FL_IREAL))
snprintf(str, sizeof(str), ", %u",
ccs_reg_conv(sensor, reg, val));
#endif
dev_dbg(&client->dev,
"0x%8.8x \"%s\" = %u, 0x%x%s\n",
reg, ccs_limits[i].name, val, val, str);
}
if (ccs_limits[i].flags & CCS_L_FL_SAME_REG)
@ -222,14 +233,13 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor)
goto out_err;
}
sensor->ccs_limits = alloc;
if (CCS_LIM(sensor, SCALER_N_MIN) < 16)
ccs_replace_limit(sensor, CCS_L_SCALER_N_MIN, 0, 16);
return 0;
out_err:
sensor->ccs_limits = NULL;
kfree(alloc);
return ret;
@ -1878,9 +1888,11 @@ static int ccs_pm_get_init(struct ccs_sensor *sensor)
goto error;
/* Device was already active, so don't set controls */
if (rval == 1)
if (rval == 1 && !sensor->handler_setup_needed)
return 0;
sensor->handler_setup_needed = false;
/* Restore V4L2 controls to the previously suspended device */
rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler);
if (rval)
@ -2030,7 +2042,7 @@ static int __ccs_get_format(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{
fmt->format = *v4l2_subdev_get_pad_format(subdev, sd_state, fmt->pad);
fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad);
return 0;
@ -2061,10 +2073,10 @@ static void ccs_get_crop_compose(struct v4l2_subdev *subdev,
if (crops)
for (i = 0; i < subdev->entity.num_pads; i++)
crops[i] =
v4l2_subdev_get_pad_crop(subdev, sd_state, i);
v4l2_subdev_state_get_crop(sd_state, i);
if (comps)
*comps = v4l2_subdev_get_pad_compose(subdev, sd_state,
ssd->sink_pad);
*comps = v4l2_subdev_state_get_compose(sd_state,
ssd->sink_pad);
}
/* Changes require propagation only on sink pad. */
@ -2097,7 +2109,7 @@ static void ccs_propagate(struct v4l2_subdev *subdev,
fallthrough;
case V4L2_SEL_TGT_COMPOSE:
*crops[CCS_PAD_SRC] = *comp;
fmt = v4l2_subdev_get_pad_format(subdev, sd_state, CCS_PAD_SRC);
fmt = v4l2_subdev_state_get_format(sd_state, CCS_PAD_SRC);
fmt->width = comp->width;
fmt->height = comp->height;
if (which == V4L2_SUBDEV_FORMAT_ACTIVE && ssd == sensor->src)
@ -2507,7 +2519,7 @@ static int ccs_set_crop(struct v4l2_subdev *subdev,
if (sel->pad == ssd->sink_pad) {
struct v4l2_mbus_framefmt *mfmt =
v4l2_subdev_get_pad_format(subdev, sd_state, sel->pad);
v4l2_subdev_state_get_format(sd_state, sel->pad);
src_size.width = mfmt->width;
src_size.height = mfmt->height;
@ -2567,8 +2579,8 @@ static int ccs_get_selection(struct v4l2_subdev *subdev,
ccs_get_native_size(ssd, &sel->r);
} else if (sel->pad == ssd->sink_pad) {
struct v4l2_mbus_framefmt *sink_fmt =
v4l2_subdev_get_pad_format(subdev, sd_state,
ssd->sink_pad);
v4l2_subdev_state_get_format(sd_state,
ssd->sink_pad);
sel->r.top = sel->r.left = 0;
sel->r.width = sink_fmt->width;
sel->r.height = sink_fmt->height;
@ -2714,66 +2726,54 @@ static int ccs_identify_module(struct ccs_sensor *sensor)
rval = ccs_read(sensor, MODULE_MANUFACTURER_ID,
&minfo->mipi_manufacturer_id);
if (!rval && !minfo->mipi_manufacturer_id)
rval = ccs_read_addr_8only(sensor,
SMIAPP_REG_U8_MANUFACTURER_ID,
&minfo->smia_manufacturer_id);
rval = ccs_read_addr(sensor, SMIAPP_REG_U8_MANUFACTURER_ID,
&minfo->smia_manufacturer_id);
if (!rval)
rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_MODEL_ID,
&minfo->model_id);
rval = ccs_read(sensor, MODULE_MODEL_ID, &minfo->model_id);
if (!rval)
rval = ccs_read_addr_8only(sensor,
CCS_R_MODULE_REVISION_NUMBER_MAJOR,
&rev);
rval = ccs_read(sensor, MODULE_REVISION_NUMBER_MAJOR, &rev);
if (!rval) {
rval = ccs_read_addr_8only(sensor,
CCS_R_MODULE_REVISION_NUMBER_MINOR,
&minfo->revision_number);
rval = ccs_read(sensor, MODULE_REVISION_NUMBER_MINOR,
&minfo->revision_number);
minfo->revision_number |= rev << 8;
}
if (!rval)
rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_YEAR,
&minfo->module_year);
rval = ccs_read(sensor, MODULE_DATE_YEAR, &minfo->module_year);
if (!rval)
rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_MONTH,
&minfo->module_month);
rval = ccs_read(sensor, MODULE_DATE_MONTH,
&minfo->module_month);
if (!rval)
rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_DAY,
&minfo->module_day);
rval = ccs_read(sensor, MODULE_DATE_DAY, &minfo->module_day);
/* Sensor info */
if (!rval)
rval = ccs_read(sensor, SENSOR_MANUFACTURER_ID,
&minfo->sensor_mipi_manufacturer_id);
if (!rval && !minfo->sensor_mipi_manufacturer_id)
rval = ccs_read_addr_8only(sensor,
CCS_R_SENSOR_MANUFACTURER_ID,
&minfo->sensor_smia_manufacturer_id);
rval = ccs_read(sensor, SENSOR_MANUFACTURER_ID,
&minfo->sensor_smia_manufacturer_id);
if (!rval)
rval = ccs_read_addr_8only(sensor,
CCS_R_SENSOR_MODEL_ID,
&minfo->sensor_model_id);
rval = ccs_read(sensor, SENSOR_MODEL_ID,
&minfo->sensor_model_id);
if (!rval)
rval = ccs_read_addr_8only(sensor,
CCS_R_SENSOR_REVISION_NUMBER,
&minfo->sensor_revision_number);
rval = ccs_read(sensor, SENSOR_REVISION_NUMBER,
&minfo->sensor_revision_number);
if (!rval && !minfo->sensor_revision_number)
rval = ccs_read_addr_8only(sensor,
CCS_R_SENSOR_REVISION_NUMBER_16,
&minfo->sensor_revision_number);
rval = ccs_read(sensor, SENSOR_REVISION_NUMBER_16,
&minfo->sensor_revision_number);
if (!rval)
rval = ccs_read_addr_8only(sensor,
CCS_R_SENSOR_FIRMWARE_VERSION,
&minfo->sensor_firmware_version);
rval = ccs_read(sensor, SENSOR_FIRMWARE_VERSION,
&minfo->sensor_firmware_version);
/* SMIA */
if (!rval)
rval = ccs_read(sensor, MIPI_CCS_VERSION, &minfo->ccs_version);
if (!rval && !minfo->ccs_version)
rval = ccs_read_addr_8only(sensor, SMIAPP_REG_U8_SMIA_VERSION,
&minfo->smia_version);
rval = ccs_read_addr(sensor, SMIAPP_REG_U8_SMIA_VERSION,
&minfo->smia_version);
if (!rval && !minfo->ccs_version)
rval = ccs_read_addr_8only(sensor, SMIAPP_REG_U8_SMIAPP_VERSION,
&minfo->smiapp_version);
rval = ccs_read_addr(sensor, SMIAPP_REG_U8_SMIAPP_VERSION,
&minfo->smiapp_version);
if (rval) {
dev_err(&client->dev, "sensor detection failed\n");
@ -3004,17 +3004,17 @@ static int ccs_init_subdev(struct ccs_sensor *sensor,
return 0;
}
static int ccs_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int ccs_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct ccs_subdev *ssd = to_ccs_subdev(sd);
struct ccs_sensor *sensor = ssd->sensor;
unsigned int pad = ssd == sensor->pixel_array ?
CCS_PA_PAD_SRC : CCS_PAD_SINK;
struct v4l2_mbus_framefmt *fmt =
v4l2_subdev_get_pad_format(sd, sd_state, pad);
v4l2_subdev_state_get_format(sd_state, pad);
struct v4l2_rect *crop =
v4l2_subdev_get_pad_crop(sd, sd_state, pad);
v4l2_subdev_state_get_crop(sd_state, pad);
bool is_active = !sd->active_state || sd->active_state == sd_state;
mutex_lock(&sensor->mutex);
@ -3034,7 +3034,7 @@ static int ccs_init_cfg(struct v4l2_subdev *sd,
return 0;
}
fmt = v4l2_subdev_get_pad_format(sd, sd_state, CCS_PAD_SRC);
fmt = v4l2_subdev_state_get_format(sd_state, CCS_PAD_SRC);
fmt->code = ssd == sensor->src ?
sensor->csi_format->code : sensor->internal_csi_format->code;
fmt->field = V4L2_FIELD_NONE;
@ -3053,7 +3053,6 @@ static const struct v4l2_subdev_video_ops ccs_video_ops = {
};
static const struct v4l2_subdev_pad_ops ccs_pad_ops = {
.init_cfg = ccs_init_cfg,
.enum_mbus_code = ccs_enum_mbus_code,
.get_fmt = ccs_get_format,
.set_fmt = ccs_set_format,
@ -3077,6 +3076,7 @@ static const struct media_entity_operations ccs_entity_ops = {
};
static const struct v4l2_subdev_internal_ops ccs_internal_src_ops = {
.init_state = ccs_init_state,
.registered = ccs_registered,
.unregistered = ccs_unregistered,
};
@ -3307,6 +3307,13 @@ static int ccs_probe(struct i2c_client *client)
if (IS_ERR(sensor->xshutdown))
return PTR_ERR(sensor->xshutdown);
sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(sensor->regmap)) {
dev_err(&client->dev, "can't initialise CCI (%ld)\n",
PTR_ERR(sensor->regmap));
return PTR_ERR(sensor->regmap);
}
rval = ccs_power_on(&client->dev);
if (rval < 0)
return rval;
@ -3532,6 +3539,7 @@ static int ccs_probe(struct i2c_client *client)
sensor->streaming = false;
sensor->dev_init_done = true;
sensor->handler_setup_needed = true;
rval = ccs_write_msr_regs(sensor);
if (rval)
@ -3636,12 +3644,16 @@ static int ccs_module_init(void)
{
unsigned int i, l;
CCS_BUILD_BUG;
for (i = 0, l = 0; ccs_limits[i].size && l < CCS_L_LAST; i++) {
if (!(ccs_limits[i].flags & CCS_L_FL_SAME_REG)) {
ccs_limit_offsets[l + 1].lim =
ALIGN(ccs_limit_offsets[l].lim +
ccs_limits[i].size,
ccs_reg_width(ccs_limits[i + 1].reg));
ccs_limits[i + 1].reg ?
CCI_REG_WIDTH_BYTES(ccs_limits[i + 1].reg) :
1U);
ccs_limit_offsets[l].info = i;
l++;
} else {

View File

@ -62,87 +62,6 @@ static u32 float_to_u32_mul_1000000(struct i2c_client *client, u32 phloat)
}
/*
* Read a 8/16/32-bit i2c register. The value is returned in 'val'.
* Returns zero if successful, or non-zero otherwise.
*/
static int ____ccs_read_addr(struct ccs_sensor *sensor, u16 reg, u16 len,
u32 *val)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
struct i2c_msg msg;
unsigned char data_buf[sizeof(u32)] = { 0 };
unsigned char offset_buf[sizeof(u16)];
int r;
if (len > sizeof(data_buf))
return -EINVAL;
msg.addr = client->addr;
msg.flags = 0;
msg.len = sizeof(offset_buf);
msg.buf = offset_buf;
put_unaligned_be16(reg, offset_buf);
r = i2c_transfer(client->adapter, &msg, 1);
if (r != 1) {
if (r >= 0)
r = -EBUSY;
goto err;
}
msg.len = len;
msg.flags = I2C_M_RD;
msg.buf = &data_buf[sizeof(data_buf) - len];
r = i2c_transfer(client->adapter, &msg, 1);
if (r != 1) {
if (r >= 0)
r = -EBUSY;
goto err;
}
*val = get_unaligned_be32(data_buf);
return 0;
err:
dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r);
return r;
}
/* Read a register using 8-bit access only. */
static int ____ccs_read_addr_8only(struct ccs_sensor *sensor, u16 reg,
u16 len, u32 *val)
{
unsigned int i;
int rval;
*val = 0;
for (i = 0; i < len; i++) {
u32 val8;
rval = ____ccs_read_addr(sensor, reg + i, 1, &val8);
if (rval < 0)
return rval;
*val |= val8 << ((len - i - 1) << 3);
}
return 0;
}
unsigned int ccs_reg_width(u32 reg)
{
if (reg & CCS_FL_16BIT)
return sizeof(u16);
if (reg & CCS_FL_32BIT)
return sizeof(u32);
return sizeof(u8);
}
static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val)
{
if (val >> 10 > U32_MAX / 15625) {
@ -178,29 +97,22 @@ u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val)
static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val,
bool only8, bool conv)
{
unsigned int len = ccs_reg_width(reg);
u64 __val;
int rval;
if (!only8)
rval = ____ccs_read_addr(sensor, CCS_REG_ADDR(reg), len, val);
else
rval = ____ccs_read_addr_8only(sensor, CCS_REG_ADDR(reg), len,
val);
rval = cci_read(sensor->regmap, reg, &__val, NULL);
if (rval < 0)
return rval;
if (!conv)
return 0;
*val = ccs_reg_conv(sensor, reg, *val);
*val = conv ? ccs_reg_conv(sensor, reg, __val) : __val;
return 0;
}
static int __ccs_read_data(struct ccs_reg *regs, size_t num_regs,
u32 reg, u32 *val)
static int __ccs_static_data_read_ro_reg(struct ccs_reg *regs, size_t num_regs,
u32 reg, u32 *val)
{
unsigned int width = ccs_reg_width(reg);
unsigned int width = CCI_REG_WIDTH_BYTES(reg);
size_t i;
for (i = 0; i < num_regs; i++, regs++) {
@ -235,16 +147,17 @@ static int __ccs_read_data(struct ccs_reg *regs, size_t num_regs,
return -ENOENT;
}
static int ccs_read_data(struct ccs_sensor *sensor, u32 reg, u32 *val)
static int
ccs_static_data_read_ro_reg(struct ccs_sensor *sensor, u32 reg, u32 *val)
{
if (!__ccs_read_data(sensor->sdata.sensor_read_only_regs,
sensor->sdata.num_sensor_read_only_regs,
reg, val))
if (!__ccs_static_data_read_ro_reg(sensor->sdata.sensor_read_only_regs,
sensor->sdata.num_sensor_read_only_regs,
reg, val))
return 0;
return __ccs_read_data(sensor->mdata.module_read_only_regs,
sensor->mdata.num_module_read_only_regs,
reg, val);
return __ccs_static_data_read_ro_reg(sensor->mdata.module_read_only_regs,
sensor->mdata.num_module_read_only_regs,
reg, val);
}
static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val,
@ -253,7 +166,7 @@ static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val,
int rval;
if (data) {
rval = ccs_read_data(sensor, reg, val);
rval = ccs_static_data_read_ro_reg(sensor, reg, val);
if (!rval)
return 0;
}
@ -291,71 +204,13 @@ int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val)
return ccs_read_addr_raw(sensor, reg, val, false, true, false, true);
}
static int ccs_write_retry(struct i2c_client *client, struct i2c_msg *msg)
{
unsigned int retries;
int r;
for (retries = 0; retries < 10; retries++) {
/*
* Due to unknown reason sensor stops responding. This
* loop is a temporaty solution until the root cause
* is found.
*/
r = i2c_transfer(client->adapter, msg, 1);
if (r != 1) {
usleep_range(1000, 2000);
continue;
}
if (retries)
dev_err(&client->dev,
"sensor i2c stall encountered. retries: %d\n",
retries);
return 0;
}
return r;
}
int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
struct i2c_msg msg;
unsigned char data[6];
unsigned int len = ccs_reg_width(reg);
int r;
if (len > sizeof(data) - 2)
return -EINVAL;
msg.addr = client->addr;
msg.flags = 0; /* Write */
msg.len = 2 + len;
msg.buf = data;
put_unaligned_be16(CCS_REG_ADDR(reg), data);
put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2);
dev_dbg(&client->dev, "writing reg 0x%4.4x value 0x%*.*x (%u)\n",
CCS_REG_ADDR(reg), ccs_reg_width(reg) << 1,
ccs_reg_width(reg) << 1, val, val);
r = ccs_write_retry(client, &msg);
if (r)
dev_err(&client->dev,
"wrote 0x%x to offset 0x%x error %d\n", val,
CCS_REG_ADDR(reg), r);
return r;
}
/*
* Write to a 8/16-bit register.
* Returns zero if successful, or non-zero otherwise.
*/
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, &reg, &val);
@ -364,7 +219,13 @@ int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
if (rval < 0)
return rval;
return ccs_write_addr_no_quirk(sensor, reg, val);
rval = 0;
do {
if (cci_write(sensor->regmap, reg, val, &rval))
fsleep(1000);
} while (rval && --retries);
return rval;
}
#define MAX_WRITE_LEN 32U
@ -373,40 +234,38 @@ int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs,
size_t num_regs)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
unsigned char buf[2 + MAX_WRITE_LEN];
struct i2c_msg msg = {
.addr = client->addr,
.buf = buf,
};
size_t i;
for (i = 0; i < num_regs; i++, regs++) {
unsigned char *regdata = regs->value;
unsigned int j;
int len;
for (j = 0; j < regs->len;
j += msg.len - 2, regdata += msg.len - 2) {
for (j = 0; j < regs->len; j += len, regdata += len) {
char printbuf[(MAX_WRITE_LEN << 1) +
1 /* \0 */] = { 0 };
unsigned int retries = 10;
int rval;
msg.len = min(regs->len - j, MAX_WRITE_LEN);
len = min(regs->len - j, MAX_WRITE_LEN);
bin2hex(printbuf, regdata, msg.len);
bin2hex(printbuf, regdata, len);
dev_dbg(&client->dev,
"writing msr reg 0x%4.4x value 0x%s\n",
regs->addr + j, printbuf);
put_unaligned_be16(regs->addr + j, buf);
memcpy(buf + 2, regdata, msg.len);
do {
rval = regmap_bulk_write(sensor->regmap,
regs->addr + j,
regdata, len);
if (rval)
fsleep(1000);
} while (rval && --retries);
msg.len += 2;
rval = ccs_write_retry(client, &msg);
if (rval) {
dev_err(&client->dev,
"error writing %u octets to address 0x%4.4x\n",
msg.len, regs->addr + j);
len, regs->addr + j);
return rval;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,7 @@
#define __CCS_H__
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
@ -211,6 +212,7 @@ struct ccs_sensor {
struct clk *ext_clk;
struct gpio_desc *xshutdown;
struct gpio_desc *reset;
struct regmap *regmap;
void *ccs_limits;
u8 nbinning_subtypes;
struct ccs_binning_subtype binning_subtypes[CCS_LIM_BINNING_SUB_TYPE_MAX_N + 1];
@ -236,6 +238,7 @@ struct ccs_sensor {
bool streaming;
bool dev_init_done;
bool handler_setup_needed;
u8 compressed_min_bpp;
struct ccs_module_info minfo;

View File

@ -12,481 +12,484 @@
#ifndef __SMIAPP_REG_DEFS_H__
#define __SMIAPP_REG_DEFS_H__
#include <linux/bits.h>
#include <media/v4l2-cci.h>
/* Register addresses */
#define SMIAPP_REG_U16_MODEL_ID (0x0000 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR 0x0002
#define SMIAPP_REG_U8_MANUFACTURER_ID 0x0003
#define SMIAPP_REG_U8_SMIA_VERSION 0x0004
#define SMIAPP_REG_U8_FRAME_COUNT 0x0005
#define SMIAPP_REG_U8_PIXEL_ORDER 0x0006
#define SMIAPP_REG_U16_DATA_PEDESTAL (0x0008 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_PIXEL_DEPTH 0x000c
#define SMIAPP_REG_U8_REVISION_NUMBER_MINOR 0x0010
#define SMIAPP_REG_U8_SMIAPP_VERSION 0x0011
#define SMIAPP_REG_U8_MODULE_DATE_YEAR 0x0012
#define SMIAPP_REG_U8_MODULE_DATE_MONTH 0x0013
#define SMIAPP_REG_U8_MODULE_DATE_DAY 0x0014
#define SMIAPP_REG_U8_MODULE_DATE_PHASE 0x0015
#define SMIAPP_REG_U16_SENSOR_MODEL_ID (0x0016 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_SENSOR_REVISION_NUMBER 0x0018
#define SMIAPP_REG_U8_SENSOR_MANUFACTURER_ID 0x0019
#define SMIAPP_REG_U8_SENSOR_FIRMWARE_VERSION 0x001a
#define SMIAPP_REG_U32_SERIAL_NUMBER (0x001c | CCS_FL_32BIT)
#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE 0x0040
#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_SUBTYPE 0x0041
#define SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(n) ((0x0042 + ((n) << 1)) | CCS_FL_16BIT) /* 0 <= n <= 14 */
#define SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(n) ((0x0060 + ((n) << 2)) | CCS_FL_32BIT) /* 0 <= n <= 7 */
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CAPABILITY (0x0080 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MIN (0x0084 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MAX (0x0086 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_STEP (0x0088 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_TYPE (0x008a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_M0 (0x008c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_C0 (0x008e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_M1 (0x0090 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_C1 (0x0092 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_TYPE 0x00c0
#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_SUBTYPE 0x00c1
#define SMIAPP_REG_U16_DATA_FORMAT_DESCRIPTOR(n) ((0x00c2 + ((n) << 1)) | CCS_FL_16BIT)
#define SMIAPP_REG_U8_MODE_SELECT 0x0100
#define SMIAPP_REG_U8_IMAGE_ORIENTATION 0x0101
#define SMIAPP_REG_U8_SOFTWARE_RESET 0x0103
#define SMIAPP_REG_U8_GROUPED_PARAMETER_HOLD 0x0104
#define SMIAPP_REG_U8_MASK_CORRUPTED_FRAMES 0x0105
#define SMIAPP_REG_U8_FAST_STANDBY_CTRL 0x0106
#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL 0x0107
#define SMIAPP_REG_U8_2ND_CCI_IF_CONTROL 0x0108
#define SMIAPP_REG_U8_2ND_CCI_ADDRESS_CONTROL 0x0109
#define SMIAPP_REG_U8_CSI_CHANNEL_IDENTIFIER 0x0110
#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE 0x0111
#define SMIAPP_REG_U16_CSI_DATA_FORMAT (0x0112 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_CSI_LANE_MODE 0x0114
#define SMIAPP_REG_U8_CSI2_10_TO_8_DT 0x0115
#define SMIAPP_REG_U8_CSI2_10_TO_7_DT 0x0116
#define SMIAPP_REG_U8_CSI2_10_TO_6_DT 0x0117
#define SMIAPP_REG_U8_CSI2_12_TO_8_DT 0x0118
#define SMIAPP_REG_U8_CSI2_12_TO_7_DT 0x0119
#define SMIAPP_REG_U8_CSI2_12_TO_6_DT 0x011a
#define SMIAPP_REG_U8_CSI2_14_TO_10_DT 0x011b
#define SMIAPP_REG_U8_CSI2_14_TO_8_DT 0x011c
#define SMIAPP_REG_U8_CSI2_16_TO_10_DT 0x011d
#define SMIAPP_REG_U8_CSI2_16_TO_8_DT 0x011e
#define SMIAPP_REG_U8_GAIN_MODE 0x0120
#define SMIAPP_REG_U16_VANA_VOLTAGE (0x0130 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_VDIG_VOLTAGE (0x0132 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_VIO_VOLTAGE (0x0134 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ (0x0136 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_TEMP_SENSOR_CONTROL 0x0138
#define SMIAPP_REG_U8_TEMP_SENSOR_MODE 0x0139
#define SMIAPP_REG_U8_TEMP_SENSOR_OUTPUT 0x013a
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME (0x0200 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME (0x0202 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL (0x0204 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENR (0x0206 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_RED (0x0208 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_BLUE (0x020a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENB (0x020c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENR (0x020e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_RED (0x0210 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_BLUE (0x0212 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENB (0x0214 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_VT_PIX_CLK_DIV (0x0300 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_VT_SYS_CLK_DIV (0x0302 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_PRE_PLL_CLK_DIV (0x0304 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_PLL_MULTIPLIER (0x0306 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_OP_PIX_CLK_DIV (0x0308 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_OP_SYS_CLK_DIV (0x030a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FRAME_LENGTH_LINES (0x0340 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_LINE_LENGTH_PCK (0x0342 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_X_ADDR_START (0x0344 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_ADDR_START (0x0346 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_X_ADDR_END (0x0348 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_ADDR_END (0x034a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_X_OUTPUT_SIZE (0x034c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_OUTPUT_SIZE (0x034e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_X_EVEN_INC (0x0380 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_X_ODD_INC (0x0382 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_EVEN_INC (0x0384 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_ODD_INC (0x0386 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALING_MODE (0x0400 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SPATIAL_SAMPLING (0x0402 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALE_M (0x0404 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALE_N (0x0406 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET (0x0408 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_CROP_Y_OFFSET (0x040a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_WIDTH (0x040c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_HEIGHT (0x040e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_COMPRESSION_MODE (0x0500 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TEST_PATTERN_MODE (0x0600 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TEST_DATA_RED (0x0602 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TEST_DATA_GREENR (0x0604 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TEST_DATA_BLUE (0x0606 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TEST_DATA_GREENB (0x0608 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_WIDTH (0x060a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_POSITION (0x060c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_VERTICAL_CURSOR_WIDTH (0x060e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_VERTICAL_CURSOR_POSITION (0x0610 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FIFO_WATER_MARK_PIXELS (0x0700 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_TCLK_POST 0x0800
#define SMIAPP_REG_U8_THS_PREPARE 0x0801
#define SMIAPP_REG_U8_THS_ZERO_MIN 0x0802
#define SMIAPP_REG_U8_THS_TRAIL 0x0803
#define SMIAPP_REG_U8_TCLK_TRAIL_MIN 0x0804
#define SMIAPP_REG_U8_TCLK_PREPARE 0x0805
#define SMIAPP_REG_U8_TCLK_ZERO 0x0806
#define SMIAPP_REG_U8_TLPX 0x0807
#define SMIAPP_REG_U8_DPHY_CTRL 0x0808
#define SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS (0x0820 | CCS_FL_32BIT)
#define SMIAPP_REG_U8_BINNING_MODE 0x0900
#define SMIAPP_REG_U8_BINNING_TYPE 0x0901
#define SMIAPP_REG_U8_BINNING_WEIGHTING 0x0902
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL 0x0a00
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS 0x0a01
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT 0x0a02
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 0x0a04
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_1 0x0a05
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_2 0x0a06
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_3 0x0a07
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_4 0x0a08
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_5 0x0a09
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_12 0x0a10
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_13 0x0a11
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_14 0x0a12
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_15 0x0a13
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_16 0x0a14
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_17 0x0a15
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_18 0x0a16
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_19 0x0a17
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_20 0x0a18
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_21 0x0a19
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_22 0x0a1a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_23 0x0a1b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_24 0x0a1c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_25 0x0a1d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_26 0x0a1e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_27 0x0a1f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_28 0x0a20
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_29 0x0a21
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_30 0x0a22
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_31 0x0a23
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_32 0x0a24
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_33 0x0a25
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_34 0x0a26
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_35 0x0a27
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_36 0x0a28
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_37 0x0a29
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_38 0x0a2a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_39 0x0a2b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_40 0x0a2c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_41 0x0a2d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_42 0x0a2e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_43 0x0a2f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_44 0x0a30
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_45 0x0a31
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_46 0x0a32
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_47 0x0a33
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_48 0x0a34
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_49 0x0a35
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_50 0x0a36
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_51 0x0a37
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_52 0x0a38
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_53 0x0a39
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_54 0x0a3a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_55 0x0a3b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_56 0x0a3c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_57 0x0a3d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_58 0x0a3e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_59 0x0a3f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_60 0x0a40
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_61 0x0a41
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_62 0x0a42
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_63 0x0a43
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_CTRL 0x0a44
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_STATUS 0x0a45
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_PAGE_SELECT 0x0a46
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_0 0x0a48
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_1 0x0a49
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_2 0x0a4a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_3 0x0a4b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_4 0x0a4c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_5 0x0a4d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_6 0x0a4e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_7 0x0a4f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_8 0x0a50
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_9 0x0a51
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_10 0x0a52
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_11 0x0a53
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_12 0x0a54
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_13 0x0a55
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_14 0x0a56
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_15 0x0a57
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_16 0x0a58
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_17 0x0a59
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_18 0x0a5a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_19 0x0a5b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_20 0x0a5c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_21 0x0a5d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_22 0x0a5e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_23 0x0a5f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_24 0x0a60
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_25 0x0a61
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_26 0x0a62
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_27 0x0a63
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_28 0x0a64
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_29 0x0a65
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_30 0x0a66
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_31 0x0a67
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_32 0x0a68
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_33 0x0a69
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_34 0x0a6a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_35 0x0a6b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_36 0x0a6c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_37 0x0a6d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_38 0x0a6e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_39 0x0a6f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_40 0x0a70
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_41 0x0a71
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_42 0x0a72
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_43 0x0a73
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_44 0x0a74
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_45 0x0a75
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_46 0x0a76
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_47 0x0a77
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_48 0x0a78
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_49 0x0a79
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_50 0x0a7a
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_51 0x0a7b
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_52 0x0a7c
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_53 0x0a7d
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_54 0x0a7e
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_55 0x0a7f
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_56 0x0a80
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_57 0x0a81
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_58 0x0a82
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_59 0x0a83
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_60 0x0a84
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_61 0x0a85
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_62 0x0a86
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_63 0x0a87
#define SMIAPP_REG_U8_SHADING_CORRECTION_ENABLE 0x0b00
#define SMIAPP_REG_U8_LUMINANCE_CORRECTION_LEVEL 0x0b01
#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_ENABLE 0x0b02
#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_WEIGHT 0x0b03
#define SMIAPP_REG_U8_BLACK_LEVEL_CORRECTION_ENABLE 0x0b04
#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ENABLE 0x0b05
#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_ENABLE 0x0b06
#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_WEIGHT 0x0b07
#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_ENABLE 0x0b08
#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_WEIGHT 0x0b09
#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_ENABLE 0x0b0a
#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_WEIGHT 0x0b0b
#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_ENABLE 0x0b0c
#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_WEIGHT 0x0b0d
#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ENABLE 0x0b0e
#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ADJUST 0x0b0f
#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ADJUST 0x0b10
#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ENABLE 0x0b11
#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ADJUST 0x0b12
#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ENABLE 0x0b13
#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ADJUST 0x0b14
#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ENABLE 0x0b15
#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ADJUST 0x0b16
#define SMIAPP_REG_U8_EDOF_MODE 0x0b80
#define SMIAPP_REG_U8_SHARPNESS 0x0b83
#define SMIAPP_REG_U8_DENOISING 0x0b84
#define SMIAPP_REG_U8_MODULE_SPECIFIC 0x0b85
#define SMIAPP_REG_U16_DEPTH_OF_FIELD (0x0b86 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FOCUS_DISTANCE (0x0b88 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_ESTIMATION_MODE_CTRL 0x0b8a
#define SMIAPP_REG_U16_COLOUR_TEMPERATURE (0x0b8c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENR (0x0b8e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_RED (0x0b90 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_BLUE (0x0b92 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENB (0x0b94 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_ESTIMATION_ZONE_MODE 0x0bc0
#define SMIAPP_REG_U16_FIXED_ZONE_WEIGHTING (0x0bc2 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_CUSTOM_ZONE_X_START (0x0bc4 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_CUSTOM_ZONE_Y_START (0x0bc6 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_CUSTOM_ZONE_WIDTH (0x0bc8 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_CUSTOM_ZONE_HEIGHT (0x0bca | CCS_FL_16BIT)
#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL1 0x0c00
#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL2 0x0c01
#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_1 0x0c02
#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_2 0x0c03
#define SMIAPP_REG_U16_TRDY_CTRL (0x0c04 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TRDOUT_CTRL (0x0c06 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TSHUTTER_STROBE_DELAY_CTRL (0x0c08 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TSHUTTER_STROBE_WIDTH_CTRL (0x0c0a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_CTRL (0x0c0c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_CTRL (0x0c0e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TGRST_INTERVAL_CTRL (0x0c10 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_FLASH_STROBE_ADJUSTMENT 0x0c12
#define SMIAPP_REG_U16_FLASH_STROBE_START_POINT (0x0c14 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_RS_CTRL (0x0c16 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_RS_CTRL (0x0c18 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_FLASH_MODE_RS 0x0c1a
#define SMIAPP_REG_U8_FLASH_TRIGGER_RS 0x0c1b
#define SMIAPP_REG_U8_FLASH_STATUS 0x0c1c
#define SMIAPP_REG_U8_SA_STROBE_MODE 0x0c1d
#define SMIAPP_REG_U16_SA_STROBE_START_POINT (0x0c1e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TSA_STROBE_DELAY_CTRL (0x0c20 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TSA_STROBE_WIDTH_CTRL (0x0c22 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_SA_STROBE_TRIGGER 0x0c24
#define SMIAPP_REG_U8_SPECIAL_ACTUATOR_STATUS 0x0c25
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_RS_CTRL (0x0c26 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_RS_CTRL (0x0c28 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_RS_CTRL 0x0c2a
#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_CTRL 0x0c2b
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_CTRL (0x0c2c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_CTRL (0x0c2e | CCS_FL_16BIT)
#define SMIAPP_REG_U8_LOW_LEVEL_CTRL 0x0c80
#define SMIAPP_REG_U16_MAIN_TRIGGER_REF_POINT (0x0c82 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAIN_TRIGGER_T3 (0x0c84 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_MAIN_TRIGGER_COUNT 0x0c86
#define SMIAPP_REG_U16_PHASE1_TRIGGER_T3 (0x0c88 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_PHASE1_TRIGGER_COUNT 0x0c8a
#define SMIAPP_REG_U16_PHASE2_TRIGGER_T3 (0x0c8c | CCS_FL_16BIT)
#define SMIAPP_REG_U8_PHASE2_TRIGGER_COUNT 0x0c8e
#define SMIAPP_REG_U8_MECH_SHUTTER_CTRL 0x0d00
#define SMIAPP_REG_U8_OPERATION_MODE 0x0d01
#define SMIAPP_REG_U8_ACT_STATE1 0x0d02
#define SMIAPP_REG_U8_ACT_STATE2 0x0d03
#define SMIAPP_REG_U16_FOCUS_CHANGE (0x0d80 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FOCUS_CHANGE_CONTROL (0x0d82 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE1 (0x0d84 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE2 (0x0d86 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_STROBE_COUNT_PHASE1 0x0d88
#define SMIAPP_REG_U8_STROBE_COUNT_PHASE2 0x0d89
#define SMIAPP_REG_U8_POSITION 0x0d8a
#define SMIAPP_REG_U8_BRACKETING_LUT_CONTROL 0x0e00
#define SMIAPP_REG_U8_BRACKETING_LUT_MODE 0x0e01
#define SMIAPP_REG_U8_BRACKETING_LUT_ENTRY_CONTROL 0x0e02
#define SMIAPP_REG_U8_LUT_PARAMETERS_START 0x0e10
#define SMIAPP_REG_U8_LUT_PARAMETERS_END 0x0eff
#define SMIAPP_REG_U16_INTEGRATION_TIME_CAPABILITY (0x1000 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MIN (0x1004 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MAX_MARGIN (0x1006 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN (0x1008 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN (0x100a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_CAPABILITY (0x1080 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_MIN (0x1084 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_MAX (0x1086 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DIGITAL_GAIN_STEP_SIZE (0x1088 | CCS_FL_16BIT)
#define SMIAPP_REG_F32_MIN_EXT_CLK_FREQ_HZ (0x1100 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_EXT_CLK_FREQ_HZ (0x1104 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_U16_MIN_PRE_PLL_CLK_DIV (0x1108 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_PRE_PLL_CLK_DIV (0x110a | CCS_FL_16BIT)
#define SMIAPP_REG_F32_MIN_PLL_IP_FREQ_HZ (0x110c | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_PLL_IP_FREQ_HZ (0x1110 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_U16_MIN_PLL_MULTIPLIER (0x1114 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_PLL_MULTIPLIER (0x1116 | CCS_FL_16BIT)
#define SMIAPP_REG_F32_MIN_PLL_OP_FREQ_HZ (0x1118 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_PLL_OP_FREQ_HZ (0x111c | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_U16_MIN_VT_SYS_CLK_DIV (0x1120 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_VT_SYS_CLK_DIV (0x1122 | CCS_FL_16BIT)
#define SMIAPP_REG_F32_MIN_VT_SYS_CLK_FREQ_HZ (0x1124 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_VT_SYS_CLK_FREQ_HZ (0x1128 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MIN_VT_PIX_CLK_FREQ_HZ (0x112c | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_VT_PIX_CLK_FREQ_HZ (0x1130 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_U16_MIN_VT_PIX_CLK_DIV (0x1134 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_VT_PIX_CLK_DIV (0x1136 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES (0x1140 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES (0x1142 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK (0x1144 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK (0x1146 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK (0x1148 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_FRAME_BLANKING_LINES (0x114a | CCS_FL_16BIT)
#define SMIAPP_REG_U8_MIN_LINE_LENGTH_PCK_STEP_SIZE 0x114c
#define SMIAPP_REG_U16_MIN_OP_SYS_CLK_DIV (0x1160 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_OP_SYS_CLK_DIV (0x1162 | CCS_FL_16BIT)
#define SMIAPP_REG_F32_MIN_OP_SYS_CLK_FREQ_HZ (0x1164 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_OP_SYS_CLK_FREQ_HZ (0x1168 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_U16_MIN_OP_PIX_CLK_DIV (0x116c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_OP_PIX_CLK_DIV (0x116e | CCS_FL_16BIT)
#define SMIAPP_REG_F32_MIN_OP_PIX_CLK_FREQ_HZ (0x1170 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_F32_MAX_OP_PIX_CLK_FREQ_HZ (0x1174 | CCS_FL_FLOAT_IREAL | CCS_FL_32BIT)
#define SMIAPP_REG_U16_X_ADDR_MIN (0x1180 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_ADDR_MIN (0x1182 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_X_ADDR_MAX (0x1184 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_Y_ADDR_MAX (0x1186 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_X_OUTPUT_SIZE (0x1188 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_Y_OUTPUT_SIZE (0x118a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_X_OUTPUT_SIZE (0x118c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_Y_OUTPUT_SIZE (0x118e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_EVEN_INC (0x11c0 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_EVEN_INC (0x11c2 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_ODD_INC (0x11c4 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_ODD_INC (0x11c6 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALING_CAPABILITY (0x1200 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALER_M_MIN (0x1204 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALER_M_MAX (0x1206 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALER_N_MIN (0x1208 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SCALER_N_MAX (0x120a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_SPATIAL_SAMPLING_CAPABILITY (0x120c | CCS_FL_16BIT)
#define SMIAPP_REG_U8_DIGITAL_CROP_CAPABILITY 0x120e
#define SMIAPP_REG_U16_COMPRESSION_CAPABILITY (0x1300 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINRED (0x1400 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINRED (0x1402 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINRED (0x1404 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINGREEN (0x1406 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINGREEN (0x1408 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINGREEN (0x140a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINBLUE (0x140c | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINBLUE (0x140e | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINBLUE (0x1410 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FIFO_SIZE_PIXELS (0x1500 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_FIFO_SUPPORT_CAPABILITY 0x1502
#define SMIAPP_REG_U8_DPHY_CTRL_CAPABILITY 0x1600
#define SMIAPP_REG_U8_CSI_LANE_MODE_CAPABILITY 0x1601
#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE_CAPABILITY 0x1602
#define SMIAPP_REG_U8_FAST_STANDBY_CAPABILITY 0x1603
#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL_CAPABILITY 0x1604
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS (0x1608 | CCS_FL_32BIT)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS (0x160c | CCS_FL_32BIT)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS (0x1610 | CCS_FL_32BIT)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS (0x1614 | CCS_FL_32BIT)
#define SMIAPP_REG_U8_TEMP_SENSOR_CAPABILITY 0x1618
#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES_BIN (0x1700 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES_BIN (0x1702 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK_BIN (0x1704 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK_BIN (0x1706 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK_BIN (0x1708 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN_BIN (0x170a | CCS_FL_16BIT)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN (0x170c | CCS_FL_16BIT)
#define SMIAPP_REG_U8_BINNING_CAPABILITY 0x1710
#define SMIAPP_REG_U8_BINNING_WEIGHTING_CAPABILITY 0x1711
#define SMIAPP_REG_U8_BINNING_SUBTYPES 0x1712
#define SMIAPP_REG_U8_BINNING_TYPE_n(n) (0x1713 + (n)) /* 1 <= n <= 237 */
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_CAPABILITY 0x1800
#define SMIAPP_REG_U8_SHADING_CORRECTION_CAPABILITY 0x1900
#define SMIAPP_REG_U8_GREEN_IMBALANCE_CAPABILITY 0x1901
#define SMIAPP_REG_U8_BLACK_LEVEL_CAPABILITY 0x1902
#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_CAPABILITY 0x1903
#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY (0x1904 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY_2 (0x1906 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_EDOF_CAPABILITY 0x1980
#define SMIAPP_REG_U8_ESTIMATION_FRAMES 0x1981
#define SMIAPP_REG_U8_SUPPORTS_SHARPNESS_ADJ 0x1982
#define SMIAPP_REG_U8_SUPPORTS_DENOISING_ADJ 0x1983
#define SMIAPP_REG_U8_SUPPORTS_MODULE_SPECIFIC_ADJ 0x1984
#define SMIAPP_REG_U8_SUPPORTS_DEPTH_OF_FIELD_ADJ 0x1985
#define SMIAPP_REG_U8_SUPPORTS_FOCUS_DISTANCE_ADJ 0x1986
#define SMIAPP_REG_U8_COLOUR_FEEDBACK_CAPABILITY 0x1987
#define SMIAPP_REG_U8_EDOF_SUPPORT_AB_NXM 0x1988
#define SMIAPP_REG_U8_ESTIMATION_MODE_CAPABILITY 0x19c0
#define SMIAPP_REG_U8_ESTIMATION_ZONE_CAPABILITY 0x19c1
#define SMIAPP_REG_U16_EST_DEPTH_OF_FIELD (0x19c2 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_EST_FOCUS_DISTANCE (0x19c4 | CCS_FL_16BIT)
#define SMIAPP_REG_U16_CAPABILITY_TRDY_MIN (0x1a00 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_FLASH_MODE_CAPABILITY 0x1a02
#define SMIAPP_REG_U16_MECH_SHUT_AND_ACT_START_ADDR (0x1b02 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_ACTUATOR_CAPABILITY 0x1b04
#define SMIAPP_REG_U16_ACTUATOR_TYPE (0x1b40 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_AF_DEVICE_ADDRESS 0x1b42
#define SMIAPP_REG_U16_FOCUS_CHANGE_ADDRESS (0x1b44 | CCS_FL_16BIT)
#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_1 0x1c00
#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_2 0x1c01
#define SMIAPP_REG_U8_BRACKETING_LUT_SIZE 0x1c02
#define SMIAPP_REG_U16_MODEL_ID CCI_REG16(0x0000)
#define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR CCI_REG8(0x0002)
#define SMIAPP_REG_U8_MANUFACTURER_ID CCI_REG8(0x0003)
#define SMIAPP_REG_U8_SMIA_VERSION CCI_REG8(0x0004)
#define SMIAPP_REG_U8_FRAME_COUNT CCI_REG8(0x0005)
#define SMIAPP_REG_U8_PIXEL_ORDER CCI_REG8(0x0006)
#define SMIAPP_REG_U16_DATA_PEDESTAL CCI_REG16(0x0008)
#define SMIAPP_REG_U8_PIXEL_DEPTH CCI_REG8(0x000c)
#define SMIAPP_REG_U8_REVISION_NUMBER_MINOR CCI_REG8(0x0010)
#define SMIAPP_REG_U8_SMIAPP_VERSION CCI_REG8(0x0011)
#define SMIAPP_REG_U8_MODULE_DATE_YEAR CCI_REG8(0x0012)
#define SMIAPP_REG_U8_MODULE_DATE_MONTH CCI_REG8(0x0013)
#define SMIAPP_REG_U8_MODULE_DATE_DAY CCI_REG8(0x0014)
#define SMIAPP_REG_U8_MODULE_DATE_PHASE CCI_REG8(0x0015)
#define SMIAPP_REG_U16_SENSOR_MODEL_ID CCI_REG16(0x0016)
#define SMIAPP_REG_U8_SENSOR_REVISION_NUMBER CCI_REG8(0x0018)
#define SMIAPP_REG_U8_SENSOR_MANUFACTURER_ID CCI_REG8(0x0019)
#define SMIAPP_REG_U8_SENSOR_FIRMWARE_VERSION CCI_REG8(0x001a)
#define SMIAPP_REG_U32_SERIAL_NUMBER CCI_REG32(0x001c)
#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_TYPE CCI_REG8(0x0040)
#define SMIAPP_REG_U8_FRAME_FORMAT_MODEL_SUBTYPE CCI_REG8(0x0041)
#define SMIAPP_REG_U16_FRAME_FORMAT_DESCRIPTOR_2(n) CCI_REG16(0x0042 + ((n) << 1)) /* 0 <= n <= 14 */
#define SMIAPP_REG_U32_FRAME_FORMAT_DESCRIPTOR_4(n) CCI_REG32(0x0060 + ((n) << 2)) /* 0 <= n <= 7 */
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CAPABILITY CCI_REG16(0x0080)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MIN CCI_REG16(0x0084)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_MAX CCI_REG16(0x0086)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_STEP CCI_REG16(0x0088)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_TYPE CCI_REG16(0x008a)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_M0 CCI_REG16(0x008c)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_C0 CCI_REG16(0x008e)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_M1 CCI_REG16(0x0090)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_C1 CCI_REG16(0x0092)
#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_TYPE CCI_REG8(0x00c0)
#define SMIAPP_REG_U8_DATA_FORMAT_MODEL_SUBTYPE CCI_REG8(0x00c1)
#define SMIAPP_REG_U16_DATA_FORMAT_DESCRIPTOR(n) CCI_REG16(0x00c2 + ((n) << 1))
#define SMIAPP_REG_U8_MODE_SELECT CCI_REG8(0x0100)
#define SMIAPP_REG_U8_IMAGE_ORIENTATION CCI_REG8(0x0101)
#define SMIAPP_REG_U8_SOFTWARE_RESET CCI_REG8(0x0103)
#define SMIAPP_REG_U8_GROUPED_PARAMETER_HOLD CCI_REG8(0x0104)
#define SMIAPP_REG_U8_MASK_CORRUPTED_FRAMES CCI_REG8(0x0105)
#define SMIAPP_REG_U8_FAST_STANDBY_CTRL CCI_REG8(0x0106)
#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL CCI_REG8(0x0107)
#define SMIAPP_REG_U8_2ND_CCI_IF_CONTROL CCI_REG8(0x0108)
#define SMIAPP_REG_U8_2ND_CCI_ADDRESS_CONTROL CCI_REG8(0x0109)
#define SMIAPP_REG_U8_CSI_CHANNEL_IDENTIFIER CCI_REG8(0x0110)
#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE CCI_REG8(0x0111)
#define SMIAPP_REG_U16_CSI_DATA_FORMAT CCI_REG16(0x0112)
#define SMIAPP_REG_U8_CSI_LANE_MODE CCI_REG8(0x0114)
#define SMIAPP_REG_U8_CSI2_10_TO_8_DT CCI_REG8(0x0115)
#define SMIAPP_REG_U8_CSI2_10_TO_7_DT CCI_REG8(0x0116)
#define SMIAPP_REG_U8_CSI2_10_TO_6_DT CCI_REG8(0x0117)
#define SMIAPP_REG_U8_CSI2_12_TO_8_DT CCI_REG8(0x0118)
#define SMIAPP_REG_U8_CSI2_12_TO_7_DT CCI_REG8(0x0119)
#define SMIAPP_REG_U8_CSI2_12_TO_6_DT CCI_REG8(0x011a)
#define SMIAPP_REG_U8_CSI2_14_TO_10_DT CCI_REG8(0x011b)
#define SMIAPP_REG_U8_CSI2_14_TO_8_DT CCI_REG8(0x011c)
#define SMIAPP_REG_U8_CSI2_16_TO_10_DT CCI_REG8(0x011d)
#define SMIAPP_REG_U8_CSI2_16_TO_8_DT CCI_REG8(0x011e)
#define SMIAPP_REG_U8_GAIN_MODE CCI_REG8(0x0120)
#define SMIAPP_REG_U16_VANA_VOLTAGE CCI_REG16(0x0130)
#define SMIAPP_REG_U16_VDIG_VOLTAGE CCI_REG16(0x0132)
#define SMIAPP_REG_U16_VIO_VOLTAGE CCI_REG16(0x0134)
#define SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ CCI_REG16(0x0136)
#define SMIAPP_REG_U8_TEMP_SENSOR_CONTROL CCI_REG8(0x0138)
#define SMIAPP_REG_U8_TEMP_SENSOR_MODE CCI_REG8(0x0139)
#define SMIAPP_REG_U8_TEMP_SENSOR_OUTPUT CCI_REG8(0x013a)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME CCI_REG16(0x0200)
#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME CCI_REG16(0x0202)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL CCI_REG16(0x0204)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENR CCI_REG16(0x0206)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_RED CCI_REG16(0x0208)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_BLUE CCI_REG16(0x020a)
#define SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GREENB CCI_REG16(0x020c)
#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENR CCI_REG16(0x020e)
#define SMIAPP_REG_U16_DIGITAL_GAIN_RED CCI_REG16(0x0210)
#define SMIAPP_REG_U16_DIGITAL_GAIN_BLUE CCI_REG16(0x0212)
#define SMIAPP_REG_U16_DIGITAL_GAIN_GREENB CCI_REG16(0x0214)
#define SMIAPP_REG_U16_VT_PIX_CLK_DIV CCI_REG16(0x0300)
#define SMIAPP_REG_U16_VT_SYS_CLK_DIV CCI_REG16(0x0302)
#define SMIAPP_REG_U16_PRE_PLL_CLK_DIV CCI_REG16(0x0304)
#define SMIAPP_REG_U16_PLL_MULTIPLIER CCI_REG16(0x0306)
#define SMIAPP_REG_U16_OP_PIX_CLK_DIV CCI_REG16(0x0308)
#define SMIAPP_REG_U16_OP_SYS_CLK_DIV CCI_REG16(0x030a)
#define SMIAPP_REG_U16_FRAME_LENGTH_LINES CCI_REG16(0x0340)
#define SMIAPP_REG_U16_LINE_LENGTH_PCK CCI_REG16(0x0342)
#define SMIAPP_REG_U16_X_ADDR_START CCI_REG16(0x0344)
#define SMIAPP_REG_U16_Y_ADDR_START CCI_REG16(0x0346)
#define SMIAPP_REG_U16_X_ADDR_END CCI_REG16(0x0348)
#define SMIAPP_REG_U16_Y_ADDR_END CCI_REG16(0x034a)
#define SMIAPP_REG_U16_X_OUTPUT_SIZE CCI_REG16(0x034c)
#define SMIAPP_REG_U16_Y_OUTPUT_SIZE CCI_REG16(0x034e)
#define SMIAPP_REG_U16_X_EVEN_INC CCI_REG16(0x0380)
#define SMIAPP_REG_U16_X_ODD_INC CCI_REG16(0x0382)
#define SMIAPP_REG_U16_Y_EVEN_INC CCI_REG16(0x0384)
#define SMIAPP_REG_U16_Y_ODD_INC CCI_REG16(0x0386)
#define SMIAPP_REG_U16_SCALING_MODE CCI_REG16(0x0400)
#define SMIAPP_REG_U16_SPATIAL_SAMPLING CCI_REG16(0x0402)
#define SMIAPP_REG_U16_SCALE_M CCI_REG16(0x0404)
#define SMIAPP_REG_U16_SCALE_N CCI_REG16(0x0406)
#define SMIAPP_REG_U16_DIGITAL_CROP_X_OFFSET CCI_REG16(0x0408)
#define SMIAPP_REG_U16_DIGITAL_CROP_Y_OFFSET CCI_REG16(0x040a)
#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_WIDTH CCI_REG16(0x040c)
#define SMIAPP_REG_U16_DIGITAL_CROP_IMAGE_HEIGHT CCI_REG16(0x040e)
#define SMIAPP_REG_U16_COMPRESSION_MODE CCI_REG16(0x0500)
#define SMIAPP_REG_U16_TEST_PATTERN_MODE CCI_REG16(0x0600)
#define SMIAPP_REG_U16_TEST_DATA_RED CCI_REG16(0x0602)
#define SMIAPP_REG_U16_TEST_DATA_GREENR CCI_REG16(0x0604)
#define SMIAPP_REG_U16_TEST_DATA_BLUE CCI_REG16(0x0606)
#define SMIAPP_REG_U16_TEST_DATA_GREENB CCI_REG16(0x0608)
#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_WIDTH CCI_REG16(0x060a)
#define SMIAPP_REG_U16_HORIZONTAL_CURSOR_POSITION CCI_REG16(0x060c)
#define SMIAPP_REG_U16_VERTICAL_CURSOR_WIDTH CCI_REG16(0x060e)
#define SMIAPP_REG_U16_VERTICAL_CURSOR_POSITION CCI_REG16(0x0610)
#define SMIAPP_REG_U16_FIFO_WATER_MARK_PIXELS CCI_REG16(0x0700)
#define SMIAPP_REG_U8_TCLK_POST CCI_REG8(0x0800)
#define SMIAPP_REG_U8_THS_PREPARE CCI_REG8(0x0801)
#define SMIAPP_REG_U8_THS_ZERO_MIN CCI_REG8(0x0802)
#define SMIAPP_REG_U8_THS_TRAIL CCI_REG8(0x0803)
#define SMIAPP_REG_U8_TCLK_TRAIL_MIN CCI_REG8(0x0804)
#define SMIAPP_REG_U8_TCLK_PREPARE CCI_REG8(0x0805)
#define SMIAPP_REG_U8_TCLK_ZERO CCI_REG8(0x0806)
#define SMIAPP_REG_U8_TLPX CCI_REG8(0x0807)
#define SMIAPP_REG_U8_DPHY_CTRL CCI_REG8(0x0808)
#define SMIAPP_REG_U32_REQUESTED_LINK_BIT_RATE_MBPS CCI_REG32(0x0820)
#define SMIAPP_REG_U8_BINNING_MODE CCI_REG8(0x0900)
#define SMIAPP_REG_U8_BINNING_TYPE CCI_REG8(0x0901)
#define SMIAPP_REG_U8_BINNING_WEIGHTING CCI_REG8(0x0902)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_CTRL CCI_REG8(0x0a00)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS CCI_REG8(0x0a01)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_PAGE_SELECT CCI_REG8(0x0a02)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_0 CCI_REG8(0x0a04)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_1 CCI_REG8(0x0a05)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_2 CCI_REG8(0x0a06)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_3 CCI_REG8(0x0a07)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_4 CCI_REG8(0x0a08)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_5 CCI_REG8(0x0a09)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_12 CCI_REG8(0x0a10)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_13 CCI_REG8(0x0a11)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_14 CCI_REG8(0x0a12)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_15 CCI_REG8(0x0a13)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_16 CCI_REG8(0x0a14)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_17 CCI_REG8(0x0a15)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_18 CCI_REG8(0x0a16)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_19 CCI_REG8(0x0a17)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_20 CCI_REG8(0x0a18)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_21 CCI_REG8(0x0a19)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_22 CCI_REG8(0x0a1a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_23 CCI_REG8(0x0a1b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_24 CCI_REG8(0x0a1c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_25 CCI_REG8(0x0a1d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_26 CCI_REG8(0x0a1e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_27 CCI_REG8(0x0a1f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_28 CCI_REG8(0x0a20)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_29 CCI_REG8(0x0a21)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_30 CCI_REG8(0x0a22)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_31 CCI_REG8(0x0a23)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_32 CCI_REG8(0x0a24)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_33 CCI_REG8(0x0a25)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_34 CCI_REG8(0x0a26)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_35 CCI_REG8(0x0a27)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_36 CCI_REG8(0x0a28)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_37 CCI_REG8(0x0a29)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_38 CCI_REG8(0x0a2a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_39 CCI_REG8(0x0a2b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_40 CCI_REG8(0x0a2c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_41 CCI_REG8(0x0a2d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_42 CCI_REG8(0x0a2e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_43 CCI_REG8(0x0a2f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_44 CCI_REG8(0x0a30)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_45 CCI_REG8(0x0a31)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_46 CCI_REG8(0x0a32)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_47 CCI_REG8(0x0a33)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_48 CCI_REG8(0x0a34)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_49 CCI_REG8(0x0a35)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_50 CCI_REG8(0x0a36)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_51 CCI_REG8(0x0a37)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_52 CCI_REG8(0x0a38)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_53 CCI_REG8(0x0a39)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_54 CCI_REG8(0x0a3a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_55 CCI_REG8(0x0a3b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_56 CCI_REG8(0x0a3c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_57 CCI_REG8(0x0a3d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_58 CCI_REG8(0x0a3e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_59 CCI_REG8(0x0a3f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_60 CCI_REG8(0x0a40)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_61 CCI_REG8(0x0a41)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_62 CCI_REG8(0x0a42)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_1_DATA_63 CCI_REG8(0x0a43)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_CTRL CCI_REG8(0x0a44)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_STATUS CCI_REG8(0x0a45)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_PAGE_SELECT CCI_REG8(0x0a46)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_0 CCI_REG8(0x0a48)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_1 CCI_REG8(0x0a49)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_2 CCI_REG8(0x0a4a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_3 CCI_REG8(0x0a4b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_4 CCI_REG8(0x0a4c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_5 CCI_REG8(0x0a4d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_6 CCI_REG8(0x0a4e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_7 CCI_REG8(0x0a4f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_8 CCI_REG8(0x0a50)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_9 CCI_REG8(0x0a51)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_10 CCI_REG8(0x0a52)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_11 CCI_REG8(0x0a53)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_12 CCI_REG8(0x0a54)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_13 CCI_REG8(0x0a55)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_14 CCI_REG8(0x0a56)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_15 CCI_REG8(0x0a57)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_16 CCI_REG8(0x0a58)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_17 CCI_REG8(0x0a59)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_18 CCI_REG8(0x0a5a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_19 CCI_REG8(0x0a5b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_20 CCI_REG8(0x0a5c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_21 CCI_REG8(0x0a5d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_22 CCI_REG8(0x0a5e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_23 CCI_REG8(0x0a5f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_24 CCI_REG8(0x0a60)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_25 CCI_REG8(0x0a61)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_26 CCI_REG8(0x0a62)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_27 CCI_REG8(0x0a63)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_28 CCI_REG8(0x0a64)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_29 CCI_REG8(0x0a65)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_30 CCI_REG8(0x0a66)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_31 CCI_REG8(0x0a67)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_32 CCI_REG8(0x0a68)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_33 CCI_REG8(0x0a69)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_34 CCI_REG8(0x0a6a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_35 CCI_REG8(0x0a6b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_36 CCI_REG8(0x0a6c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_37 CCI_REG8(0x0a6d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_38 CCI_REG8(0x0a6e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_39 CCI_REG8(0x0a6f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_40 CCI_REG8(0x0a70)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_41 CCI_REG8(0x0a71)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_42 CCI_REG8(0x0a72)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_43 CCI_REG8(0x0a73)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_44 CCI_REG8(0x0a74)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_45 CCI_REG8(0x0a75)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_46 CCI_REG8(0x0a76)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_47 CCI_REG8(0x0a77)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_48 CCI_REG8(0x0a78)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_49 CCI_REG8(0x0a79)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_50 CCI_REG8(0x0a7a)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_51 CCI_REG8(0x0a7b)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_52 CCI_REG8(0x0a7c)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_53 CCI_REG8(0x0a7d)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_54 CCI_REG8(0x0a7e)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_55 CCI_REG8(0x0a7f)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_56 CCI_REG8(0x0a80)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_57 CCI_REG8(0x0a81)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_58 CCI_REG8(0x0a82)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_59 CCI_REG8(0x0a83)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_60 CCI_REG8(0x0a84)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_61 CCI_REG8(0x0a85)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_62 CCI_REG8(0x0a86)
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_2_DATA_63 CCI_REG8(0x0a87)
#define SMIAPP_REG_U8_SHADING_CORRECTION_ENABLE CCI_REG8(0x0b00)
#define SMIAPP_REG_U8_LUMINANCE_CORRECTION_LEVEL CCI_REG8(0x0b01)
#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_ENABLE CCI_REG8(0x0b02)
#define SMIAPP_REG_U8_GREEN_IMBALANCE_FILTER_WEIGHT CCI_REG8(0x0b03)
#define SMIAPP_REG_U8_BLACK_LEVEL_CORRECTION_ENABLE CCI_REG8(0x0b04)
#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ENABLE CCI_REG8(0x0b05)
#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_ENABLE CCI_REG8(0x0b06)
#define SMIAPP_REG_U8_SINGLE_DEFECT_CORRECT_WEIGHT CCI_REG8(0x0b07)
#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_ENABLE CCI_REG8(0x0b08)
#define SMIAPP_REG_U8_DYNAMIC_COUPLET_CORRECT_WEIGHT CCI_REG8(0x0b09)
#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_ENABLE CCI_REG8(0x0b0a)
#define SMIAPP_REG_U8_COMBINED_DEFECT_CORRECT_WEIGHT CCI_REG8(0x0b0b)
#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_ENABLE CCI_REG8(0x0b0c)
#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_WEIGHT CCI_REG8(0x0b0d)
#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ENABLE CCI_REG8(0x0b0e)
#define SMIAPP_REG_U8_MAPPED_LINE_DEFECT_CORRECT_ADJUST CCI_REG8(0x0b0f)
#define SMIAPP_REG_U8_MAPPED_COUPLET_CORRECT_ADJUST CCI_REG8(0x0b10)
#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ENABLE CCI_REG8(0x0b11)
#define SMIAPP_REG_U8_MAPPED_TRIPLET_DEFECT_CORRECT_ADJUST CCI_REG8(0x0b12)
#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ENABLE CCI_REG8(0x0b13)
#define SMIAPP_REG_U8_DYNAMIC_TRIPLET_DEFECT_CORRECT_ADJUST CCI_REG8(0x0b14)
#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ENABLE CCI_REG8(0x0b15)
#define SMIAPP_REG_U8_DYNAMIC_LINE_DEFECT_CORRECT_ADJUST CCI_REG8(0x0b16)
#define SMIAPP_REG_U8_EDOF_MODE CCI_REG8(0x0b80)
#define SMIAPP_REG_U8_SHARPNESS CCI_REG8(0x0b83)
#define SMIAPP_REG_U8_DENOISING CCI_REG8(0x0b84)
#define SMIAPP_REG_U8_MODULE_SPECIFIC CCI_REG8(0x0b85)
#define SMIAPP_REG_U16_DEPTH_OF_FIELD CCI_REG16(0x0b86)
#define SMIAPP_REG_U16_FOCUS_DISTANCE CCI_REG16(0x0b88)
#define SMIAPP_REG_U8_ESTIMATION_MODE_CTRL CCI_REG8(0x0b8a)
#define SMIAPP_REG_U16_COLOUR_TEMPERATURE CCI_REG16(0x0b8c)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENR CCI_REG16(0x0b8e)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_RED CCI_REG16(0x0b90)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_BLUE CCI_REG16(0x0b92)
#define SMIAPP_REG_U16_ABSOLUTE_GAIN_GREENB CCI_REG16(0x0b94)
#define SMIAPP_REG_U8_ESTIMATION_ZONE_MODE CCI_REG8(0x0bc0)
#define SMIAPP_REG_U16_FIXED_ZONE_WEIGHTING CCI_REG16(0x0bc2)
#define SMIAPP_REG_U16_CUSTOM_ZONE_X_START CCI_REG16(0x0bc4)
#define SMIAPP_REG_U16_CUSTOM_ZONE_Y_START CCI_REG16(0x0bc6)
#define SMIAPP_REG_U16_CUSTOM_ZONE_WIDTH CCI_REG16(0x0bc8)
#define SMIAPP_REG_U16_CUSTOM_ZONE_HEIGHT CCI_REG16(0x0bca)
#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL1 CCI_REG8(0x0c00)
#define SMIAPP_REG_U8_GLOBAL_RESET_CTRL2 CCI_REG8(0x0c01)
#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_1 CCI_REG8(0x0c02)
#define SMIAPP_REG_U8_GLOBAL_RESET_MODE_CONFIG_2 CCI_REG8(0x0c03)
#define SMIAPP_REG_U16_TRDY_CTRL CCI_REG16(0x0c04)
#define SMIAPP_REG_U16_TRDOUT_CTRL CCI_REG16(0x0c06)
#define SMIAPP_REG_U16_TSHUTTER_STROBE_DELAY_CTRL CCI_REG16(0x0c08)
#define SMIAPP_REG_U16_TSHUTTER_STROBE_WIDTH_CTRL CCI_REG16(0x0c0a)
#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_CTRL CCI_REG16(0x0c0c)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_CTRL CCI_REG16(0x0c0e)
#define SMIAPP_REG_U16_TGRST_INTERVAL_CTRL CCI_REG16(0x0c10)
#define SMIAPP_REG_U8_FLASH_STROBE_ADJUSTMENT CCI_REG8(0x0c12)
#define SMIAPP_REG_U16_FLASH_STROBE_START_POINT CCI_REG16(0x0c14)
#define SMIAPP_REG_U16_TFLASH_STROBE_DELAY_RS_CTRL CCI_REG16(0x0c16)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_HIGH_RS_CTRL CCI_REG16(0x0c18)
#define SMIAPP_REG_U8_FLASH_MODE_RS CCI_REG8(0x0c1a)
#define SMIAPP_REG_U8_FLASH_TRIGGER_RS CCI_REG8(0x0c1b)
#define SMIAPP_REG_U8_FLASH_STATUS CCI_REG8(0x0c1c)
#define SMIAPP_REG_U8_SA_STROBE_MODE CCI_REG8(0x0c1d)
#define SMIAPP_REG_U16_SA_STROBE_START_POINT CCI_REG16(0x0c1e)
#define SMIAPP_REG_U16_TSA_STROBE_DELAY_CTRL CCI_REG16(0x0c20)
#define SMIAPP_REG_U16_TSA_STROBE_WIDTH_CTRL CCI_REG16(0x0c22)
#define SMIAPP_REG_U8_SA_STROBE_TRIGGER CCI_REG8(0x0c24)
#define SMIAPP_REG_U8_SPECIAL_ACTUATOR_STATUS CCI_REG8(0x0c25)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_RS_CTRL CCI_REG16(0x0c26)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_RS_CTRL CCI_REG16(0x0c28)
#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_RS_CTRL CCI_REG8(0x0c2a)
#define SMIAPP_REG_U8_TFLASH_STROBE_COUNT_CTRL CCI_REG8(0x0c2b)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH2_HIGH_CTRL CCI_REG16(0x0c2c)
#define SMIAPP_REG_U16_TFLASH_STROBE_WIDTH_LOW_CTRL CCI_REG16(0x0c2e)
#define SMIAPP_REG_U8_LOW_LEVEL_CTRL CCI_REG8(0x0c80)
#define SMIAPP_REG_U16_MAIN_TRIGGER_REF_POINT CCI_REG16(0x0c82)
#define SMIAPP_REG_U16_MAIN_TRIGGER_T3 CCI_REG16(0x0c84)
#define SMIAPP_REG_U8_MAIN_TRIGGER_COUNT CCI_REG8(0x0c86)
#define SMIAPP_REG_U16_PHASE1_TRIGGER_T3 CCI_REG16(0x0c88)
#define SMIAPP_REG_U8_PHASE1_TRIGGER_COUNT CCI_REG8(0x0c8a)
#define SMIAPP_REG_U16_PHASE2_TRIGGER_T3 CCI_REG16(0x0c8c)
#define SMIAPP_REG_U8_PHASE2_TRIGGER_COUNT CCI_REG8(0x0c8e)
#define SMIAPP_REG_U8_MECH_SHUTTER_CTRL CCI_REG8(0x0d00)
#define SMIAPP_REG_U8_OPERATION_MODE CCI_REG8(0x0d01)
#define SMIAPP_REG_U8_ACT_STATE1 CCI_REG8(0x0d02)
#define SMIAPP_REG_U8_ACT_STATE2 CCI_REG8(0x0d03)
#define SMIAPP_REG_U16_FOCUS_CHANGE CCI_REG16(0x0d80)
#define SMIAPP_REG_U16_FOCUS_CHANGE_CONTROL CCI_REG16(0x0d82)
#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE1 CCI_REG16(0x0d84)
#define SMIAPP_REG_U16_FOCUS_CHANGE_NUMBER_PHASE2 CCI_REG16(0x0d86)
#define SMIAPP_REG_U8_STROBE_COUNT_PHASE1 CCI_REG8(0x0d88)
#define SMIAPP_REG_U8_STROBE_COUNT_PHASE2 CCI_REG8(0x0d89)
#define SMIAPP_REG_U8_POSITION CCI_REG8(0x0d8a)
#define SMIAPP_REG_U8_BRACKETING_LUT_CONTROL CCI_REG8(0x0e00)
#define SMIAPP_REG_U8_BRACKETING_LUT_MODE CCI_REG8(0x0e01)
#define SMIAPP_REG_U8_BRACKETING_LUT_ENTRY_CONTROL CCI_REG8(0x0e02)
#define SMIAPP_REG_U8_LUT_PARAMETERS_START CCI_REG8(0x0e10)
#define SMIAPP_REG_U8_LUT_PARAMETERS_END CCI_REG8(0x0eff)
#define SMIAPP_REG_U16_INTEGRATION_TIME_CAPABILITY CCI_REG16(0x1000)
#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MIN CCI_REG16(0x1004)
#define SMIAPP_REG_U16_COARSE_INTEGRATION_TIME_MAX_MARGIN CCI_REG16(0x1006)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN CCI_REG16(0x1008)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN CCI_REG16(0x100a)
#define SMIAPP_REG_U16_DIGITAL_GAIN_CAPABILITY CCI_REG16(0x1080)
#define SMIAPP_REG_U16_DIGITAL_GAIN_MIN CCI_REG16(0x1084)
#define SMIAPP_REG_U16_DIGITAL_GAIN_MAX CCI_REG16(0x1086)
#define SMIAPP_REG_U16_DIGITAL_GAIN_STEP_SIZE CCI_REG16(0x1088)
#define SMIAPP_REG_F32_MIN_EXT_CLK_FREQ_HZ (CCI_REG32(0x1100) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_EXT_CLK_FREQ_HZ (CCI_REG32(0x1104) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_U16_MIN_PRE_PLL_CLK_DIV CCI_REG16(0x1108)
#define SMIAPP_REG_U16_MAX_PRE_PLL_CLK_DIV CCI_REG16(0x110a)
#define SMIAPP_REG_F32_MIN_PLL_IP_FREQ_HZ (CCI_REG32(0x110c) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_PLL_IP_FREQ_HZ (CCI_REG32(0x1110) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_U16_MIN_PLL_MULTIPLIER CCI_REG16(0x1114)
#define SMIAPP_REG_U16_MAX_PLL_MULTIPLIER CCI_REG16(0x1116)
#define SMIAPP_REG_F32_MIN_PLL_OP_FREQ_HZ (CCI_REG32(0x1118) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_PLL_OP_FREQ_HZ (CCI_REG32(0x111c) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_U16_MIN_VT_SYS_CLK_DIV CCI_REG16(0x1120)
#define SMIAPP_REG_U16_MAX_VT_SYS_CLK_DIV CCI_REG16(0x1122)
#define SMIAPP_REG_F32_MIN_VT_SYS_CLK_FREQ_HZ (CCI_REG32(0x1124) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_VT_SYS_CLK_FREQ_HZ (CCI_REG32(0x1128) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MIN_VT_PIX_CLK_FREQ_HZ (CCI_REG32(0x112c) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_VT_PIX_CLK_FREQ_HZ (CCI_REG32(0x1130) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_U16_MIN_VT_PIX_CLK_DIV CCI_REG16(0x1134)
#define SMIAPP_REG_U16_MAX_VT_PIX_CLK_DIV CCI_REG16(0x1136)
#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES CCI_REG16(0x1140)
#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES CCI_REG16(0x1142)
#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK CCI_REG16(0x1144)
#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK CCI_REG16(0x1146)
#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK CCI_REG16(0x1148)
#define SMIAPP_REG_U16_MIN_FRAME_BLANKING_LINES CCI_REG16(0x114a)
#define SMIAPP_REG_U8_MIN_LINE_LENGTH_PCK_STEP_SIZE CCI_REG8(0x114c)
#define SMIAPP_REG_U16_MIN_OP_SYS_CLK_DIV CCI_REG16(0x1160)
#define SMIAPP_REG_U16_MAX_OP_SYS_CLK_DIV CCI_REG16(0x1162)
#define SMIAPP_REG_F32_MIN_OP_SYS_CLK_FREQ_HZ (CCI_REG32(0x1164) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_OP_SYS_CLK_FREQ_HZ (CCI_REG32(0x1168) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_U16_MIN_OP_PIX_CLK_DIV CCI_REG16(0x116c)
#define SMIAPP_REG_U16_MAX_OP_PIX_CLK_DIV CCI_REG16(0x116e)
#define SMIAPP_REG_F32_MIN_OP_PIX_CLK_FREQ_HZ (CCI_REG32(0x1170) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_F32_MAX_OP_PIX_CLK_FREQ_HZ (CCI_REG32(0x1174) | CCS_FL_FLOAT_IREAL)
#define SMIAPP_REG_U16_X_ADDR_MIN CCI_REG16(0x1180)
#define SMIAPP_REG_U16_Y_ADDR_MIN CCI_REG16(0x1182)
#define SMIAPP_REG_U16_X_ADDR_MAX CCI_REG16(0x1184)
#define SMIAPP_REG_U16_Y_ADDR_MAX CCI_REG16(0x1186)
#define SMIAPP_REG_U16_MIN_X_OUTPUT_SIZE CCI_REG16(0x1188)
#define SMIAPP_REG_U16_MIN_Y_OUTPUT_SIZE CCI_REG16(0x118a)
#define SMIAPP_REG_U16_MAX_X_OUTPUT_SIZE CCI_REG16(0x118c)
#define SMIAPP_REG_U16_MAX_Y_OUTPUT_SIZE CCI_REG16(0x118e)
#define SMIAPP_REG_U16_MIN_EVEN_INC CCI_REG16(0x11c0)
#define SMIAPP_REG_U16_MAX_EVEN_INC CCI_REG16(0x11c2)
#define SMIAPP_REG_U16_MIN_ODD_INC CCI_REG16(0x11c4)
#define SMIAPP_REG_U16_MAX_ODD_INC CCI_REG16(0x11c6)
#define SMIAPP_REG_U16_SCALING_CAPABILITY CCI_REG16(0x1200)
#define SMIAPP_REG_U16_SCALER_M_MIN CCI_REG16(0x1204)
#define SMIAPP_REG_U16_SCALER_M_MAX CCI_REG16(0x1206)
#define SMIAPP_REG_U16_SCALER_N_MIN CCI_REG16(0x1208)
#define SMIAPP_REG_U16_SCALER_N_MAX CCI_REG16(0x120a)
#define SMIAPP_REG_U16_SPATIAL_SAMPLING_CAPABILITY CCI_REG16(0x120c)
#define SMIAPP_REG_U8_DIGITAL_CROP_CAPABILITY CCI_REG8(0x120e)
#define SMIAPP_REG_U16_COMPRESSION_CAPABILITY CCI_REG16(0x1300)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINRED CCI_REG16(0x1400)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINRED CCI_REG16(0x1402)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINRED CCI_REG16(0x1404)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINGREEN CCI_REG16(0x1406)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINGREEN CCI_REG16(0x1408)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINGREEN CCI_REG16(0x140a)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_REDINBLUE CCI_REG16(0x140c)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_GREENINBLUE CCI_REG16(0x140e)
#define SMIAPP_REG_U16_MATRIX_ELEMENT_BLUEINBLUE CCI_REG16(0x1410)
#define SMIAPP_REG_U16_FIFO_SIZE_PIXELS CCI_REG16(0x1500)
#define SMIAPP_REG_U8_FIFO_SUPPORT_CAPABILITY CCI_REG8(0x1502)
#define SMIAPP_REG_U8_DPHY_CTRL_CAPABILITY CCI_REG8(0x1600)
#define SMIAPP_REG_U8_CSI_LANE_MODE_CAPABILITY CCI_REG8(0x1601)
#define SMIAPP_REG_U8_CSI_SIGNALLING_MODE_CAPABILITY CCI_REG8(0x1602)
#define SMIAPP_REG_U8_FAST_STANDBY_CAPABILITY CCI_REG8(0x1603)
#define SMIAPP_REG_U8_CCI_ADDRESS_CONTROL_CAPABILITY CCI_REG8(0x1604)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_1_LANE_MODE_MBPS CCI_REG32(0x1608)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_2_LANE_MODE_MBPS CCI_REG32(0x160c)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_3_LANE_MODE_MBPS CCI_REG32(0x1610)
#define SMIAPP_REG_U32_MAX_PER_LANE_BITRATE_4_LANE_MODE_MBPS CCI_REG32(0x1614)
#define SMIAPP_REG_U8_TEMP_SENSOR_CAPABILITY CCI_REG8(0x1618)
#define SMIAPP_REG_U16_MIN_FRAME_LENGTH_LINES_BIN CCI_REG16(0x1700)
#define SMIAPP_REG_U16_MAX_FRAME_LENGTH_LINES_BIN CCI_REG16(0x1702)
#define SMIAPP_REG_U16_MIN_LINE_LENGTH_PCK_BIN CCI_REG16(0x1704)
#define SMIAPP_REG_U16_MAX_LINE_LENGTH_PCK_BIN CCI_REG16(0x1706)
#define SMIAPP_REG_U16_MIN_LINE_BLANKING_PCK_BIN CCI_REG16(0x1708)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MIN_BIN CCI_REG16(0x170a)
#define SMIAPP_REG_U16_FINE_INTEGRATION_TIME_MAX_MARGIN_BIN CCI_REG16(0x170c)
#define SMIAPP_REG_U8_BINNING_CAPABILITY CCI_REG8(0x1710)
#define SMIAPP_REG_U8_BINNING_WEIGHTING_CAPABILITY CCI_REG8(0x1711)
#define SMIAPP_REG_U8_BINNING_SUBTYPES CCI_REG8(0x1712)
#define SMIAPP_REG_U8_BINNING_TYPE_n(n) CCI_REG8(0x1713 + (n)) /* 1 <= n <= 237 */
#define SMIAPP_REG_U8_DATA_TRANSFER_IF_CAPABILITY CCI_REG8(0x1800)
#define SMIAPP_REG_U8_SHADING_CORRECTION_CAPABILITY CCI_REG8(0x1900)
#define SMIAPP_REG_U8_GREEN_IMBALANCE_CAPABILITY CCI_REG8(0x1901)
#define SMIAPP_REG_U8_BLACK_LEVEL_CAPABILITY CCI_REG8(0x1902)
#define SMIAPP_REG_U8_MODULE_SPECIFIC_CORRECTION_CAPABILITY CCI_REG8(0x1903)
#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY CCI_REG16(0x1904)
#define SMIAPP_REG_U16_DEFECT_CORRECTION_CAPABILITY_2 CCI_REG16(0x1906)
#define SMIAPP_REG_U8_EDOF_CAPABILITY CCI_REG8(0x1980)
#define SMIAPP_REG_U8_ESTIMATION_FRAMES CCI_REG8(0x1981)
#define SMIAPP_REG_U8_SUPPORTS_SHARPNESS_ADJ CCI_REG8(0x1982)
#define SMIAPP_REG_U8_SUPPORTS_DENOISING_ADJ CCI_REG8(0x1983)
#define SMIAPP_REG_U8_SUPPORTS_MODULE_SPECIFIC_ADJ CCI_REG8(0x1984)
#define SMIAPP_REG_U8_SUPPORTS_DEPTH_OF_FIELD_ADJ CCI_REG8(0x1985)
#define SMIAPP_REG_U8_SUPPORTS_FOCUS_DISTANCE_ADJ CCI_REG8(0x1986)
#define SMIAPP_REG_U8_COLOUR_FEEDBACK_CAPABILITY CCI_REG8(0x1987)
#define SMIAPP_REG_U8_EDOF_SUPPORT_AB_NXM CCI_REG8(0x1988)
#define SMIAPP_REG_U8_ESTIMATION_MODE_CAPABILITY CCI_REG8(0x19c0)
#define SMIAPP_REG_U8_ESTIMATION_ZONE_CAPABILITY CCI_REG8(0x19c1)
#define SMIAPP_REG_U16_EST_DEPTH_OF_FIELD CCI_REG16(0x19c2)
#define SMIAPP_REG_U16_EST_FOCUS_DISTANCE CCI_REG16(0x19c4)
#define SMIAPP_REG_U16_CAPABILITY_TRDY_MIN CCI_REG16(0x1a00)
#define SMIAPP_REG_U8_FLASH_MODE_CAPABILITY CCI_REG8(0x1a02)
#define SMIAPP_REG_U16_MECH_SHUT_AND_ACT_START_ADDR CCI_REG16(0x1b02)
#define SMIAPP_REG_U8_ACTUATOR_CAPABILITY CCI_REG8(0x1b04)
#define SMIAPP_REG_U16_ACTUATOR_TYPE CCI_REG16(0x1b40)
#define SMIAPP_REG_U8_AF_DEVICE_ADDRESS CCI_REG8(0x1b42)
#define SMIAPP_REG_U16_FOCUS_CHANGE_ADDRESS CCI_REG16(0x1b44)
#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_1 CCI_REG8(0x1c00)
#define SMIAPP_REG_U8_BRACKETING_LUT_CAPABILITY_2 CCI_REG8(0x1c01)
#define SMIAPP_REG_U8_BRACKETING_LUT_SIZE CCI_REG8(0x1c02)
/* Register bit definitions */
#define SMIAPP_IMAGE_ORIENTATION_HFLIP BIT(0)

View File

@ -424,8 +424,7 @@ static int ub913_set_fmt(struct v4l2_subdev *sd,
}
/* Set sink format */
fmt = v4l2_subdev_state_get_stream_format(state, format->pad,
format->stream);
fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
if (!fmt)
return -EINVAL;
@ -444,8 +443,8 @@ static int ub913_set_fmt(struct v4l2_subdev *sd,
return 0;
}
static int ub913_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int ub913_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct v4l2_subdev_route routes[] = {
{
@ -504,7 +503,6 @@ static const struct v4l2_subdev_pad_ops ub913_pad_ops = {
.get_frame_desc = ub913_get_frame_desc,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = ub913_set_fmt,
.init_cfg = ub913_init_cfg,
};
static const struct v4l2_subdev_ops ub913_subdev_ops = {
@ -512,6 +510,10 @@ static const struct v4l2_subdev_ops ub913_subdev_ops = {
.pad = &ub913_pad_ops,
};
static const struct v4l2_subdev_internal_ops ub913_internal_ops = {
.init_state = ub913_init_state,
};
static const struct media_entity_operations ub913_entity_ops = {
.link_validate = v4l2_subdev_link_validate,
};
@ -745,6 +747,7 @@ static int ub913_subdev_init(struct ub913_data *priv)
int ret;
v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub913_subdev_ops);
priv->sd.internal_ops = &ub913_internal_ops;
priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
priv->sd.entity.ops = &ub913_entity_ops;

View File

@ -558,8 +558,7 @@ static int ub953_set_fmt(struct v4l2_subdev *sd,
return v4l2_subdev_get_fmt(sd, state, format);
/* Set sink format */
fmt = v4l2_subdev_state_get_stream_format(state, format->pad,
format->stream);
fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
if (!fmt)
return -EINVAL;
@ -576,8 +575,8 @@ static int ub953_set_fmt(struct v4l2_subdev *sd,
return 0;
}
static int ub953_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int ub953_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct v4l2_subdev_route routes[] = {
{
@ -714,7 +713,6 @@ static const struct v4l2_subdev_pad_ops ub953_pad_ops = {
.get_frame_desc = ub953_get_frame_desc,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = ub953_set_fmt,
.init_cfg = ub953_init_cfg,
};
static const struct v4l2_subdev_core_ops ub953_subdev_core_ops = {
@ -728,6 +726,10 @@ static const struct v4l2_subdev_ops ub953_subdev_ops = {
.pad = &ub953_pad_ops,
};
static const struct v4l2_subdev_internal_ops ub953_internal_ops = {
.init_state = ub953_init_state,
};
static const struct media_entity_operations ub953_entity_ops = {
.link_validate = v4l2_subdev_link_validate,
};
@ -1241,6 +1243,7 @@ static int ub953_subdev_init(struct ub953_data *priv)
int ret;
v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub953_subdev_ops);
priv->sd.internal_ops = &ub953_internal_ops;
priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_STREAMS;

View File

@ -2451,9 +2451,8 @@ static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
if (rx_data[nport].num_streams > 2)
return -EPIPE;
fmt = v4l2_subdev_state_get_stream_format(state,
route->sink_pad,
route->sink_stream);
fmt = v4l2_subdev_state_get_format(state, route->sink_pad,
route->sink_stream);
if (!fmt)
return -EPIPE;
@ -2842,8 +2841,8 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
const struct ub960_format_info *ub960_fmt;
struct v4l2_mbus_framefmt *fmt;
fmt = v4l2_subdev_state_get_stream_format(state, pad,
route->source_stream);
fmt = v4l2_subdev_state_get_format(state, pad,
route->source_stream);
if (!fmt) {
ret = -EINVAL;
@ -2891,8 +2890,7 @@ static int ub960_set_fmt(struct v4l2_subdev *sd,
if (!ub960_find_format(format->format.code))
format->format.code = ub960_formats[0].code;
fmt = v4l2_subdev_state_get_stream_format(state, format->pad,
format->stream);
fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
if (!fmt)
return -EINVAL;
@ -2908,8 +2906,8 @@ static int ub960_set_fmt(struct v4l2_subdev *sd,
return 0;
}
static int ub960_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int ub960_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct ub960_data *priv = sd_to_ub960(sd);
@ -2940,8 +2938,6 @@ static const struct v4l2_subdev_pad_ops ub960_pad_ops = {
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = ub960_set_fmt,
.init_cfg = ub960_init_cfg,
};
static int ub960_log_status(struct v4l2_subdev *sd)
@ -3093,6 +3089,10 @@ static const struct v4l2_subdev_core_ops ub960_subdev_core_ops = {
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_internal_ops ub960_internal_ops = {
.init_state = ub960_init_state,
};
static const struct v4l2_subdev_ops ub960_subdev_ops = {
.core = &ub960_subdev_core_ops,
.pad = &ub960_pad_ops,
@ -3652,6 +3652,7 @@ static int ub960_create_subdev(struct ub960_data *priv)
int ret;
v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub960_subdev_ops);
priv->sd.internal_ops = &ub960_internal_ops;
v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
priv->sd.ctrl_handler = &priv->ctrl_handler;

View File

@ -995,8 +995,7 @@ __et8ek8_get_pad_format(struct et8ek8_sensor *sensor,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_format(&sensor->subdev, sd_state,
pad);
return v4l2_subdev_state_get_format(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &sensor->format;
default:
@ -1047,10 +1046,18 @@ static int et8ek8_set_pad_format(struct v4l2_subdev *subdev,
}
static int et8ek8_get_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
memset(fi, 0, sizeof(*fi));
fi->interval = sensor->current_reglist->mode.timeperframe;
@ -1058,11 +1065,19 @@ static int et8ek8_get_frame_interval(struct v4l2_subdev *subdev,
}
static int et8ek8_set_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
struct et8ek8_reglist *reglist;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
reglist = et8ek8_reglist_find_mode_ival(&meta_reglist,
sensor->current_reglist,
&fi->interval);
@ -1343,8 +1358,6 @@ static int et8ek8_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
static const struct v4l2_subdev_video_ops et8ek8_video_ops = {
.s_stream = et8ek8_s_stream,
.g_frame_interval = et8ek8_get_frame_interval,
.s_frame_interval = et8ek8_set_frame_interval,
};
static const struct v4l2_subdev_core_ops et8ek8_core_ops = {
@ -1357,6 +1370,8 @@ static const struct v4l2_subdev_pad_ops et8ek8_pad_ops = {
.enum_frame_interval = et8ek8_enum_frame_ival,
.get_fmt = et8ek8_get_pad_format,
.set_fmt = et8ek8_set_pad_format,
.get_frame_interval = et8ek8_get_frame_interval,
.set_frame_interval = et8ek8_set_frame_interval,
};
static const struct v4l2_subdev_ops et8ek8_ops = {

1451
drivers/media/i2c/gc0308.c Normal file

File diff suppressed because it is too large Load Diff

1450
drivers/media/i2c/gc2145.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -935,7 +935,7 @@ __hi556_get_pad_crop(struct hi556 *hi556,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_crop(&hi556->sd, sd_state, pad);
return v4l2_subdev_state_get_crop(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &hi556->cur_mode->crop;
}
@ -1075,7 +1075,7 @@ static int hi556_set_format(struct v4l2_subdev *sd,
mutex_lock(&hi556->mutex);
hi556_assign_pad_format(mode, &fmt->format);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format;
*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
} else {
hi556->cur_mode = mode;
__v4l2_ctrl_s_ctrl(hi556->link_freq, mode->link_freq_index);
@ -1109,9 +1109,8 @@ static int hi556_get_format(struct v4l2_subdev *sd,
mutex_lock(&hi556->mutex);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
fmt->format = *v4l2_subdev_get_try_format(&hi556->sd,
sd_state,
fmt->pad);
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
hi556_assign_pad_format(hi556->cur_mode, &fmt->format);
@ -1157,10 +1156,10 @@ static int hi556_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
mutex_lock(&hi556->mutex);
hi556_assign_pad_format(&supported_modes[0],
v4l2_subdev_get_try_format(sd, fh->state, 0));
v4l2_subdev_state_get_format(fh->state, 0));
/* Initialize try_crop rectangle. */
try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
try_crop = v4l2_subdev_state_get_crop(fh->state, 0);
try_crop->top = HI556_PIXEL_ARRAY_TOP;
try_crop->left = HI556_PIXEL_ARRAY_LEFT;
try_crop->width = HI556_PIXEL_ARRAY_WIDTH;

View File

@ -1705,7 +1705,7 @@ static int hi846_set_format(struct v4l2_subdev *sd,
}
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, sd_state, format->pad) = *mf;
*v4l2_subdev_state_get_format(sd_state, format->pad) = *mf;
return 0;
}
@ -1783,9 +1783,8 @@ static int hi846_get_format(struct v4l2_subdev *sd,
struct i2c_client *client = v4l2_get_subdevdata(sd);
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
format->format = *v4l2_subdev_get_try_format(&hi846->sd,
sd_state,
format->pad);
format->format = *v4l2_subdev_state_get_format(sd_state,
format->pad);
return 0;
}
@ -1852,7 +1851,7 @@ static int hi846_get_selection(struct v4l2_subdev *sd,
mutex_lock(&hi846->mutex);
switch (sel->which) {
case V4L2_SUBDEV_FORMAT_TRY:
v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
v4l2_subdev_state_get_crop(sd_state, sel->pad);
break;
case V4L2_SUBDEV_FORMAT_ACTIVE:
sel->r = hi846->cur_mode->crop;
@ -1872,13 +1871,13 @@ static int hi846_get_selection(struct v4l2_subdev *sd,
}
}
static int hi846_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int hi846_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct hi846 *hi846 = to_hi846(sd);
struct v4l2_mbus_framefmt *mf;
mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
mf = v4l2_subdev_state_get_format(sd_state, 0);
mutex_lock(&hi846->mutex);
mf->code = HI846_MEDIA_BUS_FORMAT;
@ -1896,7 +1895,6 @@ static const struct v4l2_subdev_video_ops hi846_video_ops = {
};
static const struct v4l2_subdev_pad_ops hi846_pad_ops = {
.init_cfg = hi846_init_cfg,
.enum_frame_size = hi846_enum_frame_size,
.enum_mbus_code = hi846_enum_mbus_code,
.set_fmt = hi846_set_format,
@ -1909,6 +1907,10 @@ static const struct v4l2_subdev_ops hi846_subdev_ops = {
.pad = &hi846_pad_ops,
};
static const struct v4l2_subdev_internal_ops hi846_internal_ops = {
.init_state = hi846_init_state,
};
static const struct media_entity_operations hi846_subdev_entity_ops = {
.link_validate = v4l2_subdev_link_validate,
};
@ -2072,6 +2074,7 @@ static int hi846_probe(struct i2c_client *client)
return ret;
v4l2_i2c_subdev_init(&hi846->sd, client, &hi846_subdev_ops);
hi846->sd.internal_ops = &hi846_internal_ops;
mutex_init(&hi846->mutex);

View File

@ -2655,7 +2655,7 @@ static int hi847_set_format(struct v4l2_subdev *sd,
mutex_lock(&hi847->mutex);
hi847_assign_pad_format(mode, &fmt->format);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) =
*v4l2_subdev_state_get_format(sd_state, fmt->pad) =
fmt->format;
} else {
hi847->cur_mode = mode;
@ -2690,9 +2690,8 @@ static int hi847_get_format(struct v4l2_subdev *sd,
mutex_lock(&hi847->mutex);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
fmt->format = *v4l2_subdev_get_try_format(&hi847->sd,
sd_state,
fmt->pad);
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
hi847_assign_pad_format(hi847->cur_mode, &fmt->format);
@ -2737,7 +2736,7 @@ static int hi847_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
mutex_lock(&hi847->mutex);
hi847_assign_pad_format(&supported_modes[0],
v4l2_subdev_get_try_format(sd, fh->state, 0));
v4l2_subdev_state_get_format(fh->state, 0));
mutex_unlock(&hi847->mutex);
return 0;

View File

@ -395,7 +395,7 @@ static int imx208_write_regs(struct imx208 *imx208,
static int imx208_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_get_try_format(sd, fh->state, 0);
v4l2_subdev_state_get_format(fh->state, 0);
/* Initialize try_fmt */
try_fmt->width = supported_modes[0].width;
@ -548,9 +548,8 @@ static int __imx208_get_pad_format(struct imx208 *imx208,
struct v4l2_subdev_format *fmt)
{
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
fmt->format = *v4l2_subdev_get_try_format(&imx208->sd,
sd_state,
fmt->pad);
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
imx208_mode_to_pad_format(imx208, imx208->cur_mode, fmt);
@ -591,7 +590,7 @@ static int imx208_set_pad_format(struct v4l2_subdev *sd,
fmt->format.width, fmt->format.height);
imx208_mode_to_pad_format(imx208, mode, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format;
*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
} else {
imx208->cur_mode = mode;
__v4l2_ctrl_s_ctrl(imx208->link_freq, mode->link_freq_index);

View File

@ -19,12 +19,31 @@
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#define IMX214_REG_MODE_SELECT 0x0100
#define IMX214_MODE_STANDBY 0x00
#define IMX214_MODE_STREAMING 0x01
#define IMX214_DEFAULT_CLK_FREQ 24000000
#define IMX214_DEFAULT_LINK_FREQ 480000000
#define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
#define IMX214_FPS 30
#define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
/* Exposure control */
#define IMX214_REG_EXPOSURE 0x0202
#define IMX214_EXPOSURE_MIN 0
#define IMX214_EXPOSURE_MAX 3184
#define IMX214_EXPOSURE_STEP 1
#define IMX214_EXPOSURE_DEFAULT 3184
/* IMX214 native and active pixel array size */
#define IMX214_NATIVE_WIDTH 4224U
#define IMX214_NATIVE_HEIGHT 3136U
#define IMX214_PIXEL_ARRAY_LEFT 8U
#define IMX214_PIXEL_ARRAY_TOP 8U
#define IMX214_PIXEL_ARRAY_WIDTH 4208U
#define IMX214_PIXEL_ARRAY_HEIGHT 3120U
static const char * const imx214_supply_name[] = {
"vdda",
"vddd",
@ -538,7 +557,7 @@ __imx214_get_pad_format(struct imx214 *imx214,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_format(&imx214->sd, sd_state, pad);
return v4l2_subdev_state_get_format(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &imx214->fmt;
default:
@ -568,7 +587,7 @@ __imx214_get_pad_crop(struct imx214 *imx214,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_crop(&imx214->sd, sd_state, pad);
return v4l2_subdev_state_get_crop(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &imx214->crop;
default:
@ -623,18 +642,35 @@ static int imx214_get_selection(struct v4l2_subdev *sd,
{
struct imx214 *imx214 = to_imx214(sd);
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
mutex_lock(&imx214->mutex);
sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad,
sel->which);
mutex_unlock(&imx214->mutex);
return 0;
mutex_lock(&imx214->mutex);
sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad,
sel->which);
mutex_unlock(&imx214->mutex);
return 0;
case V4L2_SEL_TGT_NATIVE_SIZE:
sel->r.top = 0;
sel->r.left = 0;
sel->r.width = IMX214_NATIVE_WIDTH;
sel->r.height = IMX214_NATIVE_HEIGHT;
return 0;
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
sel->r.top = IMX214_PIXEL_ARRAY_TOP;
sel->r.left = IMX214_PIXEL_ARRAY_LEFT;
sel->r.width = IMX214_PIXEL_ARRAY_WIDTH;
sel->r.height = IMX214_PIXEL_ARRAY_HEIGHT;
return 0;
}
return -EINVAL;
}
static int imx214_entity_init_cfg(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
static int imx214_entity_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_subdev_format fmt = { };
@ -665,7 +701,7 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE:
vals[1] = ctrl->val;
vals[0] = ctrl->val >> 8;
ret = regmap_bulk_write(imx214->regmap, 0x202, vals, 2);
ret = regmap_bulk_write(imx214->regmap, IMX214_REG_EXPOSURE, vals, 2);
if (ret < 0)
dev_err(imx214->dev, "Error %d\n", ret);
ret = 0;
@ -684,6 +720,76 @@ static const struct v4l2_ctrl_ops imx214_ctrl_ops = {
.s_ctrl = imx214_set_ctrl,
};
static int imx214_ctrls_init(struct imx214 *imx214)
{
static const s64 link_freq[] = {
IMX214_DEFAULT_LINK_FREQ
};
static const struct v4l2_area unit_size = {
.width = 1120,
.height = 1120,
};
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
int ret;
ret = v4l2_fwnode_device_parse(imx214->dev, &props);
if (ret < 0)
return ret;
ctrl_hdlr = &imx214->ctrls;
ret = v4l2_ctrl_handler_init(&imx214->ctrls, 6);
if (ret)
return ret;
imx214->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, NULL,
V4L2_CID_PIXEL_RATE, 0,
IMX214_DEFAULT_PIXEL_RATE, 1,
IMX214_DEFAULT_PIXEL_RATE);
imx214->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, NULL,
V4L2_CID_LINK_FREQ,
ARRAY_SIZE(link_freq) - 1,
0, link_freq);
if (imx214->link_freq)
imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/*
* WARNING!
* Values obtained reverse engineering blobs and/or devices.
* Ranges and functionality might be wrong.
*
* Sony, please release some register set documentation for the
* device.
*
* Yours sincerely, Ricardo.
*/
imx214->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
V4L2_CID_EXPOSURE,
IMX214_EXPOSURE_MIN,
IMX214_EXPOSURE_MAX,
IMX214_EXPOSURE_STEP,
IMX214_EXPOSURE_DEFAULT);
imx214->unit_size = v4l2_ctrl_new_std_compound(ctrl_hdlr,
NULL,
V4L2_CID_UNIT_CELL_SIZE,
v4l2_ctrl_ptr_create((void *)&unit_size));
v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx214_ctrl_ops, &props);
ret = ctrl_hdlr->error;
if (ret) {
v4l2_ctrl_handler_free(ctrl_hdlr);
dev_err(imx214->dev, "failed to add controls: %d\n", ret);
return ret;
}
imx214->sd.ctrl_handler = ctrl_hdlr;
return 0;
};
#define MAX_CMD 4
static int imx214_write_table(struct imx214 *imx214,
const struct reg_8 table[])
@ -743,7 +849,7 @@ static int imx214_start_streaming(struct imx214 *imx214)
dev_err(imx214->dev, "could not sync v4l2 controls\n");
goto error;
}
ret = regmap_write(imx214->regmap, 0x100, 1);
ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING);
if (ret < 0) {
dev_err(imx214->dev, "could not sent start table %d\n", ret);
goto error;
@ -761,7 +867,7 @@ static int imx214_stop_streaming(struct imx214 *imx214)
{
int ret;
ret = regmap_write(imx214->regmap, 0x100, 0);
ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY);
if (ret < 0)
dev_err(imx214->dev, "could not sent stop table %d\n", ret);
@ -795,9 +901,17 @@ err_rpm_put:
return ret;
}
static int imx214_g_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_frame_interval *fival)
static int imx214_get_frame_interval(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fival)
{
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fival->interval.numerator = 1;
fival->interval.denominator = IMX214_FPS;
@ -828,8 +942,6 @@ static int imx214_enum_frame_interval(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_video_ops imx214_video_ops = {
.s_stream = imx214_s_stream,
.g_frame_interval = imx214_g_frame_interval,
.s_frame_interval = imx214_g_frame_interval,
};
static const struct v4l2_subdev_pad_ops imx214_subdev_pad_ops = {
@ -839,7 +951,8 @@ static const struct v4l2_subdev_pad_ops imx214_subdev_pad_ops = {
.get_fmt = imx214_get_format,
.set_fmt = imx214_set_format,
.get_selection = imx214_get_selection,
.init_cfg = imx214_entity_init_cfg,
.get_frame_interval = imx214_get_frame_interval,
.set_frame_interval = imx214_get_frame_interval,
};
static const struct v4l2_subdev_ops imx214_subdev_ops = {
@ -848,6 +961,10 @@ static const struct v4l2_subdev_ops imx214_subdev_ops = {
.pad = &imx214_subdev_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx214_internal_ops = {
.init_state = imx214_entity_init_state,
};
static const struct regmap_config sensor_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
@ -907,13 +1024,6 @@ static int imx214_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct imx214 *imx214;
static const s64 link_freq[] = {
IMX214_DEFAULT_LINK_FREQ,
};
static const struct v4l2_area unit_size = {
.width = 1120,
.height = 1120,
};
int ret;
ret = imx214_parse_fwnode(dev);
@ -957,6 +1067,7 @@ static int imx214_probe(struct i2c_client *client)
}
v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
imx214->sd.internal_ops = &imx214_internal_ops;
/*
* Enable power initially, to avoid warnings
@ -968,45 +1079,10 @@ static int imx214_probe(struct i2c_client *client)
pm_runtime_enable(imx214->dev);
pm_runtime_idle(imx214->dev);
v4l2_ctrl_handler_init(&imx214->ctrls, 3);
ret = imx214_ctrls_init(imx214);
if (ret < 0)
goto error_power_off;
imx214->pixel_rate = v4l2_ctrl_new_std(&imx214->ctrls, NULL,
V4L2_CID_PIXEL_RATE, 0,
IMX214_DEFAULT_PIXEL_RATE, 1,
IMX214_DEFAULT_PIXEL_RATE);
imx214->link_freq = v4l2_ctrl_new_int_menu(&imx214->ctrls, NULL,
V4L2_CID_LINK_FREQ,
ARRAY_SIZE(link_freq) - 1,
0, link_freq);
if (imx214->link_freq)
imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/*
* WARNING!
* Values obtained reverse engineering blobs and/or devices.
* Ranges and functionality might be wrong.
*
* Sony, please release some register set documentation for the
* device.
*
* Yours sincerely, Ricardo.
*/
imx214->exposure = v4l2_ctrl_new_std(&imx214->ctrls, &imx214_ctrl_ops,
V4L2_CID_EXPOSURE,
0, 3184, 1, 0x0c70);
imx214->unit_size = v4l2_ctrl_new_std_compound(&imx214->ctrls,
NULL,
V4L2_CID_UNIT_CELL_SIZE,
v4l2_ctrl_ptr_create((void *)&unit_size));
ret = imx214->ctrls.error;
if (ret) {
dev_err(&client->dev, "%s control init failed (%d)\n",
__func__, ret);
goto free_ctrl;
}
imx214->sd.ctrl_handler = &imx214->ctrls;
mutex_init(&imx214->mutex);
imx214->ctrls.lock = &imx214->mutex;
@ -1021,7 +1097,7 @@ static int imx214_probe(struct i2c_client *client)
goto free_ctrl;
}
imx214_entity_init_cfg(&imx214->sd, NULL);
imx214_entity_init_state(&imx214->sd, NULL);
ret = v4l2_async_register_subdev_sensor(&imx214->sd);
if (ret < 0) {
@ -1036,6 +1112,7 @@ free_entity:
free_ctrl:
mutex_destroy(&imx214->mutex);
v4l2_ctrl_handler_free(&imx214->ctrls);
error_power_off:
pm_runtime_disable(imx214->dev);
return ret;

View File

@ -374,7 +374,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
int ret = 0;
state = v4l2_subdev_get_locked_active_state(&imx219->sd);
format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
if (ctrl->id == V4L2_CID_VBLANK) {
int exposure_max, exposure_def;
@ -593,8 +593,8 @@ static int imx219_set_framefmt(struct imx219 *imx219,
u64 bin_h, bin_v;
int ret = 0;
format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0);
crop = v4l2_subdev_get_pad_crop(&imx219->sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
switch (format->code) {
case MEDIA_BUS_FMT_SRGGB8_1X8:
@ -826,7 +826,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code);
format = v4l2_subdev_get_pad_format(sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
*format = fmt->format;
/*
@ -836,7 +836,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
bin_h = min(IMX219_PIXEL_ARRAY_WIDTH / format->width, 2U);
bin_v = min(IMX219_PIXEL_ARRAY_HEIGHT / format->height, 2U);
crop = v4l2_subdev_get_pad_crop(sd, state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
crop->width = format->width * bin_h;
crop->height = format->height * bin_v;
crop->left = (IMX219_NATIVE_WIDTH - crop->width) / 2;
@ -880,7 +880,7 @@ static int imx219_get_selection(struct v4l2_subdev *sd,
{
switch (sel->target) {
case V4L2_SEL_TGT_CROP: {
sel->r = *v4l2_subdev_get_pad_crop(sd, state, 0);
sel->r = *v4l2_subdev_state_get_crop(state, 0);
return 0;
}
@ -905,8 +905,8 @@ static int imx219_get_selection(struct v4l2_subdev *sd,
return -EINVAL;
}
static int imx219_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int imx219_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_TRY,
@ -933,7 +933,6 @@ static const struct v4l2_subdev_video_ops imx219_video_ops = {
};
static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
.init_cfg = imx219_init_cfg,
.enum_mbus_code = imx219_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = imx219_set_pad_format,
@ -947,6 +946,9 @@ static const struct v4l2_subdev_ops imx219_subdev_ops = {
.pad = &imx219_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
.init_state = imx219_init_state,
};
/* -----------------------------------------------------------------------------
* Power management
@ -1098,6 +1100,7 @@ static int imx219_probe(struct i2c_client *client)
return -ENOMEM;
v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
imx219->sd.internal_ops = &imx219_internal_ops;
/* Check the hardware configuration in device tree */
if (imx219_check_hwcfg(dev, imx219))

View File

@ -708,7 +708,7 @@ static int imx258_write_regs(struct imx258 *imx258,
static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_get_try_format(sd, fh->state, 0);
v4l2_subdev_state_get_format(fh->state, 0);
/* Initialize try_fmt */
try_fmt->width = supported_modes[0].width;
@ -862,9 +862,8 @@ static int __imx258_get_pad_format(struct imx258 *imx258,
struct v4l2_subdev_format *fmt)
{
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
fmt->format = *v4l2_subdev_get_try_format(&imx258->sd,
sd_state,
fmt->pad);
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
imx258_update_pad_format(imx258->cur_mode, fmt);
@ -908,7 +907,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
fmt->format.width, fmt->format.height);
imx258_update_pad_format(mode, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else {
imx258->cur_mode = mode;

View File

@ -594,8 +594,8 @@ static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl);
static int imx274_set_exposure(struct stimx274 *priv, int val);
static int imx274_set_vflip(struct stimx274 *priv, int val);
static int imx274_set_test_pattern(struct stimx274 *priv, int val);
static int imx274_set_frame_interval(struct stimx274 *priv,
struct v4l2_fract frame_interval);
static int __imx274_set_frame_interval(struct stimx274 *priv,
struct v4l2_fract frame_interval);
static inline void msleep_range(unsigned int delay_base)
{
@ -1018,8 +1018,8 @@ static int __imx274_change_compose(struct stimx274 *imx274,
int best_goodness = INT_MIN;
if (which == V4L2_SUBDEV_FORMAT_TRY) {
cur_crop = &sd_state->pads->try_crop;
tgt_fmt = &sd_state->pads->try_fmt;
cur_crop = v4l2_subdev_state_get_crop(sd_state, 0);
tgt_fmt = v4l2_subdev_state_get_format(sd_state, 0);
} else {
cur_crop = &imx274->crop;
tgt_fmt = &imx274->format;
@ -1112,7 +1112,7 @@ static int imx274_set_fmt(struct v4l2_subdev *sd,
*/
fmt->field = V4L2_FIELD_NONE;
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
sd_state->pads->try_fmt = *fmt;
*v4l2_subdev_state_get_format(sd_state, 0) = *fmt;
else
imx274->format = *fmt;
@ -1143,8 +1143,8 @@ static int imx274_get_selection(struct v4l2_subdev *sd,
}
if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
src_crop = &sd_state->pads->try_crop;
src_fmt = &sd_state->pads->try_fmt;
src_crop = v4l2_subdev_state_get_crop(sd_state, 0);
src_fmt = v4l2_subdev_state_get_format(sd_state, 0);
} else {
src_crop = &imx274->crop;
src_fmt = &imx274->format;
@ -1215,7 +1215,7 @@ static int imx274_set_selection_crop(struct stimx274 *imx274,
sel->r = new_crop;
if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
tgt_crop = &sd_state->pads->try_crop;
tgt_crop = v4l2_subdev_state_get_crop(sd_state, 0);
else
tgt_crop = &imx274->crop;
@ -1327,20 +1327,19 @@ static int imx274_apply_trimming(struct stimx274 *imx274)
return err;
}
/**
* imx274_g_frame_interval - Get the frame interval
* @sd: Pointer to V4L2 Sub device structure
* @fi: Pointer to V4l2 Sub device frame interval structure
*
* This function is used to get the frame interval.
*
* Return: 0 on success
*/
static int imx274_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
static int imx274_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct stimx274 *imx274 = to_imx274(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval = imx274->frame_interval;
dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n",
__func__, imx274->frame_interval.numerator,
@ -1349,29 +1348,28 @@ static int imx274_g_frame_interval(struct v4l2_subdev *sd,
return 0;
}
/**
* imx274_s_frame_interval - Set the frame interval
* @sd: Pointer to V4L2 Sub device structure
* @fi: Pointer to V4l2 Sub device frame interval structure
*
* This function is used to set the frame intervavl.
*
* Return: 0 on success
*/
static int imx274_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
static int imx274_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct stimx274 *imx274 = to_imx274(sd);
struct v4l2_ctrl *ctrl = imx274->ctrls.exposure;
int min, max, def;
int ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
ret = pm_runtime_resume_and_get(&imx274->client->dev);
if (ret < 0)
return ret;
mutex_lock(&imx274->lock);
ret = imx274_set_frame_interval(imx274, fi->interval);
ret = __imx274_set_frame_interval(imx274, fi->interval);
if (!ret) {
fi->interval = imx274->frame_interval;
@ -1466,8 +1464,8 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
* are changed.
* gain is not affected.
*/
ret = imx274_set_frame_interval(imx274,
imx274->frame_interval);
ret = __imx274_set_frame_interval(imx274,
imx274->frame_interval);
if (ret)
goto fail;
@ -1830,7 +1828,7 @@ fail:
}
/*
* imx274_set_frame_interval - Function called when setting frame interval
* __imx274_set_frame_interval - Function called when setting frame interval
* @priv: Pointer to device structure
* @frame_interval: Variable for frame interval
*
@ -1839,8 +1837,8 @@ fail:
*
* Return: 0 on success
*/
static int imx274_set_frame_interval(struct stimx274 *priv,
struct v4l2_fract frame_interval)
static int __imx274_set_frame_interval(struct stimx274 *priv,
struct v4l2_fract frame_interval)
{
int err;
u32 frame_length, req_frame_rate;
@ -1927,11 +1925,11 @@ static const struct v4l2_subdev_pad_ops imx274_pad_ops = {
.set_fmt = imx274_set_fmt,
.get_selection = imx274_get_selection,
.set_selection = imx274_set_selection,
.get_frame_interval = imx274_get_frame_interval,
.set_frame_interval = imx274_set_frame_interval,
};
static const struct v4l2_subdev_video_ops imx274_video_ops = {
.g_frame_interval = imx274_g_frame_interval,
.s_frame_interval = imx274_s_frame_interval,
.s_stream = imx274_s_stream,
};

View File

@ -41,18 +41,18 @@
#define IMX290_WINMODE_720P (1 << 4)
#define IMX290_WINMODE_CROP (4 << 4)
#define IMX290_FR_FDG_SEL CCI_REG8(0x3009)
#define IMX290_BLKLEVEL CCI_REG16(0x300a)
#define IMX290_BLKLEVEL CCI_REG16_LE(0x300a)
#define IMX290_GAIN CCI_REG8(0x3014)
#define IMX290_VMAX CCI_REG24(0x3018)
#define IMX290_VMAX CCI_REG24_LE(0x3018)
#define IMX290_VMAX_MAX 0x3ffff
#define IMX290_HMAX CCI_REG16(0x301c)
#define IMX290_HMAX CCI_REG16_LE(0x301c)
#define IMX290_HMAX_MAX 0xffff
#define IMX290_SHS1 CCI_REG24(0x3020)
#define IMX290_SHS1 CCI_REG24_LE(0x3020)
#define IMX290_WINWV_OB CCI_REG8(0x303a)
#define IMX290_WINPV CCI_REG16(0x303c)
#define IMX290_WINWV CCI_REG16(0x303e)
#define IMX290_WINPH CCI_REG16(0x3040)
#define IMX290_WINWH CCI_REG16(0x3042)
#define IMX290_WINPV CCI_REG16_LE(0x303c)
#define IMX290_WINWV CCI_REG16_LE(0x303e)
#define IMX290_WINPH CCI_REG16_LE(0x3040)
#define IMX290_WINWH CCI_REG16_LE(0x3042)
#define IMX290_OUT_CTRL CCI_REG8(0x3046)
#define IMX290_ODBIT_10BIT (0 << 0)
#define IMX290_ODBIT_12BIT (1 << 0)
@ -78,28 +78,28 @@
#define IMX290_ADBIT2 CCI_REG8(0x317c)
#define IMX290_ADBIT2_10BIT 0x12
#define IMX290_ADBIT2_12BIT 0x00
#define IMX290_CHIP_ID CCI_REG16(0x319a)
#define IMX290_CHIP_ID CCI_REG16_LE(0x319a)
#define IMX290_ADBIT3 CCI_REG8(0x31ec)
#define IMX290_ADBIT3_10BIT 0x37
#define IMX290_ADBIT3_12BIT 0x0e
#define IMX290_REPETITION CCI_REG8(0x3405)
#define IMX290_PHY_LANE_NUM CCI_REG8(0x3407)
#define IMX290_OPB_SIZE_V CCI_REG8(0x3414)
#define IMX290_Y_OUT_SIZE CCI_REG16(0x3418)
#define IMX290_CSI_DT_FMT CCI_REG16(0x3441)
#define IMX290_Y_OUT_SIZE CCI_REG16_LE(0x3418)
#define IMX290_CSI_DT_FMT CCI_REG16_LE(0x3441)
#define IMX290_CSI_DT_FMT_RAW10 0x0a0a
#define IMX290_CSI_DT_FMT_RAW12 0x0c0c
#define IMX290_CSI_LANE_MODE CCI_REG8(0x3443)
#define IMX290_EXTCK_FREQ CCI_REG16(0x3444)
#define IMX290_TCLKPOST CCI_REG16(0x3446)
#define IMX290_THSZERO CCI_REG16(0x3448)
#define IMX290_THSPREPARE CCI_REG16(0x344a)
#define IMX290_TCLKTRAIL CCI_REG16(0x344c)
#define IMX290_THSTRAIL CCI_REG16(0x344e)
#define IMX290_TCLKZERO CCI_REG16(0x3450)
#define IMX290_TCLKPREPARE CCI_REG16(0x3452)
#define IMX290_TLPX CCI_REG16(0x3454)
#define IMX290_X_OUT_SIZE CCI_REG16(0x3472)
#define IMX290_EXTCK_FREQ CCI_REG16_LE(0x3444)
#define IMX290_TCLKPOST CCI_REG16_LE(0x3446)
#define IMX290_THSZERO CCI_REG16_LE(0x3448)
#define IMX290_THSPREPARE CCI_REG16_LE(0x344a)
#define IMX290_TCLKTRAIL CCI_REG16_LE(0x344c)
#define IMX290_THSTRAIL CCI_REG16_LE(0x344e)
#define IMX290_TCLKZERO CCI_REG16_LE(0x3450)
#define IMX290_TCLKPREPARE CCI_REG16_LE(0x3452)
#define IMX290_TLPX CCI_REG16_LE(0x3454)
#define IMX290_X_OUT_SIZE CCI_REG16_LE(0x3472)
#define IMX290_INCKSEL7 CCI_REG8(0x3480)
#define IMX290_PGCTRL_REGEN BIT(0)
@ -758,7 +758,7 @@ static int imx290_set_ctrl(struct v4l2_ctrl *ctrl)
return 0;
state = v4l2_subdev_get_locked_active_state(&imx290->sd);
format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
@ -994,7 +994,7 @@ static int imx290_start_streaming(struct imx290 *imx290,
}
/* Apply the register values related to current frame format */
format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
ret = imx290_setup_format(imx290, format);
if (ret < 0) {
dev_err(imx290->dev, "Could not set frame format - %d\n", ret);
@ -1132,7 +1132,7 @@ static int imx290_set_fmt(struct v4l2_subdev *sd,
fmt->format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
format = v4l2_subdev_state_get_format(sd_state, 0);
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
imx290->current_mode = mode;
@ -1155,7 +1155,7 @@ static int imx290_get_selection(struct v4l2_subdev *sd,
switch (sel->target) {
case V4L2_SEL_TGT_CROP: {
format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
format = v4l2_subdev_state_get_format(sd_state, 0);
/*
* The sensor moves the readout by 1 pixel based on flips to
@ -1195,8 +1195,8 @@ static int imx290_get_selection(struct v4l2_subdev *sd,
}
}
static int imx290_entity_init_cfg(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
static int imx290_entity_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_TRY,
@ -1221,7 +1221,6 @@ static const struct v4l2_subdev_video_ops imx290_video_ops = {
};
static const struct v4l2_subdev_pad_ops imx290_pad_ops = {
.init_cfg = imx290_entity_init_cfg,
.enum_mbus_code = imx290_enum_mbus_code,
.enum_frame_size = imx290_enum_frame_size,
.get_fmt = v4l2_subdev_get_fmt,
@ -1235,6 +1234,10 @@ static const struct v4l2_subdev_ops imx290_subdev_ops = {
.pad = &imx290_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx290_internal_ops = {
.init_state = imx290_entity_init_state,
};
static const struct media_entity_operations imx290_subdev_entity_ops = {
.link_validate = v4l2_subdev_link_validate,
};
@ -1248,6 +1251,7 @@ static int imx290_subdev_init(struct imx290 *imx290)
imx290->current_mode = &imx290_modes_ptr(imx290)[0];
v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
imx290->sd.internal_ops = &imx290_internal_ops;
imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;
imx290->sd.dev = imx290->dev;

View File

@ -323,7 +323,7 @@ static int imx296_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
state = v4l2_subdev_get_locked_active_state(&sensor->subdev);
format = v4l2_subdev_get_pad_format(&sensor->subdev, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
@ -511,8 +511,8 @@ static int imx296_setup(struct imx296 *sensor, struct v4l2_subdev_state *state)
unsigned int i;
int ret = 0;
format = v4l2_subdev_get_pad_format(&sensor->subdev, state, 0);
crop = v4l2_subdev_get_pad_crop(&sensor->subdev, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
for (i = 0; i < ARRAY_SIZE(imx296_init_table); ++i)
imx296_write(sensor, imx296_init_table[i].reg,
@ -662,7 +662,7 @@ static int imx296_enum_frame_size(struct v4l2_subdev *sd,
{
const struct v4l2_mbus_framefmt *format;
format = v4l2_subdev_get_pad_format(sd, state, fse->pad);
format = v4l2_subdev_state_get_format(state, fse->pad);
if (fse->index >= 2 || fse->code != format->code)
return -EINVAL;
@ -683,8 +683,8 @@ static int imx296_set_format(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
crop = v4l2_subdev_get_pad_crop(sd, state, fmt->pad);
format = v4l2_subdev_get_pad_format(sd, state, fmt->pad);
crop = v4l2_subdev_state_get_crop(state, fmt->pad);
format = v4l2_subdev_state_get_format(state, fmt->pad);
/*
* Binning is only allowed when cropping is disabled according to the
@ -732,7 +732,7 @@ static int imx296_get_selection(struct v4l2_subdev *sd,
{
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
sel->r = *v4l2_subdev_get_pad_crop(sd, state, sel->pad);
sel->r = *v4l2_subdev_state_get_crop(state, sel->pad);
break;
case V4L2_SEL_TGT_CROP_DEFAULT:
@ -780,14 +780,14 @@ static int imx296_set_selection(struct v4l2_subdev *sd,
rect.height = min_t(unsigned int, rect.height,
IMX296_PIXEL_ARRAY_HEIGHT - rect.top);
crop = v4l2_subdev_get_pad_crop(sd, state, sel->pad);
crop = v4l2_subdev_state_get_crop(state, sel->pad);
if (rect.width != crop->width || rect.height != crop->height) {
/*
* Reset the output image size if the crop rectangle size has
* been modified.
*/
format = v4l2_subdev_get_pad_format(sd, state, sel->pad);
format = v4l2_subdev_state_get_format(state, sel->pad);
format->width = rect.width;
format->height = rect.height;
}
@ -798,8 +798,8 @@ static int imx296_set_selection(struct v4l2_subdev *sd,
return 0;
}
static int imx296_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int imx296_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct v4l2_subdev_selection sel = {
.target = V4L2_SEL_TGT_CROP,
@ -830,7 +830,6 @@ static const struct v4l2_subdev_pad_ops imx296_subdev_pad_ops = {
.set_fmt = imx296_set_format,
.get_selection = imx296_get_selection,
.set_selection = imx296_set_selection,
.init_cfg = imx296_init_cfg,
};
static const struct v4l2_subdev_ops imx296_subdev_ops = {
@ -838,12 +837,17 @@ static const struct v4l2_subdev_ops imx296_subdev_ops = {
.pad = &imx296_subdev_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx296_internal_ops = {
.init_state = imx296_init_state,
};
static int imx296_subdev_init(struct imx296 *sensor)
{
struct i2c_client *client = to_i2c_client(sensor->dev);
int ret;
v4l2_i2c_subdev_init(&sensor->subdev, client, &imx296_subdev_ops);
sensor->subdev.internal_ops = &imx296_internal_ops;
ret = imx296_ctrls_init(sensor);
if (ret < 0)

View File

@ -1860,7 +1860,7 @@ static int imx319_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct imx319 *imx319 = to_imx319(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_get_try_format(sd, fh->state, 0);
v4l2_subdev_state_get_format(fh->state, 0);
mutex_lock(&imx319->mutex);
@ -2001,10 +2001,9 @@ static int imx319_do_get_pad_format(struct imx319 *imx319,
struct v4l2_subdev_format *fmt)
{
struct v4l2_mbus_framefmt *framefmt;
struct v4l2_subdev *sd = &imx319->sd;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format = *framefmt;
} else {
imx319_update_pad_format(imx319, imx319->cur_mode, fmt);
@ -2055,7 +2054,7 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
fmt->format.width, fmt->format.height);
imx319_update_pad_format(imx319, mode, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else {
imx319->cur_mode = mode;
@ -2464,19 +2463,21 @@ static int imx319_probe(struct i2c_client *client)
goto error_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&imx319->sd);
if (ret < 0)
goto error_media_entity;
/* Set the device's state to active if it's in D0 state. */
if (full_power)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
ret = v4l2_async_register_subdev_sensor(&imx319->sd);
if (ret < 0)
goto error_media_entity_pm;
return 0;
error_media_entity:
error_media_entity_pm:
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
media_entity_cleanup(&imx319->sd.entity);
error_handler_free:

View File

@ -879,7 +879,7 @@ static int imx334_get_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format = *framefmt;
} else {
fmt->format.code = imx334->cur_code;
@ -920,7 +920,7 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else if (imx334->cur_mode != mode || imx334->cur_code != fmt->format.code) {
imx334->cur_code = fmt->format.code;
@ -935,14 +935,14 @@ static int imx334_set_pad_format(struct v4l2_subdev *sd,
}
/**
* imx334_init_pad_cfg() - Initialize sub-device pad configuration
* imx334_init_state() - Initialize sub-device state
* @sd: pointer to imx334 V4L2 sub-device structure
* @sd_state: V4L2 sub-device state
*
* Return: 0 if successful, error code otherwise.
*/
static int imx334_init_pad_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int imx334_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct imx334 *imx334 = to_imx334(sd);
struct v4l2_subdev_format fmt = { 0 };
@ -1190,7 +1190,6 @@ static const struct v4l2_subdev_video_ops imx334_video_ops = {
};
static const struct v4l2_subdev_pad_ops imx334_pad_ops = {
.init_cfg = imx334_init_pad_cfg,
.enum_mbus_code = imx334_enum_mbus_code,
.enum_frame_size = imx334_enum_frame_size,
.get_fmt = imx334_get_pad_format,
@ -1202,6 +1201,10 @@ static const struct v4l2_subdev_ops imx334_subdev_ops = {
.pad = &imx334_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx334_internal_ops = {
.init_state = imx334_init_state,
};
/**
* imx334_power_on() - Sensor power on sequence
* @dev: pointer to i2c device
@ -1359,6 +1362,7 @@ static int imx334_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx334->sd, client, &imx334_subdev_ops);
imx334->sd.internal_ops = &imx334_internal_ops;
ret = imx334_parse_hw_config(imx334);
if (ret) {

View File

@ -55,6 +55,14 @@
#define IMX335_REG_MIN 0x00
#define IMX335_REG_MAX 0xfffff
/* IMX335 native and active pixel array size. */
#define IMX335_NATIVE_WIDTH 2616U
#define IMX335_NATIVE_HEIGHT 1964U
#define IMX335_PIXEL_ARRAY_LEFT 12U
#define IMX335_PIXEL_ARRAY_TOP 12U
#define IMX335_PIXEL_ARRAY_WIDTH 2592U
#define IMX335_PIXEL_ARRAY_HEIGHT 1944U
/**
* struct imx335_reg - imx335 sensor register
* @address: Register address
@ -75,6 +83,12 @@ struct imx335_reg_list {
const struct imx335_reg *regs;
};
static const char * const imx335_supply_name[] = {
"avdd", /* Analog (2.9V) supply */
"ovdd", /* Digital I/O (1.8V) supply */
"dvdd", /* Digital Core (1.2V) supply */
};
/**
* struct imx335_mode - imx335 sensor mode structure
* @width: Frame width
@ -108,6 +122,7 @@ struct imx335_mode {
* @sd: V4L2 sub-device
* @pad: Media pad. Only one pad supported
* @reset_gpio: Sensor reset gpio
* @supplies: Regulator supplies to handle power control
* @inclk: Sensor input clock
* @ctrl_handler: V4L2 control handler
* @link_freq_ctrl: Pointer to link frequency control
@ -119,6 +134,7 @@ struct imx335_mode {
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
* @mutex: Mutex for serializing sensor controls
* @cur_mbus_code: Currently selected media bus format code
*/
struct imx335 {
struct device *dev;
@ -126,6 +142,8 @@ struct imx335 {
struct v4l2_subdev sd;
struct media_pad pad;
struct gpio_desc *reset_gpio;
struct regulator_bulk_data supplies[ARRAY_SIZE(imx335_supply_name)];
struct clk *inclk;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *link_freq_ctrl;
@ -139,6 +157,7 @@ struct imx335 {
u32 vblank;
const struct imx335_mode *cur_mode;
struct mutex mutex;
u32 cur_mbus_code;
};
static const s64 link_freq[] = {
@ -233,6 +252,25 @@ static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3a00, 0x01},
};
static const struct imx335_reg raw10_framefmt_regs[] = {
{0x3050, 0x00},
{0x319d, 0x00},
{0x341c, 0xff},
{0x341d, 0x01},
};
static const struct imx335_reg raw12_framefmt_regs[] = {
{0x3050, 0x01},
{0x319d, 0x01},
{0x341c, 0x47},
{0x341d, 0x00},
};
static const u32 imx335_mbus_codes[] = {
MEDIA_BUS_FMT_SRGGB12_1X12,
MEDIA_BUS_FMT_SRGGB10_1X10,
};
/* Supported sensor mode configurations */
static const struct imx335_mode supported_mode = {
.width = 2592,
@ -243,7 +281,6 @@ static const struct imx335_mode supported_mode = {
.vblank_max = 133060,
.pclk = 396000000,
.link_freq_idx = 0,
.code = MEDIA_BUS_FMT_SRGGB12_1X12,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_2592x1940_regs),
.regs = mode_2592x1940_regs,
@ -396,7 +433,7 @@ static int imx335_update_exp_gain(struct imx335 *imx335, u32 exposure, u32 gain)
lpfr = imx335->vblank + imx335->cur_mode->height;
shutter = lpfr - exposure;
dev_dbg(imx335->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u",
dev_dbg(imx335->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u\n",
exposure, gain, shutter, lpfr);
ret = imx335_write_reg(imx335, IMX335_REG_HOLD, 1, 1);
@ -443,7 +480,7 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_VBLANK:
imx335->vblank = imx335->vblank_ctrl->val;
dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u",
dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u\n",
imx335->vblank,
imx335->vblank + imx335->cur_mode->height);
@ -462,7 +499,7 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
exposure = ctrl->val;
analog_gain = imx335->again_ctrl->val;
dev_dbg(imx335->dev, "Received exp %u, analog gain %u",
dev_dbg(imx335->dev, "Received exp %u, analog gain %u\n",
exposure, analog_gain);
ret = imx335_update_exp_gain(imx335, exposure, analog_gain);
@ -471,7 +508,7 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
break;
default:
dev_err(imx335->dev, "Invalid control %d", ctrl->id);
dev_err(imx335->dev, "Invalid control %d\n", ctrl->id);
ret = -EINVAL;
}
@ -483,6 +520,18 @@ static const struct v4l2_ctrl_ops imx335_ctrl_ops = {
.s_ctrl = imx335_set_ctrl,
};
static int imx335_get_format_code(struct imx335 *imx335, u32 code)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(imx335_mbus_codes); i++) {
if (imx335_mbus_codes[i] == code)
return imx335_mbus_codes[i];
}
return imx335_mbus_codes[0];
}
/**
* imx335_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
* @sd: pointer to imx335 V4L2 sub-device structure
@ -495,10 +544,10 @@ static int imx335_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
if (code->index > 0)
if (code->index >= ARRAY_SIZE(imx335_mbus_codes))
return -EINVAL;
code->code = supported_mode.code;
code->code = imx335_mbus_codes[code->index];
return 0;
}
@ -515,10 +564,14 @@ static int imx335_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fsize)
{
if (fsize->index > 0)
struct imx335 *imx335 = to_imx335(sd);
u32 code;
if (fsize->index > ARRAY_SIZE(imx335_mbus_codes))
return -EINVAL;
if (fsize->code != supported_mode.code)
code = imx335_get_format_code(imx335, fsize->code);
if (fsize->code != code)
return -EINVAL;
fsize->min_width = supported_mode.width;
@ -542,7 +595,7 @@ static void imx335_fill_pad_format(struct imx335 *imx335,
{
fmt->format.width = mode->width;
fmt->format.height = mode->height;
fmt->format.code = mode->code;
fmt->format.code = imx335->cur_mbus_code;
fmt->format.field = V4L2_FIELD_NONE;
fmt->format.colorspace = V4L2_COLORSPACE_RAW;
fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
@ -569,7 +622,7 @@ static int imx335_get_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format = *framefmt;
} else {
imx335_fill_pad_format(imx335, imx335->cur_mode, fmt);
@ -594,17 +647,22 @@ static int imx335_set_pad_format(struct v4l2_subdev *sd,
{
struct imx335 *imx335 = to_imx335(sd);
const struct imx335_mode *mode;
int ret = 0;
int i, ret = 0;
mutex_lock(&imx335->mutex);
mode = &supported_mode;
for (i = 0; i < ARRAY_SIZE(imx335_mbus_codes); i++) {
if (imx335_mbus_codes[i] == fmt->format.code)
imx335->cur_mbus_code = imx335_mbus_codes[i];
}
imx335_fill_pad_format(imx335, mode, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else {
ret = imx335_update_controls(imx335, mode);
@ -618,14 +676,14 @@ static int imx335_set_pad_format(struct v4l2_subdev *sd,
}
/**
* imx335_init_pad_cfg() - Initialize sub-device pad configuration
* imx335_init_state() - Initialize sub-device state
* @sd: pointer to imx335 V4L2 sub-device structure
* @sd_state: V4L2 sub-device configuration
*
* Return: 0 if successful, error code otherwise.
*/
static int imx335_init_pad_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int imx335_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct imx335 *imx335 = to_imx335(sd);
struct v4l2_subdev_format fmt = { 0 };
@ -636,6 +694,56 @@ static int imx335_init_pad_cfg(struct v4l2_subdev *sd,
return imx335_set_pad_format(sd, sd_state, &fmt);
}
/**
* imx335_get_selection() - Selection API
* @sd: pointer to imx335 V4L2 sub-device structure
* @sd_state: V4L2 sub-device configuration
* @sel: V4L2 selection info
*
* Return: 0 if successful, error code otherwise.
*/
static int imx335_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_selection *sel)
{
switch (sel->target) {
case V4L2_SEL_TGT_NATIVE_SIZE:
sel->r.top = 0;
sel->r.left = 0;
sel->r.width = IMX335_NATIVE_WIDTH;
sel->r.height = IMX335_NATIVE_HEIGHT;
return 0;
case V4L2_SEL_TGT_CROP:
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
sel->r.top = IMX335_PIXEL_ARRAY_TOP;
sel->r.left = IMX335_PIXEL_ARRAY_LEFT;
sel->r.width = IMX335_PIXEL_ARRAY_WIDTH;
sel->r.height = IMX335_PIXEL_ARRAY_HEIGHT;
return 0;
}
return -EINVAL;
}
static int imx335_set_framefmt(struct imx335 *imx335)
{
switch (imx335->cur_mbus_code) {
case MEDIA_BUS_FMT_SRGGB10_1X10:
return imx335_write_regs(imx335, raw10_framefmt_regs,
ARRAY_SIZE(raw10_framefmt_regs));
case MEDIA_BUS_FMT_SRGGB12_1X12:
return imx335_write_regs(imx335, raw12_framefmt_regs,
ARRAY_SIZE(raw12_framefmt_regs));
}
return -EINVAL;
}
/**
* imx335_start_streaming() - Start sensor stream
* @imx335: pointer to imx335 device
@ -652,14 +760,21 @@ static int imx335_start_streaming(struct imx335 *imx335)
ret = imx335_write_regs(imx335, reg_list->regs,
reg_list->num_of_regs);
if (ret) {
dev_err(imx335->dev, "fail to write initial registers");
dev_err(imx335->dev, "fail to write initial registers\n");
return ret;
}
ret = imx335_set_framefmt(imx335);
if (ret) {
dev_err(imx335->dev, "%s failed to set frame format: %d\n",
__func__, ret);
return ret;
}
/* Setup handler will write actual exposure and gain */
ret = __v4l2_ctrl_handler_setup(imx335->sd.ctrl_handler);
if (ret) {
dev_err(imx335->dev, "fail to setup handler");
dev_err(imx335->dev, "fail to setup handler\n");
return ret;
}
@ -667,7 +782,7 @@ static int imx335_start_streaming(struct imx335 *imx335)
ret = imx335_write_reg(imx335, IMX335_REG_MODE_SELECT,
1, IMX335_MODE_STREAMING);
if (ret) {
dev_err(imx335->dev, "fail to start streaming");
dev_err(imx335->dev, "fail to start streaming\n");
return ret;
}
@ -744,7 +859,7 @@ static int imx335_detect(struct imx335 *imx335)
return ret;
if (val != IMX335_ID) {
dev_err(imx335->dev, "chip id mismatch: %x!=%x",
dev_err(imx335->dev, "chip id mismatch: %x!=%x\n",
IMX335_ID, val);
return -ENXIO;
}
@ -776,27 +891,40 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(imx335->reset_gpio)) {
dev_err(imx335->dev, "failed to get reset gpio %ld",
dev_err(imx335->dev, "failed to get reset gpio %ld\n",
PTR_ERR(imx335->reset_gpio));
return PTR_ERR(imx335->reset_gpio);
}
for (i = 0; i < ARRAY_SIZE(imx335_supply_name); i++)
imx335->supplies[i].supply = imx335_supply_name[i];
ret = devm_regulator_bulk_get(imx335->dev,
ARRAY_SIZE(imx335_supply_name),
imx335->supplies);
if (ret) {
dev_err(imx335->dev, "Failed to get regulators\n");
return ret;
}
/* Get sensor input clock */
imx335->inclk = devm_clk_get(imx335->dev, NULL);
if (IS_ERR(imx335->inclk)) {
dev_err(imx335->dev, "could not get inclk");
dev_err(imx335->dev, "could not get inclk\n");
return PTR_ERR(imx335->inclk);
}
rate = clk_get_rate(imx335->inclk);
if (rate != IMX335_INCLK_RATE) {
dev_err(imx335->dev, "inclk frequency mismatch");
dev_err(imx335->dev, "inclk frequency mismatch\n");
return -EINVAL;
}
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
if (!ep) {
dev_err(imx335->dev, "Failed to get next endpoint\n");
return -ENXIO;
}
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
fwnode_handle_put(ep);
@ -805,14 +933,14 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX335_NUM_DATA_LANES) {
dev_err(imx335->dev,
"number of CSI2 data lanes %d is not supported",
"number of CSI2 data lanes %d is not supported\n",
bus_cfg.bus.mipi_csi2.num_data_lanes);
ret = -EINVAL;
goto done_endpoint_free;
}
if (!bus_cfg.nr_of_link_frequencies) {
dev_err(imx335->dev, "no link frequencies defined");
dev_err(imx335->dev, "no link frequencies defined\n");
ret = -EINVAL;
goto done_endpoint_free;
}
@ -821,6 +949,8 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
if (bus_cfg.link_frequencies[i] == IMX335_LINK_FREQ)
goto done_endpoint_free;
dev_err(imx335->dev, "no compatible link frequencies found\n");
ret = -EINVAL;
done_endpoint_free:
@ -835,9 +965,10 @@ static const struct v4l2_subdev_video_ops imx335_video_ops = {
};
static const struct v4l2_subdev_pad_ops imx335_pad_ops = {
.init_cfg = imx335_init_pad_cfg,
.enum_mbus_code = imx335_enum_mbus_code,
.enum_frame_size = imx335_enum_frame_size,
.get_selection = imx335_get_selection,
.set_selection = imx335_get_selection,
.get_fmt = imx335_get_pad_format,
.set_fmt = imx335_set_pad_format,
};
@ -847,6 +978,10 @@ static const struct v4l2_subdev_ops imx335_subdev_ops = {
.pad = &imx335_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx335_internal_ops = {
.init_state = imx335_init_state,
};
/**
* imx335_power_on() - Sensor power on sequence
* @dev: pointer to i2c device
@ -859,20 +994,32 @@ static int imx335_power_on(struct device *dev)
struct imx335 *imx335 = to_imx335(sd);
int ret;
ret = regulator_bulk_enable(ARRAY_SIZE(imx335_supply_name),
imx335->supplies);
if (ret) {
dev_err(dev, "%s: failed to enable regulators\n",
__func__);
return ret;
}
usleep_range(500, 550); /* Tlow */
/* Set XCLR */
gpiod_set_value_cansleep(imx335->reset_gpio, 1);
ret = clk_prepare_enable(imx335->inclk);
if (ret) {
dev_err(imx335->dev, "fail to enable inclk");
dev_err(imx335->dev, "fail to enable inclk\n");
goto error_reset;
}
usleep_range(20, 22);
usleep_range(20, 22); /* T4 */
return 0;
error_reset:
gpiod_set_value_cansleep(imx335->reset_gpio, 0);
regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
return ret;
}
@ -889,8 +1036,8 @@ static int imx335_power_off(struct device *dev)
struct imx335 *imx335 = to_imx335(sd);
gpiod_set_value_cansleep(imx335->reset_gpio, 0);
clk_disable_unprepare(imx335->inclk);
regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
return 0;
}
@ -962,14 +1109,14 @@ static int imx335_init_controls(struct imx335 *imx335)
imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
&imx335_ctrl_ops,
V4L2_CID_HBLANK,
IMX335_REG_MIN,
IMX335_REG_MAX,
mode->hblank,
mode->hblank,
1, mode->hblank);
if (imx335->hblank_ctrl)
imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
if (ctrl_hdlr->error) {
dev_err(imx335->dev, "control init failed: %d",
dev_err(imx335->dev, "control init failed: %d\n",
ctrl_hdlr->error);
v4l2_ctrl_handler_free(ctrl_hdlr);
return ctrl_hdlr->error;
@ -999,10 +1146,11 @@ static int imx335_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx335->sd, client, &imx335_subdev_ops);
imx335->sd.internal_ops = &imx335_internal_ops;
ret = imx335_parse_hw_config(imx335);
if (ret) {
dev_err(imx335->dev, "HW configuration is not supported");
dev_err(imx335->dev, "HW configuration is not supported\n");
return ret;
}
@ -1010,24 +1158,25 @@ static int imx335_probe(struct i2c_client *client)
ret = imx335_power_on(imx335->dev);
if (ret) {
dev_err(imx335->dev, "failed to power-on the sensor");
dev_err(imx335->dev, "failed to power-on the sensor\n");
goto error_mutex_destroy;
}
/* Check module identity */
ret = imx335_detect(imx335);
if (ret) {
dev_err(imx335->dev, "failed to find sensor: %d", ret);
dev_err(imx335->dev, "failed to find sensor: %d\n", ret);
goto error_power_off;
}
/* Set default mode to max resolution */
imx335->cur_mode = &supported_mode;
imx335->cur_mbus_code = imx335_mbus_codes[0];
imx335->vblank = imx335->cur_mode->vblank;
ret = imx335_init_controls(imx335);
if (ret) {
dev_err(imx335->dev, "failed to init controls: %d", ret);
dev_err(imx335->dev, "failed to init controls: %d\n", ret);
goto error_power_off;
}
@ -1039,14 +1188,14 @@ static int imx335_probe(struct i2c_client *client)
imx335->pad.flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&imx335->sd.entity, 1, &imx335->pad);
if (ret) {
dev_err(imx335->dev, "failed to init entity pads: %d", ret);
dev_err(imx335->dev, "failed to init entity pads: %d\n", ret);
goto error_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&imx335->sd);
if (ret < 0) {
dev_err(imx335->dev,
"failed to register async subdev: %d", ret);
"failed to register async subdev: %d\n", ret);
goto error_media_entity;
}

View File

@ -1158,7 +1158,7 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct imx355 *imx355 = to_imx355(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_get_try_format(sd, fh->state, 0);
v4l2_subdev_state_get_format(fh->state, 0);
mutex_lock(&imx355->mutex);
@ -1299,10 +1299,9 @@ static int imx355_do_get_pad_format(struct imx355 *imx355,
struct v4l2_subdev_format *fmt)
{
struct v4l2_mbus_framefmt *framefmt;
struct v4l2_subdev *sd = &imx355->sd;
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format = *framefmt;
} else {
imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
@ -1353,7 +1352,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
fmt->format.width, fmt->format.height);
imx355_update_pad_format(imx355, mode, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else {
imx355->cur_mode = mode;
@ -1748,10 +1747,6 @@ static int imx355_probe(struct i2c_client *client)
goto error_handler_free;
}
ret = v4l2_async_register_subdev_sensor(&imx355->sd);
if (ret < 0)
goto error_media_entity;
/*
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
@ -1760,9 +1755,15 @@ static int imx355_probe(struct i2c_client *client)
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
ret = v4l2_async_register_subdev_sensor(&imx355->sd);
if (ret < 0)
goto error_media_entity_runtime_pm;
return 0;
error_media_entity:
error_media_entity_runtime_pm:
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
media_entity_cleanup(&imx355->sd.entity);
error_handler_free:

View File

@ -721,7 +721,7 @@ static int imx412_get_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
fmt->format = *framefmt;
} else {
imx412_fill_pad_format(imx412, imx412->cur_mode, fmt);
@ -756,7 +756,7 @@ static int imx412_set_pad_format(struct v4l2_subdev *sd,
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
} else {
ret = imx412_update_controls(imx412, mode);
@ -770,14 +770,14 @@ static int imx412_set_pad_format(struct v4l2_subdev *sd,
}
/**
* imx412_init_pad_cfg() - Initialize sub-device pad configuration
* imx412_init_state() - Initialize sub-device state
* @sd: pointer to imx412 V4L2 sub-device structure
* @sd_state: V4L2 sub-device configuration
*
* Return: 0 if successful, error code otherwise.
*/
static int imx412_init_pad_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int imx412_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct imx412 *imx412 = to_imx412(sd);
struct v4l2_subdev_format fmt = { 0 };
@ -997,7 +997,6 @@ static const struct v4l2_subdev_video_ops imx412_video_ops = {
};
static const struct v4l2_subdev_pad_ops imx412_pad_ops = {
.init_cfg = imx412_init_pad_cfg,
.enum_mbus_code = imx412_enum_mbus_code,
.enum_frame_size = imx412_enum_frame_size,
.get_fmt = imx412_get_pad_format,
@ -1009,6 +1008,10 @@ static const struct v4l2_subdev_ops imx412_subdev_ops = {
.pad = &imx412_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx412_internal_ops = {
.init_state = imx412_init_state,
};
/**
* imx412_power_on() - Sensor power on sequence
* @dev: pointer to i2c device
@ -1177,6 +1180,7 @@ static int imx412_probe(struct i2c_client *client)
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx412->sd, client, &imx412_subdev_ops);
imx412->sd.internal_ops = &imx412_internal_ops;
ret = imx412_parse_hw_config(imx412);
if (ret) {

View File

@ -546,7 +546,7 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
state = v4l2_subdev_get_locked_active_state(&sensor->subdev);
format = v4l2_subdev_get_pad_format(&sensor->subdev, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
@ -828,7 +828,7 @@ static int imx415_enum_frame_size(struct v4l2_subdev *sd,
{
const struct v4l2_mbus_framefmt *format;
format = v4l2_subdev_get_pad_format(sd, state, fse->pad);
format = v4l2_subdev_state_get_format(state, fse->pad);
if (fse->index > 0 || fse->code != format->code)
return -EINVAL;
@ -846,7 +846,7 @@ static int imx415_set_format(struct v4l2_subdev *sd,
{
struct v4l2_mbus_framefmt *format;
format = v4l2_subdev_get_pad_format(sd, state, fmt->pad);
format = v4l2_subdev_state_get_format(state, fmt->pad);
format->width = fmt->format.width;
format->height = fmt->format.height;
@ -880,8 +880,8 @@ static int imx415_get_selection(struct v4l2_subdev *sd,
return -EINVAL;
}
static int imx415_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int imx415_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct v4l2_subdev_format format = {
.format = {
@ -905,7 +905,6 @@ static const struct v4l2_subdev_pad_ops imx415_subdev_pad_ops = {
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = imx415_set_format,
.get_selection = imx415_get_selection,
.init_cfg = imx415_init_cfg,
};
static const struct v4l2_subdev_ops imx415_subdev_ops = {
@ -913,12 +912,17 @@ static const struct v4l2_subdev_ops imx415_subdev_ops = {
.pad = &imx415_subdev_pad_ops,
};
static const struct v4l2_subdev_internal_ops imx415_internal_ops = {
.init_state = imx415_init_state,
};
static int imx415_subdev_init(struct imx415 *sensor)
{
struct i2c_client *client = to_i2c_client(sensor->dev);
int ret;
v4l2_i2c_subdev_init(&sensor->subdev, client, &imx415_subdev_ops);
sensor->subdev.internal_ops = &imx415_internal_ops;
ret = imx415_ctrls_init(sensor);
if (ret)

View File

@ -1007,8 +1007,8 @@ static int isl7998x_get_fmt(struct v4l2_subdev *sd,
mutex_lock(&isl7998x->lock);
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
format->format = *v4l2_subdev_get_try_format(sd, sd_state,
format->pad);
format->format = *v4l2_subdev_state_get_format(sd_state,
format->pad);
goto out;
}
@ -1044,7 +1044,7 @@ static int isl7998x_set_fmt(struct v4l2_subdev *sd,
mf->field = mode->field;
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
*v4l2_subdev_get_try_format(sd, sd_state, format->pad) = format->format;
*v4l2_subdev_state_get_format(sd_state, format->pad) = format->format;
mutex_unlock(&isl7998x->lock);

View File

@ -868,11 +868,19 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
static int max9286_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval)
static int max9286_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *interval)
{
struct max9286_priv *priv = sd_to_max9286(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (interval->pad != MAX9286_SRC_PAD)
return -EINVAL;
@ -881,11 +889,19 @@ static int max9286_g_frame_interval(struct v4l2_subdev *sd,
return 0;
}
static int max9286_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval)
static int max9286_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *interval)
{
struct max9286_priv *priv = sd_to_max9286(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (interval->pad != MAX9286_SRC_PAD)
return -EINVAL;
@ -913,7 +929,7 @@ max9286_get_pad_format(struct max9286_priv *priv,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_format(&priv->sd, sd_state, pad);
return v4l2_subdev_state_get_format(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &priv->fmt[pad];
default:
@ -983,14 +999,14 @@ static int max9286_get_fmt(struct v4l2_subdev *sd,
static const struct v4l2_subdev_video_ops max9286_video_ops = {
.s_stream = max9286_s_stream,
.g_frame_interval = max9286_g_frame_interval,
.s_frame_interval = max9286_s_frame_interval,
};
static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
.enum_mbus_code = max9286_enum_mbus_code,
.get_fmt = max9286_get_fmt,
.set_fmt = max9286_set_fmt,
.get_frame_interval = max9286_get_frame_interval,
.set_frame_interval = max9286_set_frame_interval,
};
static const struct v4l2_subdev_ops max9286_subdev_ops = {
@ -1020,7 +1036,7 @@ static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
unsigned int i;
for (i = 0; i < MAX9286_N_SINKS; i++) {
format = v4l2_subdev_get_try_format(subdev, fh->state, i);
format = v4l2_subdev_state_get_format(fh->state, i);
max9286_init_format(format);
}

View File

@ -325,7 +325,7 @@ static int mt9m001_get_fmt(struct v4l2_subdev *sd,
return -EINVAL;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
mf = v4l2_subdev_get_try_format(sd, sd_state, 0);
mf = v4l2_subdev_state_get_format(sd_state, 0);
format->format = *mf;
return 0;
}
@ -405,7 +405,7 @@ static int mt9m001_set_fmt(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
return mt9m001_s_fmt(sd, fmt, mf);
sd_state->pads->try_fmt = *mf;
*v4l2_subdev_state_get_format(sd_state, 0) = *mf;
return 0;
}
@ -650,13 +650,13 @@ static const struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
#endif
};
static int mt9m001_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int mt9m001_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct mt9m001 *mt9m001 = to_mt9m001(client);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_get_try_format(sd, sd_state, 0);
v4l2_subdev_state_get_format(sd_state, 0);
try_fmt->width = MT9M001_MAX_WIDTH;
try_fmt->height = MT9M001_MAX_HEIGHT;
@ -708,7 +708,6 @@ static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
};
static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = {
.init_cfg = mt9m001_init_cfg,
.enum_mbus_code = mt9m001_enum_mbus_code,
.get_selection = mt9m001_get_selection,
.set_selection = mt9m001_set_selection,
@ -724,6 +723,10 @@ static const struct v4l2_subdev_ops mt9m001_subdev_ops = {
.pad = &mt9m001_subdev_pad_ops,
};
static const struct v4l2_subdev_internal_ops mt9m001_internal_ops = {
.init_state = mt9m001_init_state,
};
static int mt9m001_probe(struct i2c_client *client)
{
struct mt9m001 *mt9m001;
@ -755,6 +758,7 @@ static int mt9m001_probe(struct i2c_client *client)
return PTR_ERR(mt9m001->reset_gpio);
v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
mt9m001->subdev.internal_ops = &mt9m001_internal_ops;
mt9m001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;
v4l2_ctrl_handler_init(&mt9m001->hdl, 4);

View File

@ -525,7 +525,7 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd,
return -EINVAL;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
mf = v4l2_subdev_get_try_format(sd, sd_state, format->pad);
mf = v4l2_subdev_state_get_format(sd_state, format->pad);
format->format = *mf;
return 0;
}
@ -671,7 +671,7 @@ static int mt9m111_set_fmt(struct v4l2_subdev *sd,
mf->xfer_func = V4L2_XFER_FUNC_DEFAULT;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *mf;
*v4l2_subdev_state_get_format(sd_state, 0) = *mf;
return 0;
}
@ -1045,18 +1045,27 @@ static const struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
#endif
};
static int mt9m111_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
static int mt9m111_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval = mt9m111->frame_interval;
return 0;
}
static int mt9m111_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
static int mt9m111_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
const struct mt9m111_mode_info *mode;
@ -1066,6 +1075,13 @@ static int mt9m111_s_frame_interval(struct v4l2_subdev *sd,
if (mt9m111->is_streaming)
return -EBUSY;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (fi->pad != 0)
return -EINVAL;
@ -1111,11 +1127,11 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
static int mt9m111_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
static int mt9m111_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_mbus_framefmt *format =
v4l2_subdev_get_try_format(sd, sd_state, 0);
v4l2_subdev_state_get_format(sd_state, 0);
format->width = MT9M111_MAX_WIDTH;
format->height = MT9M111_MAX_HEIGHT;
@ -1151,17 +1167,16 @@ static int mt9m111_get_mbus_config(struct v4l2_subdev *sd,
static const struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
.s_stream = mt9m111_s_stream,
.g_frame_interval = mt9m111_g_frame_interval,
.s_frame_interval = mt9m111_s_frame_interval,
};
static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = {
.init_cfg = mt9m111_init_cfg,
.enum_mbus_code = mt9m111_enum_mbus_code,
.get_selection = mt9m111_get_selection,
.set_selection = mt9m111_set_selection,
.get_fmt = mt9m111_get_fmt,
.set_fmt = mt9m111_set_fmt,
.get_frame_interval = mt9m111_get_frame_interval,
.set_frame_interval = mt9m111_set_frame_interval,
.get_mbus_config = mt9m111_get_mbus_config,
};
@ -1171,6 +1186,10 @@ static const struct v4l2_subdev_ops mt9m111_subdev_ops = {
.pad = &mt9m111_subdev_pad_ops,
};
static const struct v4l2_subdev_internal_ops mt9m111_internal_ops = {
.init_state = mt9m111_init_state,
};
/*
* Interface active, can use i2c. If it fails, it can indeed mean, that
* this wasn't our capture interface, so, we wait for the right one
@ -1275,6 +1294,7 @@ static int mt9m111_probe(struct i2c_client *client)
mt9m111->ctx = &context_b;
v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
mt9m111->subdev.internal_ops = &mt9m111_internal_ops;
mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;

View File

@ -796,13 +796,13 @@ static int mt9m114_configure(struct mt9m114 *sensor,
u64 read_mode;
int ret = 0;
pa_format = v4l2_subdev_get_pad_format(&sensor->pa.sd, pa_state, 0);
pa_crop = v4l2_subdev_get_pad_crop(&sensor->pa.sd, pa_state, 0);
pa_format = v4l2_subdev_state_get_format(pa_state, 0);
pa_crop = v4l2_subdev_state_get_crop(pa_state, 0);
ifp_format = v4l2_subdev_get_pad_format(&sensor->ifp.sd, ifp_state, 1);
ifp_format = v4l2_subdev_state_get_format(ifp_state, 1);
ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code);
ifp_crop = v4l2_subdev_get_pad_crop(&sensor->ifp.sd, ifp_state, 0);
ifp_compose = v4l2_subdev_get_pad_compose(&sensor->ifp.sd, ifp_state, 0);
ifp_crop = v4l2_subdev_state_get_crop(ifp_state, 0);
ifp_compose = v4l2_subdev_state_get_compose(ifp_state, 0);
ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
&read_mode, NULL);
@ -1045,7 +1045,7 @@ static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
state = v4l2_subdev_get_locked_active_state(&sensor->pa.sd);
format = v4l2_subdev_get_pad_format(&sensor->pa.sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
switch (ctrl->id) {
case V4L2_CID_HBLANK:
@ -1152,20 +1152,20 @@ static inline struct mt9m114 *pa_to_mt9m114(struct v4l2_subdev *sd)
return container_of(sd, struct mt9m114, pa.sd);
}
static int mt9m114_pa_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int mt9m114_pa_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
crop = v4l2_subdev_get_pad_crop(sd, state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
crop->left = 0;
crop->top = 0;
crop->width = MT9M114_PIXEL_ARRAY_WIDTH;
crop->height = MT9M114_PIXEL_ARRAY_HEIGHT;
format = v4l2_subdev_get_pad_format(sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
format->width = MT9M114_PIXEL_ARRAY_WIDTH;
format->height = MT9M114_PIXEL_ARRAY_HEIGHT;
@ -1220,8 +1220,8 @@ static int mt9m114_pa_set_fmt(struct v4l2_subdev *sd,
unsigned int hscale;
unsigned int vscale;
crop = v4l2_subdev_get_pad_crop(sd, state, fmt->pad);
format = v4l2_subdev_get_pad_format(sd, state, fmt->pad);
crop = v4l2_subdev_state_get_crop(state, fmt->pad);
format = v4l2_subdev_state_get_format(state, fmt->pad);
/* The sensor can bin horizontally and vertically. */
hscale = DIV_ROUND_CLOSEST(crop->width, fmt->format.width ? : 1);
@ -1243,7 +1243,7 @@ static int mt9m114_pa_get_selection(struct v4l2_subdev *sd,
{
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
sel->r = *v4l2_subdev_get_pad_crop(sd, state, sel->pad);
sel->r = *v4l2_subdev_state_get_crop(state, sel->pad);
return 0;
case V4L2_SEL_TGT_CROP_DEFAULT:
@ -1271,8 +1271,8 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
crop = v4l2_subdev_get_pad_crop(sd, state, sel->pad);
format = v4l2_subdev_get_pad_format(sd, state, sel->pad);
crop = v4l2_subdev_state_get_crop(state, sel->pad);
format = v4l2_subdev_state_get_format(state, sel->pad);
/*
* Clamp the crop rectangle. The vertical coordinates must be even, and
@ -1304,7 +1304,6 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
}
static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = {
.init_cfg = mt9m114_pa_init_cfg,
.enum_mbus_code = mt9m114_pa_enum_mbus_code,
.enum_frame_size = mt9m114_pa_enum_framesizes,
.get_fmt = v4l2_subdev_get_fmt,
@ -1317,6 +1316,10 @@ static const struct v4l2_subdev_ops mt9m114_pa_ops = {
.pad = &mt9m114_pa_pad_ops,
};
static const struct v4l2_subdev_internal_ops mt9m114_pa_internal_ops = {
.init_state = mt9m114_pa_init_state,
};
static int mt9m114_pa_init(struct mt9m114 *sensor)
{
struct v4l2_ctrl_handler *hdl = &sensor->pa.hdl;
@ -1329,6 +1332,7 @@ static int mt9m114_pa_init(struct mt9m114 *sensor)
/* Initialize the subdev. */
v4l2_subdev_init(sd, &mt9m114_pa_ops);
sd->internal_ops = &mt9m114_pa_internal_ops;
v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " pixel array");
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
@ -1402,7 +1406,7 @@ static int mt9m114_pa_init(struct mt9m114 *sensor)
/* Update the range of the blanking controls based on the format. */
state = v4l2_subdev_lock_and_get_active_state(sd);
format = v4l2_subdev_get_pad_format(sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
mt9m114_pa_ctrl_update_blanking(sensor, format);
v4l2_subdev_unlock_state(state);
@ -1581,12 +1585,20 @@ static int mt9m114_ifp_s_stream(struct v4l2_subdev *sd, int enable)
return ret;
}
static int mt9m114_ifp_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval)
static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *interval)
{
struct v4l2_fract *ival = &interval->interval;
struct mt9m114 *sensor = ifp_to_mt9m114(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(sensor->ifp.hdl.lock);
ival->numerator = 1;
@ -1597,13 +1609,21 @@ static int mt9m114_ifp_g_frame_interval(struct v4l2_subdev *sd,
return 0;
}
static int mt9m114_ifp_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval)
static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *interval)
{
struct v4l2_fract *ival = &interval->interval;
struct mt9m114 *sensor = ifp_to_mt9m114(sd);
int ret = 0;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
mutex_lock(sensor->ifp.hdl.lock);
if (ival->numerator != 0 && ival->denominator != 0)
@ -1624,15 +1644,15 @@ static int mt9m114_ifp_s_frame_interval(struct v4l2_subdev *sd,
return ret;
}
static int mt9m114_ifp_init_cfg(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
static int mt9m114_ifp_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{
struct mt9m114 *sensor = ifp_to_mt9m114(sd);
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
struct v4l2_rect *compose;
format = v4l2_subdev_get_pad_format(sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
format->width = MT9M114_PIXEL_ARRAY_WIDTH;
format->height = MT9M114_PIXEL_ARRAY_HEIGHT;
@ -1643,21 +1663,21 @@ static int mt9m114_ifp_init_cfg(struct v4l2_subdev *sd,
format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
format->xfer_func = V4L2_XFER_FUNC_NONE;
crop = v4l2_subdev_get_pad_crop(sd, state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
crop->left = 4;
crop->top = 4;
crop->width = format->width - 8;
crop->height = format->height - 8;
compose = v4l2_subdev_get_pad_compose(sd, state, 0);
compose = v4l2_subdev_state_get_compose(state, 0);
compose->left = 0;
compose->top = 0;
compose->width = crop->width;
compose->height = crop->height;
format = v4l2_subdev_get_pad_format(sd, state, 1);
format = v4l2_subdev_state_get_format(state, 1);
format->width = compose->width;
format->height = compose->height;
@ -1738,7 +1758,7 @@ static int mt9m114_ifp_enum_framesizes(struct v4l2_subdev *sd,
} else {
const struct v4l2_rect *crop;
crop = v4l2_subdev_get_pad_crop(sd, state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
fse->max_width = crop->width;
fse->max_height = crop->height;
@ -1777,7 +1797,7 @@ static int mt9m114_ifp_set_fmt(struct v4l2_subdev *sd,
struct mt9m114 *sensor = ifp_to_mt9m114(sd);
struct v4l2_mbus_framefmt *format;
format = v4l2_subdev_get_pad_format(sd, state, fmt->pad);
format = v4l2_subdev_state_get_format(state, fmt->pad);
if (fmt->pad == 0) {
/* Only the size can be changed on the sink pad. */
@ -1797,7 +1817,7 @@ static int mt9m114_ifp_set_fmt(struct v4l2_subdev *sd,
/* If the output format is RAW10, bypass the scaler. */
if (format->code == MEDIA_BUS_FMT_SGRBG10_1X10)
*format = *v4l2_subdev_get_pad_format(sd, state, 0);
*format = *v4l2_subdev_state_get_format(state, 0);
}
fmt->format = *format;
@ -1819,7 +1839,7 @@ static int mt9m114_ifp_get_selection(struct v4l2_subdev *sd,
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
sel->r = *v4l2_subdev_get_pad_crop(sd, state, 0);
sel->r = *v4l2_subdev_state_get_crop(state, 0);
break;
case V4L2_SEL_TGT_CROP_DEFAULT:
@ -1828,7 +1848,7 @@ static int mt9m114_ifp_get_selection(struct v4l2_subdev *sd,
* The crop default and bounds are equal to the sink
* format size minus 4 pixels on each side for demosaicing.
*/
format = v4l2_subdev_get_pad_format(sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
sel->r.left = 4;
sel->r.top = 4;
@ -1837,7 +1857,7 @@ static int mt9m114_ifp_get_selection(struct v4l2_subdev *sd,
break;
case V4L2_SEL_TGT_COMPOSE:
sel->r = *v4l2_subdev_get_pad_compose(sd, state, 0);
sel->r = *v4l2_subdev_state_get_compose(state, 0);
break;
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
@ -1846,7 +1866,7 @@ static int mt9m114_ifp_get_selection(struct v4l2_subdev *sd,
* The compose default and bounds sizes are equal to the sink
* crop rectangle size.
*/
crop = v4l2_subdev_get_pad_crop(sd, state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
sel->r.left = 0;
sel->r.top = 0;
sel->r.width = crop->width;
@ -1877,9 +1897,9 @@ static int mt9m114_ifp_set_selection(struct v4l2_subdev *sd,
if (sel->pad != 0)
return -EINVAL;
format = v4l2_subdev_get_pad_format(sd, state, 0);
crop = v4l2_subdev_get_pad_crop(sd, state, 0);
compose = v4l2_subdev_get_pad_compose(sd, state, 0);
format = v4l2_subdev_state_get_format(state, 0);
crop = v4l2_subdev_state_get_crop(state, 0);
compose = v4l2_subdev_state_get_compose(state, 0);
if (sel->target == V4L2_SEL_TGT_CROP) {
/*
@ -1921,7 +1941,7 @@ static int mt9m114_ifp_set_selection(struct v4l2_subdev *sd,
}
/* Propagate the compose rectangle to the source format. */
format = v4l2_subdev_get_pad_format(sd, state, 1);
format = v4l2_subdev_state_get_format(state, 1);
format->width = compose->width;
format->height = compose->height;
@ -1963,12 +1983,9 @@ static int mt9m114_ifp_registered(struct v4l2_subdev *sd)
static const struct v4l2_subdev_video_ops mt9m114_ifp_video_ops = {
.s_stream = mt9m114_ifp_s_stream,
.g_frame_interval = mt9m114_ifp_g_frame_interval,
.s_frame_interval = mt9m114_ifp_s_frame_interval,
};
static const struct v4l2_subdev_pad_ops mt9m114_ifp_pad_ops = {
.init_cfg = mt9m114_ifp_init_cfg,
.enum_mbus_code = mt9m114_ifp_enum_mbus_code,
.enum_frame_size = mt9m114_ifp_enum_framesizes,
.enum_frame_interval = mt9m114_ifp_enum_frameintervals,
@ -1976,6 +1993,8 @@ static const struct v4l2_subdev_pad_ops mt9m114_ifp_pad_ops = {
.set_fmt = mt9m114_ifp_set_fmt,
.get_selection = mt9m114_ifp_get_selection,
.set_selection = mt9m114_ifp_set_selection,
.get_frame_interval = mt9m114_ifp_get_frame_interval,
.set_frame_interval = mt9m114_ifp_set_frame_interval,
};
static const struct v4l2_subdev_ops mt9m114_ifp_ops = {
@ -1984,6 +2003,7 @@ static const struct v4l2_subdev_ops mt9m114_ifp_ops = {
};
static const struct v4l2_subdev_internal_ops mt9m114_ifp_internal_ops = {
.init_state = mt9m114_ifp_init_state,
.registered = mt9m114_ifp_registered,
.unregistered = mt9m114_ifp_unregistered,
};
@ -2112,7 +2132,7 @@ static int mt9m114_power_on(struct mt9m114 *sensor)
duration = DIV_ROUND_UP(2 * 50 * 1000000, freq);
gpiod_set_value(sensor->reset, 1);
udelay(duration);
fsleep(duration);
gpiod_set_value(sensor->reset, 0);
} else {
/*

View File

@ -549,8 +549,7 @@ __mt9p031_get_pad_format(struct mt9p031 *mt9p031,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_format(&mt9p031->subdev, sd_state,
pad);
return v4l2_subdev_state_get_format(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &mt9p031->format;
default:
@ -565,8 +564,7 @@ __mt9p031_get_pad_crop(struct mt9p031 *mt9p031,
{
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_get_try_crop(&mt9p031->subdev, sd_state,
pad);
return v4l2_subdev_state_get_crop(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &mt9p031->crop;
default:
@ -698,8 +696,8 @@ static int mt9p031_set_selection(struct v4l2_subdev *subdev,
return 0;
}
static int mt9p031_init_cfg(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
static int mt9p031_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
{
struct mt9p031 *mt9p031 = to_mt9p031(subdev);
struct v4l2_mbus_framefmt *format;
@ -1043,7 +1041,6 @@ static const struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = {
};
static const struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = {
.init_cfg = mt9p031_init_cfg,
.enum_mbus_code = mt9p031_enum_mbus_code,
.enum_frame_size = mt9p031_enum_frame_size,
.get_fmt = mt9p031_get_format,
@ -1059,6 +1056,7 @@ static const struct v4l2_subdev_ops mt9p031_subdev_ops = {
};
static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
.init_state = mt9p031_init_state,
.registered = mt9p031_registered,
.open = mt9p031_open,
.close = mt9p031_close,
@ -1191,7 +1189,7 @@ static int mt9p031_probe(struct i2c_client *client)
mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ret = mt9p031_init_cfg(&mt9p031->subdev, NULL);
ret = mt9p031_init_state(&mt9p031->subdev, NULL);
if (ret)
goto done;

View File

@ -982,7 +982,6 @@ static int mt9t112_set_fmt(struct v4l2_subdev *sd,
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
return mt9t112_s_fmt(sd, mf);
sd_state->pads->try_fmt = *mf;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More